diff --git a/ChangeLog b/ChangeLog index d4cf85b7e..20c8eaf95 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,14 @@ mbed TLS ChangeLog (Sorted per branch, date) += mbed TLS x.x.x branch released xxxx-xx-xx + +Bugfix + * Fix output certificate verification flags set by x509_crt_verify_top() when + traversing a chain of trusted CA. The issue would cause both flags, + BADCERT_NOT_TRUSTED and BADCERT_EXPIRED, to be set when the verification + conditions are not met regardless of the cause. Found by Harm Verhagen and + inestlerode. #665 #561 + = mbed TLS 1.3.18 branch 2016-10-17 Security diff --git a/library/x509_crt.c b/library/x509_crt.c index 4b831aed3..a3517f64f 100644 --- a/library/x509_crt.c +++ b/library/x509_crt.c @@ -1775,6 +1775,7 @@ static int x509_crt_verify_top( int ca_flags = 0, check_path_cnt; unsigned char hash[POLARSSL_MD_MAX_SIZE]; const md_info_t *md_info; + x509_crt *future_past_ca = NULL; if( x509_time_expired( &child->valid_to ) ) *flags |= BADCERT_EXPIRED; @@ -1823,16 +1824,6 @@ static int x509_crt_verify_top( continue; } - if( x509_time_expired( &trust_ca->valid_to ) ) - { - continue; - } - - if( x509_time_future( &trust_ca->valid_from ) ) - { - continue; - } - if( pk_verify_ext( child->sig_pk, child->sig_opts, &trust_ca->pk, child->sig_md, hash, md_info->size, child->sig.p, child->sig.len ) != 0 ) @@ -1840,11 +1831,23 @@ static int x509_crt_verify_top( continue; } + if( x509_time_expired( &trust_ca->valid_to ) || + x509_time_future( &trust_ca->valid_from ) ) + { + if( future_past_ca == NULL ) + future_past_ca = trust_ca; + continue; + } + + break; + } + + if( trust_ca != NULL || ( trust_ca = future_past_ca ) != NULL ) + { /* * Top of chain is signed by a trusted CA */ *flags &= ~BADCERT_NOT_TRUSTED; - break; } /* @@ -1864,6 +1867,12 @@ static int x509_crt_verify_top( ((void) ca_crl); #endif + 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,