1 /* IPSec VPN client compatible with Cisco equipment.
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2 of the License, or
6 (at your option) any later version.
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include <openssl/pem.h>
27 crypto_ctx
*crypto_ctx_new(crypto_error
**error
)
31 ctx
= malloc(sizeof(crypto_ctx
));
33 crypto_error_set(error
, 1, ENOMEM
,
34 "not enough memory for crypto context");
38 OpenSSL_add_all_ciphers();
39 OpenSSL_add_all_digests();
40 OpenSSL_add_all_algorithms();
41 ERR_load_crypto_strings();
43 memset(ctx
, 0, sizeof(crypto_ctx
));
44 ctx
->stack
= sk_X509_new_null();
47 crypto_error_set(error
, 1, ENOMEM
,
48 "not enough memory for crypto certificate stack");
55 void crypto_ctx_free(crypto_ctx
*ctx
)
59 sk_X509_free(ctx
->stack
);
61 memset(ctx
, 0, sizeof(crypto_ctx
));
66 static int password_cb(char *buf
, int size
, int rwflag
, void *userdata
)
68 /* Dummy callback to ensure openssl doesn't prompt for a password */
72 unsigned char *crypto_read_cert(const char *path
,
78 unsigned char *data
= NULL
, *p
;
80 fp
= fopen(path
, "r");
82 crypto_error_set(error
, 1, 0, "certificate (%s) could not be opened", path
);
86 cert
= PEM_read_X509(fp
, NULL
, password_cb
, NULL
);
91 p
= data
= crypto_read_file(path
, out_len
, error
);
92 if (!data
|| !*out_len
) {
93 crypto_error_set(error
, 1, 0, "could not read certificate %s", path
);
97 cert
= d2i_X509(NULL
, (const unsigned char **) &p
, (int) (*out_len
));
100 crypto_error_set(error
, 1, 0, "could not allocate memory for certificate");
107 /* Get length of DER data */
108 *out_len
= i2d_X509(cert
, NULL
);
110 crypto_error_set(error
, 1, 0, "invalid certificate length");
114 p
= data
= malloc(*out_len
);
116 crypto_error_set(error
, 1, 0, "could not allocate memory for certificate");
120 /* Encode the certificate to DER */
121 *out_len
= i2d_X509(cert
, &p
);
123 crypto_error_set(error
, 1, 0, "could not export certificate data");
137 int crypto_push_cert(crypto_ctx
*ctx
,
138 const unsigned char *data
,
140 crypto_error
**error
)
144 if (!ctx
|| !data
|| (len
<= 0)) {
145 crypto_error_set(error
, 1, 0, "invalid crypto context or data");
149 /* convert the certificate to an openssl-X509 structure and push it onto the chain stack */
150 cert
= d2i_X509(NULL
, &data
, (int) len
);
152 ERR_print_errors_fp(stderr
);
153 crypto_error_set(error
, 1, 0, "failed to decode certificate");
156 sk_X509_push(ctx
->stack
, cert
);
160 int crypto_verify_chain(crypto_ctx
*ctx
,
163 crypto_error
**error
)
166 X509_STORE
*store
= NULL
;
167 X509_LOOKUP
*lookup
= NULL
;
168 X509_STORE_CTX
*verify_ctx
= NULL
;
172 crypto_error_set(error
, 1, 0, "invalid crypto context");
176 x509
= sk_X509_value(ctx
->stack
, sk_X509_num(ctx
->stack
) - 1);
178 ERR_print_errors_fp (stderr
);
179 crypto_error_set(error
, 1, 0, "no certificates in the stack");
183 /* BEGIN - verify certificate chain */
184 /* create the cert store */
185 if (!(store
= X509_STORE_new())) {
186 crypto_error_set(error
, 1, 0, "error creating X509_STORE object");
189 /* load the CA certificates */
190 if (X509_STORE_load_locations (store
, ca_file
, ca_dir
) != 1) {
191 crypto_error_set(error
, 1, 0, "error loading the CA file (%s) "
192 "or directory (%s)", ca_file
, ca_dir
);
195 if (X509_STORE_set_default_paths (store
) != 1) {
196 crypto_error_set(error
, 1, 0, "error loading the system-wide CA"
203 /* add the corresponding CRL for each CA in the chain to the lookup */
204 #define CRL_FILE "root-ca-crl.crl.pem"
206 if (!(lookup
= X509_STORE_add_lookup(store
, X509_LOOKUP_file()))) {
207 crypto_error_set(error
, 1, 0, "error creating X509 lookup object.");
210 if (X509_load_crl_file(lookup
, CRL_FILE
, X509_FILETYPE_PEM
) != 1) {
211 ERR_print_errors_fp(stderr
);
212 crypto_error_set(error
, 1, 0, "error reading CRL file");
215 X509_STORE_set_flags(store
, X509_V_FLAG_CRL_CHECK
| X509_V_FLAG_CRL_CHECK_ALL
);
218 /* create a verification context and initialize it */
219 if (!(verify_ctx
= X509_STORE_CTX_new ())) {
220 crypto_error_set(error
, 1, 0, "error creating X509_STORE_CTX object");
223 /* X509_STORE_CTX_init did not return an error condition in prior versions */
224 if (X509_STORE_CTX_init (verify_ctx
, store
, x509
, ctx
->stack
) != 1) {
225 crypto_error_set(error
, 1, 0, "error intializing verification context");
229 /* verify the certificate */
230 if (X509_verify_cert(verify_ctx
) != 1) {
231 ERR_print_errors_fp(stderr
);
232 crypto_error_set(error
, 2, 0, "error verifying the certificate "
241 X509_LOOKUP_free(lookup
);
243 X509_STORE_free(store
);
245 X509_STORE_CTX_free(verify_ctx
);
249 unsigned char *crypto_decrypt_signature(crypto_ctx
*ctx
,
250 const unsigned char *sig_data
,
253 unsigned int padding
,
254 crypto_error
**error
)
257 EVP_PKEY
*pkey
= NULL
;
259 unsigned char *hash
= NULL
;
260 int tmp_len
= -1, ossl_pad
;
265 crypto_error_set(error
, 1, 0, "invalid crypto context");
269 x509
= sk_X509_value(ctx
->stack
, sk_X509_num(ctx
->stack
) - 1);
271 ERR_print_errors_fp (stderr
);
272 crypto_error_set(error
, 1, 0, "no certificates in the stack");
276 pkey
= X509_get_pubkey(x509
);
278 ERR_print_errors_fp (stderr
);
279 crypto_error_set(error
, 1, 0, "error getting certificate public key");
283 rsa
= EVP_PKEY_get1_RSA(pkey
);
285 ERR_print_errors_fp (stderr
);
286 crypto_error_set(error
, 1, 0, "error getting public key RSA");
290 hash
= calloc(1, RSA_size(rsa
));
292 crypto_error_set(error
, 1, 0, "not enough memory to decrypt signature");
297 case CRYPTO_PAD_NONE
:
298 ossl_pad
= RSA_NO_PADDING
;
300 case CRYPTO_PAD_PKCS1
:
301 ossl_pad
= RSA_PKCS1_PADDING
;
304 crypto_error_set(error
, 1, 0, "unknown padding mechanism %d", padding
);
308 tmp_len
= RSA_public_decrypt(sig_len
, sig_data
, hash
, rsa
, ossl_pad
);
310 *out_len
= (size_t) tmp_len
;
312 ERR_print_errors_fp (stderr
);
313 crypto_error_set(error
, 1, 0, "could not decrypt signature");