From a5943858d8ebac35692fde7dbd6fbc4f2410945a Mon Sep 17 00:00:00 2001 From: Paul Bakker Date: Mon, 9 Sep 2013 17:21:45 +0200 Subject: [PATCH] x509_verify() now case insensitive for cn (RFC 6125 6.4) --- ChangeLog | 1 + library/x509parse.c | 31 ++++++++++++++++++++++---- tests/suites/test_suite_x509parse.data | 4 ++-- 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9f24244dd..4a75d6e83 100644 --- a/ChangeLog +++ b/ChangeLog @@ -40,6 +40,7 @@ Changes (Ability to keep old as well with POLARSSL_ERROR_STRERROR_BC) * SHA2 renamed to SHA256, SHA4 renamed to SHA512 and functions accordingly * All RSA operations require a random generator for blinding purposes + * x509_verify() now case insensitive for cn (RFC 6125 6.4) Bugfix * Fixed parse error in ssl_parse_certificate_request() diff --git a/library/x509parse.c b/library/x509parse.c index c175df4c4..2ab52fba4 100644 --- a/library/x509parse.c +++ b/library/x509parse.c @@ -3457,6 +3457,29 @@ static int x509parse_verifycrl(x509_cert *crt, x509_cert *ca, return flags; } +// Equal == 0, inequal == 1 +static int x509_name_cmp( const void *s1, const void *s2, size_t len ) +{ + size_t i; + unsigned char diff; + const unsigned char *n1 = s1, *n2 = s2; + + for( i = 0; i < len; i++ ) + { + diff = n1[i] ^ n2[i]; + + if( ( n1[i] >= 'a' || n1[i] <= 'z' ) && ( diff == 0 || diff == 32 ) ) + continue; + + if( ( n1[i] >= 'A' || n1[i] <= 'Z' ) && ( diff == 0 || diff == 32 ) ) + continue; + + return( 1 ); + } + + return( 0 ); +} + static int x509_wildcard_verify( const char *cn, x509_buf *name ) { size_t i; @@ -3478,7 +3501,7 @@ static int x509_wildcard_verify( const char *cn, x509_buf *name ) return( 0 ); if( strlen( cn ) - cn_idx == name->len - 1 && - memcmp( name->p + 1, cn + cn_idx, name->len - 1 ) == 0 ) + x509_name_cmp( name->p + 1, cn + cn_idx, name->len - 1 ) == 0 ) { return( 1 ); } @@ -3657,7 +3680,7 @@ static int x509parse_verify_child( ret = x509parse_verify_child( parent, grandparent, trust_ca, ca_crl, path_cnt + 1, &parent_flags, f_vrfy, p_vrfy ); if( ret != 0 ) return( ret ); - } + } else { ret = x509parse_verify_top( parent, trust_ca, ca_crl, path_cnt + 1, &parent_flags, f_vrfy, p_vrfy ); @@ -3706,7 +3729,7 @@ int x509parse_verify( x509_cert *crt, while( cur != NULL ) { if( cur->buf.len == cn_len && - memcmp( cn, cur->buf.p, cn_len ) == 0 ) + x509_name_cmp( cn, cur->buf.p, cn_len ) == 0 ) break; if( cur->buf.len > 2 && @@ -3727,7 +3750,7 @@ int x509parse_verify( x509_cert *crt, if( OID_CMP( OID_AT_CN, &name->oid ) ) { if( name->val.len == cn_len && - memcmp( name->val.p, cn, cn_len ) == 0 ) + x509_name_cmp( name->val.p, cn, cn_len ) == 0 ) break; if( name->val.len > 2 && diff --git a/tests/suites/test_suite_x509parse.data b/tests/suites/test_suite_x509parse.data index f089570d0..ef7bbd4d2 100644 --- a/tests/suites/test_suite_x509parse.data +++ b/tests/suites/test_suite_x509parse.data @@ -418,9 +418,9 @@ X509 Certificate verification #19 (Not trusted Cert, allowing callback) depends_on:POLARSSL_PEM_C:POLARSSL_FS_IO:POLARSSL_RSA_C:POLARSSL_PKCS1_V15 x509_verify:"data_files/server2.crt":"data_files/server1.crt":"data_files/crl_expired.pem":"NULL":0:0:"verify_all" -X509 Certificate verification #21 (domain matching wildcard certificate) +X509 Certificate verification #21 (domain matching wildcard certificate, case insensitive) depends_on:POLARSSL_PEM_C:POLARSSL_FS_IO:POLARSSL_SHA1_C:POLARSSL_RSA_C:POLARSSL_PKCS1_V15 -x509_verify:"data_files/cert_example_wildcard.crt":"data_files/test-ca.crt":"data_files/crl.pem":"mail.example.com":0:0:"NULL" +x509_verify:"data_files/cert_example_wildcard.crt":"data_files/test-ca.crt":"data_files/crl.pem":"mail.ExAmPlE.com":0:0:"NULL" X509 Certificate verification #22 (domain not matching wildcard certificate) depends_on:POLARSSL_PEM_C:POLARSSL_FS_IO:POLARSSL_SHA1_C:POLARSSL_RSA_C:POLARSSL_PKCS1_V15