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
28 static int gnutls_initialized
= 0;
30 #define CERT_STACK_DEPTH 20
32 crypto_ctx
*crypto_ctx_new(crypto_error
**error
)
36 if (!gnutls_initialized
) {
37 if (gnutls_global_init() != 0) {
38 crypto_error_set(error
, 1, 0, "error initializing gnutls globals");
41 gnutls_initialized
= 1;
44 ctx
= gnutls_calloc(1, sizeof(crypto_ctx
));
46 crypto_error_set(error
, 1, ENOMEM
, "not enough memory for crypto context");
50 ctx
->stack
= gnutls_calloc(CERT_STACK_DEPTH
, sizeof(gnutls_x509_crt_t
));
53 crypto_error_set(error
, 1, ENOMEM
,
54 "not enough memory for crypto certificate stack");
61 void crypto_ctx_free(crypto_ctx
*ctx
)
66 for (i
= 0; i
< ctx
->num
; i
++)
67 gnutls_x509_crt_deinit(ctx
->stack
[i
]);
68 gnutls_free(ctx
->stack
);
69 memset(ctx
, 0, sizeof(crypto_ctx
));
74 unsigned char *crypto_read_cert(const char *path
,
78 gnutls_x509_crt_t cert
;
79 unsigned char *data
= NULL
;
84 dt
.data
= crypto_read_file(path
, &fsize
, error
);
88 dt
.size
= (unsigned int) fsize
;
89 if (gnutls_x509_crt_init(&cert
) != GNUTLS_E_SUCCESS
) {
90 crypto_error_set(error
, 1, ENOMEM
, "not enough memory for certificate");
94 err
= gnutls_x509_crt_import(cert
, &dt
, GNUTLS_X509_FMT_PEM
);
95 if (err
!= GNUTLS_E_SUCCESS
)
96 err
= gnutls_x509_crt_import(cert
, &dt
, GNUTLS_X509_FMT_DER
);
97 if (err
!= GNUTLS_E_SUCCESS
) {
98 crypto_error_set(error
, 1, 0, "certificate (%s) format unknown", path
);
103 data
= malloc(*out_len
);
104 err
= gnutls_x509_crt_export(cert
, GNUTLS_X509_FMT_DER
, data
, out_len
);
105 if (err
!= GNUTLS_E_SUCCESS
) {
108 crypto_error_set(error
, 1, 0, "certificate could not be exported");
113 gnutls_free(dt
.data
);
114 gnutls_x509_crt_deinit(cert
);
118 int crypto_push_cert(crypto_ctx
*ctx
,
119 const unsigned char *data
,
121 crypto_error
**error
)
123 gnutls_x509_crt_t cert
;
127 if (!ctx
|| !data
|| (len
<= 0)) {
128 crypto_error_set(error
, 1, 0, "invalid crypto context or data");
132 if (ctx
->num
>= CERT_STACK_DEPTH
) {
133 crypto_error_set(error
, 1, 0, "too many certificates in the chain.");
137 gnutls_x509_crt_init (&cert
);
139 dt
.data
= (unsigned char *) data
;
141 err
= gnutls_x509_crt_import (cert
, &dt
, GNUTLS_X509_FMT_DER
);
142 if (err
!= GNUTLS_E_SUCCESS
) {
143 gnutls_x509_crt_deinit (cert
);
144 crypto_error_set(error
, 1, 0, "failed to decode certificate");
148 ctx
->stack
[ctx
->num
] = cert
;
153 static int verify_issuer(gnutls_x509_crt_t crt
,
154 gnutls_x509_crt_t issuer
,
155 crypto_error
**error
)
158 time_t now
= time (0);
160 if (gnutls_x509_crt_verify(crt
, &issuer
, 1, 0, &output
) < 0) {
161 crypto_error_set(error
, 1, 0, "failed to verify against issuer");
165 if (output
& GNUTLS_CERT_INVALID
) {
166 if (output
& GNUTLS_CERT_SIGNER_NOT_FOUND
) {
167 crypto_error_set(error
, 1, 0, "certificate signer not found");
170 if (output
& GNUTLS_CERT_SIGNER_NOT_CA
) {
171 crypto_error_set(error
, 1, 0, "certificate signer not a CA");
176 if (gnutls_x509_crt_get_activation_time(crt
) > now
) {
177 crypto_error_set(error
, 1, 0, "certificate activation in the future");
181 if (gnutls_x509_crt_get_expiration_time(crt
) < now
) {
182 crypto_error_set(error
, 1, 0, "certificate expired");
189 static int verify_last(gnutls_x509_crt_t crt
,
190 gnutls_x509_crt_t
*ca_list
,
192 crypto_error
**error
)
195 time_t now
= time (0);
197 if (gnutls_x509_crt_verify (crt
, ca_list
, ca_list_size
,
198 GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT
,
200 crypto_error_set(error
, 1, 0, "failed to verify against CA list");
204 if (output
& GNUTLS_CERT_INVALID
) {
205 if (output
& GNUTLS_CERT_SIGNER_NOT_CA
) {
206 crypto_error_set(error
, 1, 0, "certificate signer not a CA");
211 if (gnutls_x509_crt_get_activation_time(crt
) > now
) {
212 crypto_error_set(error
, 1, 0, "certificate activation in the future");
216 if (gnutls_x509_crt_get_expiration_time(crt
) < now
) {
217 crypto_error_set(error
, 1, 0, "certificate expired");
224 static gnutls_x509_crt_t
*load_one_ca_file(const char *path
, crypto_error
**error
)
226 gnutls_x509_crt_t
*list
= NULL
;
227 gnutls_x509_crt_t cert
;
232 dt
.data
= crypto_read_file(path
, &fsize
, error
);
236 dt
.size
= (unsigned int) fsize
;
237 if (gnutls_x509_crt_init (&cert
) != GNUTLS_E_SUCCESS
) {
238 gnutls_free(dt
.data
);
239 crypto_error_set(error
, 1, ENOMEM
, "not enough memory for certificate");
243 err
= gnutls_x509_crt_import (cert
, &dt
, GNUTLS_X509_FMT_PEM
);
244 if (err
!= GNUTLS_E_SUCCESS
)
245 err
= gnutls_x509_crt_import (cert
, &dt
, GNUTLS_X509_FMT_DER
);
246 gnutls_free(dt
.data
);
247 if (err
!= GNUTLS_E_SUCCESS
) {
248 crypto_error_set(error
, 1, 0, "certificate (%s) format unknown", path
);
252 list
= gnutls_malloc(sizeof(gnutls_x509_crt_t
));
254 crypto_error_set(error
, 1, ENOMEM
, "not enough memory for certificate list");
260 gnutls_x509_crt_deinit (cert
);
264 static gnutls_x509_crt_t
*load_ca_list_file(const char *path
,
265 size_t *out_list_size
,
266 crypto_error
**error
)
268 gnutls_x509_crt_t
*list
;
269 gnutls_datum dt
= { NULL
, 0 };
272 unsigned int num
= 200;
274 dt
.data
= crypto_read_file(path
, &fsize
, error
);
278 dt
.size
= (unsigned int) fsize
;
279 list
= gnutls_malloc(sizeof(gnutls_x509_crt_t
) * num
);
281 crypto_error_set(error
, 1, ENOMEM
, "not enough memory for CA list");
285 err
= gnutls_x509_crt_list_import(list
, &num
, &dt
, GNUTLS_X509_FMT_PEM
, 0);
289 list
= load_one_ca_file(path
, error
);
294 num
= err
; /* gnutls_x509_crt_list_import() returns # read */
297 crypto_error_set(error
, 1, 0, "importing CA list (%d)", err
);
301 *out_list_size
= num
;
304 gnutls_free(dt
.data
);
308 int crypto_verify_chain(crypto_ctx
*ctx
,
311 crypto_error
**error
)
313 int err
, i
, ret
= 1, start
= 0;
314 gnutls_x509_crt_t
*ca_list
= NULL
;
315 size_t ca_list_size
= 0;
324 ca_list
= load_ca_list_file(ca_file
, &ca_list_size
, error
);
328 /* FIXME: Try to load all files in the directory I guess... */
329 crypto_error_set(error
, 1, 0, "ca_dir not yet supported");
333 /* If the server cert is self-signed, ignore it in the issuers check */
334 err
= gnutls_x509_crt_check_issuer(ctx
->stack
[0], ctx
->stack
[0]);
338 /* Check each certificate against its issuer */
339 for (i
= start
; i
< ctx
->num
- 1; i
++) {
340 if (verify_issuer(ctx
->stack
[i
], ctx
->stack
[i
+ 1], error
))
344 /* Verify the last certificate */
345 if (verify_last(ctx
->stack
[ctx
->num
- 1], ca_list
, ca_list_size
, error
))
352 for (i
= 0; i
< (int) ca_list_size
; i
++)
353 gnutls_x509_crt_deinit(ca_list
[i
]);
354 gnutls_free(ca_list
);
359 static unsigned char *check_pkcs1_padding(unsigned char* from
,
362 crypto_error
**error
)
365 unsigned char *rec_hash
= NULL
;
368 /* No function provided to check that hash conforms to
369 * PKCS#1 1.5 padding scheme. Moreover gcrypt trim first
371 if (from
[i
++] != 0x01) {
372 crypto_error_set(error
, 1, 0, "hash doesn't conform to PKCS#1 padding");
376 while (from
[i
] != 0x00) {
377 if (from
[i
++] != 0xFF) {
378 crypto_error_set(error
, 1, 0, "hash doesn't conform to PKCS#1 padding");
383 i
++; /* Skips 00 byte */
386 crypto_error_set(error
, 1, 0, "PKCS#1 padding too short");
390 hash_len
= from_len
- i
;
391 rec_hash
= calloc(1, hash_len
);
395 memcpy(rec_hash
, from
+ i
, hash_len
);
403 unsigned char *crypto_decrypt_signature(crypto_ctx
*ctx
,
404 const unsigned char *sig_data
,
407 unsigned int padding
,
408 crypto_error
**error
)
410 unsigned char *buf
= NULL
, *rec_hash
= NULL
;
411 gnutls_datum_t n
= { NULL
, 0 }, e
= { NULL
, 0 };
413 gcry_sexp_t key
= NULL
, sig
= NULL
, decrypted
= NULL
, child
= NULL
;
414 gcry_mpi_t n_mpi
= NULL
, e_mpi
= NULL
, sig_mpi
= NULL
, dec_mpi
= NULL
;
415 size_t buf_len
= 0, hash_len
= 0;
418 crypto_error_set(error
, 1, 0, "invalid crypto context");
423 crypto_error_set(error
, 1, 0, "no certificates in the stack");
427 algo
= gnutls_x509_crt_get_pk_algorithm(ctx
->stack
[ctx
->num
- 1], NULL
);
428 if (algo
!= GNUTLS_PK_RSA
) {
429 crypto_error_set(error
, 1, 0, "certificate public key algorithm not RSA");
433 err
= gnutls_x509_crt_get_pk_rsa_raw(ctx
->stack
[ctx
->num
- 1], &n
, &e
);
434 if (err
!= GNUTLS_E_SUCCESS
) {
435 crypto_error_set(error
, 1, 0, "error getting certificate public key");
439 err
= gcry_mpi_scan(&n_mpi
, GCRYMPI_FMT_USG
, n
.data
, n
.size
, NULL
);
441 crypto_error_set(error
, 1, 0, "invalid RSA key 'n' format");
445 err
= gcry_mpi_scan(&e_mpi
, GCRYMPI_FMT_USG
, e
.data
, e
.size
, NULL
);
447 crypto_error_set(error
, 1, 0, "invalid RSA key 'e' format");
451 err
= gcry_sexp_build(&key
, NULL
, "(public-key (rsa (n %m) (e %m)))", n_mpi
, e_mpi
);
453 crypto_error_set(error
, 1, 0, "could not create public-key expression");
457 err
= gcry_mpi_scan(&sig_mpi
, GCRYMPI_FMT_USG
, sig_data
, sig_len
, NULL
);
459 crypto_error_set(error
, 1, 0, "invalid signature format");
463 err
= gcry_sexp_build(&sig
, NULL
, "(data (flags raw) (value %m))", sig_mpi
);
465 crypto_error_set(error
, 1, 0, "could not create signature expression");
469 /* encrypt is equivalent to public key decryption for RSA keys */
470 err
= gcry_pk_encrypt(&decrypted
, sig
, key
);
472 crypto_error_set(error
, 1, 0, "could not decrypt signature");
476 child
= gcry_sexp_find_token(decrypted
, "a", 1);
478 crypto_error_set(error
, 1, 0, "could not get decrypted signature result");
482 dec_mpi
= gcry_sexp_nth_mpi(child
, 1, GCRYMPI_FMT_USG
);
483 gcry_sexp_release(child
);
486 crypto_error_set(error
, 1, 0, "could not get decrypted signature result");
490 gcry_mpi_aprint(GCRYMPI_FMT_USG
, &buf
, &buf_len
, dec_mpi
);
492 crypto_error_set(error
, 1, 0, "could not get extract decrypted signature");
497 case CRYPTO_PAD_NONE
:
501 *out_len
= (int) hash_len
;
503 case CRYPTO_PAD_PKCS1
:
504 rec_hash
= check_pkcs1_padding(buf
, buf_len
, &hash_len
, error
);
506 crypto_error_set(error
, 1, 0, "could not get extract decrypted padded signature");
509 *out_len
= (int) hash_len
;
512 crypto_error_set(error
, 1, 0, "unknown padding mechanism %d", padding
);
520 gcry_mpi_release(dec_mpi
);
522 gcry_sexp_release(decrypted
);
524 gcry_sexp_release(key
);
526 gcry_sexp_release(sig
);
528 gcry_mpi_release(sig_mpi
);
530 gcry_mpi_release(n_mpi
);
532 gcry_mpi_release(e_mpi
);