From d249b7ab9a1fbb982b4d08e8bc8431f92bf9e44d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Tue, 24 Jun 2014 11:49:16 +0200 Subject: [PATCH] Restore ability to trust non-CA selfsigned EE cert --- ChangeLog | 3 ++ library/x509_crt.c | 43 ++++++++++++++++++------- tests/data_files/server5-selfsigned.crt | 12 +++++++ tests/data_files/server6-ss-child.crt | 13 ++++++++ tests/suites/test_suite_x509parse.data | 8 +++++ 5 files changed, 67 insertions(+), 12 deletions(-) create mode 100644 tests/data_files/server5-selfsigned.crt create mode 100644 tests/data_files/server6-ss-child.crt diff --git a/ChangeLog b/ChangeLog index 097f0ffd0..886fe1142 100644 --- a/ChangeLog +++ b/ChangeLog @@ -43,6 +43,9 @@ Bugfix to 32 bytes with CBC-based ciphersuites and TLS >= 1.1 * Restore ability to use a v1 cert as a CA if trusted locally. (This had been removed in 1.3.6.) + * Restore ability to locally trust a self-signed cert that is not a proper + CA for use as an end entity certificate. (This had been removed in + 1.3.6.) = PolarSSL 1.3.7 released on 2014-05-02 Features diff --git a/library/x509_crt.c b/library/x509_crt.c index 6f7266130..03cdda807 100644 --- a/library/x509_crt.c +++ b/library/x509_crt.c @@ -1587,11 +1587,16 @@ static int x509_wildcard_verify( const char *cn, x509_buf *name ) /* * Check if 'parent' is a suitable parent (signing CA) for 'child'. * Return 0 if yes, -1 if not. + * + * top means parent is a locally-trusted certificate + * bottom means child is the end entity cert */ static int x509_crt_check_parent( const x509_crt *child, const x509_crt *parent, - int top ) + int top, int bottom ) { + int need_ca_bit; + /* Parent must be the issuer */ if( child->issuer_raw.len != parent->subject_raw.len || memcmp( child->issuer_raw.p, parent->subject_raw.p, @@ -1600,17 +1605,30 @@ static int x509_crt_check_parent( const x509_crt *child, return( -1 ); } - /* Parent must have the basicConstraints CA bit set. - * Exception: v1/v2 certificates that are locally trusted. */ - if( parent->ca_istrue == 0 && - ! ( top && parent->version < 3 ) ) + /* Parent must have the basicConstraints CA bit set as a general rule */ + need_ca_bit = 1; + + /* Exception: v1/v2 certificates that are locally trusted. */ + if( top && parent->version < 3 ) + need_ca_bit = 0; + + /* Exception: self-signed end-entity certs that are locally trusted. */ + if( top && bottom && + child->raw.len == parent->raw.len && + memcmp( child->raw.p, parent->raw.p, child->raw.len ) == 0 ) + { + need_ca_bit = 0; + } + + if( need_ca_bit && ! parent->ca_istrue ) + return( -1 ); + +#if defined(POLARSSL_X509_CHECK_KEY_USAGE) + if( need_ca_bit && + x509_crt_check_key_usage( parent, KU_KEY_CERT_SIGN ) != 0 ) { return( -1 ); } - -#if defined(POLARSSL_X509_CHECK_KEY_USAGE) - if( x509_crt_check_key_usage( parent, KU_KEY_CERT_SIGN ) != 0 ) - return( -1 ); #endif return( 0 ); @@ -1651,7 +1669,7 @@ static int x509_crt_verify_top( for( /* trust_ca */ ; trust_ca != NULL; trust_ca = trust_ca->next ) { - if( x509_crt_check_parent( child, trust_ca, 1 ) != 0 ) + if( x509_crt_check_parent( child, trust_ca, 1, path_cnt == 0 ) != 0 ) continue; /* @@ -1778,7 +1796,8 @@ static int x509_crt_verify_child( grandparent != NULL; grandparent = grandparent->next ) { - if( x509_crt_check_parent( parent, grandparent, 0 ) == 0 ) + if( x509_crt_check_parent( parent, grandparent, + 0, path_cnt == 0 ) == 0 ) break; } @@ -1880,7 +1899,7 @@ int x509_crt_verify( x509_crt *crt, /* Look for a parent upwards the chain */ for( parent = crt->next; parent != NULL; parent = parent->next ) { - if( x509_crt_check_parent( crt, parent, 0 ) == 0 ) + if( x509_crt_check_parent( crt, parent, 0, pathlen == 0 ) == 0 ) break; } diff --git a/tests/data_files/server5-selfsigned.crt b/tests/data_files/server5-selfsigned.crt new file mode 100644 index 000000000..cb5564751 --- /dev/null +++ b/tests/data_files/server5-selfsigned.crt @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIBzTCCAXKgAwIBAgIMU6LLSxJOrYN9qJSyMAoGCCqGSM49BAMCMEcxEzARBgNV +BAMTCnNlbGZzaWduZWQxEDAOBgNVBAsTB3Rlc3RpbmcxETAPBgNVBAoTCFBvbGFy +U1NMMQswCQYDVQQGEwJOTDAiGA8yMDE0MDYxOTExMzY0M1oYDzIwMjQwNjE4MTEz +NjQzWjBHMRMwEQYDVQQDEwpzZWxmc2lnbmVkMRAwDgYDVQQLEwd0ZXN0aW5nMREw +DwYDVQQKEwhQb2xhclNTTDELMAkGA1UEBhMCTkwwWTATBgcqhkjOPQIBBggqhkjO +PQMBBwNCAAQ3zFbZdgkeWnI+x1kt/yBu7nz5BpF00K0UtfdoIllikk7lANgjEf/q +L9I0XV0WvYqIwmt3DVXNiioO+gHItO3/o0AwPjAMBgNVHRMBAf8EAjAAMA8GA1Ud +DwEB/wQFAwMHgAAwHQYDVR0OBBYEFLZtURgXjmWq8uzV8wHkbFLCNB1bMAoGCCqG +SM49BAMCA0kAMEYCIQCf/bzFoge0pCOIrtHrABgc1+Cl9kjlsICpduXhdHUMOwIh +AOJ+nBHfaEGyF4PRJvn/jMDeIaH1zisinVzC2v+JQOWq +-----END CERTIFICATE----- diff --git a/tests/data_files/server6-ss-child.crt b/tests/data_files/server6-ss-child.crt new file mode 100644 index 000000000..3c6fd4d1b --- /dev/null +++ b/tests/data_files/server6-ss-child.crt @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIIB8jCCAZmgAwIBAgIMU6LLWCI5lHSn7HnsMAoGCCqGSM49BAMCMEcxEzARBgNV +BAMTCnNlbGZzaWduZWQxEDAOBgNVBAsTB3Rlc3RpbmcxETAPBgNVBAoTCFBvbGFy +U1NMMQswCQYDVQQGEwJOTDAiGA8yMDE0MDYxOTExMzY1NloYDzIwMjQwNjE4MTEz +NjU2WjBNMRkwFwYDVQQDExBzZWxmc2lnbmVkLWNoaWxkMRAwDgYDVQQLEwd0ZXN0 +aW5nMREwDwYDVQQKEwhQb2xhclNTTDELMAkGA1UEBhMCTkwwWTATBgcqhkjOPQIB +BggqhkjOPQMBBwNCAASBWTF2SST6Fa2roDFuDu0zEfqRJVXBsMGcA3I+mLotpHI3 +iR9DN40fjjrY8FfoL0/JAKT323MPssYElNFAOzjjo2EwXzAMBgNVHRMBAf8EAjAA +MA8GA1UdDwEB/wQFAwMHgAAwHQYDVR0OBBYEFDxZrEo+LvwCNi/afcvLnHqyiZlT +MB8GA1UdIwQYMBaAFLZtURgXjmWq8uzV8wHkbFLCNB1bMAoGCCqGSM49BAMCA0cA +MEQCIAMlQ59/NW7S0hP1cu5OTD2zqT087bEmnIfOTBYfj8UFAiBBrrz2dipODVYx +vvTsQmSCzjrm+JtQQoWa+cdnAG3w5g== +-----END CERTIFICATE----- diff --git a/tests/suites/test_suite_x509parse.data b/tests/suites/test_suite_x509parse.data index 12019b0dc..a22741e5f 100644 --- a/tests/suites/test_suite_x509parse.data +++ b/tests/suites/test_suite_x509parse.data @@ -634,6 +634,14 @@ X509 Certificate verification #72 (v1 chain) depends_on:POLARSSL_PEM_PARSE_C:POLARSSL_RSA_C:POLARSSL_PKCS1_V15:POLARSSL_SHA256_C x509_verify:"data_files/server2-v1-chain.crt":"data_files/test-ca-v1.crt":"data_files/crl.pem":"NULL":POLARSSL_ERR_X509_CERT_VERIFY_FAILED:BADCERT_NOT_TRUSTED:"NULL" +X509 Certificate verification #73 (selfsigned trusted without CA bit) +depends_on:POLARSSL_PEM_PARSE_C:POLARSSL_ECDSA_C:POLARSSL_SHA256_C +x509_verify:"data_files/server5-selfsigned.crt":"data_files/server5-selfsigned.crt":"data_files/crl.pem":"NULL":0:0:"NULL" + +X509 Certificate verification #74 (signed by selfsigned trusted without CA bit) +depends_on:POLARSSL_PEM_PARSE_C:POLARSSL_ECDSA_C:POLARSSL_SHA256_C +x509_verify:"data_files/server6-ss-child.crt":"data_files/server5-selfsigned.crt":"data_files/crl.pem":"NULL":POLARSSL_ERR_X509_CERT_VERIFY_FAILED:BADCERT_NOT_TRUSTED:"NULL" + X509 Parse Selftest depends_on:POLARSSL_SHA1_C:POLARSSL_PEM_PARSE_C:POLARSSL_CERTS_C x509_selftest: