diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2002-06-22 14:52:37 +0000 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2002-06-22 14:52:37 +0000 |
commit | ea5da3f8fd0b439a847f9dca9376d0ebc94fbb38 (patch) | |
tree | 350311b44136139d56e9365f87383c24a86e8903 | |
parent | f2ea2f1c95bc0fafdc51ac818cc0dd9546607cf2 (diff) | |
download | gnutls-ea5da3f8fd0b439a847f9dca9376d0ebc94fbb38.tar.gz |
The TLS handshake no longer fails if the X.509 extensions in the Certificate are critical and unsupported. The unsupported critical extensions are now only catched by the verification functions.
-rw-r--r-- | lib/auth_cert.c | 4 | ||||
-rw-r--r-- | lib/auth_dhe.c | 2 | ||||
-rw-r--r-- | lib/auth_rsa.c | 2 | ||||
-rw-r--r-- | lib/gnutls_cert.h | 3 | ||||
-rw-r--r-- | lib/gnutls_record.c | 5 | ||||
-rw-r--r-- | lib/gnutls_str.h | 5 | ||||
-rw-r--r-- | lib/gnutls_x509.c | 27 | ||||
-rw-r--r-- | lib/gnutls_x509.h | 2 | ||||
-rw-r--r-- | lib/x509_extensions.c | 16 | ||||
-rw-r--r-- | lib/x509_extensions.h | 2 | ||||
-rw-r--r-- | lib/x509_sig_check.c | 4 |
11 files changed, 44 insertions, 28 deletions
diff --git a/lib/auth_cert.c b/lib/auth_cert.c index c5477373c9..d3597d9d7e 100644 --- a/lib/auth_cert.c +++ b/lib/auth_cert.c @@ -750,7 +750,7 @@ int _gnutls_proc_x509_server_certificate(GNUTLS_STATE state, opaque * data, if ((ret = _gnutls_x509_cert2gnutls_cert(&peer_certificate_list - [j], tmp)) < 0) { + [j], tmp, 1)) < 0) { gnutls_assert(); CLEAR_CERTS; gnutls_afree(peer_certificate_list); @@ -1153,7 +1153,7 @@ int _gnutls_proc_cert_client_cert_vrfy(GNUTLS_STATE state, opaque * data, ret = _gnutls_x509_cert2gnutls_cert(&peer_cert, info-> - raw_certificate_list[0]); + raw_certificate_list[0], 1); break; case GNUTLS_CRT_OPENPGP: if (_E_gnutls_openpgp_cert2gnutls_cert==NULL) { diff --git a/lib/auth_dhe.c b/lib/auth_dhe.c index 4367e8df14..9d2df316ba 100644 --- a/lib/auth_dhe.c +++ b/lib/auth_dhe.c @@ -389,7 +389,7 @@ static int proc_dhe_server_kx(GNUTLS_STATE state, opaque * data, case GNUTLS_CRT_X509: if ((ret = _gnutls_x509_cert2gnutls_cert( &peer_cert, - info->raw_certificate_list[0])) < 0) { + info->raw_certificate_list[0], 1)) < 0) { gnutls_assert(); return ret; } diff --git a/lib/auth_rsa.c b/lib/auth_rsa.c index 6b62f370bd..9fd20d819c 100644 --- a/lib/auth_rsa.c +++ b/lib/auth_rsa.c @@ -81,7 +81,7 @@ int i; case GNUTLS_CRT_X509: if ((ret = _gnutls_x509_cert2gnutls_cert( &peer_cert, - info->raw_certificate_list[0])) < 0) { + info->raw_certificate_list[0], 1)) < 0) { gnutls_assert(); return ret; } diff --git a/lib/gnutls_cert.h b/lib/gnutls_cert.h index 33e2a933c1..c86943d42f 100644 --- a/lib/gnutls_cert.h +++ b/lib/gnutls_cert.h @@ -47,9 +47,6 @@ typedef struct gnutls_cert { uint16 keyUsage; /* bits from X509KEY_* */ - int valid; /* 0 if the certificate looks good. - */ - int CA; /* 0 if the certificate does not belong to * a certificate authority. 1 otherwise. */ diff --git a/lib/gnutls_record.c b/lib/gnutls_record.c index df657e2e56..e31119bb0a 100644 --- a/lib/gnutls_record.c +++ b/lib/gnutls_record.c @@ -146,7 +146,10 @@ int gnutls_bye( GNUTLS_STATE state, GNUTLS_CloseRequest how) if (ret2 < 0) return ret2; - + break; + default: + gnutls_assert(); + return GNUTLS_E_INTERNAL_ERROR; } STATE = STATE0; diff --git a/lib/gnutls_str.h b/lib/gnutls_str.h index bc8f1252ed..8855180b1d 100644 --- a/lib/gnutls_str.h +++ b/lib/gnutls_str.h @@ -15,7 +15,12 @@ typedef struct { void _gnutls_string_init( gnutls_string*, ALLOC_FUNC, REALLOC_FUNC, FREE_FUNC); void _gnutls_string_clear( gnutls_string*); + +/* Beware, do not clear the string, after calling this + * function + */ gnutls_datum _gnutls_string2datum( gnutls_string* str); + int _gnutls_string_copy_str( gnutls_string* dest, const char* src); int _gnutls_string_append_str( gnutls_string*, const char* str); int _gnutls_string_append_data( gnutls_string*, const void* data, size_t data_size); diff --git a/lib/gnutls_x509.c b/lib/gnutls_x509.c index a2e63da7f4..3c395a178b 100644 --- a/lib/gnutls_x509.c +++ b/lib/gnutls_x509.c @@ -864,7 +864,7 @@ int _gnutls_x509_cert_verify_peers(GNUTLS_STATE state) if ((ret = _gnutls_x509_cert2gnutls_cert(&peer_certificate_list[i], info-> - raw_certificate_list[i])) < + raw_certificate_list[i], 0)) < 0) { gnutls_assert(); CLEAR_CERTS; @@ -968,7 +968,7 @@ int gnutls_x509_verify_certificate( const gnutls_datum* cert_list, int 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) { + cert_list[i], 0)) < 0) { gnutls_assert(); CLEAR_CERTS_CA; gnutls_free( peer_certificate_list); @@ -982,7 +982,7 @@ int gnutls_x509_verify_certificate( const gnutls_datum* cert_list, int 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) { + CA_list[i], 0)) < 0) { gnutls_assert(); CLEAR_CERTS_CA; gnutls_free( peer_certificate_list); @@ -1107,7 +1107,7 @@ static int parse_der_cert_mem( gnutls_cert** cert_list, int* ncerts, if ((ret = _gnutls_x509_cert2gnutls_cert( &cert_list[0][i - 1], - tmp)) < 0) { + tmp, 0)) < 0) { gnutls_assert(); return ret; } @@ -1179,7 +1179,7 @@ static int parse_pkcs7_cert_mem( gnutls_cert** cert_list, int* ncerts, if ((ret = _gnutls_x509_cert2gnutls_cert( &cert_list[0][i - 1], - tmp2)) < 0) { + tmp2, 0)) < 0) { gnutls_assert(); return ret; } @@ -1252,7 +1252,7 @@ static int parse_pem_cert_mem( gnutls_cert** cert_list, int* ncerts, if ((ret = _gnutls_x509_cert2gnutls_cert( &cert_list[0][i - 1], - tmp)) < 0) { + tmp, 0)) < 0) { gnutls_free(b64); gnutls_assert(); return ret; @@ -1969,8 +1969,13 @@ int len, result; * (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, gnutls_datum derCert) +int _gnutls_x509_cert2gnutls_cert(gnutls_cert * gCert, gnutls_datum derCert, + int no_critical_ext /* if non zero do not parse X.509 extensions */) { int result; ASN1_TYPE c2; @@ -1980,7 +1985,6 @@ int _gnutls_x509_cert2gnutls_cert(gnutls_cert * gCert, gnutls_datum derCert) memset(gCert, 0, sizeof(gnutls_cert)); - gCert->valid = 1; gCert->cert_type = GNUTLS_CRT_X509; if (gnutls_set_datum(&gCert->raw, derCert.data, derCert.size) < 0) { @@ -2069,7 +2073,7 @@ int _gnutls_x509_cert2gnutls_cert(gnutls_cert * gCert, gnutls_datum derCert) if ((result = _gnutls_get_ext_type(c2, "certificate2.tbsCertificate.extensions", - gCert)) < 0) { + gCert, no_critical_ext)) < 0) { gnutls_assert(); asn1_delete_structure(&c2); gnutls_free_datum( &gCert->raw); @@ -2078,11 +2082,6 @@ int _gnutls_x509_cert2gnutls_cert(gnutls_cert * gCert, gnutls_datum derCert) asn1_delete_structure(&c2); - - gCert->valid = 0; /* if we got until here - * the certificate is valid. - */ - return 0; } diff --git a/lib/gnutls_x509.h b/lib/gnutls_x509.h index 69e149846d..105bae09ce 100644 --- a/lib/gnutls_x509.h +++ b/lib/gnutls_x509.h @@ -1,7 +1,7 @@ #include <libtasn1.h> int _gnutls_x509_cert_verify_peers(GNUTLS_STATE state); -int _gnutls_x509_cert2gnutls_cert(gnutls_cert * gCert, gnutls_datum derCert); +int _gnutls_x509_cert2gnutls_cert(gnutls_cert * gCert, gnutls_datum derCert, int noext); #define MAX_INT_DIGITS 4 void _gnutls_int2str(unsigned int k, char *data); diff --git a/lib/x509_extensions.c b/lib/x509_extensions.c index 181c352739..2c38827551 100644 --- a/lib/x509_extensions.c +++ b/lib/x509_extensions.c @@ -114,9 +114,13 @@ static int _extract_basicConstraints(int *CA, opaque * extnValue, } +/* + * 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 extnValueLen, int no_critical_ext) { if (strcmp(extnID, "2 5 29 14") == 0) { /* subject Key ID */ @@ -139,7 +143,7 @@ static int _parse_extension(gnutls_cert * cert, char *extnID, _gnutls_x509_log("X509_EXT: CERT[%s]: Unsupported Extension: %s, %s\n", GET_CN(cert->raw), extnID, critical); - if (strcmp(critical, "TRUE") == 0) { + if (strcmp(critical, "TRUE") == 0 && no_critical_ext == 0) { gnutls_assert(); return GNUTLS_E_X509_UNSUPPORTED_CRITICAL_EXTENSION; } @@ -149,8 +153,12 @@ static int _parse_extension(gnutls_cert * cert, char *extnID, /* 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, char *root, gnutls_cert * cert) +int _gnutls_get_ext_type(ASN1_TYPE rasn, char *root, gnutls_cert * cert, + int no_critical_ext) { int k, result, len; char name[128], name2[128], counter[MAX_INT_DIGITS]; @@ -235,7 +243,7 @@ int _gnutls_get_ext_type(ASN1_TYPE rasn, char *root, gnutls_cert * cert) /* Handle Extension */ if ((result = _parse_extension(cert, extnID, critical, - extnValue, len)) < 0) { + extnValue, len, no_critical_ext)) < 0) { gnutls_assert(); return result; } diff --git a/lib/x509_extensions.h b/lib/x509_extensions.h index ddcb0e72d8..755f942cbb 100644 --- a/lib/x509_extensions.h +++ b/lib/x509_extensions.h @@ -1,2 +1,2 @@ -int _gnutls_get_ext_type( ASN1_TYPE rasn, char *root, gnutls_cert *cert); +int _gnutls_get_ext_type( ASN1_TYPE rasn, 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 index 89e5f633ae..3987e7684a 100644 --- a/lib/x509_sig_check.c +++ b/lib/x509_sig_check.c @@ -225,6 +225,10 @@ gnutls_datum tbs; gnutls_free_datum(&tbs); return 0; break; + default: + gnutls_assert(); + gnutls_free_datum(&tbs); + return GNUTLS_E_INTERNAL_ERROR; } |