diff --git a/ChangeLog b/ChangeLog index 6995003f1..9ce5b8399 100644 --- a/ChangeLog +++ b/ChangeLog @@ -18,6 +18,7 @@ Security * Forbid change of server certificate during renegotiation to prevent "triple handshake" attack when authentication mode is optional (the attack was already impossible when authentication is required). + * Check notBefore timestamp of certificates and CRLs from the future. Bugfix * ecp_gen_keypair() does more tries to prevent failure because of diff --git a/include/polarssl/x509.h b/include/polarssl/x509.h index 1520a7cfa..008e795e1 100644 --- a/include/polarssl/x509.h +++ b/include/polarssl/x509.h @@ -78,6 +78,8 @@ #define BADCERT_MISSING 0x40 /**< Certificate was missing. */ #define BADCERT_SKIP_VERIFY 0x80 /**< Certificate verification was skipped. */ #define BADCERT_OTHER 0x0100 /**< Other reason (can be used by verify callback) */ +#define BADCERT_FUTURE 0x0200 /**< The certificate validity starts in the future. */ +#define BADCRL_FUTURE 0x0400 /**< The CRL is from the future */ /* \} name */ /* \} addtogroup x509_module */ diff --git a/library/x509_crt.c b/library/x509_crt.c index d18e117fb..4668cdf45 100644 --- a/library/x509_crt.c +++ b/library/x509_crt.c @@ -1255,6 +1255,9 @@ static int x509_crt_verifycrl( x509_crt *crt, x509_crt *ca, if( x509_time_expired( &crl_list->next_update ) ) flags |= BADCRL_EXPIRED; + if( x509_time_future( &crl_list->this_update ) ) + flags |= BADCRL_FUTURE; + /* * Check if certificate is revoked */ @@ -1340,6 +1343,9 @@ static int x509_crt_verify_top( if( x509_time_expired( &child->valid_to ) ) *flags |= BADCERT_EXPIRED; + if( x509_time_future( &child->valid_from ) ) + *flags |= BADCERT_FUTURE; + /* * Child is the top of the chain. Check against the trust_ca list. */ @@ -1420,6 +1426,9 @@ static int x509_crt_verify_top( if( x509_time_expired( &trust_ca->valid_to ) ) ca_flags |= BADCERT_EXPIRED; + if( x509_time_future( &trust_ca->valid_from ) ) + ca_flags |= BADCERT_FUTURE; + if( NULL != f_vrfy ) { if( ( ret = f_vrfy( p_vrfy, trust_ca, path_cnt + 1, &ca_flags ) ) != 0 ) @@ -1451,8 +1460,8 @@ static int x509_crt_verify_child( x509_crt *grandparent; const md_info_t *md_info; - if( x509_time_expired( &child->valid_to ) ) - *flags |= BADCERT_EXPIRED; + if( x509_time_future( &child->valid_from ) ) + *flags |= BADCERT_FUTURE; md_info = md_info_from_type( child->sig_md ); if( md_info == NULL ) diff --git a/tests/data_files/server5-expired.crt b/tests/data_files/server5-expired.crt new file mode 100644 index 000000000..d726e5c8e --- /dev/null +++ b/tests/data_files/server5-expired.crt @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICHjCCAaWgAwIBAgIBHjAKBggqhkjOPQQDAjA+MQswCQYDVQQGEwJOTDERMA8G +A1UEChMIUG9sYXJTU0wxHDAaBgNVBAMTE1BvbGFyc3NsIFRlc3QgRUMgQ0EwHhcN +MDQwMzEwMTIwOTMwWhcNMTQwMzA4MTIwOTMwWjA0MQswCQYDVQQGEwJOTDERMA8G +A1UEChMIUG9sYXJTU0wxEjAQBgNVBAMTCWxvY2FsaG9zdDBZMBMGByqGSM49AgEG +CCqGSM49AwEHA0IABDfMVtl2CR5acj7HWS3/IG7ufPkGkXTQrRS192giWWKSTuUA +2CMR/+ov0jRdXRa9iojCa3cNVc2KKg76Aci07f+jgZ0wgZowCQYDVR0TBAIwADAd +BgNVHQ4EFgQUUGGlj9QH2deCAQzlZX+MY0anE74wbgYDVR0jBGcwZYAUnW0gJEkB +PyvLeLUZvH4kydv7NnyhQqRAMD4xCzAJBgNVBAYTAk5MMREwDwYDVQQKEwhQb2xh +clNTTDEcMBoGA1UEAxMTUG9sYXJzc2wgVGVzdCBFQyBDQYIJAMFD4n5iQ8zoMAoG +CCqGSM49BAMCA2cAMGQCMCDxvDmhlrEk0r4hqCwvQDxWEoXPbbD1gglfLT3BsGpu +XHUQ1W2HwB3o/7N5I13BBgIwcmG17zyNIOkYiyExYtPCZCpbofEMpRY5qWG0K6YL +fN08jSzyFt6kbO4ak0D6tC5Q +-----END CERTIFICATE----- diff --git a/tests/suites/test_suite_x509parse.data b/tests/suites/test_suite_x509parse.data index 166be6806..6f2c2d350 100644 --- a/tests/suites/test_suite_x509parse.data +++ b/tests/suites/test_suite_x509parse.data @@ -194,22 +194,38 @@ X509 Time Future #6 depends_on:POLARSSL_PEM_PARSE_C:POLARSSL_ECP_C x509_time_future:"data_files/test-ca2.crt":"valid_to":1 -X509 Certificate verification #1 (Revoked Cert, Expired CRL) +X509 Certificate verification #1 (Revoked Cert, Expired CRL, no CN) depends_on:POLARSSL_PEM_PARSE_C:POLARSSL_SHA1_C:POLARSSL_RSA_C:POLARSSL_PKCS1_V15 x509_verify:"data_files/server1.crt":"data_files/test-ca.crt":"data_files/crl_expired.pem":"NULL":POLARSSL_ERR_X509_CERT_VERIFY_FAILED:BADCERT_REVOKED | BADCRL_EXPIRED:"NULL" +X509 Certificate verification #1a (Revoked Cert, Future CRL, no CN) +depends_on:POLARSSL_PEM_PARSE_C:POLARSSL_SHA1_C:POLARSSL_ECP_C: +x509_verify:"data_files/server6.crt":"data_files/test-ca2.crt":"data_files/crl-future.pem":"NULL":POLARSSL_ERR_X509_CERT_VERIFY_FAILED:BADCERT_REVOKED | BADCRL_FUTURE:"NULL" + X509 Certificate verification #2 (Revoked Cert, Expired CRL) depends_on:POLARSSL_PEM_PARSE_C:POLARSSL_SHA1_C:POLARSSL_RSA_C:POLARSSL_PKCS1_V15 x509_verify:"data_files/server1.crt":"data_files/test-ca.crt":"data_files/crl_expired.pem":"PolarSSL Server 1":POLARSSL_ERR_X509_CERT_VERIFY_FAILED:BADCERT_REVOKED | BADCRL_EXPIRED:"NULL" -X509 Certificate verification #3 (Revoked Cert, Expired CRL, CN Mismatch) +X509 Certificate verification #2a (Revoked Cert, Future CRL) +depends_on:POLARSSL_PEM_PARSE_C:POLARSSL_SHA1_C:POLARSSL_ECP_C: +x509_verify:"data_files/server6.crt":"data_files/test-ca2.crt":"data_files/crl-future.pem":"localhost":POLARSSL_ERR_X509_CERT_VERIFY_FAILED:BADCERT_REVOKED | BADCRL_FUTURE:"NULL" + +X509 Certificate verification #3 (Revoked Cert, Future CRL, CN Mismatch) depends_on:POLARSSL_PEM_PARSE_C:POLARSSL_SHA1_C:POLARSSL_RSA_C:POLARSSL_PKCS1_V15 x509_verify:"data_files/server1.crt":"data_files/test-ca.crt":"data_files/crl_expired.pem":"PolarSSL Wrong CN":POLARSSL_ERR_X509_CERT_VERIFY_FAILED:BADCERT_REVOKED | BADCRL_EXPIRED | BADCERT_CN_MISMATCH:"NULL" +X509 Certificate verification #3a (Revoked Cert, Expired CRL, CN Mismatch) +depends_on:POLARSSL_PEM_PARSE_C:POLARSSL_SHA1_C:POLARSSL_ECP_C: +x509_verify:"data_files/server6.crt":"data_files/test-ca2.crt":"data_files/crl-future.pem":"Wrong CN":POLARSSL_ERR_X509_CERT_VERIFY_FAILED:BADCERT_REVOKED | BADCRL_FUTURE | BADCERT_CN_MISMATCH:"NULL" + X509 Certificate verification #4 (Valid Cert, Expired CRL) depends_on:POLARSSL_PEM_PARSE_C:POLARSSL_SHA1_C:POLARSSL_RSA_C:POLARSSL_PKCS1_V15 x509_verify:"data_files/server2.crt":"data_files/test-ca.crt":"data_files/crl_expired.pem":"NULL":POLARSSL_ERR_X509_CERT_VERIFY_FAILED:BADCRL_EXPIRED:"NULL" +X509 Certificate verification #4a (Revoked Cert, Future CRL) +depends_on:POLARSSL_PEM_PARSE_C:POLARSSL_SHA1_C:POLARSSL_ECP_C: +x509_verify:"data_files/server5.crt":"data_files/test-ca2.crt":"data_files/crl-future.pem":"NULL":POLARSSL_ERR_X509_CERT_VERIFY_FAILED:BADCRL_FUTURE:"NULL" + X509 Certificate verification #5 (Revoked Cert) depends_on:POLARSSL_PEM_PARSE_C:POLARSSL_SHA1_C:POLARSSL_RSA_C:POLARSSL_PKCS1_V15 x509_verify:"data_files/server1.crt":"data_files/test-ca.crt":"data_files/crl.pem":"NULL":POLARSSL_ERR_X509_CERT_VERIFY_FAILED:BADCERT_REVOKED:"NULL" @@ -223,8 +239,16 @@ depends_on:POLARSSL_PEM_PARSE_C:POLARSSL_SHA1_C:POLARSSL_RSA_C:POLARSSL_PKCS1_V1 x509_verify:"data_files/server1.crt":"data_files/test-ca.crt":"data_files/crl.pem":"PolarSSL Wrong CN":POLARSSL_ERR_X509_CERT_VERIFY_FAILED:BADCERT_REVOKED | BADCERT_CN_MISMATCH:"NULL" X509 Certificate verification #8 (Valid Cert) -depends_on:POLARSSL_PEM_PARSE_C:POLARSSL_SHA1_C:POLARSSL_RSA_C:POLARSSL_PKCS1_V15 -x509_verify:"data_files/server2.crt":"data_files/test-ca.crt":"data_files/crl.pem":"NULL":0:0:"NULL" +depends_on:POLARSSL_PEM_PARSE_C:POLARSSL_SHA1_C:POLARSSL_ECP_C: +x509_verify:"data_files/server5.crt":"data_files/test-ca2.crt":"data_files/crl-ec-sha1.pem":"NULL":0:0:"NULL" + +X509 Certificate verification #8a (Expired Cert) +depends_on:POLARSSL_PEM_PARSE_C:POLARSSL_SHA1_C:POLARSSL_ECP_C: +x509_verify:"data_files/server5-expired.crt":"data_files/test-ca2.crt":"data_files/crl-ec-sha1.pem":"NULL":POLARSSL_ERR_X509_CERT_VERIFY_FAILED:BADCERT_EXPIRED:"NULL" + +X509 Certificate verification #8b (Future Cert) +depends_on:POLARSSL_PEM_PARSE_C:POLARSSL_SHA1_C:POLARSSL_ECP_C: +x509_verify:"data_files/server5-future.crt":"data_files/test-ca2.crt":"data_files/crl-ec-sha1.pem":"NULL":POLARSSL_ERR_X509_CERT_VERIFY_FAILED:BADCERT_FUTURE:"NULL" X509 Certificate verification #9 (Not trusted Cert) depends_on:POLARSSL_PEM_PARSE_C:POLARSSL_SHA1_C:POLARSSL_RSA_C:POLARSSL_PKCS1_V15