diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2003-02-09 09:37:35 +0000 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2003-02-09 09:37:35 +0000 |
commit | e25325c312e339bd1a3624de4b877c73960b58c7 (patch) | |
tree | 30c5ab7919ace214d2c4f7e5773538ffdb127cf2 | |
parent | a72c0ee5e22684e8e995e1fc4871fa06e1edc30f (diff) | |
download | gnutls-e25325c312e339bd1a3624de4b877c73960b58c7.tar.gz |
Several internal changes to use the new certificate API. CRL support is complete.
39 files changed, 1225 insertions, 1985 deletions
diff --git a/includes/Makefile.am b/includes/Makefile.am index 41eea42982..bcfa3d8787 100644 --- a/includes/Makefile.am +++ b/includes/Makefile.am @@ -1,7 +1,7 @@ ## Process this file with automake to produce Makefile.in nobase_include_HEADERS = gnutls/extra.h gnutls/openssl.h gnutls/gnutls.h \ - gnutls/compat4.h gnutls/x509.h + gnutls/compat4.h gnutls/x509.h gnutls/compat8.h SUBDIRS = gnutls diff --git a/includes/gnutls/Makefile.am b/includes/gnutls/Makefile.am index 2b7d59d810..c64034e78c 100644 --- a/includes/gnutls/Makefile.am +++ b/includes/gnutls/Makefile.am @@ -1 +1 @@ -EXTRA_DIST = extra.h openssl.h gnutls.h compat4.h x509.h +EXTRA_DIST = extra.h openssl.h gnutls.h compat4.h x509.h compat8.h diff --git a/includes/gnutls/compat8.h b/includes/gnutls/compat8.h new file mode 100644 index 0000000000..9f16664605 --- /dev/null +++ b/includes/gnutls/compat8.h @@ -0,0 +1,20 @@ +int gnutls_x509_extract_dn( const gnutls_datum*, gnutls_x509_dn*); +int gnutls_x509_extract_dn_string(const gnutls_datum * idn, + char *buf, unsigned int sizeof_buf); +int gnutls_x509_extract_certificate_dn( const gnutls_datum*, gnutls_x509_dn*); +int gnutls_x509_extract_certificate_dn_string(char *buf, unsigned int sizeof_buf, + const gnutls_datum * cert, int issuer); +int gnutls_x509_extract_certificate_issuer_dn( const gnutls_datum*, gnutls_x509_dn *); +int gnutls_x509_extract_certificate_version( const gnutls_datum*); +int gnutls_x509_extract_certificate_serial(const gnutls_datum * cert, char* result, int* result_size); +time_t gnutls_x509_extract_certificate_activation_time( const gnutls_datum*); +time_t gnutls_x509_extract_certificate_expiration_time( const gnutls_datum*); +int gnutls_x509_extract_certificate_subject_alt_name( const gnutls_datum*, int seq, char*, int*); +int gnutls_x509_pkcs7_extract_certificate(const gnutls_datum * pkcs7_struct, int indx, char* certificate, int* certificate_size); +int gnutls_x509_extract_certificate_pk_algorithm( const gnutls_datum * cert, int* bits); +int gnutls_x509_extract_certificate_ca_status(const gnutls_datum * cert); +int gnutls_x509_extract_key_pk_algorithm( const gnutls_datum * key); + +int gnutls_x509_verify_certificate( const gnutls_datum* cert_list, int cert_list_length, const gnutls_datum * CA_list, int CA_list_length, const gnutls_datum* CRL_list, int CRL_list_length); +int gnutls_x509_check_certificates_hostname(const gnutls_datum * cert, + const char *hostname); diff --git a/lib/Makefile.am b/lib/Makefile.am index c7fae4a43f..6c359f9808 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -17,8 +17,8 @@ EXTRA_DIST = debug.h gnutls_compress.h defines.h gnutls.asn pkix.asn \ libgnutls-config.in libgnutls.m4 gnutls.h.in.in gnutls_errors_int.h \ gnutls-api.tex gnutls_datum.h auth_cert.h gnutls_mpi.h \ gnutls_pk.h gnutls_record.h gnutls_cert.h \ - gnutls_privkey.h gnutls_constate.h gnutls_global.h x509_verify.h \ - gnutls_sig.h gnutls_mem.h x509_extensions.h gnutls_ui.h \ + gnutls_privkey.h gnutls_constate.h gnutls_global.h \ + gnutls_sig.h gnutls_mem.h gnutls_ui.h \ io_debug.h ext_max_record.h gnutls_session_pack.h \ gnutls_alert.h gnutls_str.h gnutls_state.h gnutls_x509.h \ ext_cert_type.h gnutls_rsa_export.h ext_server_name.h auth_dh_common.h \ @@ -33,10 +33,10 @@ COBJECTS = gnutls_record.c gnutls_compress.c debug.c \ gnutls_compress_int.c gnutls_session.c gnutls_db.c x509_b64.c \ auth_anon.c gnutls_extensions.c gnutls_auth.c gnutls_random.c \ gnutls_v2_compat.c gnutls_datum.c auth_rsa.c gnutls_session_pack.c \ - gnutls_mpi.c gnutls_pk.c gnutls_cert.c x509_verify.c\ + gnutls_mpi.c gnutls_pk.c gnutls_cert.c \ gnutls_global.c gnutls_privkey.c gnutls_constate.c gnutls_anon_cred.c \ - x509_sig_check.c pkix_asn1_tab.c gnutls_asn1_tab.c gnutls_mem.c \ - x509_extensions.c auth_cert.c gnutls_ui.c gnutls_sig.c auth_dhe.c \ + pkix_asn1_tab.c gnutls_asn1_tab.c gnutls_mem.c \ + auth_cert.c gnutls_ui.c gnutls_sig.c auth_dhe.c \ gnutls_dh_primes.c ext_max_record.c gnutls_alert.c gnutls_int_compat.c \ gnutls_str.c gnutls_state.c gnutls_x509.c ext_cert_type.c \ gnutls_rsa_export.c auth_rsa_export.c \ diff --git a/lib/auth_cert.c b/lib/auth_cert.c index 82edbdcc9a..a8c4c80328 100644 --- a/lib/auth_cert.c +++ b/lib/auth_cert.c @@ -37,9 +37,7 @@ #include <gnutls_algorithms.h> #include <gnutls_global.h> #include <gnutls_record.h> -#include <x509_verify.h> #include <gnutls_sig.h> -#include <x509_extensions.h> #include <gnutls_state.h> #include <gnutls_pk.h> #include <gnutls_x509.h> @@ -47,7 +45,8 @@ #include "debug.h" static int _gnutls_server_find_cert_list_index(gnutls_session session, - gnutls_pk_algorithm requested_algo); + gnutls_pk_algorithm + requested_algo); /* Copies data from a internal certificate struct (gnutls_cert) to * exported certificate struct (CERTIFICATE_AUTH_INFO) @@ -77,9 +76,9 @@ int _gnutls_copy_certificate_auth_info(CERTIFICATE_AUTH_INFO info, if (cert->raw.size > 0) { ret = _gnutls_set_datum(&info-> - raw_certificate_list[i], - cert[i].raw.data, - cert[i].raw.size); + raw_certificate_list[i], + cert[i].raw.data, + cert[i].raw.size); if (ret < 0) { gnutls_assert(); goto clear; @@ -102,58 +101,16 @@ int _gnutls_copy_certificate_auth_info(CERTIFICATE_AUTH_INFO info, } -/* Returns the issuer's Distinguished name in odn, of the certificate - * specified in cert. - */ -int _gnutls_find_dn(gnutls_datum * odn, gnutls_cert * cert) -{ - ASN1_TYPE dn; - int len, result; - int start, end; - - if ((result=_gnutls_asn1_create_element - (_gnutls_get_pkix(), "PKIX1.Certificate", &dn, - "dn")) != ASN1_SUCCESS) { - gnutls_assert(); - return _gnutls_asn2err(result); - } - - result = asn1_der_decoding(&dn, cert->raw.data, cert->raw.size, NULL); - if (result != ASN1_SUCCESS) { - /* couldn't decode DER */ - gnutls_assert(); - asn1_delete_structure(&dn); - return _gnutls_asn2err(result); - } - - result = asn1_der_decoding_startEnd(dn, cert->raw.data, cert->raw.size, - "dn.tbsCertificate.issuer", &start, - &end); - - if (result != ASN1_SUCCESS) { - /* couldn't decode DER */ - gnutls_assert(); - asn1_delete_structure(&dn); - return _gnutls_asn2err(result); - } - asn1_delete_structure(&dn); - - len = end - start + 1; - - odn->size = len; - odn->data = &cert->raw.data[start]; - - return 0; -} /* returns 0 if the algo_to-check exists in the pk_algos list, * -1 otherwise. */ inline - static int _gnutls_check_pk_algo_in_list(gnutls_pk_algorithm * pk_algos, - int pk_algos_length, - gnutls_pk_algorithm algo_to_check) + static int _gnutls_check_pk_algo_in_list(gnutls_pk_algorithm * + pk_algos, int pk_algos_length, + gnutls_pk_algorithm + algo_to_check) { int i; for (i = 0; i < pk_algos_length; i++) { @@ -164,20 +121,22 @@ inline return -1; } + + /* Locates the most appropriate x509 certificate using the * given DN. If indx == -1 then no certificate was found. */ static int _find_x509_cert(const gnutls_certificate_credentials cred, opaque * _data, size_t _data_size, - gnutls_pk_algorithm * pk_algos, int pk_algos_length, - int *indx) + gnutls_pk_algorithm * pk_algos, + int pk_algos_length, int *indx) { uint size; gnutls_datum odn; opaque *data = _data; ssize_t data_size = _data_size; uint i, j; - int result; + int result, cert_pk; *indx = -1; @@ -191,9 +150,7 @@ static int _find_x509_cert(const gnutls_certificate_credentials cred, for (i = 0; i < cred->ncerts; i++) { for (j = 0; j < cred->cert_list_length[i]; j++) { if ((result = - _gnutls_find_dn(&odn, - &cred->cert_list[i] - [j])) < 0) { + _gnutls_cert_get_dn( &cred->cert_list[i][j], &odn)) < 0) { gnutls_assert(); return result; } @@ -205,14 +162,10 @@ static int _find_x509_cert(const gnutls_certificate_credentials cred, * the *_SIGN algorithm matches * the cert is our cert! */ - if ((memcmp(odn.data, - data, size) == 0) && - (_gnutls_check_pk_algo_in_list - (pk_algos, pk_algos_length, - cred->cert_list[i][0]. - subject_pk_algorithm) == 0) - && (cred->cert_list[i][0].cert_type == - GNUTLS_CRT_X509)) { + cert_pk = cred->cert_list[i][0].subject_pk_algorithm; + + if ((memcmp(odn.data, data, size) == 0) && + (_gnutls_check_pk_algo_in_list(pk_algos, pk_algos_length, cert_pk) == 0)) { *indx = i; break; } @@ -236,8 +189,8 @@ static int _find_x509_cert(const gnutls_certificate_credentials cred, /* Locates the most appropriate openpgp cert */ static int _find_openpgp_cert(const gnutls_certificate_credentials cred, - gnutls_pk_algorithm * pk_algos, int pk_algos_length, - int *indx) + gnutls_pk_algorithm * pk_algos, + int pk_algos_length, int *indx) { uint i, j; @@ -276,7 +229,8 @@ static int _find_openpgp_cert(const gnutls_certificate_credentials cred, static int _gnutls_find_acceptable_client_cert(gnutls_session session, opaque * _data, size_t _data_size, int *ind, - gnutls_pk_algorithm * pk_algos, + gnutls_pk_algorithm * + pk_algos, int pk_algos_length) { int result, size; @@ -288,8 +242,7 @@ static int _gnutls_find_acceptable_client_cert(gnutls_session session, ssize_t data_size = _data_size; cred = - _gnutls_get_cred(session->key, GNUTLS_CRD_CERTIFICATE, - NULL); + _gnutls_get_cred(session->key, GNUTLS_CRD_CERTIFICATE, NULL); if (cred == NULL) { gnutls_assert(); return GNUTLS_E_INSUFICIENT_CREDENTIALS; @@ -302,8 +255,8 @@ static int _gnutls_find_acceptable_client_cert(gnutls_session session, */ try = session->internals.client_cert_callback(session, - NULL, 0, - NULL, 0); + NULL, 0, + NULL, 0); } @@ -337,7 +290,7 @@ static int _gnutls_find_acceptable_client_cert(gnutls_session session, gnutls_datum *my_certs = NULL; gnutls_datum *issuers_dn = NULL; uint issuers_dn_len = 0; - opaque* dataptr = data; + opaque *dataptr = data; ssize_t dataptr_size = data_size; /* Count the number of the given issuers; @@ -346,10 +299,10 @@ static int _gnutls_find_acceptable_client_cert(gnutls_session session, */ do { /* This works like DECR_LEN() */ - DECR_LENGTH_COM( dataptr_size, 2, goto clear); + DECR_LENGTH_COM(dataptr_size, 2, goto clear); size = _gnutls_read_uint16(data); - DECR_LENGTH_COM( dataptr_size, size, goto clear); + DECR_LENGTH_COM(dataptr_size, size, goto clear); dataptr += 2; @@ -357,7 +310,7 @@ static int _gnutls_find_acceptable_client_cert(gnutls_session session, issuers_dn_len++; dataptr += size; } - + if (dataptr_size == 0) break; @@ -372,15 +325,18 @@ static int _gnutls_find_acceptable_client_cert(gnutls_session session, /* put the requested DNs to req_dn, only in case * of X509 certificates. */ - if (gnutls_certificate_type_get(session) == GNUTLS_CRT_X509) { + if (gnutls_certificate_type_get(session) == + GNUTLS_CRT_X509) { data = _data; data_size = _data_size; - issuers_dn = gnutls_alloca( issuers_dn_len * sizeof(gnutls_datum)); + issuers_dn = + gnutls_alloca(issuers_dn_len * + sizeof(gnutls_datum)); if (issuers_dn == NULL) goto clear; - for (i=0;i<issuers_dn_len;i++) { + for (i = 0; i < issuers_dn_len; i++) { /* The checks here for the buffer boundaries * are not needed since the buffer has been * parsed above. @@ -405,7 +361,7 @@ static int _gnutls_find_acceptable_client_cert(gnutls_session session, /* maps j -> i */ ij_map = gnutls_alloca(sizeof(int) * cred->ncerts); - if (ij_map==NULL) { + if (ij_map == NULL) { gnutls_assert(); goto clear; } @@ -435,10 +391,10 @@ static int _gnutls_find_acceptable_client_cert(gnutls_session session, indx = session->internals.client_cert_callback(session, - my_certs, - j, - issuers_dn, - issuers_dn_len); + my_certs, + j, + issuers_dn, + issuers_dn_len); /* the indx returned by the user is relative * to the certificates we provided him. @@ -512,8 +468,7 @@ int _gnutls_gen_x509_certificate(gnutls_session session, opaque ** data) enum PGPKeyDescriptorType { PGP_KEY_FINGERPRINT, PGP_KEY }; -int _gnutls_gen_openpgp_certificate(gnutls_session session, - opaque ** data) +int _gnutls_gen_openpgp_certificate(gnutls_session session, opaque ** data) { int ret; opaque *pdata; @@ -563,7 +518,7 @@ OPENPGP_KEY_REQUEST _E_gnutls_openpgp_request_key = NULL; extern OPENPGP_CERT2GNUTLS_CERT _E_gnutls_openpgp_cert2gnutls_cert; int _gnutls_gen_openpgp_certificate_fpr(gnutls_session session, - opaque ** data) + opaque ** data) { int ret, fpr_size, packet_size; opaque *pdata; @@ -608,12 +563,14 @@ int _gnutls_gen_openpgp_certificate_fpr(gnutls_session session, fpr_size = 20; - if (_E_gnutls_openpgp_fingerprint==NULL) { + if (_E_gnutls_openpgp_fingerprint == NULL) { gnutls_assert(); return GNUTLS_E_INIT_LIBEXTRA; } - if ( (ret=_E_gnutls_openpgp_fingerprint( &apr_cert_list[0].raw, pdata, &fpr_size)) < 0) { + if ((ret = + _E_gnutls_openpgp_fingerprint(&apr_cert_list[0].raw, pdata, + &fpr_size)) < 0) { gnutls_assert(); return ret; } @@ -623,14 +580,14 @@ int _gnutls_gen_openpgp_certificate_fpr(gnutls_session session, -int _gnutls_gen_cert_client_certificate(gnutls_session session, opaque ** data) +int _gnutls_gen_cert_client_certificate(gnutls_session session, + opaque ** data) { switch (session->security_parameters.cert_type) { case GNUTLS_CRT_OPENPGP: if (_gnutls_openpgp_send_fingerprint(session) == 0) return - _gnutls_gen_openpgp_certificate(session, - data); + _gnutls_gen_openpgp_certificate(session, data); else return _gnutls_gen_openpgp_certificate_fpr @@ -645,7 +602,8 @@ int _gnutls_gen_cert_client_certificate(gnutls_session session, opaque ** data) } } -int _gnutls_gen_cert_server_certificate(gnutls_session session, opaque ** data) +int _gnutls_gen_cert_server_certificate(gnutls_session session, + opaque ** data) { switch (session->security_parameters.cert_type) { case GNUTLS_CRT_OPENPGP: @@ -661,9 +619,9 @@ int _gnutls_gen_cert_server_certificate(gnutls_session session, opaque ** data) /* Process server certificate */ -#define CLEAR_CERTS for(x=0;x<peer_certificate_list_size;x++) _gnutls_free_cert(peer_certificate_list[x]) -int _gnutls_proc_x509_server_certificate(gnutls_session session, opaque * data, - size_t data_size) +#define CLEAR_CERTS for(x=0;x<peer_certificate_list_size;x++) _gnutls_free_cert(&peer_certificate_list[x]) +int _gnutls_proc_x509_server_certificate(gnutls_session session, + opaque * data, size_t data_size) { int size, len, ret; opaque *p = data; @@ -676,8 +634,7 @@ int _gnutls_proc_x509_server_certificate(gnutls_session session, opaque * data, gnutls_datum tmp; cred = - _gnutls_get_cred(session->key, GNUTLS_CRD_CERTIFICATE, - NULL); + _gnutls_get_cred(session->key, GNUTLS_CRD_CERTIFICATE, NULL); if (cred == NULL) { gnutls_assert(); return GNUTLS_E_INSUFICIENT_CREDENTIALS; @@ -711,7 +668,7 @@ int _gnutls_proc_x509_server_certificate(gnutls_session session, opaque * data, } i = dsize; - while(i > 0) { + while (i > 0) { DECR_LEN(dsize, 3); len = _gnutls_read_uint24(p); p += 3; @@ -731,15 +688,15 @@ int _gnutls_proc_x509_server_certificate(gnutls_session session, opaque * data, */ peer_certificate_list = - gnutls_alloca( sizeof(gnutls_cert) * + gnutls_alloca(sizeof(gnutls_cert) * (peer_certificate_list_size)); if (peer_certificate_list == NULL) { gnutls_assert(); return GNUTLS_E_MEMORY_ERROR; } - memset( peer_certificate_list, 0, sizeof(gnutls_cert)* - peer_certificate_list_size); + memset(peer_certificate_list, 0, sizeof(gnutls_cert) * + peer_certificate_list_size); p = data + 3; @@ -748,7 +705,7 @@ int _gnutls_proc_x509_server_certificate(gnutls_session session, opaque * data, * been parsed before. */ - for (j=0;j<peer_certificate_list_size;j++) { + for (j = 0; j < peer_certificate_list_size; j++) { len = _gnutls_read_uint24(p); p += 3; @@ -757,7 +714,9 @@ int _gnutls_proc_x509_server_certificate(gnutls_session session, opaque * data, if ((ret = _gnutls_x509_cert2gnutls_cert(&peer_certificate_list - [j], tmp, CERT_ONLY_EXTENSIONS)) < 0) { + [j], &tmp, + CERT_ONLY_EXTENSIONS)) < + 0) { gnutls_assert(); CLEAR_CERTS; gnutls_afree(peer_certificate_list); @@ -780,7 +739,7 @@ int _gnutls_proc_x509_server_certificate(gnutls_session session, opaque * data, } if ((ret = - _gnutls_check_x509_key_usage(&peer_certificate_list[0], + _gnutls_check_key_usage(&peer_certificate_list[0], gnutls_kx_get(session))) < 0) { gnutls_assert(); @@ -795,9 +754,10 @@ int _gnutls_proc_x509_server_certificate(gnutls_session session, opaque * data, return 0; } -#define CLEAR_CERTS for(x=0;x<peer_certificate_list_size;x++) _gnutls_free_cert(peer_certificate_list[x]) +#define CLEAR_CERTS for(x=0;x<peer_certificate_list_size;x++) _gnutls_free_cert(&peer_certificate_list[x]) int _gnutls_proc_openpgp_server_certificate(gnutls_session session, - opaque * data, size_t data_size) + opaque * data, + size_t data_size) { int size, ret, len; opaque *p = data; @@ -810,8 +770,7 @@ int _gnutls_proc_openpgp_server_certificate(gnutls_session session, gnutls_datum tmp, akey = { NULL, 0 }; cred = - _gnutls_get_cred(session->key, GNUTLS_CRD_CERTIFICATE, - NULL); + _gnutls_get_cred(session->key, GNUTLS_CRD_CERTIFICATE, NULL); if (cred == NULL) { gnutls_assert(); return GNUTLS_E_INSUFICIENT_CREDENTIALS; @@ -845,35 +804,37 @@ int _gnutls_proc_openpgp_server_certificate(gnutls_session session, /* Read PGPKeyDescriptor */ DECR_LEN(dsize, 1); - if (*p == PGP_KEY_FINGERPRINT) { /* the fingerprint */ + if (*p == PGP_KEY_FINGERPRINT) { /* the fingerprint */ p++; - + DECR_LEN(dsize, 1); - len = (uint8) *p; - p++; - + len = (uint8) * p; + p++; + if (len != 20) { gnutls_assert(); return GNUTLS_E_UNIMPLEMENTED_FEATURE; } - - DECR_LEN( dsize, 20); + + DECR_LEN(dsize, 20); /* request the actual key from our database, or * a key server or anything. */ - if (_E_gnutls_openpgp_request_key==NULL) { + if (_E_gnutls_openpgp_request_key == NULL) { gnutls_assert(); return GNUTLS_E_INIT_LIBEXTRA; } - if ( (ret=_E_gnutls_openpgp_request_key( session, &akey, cred, p, 20)) < 0) { + if ((ret = + _E_gnutls_openpgp_request_key(session, &akey, cred, p, + 20)) < 0) { gnutls_assert(); return ret; } tmp = akey; peer_certificate_list_size++; - } else if (*p == PGP_KEY) { /* the whole key */ + } else if (*p == PGP_KEY) { /* the whole key */ p++; @@ -904,38 +865,38 @@ int _gnutls_proc_openpgp_server_certificate(gnutls_session session, if (peer_certificate_list_size == 0) { gnutls_assert(); - _gnutls_free_datum( &akey); + _gnutls_free_datum(&akey); return GNUTLS_E_UNEXPECTED_PACKET_LENGTH; } peer_certificate_list = - gnutls_alloca( sizeof(gnutls_cert) * + gnutls_alloca(sizeof(gnutls_cert) * (peer_certificate_list_size)); - if (peer_certificate_list == NULL) { + if (peer_certificate_list == NULL) { gnutls_assert(); return GNUTLS_E_MEMORY_ERROR; } - memset( peer_certificate_list, 0, sizeof(gnutls_cert)* - peer_certificate_list_size); + memset(peer_certificate_list, 0, sizeof(gnutls_cert) * + peer_certificate_list_size); - if (_E_gnutls_openpgp_cert2gnutls_cert==NULL) { + if (_E_gnutls_openpgp_cert2gnutls_cert == NULL) { gnutls_assert(); - _gnutls_free_datum( &akey); + _gnutls_free_datum(&akey); CLEAR_CERTS; gnutls_afree(peer_certificate_list); return GNUTLS_E_INIT_LIBEXTRA; } - + if ((ret = _E_gnutls_openpgp_cert2gnutls_cert(&peer_certificate_list[0], - tmp)) < 0) { + &tmp)) < 0) { gnutls_assert(); - _gnutls_free_datum( &akey); + _gnutls_free_datum(&akey); CLEAR_CERTS; gnutls_afree(peer_certificate_list); return ret; } - _gnutls_free_datum( &akey); + _gnutls_free_datum(&akey); if ((ret = _gnutls_copy_certificate_auth_info(info, @@ -949,7 +910,7 @@ int _gnutls_proc_openpgp_server_certificate(gnutls_session session, } if ((ret = - _gnutls_check_x509_key_usage(&peer_certificate_list[0], + _gnutls_check_key_usage(&peer_certificate_list[0], gnutls_kx_get(session))) < 0) { gnutls_assert(); @@ -964,12 +925,13 @@ int _gnutls_proc_openpgp_server_certificate(gnutls_session session, return 0; } -int _gnutls_proc_cert_server_certificate(gnutls_session session, opaque * data, - size_t data_size) +int _gnutls_proc_cert_server_certificate(gnutls_session session, + opaque * data, size_t data_size) { switch (session->security_parameters.cert_type) { case GNUTLS_CRT_OPENPGP: - return _gnutls_proc_openpgp_server_certificate(session, data, + return _gnutls_proc_openpgp_server_certificate(session, + data, data_size); case GNUTLS_CRT_X509: return _gnutls_proc_x509_server_certificate(session, data, @@ -1014,8 +976,7 @@ int _gnutls_proc_cert_cert_req(gnutls_session session, opaque * data, int pk_algos_length; cred = - _gnutls_get_cred(session->key, GNUTLS_CRD_CERTIFICATE, - NULL); + _gnutls_get_cred(session->key, GNUTLS_CRD_CERTIFICATE, NULL); if (cred == NULL) { gnutls_assert(); return GNUTLS_E_INSUFICIENT_CREDENTIALS; @@ -1083,7 +1044,8 @@ int _gnutls_proc_cert_cert_req(gnutls_session session, opaque * data, return 0; } -int _gnutls_gen_cert_client_cert_vrfy(gnutls_session session, opaque ** data) +int _gnutls_gen_cert_client_cert_vrfy(gnutls_session session, + opaque ** data) { int ret; gnutls_cert *apr_cert_list; @@ -1131,8 +1093,8 @@ int _gnutls_gen_cert_client_cert_vrfy(gnutls_session session, opaque ** data) return size + 2; } -int _gnutls_proc_cert_client_cert_vrfy(gnutls_session session, opaque * data, - size_t data_size) +int _gnutls_proc_cert_client_cert_vrfy(gnutls_session session, + opaque * data, size_t data_size) { int size, ret; ssize_t dsize = data_size; @@ -1160,19 +1122,20 @@ int _gnutls_proc_cert_client_cert_vrfy(gnutls_session session, opaque * data, case GNUTLS_CRT_X509: ret = _gnutls_x509_cert2gnutls_cert(&peer_cert, - info-> - raw_certificate_list[0], CERT_NO_COPY); + &info-> + raw_certificate_list[0], + CERT_NO_COPY); break; case GNUTLS_CRT_OPENPGP: - if (_E_gnutls_openpgp_cert2gnutls_cert==NULL) { + if (_E_gnutls_openpgp_cert2gnutls_cert == NULL) { gnutls_assert(); return GNUTLS_E_INIT_LIBEXTRA; } ret = _E_gnutls_openpgp_cert2gnutls_cert(&peer_cert, - info-> - raw_certificate_list - [0]); + &info-> + raw_certificate_list + [0]); break; default: gnutls_assert(); @@ -1187,16 +1150,17 @@ int _gnutls_proc_cert_client_cert_vrfy(gnutls_session session, opaque * data, if ((ret = _gnutls_verify_sig_hdata(session, &peer_cert, &sig)) < 0) { gnutls_assert(); - _gnutls_free_cert(peer_cert); + _gnutls_free_cert(&peer_cert); return ret; } - _gnutls_free_cert(peer_cert); + _gnutls_free_cert(&peer_cert); return 0; } #define CERTTYPE_SIZE 3 -int _gnutls_gen_cert_server_cert_req(gnutls_session session, opaque ** data) +int _gnutls_gen_cert_server_cert_req(gnutls_session session, + opaque ** data) { const gnutls_certificate_credentials cred; int size; @@ -1208,8 +1172,7 @@ int _gnutls_gen_cert_server_cert_req(gnutls_session session, opaque ** data) */ cred = - _gnutls_get_cred(session->key, GNUTLS_CRD_CERTIFICATE, - NULL); + _gnutls_get_cred(session->key, GNUTLS_CRD_CERTIFICATE, NULL); if (cred == NULL) { gnutls_assert(); return GNUTLS_E_INSUFICIENT_CREDENTIALS; @@ -1247,16 +1210,15 @@ int _gnutls_gen_cert_server_cert_req(gnutls_session session, opaque ** data) /* This function will return the appropriate certificate to use. The return * value depends on the side (client or server). */ -int _gnutls_find_apr_cert(gnutls_session session, gnutls_cert ** apr_cert_list, +int _gnutls_find_apr_cert(gnutls_session session, + gnutls_cert ** apr_cert_list, int *apr_cert_list_length, gnutls_private_key ** apr_pkey) { const gnutls_certificate_credentials cred; int ind; - cred = - _gnutls_get_kx_cred(session, GNUTLS_CRD_CERTIFICATE, - NULL); + cred = _gnutls_get_kx_cred(session, GNUTLS_CRD_CERTIFICATE, NULL); if (cred == NULL) { gnutls_assert(); @@ -1327,20 +1289,19 @@ int _gnutls_find_apr_cert(gnutls_session session, gnutls_cert ** apr_cert_list, * (frontend to _gnutls_server_find_cert_index()) */ const gnutls_cert *_gnutls_server_find_cert(gnutls_session session, - gnutls_pk_algorithm requested_algo) + gnutls_pk_algorithm + requested_algo) { int i; const gnutls_certificate_credentials x509_cred; x509_cred = - _gnutls_get_cred(session->key, GNUTLS_CRD_CERTIFICATE, - NULL); + _gnutls_get_cred(session->key, GNUTLS_CRD_CERTIFICATE, NULL); if (x509_cred == NULL) return NULL; - i = _gnutls_server_find_cert_list_index(session, - requested_algo); + i = _gnutls_server_find_cert_list_index(session, requested_algo); if (i < 0) return NULL; @@ -1355,7 +1316,8 @@ const gnutls_cert *_gnutls_server_find_cert(gnutls_session session, * or -1 for any). */ static int _gnutls_server_find_cert_list_index(gnutls_session session, - gnutls_pk_algorithm requested_algo) + gnutls_pk_algorithm + requested_algo) { uint i, j; int index = -1; @@ -1364,8 +1326,7 @@ static int _gnutls_server_find_cert_list_index(gnutls_session session, int *ij_map = NULL; cred = - _gnutls_get_cred(session->key, GNUTLS_CRD_CERTIFICATE, - NULL); + _gnutls_get_cred(session->key, GNUTLS_CRD_CERTIFICATE, NULL); if (cred == NULL) { gnutls_assert(); return GNUTLS_E_INSUFICIENT_CREDENTIALS; @@ -1375,7 +1336,7 @@ static int _gnutls_server_find_cert_list_index(gnutls_session session, for (i = 0; i < cred->ncerts; i++) { /* find one compatible certificate */ - if (requested_algo == (gnutls_pk_algorithm)-1 || + if (requested_algo == (gnutls_pk_algorithm) - 1 || requested_algo == cred->cert_list[i][0].subject_pk_algorithm) { /* if cert type matches */ @@ -1404,12 +1365,13 @@ static int _gnutls_server_find_cert_list_index(gnutls_session session, j = 0; for (i = 0; i < cred->ncerts; i++) { /* Add compatible certificates */ - if (requested_algo == (gnutls_pk_algorithm)-1 || + if (requested_algo == (gnutls_pk_algorithm) - 1 || requested_algo == cred->cert_list[i][0].subject_pk_algorithm) { /* if cert type matches */ - if (session->security_parameters.cert_type == + if (session->security_parameters. + cert_type == cred->cert_list[i][0].cert_type) { ij_map[j] = i; @@ -1422,8 +1384,8 @@ static int _gnutls_server_find_cert_list_index(gnutls_session session, index = session->internals.server_cert_callback(session, - my_certs, - my_certs_length); + my_certs, + my_certs_length); index = ij_map[index]; diff --git a/lib/auth_cert.h b/lib/auth_cert.h index 347cb95c1d..909c0e8d6a 100644 --- a/lib/auth_cert.h +++ b/lib/auth_cert.h @@ -2,6 +2,7 @@ # define AUTH_X509_H # include "gnutls_cert.h" # include "gnutls_auth.h" +# include "x509/x509.h" /* This structure may be complex but, it's the only way to * support a server that has multiple certificates @@ -20,7 +21,7 @@ typedef struct { /* contains the number of the certificates in a * row (should be 1 for OpenPGP keys). */ - uint ncerts; /* contains the number of columns in cert_list. + uint ncerts;/* contains the number of columns in cert_list. * This is the same with the number of pkeys. */ @@ -40,10 +41,14 @@ typedef struct { /* X509 specific stuff */ - gnutls_cert * x509_ca_list; + gnutls_x509_certificate * x509_ca_list; uint x509_ncas; /* number of CAs in the ca_list */ + gnutls_x509_crl * x509_crl_list; + uint x509_ncrls;/* number of CRLs in the crl_list + */ + /* holds a sequence of the * RDNs of the CAs above. * This is better than @@ -81,8 +86,7 @@ int _gnutls_proc_cert_cert_req(gnutls_session, opaque *, size_t); int _gnutls_proc_cert_client_cert_vrfy(gnutls_session, opaque *, size_t); int _gnutls_proc_cert_server_certificate(gnutls_session, opaque *, size_t); int _gnutls_find_apr_cert( gnutls_session session, gnutls_cert** apr_cert_list, int *apr_cert_list_length, gnutls_private_key** apr_pkey); -int _gnutls_find_dn( gnutls_datum* odn, gnutls_cert* cert); -const gnutls_cert* _gnutls_server_find_cert( struct gnutls_session_int*, gnutls_pk_algorithm); +const gnutls_cert * _gnutls_server_find_cert( struct gnutls_session_int*, gnutls_pk_algorithm); #define _gnutls_proc_cert_client_certificate _gnutls_proc_cert_server_certificate diff --git a/lib/auth_dhe.c b/lib/auth_dhe.c index 0d476da51f..887cf27fe9 100644 --- a/lib/auth_dhe.c +++ b/lib/auth_dhe.c @@ -95,7 +95,6 @@ static int gen_dhe_server_kx(gnutls_session session, opaque ** data) } bits = _gnutls_dh_get_prime_bits( session); -fprintf(stderr, "bits: %d\n", bits); /* find the appropriate certificate */ if ((ret = @@ -210,7 +209,7 @@ static int proc_dhe_server_kx(gnutls_session session, opaque * data, case GNUTLS_CRT_X509: if ((ret = _gnutls_x509_cert2gnutls_cert( &peer_cert, - info->raw_certificate_list[0], CERT_NO_COPY)) < 0) { + &info->raw_certificate_list[0], CERT_NO_COPY)) < 0) { gnutls_assert(); return ret; } @@ -223,7 +222,7 @@ static int proc_dhe_server_kx(gnutls_session session, opaque * data, } if ((ret = _E_gnutls_openpgp_cert2gnutls_cert( &peer_cert, - info->raw_certificate_list[0])) < 0) { + &info->raw_certificate_list[0])) < 0) { gnutls_assert(); return ret; } @@ -239,7 +238,7 @@ static int proc_dhe_server_kx(gnutls_session session, opaque * data, &peer_cert, &vparams, &signature); - _gnutls_free_cert( peer_cert); + _gnutls_free_cert( &peer_cert); if (ret < 0) { gnutls_assert(); return ret; diff --git a/lib/auth_rsa.c b/lib/auth_rsa.c index 82755e8a72..999154cfeb 100644 --- a/lib/auth_rsa.c +++ b/lib/auth_rsa.c @@ -35,7 +35,6 @@ #include <gnutls_pk.h> #include <gnutls_algorithms.h> #include <gnutls_global.h> -#include <x509_verify.h> #include "debug.h" #include <gnutls_sig.h> #include <gnutls_x509.h> @@ -86,7 +85,7 @@ int i; case GNUTLS_CRT_X509: if ((ret = _gnutls_x509_cert2gnutls_cert( &peer_cert, - info->raw_certificate_list[0], CERT_ONLY_PUBKEY|CERT_NO_COPY)) < 0) { + &info->raw_certificate_list[0], CERT_ONLY_PUBKEY|CERT_NO_COPY)) < 0) { gnutls_assert(); return ret; } @@ -99,7 +98,7 @@ int i; } if ((ret = _E_gnutls_openpgp_cert2gnutls_cert( &peer_cert, - info->raw_certificate_list[0])) < 0) { + &info->raw_certificate_list[0])) < 0) { gnutls_assert(); return ret; } @@ -116,7 +115,7 @@ int i; == GNUTLS_KX_RSA_EXPORT && _gnutls_mpi_get_nbits(peer_cert.params[0]) > 512) { - _gnutls_free_cert( peer_cert); + _gnutls_free_cert( &peer_cert); if (session->key->rsa[0] == NULL || session->key->rsa[1] == NULL) { @@ -147,7 +146,7 @@ int i; for (i=0;i<*params_len;i++) { params[i] = _gnutls_mpi_copy(peer_cert.params[i]); } - _gnutls_free_cert( peer_cert); + _gnutls_free_cert( &peer_cert); return 0; } diff --git a/lib/auth_rsa_export.c b/lib/auth_rsa_export.c index e251d1dea8..2d54662b55 100644 --- a/lib/auth_rsa_export.c +++ b/lib/auth_rsa_export.c @@ -35,7 +35,6 @@ #include <gnutls_pk.h> #include <gnutls_algorithms.h> #include <gnutls_global.h> -#include <x509_verify.h> #include "debug.h" #include <gnutls_sig.h> #include <gnutls_x509.h> @@ -194,7 +193,7 @@ CERTIFICATE_AUTH_INFO info = _gnutls_get_auth_info( session); case GNUTLS_CRT_X509: if ((ret = _gnutls_x509_cert2gnutls_cert( &peer_cert, - info->raw_certificate_list[0], CERT_NO_COPY)) < 0) { + &info->raw_certificate_list[0], CERT_NO_COPY)) < 0) { gnutls_assert(); return 0; } @@ -207,7 +206,7 @@ CERTIFICATE_AUTH_INFO info = _gnutls_get_auth_info( session); } if ((ret = _E_gnutls_openpgp_cert2gnutls_cert( &peer_cert, - info->raw_certificate_list[0])) < 0) { + &info->raw_certificate_list[0])) < 0) { gnutls_assert(); return 0; } @@ -225,11 +224,11 @@ CERTIFICATE_AUTH_INFO info = _gnutls_get_auth_info( session); if ( _gnutls_mpi_get_nbits( peer_cert.params[0]) <= 512) { - _gnutls_free_cert( peer_cert); + _gnutls_free_cert( &peer_cert); return 1; } - _gnutls_free_cert( peer_cert); + _gnutls_free_cert( &peer_cert); return 0; } @@ -318,7 +317,7 @@ static int proc_rsa_export_server_kx(gnutls_session session, opaque * data, case GNUTLS_CRT_X509: if ((ret = _gnutls_x509_cert2gnutls_cert( &peer_cert, - info->raw_certificate_list[0], CERT_NO_COPY)) < 0) { + &info->raw_certificate_list[0], CERT_NO_COPY)) < 0) { gnutls_assert(); return ret; } @@ -331,7 +330,7 @@ static int proc_rsa_export_server_kx(gnutls_session session, opaque * data, } if ((ret = _E_gnutls_openpgp_cert2gnutls_cert( &peer_cert, - info->raw_certificate_list[0])) < 0) { + &info->raw_certificate_list[0])) < 0) { gnutls_assert(); return ret; } @@ -347,7 +346,7 @@ static int proc_rsa_export_server_kx(gnutls_session session, opaque * data, &peer_cert, &vparams, &signature); - _gnutls_free_cert( peer_cert); + _gnutls_free_cert( &peer_cert); if (ret < 0) { gnutls_assert(); return ret; diff --git a/lib/gnutls.h.in.in b/lib/gnutls.h.in.in index 101d19da68..1b010fce5f 100644 --- a/lib/gnutls.h.in.in +++ b/lib/gnutls.h.in.in @@ -314,6 +314,11 @@ int gnutls_certificate_set_x509_trust_file( gnutls_certificate_credentials res, int gnutls_certificate_set_x509_trust_mem(gnutls_certificate_credentials res, const gnutls_datum *CA, gnutls_x509_certificate_format); +int gnutls_certificate_set_x509_crl_file(gnutls_certificate_credentials res, + const char *crlfile, gnutls_x509_certificate_format type); +int gnutls_certificate_set_x509_crl_mem(gnutls_certificate_credentials res, + const gnutls_datum *CRL, gnutls_x509_certificate_format type); + int gnutls_certificate_set_x509_key_file( gnutls_certificate_credentials res, const char *CERTFILE, const char* KEYFILE, gnutls_x509_certificate_format); int gnutls_certificate_set_x509_key_mem(gnutls_certificate_credentials res, @@ -326,6 +331,7 @@ int gnutls_global_init(void); void gnutls_global_deinit(void); typedef void* (*gnutls_alloc_function)(size_t); +typedef void* (*gnutls_calloc_function)(size_t, size_t); typedef void (*gnutls_free_function)(void*); typedef void* (*gnutls_realloc_function)(void*, size_t); @@ -336,6 +342,7 @@ void gnutls_global_set_mem_functions( /* For use in callbacks */ extern gnutls_alloc_function gnutls_malloc; +extern gnutls_calloc_function gnutls_calloc; extern gnutls_free_function gnutls_free; typedef void (*gnutls_log_func)( const char*); diff --git a/lib/gnutls_cert.c b/lib/gnutls_cert.c index 4eae11b8c2..81233570c8 100644 --- a/lib/gnutls_cert.c +++ b/lib/gnutls_cert.c @@ -31,9 +31,7 @@ #include <gnutls_datum.h> #include <gnutls_mpi.h> #include <gnutls_global.h> -#include <x509_verify.h> #include <gnutls_privkey.h> -#include <x509_extensions.h> #include <gnutls_algorithms.h> #include <gnutls_dh.h> #include <gnutls_str.h> @@ -42,20 +40,9 @@ #include <gnutls_x509.h> #include <gnutls_extra.h> #include "x509/compat.h" +#include "x509/x509.h" +#include "x509/mpi.h" -void _gnutls_free_cert(gnutls_cert cert) -{ - int i; - - for (i = 0; i < cert.params_size; i++) { - _gnutls_mpi_release(&cert.params[i]); - } - - _gnutls_free_datum(&cert.signature); - _gnutls_free_datum(&cert.raw); - - return; -} /** * gnutls_certificate_free_credentials - Used to free an allocated gnutls_certificate_credentials structure @@ -75,7 +62,7 @@ void gnutls_certificate_free_credentials(gnutls_certificate_credentials sc) for (i = 0; i < sc->ncerts; i++) { for (j = 0; j < sc->cert_list_length[i]; j++) { - _gnutls_free_cert(sc->cert_list[i][j]); + _gnutls_free_cert( &sc->cert_list[i][j]); } gnutls_free( sc->cert_list[i]); } @@ -84,7 +71,11 @@ void gnutls_certificate_free_credentials(gnutls_certificate_credentials sc) gnutls_free(sc->cert_list); for (j = 0; j < sc->x509_ncas; j++) { - _gnutls_free_cert( sc->x509_ca_list[j]); + gnutls_x509_certificate_deinit( sc->x509_ca_list[j]); + } + + for (j = 0; j < sc->x509_ncrls; j++) { + gnutls_x509_crl_deinit( sc->x509_crl_list[j]); } gnutls_free( sc->x509_ca_list); @@ -126,7 +117,7 @@ int gnutls_certificate_allocate_credentials(gnutls_certificate_credentials * res * This function also uses the KeyUsage field of the certificate * extensions in order to disable unneded algorithms. */ -int _gnutls_cert_supported_kx(const gnutls_cert * cert, gnutls_kx_algorithm ** alg, +int _gnutls_cert_supported_kx(const gnutls_cert* cert, gnutls_kx_algorithm ** alg, int *alg_size) { gnutls_kx_algorithm kx; @@ -138,16 +129,8 @@ int _gnutls_cert_supported_kx(const gnutls_cert * cert, gnutls_kx_algorithm ** a for (kx = 0; kx < MAX_ALGOS; kx++) { pk = _gnutls_map_pk_get_pk(kx); if (pk == cert->subject_pk_algorithm) { - if (cert->cert_type==GNUTLS_CRT_X509) { - /* then check key usage */ - if (_gnutls_check_x509_key_usage(cert, kx) == 0) { - kxlist[i] = kx; - i++; - } - } else if ( cert->cert_type==GNUTLS_CRT_OPENPGP) { - /* FIXME: something like key usage - * should be added - */ + /* then check key usage */ + if (_gnutls_check_key_usage(cert, kx) == 0) { kxlist[i] = kx; i++; } @@ -457,3 +440,124 @@ time_t gnutls_certificate_activation_time_peers(gnutls_session session) } } + +/* This function will convert a der certificate, to a format + * (structure) that gnutls can understand and use. Actually the + * important thing on this function is that it extracts the + * certificate's (public key) parameters. + * + * The noext flag is used to complete the handshake even if the + * extensions found in the certificate are unsupported and critical. + * The critical extensions will be catched by the verification functions. + */ +int _gnutls_x509_cert2gnutls_cert(gnutls_cert * gcert, const gnutls_datum *derCert, + int flags /* OR of ConvFlags */) +{ + int ret = 0; + gnutls_x509_certificate cert; + + ret = gnutls_x509_certificate_init( &cert); + if ( ret < 0) { + gnutls_assert(); + return ret; + } + + ret = gnutls_x509_certificate_import( cert, derCert, GNUTLS_X509_FMT_DER); + if ( ret < 0) { + gnutls_assert(); + gnutls_x509_certificate_deinit( cert); + return ret; + } + + memset(gcert, 0, sizeof(gnutls_cert)); + gcert->cert_type = GNUTLS_CRT_X509; + + if ( !(flags & CERT_NO_COPY)) { + if (_gnutls_set_datum(&gcert->raw, derCert->data, derCert->size) < 0) { + gnutls_assert(); + gnutls_x509_certificate_deinit( cert); + return GNUTLS_E_MEMORY_ERROR; + } + } else + /* now we have 0 or a bitwise or of things to decode */ + flags ^= CERT_NO_COPY; + + + if (flags & CERT_ONLY_EXTENSIONS || flags == 0) { + gnutls_x509_certificate_get_key_usage( cert, &gcert->keyUsage, NULL); + gcert->version = gnutls_x509_certificate_get_version( cert); + } + gcert->subject_pk_algorithm = gnutls_x509_certificate_get_pk_algorithm( cert, NULL); + + if (flags & CERT_ONLY_PUBKEY || flags == 0) { + gcert->params_size = MAX_PARAMS_SIZE; + ret = _gnutls_x509_certificate_get_mpis( cert, gcert->params, &gcert->params_size); + if (ret < 0) { + gnutls_assert(); + gnutls_x509_certificate_deinit( cert); + return ret; + } + } + + gnutls_x509_certificate_deinit( cert); + + return 0; + +} + +void _gnutls_free_cert(gnutls_cert *cert) +{ + int i; + + for (i = 0; i < cert->params_size; i++) { + _gnutls_mpi_release( &cert->params[i]); + } + + _gnutls_free_datum(&cert->raw); + + return; +} + +/* Returns the issuer's Distinguished name in odn, of the certificate + * specified in cert. + */ +int _gnutls_cert_get_dn(gnutls_cert * cert, gnutls_datum * odn ) +{ + ASN1_TYPE dn; + int len, result; + int start, end; + + if ((result=_gnutls_asn1_create_element + (_gnutls_get_pkix(), "PKIX1.Certificate", &dn, + "dn")) != ASN1_SUCCESS) { + gnutls_assert(); + return _gnutls_asn2err(result); + } + + result = asn1_der_decoding(&dn, cert->raw.data, cert->raw.size, NULL); + if (result != ASN1_SUCCESS) { + /* couldn't decode DER */ + gnutls_assert(); + asn1_delete_structure(&dn); + return _gnutls_asn2err(result); + } + + result = asn1_der_decoding_startEnd(dn, cert->raw.data, cert->raw.size, + "dn.tbsCertificate.issuer", &start, + &end); + + if (result != ASN1_SUCCESS) { + /* couldn't decode DER */ + gnutls_assert(); + asn1_delete_structure(&dn); + return _gnutls_asn2err(result); + } + asn1_delete_structure(&dn); + + len = end - start + 1; + + odn->size = len; + odn->data = &cert->raw.data[start]; + + return 0; +} diff --git a/lib/gnutls_cert.h b/lib/gnutls_cert.h index 5c24545f6c..b792c4b7ef 100644 --- a/lib/gnutls_cert.h +++ b/lib/gnutls_cert.h @@ -4,6 +4,7 @@ #include <gnutls_pk.h> #include <libtasn1.h> #include <gnutls_ui.h> +#include "x509/x509.h" #define MAX_PARAMS_SIZE 6 /* ok for RSA and DSA */ @@ -49,26 +50,16 @@ typedef struct gnutls_cert { gnutls_pk_algorithm subject_pk_algorithm; - gnutls_datum signature; - - time_t expiration_time; - time_t activation_time; - - int version; /* 1,2,3 - */ - - uint16 keyUsage; /* bits from KEY_* - */ - - int CA; /* 0 if the certificate does not belong to - * a certificate authority. 1 otherwise. - */ + unsigned int keyUsage; /* bits from KEY_* + */ + unsigned int version; /* holds the type (PGP, X509) */ gnutls_certificate_type cert_type; - gnutls_datum raw; /* the raw certificate */ + gnutls_datum raw; + } gnutls_cert; typedef struct { @@ -96,8 +87,17 @@ typedef struct { struct gnutls_session_int; /* because gnutls_session is not defined when this file is included */ -int _gnutls_cert_supported_kx( const gnutls_cert* cert, gnutls_kx_algorithm **alg, int *alg_size); +typedef enum ConvFlags { + CERT_NO_COPY=2, + CERT_ONLY_PUBKEY=4, + CERT_ONLY_EXTENSIONS=16 +} ConvFlags; + +int _gnutls_x509_cert2gnutls_cert(gnutls_cert * gcert, const gnutls_datum *derCert, + int flags); +void _gnutls_free_cert(gnutls_cert* cert); +int _gnutls_cert_get_dn(gnutls_cert * cert, gnutls_datum * odn); -void _gnutls_free_cert(gnutls_cert cert); +int _gnutls_cert_supported_kx( const gnutls_cert* cert, gnutls_kx_algorithm **alg, int *alg_size); #endif diff --git a/lib/gnutls_dh_primes.c b/lib/gnutls_dh_primes.c index 5df8231b75..0c11f9c263 100644 --- a/lib/gnutls_dh_primes.c +++ b/lib/gnutls_dh_primes.c @@ -276,7 +276,7 @@ int gnutls_dh_params_generate(gnutls_datum * prime, #ifdef DEBUG { - opaque buffer[128]; + opaque buffer[512]; _gnutls_log ("dh_params_generate: Generated %d bits prime %s, generator %s.\n", diff --git a/lib/gnutls_handshake.c b/lib/gnutls_handshake.c index 54ef95434b..4eff808aa9 100644 --- a/lib/gnutls_handshake.c +++ b/lib/gnutls_handshake.c @@ -2300,7 +2300,7 @@ int _gnutls_remove_unwanted_ciphersuites(gnutls_session session, GNUTLS_CipherSuite *newSuite; int newSuiteSize = 0, i, j, keep; const gnutls_certificate_credentials x509_cred; - const gnutls_cert *cert = NULL; + const gnutls_cert* cert = NULL; gnutls_kx_algorithm *alg; int alg_size; gnutls_kx_algorithm kx; diff --git a/lib/gnutls_rsa_export.c b/lib/gnutls_rsa_export.c index 2ab656e42e..d1049123b5 100644 --- a/lib/gnutls_rsa_export.c +++ b/lib/gnutls_rsa_export.c @@ -433,7 +433,7 @@ int gnutls_rsa_params_generate(gnutls_datum * m, gnutls_datum *e, #ifdef DEBUG { - opaque buffer[128]; + opaque buffer[512]; _gnutls_log("rsa_params_generate: Generated %d bits modulus %s, exponent %s.\n", bits, _gnutls_bin2hex(m->data, m->size, buffer, sizeof(buffer)), diff --git a/lib/gnutls_ui.h b/lib/gnutls_ui.h index e837fed165..aea5f2cbb6 100644 --- a/lib/gnutls_ui.h +++ b/lib/gnutls_ui.h @@ -56,6 +56,8 @@ int gnutls_rsa_export_get_modulus_bits(gnutls_session session); /* X509PKI */ +#include <gnutls/compat8.h> + void gnutls_certificate_client_set_select_function( gnutls_session, gnutls_certificate_client_select_function *); void gnutls_certificate_server_set_select_function( gnutls_session, gnutls_certificate_server_select_function *); @@ -64,28 +66,6 @@ void gnutls_certificate_server_set_request( gnutls_session, gnutls_certificate_r /* X.509 certificate handling functions */ -int gnutls_x509_extract_dn( const gnutls_datum*, gnutls_x509_dn*); -int gnutls_x509_extract_dn_string(const gnutls_datum * idn, - char *buf, unsigned int sizeof_buf); -int gnutls_x509_extract_certificate_dn( const gnutls_datum*, gnutls_x509_dn*); -int gnutls_x509_extract_certificate_dn_string(char *buf, unsigned int sizeof_buf, - const gnutls_datum * cert, int issuer); -int gnutls_x509_extract_certificate_issuer_dn( const gnutls_datum*, gnutls_x509_dn *); -int gnutls_x509_extract_certificate_version( const gnutls_datum*); -int gnutls_x509_extract_certificate_serial(const gnutls_datum * cert, char* result, int* result_size); -time_t gnutls_x509_extract_certificate_activation_time( const gnutls_datum*); -time_t gnutls_x509_extract_certificate_expiration_time( const gnutls_datum*); -int gnutls_x509_extract_certificate_subject_alt_name( const gnutls_datum*, int seq, char*, int*); -int gnutls_x509_pkcs7_extract_certificate(const gnutls_datum * pkcs7_struct, int indx, char* certificate, int* certificate_size); -int gnutls_x509_extract_certificate_pk_algorithm( const gnutls_datum * cert, int* bits); -int gnutls_x509_extract_certificate_ca_status(const gnutls_datum * cert); -int gnutls_x509_extract_key_pk_algorithm( const gnutls_datum * key); - -int gnutls_x509_verify_certificate( const gnutls_datum* cert_list, int cert_list_length, const gnutls_datum * CA_list, int CA_list_length, const gnutls_datum* CRL_list, int CRL_list_length); - -int gnutls_x509_check_certificates_hostname(const gnutls_datum * cert, - const char *hostname); - int gnutls_pkcs3_extract_dh_params(const gnutls_datum * params, gnutls_x509_certificate_format format, gnutls_datum * prime, gnutls_datum * generator, int* prime_bits); diff --git a/lib/gnutls_x509.c b/lib/gnutls_x509.c index feb49b7b36..41ca970935 100644 --- a/lib/gnutls_x509.c +++ b/lib/gnutls_x509.c @@ -33,9 +33,7 @@ #include <gnutls_algorithms.h> #include <gnutls_global.h> #include <gnutls_record.h> -#include <x509_verify.h> #include <gnutls_sig.h> -#include <x509_extensions.h> #include <gnutls_state.h> #include <gnutls_pk.h> #include <gnutls_str.h> @@ -44,38 +42,27 @@ #include <gnutls_privkey.h> #include <gnutls_x509.h> #include "x509/common.h" +#include "x509/x509.h" +#include "x509/verify.h" #include "x509/compat.h" #include "x509/mpi.h" +#include "x509/pkcs7.h" /* * some x509 certificate parsing functions. */ -int _gnutls_x509_get_version(ASN1_TYPE c2, const char *root) -{ - opaque gversion[5]; - char name[1024]; - int len, result; - - _gnutls_str_cpy(name, sizeof(name), root); - _gnutls_str_cat(name, sizeof(name), ".tbsCertificate.version"); - - len = sizeof(gversion) - 1; - if ((result = asn1_read_value(c2, name, gversion, &len)) != ASN1_SUCCESS) { - gnutls_assert(); - return _gnutls_asn2err(result); - } - return (int) gversion[0] + 1; -} - - -#define CLEAR_CERTS for(x=0;x<peer_certificate_list_size;x++) _gnutls_free_cert(peer_certificate_list[x]) +#define CLEAR_CERTS for(x=0;x<peer_certificate_list_size;x++) { \ + if (peer_certificate_list[x]) \ + gnutls_x509_certificate_deinit(peer_certificate_list[x]); \ + } \ + gnutls_free( peer_certificate_list) /*- * _gnutls_x509_cert_verify_peers - This function returns the peer's certificate status * @session: is a gnutls session * - * This function will try to verify the peer's certificate and return it's status (TRUSTED, EXPIRED etc.). + * This function will try to verify the peer's certificate and return it's status (TRUSTED, REVOKED etc.). * The return value (status) should be one of the gnutls_certificate_status enumerated elements. * However you must also check the peer's name in order to check if the verified certificate belongs to the * actual peer. Returns a negative error code in case of an error, or GNUTLS_E_NO_CERTIFICATE_FOUND if no certificate was sent. @@ -85,8 +72,8 @@ int _gnutls_x509_cert_verify_peers(gnutls_session session) { CERTIFICATE_AUTH_INFO info; const gnutls_certificate_credentials cred; - int verify; - gnutls_cert *peer_certificate_list; + unsigned int verify; + gnutls_x509_certificate *peer_certificate_list; int peer_certificate_list_size, i, x, ret; CHECK_AUTH(GNUTLS_CRD_CERTIFICATE, GNUTLS_E_INVALID_REQUEST); @@ -113,160 +100,44 @@ int _gnutls_x509_cert_verify_peers(gnutls_session session) peer_certificate_list = gnutls_calloc(1, peer_certificate_list_size * - sizeof(gnutls_cert)); + sizeof(gnutls_x509_certificate)); if (peer_certificate_list == NULL) { gnutls_assert(); return GNUTLS_E_MEMORY_ERROR; } for (i = 0; i < peer_certificate_list_size; i++) { - if ((ret = - _gnutls_x509_cert2gnutls_cert(&peer_certificate_list[i], - info-> - raw_certificate_list[i], 0)) < - 0) { + ret = gnutls_x509_certificate_init( &peer_certificate_list[i]); + if (ret < 0) { gnutls_assert(); CLEAR_CERTS; - gnutls_free(peer_certificate_list); - return ret; - } - } - - /* Verify certificate - */ - verify = - _gnutls_x509_verify_certificate(peer_certificate_list, - peer_certificate_list_size, - cred->x509_ca_list, cred->x509_ncas, NULL, 0); - - CLEAR_CERTS; - gnutls_free(peer_certificate_list); - - if (verify < 0) { - gnutls_assert(); - return verify; - } - - - return verify; -} - -#define CLEAR_CERTS_CA for(x=0;x<peer_certificate_list_size;x++) _gnutls_free_cert(peer_certificate_list[x]); \ - for(x=0;x<ca_certificate_list_size;x++) _gnutls_free_cert(ca_certificate_list[x]) -/** - * gnutls_x509_verify_certificate - This function verifies given certificate list - * @cert_list: is the certificate list to be verified - * @cert_list_length: holds the number of certificate in cert_list - * @CA_list: is the CA list which will be used in verification - * @CA_list_length: holds the number of CA certificate in CA_list - * @CRL_list: not used - * @CRL_list_length: not used - * - * This function will try to verify the given certificate list and return it's status (TRUSTED, EXPIRED etc.). - * The return value (status) should be one or more of the gnutls_certificate_status - * enumerated elements bitwise or'd. Note that expiration and activation dates are not checked - * by this function, you should check them using the appropriate functions. - * - * This function understands the basicConstraints (2 5 29 19) PKIX extension. - * This means that only a certificate authority can sign a certificate. - * - * However you must also check the peer's name in order to check if the verified certificate belongs to the - * actual peer. - * - * The return value (status) should be one or more of the gnutls_certificate_status - * enumerated elements bitwise or'd. - * - * GNUTLS_CERT_NOT_TRUSTED\: the peer's certificate is not trusted. - * - * GNUTLS_CERT_INVALID\: the certificate chain is broken. - * - * GNUTLS_CERT_REVOKED\: the certificate has been revoked - * (not implemented yet). - * - * GNUTLS_CERT_CORRUPTED\: the certificate is corrupted. - * - * A negative error code is returned in case of an error. - * GNUTLS_E_NO_CERTIFICATE_FOUND is returned to indicate that - * no certificate was sent by the peer. - * - * - **/ -int gnutls_x509_verify_certificate( const gnutls_datum* cert_list, int cert_list_length, const gnutls_datum * CA_list, int CA_list_length, const gnutls_datum* CRL_list, int CRL_list_length) -{ - int verify; - gnutls_cert *peer_certificate_list; - gnutls_cert *ca_certificate_list; - int peer_certificate_list_size, i, x, ret, ca_certificate_list_size; - - if (cert_list == NULL || cert_list_length == 0) - return GNUTLS_E_NO_CERTIFICATE_FOUND; - - /* generate a list of gnutls_certs based on the auth info - * raw certs. - */ - peer_certificate_list_size = cert_list_length; - peer_certificate_list = - gnutls_calloc(1, - peer_certificate_list_size * - sizeof(gnutls_cert)); - if (peer_certificate_list == NULL) { - gnutls_assert(); - return GNUTLS_E_MEMORY_ERROR; - } - - ca_certificate_list_size = CA_list_length; - ca_certificate_list = - gnutls_calloc(1, - ca_certificate_list_size * - sizeof(gnutls_cert)); - if (ca_certificate_list == NULL) { - gnutls_assert(); - gnutls_free( peer_certificate_list); - return GNUTLS_E_MEMORY_ERROR; - } - - /* convert certA_list to gnutls_cert* list - */ - for (i = 0; i < peer_certificate_list_size; i++) { - if ((ret = - _gnutls_x509_cert2gnutls_cert(&peer_certificate_list[i], - cert_list[i], 0)) < 0) { - gnutls_assert(); - CLEAR_CERTS_CA; - gnutls_free( peer_certificate_list); - gnutls_free( ca_certificate_list); return ret; } - } - - /* convert CA_list to gnutls_cert* list - */ - for (i = 0; i < ca_certificate_list_size; i++) { - if ((ret = - _gnutls_x509_cert2gnutls_cert(&ca_certificate_list[i], - CA_list[i], 0)) < 0) { + + ret = + gnutls_x509_certificate_import(peer_certificate_list[i], + &info-> + raw_certificate_list[i], GNUTLS_X509_FMT_DER); + if (ret < 0) { gnutls_assert(); - CLEAR_CERTS_CA; - gnutls_free( peer_certificate_list); - gnutls_free( ca_certificate_list); + CLEAR_CERTS; return ret; } } /* Verify certificate */ - verify = - _gnutls_x509_verify_certificate(peer_certificate_list, + ret = + gnutls_x509_certificate_list_verify(peer_certificate_list, peer_certificate_list_size, - ca_certificate_list, ca_certificate_list_size, NULL, 0); + cred->x509_ca_list, cred->x509_ncas, + cred->x509_crl_list, cred->x509_ncrls, 0, &verify); - CLEAR_CERTS_CA; - gnutls_free( peer_certificate_list); - gnutls_free( ca_certificate_list); + CLEAR_CERTS; - if (verify < 0) { + if (ret < 0) { gnutls_assert(); - return verify; + return ret; } return verify; @@ -279,9 +150,11 @@ int gnutls_x509_verify_certificate( const gnutls_datum* cert_list, int cert_list /* returns error if the certificate has different algorithm than * the given key parameters. */ -static int _gnutls_check_key_cert_match( gnutls_certificate_credentials res) { +static int _gnutls_check_key_cert_match( gnutls_certificate_credentials res) +{ +int pk = res->cert_list[res->ncerts-1][0].subject_pk_algorithm; - if (res->pkey[res->ncerts-1].pk_algorithm != res->cert_list[res->ncerts-1][0].subject_pk_algorithm) { + if (res->pkey[res->ncerts-1].pk_algorithm != (unsigned int)pk) { gnutls_assert(); return GNUTLS_E_CERTIFICATE_KEY_MISMATCH; } @@ -316,32 +189,54 @@ static int parse_der_cert_mem( gnutls_cert** cert_list, int* ncerts, tmp.data = (opaque*)input_cert; tmp.size = input_cert_size; - if ((ret = - _gnutls_x509_cert2gnutls_cert( - &cert_list[0][i - 1], - tmp, 0)) < 0) { + ret = _gnutls_x509_cert2gnutls_cert( + &cert_list[0][i - 1], &tmp, 0); + if ( ret < 0) { gnutls_assert(); return ret; } - + *ncerts = i; return 1; /* one certificate parsed */ } +#define CERT_PEM 1 /* Reads a PKCS7 base64 encoded certificate list from memory and stores it to * a gnutls_cert structure. * returns the number of certificate parsed */ -static int parse_pkcs7_cert_mem( gnutls_cert** cert_list, int* ncerts, - const char *input_cert, int input_cert_size) +static int parse_pkcs7_cert_mem( gnutls_cert** cert_list, int* ncerts, const + char *input_cert, int input_cert_size, int flags) { int i, j, count; gnutls_datum tmp, tmp2; int ret; opaque pcert[MAX_X509_CERT_SIZE]; int pcert_size; + gnutls_pkcs7 pkcs7; + + ret = gnutls_pkcs7_init( &pkcs7); + if (ret < 0) { + gnutls_assert(); + return ret; + } + + if (flags & CERT_PEM) + ret = gnutls_pkcs7_import( pkcs7, &tmp, GNUTLS_X509_FMT_PEM); + else + ret = gnutls_pkcs7_import( pkcs7, &tmp, GNUTLS_X509_FMT_DER); + if (ret < 0) { + /* if we failed to read the structure, + * then just try to decode a plain DER + * certificate. + */ + gnutls_assert(); + gnutls_pkcs7_deinit(pkcs7); + return parse_der_cert_mem( cert_list, ncerts, + input_cert, input_cert_size); + } i = *ncerts + 1; @@ -349,22 +244,19 @@ static int parse_pkcs7_cert_mem( gnutls_cert** cert_list, int* ncerts, tmp.data = (opaque*)input_cert; tmp.size = input_cert_size; - count = gnutls_x509_pkcs7_extract_certificate_count( &tmp); + ret = gnutls_pkcs7_get_certificate_count( pkcs7); - if (count <= 0) { + if (ret < 0) { gnutls_assert(); - /* if we failed to read the count, - * then just try to decode a plain DER - * certificate. - */ - return parse_der_cert_mem( cert_list, ncerts, - input_cert, input_cert_size); + gnutls_pkcs7_deinit(pkcs7); + return ret; } + count = ret; j = count - 1; do { pcert_size = sizeof(pcert); - ret = gnutls_x509_pkcs7_extract_certificate( &tmp, j, pcert, &pcert_size); + ret = gnutls_pkcs7_get_certificate( pkcs7, j, pcert, &pcert_size); j--; /* if the current certificate is too long, just ignore @@ -387,21 +279,23 @@ static int parse_pkcs7_cert_mem( gnutls_cert** cert_list, int* ncerts, tmp2.data = pcert; tmp2.size = pcert_size; - if ((ret = - _gnutls_x509_cert2gnutls_cert( - &cert_list[0][i - 1], - tmp2, 0)) < 0) { + ret = _gnutls_x509_cert2gnutls_cert( + &cert_list[0][i - 1], &tmp2, 0); + + if ( ret < 0) { gnutls_assert(); + gnutls_pkcs7_deinit(pkcs7); return ret; } - + i++; } } while (ret >= 0 && j >= 0); - + *ncerts = i - 1; + gnutls_pkcs7_deinit(pkcs7); return count; } @@ -412,9 +306,9 @@ static int parse_pkcs7_cert_mem( gnutls_cert** cert_list, int* ncerts, static int parse_pem_cert_mem( gnutls_cert** cert_list, int* ncerts, const char *input_cert, int input_cert_size) { - int siz, i, siz2; - opaque *b64; + int siz, siz2, i; const char *ptr; + opaque *ptr2; gnutls_datum tmp; int ret, count; @@ -422,18 +316,9 @@ static int parse_pem_cert_mem( gnutls_cert** cert_list, int* ncerts, { siz = strlen( ptr); - siz2 = _gnutls_fbase64_decode( NULL, ptr, siz, &b64); - - if (siz2 < 0) { - gnutls_assert(); - return GNUTLS_E_BASE64_DECODING_ERROR; - } - - ret = parse_pkcs7_cert_mem( cert_list, ncerts, b64, - siz2); + ret = parse_pkcs7_cert_mem( cert_list, ncerts, ptr, + siz, CERT_PEM); - gnutls_free(b64); - return ret; } @@ -452,7 +337,8 @@ static int parse_pem_cert_mem( gnutls_cert** cert_list, int* ncerts, count = 0; do { - siz2 = _gnutls_fbase64_decode(NULL, ptr, siz, &b64); + + siz2 = _gnutls_fbase64_decode(NULL, ptr, siz, &ptr2); siz -= siz2; if (siz2 < 0) { @@ -467,23 +353,19 @@ static int parse_pem_cert_mem( gnutls_cert** cert_list, int* ncerts, if ( *cert_list == NULL) { gnutls_assert(); - gnutls_free(b64); return GNUTLS_E_MEMORY_ERROR; } - tmp.data = b64; + tmp.data = ptr2; tmp.size = siz2; - if ((ret = - _gnutls_x509_cert2gnutls_cert( - &cert_list[0][i - 1], - tmp, 0)) < 0) { - gnutls_free(b64); + ret = _gnutls_x509_cert2gnutls_cert( + &cert_list[0][i - 1], &tmp, 0); + if ( ret < 0) { gnutls_assert(); return ret; } - gnutls_free(b64); - + /* now we move ptr after the pem header */ ptr++; @@ -506,14 +388,16 @@ static int parse_pem_cert_mem( gnutls_cert** cert_list, int* ncerts, /* Reads a DER or PEM certificate from memory */ -static int read_cert_mem(gnutls_certificate_credentials res, const char *cert, int cert_size, +static +int read_cert_mem(gnutls_certificate_credentials res, const char *cert, int cert_size, gnutls_x509_certificate_format type) { int ret; /* allocate space for the certificate to add */ - res->cert_list = gnutls_realloc_fast( res->cert_list, (1+ res->ncerts)*sizeof(gnutls_cert*)); + res->cert_list = gnutls_realloc_fast( res->cert_list, + (1+ res->ncerts)*sizeof(gnutls_cert*)); if ( res->cert_list==NULL) { gnutls_assert(); return GNUTLS_E_MEMORY_ERROR; @@ -530,8 +414,8 @@ static int read_cert_mem(gnutls_certificate_credentials res, const char *cert, i res->cert_list_length[res->ncerts] = 0; if (type==GNUTLS_X509_FMT_DER) - ret = parse_pkcs7_cert_mem( &res->cert_list[res->ncerts], &res->cert_list_length[res->ncerts], - cert, cert_size); + ret = parse_pkcs7_cert_mem( &res->cert_list[res->ncerts], + &res->cert_list_length[res->ncerts], cert, cert_size, 0); else ret = parse_pem_cert_mem( &res->cert_list[res->ncerts], &res->cert_list_length[res->ncerts], cert, cert_size); @@ -544,21 +428,6 @@ static int read_cert_mem(gnutls_certificate_credentials res, const char *cert, i return ret; } -/* Reads a base64 encoded CA list from memory - * This is to be called once. - */ -static int read_ca_mem(gnutls_certificate_credentials res, const char *ca, int ca_size, - gnutls_x509_certificate_format type) -{ - - if (type==GNUTLS_X509_FMT_DER) - return parse_der_cert_mem( &res->x509_ca_list, &res->x509_ncas, - ca, ca_size); - else - return parse_pem_cert_mem( &res->x509_ca_list, &res->x509_ncas, - ca, ca_size); - -} /* This will check if the given DER key is a PKCS-1 RSA key. @@ -762,29 +631,6 @@ static int read_cert_file(gnutls_certificate_credentials res, const char *certfi } -/* Reads a base64 encoded CA file (file contains multiple certificate - * authorities). This is to be called once. - */ -static int read_ca_file(gnutls_certificate_credentials res, const char *cafile, - gnutls_x509_certificate_format type) -{ - int siz; - char x[MAX_FILE_SIZE]; - FILE *fd1; - - fd1 = fopen(cafile, "rb"); - if (fd1 == NULL) { - gnutls_assert(); - return GNUTLS_E_FILE_ERROR; - } - - siz = fread(x, 1, sizeof(x)-1, fd1); - fclose(fd1); - - x[siz] = 0; - - return read_ca_mem( res, x, siz, type); -} /* Reads PKCS-1 RSA private key file or a DSA file (in the format openssl @@ -897,7 +743,8 @@ int gnutls_certificate_set_x509_key_file(gnutls_certificate_credentials res, con } static int generate_rdn_seq( gnutls_certificate_credentials res) { -gnutls_datum tmp; +gnutls_const_datum tmp; +gnutls_datum _tmp; int ret; uint size, i; opaque *pdata; @@ -915,7 +762,8 @@ opaque *pdata; size = 0; for (i = 0; i < res->x509_ncas; i++) { - if ((ret = _gnutls_find_dn(&tmp, &res->x509_ca_list[i])) < 0) { + if ((ret = _gnutls_x509_certificate_get_raw_issuer_dn( + res->x509_ca_list[i], &tmp)) < 0) { gnutls_assert(); return ret; } @@ -935,20 +783,194 @@ opaque *pdata; pdata = res->x509_rdn_sequence.data; for (i = 0; i < res->x509_ncas; i++) { - if ((ret = _gnutls_find_dn(&tmp, &res->x509_ca_list[i])) < 0) { + if ((ret = _gnutls_x509_certificate_get_raw_issuer_dn( + res->x509_ca_list[i], &tmp)) < 0) { gnutls_free(res->x509_rdn_sequence.data); res->x509_rdn_sequence.size = 0; res->x509_rdn_sequence.data = NULL; gnutls_assert(); return ret; } - _gnutls_write_datum16(pdata, tmp); + + _tmp.data = (char*) tmp.data; + _tmp.size = tmp.size; + _gnutls_write_datum16(pdata, _tmp); pdata += (2 + tmp.size); } return 0; } + + + +/* Returns 0 if it's ok to use the gnutls_kx_algorithm with this + * certificate (uses the KeyUsage field). + */ +int _gnutls_check_key_usage( const gnutls_cert* cert, + gnutls_kx_algorithm alg) +{ + unsigned int keyUsage = 0; + int encipher_type; + + if ( cert==NULL) { + gnutls_assert(); + return GNUTLS_E_INTERNAL_ERROR; + } + + /* FIXME: check here */ + if (_gnutls_map_kx_get_cred(alg, 1) == GNUTLS_CRD_CERTIFICATE || + _gnutls_map_kx_get_cred(alg, 0) == GNUTLS_CRD_CERTIFICATE) + { + + keyUsage = cert->keyUsage; + + encipher_type = _gnutls_kx_encipher_type( alg); + + if (keyUsage != 0 && encipher_type != CIPHER_IGN) { + /* If keyUsage has been set in the certificate + */ + + if ( encipher_type == CIPHER_ENCRYPT) { + /* If the key exchange method requires an encipher + * type algorithm, and key's usage does not permit + * encipherment, then fail. + */ + if (!(keyUsage & KEY_KEY_ENCIPHERMENT)) + return + GNUTLS_E_KEY_USAGE_VIOLATION; + } + + if ( encipher_type == CIPHER_SIGN) { + /* The same as above, but for sign only keys + */ + if (!(keyUsage & KEY_DIGITAL_SIGNATURE)) + return + GNUTLS_E_KEY_USAGE_VIOLATION; + } + } + } + return 0; +} + + + +static int parse_pem_ca_mem( gnutls_x509_certificate** cert_list, int* ncerts, + const char *input_cert, int input_cert_size) +{ + int siz, i; + const char *ptr; + gnutls_datum tmp; + int ret, count; + + /* move to the certificate + */ + ptr = strstr( input_cert, PEM_CERT_SEP); + if (ptr == NULL) ptr = strstr( input_cert, PEM_CERT_SEP2); + + if (ptr == NULL) { + gnutls_assert(); + return GNUTLS_E_BASE64_DECODING_ERROR; + } + siz = strlen( ptr); + + i = *ncerts + 1; + count = 0; + + do { + + *cert_list = + (gnutls_x509_certificate *) gnutls_realloc_fast( *cert_list, + i * + sizeof(gnutls_x509_certificate)); + + if ( *cert_list == NULL) { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } + + ret = gnutls_x509_certificate_init( &cert_list[0][i - 1]); + if ( ret < 0) { + gnutls_assert(); + return ret; + } + + tmp.data = (char*)ptr; + tmp.size = siz; + + ret = + gnutls_x509_certificate_import( + cert_list[0][i - 1], + &tmp, GNUTLS_X509_FMT_PEM); + if (ret < 0) { + gnutls_assert(); + return ret; + } + + /* now we move ptr after the pem header + */ + ptr++; + /* find the next certificate (if any) + */ + ptr = strstr(ptr, PEM_CERT_SEP); + if (ptr == NULL) ptr = strstr( input_cert, PEM_CERT_SEP2); + + i++; + count++; + + } while ( ptr != NULL); + + *ncerts = i - 1; + + return count; +} + +/* Reads a DER encoded certificate list from memory and stores it to + * a gnutls_cert structure. This is only called if PKCS7 read fails. + * returns the number of certificates parsed (1) + */ +static int parse_der_ca_mem( gnutls_x509_certificate** cert_list, int* ncerts, + const char *input_cert, int input_cert_size) +{ + int i; + gnutls_datum tmp; + int ret; + + i = *ncerts + 1; + + *cert_list = + (gnutls_x509_certificate *) gnutls_realloc_fast( *cert_list, + i * + sizeof(gnutls_x509_certificate)); + + if ( *cert_list == NULL) { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } + + tmp.data = (opaque*)input_cert; + tmp.size = input_cert_size; + + ret = gnutls_x509_certificate_init( &cert_list[0][i - 1]); + if ( ret < 0) { + gnutls_assert(); + return ret; + } + + ret = + gnutls_x509_certificate_import( + cert_list[0][i - 1], + &tmp, GNUTLS_X509_FMT_DER); + if (ret < 0) { + gnutls_assert(); + return ret; + } + + *ncerts = i; + + return 1; /* one certificate parsed */ +} + /** * gnutls_certificate_set_x509_trust_mem - Used to add trusted CAs in a gnutls_certificate_credentials structure * @res: is an &gnutls_certificate_credentials structure. @@ -964,8 +986,12 @@ int gnutls_certificate_set_x509_trust_mem(gnutls_certificate_credentials res, { int ret, ret2; - if ((ret = read_ca_mem(res, CA->data, CA->size, type)) < 0) - return ret; + if (type==GNUTLS_X509_FMT_DER) + return parse_der_ca_mem( &res->x509_ca_list, &res->x509_ncas, + CA->data, CA->size); + else + return parse_pem_ca_mem( &res->x509_ca_list, &res->x509_ncas, + CA->data, CA->size); if ((ret2 = generate_rdn_seq(res)) < 0) return ret2; @@ -989,9 +1015,34 @@ int gnutls_certificate_set_x509_trust_file(gnutls_certificate_credentials res, const char *CAFILE, gnutls_x509_certificate_format type) { int ret, ret2; + int siz; + char x[MAX_FILE_SIZE]; + FILE *fd1; + + /* FIXME: does not work on long files + */ + fd1 = fopen(CAFILE, "rb"); + if (fd1 == NULL) { + gnutls_assert(); + return GNUTLS_E_FILE_ERROR; + } + + siz = fread(x, 1, sizeof(x)-1, fd1); + fclose(fd1); + + x[siz] = 0; - if ((ret = read_ca_file(res, CAFILE, type)) < 0) + if (type==GNUTLS_X509_FMT_DER) + ret = parse_der_ca_mem( &res->x509_ca_list, &res->x509_ncas, + x, siz); + else + ret = parse_pem_ca_mem( &res->x509_ca_list, &res->x509_ncas, + x, siz); + + if (ret < 0) { + gnutls_assert(); return ret; + } if ((ret2 = generate_rdn_seq(res)) < 0) return ret2; @@ -999,322 +1050,217 @@ int gnutls_certificate_set_x509_trust_file(gnutls_certificate_credentials res, return ret; } +static int parse_pem_crl_mem( gnutls_x509_crl** crl_list, int* ncrls, + const char *input_crl, int input_crl_size) +{ + int siz, i; + const char *ptr; + gnutls_datum tmp; + int ret, count; -/* Extracts DSA and RSA parameters from a certificate. - */ -static -int _gnutls_extract_x509_cert_mpi_params( const char* ALGO_OID, gnutls_cert * gCert, - ASN1_TYPE c2, const char* name, char* tmpstr, int tmpstr_size) { -int len, result; -char name1[128]; - - _gnutls_str_cpy( name1, sizeof(name1), name); - _gnutls_str_cat( name1, sizeof(name1), ".tbsCertificate.subjectPublicKeyInfo.subjectPublicKey"); - - len = tmpstr_size - 1; - result = - asn1_read_value - (c2, name1, tmpstr, &len); - - if (result != ASN1_SUCCESS) { + /* move to the certificate + */ + ptr = strstr( input_crl, PEM_CRL_SEP); + if (ptr == NULL) { gnutls_assert(); - return _gnutls_asn2err(result); + return GNUTLS_E_BASE64_DECODING_ERROR; } - gCert->subject_pk_algorithm = _gnutls_x509_oid2pk_algorithm( ALGO_OID); - - switch( gCert->subject_pk_algorithm) { - case GNUTLS_PK_RSA: - /* params[0] is the modulus, - * params[1] is the exponent - */ - if ((sizeof(gCert->params) / sizeof(GNUTLS_MPI)) < RSA_PUBLIC_PARAMS) { - gnutls_assert(); - /* internal error. Increase the GNUTLS_MPIs in params */ - return GNUTLS_E_INTERNAL_ERROR; - } - - if ((result = - _gnutls_x509_read_rsa_params(tmpstr, len / 8, gCert->params)) < 0) { - gnutls_assert(); - return result; - } - gCert->params_size = RSA_PUBLIC_PARAMS; - - return 0; - break; - case GNUTLS_PK_DSA: - /* params[0] is p, - * params[1] is q, - * params[2] is q, - * params[3] is pub. - */ - - if ((sizeof(gCert->params) / sizeof(GNUTLS_MPI)) < DSA_PUBLIC_PARAMS) { - gnutls_assert(); - /* internal error. Increase the GNUTLS_MPIs in params */ - return GNUTLS_E_INTERNAL_ERROR; - } + siz = strlen( ptr); - if ((result = - _gnutls_x509_read_dsa_pubkey(tmpstr, len / 8, gCert->params)) < 0) { - gnutls_assert(); - return result; - } + i = *ncrls + 1; + count = 0; - /* Now read the parameters - */ - _gnutls_str_cpy( name1, sizeof(name1), name); - _gnutls_str_cat( name1, sizeof(name1), ".tbsCertificate.subjectPublicKeyInfo.algorithm.parameters"); + do { - len = tmpstr_size - 1; - result = - asn1_read_value(c2, name1, tmpstr, &len); + *crl_list = + (gnutls_x509_crl *) gnutls_realloc_fast( *crl_list, + i * + sizeof(gnutls_x509_crl)); - if (result != ASN1_SUCCESS) { + if ( *crl_list == NULL) { gnutls_assert(); - return _gnutls_asn2err(result); + return GNUTLS_E_MEMORY_ERROR; } - if ((result = - _gnutls_x509_read_dsa_params(tmpstr, len, gCert->params)) < 0) { + ret = gnutls_x509_crl_init( &crl_list[0][i - 1]); + if ( ret < 0) { gnutls_assert(); - return result; + return ret; } - gCert->params_size = DSA_PUBLIC_PARAMS; - return 0; - break; + tmp.data = (char*)ptr; + tmp.size = siz; + + ret = + gnutls_x509_crl_import( + crl_list[0][i - 1], + &tmp, GNUTLS_X509_FMT_PEM); + if (ret < 0) { + gnutls_assert(); + return ret; + } - default: - /* other types like DH - * currently not supported + /* now we move ptr after the pem header */ - gnutls_assert(); - _gnutls_log("X509 certificate: Found algorithm: %s\n", ALGO_OID); - - gCert->subject_pk_algorithm = GNUTLS_PK_UNKNOWN; - - return GNUTLS_E_X509_CERTIFICATE_ERROR; - } -} + ptr++; + /* find the next certificate (if any) + */ + ptr = strstr(ptr, PEM_CRL_SEP); + i++; + count++; + } while ( ptr != NULL); + *ncrls = i - 1; -#define X509_SIG_SIZE 1024 + return count; +} -/* This function will convert a der certificate, to a format - * (structure) that gnutls can understand and use. Actually the - * important thing on this function is that it extracts the - * certificate's (public key) parameters. - * - * The noext flag is used to complete the handshake even if the - * extensions found in the certificate are unsupported and critical. - * The critical extensions will be catched by the verification functions. +/* Reads a DER encoded certificate list from memory and stores it to + * a gnutls_cert structure. This is only called if PKCS7 read fails. + * returns the number of certificates parsed (1) */ -int _gnutls_x509_cert2gnutls_cert(gnutls_cert * gCert, gnutls_datum derCert, - ConvFlags fast /* if non zero do not parse the whole certificate */) +static int parse_der_crl_mem( gnutls_x509_crl** crl_list, int* ncrls, + const char *input_crl, int input_crl_size) { - int result = 0; - ASN1_TYPE c2; - opaque str[MAX_X509_CERT_SIZE]; - char oid[128]; - int len = sizeof(str); - - memset(gCert, 0, sizeof(gnutls_cert)); - - gCert->cert_type = GNUTLS_CRT_X509; + int i; + gnutls_datum tmp; + int ret; - if ( !(fast & CERT_NO_COPY)) { - if (_gnutls_set_datum(&gCert->raw, derCert.data, derCert.size) < 0) { - gnutls_assert(); - return GNUTLS_E_MEMORY_ERROR; - } - } else - /* now we have 0 or a bitwise or of things to decode */ - fast ^= CERT_NO_COPY; + i = *ncrls + 1; + *crl_list = + (gnutls_x509_crl *) gnutls_realloc_fast( *crl_list, + i * + sizeof(gnutls_x509_crl)); - if ((result=_gnutls_asn1_create_element - (_gnutls_get_pkix(), "PKIX1.Certificate", &c2, - "cert")) - != ASN1_SUCCESS) { + if ( *crl_list == NULL) { gnutls_assert(); - _gnutls_free_datum( &gCert->raw); - return _gnutls_asn2err(result); - } - - if (fast & CERT_ONLY_EXTENSIONS) { - result = asn1_der_decoding_element( &c2, "cert.tbsCertificate.extensions", - derCert.data, derCert.size, NULL); - - if (result != ASN1_SUCCESS) { - /* couldn't decode DER */ - - _gnutls_log("X509 certificate: Decoding error %d\n", result); - gnutls_assert(); - asn1_delete_structure(&c2); - _gnutls_free_datum( &gCert->raw); - return _gnutls_asn2err(result); - } + return GNUTLS_E_MEMORY_ERROR; } - if (fast & CERT_ONLY_PUBKEY) { - result = asn1_der_decoding_element( &c2, "cert.tbsCertificate.subjectPublicKeyInfo", - derCert.data, derCert.size, NULL); + tmp.data = (opaque*)input_crl; + tmp.size = input_crl_size; - if (result != ASN1_SUCCESS) { - /* couldn't decode DER */ - - _gnutls_log("X509 certificate: Decoding error %d\n", result); - gnutls_assert(); - asn1_delete_structure(&c2); - _gnutls_free_datum( &gCert->raw); - return _gnutls_asn2err(result); - } + ret = gnutls_x509_crl_init( &crl_list[0][i - 1]); + if ( ret < 0) { + gnutls_assert(); + return ret; } - - if (fast==0) { - result = asn1_der_decoding(&c2, derCert.data, derCert.size, - NULL); - - if (result != ASN1_SUCCESS) { - /* couldn't decode DER */ - _gnutls_log("X509 certificate: Decoding error %d\n", result); - - gnutls_assert(); - asn1_delete_structure(&c2); - _gnutls_free_datum( &gCert->raw); - return _gnutls_asn2err(result); - } + + ret = + gnutls_x509_crl_import( + crl_list[0][i - 1], + &tmp, GNUTLS_X509_FMT_DER); + if (ret < 0) { + gnutls_assert(); + return ret; } - - if (fast==0) { /* decode all */ - len = gCert->signature.size = X509_SIG_SIZE; - gCert->signature.data = gnutls_malloc( gCert->signature.size); - if (gCert->signature.data==NULL) { - gnutls_assert(); - return GNUTLS_E_MEMORY_ERROR; - } + *ncrls = i; - result = - asn1_read_value - (c2, "cert.signature", gCert->signature.data, &len); + return 1; /* one certificate parsed */ +} - if ((len % 8) != 0) { - gnutls_assert(); - asn1_delete_structure(&c2); - _gnutls_free_datum( &gCert->raw); - _gnutls_free_datum( &gCert->signature); - return GNUTLS_E_UNIMPLEMENTED_FEATURE; - } - - len /= 8; /* convert to bytes */ - gCert->signature.size = len; /* put the actual sig size */ - gCert->expiration_time = - _gnutls_x509_get_time(c2, "cert.tbsCertificate.validity.notAfter"); - gCert->activation_time = - _gnutls_x509_get_time(c2, "cert.tbsCertificate.validity.notBefore"); +/* Reads a DER or PEM CRL from memory + */ +static +int read_crl_mem(gnutls_certificate_credentials res, const char *crl, int crl_size, + gnutls_x509_certificate_format type) +{ + int ret; - gCert->version = _gnutls_x509_get_version(c2, "cert"); - if (gCert->version < 0) { - gnutls_assert(); - asn1_delete_structure(&c2); - _gnutls_free_datum( &gCert->raw); - return GNUTLS_E_ASN1_GENERIC_ERROR; - } + /* allocate space for the certificate to add + */ + res->x509_crl_list = gnutls_realloc_fast( res->x509_crl_list, + (1+ res->x509_ncrls)*sizeof(gnutls_x509_crl)); + if ( res->x509_crl_list==NULL) { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; } - if (fast & CERT_ONLY_PUBKEY || fast == 0) { - len = sizeof(oid) - 1; - result = - asn1_read_value - (c2, - "cert.tbsCertificate.subjectPublicKeyInfo.algorithm.algorithm", - oid, &len); - - if (result != ASN1_SUCCESS) { - gnutls_assert(); - asn1_delete_structure(&c2); - _gnutls_free_datum( &gCert->raw); - return _gnutls_asn2err(result); - } + if (type==GNUTLS_X509_FMT_DER) + ret = parse_der_crl_mem( &res->x509_crl_list, + &res->x509_ncrls, crl, crl_size); + else + ret = parse_pem_crl_mem( &res->x509_crl_list, + &res->x509_ncrls, crl, crl_size); - if ( (result=_gnutls_extract_x509_cert_mpi_params( oid, gCert, c2, "cert", str, sizeof(str))) < 0) { - gnutls_assert(); - asn1_delete_structure(&c2); - _gnutls_free_datum( &gCert->raw); - return result; - } + if (ret < 0) { + gnutls_assert(); + return ret; } - if (fast & CERT_ONLY_EXTENSIONS || fast == 0) { - if ((result = - _gnutls_get_ext_type(c2, - "cert.tbsCertificate.extensions", - gCert, fast)) < 0) { - gnutls_assert(); - asn1_delete_structure(&c2); - _gnutls_free_datum( &gCert->raw); - return result; - } - - } + return ret; +} - asn1_delete_structure(&c2); +/** + * gnutls_certificate_set_x509_crl_mem - Used to add CRLs in a gnutls_certificate_credentials structure + * @res: is an &gnutls_certificate_credentials structure. + * @CRL: is a list of trusted CRLs. They should have been verified before. + * @type: is DER or PEM + * + * This function adds the trusted CRLs in order to verify client or server + * certificates. This function may be called multiple times. + * + **/ +int gnutls_certificate_set_x509_crl_mem(gnutls_certificate_credentials res, + const gnutls_datum *CRL, gnutls_x509_certificate_format type) +{ + int ret; - return 0; + if ((ret = read_crl_mem(res, CRL->data, CRL->size, type)) < 0) + return ret; + return ret; } -/* Returns 0 if it's ok to use the gnutls_kx_algorithm with this - * certificate (uses the KeyUsage field). - */ -int _gnutls_check_x509_key_usage( const gnutls_cert * cert, - gnutls_kx_algorithm alg) +/** + * gnutls_certificate_set_x509_crl_file - Used to add CRLs in a gnutls_certificate_credentials structure + * @res: is an &gnutls_certificate_credentials structure. + * @crlfile: is a file containing the list of verified CRLs (DER or PEM list) + * @type: is PEM or DER + * + * This function sets the trusted CRLs in order to verify client or server + * certificates. This function may be called multiple times, and the + * given CRLs will be appended to the crl list. + * Returns the number of certificate processed. + * + **/ +int gnutls_certificate_set_x509_crl_file(gnutls_certificate_credentials res, + const char *crlfile, gnutls_x509_certificate_format type) { - uint16 keyUsage; - int encipher_type; + int ret; + int siz; + char x[MAX_FILE_SIZE]; + FILE *fd1; - if ( cert==NULL) { + /* FIXME: does not work on long files + */ + fd1 = fopen(crlfile, "rb"); + if (fd1 == NULL) { gnutls_assert(); - return GNUTLS_E_INTERNAL_ERROR; + return GNUTLS_E_FILE_ERROR; } - /* FIXME: check here */ - if (_gnutls_map_kx_get_cred(alg, 1) == GNUTLS_CRD_CERTIFICATE || - _gnutls_map_kx_get_cred(alg, 0) == GNUTLS_CRD_CERTIFICATE) - { + siz = fread(x, 1, sizeof(x)-1, fd1); + fclose(fd1); - keyUsage = cert->keyUsage; - encipher_type = _gnutls_kx_encipher_type( alg); - - if (keyUsage != 0 && encipher_type != CIPHER_IGN) { - /* If keyUsage has been set in the certificate - */ + x[siz] = 0; - if ( encipher_type == CIPHER_ENCRYPT) { - /* If the key exchange method requires an encipher - * type algorithm, and key's usage does not permit - * encipherment, then fail. - */ - if (!(keyUsage & KEY_KEY_ENCIPHERMENT)) - return - GNUTLS_E_KEY_USAGE_VIOLATION; - } + if (type==GNUTLS_X509_FMT_DER) + ret = parse_der_crl_mem( &res->x509_crl_list, &res->x509_ncrls, + x, siz); + else + ret = parse_pem_crl_mem( &res->x509_crl_list, &res->x509_ncrls, + x, siz); - if ( encipher_type == CIPHER_SIGN) { - /* The same as above, but for sign only keys - */ - if (!(keyUsage & KEY_DIGITAL_SIGNATURE)) - return - GNUTLS_E_KEY_USAGE_VIOLATION; - } - } + if (ret < 0) { + gnutls_assert(); + return ret; } - return 0; -} - + return ret; +} diff --git a/lib/gnutls_x509.h b/lib/gnutls_x509.h index 7bf61eebb5..d5ac72c05a 100644 --- a/lib/gnutls_x509.h +++ b/lib/gnutls_x509.h @@ -2,22 +2,16 @@ int _gnutls_x509_cert_verify_peers(gnutls_session session); -typedef enum ConvFlags { - CERT_NO_COPY=2, - CERT_ONLY_PUBKEY=4, - CERT_ONLY_EXTENSIONS=16 -} ConvFlags; - -int _gnutls_x509_cert2gnutls_cert(gnutls_cert * gCert, gnutls_datum derCert, ConvFlags flags); - #define PEM_CERT_SEP2 "-----BEGIN X509 CERTIFICATE" #define PEM_CERT_SEP "-----BEGIN CERTIFICATE" #define PEM_PKCS7_SEP "-----BEGIN PKCS7" +#define PEM_CRL_SEP "-----BEGIN X509 CRL" + #define PEM_KEY_RSA_SEP "-----BEGIN RSA" #define PEM_KEY_DSA_SEP "-----BEGIN DSA" -int _gnutls_check_x509_key_usage( const gnutls_cert * cert, gnutls_kx_algorithm alg); +int _gnutls_check_key_usage( const gnutls_cert* cert, gnutls_kx_algorithm alg); int _gnutls_x509_read_rsa_params(opaque * der, int dersize, GNUTLS_MPI * params); int _gnutls_x509_read_dsa_pubkey(opaque * der, int dersize, GNUTLS_MPI * params); diff --git a/lib/x509/compat.c b/lib/x509/compat.c index ebe82df30b..213cfb42cf 100644 --- a/lib/x509/compat.c +++ b/lib/x509/compat.c @@ -560,3 +560,189 @@ int gnutls_x509_extract_certificate_dn_string(char *buf, unsigned int sizeof_buf return result; } + +/** + * gnutls_x509_verify_certificate - This function verifies given certificate list + * @cert_list: is the certificate list to be verified + * @cert_list_length: holds the number of certificate in cert_list + * @CA_list: is the CA list which will be used in verification + * @CA_list_length: holds the number of CA certificate in CA_list + * @CRL_list: not used + * @CRL_list_length: not used + * + * This function will try to verify the given certificate list and return it's status (TRUSTED, EXPIRED etc.). + * The return value (status) should be one or more of the gnutls_certificate_status + * enumerated elements bitwise or'd. Note that expiration and activation dates are not checked + * by this function, you should check them using the appropriate functions. + * + * This function understands the basicConstraints (2 5 29 19) PKIX extension. + * This means that only a certificate authority can sign a certificate. + * + * However you must also check the peer's name in order to check if the verified certificate belongs to the + * actual peer. + * + * The return value (status) should be one or more of the gnutls_certificate_status + * enumerated elements bitwise or'd. + * + * GNUTLS_CERT_NOT_TRUSTED\: the peer's certificate is not trusted. + * + * GNUTLS_CERT_INVALID\: the certificate chain is broken. + * + * GNUTLS_CERT_REVOKED\: the certificate has been revoked + * (not implemented yet). + * + * GNUTLS_CERT_CORRUPTED\: the certificate is corrupted. + * + * A negative error code is returned in case of an error. + * GNUTLS_E_NO_CERTIFICATE_FOUND is returned to indicate that + * no certificate was sent by the peer. + * + * + **/ +int gnutls_x509_verify_certificate( const gnutls_datum* cert_list, int cert_list_length, + const gnutls_datum * CA_list, int CA_list_length, + const gnutls_datum* CRL_list, int CRL_list_length) +{ + unsigned int verify; + gnutls_x509_certificate *peer_certificate_list = NULL; + gnutls_x509_certificate *ca_certificate_list = NULL; + gnutls_x509_crl *crl_list = NULL; + int peer_certificate_list_size=0, i, x, ret; + int ca_certificate_list_size=0, crl_list_size=0; + + if (cert_list == NULL || cert_list_length == 0) + return GNUTLS_E_NO_CERTIFICATE_FOUND; + + /* generate a list of gnutls_certs based on the auth info + * raw certs. + */ + peer_certificate_list_size = cert_list_length; + peer_certificate_list = + gnutls_calloc(1, + peer_certificate_list_size * + sizeof(gnutls_x509_certificate)); + if (peer_certificate_list == NULL) { + gnutls_assert(); + ret = GNUTLS_E_MEMORY_ERROR; + goto cleanup; + } + + ca_certificate_list_size = CA_list_length; + ca_certificate_list = + gnutls_calloc(1, + ca_certificate_list_size * + sizeof(gnutls_x509_certificate)); + if (ca_certificate_list == NULL) { + gnutls_assert(); + ret = GNUTLS_E_MEMORY_ERROR; + goto cleanup; + } + + /* allocate memory for CRL + */ + crl_list_size = CRL_list_length; + crl_list = + gnutls_calloc(1, + crl_list_size * + sizeof(gnutls_x509_crl)); + if (crl_list == NULL) { + gnutls_assert(); + ret = GNUTLS_E_MEMORY_ERROR; + goto cleanup; + } + + /* convert certA_list to gnutls_cert* list + */ + for (i = 0; i < peer_certificate_list_size; i++) { + ret = gnutls_x509_certificate_init( &peer_certificate_list[i]); + if (ret < 0) { + gnutls_assert(); + goto cleanup; + } + + ret = + gnutls_x509_certificate_import(peer_certificate_list[i], + &cert_list[i], GNUTLS_X509_FMT_DER); + if (ret < 0) { + gnutls_assert(); + goto cleanup; + } + } + + /* convert CA_list to gnutls_x509_cert* list + */ + for (i = 0; i < ca_certificate_list_size; i++) { + ret = gnutls_x509_certificate_init(&ca_certificate_list[i]); + if (ret < 0) { + gnutls_assert(); + goto cleanup; + } + + ret = + gnutls_x509_certificate_import(ca_certificate_list[i], + &CA_list[i], GNUTLS_X509_FMT_DER); + if (ret < 0) { + gnutls_assert(); + goto cleanup; + } + } + + /* convert CRL_list to gnutls_x509_crl* list + */ + for (i = 0; i < crl_list_size; i++) { + ret = gnutls_x509_crl_init( &crl_list[i]); + if (ret < 0) { + gnutls_assert(); + goto cleanup; + } + + ret = + gnutls_x509_crl_import(crl_list[i], + &CRL_list[i], GNUTLS_X509_FMT_DER); + if (ret < 0) { + gnutls_assert(); + goto cleanup; + } + } + + /* Verify certificate + */ + ret = + gnutls_x509_certificate_list_verify(peer_certificate_list, + peer_certificate_list_size, + ca_certificate_list, ca_certificate_list_size, + crl_list, crl_list_size, 0, &verify); + + if (ret < 0) { + gnutls_assert(); + goto cleanup; + } + + ret = verify; + + cleanup: + + if (peer_certificate_list != NULL) + for(x=0;x<peer_certificate_list_size;x++) { + if (peer_certificate_list[x] != NULL) + gnutls_x509_certificate_deinit(peer_certificate_list[x]); + } + + if (ca_certificate_list != NULL) + for(x=0;x<ca_certificate_list_size;x++) { + if (ca_certificate_list[x] != NULL) + gnutls_x509_certificate_deinit(ca_certificate_list[x]); + } + + if (crl_list != NULL) + for(x=0;x<crl_list_size;x++) { + if (crl_list[x] != NULL) + gnutls_x509_crl_deinit(crl_list[x]); + } + + gnutls_free( crl_list); + gnutls_free( ca_certificate_list); + gnutls_free( peer_certificate_list); + + return ret; +} diff --git a/lib/x509/extensions.c b/lib/x509/extensions.c index 52ade38b08..79ed83691b 100644 --- a/lib/x509/extensions.c +++ b/lib/x509/extensions.c @@ -65,7 +65,6 @@ int _gnutls_x509_certificate_get_extension( gnutls_x509_certificate cert, const */ if (result == ASN1_ELEMENT_NOT_FOUND) { - gnutls_assert(); break; } @@ -152,7 +151,6 @@ int _gnutls_x509_certificate_get_extension( gnutls_x509_certificate cert, const } while (1); if (result == ASN1_ELEMENT_NOT_FOUND) { - gnutls_assert(); return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; } else { gnutls_assert(); diff --git a/lib/x509/pkcs7.h b/lib/x509/pkcs7.h index 68979defdc..cb1feb21d1 100644 --- a/lib/x509/pkcs7.h +++ b/lib/x509/pkcs7.h @@ -4,3 +4,11 @@ typedef struct gnutls_pkcs7_int { } gnutls_pkcs7_int; typedef struct gnutls_pkcs7_int *gnutls_pkcs7; + +int gnutls_pkcs7_init(gnutls_pkcs7 * pkcs7); +void gnutls_pkcs7_deinit(gnutls_pkcs7 pkcs7); +int gnutls_pkcs7_import(gnutls_pkcs7 pkcs7, const gnutls_datum * data, + gnutls_x509_certificate_format format); +int gnutls_pkcs7_get_certificate(gnutls_pkcs7 pkcs7, + int indx, char* certificate, int* certificate_size); +int gnutls_pkcs7_get_certificate_count(gnutls_pkcs7 pkcs7); diff --git a/lib/x509/x509.h b/lib/x509/x509.h index 31f06e4918..18592125fa 100644 --- a/lib/x509/x509.h +++ b/lib/x509/x509.h @@ -49,4 +49,18 @@ int gnutls_x509_crl_get_certificate(gnutls_x509_crl crl, int index, unsigned char *serial, int *serial_size, time_t * time); +void gnutls_x509_crl_deinit(gnutls_x509_crl crl); +int gnutls_x509_crl_init(gnutls_x509_crl * crl); +int gnutls_x509_crl_import(gnutls_x509_crl crl, const gnutls_datum * data, + gnutls_x509_certificate_format format); + +int gnutls_x509_certificate_init(gnutls_x509_certificate * cert); +void gnutls_x509_certificate_deinit(gnutls_x509_certificate cert); +int gnutls_x509_certificate_import(gnutls_x509_certificate cert, const gnutls_datum * data, + gnutls_x509_certificate_format format); + +int gnutls_x509_certificate_get_key_usage(gnutls_x509_certificate cert, unsigned int *key_usage, + int *critical); +int gnutls_x509_certificate_get_version(gnutls_x509_certificate cert); + #endif diff --git a/lib/x509_extensions.c b/lib/x509_extensions.c deleted file mode 100644 index 1a17b920e9..0000000000 --- a/lib/x509_extensions.c +++ /dev/null @@ -1,328 +0,0 @@ -/* - * Copyright (C) 2001,2002,2003 Nikos Mavroyanopoulos - * - * This file is part of GNUTLS. - * - * The GNUTLS library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -/* Functions that relate to the X.509 extension parsing. - */ - -#include <gnutls_int.h> -#include <libtasn1.h> -#include <gnutls_num.h> -#include <gnutls_cert.h> -#include <gnutls_errors.h> -#include <gnutls_global.h> -#include "debug.h" -#include <gnutls_str.h> -#include <gnutls_x509.h> -#include "x509/common.h" -#include "x509/x509.h" -#include "x509/extensions.h" - -/* This file contains code to parse the X.509 certificate - * extensions. Not all the PKIX extensions are supported. - */ - -/* - * If no_critical_ext is non zero, then unsupported critical extensions - * do not lead into a fatal error. - */ -static int _parse_extension(gnutls_cert * cert, char *extnID, - char *critical, char *extnValue, - int extnValueLen, int no_critical_ext) -{ - - if (strcmp(extnID, "2 5 29 14") == 0) { /* subject Key ID */ - /* we don't use it */ - return 0; - } - - if (strcmp(extnID, "2 5 29 15") == 0) { /* Key Usage */ - return _gnutls_x509_ext_extract_keyUsage(&cert->keyUsage, extnValue, extnValueLen); - } - - if (strcmp(extnID, "2 5 29 19") == 0) { /* Basic Constraints */ - /* actually checks if a certificate belongs to - * a Certificate Authority. - */ - return _gnutls_x509_ext_extract_basicConstraints(&cert->CA, extnValue, - extnValueLen); - } - - _gnutls_x509_log("X509_EXT: CERT[%s]: Unsupported Extension: %s, %s\n", - GET_CN(cert->raw), extnID, critical); - - if (strcmp(critical, "TRUE") == 0 && no_critical_ext == 0) { - gnutls_assert(); - return GNUTLS_E_X509_UNSUPPORTED_CRITICAL_EXTENSION; - } - return 0; - -} - -/* This function will attempt to parse Extensions in - * an X509v3 certificate - * - * If no_critical_ext is non zero, then unsupported critical extensions - * do not lead into a fatal error. - */ -int _gnutls_get_ext_type(ASN1_TYPE rasn, const char *root, gnutls_cert * cert, - int no_critical_ext) -{ - int k, result, len; - char name[128], name2[128], counter[MAX_INT_DIGITS]; - char str[1024]; - char critical[10]; - char extnID[128]; - char extnValue[256]; - - k = 0; - do { - k++; - - _gnutls_str_cpy(name, sizeof(name), root); - _gnutls_str_cat(name, sizeof(name), ".?"); - _gnutls_int2str(k, counter); - _gnutls_str_cat(name, sizeof(name), counter); - - len = sizeof(str) - 1; - result = asn1_read_value(rasn, name, str, &len); - - /* move to next - */ - - if (result == ASN1_ELEMENT_NOT_FOUND) - break; - - do { - - _gnutls_str_cpy(name2, sizeof(name2), name); - _gnutls_str_cat(name2, sizeof(name2), ".extnID"); - - len = sizeof(extnID) - 1; - result = - asn1_read_value(rasn, name2, extnID, &len); - - if (result == ASN1_ELEMENT_NOT_FOUND) - break; - else if (result != ASN1_SUCCESS) { - gnutls_assert(); - return _gnutls_asn2err(result); - } - - _gnutls_str_cpy(name2, sizeof(name2), name); - _gnutls_str_cat(name2, sizeof(name2), ".critical"); - - len = sizeof(critical) - 1; - result = - asn1_read_value(rasn, name2, critical, &len); - - if (result == ASN1_ELEMENT_NOT_FOUND) - break; - else if (result != ASN1_SUCCESS) { - gnutls_assert(); - return _gnutls_asn2err(result); - } - - _gnutls_str_cpy(name2, sizeof(name2), name); - _gnutls_str_cat(name2, sizeof(name2), ".extnValue"); - - len = sizeof(extnValue) - 1; - result = - asn1_read_value(rasn, name2, extnValue, &len); - - if (result == ASN1_ELEMENT_NOT_FOUND) - break; - else { - if (result == ASN1_MEM_ERROR - && strcmp(critical, "FALSE") == 0) { - - _gnutls_x509_log - ("X509_EXT: Cannot parse extension: %s. Too small buffer.", - extnID); - - continue; - } - if (result != ASN1_SUCCESS) { - gnutls_assert(); - return _gnutls_asn2err(result); - } - } - - /* Handle Extension */ - if ((result = - _parse_extension(cert, extnID, critical, - extnValue, len, no_critical_ext)) < 0) { - gnutls_assert(); - return result; - } - - - } while (0); - } while (1); - - if (result == ASN1_ELEMENT_NOT_FOUND) - return 0; - else - return _gnutls_asn2err(result); -} - -/* This function will attempt to return the requested extension found in - * the given X509v3 certificate. The return value is allocated and stored into - * ret. - */ -int _gnutls_get_extension( const gnutls_datum * cert, const char* extension_id, gnutls_datum* ret) -{ - int k, result, len; - char name[128], name2[128], counter[MAX_INT_DIGITS]; - char str[1024]; - char critical[10]; - char extnID[128]; - char extnValue[256]; - ASN1_TYPE rasn; - - ret->data = NULL; - ret->size = 0; - - if ((result=_gnutls_asn1_create_element - (_gnutls_get_pkix(), "PKIX1.Certificate", &rasn, - "c2")) - != ASN1_SUCCESS) { - gnutls_assert(); - return _gnutls_asn2err(result); - } - - result = - asn1_der_decoding(&rasn, cert->data, cert->size, NULL); - if (result != ASN1_SUCCESS) { - /* couldn't decode DER */ - - _gnutls_x509_log("X509_EXT: Decoding error %d\n", result); - - gnutls_assert(); - asn1_delete_structure(&rasn); - return _gnutls_asn2err(result); - } - - k = 0; - do { - k++; - - _gnutls_str_cpy(name, sizeof(name), "c2.tbsCertificate.extensions.?"); - _gnutls_int2str(k, counter); - _gnutls_str_cat(name, sizeof(name), counter); - - len = sizeof(str) - 1; - result = asn1_read_value(rasn, name, str, &len); - - /* move to next - */ - - if (result == ASN1_ELEMENT_NOT_FOUND) { - gnutls_assert(); - break; - } - - do { - - _gnutls_str_cpy(name2, sizeof(name2), name); - _gnutls_str_cat(name2, sizeof(name2), ".extnID"); - - len = sizeof(extnID) - 1; - result = - asn1_read_value(rasn, name2, extnID, &len); - - if (result == ASN1_ELEMENT_NOT_FOUND) { - gnutls_assert(); - break; - } else if (result != ASN1_SUCCESS) { - gnutls_assert(); - return _gnutls_asn2err(result); - } - - _gnutls_str_cpy(name2, sizeof(name2), name); - _gnutls_str_cat(name2, sizeof(name2), ".critical"); - - len = sizeof(critical) - 1; - result = - asn1_read_value(rasn, name2, critical, &len); - - if (result == ASN1_ELEMENT_NOT_FOUND) { - gnutls_assert(); - break; - } else if (result != ASN1_SUCCESS) { - gnutls_assert(); - asn1_delete_structure(&rasn); - return _gnutls_asn2err(result); - } - - _gnutls_str_cpy(name2, sizeof(name2), name); - _gnutls_str_cat(name2, sizeof(name2), ".extnValue"); - - len = sizeof(extnValue) - 1; - result = - asn1_read_value(rasn, name2, extnValue, &len); - - if (result == ASN1_ELEMENT_NOT_FOUND) - break; - else { - if (result == ASN1_MEM_ERROR - && strcmp(critical, "FALSE") == 0) { - - _gnutls_x509_log - ("X509_EXT: Cannot parse extension: %s. Too small buffer.", - extnID); - - continue; - } - if (result != ASN1_SUCCESS) { - gnutls_assert(); - asn1_delete_structure(&rasn); - return _gnutls_asn2err(result); - } - } - - /* Handle Extension */ - if ( strcmp(extnID, extension_id)==0) { /* extension was found */ - asn1_delete_structure(&rasn); - ret->data = gnutls_malloc( len); - if (ret->data==NULL) - return GNUTLS_E_MEMORY_ERROR; - - ret->size = len; - memcpy( ret->data, extnValue, len); - - return 0; - } - - - } while (0); - } while (1); - - asn1_delete_structure(&rasn); - - - if (result == ASN1_ELEMENT_NOT_FOUND) { - gnutls_assert(); - return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; - } else { - gnutls_assert(); - return _gnutls_asn2err(result); - } -} diff --git a/lib/x509_extensions.h b/lib/x509_extensions.h deleted file mode 100644 index fc80dcca80..0000000000 --- a/lib/x509_extensions.h +++ /dev/null @@ -1,2 +0,0 @@ -int _gnutls_get_ext_type( ASN1_TYPE rasn, const char *root, gnutls_cert *cert, int no_critical_ext); -int _gnutls_get_extension( const gnutls_datum * cert, const char* extension_id, gnutls_datum* ret); diff --git a/lib/x509_sig_check.c b/lib/x509_sig_check.c deleted file mode 100644 index 2025a1e951..0000000000 --- a/lib/x509_sig_check.c +++ /dev/null @@ -1,246 +0,0 @@ -/* - * Copyright (C) 2001,2002,2003 Nikos Mavroyanopoulos - * - * This file is part of GNUTLS. - * - * The GNUTLS library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -/* Functions that relate to X.509 certificate signature checking. - */ - -#include <gnutls_int.h> -#include <gnutls_errors.h> -#include <x509_b64.h> -#include <auth_cert.h> -#include <gnutls_cert.h> -#include <libtasn1.h> -#include <gnutls_datum.h> -#include <gnutls_mpi.h> -#include <gnutls_privkey.h> -#include <gnutls_global.h> -#include <gnutls_pk.h> -#include <debug.h> -#include <gnutls_str.h> - -/* returns DER tbsCertificate - */ -static gnutls_datum _gnutls_get_tbs( gnutls_cert* cert) { -ASN1_TYPE c2; -gnutls_datum ret = {NULL, 0}; -opaque *str; -int result, len; -int start, end; - - if (_gnutls_asn1_create_element( _gnutls_get_pkix(), "PKIX1.Certificate", &c2, "certificate")!=ASN1_SUCCESS) { - gnutls_assert(); - return ret; - } - - result = asn1_der_decoding( &c2, cert->raw.data, cert->raw.size, NULL); - if (result != ASN1_SUCCESS) { - gnutls_assert(); - asn1_delete_structure(&c2); - return ret; - } - - result = asn1_der_decoding_startEnd( c2, cert->raw.data, cert->raw.size, - "certificate.tbsCertificate", &start, &end); - asn1_delete_structure(&c2); - - if (result != ASN1_SUCCESS) { - gnutls_assert(); - return ret; - } - - len = end - start + 1; - str = &cert->raw.data[start]; - - if (_gnutls_set_datum( &ret, str, len) < 0) { - gnutls_assert(); - return ret; - } - - return ret; -} - - -/* we use DER here -- FIXME: use BER - */ -static int _gnutls_get_ber_digest_info( const gnutls_datum *info, gnutls_mac_algorithm *hash, opaque* digest, int *digest_size) { -ASN1_TYPE dinfo; -int result; -opaque str[1024]; -int len; - - if ((result=_gnutls_asn1_create_element( _gnutls_get_gnutls_asn(), "GNUTLS.DigestInfo", &dinfo, "digest_info"))!=ASN1_SUCCESS) { - gnutls_assert(); - return _gnutls_asn2err(result); - } - - result = asn1_der_decoding( &dinfo, info->data, info->size, NULL); - if (result != ASN1_SUCCESS) { - gnutls_assert(); - asn1_delete_structure(&dinfo); - return _gnutls_asn2err(result); - } - - len = sizeof(str)-1; - result = - asn1_read_value( dinfo, "digest_info.digestAlgorithm.algorithm", str, &len); - if (result != ASN1_SUCCESS) { - gnutls_assert(); - asn1_delete_structure(&dinfo); - return _gnutls_asn2err(result); - } - - *hash = (gnutls_mac_algorithm)-1; - - if ( strcmp(str, "1 2 840 113549 2 5")==0) { /* MD5 */ - *hash = GNUTLS_MAC_MD5; - } else - if ( strcmp(str, "1 3 14 3 2 26")==0) { /* SHA1 ID */ - *hash = GNUTLS_MAC_SHA; - } - - if (*hash==(gnutls_mac_algorithm)-1) { - - _gnutls_x509_log( "X509_SIG: HASH OID: %s\n", str); - - gnutls_assert(); - return GNUTLS_E_UNIMPLEMENTED_FEATURE; - } - - result = - asn1_read_value( dinfo, "digest_info.digest", digest, digest_size); - if (result != ASN1_SUCCESS) { - gnutls_assert(); - asn1_delete_structure(&dinfo); - return _gnutls_asn2err(result); - } - - asn1_delete_structure(&dinfo); - - return 0; -} - -/* if hash==MD5 then we do RSA-MD5 - * if hash==SHA then we do RSA-SHA - * params[0] is modulus - * params[1] is public key - */ -static int -_pkcs1_rsa_verify_sig( const gnutls_datum* signature, gnutls_datum* text, GNUTLS_MPI *params, int params_len) -{ - gnutls_mac_algorithm hash; - int ret; - opaque digest[MAX_HASH_SIZE], md[MAX_HASH_SIZE]; - int digest_size; - GNUTLS_HASH_HANDLE hd; - gnutls_datum decrypted; - - if ( (ret=_gnutls_pkcs1_rsa_decrypt( &decrypted, *signature, params, params_len, 1)) < 0) { - gnutls_assert(); - return ret; - } - - /* decrypted is a BER encoded data of type DigestInfo - */ - - digest_size = sizeof(digest); - if ( (ret = _gnutls_get_ber_digest_info( &decrypted, &hash, digest, &digest_size)) != 0) { - gnutls_assert(); - _gnutls_free_datum( &decrypted); - return ret; - } - - _gnutls_free_datum( &decrypted); - - if (digest_size != _gnutls_hash_get_algo_len(hash)) { - gnutls_assert(); - return GNUTLS_E_ASN1_GENERIC_ERROR; - } - - hd = _gnutls_hash_init( hash); - _gnutls_hash( hd, text->data, text->size); - _gnutls_hash_deinit( hd, md); - - if (memcmp( md, digest, digest_size)!=0) { - gnutls_assert(); - return GNUTLS_E_PK_SIG_VERIFY_FAILED; - } - - return 0; -} - -/* verifies if the certificate is properly signed. - * returns 0 on success. - */ -gnutls_certificate_status gnutls_x509_verify_signature(gnutls_cert* cert, gnutls_cert* issuer) { -gnutls_datum signature; -gnutls_datum tbs; - - signature.data = cert->signature.data; - signature.size = cert->signature.size; - - tbs = _gnutls_get_tbs( cert); - if (tbs.data==NULL) { - gnutls_assert(); - return GNUTLS_CERT_INVALID; - } - - _gnutls_x509_log("X509_VERIFY: CERT[%s]\n", GET_CN(cert->raw)); - _gnutls_x509_log("X509_VERIFY: ISSUER[%s]\n", GET_CN(issuer->raw)); - - switch( issuer->subject_pk_algorithm) { - case GNUTLS_PK_RSA: - - if (_pkcs1_rsa_verify_sig( &signature, &tbs, issuer->params, issuer->params_size)!=0) { - gnutls_assert(); - _gnutls_free_datum( &tbs); - return GNUTLS_CERT_INVALID; - } - - _gnutls_free_datum(&tbs); - return 0; - break; - - case GNUTLS_PK_DSA: - if (_gnutls_dsa_verify( &tbs, &signature, issuer->params, issuer->params_size)!=0) { - gnutls_assert(); - _gnutls_free_datum( &tbs); - return GNUTLS_CERT_INVALID; - } - - _gnutls_free_datum(&tbs); - return 0; - break; - default: - gnutls_assert(); - _gnutls_free_datum(&tbs); - return GNUTLS_E_INTERNAL_ERROR; - - } - - _gnutls_free_datum(&tbs); - - _gnutls_x509_log( "X509_SIG: PK: %d\n", issuer->subject_pk_algorithm); - - gnutls_assert(); - return GNUTLS_CERT_INVALID; -} - - diff --git a/lib/x509_verify.c b/lib/x509_verify.c deleted file mode 100644 index 8681df263e..0000000000 --- a/lib/x509_verify.c +++ /dev/null @@ -1,320 +0,0 @@ -/* - * Copyright (C) 2001,2002,2003 Nikos Mavroyanopoulos <nmav@hellug.gr> - * - * This file is part of GNUTLS. - * - * The GNUTLS library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -/* All functions which relate to X.509 certificate verification stuff are - * included here - */ - -#include "gnutls_int.h" -#include "gnutls_errors.h" -#include "gnutls_cert.h" -#include "libtasn1.h" -#include "gnutls_global.h" -#include "gnutls_num.h" /* GMAX */ -#include <gnutls_sig.h> -#include <gnutls_str.h> - - -/* Return 0 or INVALID, if the issuer is a CA, - * or not. - */ -static int check_if_ca(const gnutls_cert * cert, - const gnutls_cert * issuer) -{ - gnutls_certificate_status ret = GNUTLS_CERT_INVALID; - - /* Check if the issuer is the same with the - * certificate. This is added in order for trusted - * certificates to be able to verify themselves. - */ - if (cert->raw.size == issuer->raw.size) { - if (memcmp - (cert->raw.data, issuer->raw.data, - cert->raw.size) == 0) { - return 0; - } - } - - if (issuer->CA == 1) { - ret = 0; - } else - gnutls_assert(); - - return ret; -} - - - -void _gnutls_int2str(int k, char *data); - -#define MAX_DN_ELEM 1024 - -/* This function checks if 'certs' issuer is 'issuer_cert'. - * This does a straight (DER) compare of the issuer/subject fields in - * the given certificates. - * - * FIXME: use a real DN comparison algorithm. - */ -static -int compare_dn(gnutls_cert * cert, gnutls_cert * issuer_cert) -{ - ASN1_TYPE c2, c3; - int result, len1; - int len2; - int start1, start2, end1, end2; - - /* get the issuer of 'cert' - */ - if ((result = - _gnutls_asn1_create_element(_gnutls_get_pkix(), "PKIX1.Certificate", - &c2, "certificate2")) != ASN1_SUCCESS) { - gnutls_assert(); - return _gnutls_asn2err(result); - } - - result = asn1_der_decoding(&c2, cert->raw.data, cert->raw.size, NULL); - if (result != ASN1_SUCCESS) { - /* couldn't decode DER */ - gnutls_assert(); - asn1_delete_structure(&c2); - return _gnutls_asn2err(result); - } - - - - /* get the 'subject' info of 'issuer_cert' - */ - if ((result = - _gnutls_asn1_create_element(_gnutls_get_pkix(), "PKIX1.Certificate", - &c3, "certificate2")) != ASN1_SUCCESS) { - gnutls_assert(); - asn1_delete_structure(&c2); - return _gnutls_asn2err(result); - } - - result = - asn1_der_decoding(&c3, issuer_cert->raw.data, issuer_cert->raw.size, NULL); - if (result != ASN1_SUCCESS) { - /* couldn't decode DER */ - gnutls_assert(); - asn1_delete_structure(&c2); - return _gnutls_asn2err(result); - } - - - result = - asn1_der_decoding_startEnd(c2, cert->raw.data, cert->raw.size, - "certificate2.tbsCertificate.issuer", &start1, &end1); - asn1_delete_structure(&c2); - - if (result != ASN1_SUCCESS) { - gnutls_assert(); - asn1_delete_structure(&c3); - return _gnutls_asn2err(result); - } - - len1 = end1 - start1 + 1; - - result = - asn1_der_decoding_startEnd(c3, issuer_cert->raw.data, - issuer_cert->raw.size, - "certificate2.tbsCertificate.subject", - &start2, &end2); - asn1_delete_structure(&c3); - - if (result != ASN1_SUCCESS) { - gnutls_assert(); - return _gnutls_asn2err(result); - } - - len2 = end2 - start2 + 1; - - /* The error code returned does not really matter - * here. - */ - if (len1 != len2) { - gnutls_assert(); - return GNUTLS_E_INTERNAL_ERROR; - } - if (memcmp(&issuer_cert->raw.data[start2], - &cert->raw.data[start1], len1) != 0) { - gnutls_assert(); - return GNUTLS_E_INTERNAL_ERROR; - } - - /* they match */ - return 0; - -} - -static gnutls_cert *find_issuer(gnutls_cert * cert, - gnutls_cert * trusted_cas, int tcas_size) -{ - int i; - - /* this is serial search. - */ - - for (i = 0; i < tcas_size; i++) { - if (compare_dn(cert, &trusted_cas[i]) == 0) - return &trusted_cas[i]; - } - - gnutls_assert(); - return NULL; -} - -/* ret_trust is the value to return when the certificate chain is ok - * ret_else is the value to return otherwise. - */ -int gnutls_verify_certificate2(gnutls_cert * cert, - gnutls_cert * trusted_cas, int tcas_size, - void *CRLs, int crls_size, int ret_trust, - int ret_else) -{ -/* CRL is ignored for now */ - - gnutls_cert *issuer; - int ret; - - if (tcas_size >= 1) - issuer = find_issuer(cert, trusted_cas, tcas_size); - else { - gnutls_assert(); - return ret_else; - } - - /* issuer is not in trusted certificate - * authorities. - */ - if (issuer == NULL) { - gnutls_assert(); - return ret_else; - } - - ret = check_if_ca(cert, issuer); - if (ret != 0) { - gnutls_assert(); - return ret_else | GNUTLS_CERT_INVALID; - } - - ret = gnutls_x509_verify_signature(cert, issuer); - if (ret != 0) { - gnutls_assert(); - return ret_else | GNUTLS_CERT_INVALID; - } - - /* FIXME: Check CRL --not done yet. - */ - - - return ret_trust; -} - -/* The algorithm used is: - * 1. Check the certificate chain given by the peer, if it is ok. - * 2. If any certificate in the chain are revoked, not - * valid, or they are not CAs then the certificate is invalid. - * 3. If 1 is ok, then find a certificate in the trusted CAs file - * that has the DN of the issuer field in the last certificate - * in the peer's certificate chain. - * 4. If it does exist then verify it. If verification is ok then - * it is trusted. Otherwise it is just valid (but not trusted). - */ -/* This function verifies a X.509 certificate list. The certificate list should - * lead to a trusted CA in order to be trusted. - */ -int _gnutls_x509_verify_certificate(gnutls_cert * certificate_list, - int clist_size, - gnutls_cert * trusted_cas, - int tcas_size, void *CRLs, - int crls_size) -{ - int i = 0, ret; - gnutls_certificate_status status = 0; - - if (clist_size == 0) { - return GNUTLS_E_NO_CERTIFICATE_FOUND; - } - - /* Verify the certificate path */ - for (i = 0; i < clist_size; i++) { - if (i + 1 >= clist_size) - break; - - if ((ret = - gnutls_verify_certificate2(&certificate_list[i], - &certificate_list[i + 1], - 1, NULL, 0, 0, - GNUTLS_CERT_INVALID)) != - 0) { - /* - * We only accept the first certificate to be - * expired, revoked etc. If any of the certificates in the - * certificate chain is expired then the certificate - * is not valid. - */ - if (ret > 0) { - gnutls_assert(); - status |= ret; - } else { - gnutls_assert(); - return ret; - } - } - } - - if (status > 0) { /* If there is any problem in the - * certificate chain then mark as not trusted - * and return immediately. - */ - return (status | GNUTLS_CERT_NOT_TRUSTED); - } - - /* Now verify the last certificate in the certificate path - * against the trusted CA certificate list. - * - * If no CAs are present returns NOT_TRUSTED. Thus works - * in self signed etc certificates. - */ - ret = - gnutls_verify_certificate2(&certificate_list[i], trusted_cas, - tcas_size, CRLs, crls_size, 0, - GNUTLS_CERT_NOT_TRUSTED); - - if (ret > 0) { - /* if the last certificate in the certificate - * list is invalid, then the certificate is not - * trusted. - */ - gnutls_assert(); - status |= ret; - } - - if (ret < 0) { - gnutls_assert(); - return ret; - } - - /* if we got here, then it's trusted. - */ - return status; -} diff --git a/lib/x509_verify.h b/lib/x509_verify.h deleted file mode 100644 index 63cb56d887..0000000000 --- a/lib/x509_verify.h +++ /dev/null @@ -1,3 +0,0 @@ -int _gnutls_x509_verify_certificate(gnutls_cert * certificate_list, - int clist_size, gnutls_cert * trusted_cas, int tcas_size, void *CRLs, - int crls_size); diff --git a/libextra/auth_srp_rsa.c b/libextra/auth_srp_rsa.c index af453777f3..d5937baf1f 100644 --- a/libextra/auth_srp_rsa.c +++ b/libextra/auth_srp_rsa.c @@ -175,7 +175,7 @@ opaque* p; case GNUTLS_CRT_X509: if ((ret = _gnutls_x509_cert2gnutls_cert( &peer_cert, - info->raw_certificate_list[0], CERT_NO_COPY)) < 0) { + &info->raw_certificate_list[0], CERT_NO_COPY)) < 0) { gnutls_assert(); return ret; } @@ -188,7 +188,7 @@ opaque* p; } if ((ret = _E_gnutls_openpgp_cert2gnutls_cert( &peer_cert, - info->raw_certificate_list[0])) < 0) { + &info->raw_certificate_list[0])) < 0) { gnutls_assert(); return ret; } @@ -204,7 +204,7 @@ opaque* p; &peer_cert, &vparams, &signature); - _gnutls_free_cert( peer_cert); + _gnutls_free_cert( &peer_cert); if (ret < 0) { gnutls_assert(); return ret; diff --git a/libextra/gnutls_extra.h b/libextra/gnutls_extra.h index 51676ed806..a458512b9d 100644 --- a/libextra/gnutls_extra.h +++ b/libextra/gnutls_extra.h @@ -7,4 +7,4 @@ typedef time_t (*OPENPGP_KEY_EXPIRATION_TIME_FUNC)( const gnutls_datum*); typedef int (*OPENPGP_KEY_REQUEST)(gnutls_session, gnutls_datum*, const gnutls_certificate_credentials, opaque*,int); typedef int (*OPENPGP_FINGERPRINT)(const gnutls_datum*, unsigned char*, size_t*); -typedef int (*OPENPGP_CERT2GNUTLS_CERT)(gnutls_cert*, gnutls_datum); +typedef int (*OPENPGP_CERT2GNUTLS_CERT)(gnutls_cert*, const gnutls_datum*); diff --git a/libextra/gnutls_openpgp.c b/libextra/gnutls_openpgp.c index 67321f182f..8a17e44b06 100644 --- a/libextra/gnutls_openpgp.c +++ b/libextra/gnutls_openpgp.c @@ -319,59 +319,12 @@ openpgp_pk_to_gnutls_cert( gnutls_cert *cert, cdkPKT_public_key *pk ) break; } } - if( !rc ) { - cert->expiration_time = pk->expiredate; - cert->activation_time = pk->timestamp; - } if( rc ) release_mpi_array( cert->params, i-1 ); return rc; } - -static int -openpgp_sig_to_gnutls_cert( gnutls_cert *cert, cdkPKT_signature *sig ) -{ - CDK_STREAM tmp; - CDK_PACKET pkt; - uint8 buf[4096]; - int rc, nread; - - if( !cert || !sig ) { - gnutls_assert( ); - return GNUTLS_E_INVALID_REQUEST; - } - - tmp = cdk_stream_tmp( ); - if( !tmp ) { - gnutls_assert(); - return GNUTLS_E_MEMORY_ERROR; - } - - memset( &pkt, 0, sizeof pkt ); - pkt.pkttype = CDK_PKT_SIGNATURE; - pkt.pkt.signature = sig; - rc = cdk_pkt_build( tmp, &pkt ); - if( !rc ) { - cdk_stream_seek( tmp, 0 ); - nread = cdk_stream_read( tmp, buf, 4095 ); - if( nread ) { - rc = datum_append( &cert->signature, buf, nread ); - if( rc < 0 ) { - gnutls_assert( ); - rc = GNUTLS_E_MEMORY_ERROR; - } - } - } - else - rc = map_cdk_rc( rc ); - - cdk_stream_close( tmp ); - return rc; -} - - /*- * _gnutls_openpgp_key2gnutls_key - Converts an OpenPGP secret key to GnuTLS * @pkey: the GnuTLS private key context to store the key. @@ -463,7 +416,7 @@ leave: * specific certificate. -*/ int -_gnutls_openpgp_cert2gnutls_cert( gnutls_cert *cert, gnutls_datum raw ) +_gnutls_openpgp_cert2gnutls_cert( gnutls_cert *cert, const gnutls_datum *raw ) { CDK_KBNODE knode = NULL; CDK_PACKET *pkt = NULL; @@ -476,13 +429,13 @@ _gnutls_openpgp_cert2gnutls_cert( gnutls_cert *cert, gnutls_datum raw ) memset( cert, 0, sizeof *cert ); - rc = cdk_kbnode_read_from_mem( &knode, raw.data, raw.size ); + rc = cdk_kbnode_read_from_mem( &knode, raw->data, raw->size ); if( !(rc = map_cdk_rc( rc )) ) pkt = cdk_kbnode_find_packet( knode, CDK_PKT_PUBLIC_KEY ); if( !pkt ) rc = GNUTLS_E_INTERNAL_ERROR; if( !rc ) - rc = _gnutls_set_datum( &cert->raw, raw.data, raw.size ); + rc = _gnutls_set_datum( &cert->raw, raw->data, raw->size ); if( !rc ) rc = openpgp_pk_to_gnutls_cert( cert, pkt->pkt.public_key ); @@ -628,11 +581,6 @@ gnutls_certificate_set_openpgp_key_mem( gnutls_certificate_credentials res, openpgp_pk_to_gnutls_cert( &res->cert_list[n][0], pk ); i++; } - else if( pkt->pkttype == CDK_PKT_SIGNATURE ) { - int n = res->ncerts; - cdkPKT_signature *sig = pkt->pkt.signature; - openpgp_sig_to_gnutls_cert( &res->cert_list[n][0], sig ); - } } res->ncerts++; @@ -735,11 +683,6 @@ gnutls_certificate_set_openpgp_key_file( gnutls_certificate_credentials res, openpgp_pk_to_gnutls_cert( &res->cert_list[n][0], pk ); i++; } - else if( pkt->pkttype == CDK_PKT_SIGNATURE ) { - int n = res->ncerts; - cdkPKT_signature *sig = pkt->pkt.signature; - openpgp_sig_to_gnutls_cert( &res->cert_list[n][0], sig ); - } } } if( rc == CDK_EOF && i > 1 ) diff --git a/libextra/gnutls_openpgp.h b/libextra/gnutls_openpgp.h index 4260cb9411..c23c1d6d0b 100644 --- a/libextra/gnutls_openpgp.h +++ b/libextra/gnutls_openpgp.h @@ -93,7 +93,7 @@ int gnutls_openpgp_key_to_xml( /* internal */ int _gnutls_openpgp_cert2gnutls_cert( gnutls_cert *cert, - gnutls_datum raw ); + const gnutls_datum *raw ); int _gnutls_openpgp_request_key( diff --git a/src/cli-gaa.c b/src/cli-gaa.c index ddf000ebe7..81ab6de58f 100644 --- a/src/cli-gaa.c +++ b/src/cli-gaa.c @@ -142,6 +142,7 @@ void gaa_help(void) __gaa_helpsingle(0, "kx", "kx1 kx2... ", "Key exchange methods to enable."); __gaa_helpsingle(0, "ctypes", "certType1 certType2... ", "Certificate types to enable."); __gaa_helpsingle(0, "x509cafile", "FILE ", "Certificate file to use."); + __gaa_helpsingle(0, "x509crlfile", "FILE ", "CRL file to use."); __gaa_helpsingle(0, "pgpkeyfile", "FILE ", "PGP Key file to use."); __gaa_helpsingle(0, "pgpkeyring", "FILE ", "PGP Key ring file to use."); __gaa_helpsingle(0, "pgptrustdb", "FILE ", "PGP trustdb file to use."); @@ -168,24 +169,26 @@ typedef struct _gaainfo gaainfo; struct _gaainfo { -#line 97 "cli.gaa" +#line 100 "cli.gaa" char *rest_args; -#line 87 "cli.gaa" +#line 90 "cli.gaa" char *srp_passwd; -#line 84 "cli.gaa" +#line 87 "cli.gaa" char *srp_username; -#line 81 "cli.gaa" +#line 84 "cli.gaa" char *x509_certfile; -#line 78 "cli.gaa" +#line 81 "cli.gaa" char *x509_keyfile; -#line 75 "cli.gaa" +#line 78 "cli.gaa" char *pgp_certfile; -#line 72 "cli.gaa" +#line 75 "cli.gaa" char *pgp_trustdb; -#line 69 "cli.gaa" +#line 72 "cli.gaa" char *pgp_keyring; -#line 66 "cli.gaa" +#line 69 "cli.gaa" char *pgp_keyfile; +#line 66 "cli.gaa" + char *x509_crlfile; #line 63 "cli.gaa" char *x509_cafile; #line 60 "cli.gaa" @@ -282,7 +285,7 @@ int gaa_error = 0; #define GAA_MULTIPLE_OPTION 3 #define GAA_REST 0 -#define GAA_NB_OPTION 27 +#define GAA_NB_OPTION 28 #define GAAOPTID_copyright 1 #define GAAOPTID_version 2 #define GAAOPTID_help 3 @@ -295,21 +298,22 @@ int gaa_error = 0; #define GAAOPTID_pgptrustdb 10 #define GAAOPTID_pgpkeyring 11 #define GAAOPTID_pgpkeyfile 12 -#define GAAOPTID_x509cafile 13 -#define GAAOPTID_ctypes 14 -#define GAAOPTID_kx 15 -#define GAAOPTID_macs 16 -#define GAAOPTID_comp 17 -#define GAAOPTID_protocols 18 -#define GAAOPTID_ciphers 19 -#define GAAOPTID_recordsize 20 -#define GAAOPTID_port 21 -#define GAAOPTID_xml 22 -#define GAAOPTID_fingerprint 23 -#define GAAOPTID_x509fmtder 24 -#define GAAOPTID_crlf 25 -#define GAAOPTID_starttls 26 -#define GAAOPTID_resume 27 +#define GAAOPTID_x509crlfile 13 +#define GAAOPTID_x509cafile 14 +#define GAAOPTID_ctypes 15 +#define GAAOPTID_kx 16 +#define GAAOPTID_macs 17 +#define GAAOPTID_comp 18 +#define GAAOPTID_protocols 19 +#define GAAOPTID_ciphers 20 +#define GAAOPTID_recordsize 21 +#define GAAOPTID_port 22 +#define GAAOPTID_xml 23 +#define GAAOPTID_fingerprint 24 +#define GAAOPTID_x509fmtder 25 +#define GAAOPTID_crlf 26 +#define GAAOPTID_starttls 27 +#define GAAOPTID_resume 28 #line 168 "gaa.skel" @@ -544,6 +548,12 @@ struct GAAOPTION_pgpkeyfile int size1; }; +struct GAAOPTION_x509crlfile +{ + char* arg1; + int size1; +}; + struct GAAOPTION_x509cafile { char* arg1; @@ -642,6 +652,7 @@ int gaa_get_option_num(char *str, int status) GAA_CHECK1STR("", GAAOPTID_pgptrustdb); GAA_CHECK1STR("", GAAOPTID_pgpkeyring); GAA_CHECK1STR("", GAAOPTID_pgpkeyfile); + GAA_CHECK1STR("", GAAOPTID_x509crlfile); GAA_CHECK1STR("", GAAOPTID_x509cafile); GAA_CHECK1STR("", GAAOPTID_ctypes); GAA_CHECK1STR("", GAAOPTID_kx); @@ -679,6 +690,7 @@ int gaa_get_option_num(char *str, int status) GAA_CHECKSTR("pgptrustdb", GAAOPTID_pgptrustdb); GAA_CHECKSTR("pgpkeyring", GAAOPTID_pgpkeyring); GAA_CHECKSTR("pgpkeyfile", GAAOPTID_pgpkeyfile); + GAA_CHECKSTR("x509crlfile", GAAOPTID_x509crlfile); GAA_CHECKSTR("x509cafile", GAAOPTID_x509cafile); GAA_CHECKSTR("ctypes", GAAOPTID_ctypes); GAA_CHECKSTR("kx", GAAOPTID_kx); @@ -714,6 +726,7 @@ int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list) struct GAAOPTION_pgptrustdb GAATMP_pgptrustdb; struct GAAOPTION_pgpkeyring GAATMP_pgpkeyring; struct GAAOPTION_pgpkeyfile GAATMP_pgpkeyfile; + struct GAAOPTION_x509crlfile GAATMP_x509crlfile; struct GAAOPTION_x509cafile GAATMP_x509cafile; struct GAAOPTION_ctypes GAATMP_ctypes; struct GAAOPTION_kx GAATMP_kx; @@ -745,28 +758,28 @@ int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list) { case GAAOPTID_copyright: OK = 0; -#line 95 "cli.gaa" +#line 98 "cli.gaa" { print_license(); exit(0); ;}; return GAA_OK; break; case GAAOPTID_version: OK = 0; -#line 94 "cli.gaa" +#line 97 "cli.gaa" { cli_version(); exit(0); ;}; return GAA_OK; break; case GAAOPTID_help: OK = 0; -#line 92 "cli.gaa" +#line 95 "cli.gaa" { gaa_help(); exit(0); ;}; return GAA_OK; break; case GAAOPTID_list: OK = 0; -#line 91 "cli.gaa" +#line 94 "cli.gaa" { print_list(); exit(0); ;}; return GAA_OK; @@ -776,7 +789,7 @@ int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list) GAA_TESTMOREARGS; GAA_FILL(GAATMP_srppasswd.arg1, gaa_getstr, GAATMP_srppasswd.size1); gaa_index++; -#line 88 "cli.gaa" +#line 91 "cli.gaa" { gaaval->srp_passwd = GAATMP_srppasswd.arg1 ;}; return GAA_OK; @@ -786,7 +799,7 @@ int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list) GAA_TESTMOREARGS; GAA_FILL(GAATMP_srpusername.arg1, gaa_getstr, GAATMP_srpusername.size1); gaa_index++; -#line 85 "cli.gaa" +#line 88 "cli.gaa" { gaaval->srp_username = GAATMP_srpusername.arg1 ;}; return GAA_OK; @@ -796,7 +809,7 @@ int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list) GAA_TESTMOREARGS; GAA_FILL(GAATMP_x509certfile.arg1, gaa_getstr, GAATMP_x509certfile.size1); gaa_index++; -#line 82 "cli.gaa" +#line 85 "cli.gaa" { gaaval->x509_certfile = GAATMP_x509certfile.arg1 ;}; return GAA_OK; @@ -806,7 +819,7 @@ int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list) GAA_TESTMOREARGS; GAA_FILL(GAATMP_x509keyfile.arg1, gaa_getstr, GAATMP_x509keyfile.size1); gaa_index++; -#line 79 "cli.gaa" +#line 82 "cli.gaa" { gaaval->x509_keyfile = GAATMP_x509keyfile.arg1 ;}; return GAA_OK; @@ -816,7 +829,7 @@ int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list) GAA_TESTMOREARGS; GAA_FILL(GAATMP_pgpcertfile.arg1, gaa_getstr, GAATMP_pgpcertfile.size1); gaa_index++; -#line 76 "cli.gaa" +#line 79 "cli.gaa" { gaaval->pgp_certfile = GAATMP_pgpcertfile.arg1 ;}; return GAA_OK; @@ -826,7 +839,7 @@ int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list) GAA_TESTMOREARGS; GAA_FILL(GAATMP_pgptrustdb.arg1, gaa_getstr, GAATMP_pgptrustdb.size1); gaa_index++; -#line 73 "cli.gaa" +#line 76 "cli.gaa" { gaaval->pgp_trustdb = GAATMP_pgptrustdb.arg1 ;}; return GAA_OK; @@ -836,7 +849,7 @@ int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list) GAA_TESTMOREARGS; GAA_FILL(GAATMP_pgpkeyring.arg1, gaa_getstr, GAATMP_pgpkeyring.size1); gaa_index++; -#line 70 "cli.gaa" +#line 73 "cli.gaa" { gaaval->pgp_keyring = GAATMP_pgpkeyring.arg1 ;}; return GAA_OK; @@ -846,11 +859,21 @@ int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list) GAA_TESTMOREARGS; GAA_FILL(GAATMP_pgpkeyfile.arg1, gaa_getstr, GAATMP_pgpkeyfile.size1); gaa_index++; -#line 67 "cli.gaa" +#line 70 "cli.gaa" { gaaval->pgp_keyfile = GAATMP_pgpkeyfile.arg1 ;}; return GAA_OK; break; + case GAAOPTID_x509crlfile: + OK = 0; + GAA_TESTMOREARGS; + GAA_FILL(GAATMP_x509crlfile.arg1, gaa_getstr, GAATMP_x509crlfile.size1); + gaa_index++; +#line 67 "cli.gaa" +{ gaaval->x509_crlfile = GAATMP_x509crlfile.arg1 ;}; + + return GAA_OK; + break; case GAAOPTID_x509cafile: OK = 0; GAA_TESTMOREARGS; @@ -975,7 +998,7 @@ int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list) GAA_TESTMOREARGS; GAA_FILL(GAAREST_tmp.arg1, gaa_getstr, GAAREST_tmp.size1); gaa_index++; -#line 98 "cli.gaa" +#line 101 "cli.gaa" { gaaval->rest_args = GAAREST_tmp.arg1; ;}; return GAA_OK; @@ -1004,11 +1027,11 @@ int gaa(int argc, char **argv, gaainfo *gaaval) if(inited == 0) { -#line 100 "cli.gaa" +#line 103 "cli.gaa" { gaaval->resume=0; gaaval->port=443; gaaval->rest_args=NULL; gaaval->ciphers=NULL; gaaval->kx=NULL; gaaval->comp=NULL; gaaval->macs=NULL; gaaval->ctype=NULL; gaaval->nciphers=0; gaaval->nkx=0; gaaval->ncomp=0; gaaval->nmacs=0; gaaval->nctype = 0; gaaval->record_size=0; - gaaval->fingerprint=0; gaaval->pgp_trustdb=NULL; gaaval->pgp_keyring=NULL; + gaaval->fingerprint=0; gaaval->pgp_trustdb=NULL; gaaval->pgp_keyring=NULL; gaaval->x509_crlfile = NULL; gaaval->x509_cafile = NULL; gaaval->pgp_keyfile=NULL; gaaval->pgp_certfile=NULL; gaaval->x509_keyfile=NULL; gaaval->x509_certfile=NULL; gaaval->crlf = 0; gaaval->xml = 0; gaaval->srp_username=NULL; gaaval->srp_passwd=NULL; gaaval->fmtder = 0; gaaval->starttls =0; ;}; diff --git a/src/cli-gaa.h b/src/cli-gaa.h index e4c115b458..128804cd4b 100644 --- a/src/cli-gaa.h +++ b/src/cli-gaa.h @@ -8,24 +8,26 @@ typedef struct _gaainfo gaainfo; struct _gaainfo { -#line 97 "cli.gaa" +#line 100 "cli.gaa" char *rest_args; -#line 87 "cli.gaa" +#line 90 "cli.gaa" char *srp_passwd; -#line 84 "cli.gaa" +#line 87 "cli.gaa" char *srp_username; -#line 81 "cli.gaa" +#line 84 "cli.gaa" char *x509_certfile; -#line 78 "cli.gaa" +#line 81 "cli.gaa" char *x509_keyfile; -#line 75 "cli.gaa" +#line 78 "cli.gaa" char *pgp_certfile; -#line 72 "cli.gaa" +#line 75 "cli.gaa" char *pgp_trustdb; -#line 69 "cli.gaa" +#line 72 "cli.gaa" char *pgp_keyring; -#line 66 "cli.gaa" +#line 69 "cli.gaa" char *pgp_keyfile; +#line 66 "cli.gaa" + char *x509_crlfile; #line 63 "cli.gaa" char *x509_cafile; #line 60 "cli.gaa" @@ -108,16 +108,6 @@ void init_global_tls_stuff(void); #define MAX(X,Y) (X >= Y ? X : Y); -#define DEFAULT_X509_CAFILE "x509/ca.pem" -#define DEFAULT_X509_KEYFILE2 "x509/clikey-dsa.pem" -#define DEFAULT_X509_CERTFILE2 "x509/clicert-dsa.pem" - -#define DEFAULT_X509_KEYFILE "x509/clikey.pem" -#define DEFAULT_X509_CERTFILE "x509/clicert.pem" - -#define DEFAULT_PGP_KEYFILE "openpgp/cli_sec.asc" -#define DEFAULT_PGP_CERTFILE "openpgp/cli_pub.asc" -#define DEFAULT_PGP_KEYRING "openpgp/cli_ring.gpg" /* initializes a gnutls_session with some defaults. */ @@ -370,8 +360,6 @@ int main(int argc, char **argv) return 0; } -#undef DEBUG - static gaainfo info; void gaa_parser(int argc, char **argv) { @@ -395,48 +383,15 @@ void gaa_parser(int argc, char **argv) else x509ctype = GNUTLS_X509_FMT_DER; -#ifdef DEBUG - if (info.x509_certfile != NULL) - x509_certfile = info.x509_certfile; - else - x509_certfile = DEFAULT_X509_CERTFILE; - - if (info.x509_keyfile != NULL) - x509_keyfile = info.x509_keyfile; - else - x509_keyfile = DEFAULT_X509_KEYFILE; - - if (info.x509_cafile != NULL) - x509_cafile = info.x509_certfile; - else - x509_cafile = DEFAULT_X509_CAFILE; - - if (info.pgp_certfile != NULL) - pgp_certfile = info.pgp_certfile; - else - pgp_certfile = DEFAULT_PGP_CERTFILE; - - if (info.pgp_keyfile != NULL) - pgp_keyfile = info.pgp_keyfile; - else - pgp_keyfile = DEFAULT_PGP_KEYFILE; - - if (info.srp_passwd != NULL) - srp_passwd = info.srp_passwd; - - if (info.srp_username != NULL) - srp_username = info.srp_username; -#else srp_username = info.srp_username; srp_passwd = info.srp_passwd; x509_cafile = info.x509_cafile; + x509_crlfile = info.x509_crlfile; x509_keyfile = info.x509_keyfile; x509_certfile = info.x509_certfile; pgp_keyfile = info.pgp_keyfile; pgp_certfile = info.pgp_certfile; -#endif - pgp_keyring = info.pgp_keyring; pgp_trustdb = info.pgp_trustdb; @@ -605,6 +560,17 @@ int ret; } } + if (x509_crlfile != NULL) { + ret = + gnutls_certificate_set_x509_crl_file(xcred, + x509_crlfile, x509ctype); + if (ret < 0) { + fprintf(stderr, "Error setting the x509 CRL file\n"); + } else { + printf("Processed %d CRL(s).\n", ret); + } + } + if (x509_certfile != NULL) { ret = gnutls_certificate_set_x509_key_file(xcred, diff --git a/src/cli.gaa b/src/cli.gaa index 67929b1f1a..3b21543cff 100644 --- a/src/cli.gaa +++ b/src/cli.gaa @@ -63,6 +63,9 @@ option (ctypes) *STR "certType1 certType2..." { $ctype = $1; $nctype = @1 } "Cer #char *x509_cafile; option (x509cafile) STR "FILE" { $x509_cafile = $1 } "Certificate file to use." +#char *x509_crlfile; +option (x509crlfile) STR "FILE" { $x509_crlfile = $1 } "CRL file to use." + #char *pgp_keyfile; option (pgpkeyfile) STR "FILE" { $pgp_keyfile = $1 } "PGP Key file to use." @@ -100,7 +103,7 @@ rest STR "hostname" { $rest_args = $1; } init { $resume=0; $port=443; $rest_args=NULL; $ciphers=NULL; $kx=NULL; $comp=NULL; $macs=NULL; $ctype=NULL; $nciphers=0; $nkx=0; $ncomp=0; $nmacs=0; $nctype = 0; $record_size=0; - $fingerprint=0; $pgp_trustdb=NULL; $pgp_keyring=NULL; + $fingerprint=0; $pgp_trustdb=NULL; $pgp_keyring=NULL; $x509_crlfile = NULL; $x509_cafile = NULL; $pgp_keyfile=NULL; $pgp_certfile=NULL; $x509_keyfile=NULL; $x509_certfile=NULL; $crlf = 0; $xml = 0; $srp_username=NULL; $srp_passwd=NULL; $fmtder = 0; $starttls =0; } diff --git a/src/serv-gaa.c b/src/serv-gaa.c index 5fe708a9f9..f8f0f15d77 100644 --- a/src/serv-gaa.c +++ b/src/serv-gaa.c @@ -134,6 +134,7 @@ void gaa_help(void) __gaa_helpsingle('d', "dhparams", "FILE ", "DH params file to use."); __gaa_helpsingle(0, "x509fmtder", "", "Use DER format for certificates"); __gaa_helpsingle(0, "x509cafile", "FILE ", "Certificate file to use."); + __gaa_helpsingle(0, "x509crlfile", "FILE ", "CRL file to use."); __gaa_helpsingle(0, "pgpkeyring", "FILE ", "PGP Key ring file to use."); __gaa_helpsingle(0, "pgptrustdb", "FILE ", "PGP trustdb file to use."); __gaa_helpsingle(0, "pgpkeyfile", "FILE ", "PGP Key file to use."); @@ -166,46 +167,48 @@ typedef struct _gaainfo gaainfo; struct _gaainfo { -#line 83 "serv.gaa" +#line 86 "serv.gaa" char **ctype; -#line 82 "serv.gaa" +#line 85 "serv.gaa" int nctype; -#line 79 "serv.gaa" +#line 82 "serv.gaa" char **kx; -#line 78 "serv.gaa" +#line 81 "serv.gaa" int nkx; -#line 75 "serv.gaa" +#line 78 "serv.gaa" char **macs; -#line 74 "serv.gaa" +#line 77 "serv.gaa" int nmacs; -#line 71 "serv.gaa" +#line 74 "serv.gaa" char **comp; -#line 70 "serv.gaa" +#line 73 "serv.gaa" int ncomp; -#line 67 "serv.gaa" +#line 70 "serv.gaa" char **proto; -#line 66 "serv.gaa" +#line 69 "serv.gaa" int nproto; -#line 63 "serv.gaa" +#line 66 "serv.gaa" char **ciphers; -#line 62 "serv.gaa" +#line 65 "serv.gaa" int nciphers; -#line 58 "serv.gaa" +#line 61 "serv.gaa" char *srp_passwd_conf; -#line 55 "serv.gaa" +#line 58 "serv.gaa" char *srp_passwd; -#line 52 "serv.gaa" +#line 55 "serv.gaa" char *x509_certfile; -#line 49 "serv.gaa" +#line 52 "serv.gaa" char *x509_keyfile; -#line 46 "serv.gaa" +#line 49 "serv.gaa" char *pgp_certfile; -#line 43 "serv.gaa" +#line 46 "serv.gaa" char *pgp_keyfile; -#line 40 "serv.gaa" +#line 43 "serv.gaa" char *pgp_trustdb; -#line 37 "serv.gaa" +#line 40 "serv.gaa" char *pgp_keyring; +#line 37 "serv.gaa" + char *x509_crlfile; #line 34 "serv.gaa" char *x509_cafile; #line 31 "serv.gaa" @@ -276,7 +279,7 @@ int gaa_error = 0; #define GAA_MULTIPLE_OPTION 3 #define GAA_REST 0 -#define GAA_NB_OPTION 27 +#define GAA_NB_OPTION 28 #define GAAOPTID_copyright 1 #define GAAOPTID_version 2 #define GAAOPTID_help 3 @@ -295,15 +298,16 @@ int gaa_error = 0; #define GAAOPTID_pgpkeyfile 16 #define GAAOPTID_pgptrustdb 17 #define GAAOPTID_pgpkeyring 18 -#define GAAOPTID_x509cafile 19 -#define GAAOPTID_x509fmtder 20 -#define GAAOPTID_dhparams 21 -#define GAAOPTID_echo 22 -#define GAAOPTID_http 23 -#define GAAOPTID_nodb 24 -#define GAAOPTID_quiet 25 -#define GAAOPTID_port 26 -#define GAAOPTID_generate 27 +#define GAAOPTID_x509crlfile 19 +#define GAAOPTID_x509cafile 20 +#define GAAOPTID_x509fmtder 21 +#define GAAOPTID_dhparams 22 +#define GAAOPTID_echo 23 +#define GAAOPTID_http 24 +#define GAAOPTID_nodb 25 +#define GAAOPTID_quiet 26 +#define GAAOPTID_port 27 +#define GAAOPTID_generate 28 #line 168 "gaa.skel" @@ -574,6 +578,12 @@ struct GAAOPTION_pgpkeyring int size1; }; +struct GAAOPTION_x509crlfile +{ + char* arg1; + int size1; +}; + struct GAAOPTION_x509cafile { char* arg1; @@ -635,6 +645,7 @@ int gaa_get_option_num(char *str, int status) GAA_CHECK1STR("", GAAOPTID_pgpkeyfile); GAA_CHECK1STR("", GAAOPTID_pgptrustdb); GAA_CHECK1STR("", GAAOPTID_pgpkeyring); + GAA_CHECK1STR("", GAAOPTID_x509crlfile); GAA_CHECK1STR("", GAAOPTID_x509cafile); GAA_CHECK1STR("d", GAAOPTID_dhparams); GAA_CHECK1STR("p", GAAOPTID_port); @@ -672,6 +683,7 @@ int gaa_get_option_num(char *str, int status) GAA_CHECKSTR("pgpkeyfile", GAAOPTID_pgpkeyfile); GAA_CHECKSTR("pgptrustdb", GAAOPTID_pgptrustdb); GAA_CHECKSTR("pgpkeyring", GAAOPTID_pgpkeyring); + GAA_CHECKSTR("x509crlfile", GAAOPTID_x509crlfile); GAA_CHECKSTR("x509cafile", GAAOPTID_x509cafile); GAA_CHECKSTR("x509fmtder", GAAOPTID_x509fmtder); GAA_CHECKSTR("dhparams", GAAOPTID_dhparams); @@ -707,6 +719,7 @@ int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list) struct GAAOPTION_pgpkeyfile GAATMP_pgpkeyfile; struct GAAOPTION_pgptrustdb GAATMP_pgptrustdb; struct GAAOPTION_pgpkeyring GAATMP_pgpkeyring; + struct GAAOPTION_x509crlfile GAATMP_x509crlfile; struct GAAOPTION_x509cafile GAATMP_x509cafile; struct GAAOPTION_dhparams GAATMP_dhparams; struct GAAOPTION_port GAATMP_port; @@ -732,28 +745,28 @@ int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list) { case GAAOPTID_copyright: OK = 0; -#line 91 "serv.gaa" +#line 94 "serv.gaa" { print_license(); exit(0); ;}; return GAA_OK; break; case GAAOPTID_version: OK = 0; -#line 90 "serv.gaa" +#line 93 "serv.gaa" { serv_version(); exit(0); ;}; return GAA_OK; break; case GAAOPTID_help: OK = 0; -#line 88 "serv.gaa" +#line 91 "serv.gaa" { gaa_help(); exit(0); ;}; return GAA_OK; break; case GAAOPTID_list: OK = 0; -#line 87 "serv.gaa" +#line 90 "serv.gaa" { print_list(); exit(0); ;}; return GAA_OK; @@ -761,7 +774,7 @@ int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list) case GAAOPTID_ctypes: OK = 0; GAA_LIST_FILL(GAATMP_ctypes.arg1, gaa_getstr, char*, GAATMP_ctypes.size1); -#line 84 "serv.gaa" +#line 87 "serv.gaa" { gaaval->ctype = GAATMP_ctypes.arg1; gaaval->nctype = GAATMP_ctypes.size1 ;}; return GAA_OK; @@ -769,7 +782,7 @@ int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list) case GAAOPTID_kx: OK = 0; GAA_LIST_FILL(GAATMP_kx.arg1, gaa_getstr, char*, GAATMP_kx.size1); -#line 80 "serv.gaa" +#line 83 "serv.gaa" { gaaval->kx = GAATMP_kx.arg1; gaaval->nkx = GAATMP_kx.size1 ;}; return GAA_OK; @@ -777,7 +790,7 @@ int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list) case GAAOPTID_macs: OK = 0; GAA_LIST_FILL(GAATMP_macs.arg1, gaa_getstr, char*, GAATMP_macs.size1); -#line 76 "serv.gaa" +#line 79 "serv.gaa" { gaaval->macs = GAATMP_macs.arg1; gaaval->nmacs = GAATMP_macs.size1 ;}; return GAA_OK; @@ -785,7 +798,7 @@ int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list) case GAAOPTID_comp: OK = 0; GAA_LIST_FILL(GAATMP_comp.arg1, gaa_getstr, char*, GAATMP_comp.size1); -#line 72 "serv.gaa" +#line 75 "serv.gaa" { gaaval->comp = GAATMP_comp.arg1; gaaval->ncomp = GAATMP_comp.size1 ;}; return GAA_OK; @@ -793,7 +806,7 @@ int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list) case GAAOPTID_protocols: OK = 0; GAA_LIST_FILL(GAATMP_protocols.arg1, gaa_getstr, char*, GAATMP_protocols.size1); -#line 68 "serv.gaa" +#line 71 "serv.gaa" { gaaval->proto = GAATMP_protocols.arg1; gaaval->nproto = GAATMP_protocols.size1 ;}; return GAA_OK; @@ -801,7 +814,7 @@ int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list) case GAAOPTID_ciphers: OK = 0; GAA_LIST_FILL(GAATMP_ciphers.arg1, gaa_getstr, char*, GAATMP_ciphers.size1); -#line 64 "serv.gaa" +#line 67 "serv.gaa" { gaaval->ciphers = GAATMP_ciphers.arg1; gaaval->nciphers = GAATMP_ciphers.size1 ;}; return GAA_OK; @@ -811,7 +824,7 @@ int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list) GAA_TESTMOREARGS; GAA_FILL(GAATMP_srppasswdconf.arg1, gaa_getstr, GAATMP_srppasswdconf.size1); gaa_index++; -#line 59 "serv.gaa" +#line 62 "serv.gaa" { gaaval->srp_passwd_conf = GAATMP_srppasswdconf.arg1 ;}; return GAA_OK; @@ -821,7 +834,7 @@ int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list) GAA_TESTMOREARGS; GAA_FILL(GAATMP_srppasswd.arg1, gaa_getstr, GAATMP_srppasswd.size1); gaa_index++; -#line 56 "serv.gaa" +#line 59 "serv.gaa" { gaaval->srp_passwd = GAATMP_srppasswd.arg1 ;}; return GAA_OK; @@ -831,7 +844,7 @@ int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list) GAA_TESTMOREARGS; GAA_FILL(GAATMP_x509certfile.arg1, gaa_getstr, GAATMP_x509certfile.size1); gaa_index++; -#line 53 "serv.gaa" +#line 56 "serv.gaa" { gaaval->x509_certfile = GAATMP_x509certfile.arg1 ;}; return GAA_OK; @@ -841,7 +854,7 @@ int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list) GAA_TESTMOREARGS; GAA_FILL(GAATMP_x509keyfile.arg1, gaa_getstr, GAATMP_x509keyfile.size1); gaa_index++; -#line 50 "serv.gaa" +#line 53 "serv.gaa" { gaaval->x509_keyfile = GAATMP_x509keyfile.arg1 ;}; return GAA_OK; @@ -851,7 +864,7 @@ int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list) GAA_TESTMOREARGS; GAA_FILL(GAATMP_pgpcertfile.arg1, gaa_getstr, GAATMP_pgpcertfile.size1); gaa_index++; -#line 47 "serv.gaa" +#line 50 "serv.gaa" { gaaval->pgp_certfile = GAATMP_pgpcertfile.arg1 ;}; return GAA_OK; @@ -861,7 +874,7 @@ int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list) GAA_TESTMOREARGS; GAA_FILL(GAATMP_pgpkeyfile.arg1, gaa_getstr, GAATMP_pgpkeyfile.size1); gaa_index++; -#line 44 "serv.gaa" +#line 47 "serv.gaa" { gaaval->pgp_keyfile = GAATMP_pgpkeyfile.arg1 ;}; return GAA_OK; @@ -871,7 +884,7 @@ int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list) GAA_TESTMOREARGS; GAA_FILL(GAATMP_pgptrustdb.arg1, gaa_getstr, GAATMP_pgptrustdb.size1); gaa_index++; -#line 41 "serv.gaa" +#line 44 "serv.gaa" { gaaval->pgp_trustdb = GAATMP_pgptrustdb.arg1 ;}; return GAA_OK; @@ -881,11 +894,21 @@ int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list) GAA_TESTMOREARGS; GAA_FILL(GAATMP_pgpkeyring.arg1, gaa_getstr, GAATMP_pgpkeyring.size1); gaa_index++; -#line 38 "serv.gaa" +#line 41 "serv.gaa" { gaaval->pgp_keyring = GAATMP_pgpkeyring.arg1 ;}; return GAA_OK; break; + case GAAOPTID_x509crlfile: + OK = 0; + GAA_TESTMOREARGS; + GAA_FILL(GAATMP_x509crlfile.arg1, gaa_getstr, GAATMP_x509crlfile.size1); + gaa_index++; +#line 38 "serv.gaa" +{ gaaval->x509_crlfile = GAATMP_x509crlfile.arg1 ;}; + + return GAA_OK; + break; case GAAOPTID_x509cafile: OK = 0; GAA_TESTMOREARGS; @@ -982,12 +1005,12 @@ int gaa(int argc, char **argv, gaainfo *gaaval) if(inited == 0) { -#line 94 "serv.gaa" +#line 97 "serv.gaa" { gaaval->generate=0; gaaval->port=5556; gaaval->http=0; gaaval->ciphers=NULL; gaaval->kx=NULL; gaaval->comp=NULL; gaaval->macs=NULL; gaaval->ctype=NULL; gaaval->nciphers=0; gaaval->nkx=0; gaaval->ncomp=0; gaaval->nmacs=0; gaaval->nctype = 0; gaaval->nodb = 0; gaaval->x509_cafile = NULL; gaaval->pgp_keyfile=NULL; gaaval->pgp_certfile=NULL; - gaaval->x509_keyfile=NULL; gaaval->x509_certfile=NULL; + gaaval->x509_keyfile=NULL; gaaval->x509_certfile=NULL; gaaval->x509_crlfile = NULL; gaaval->srp_passwd=NULL; gaaval->srp_passwd_conf=NULL; gaaval->quiet = 0; gaaval->pgp_trustdb=NULL; gaaval->pgp_keyring=NULL; gaaval->fmtder = 0; gaaval->dh_params_file=NULL; ;}; diff --git a/src/serv-gaa.h b/src/serv-gaa.h index 918eee5f65..8eb3e76be0 100644 --- a/src/serv-gaa.h +++ b/src/serv-gaa.h @@ -8,46 +8,48 @@ typedef struct _gaainfo gaainfo; struct _gaainfo { -#line 83 "serv.gaa" +#line 86 "serv.gaa" char **ctype; -#line 82 "serv.gaa" +#line 85 "serv.gaa" int nctype; -#line 79 "serv.gaa" +#line 82 "serv.gaa" char **kx; -#line 78 "serv.gaa" +#line 81 "serv.gaa" int nkx; -#line 75 "serv.gaa" +#line 78 "serv.gaa" char **macs; -#line 74 "serv.gaa" +#line 77 "serv.gaa" int nmacs; -#line 71 "serv.gaa" +#line 74 "serv.gaa" char **comp; -#line 70 "serv.gaa" +#line 73 "serv.gaa" int ncomp; -#line 67 "serv.gaa" +#line 70 "serv.gaa" char **proto; -#line 66 "serv.gaa" +#line 69 "serv.gaa" int nproto; -#line 63 "serv.gaa" +#line 66 "serv.gaa" char **ciphers; -#line 62 "serv.gaa" +#line 65 "serv.gaa" int nciphers; -#line 58 "serv.gaa" +#line 61 "serv.gaa" char *srp_passwd_conf; -#line 55 "serv.gaa" +#line 58 "serv.gaa" char *srp_passwd; -#line 52 "serv.gaa" +#line 55 "serv.gaa" char *x509_certfile; -#line 49 "serv.gaa" +#line 52 "serv.gaa" char *x509_keyfile; -#line 46 "serv.gaa" +#line 49 "serv.gaa" char *pgp_certfile; -#line 43 "serv.gaa" +#line 46 "serv.gaa" char *pgp_keyfile; -#line 40 "serv.gaa" +#line 43 "serv.gaa" char *pgp_trustdb; -#line 37 "serv.gaa" +#line 40 "serv.gaa" char *pgp_keyring; +#line 37 "serv.gaa" + char *x509_crlfile; #line 34 "serv.gaa" char *x509_cafile; #line 31 "serv.gaa" diff --git a/src/serv.c b/src/serv.c index 424c8a0ff0..14a774a7dc 100644 --- a/src/serv.c +++ b/src/serv.c @@ -152,7 +152,6 @@ static void listener_free(listener_item * j) /* we use primes up to 1024 in this server. * otherwise we should add them here. */ -static int prime_nums[] = { 768, 1024, 0 }; gnutls_dh_params dh_params; gnutls_rsa_params rsa_params; @@ -160,14 +159,13 @@ gnutls_rsa_params rsa_params; static int generate_dh_primes(void) { gnutls_datum prime, generator; - int i = 0; + int prime_bits = 768; if (gnutls_dh_params_init(&dh_params) < 0) { fprintf(stderr, "Error in dh parameter initialization\n"); exit(1); } - do { /* Generate Diffie Hellman parameters - for use with DHE * kx algorithms. These should be discarded and regenerated * once a day, once a week or once a month. Depends on the @@ -175,23 +173,22 @@ static int generate_dh_primes(void) */ printf ("Generating Diffie Hellman parameters [%d]. Please wait...\n", - prime_nums[i]); + prime_bits); fflush(stdout); - if (gnutls_dh_params_generate(&prime, &generator, prime_nums[i]) < 0) { + if (gnutls_dh_params_generate(&prime, &generator, prime_bits) < 0) { fprintf(stderr, "Error in prime generation\n"); exit(1); } if (gnutls_dh_params_set - (dh_params, prime, generator, prime_nums[i]) < 0) { + (dh_params, prime, generator, prime_bits) < 0) { fprintf(stderr, "Error in prime replacement\n"); exit(1); } gnutls_free(prime.data); gnutls_free(generator.data); - } while (prime_nums[++i] != 0); return 0; } @@ -616,6 +613,16 @@ int main(int argc, char **argv) } } + if (x509_crlfile != NULL) { + if ((ret = gnutls_certificate_set_x509_crl_file + (cert_cred, x509_crlfile, x509ctype)) < 0) { + fprintf(stderr, "Error reading '%s'\n", x509_crlfile); + exit(1); + } else { + printf("Processed %d CRL(s).\n", ret); + } + } + if (pgp_keyring != NULL) { ret = gnutls_certificate_set_openpgp_keyring_file(cert_cred, @@ -940,23 +947,6 @@ int main(int argc, char **argv) } -#define DEFAULT_X509_KEYFILE "x509/key.pem" -#define DEFAULT_X509_CERTFILE "x509/cert.pem" - -#define DEFAULT_X509_KEYFILE2 "x509/key-dsa.pem" -#define DEFAULT_X509_CERTFILE2 "x509/cert-dsa.pem" - -#define DEFAULT_PGP_KEYFILE "openpgp/sec.asc" -#define DEFAULT_PGP_CERTFILE "openpgp/pub.asc" - -#define DEFAULT_X509_CAFILE "x509/ca.pem" -#define DEFAULT_X509_CRLFILE NULL; - -#define DEFAULT_SRP_PASSWD "srp/tpasswd" -#define DEFAULT_SRP_PASSWD_CONF "srp/tpasswd.conf" - -#undef DEBUG - static gaainfo info; void gaa_parser(int argc, char **argv) { @@ -988,50 +978,14 @@ void gaa_parser(int argc, char **argv) port = info.port; -#ifdef DEBUG - if (info.x509_certfile != NULL) - x509_certfile = info.x509_certfile; - else - x509_certfile = DEFAULT_X509_CERTFILE; - - if (info.x509_keyfile != NULL) - x509_keyfile = info.x509_keyfile; - else - x509_keyfile = DEFAULT_X509_KEYFILE; - - if (info.x509_cafile != NULL) - x509_cafile = info.x509_certfile; - else - x509_cafile = DEFAULT_X509_CAFILE; - - if (info.pgp_certfile != NULL) - pgp_certfile = info.pgp_certfile; - else - pgp_certfile = DEFAULT_PGP_CERTFILE; - - if (info.pgp_keyfile != NULL) - pgp_keyfile = info.pgp_keyfile; - else - pgp_keyfile = DEFAULT_PGP_KEYFILE; - - if (info.srp_passwd != NULL) - srp_passwd = info.srp_passwd; - else - srp_passwd = DEFAULT_SRP_PASSWD; - - if (info.srp_passwd_conf != NULL) - srp_passwd_conf = info.srp_passwd_conf; - else - srp_passwd_conf = DEFAULT_SRP_PASSWD_CONF; -#else x509_certfile = info.x509_certfile; x509_keyfile = info.x509_keyfile; x509_cafile = info.x509_cafile; + x509_crlfile = info.x509_crlfile; pgp_certfile = info.pgp_certfile; pgp_keyfile = info.pgp_keyfile; srp_passwd = info.srp_passwd; srp_passwd_conf = info.srp_passwd_conf; -#endif pgp_keyring = info.pgp_keyring; pgp_trustdb = info.pgp_trustdb; diff --git a/src/serv.gaa b/src/serv.gaa index dbc58b7d4a..f3dcb2bc97 100644 --- a/src/serv.gaa +++ b/src/serv.gaa @@ -34,6 +34,9 @@ option (x509fmtder) { $fmtder = 1 } "Use DER format for certificates" #char *x509_cafile; option (x509cafile) STR "FILE" { $x509_cafile = $1 } "Certificate file to use." +#char *x509_crlfile; +option (x509crlfile) STR "FILE" { $x509_crlfile = $1 } "CRL file to use." + #char *pgp_keyring; option (pgpkeyring) STR "FILE" { $pgp_keyring = $1 } "PGP Key ring file to use." @@ -95,7 +98,7 @@ init { $generate=0; $port=5556; $http=0; $ciphers=NULL; $kx=NULL; $comp=NULL; $macs=NULL; $ctype=NULL; $nciphers=0; $nkx=0; $ncomp=0; $nmacs=0; $nctype = 0; $nodb = 0; $x509_cafile = NULL; $pgp_keyfile=NULL; $pgp_certfile=NULL; - $x509_keyfile=NULL; $x509_certfile=NULL; + $x509_keyfile=NULL; $x509_certfile=NULL; $x509_crlfile = NULL; $srp_passwd=NULL; $srp_passwd_conf=NULL; $quiet = 0; $pgp_trustdb=NULL; $pgp_keyring=NULL; $fmtder = 0; $dh_params_file=NULL; } |