From: Nikos Mavrogiannopoulos Date: Wed, 2 Feb 2011 09:12:55 +0000 (+0100) Subject: Time checks were moved to _gnutls_verify_certificate2(). X-Git-Tag: gnutls_2_99_0~341 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=faa7dae89b2f61af31cb43943a442abfa22acc70;p=thirdparty%2Fgnutls.git Time checks were moved to _gnutls_verify_certificate2(). This allows for straightforward chain verification, and thus better printing of the chain output, although some checks might be performed in duplicate. As a side-effect better errors are returned (or precisely more combinations of verification errors), thus chainverify test was affected. --- diff --git a/lib/x509/verify.c b/lib/x509/verify.c index ac0f5d0aff..f2f05fa1c9 100644 --- a/lib/x509/verify.c +++ b/lib/x509/verify.c @@ -320,7 +320,30 @@ gnutls_x509_crt_t issuer = NULL; return issuer; } +static unsigned int +check_time (gnutls_x509_crt_t crt, time_t now) +{ + int status = 0; + time_t t; + + t = gnutls_x509_crt_get_activation_time (crt); + if (t == (time_t) - 1 || now < t) + { + status |= GNUTLS_CERT_NOT_ACTIVATED; + status |= GNUTLS_CERT_INVALID; + return status; + } + t = gnutls_x509_crt_get_expiration_time (crt); + if (t == (time_t) - 1 || now > t) + { + status |= GNUTLS_CERT_EXPIRED; + status |= GNUTLS_CERT_INVALID; + return status; + } + + return 0; +} /* * Verifies the given certificate again a certificate list of @@ -340,6 +363,7 @@ _gnutls_verify_certificate2 (gnutls_x509_crt_t cert, int tcas_size, unsigned int flags, unsigned int *output, gnutls_x509_crt_t * _issuer, + time_t now, gnutls_verify_output_function func) { gnutls_datum_t cert_signed_data = { NULL, 0 }; @@ -458,9 +482,31 @@ _gnutls_verify_certificate2 (gnutls_x509_crt_t cert, } } + /* Check activation/expiration times + */ + if (!(flags & GNUTLS_VERIFY_DISABLE_TIME_CHECKS)) + { + /* check the time of the issuer first */ + if (!(flags & GNUTLS_VERIFY_DISABLE_TRUSTED_TIME_CHECKS)) + { + out |= check_time (issuer, now); + if (out != 0) + { + result = 0; + if (output) *output |= out; + } + } + + out |= check_time (cert, now); + if (out != 0) + { + result = 0; + if (output) *output |= out; + } + } + cleanup: if (result >= 0 && func) func(cert, issuer, NULL, out); - _gnutls_free_datum (&cert_signed_data); _gnutls_free_datum (&cert_signature); @@ -486,31 +532,6 @@ gnutls_x509_crt_check_issuer (gnutls_x509_crt_t cert, return is_issuer (cert, issuer); } -static unsigned int -check_time (gnutls_x509_crt_t crt, time_t now) -{ - int status = 0; - time_t t; - - t = gnutls_x509_crt_get_activation_time (crt); - if (t == (time_t) - 1 || now < t) - { - status |= GNUTLS_CERT_NOT_ACTIVATED; - status |= GNUTLS_CERT_INVALID; - return status; - } - - t = gnutls_x509_crt_get_expiration_time (crt); - if (t == (time_t) - 1 || now > t) - { - status |= GNUTLS_CERT_EXPIRED; - status |= GNUTLS_CERT_INVALID; - return status; - } - - return 0; -} - /* Verify X.509 certificate chain. * * Note that the return value is an OR of GNUTLS_CERT_* elements. @@ -602,9 +623,10 @@ _gnutls_x509_verify_certificate (const gnutls_x509_crt_t * certificate_list, * If no CAs are present returns CERT_INVALID. Thus works * in self signed etc certificates. */ + output = 0; ret = _gnutls_verify_certificate2 (certificate_list[clist_size - 1], trusted_cas, tcas_size, flags, &output, - &issuer, func); + &issuer, now, func); if (ret == 0) { /* if the last certificate in the certificate @@ -617,42 +639,11 @@ _gnutls_x509_verify_certificate (const gnutls_x509_crt_t * certificate_list, return status; } - /* Check activation/expiration times - */ - if (!(flags & GNUTLS_VERIFY_DISABLE_TIME_CHECKS)) - { - /* check the time of the issuer first */ - if (!(flags & GNUTLS_VERIFY_DISABLE_TRUSTED_TIME_CHECKS)) - { - if (issuer == NULL) - { - gnutls_assert (); - return GNUTLS_E_INTERNAL_ERROR; - } - - status |= check_time (issuer, now); - if (status != 0) - { - if (func) func(certificate_list[clist_size - 1], issuer, NULL, status); - return status; - } - } - - for (i = 0; i < clist_size; i++) - { - status |= check_time (certificate_list[i], now); - if (status != 0) - { - if (func) func(certificate_list[i], NULL, NULL, status); - return status; - } - } - } - /* Verify the certificate path (chain) */ for (i = clist_size - 1; i > 0; i--) { + output = 0; if (i - 1 < 0) break; @@ -664,8 +655,9 @@ _gnutls_x509_verify_certificate (const gnutls_x509_crt_t * certificate_list, if ((ret = _gnutls_verify_certificate2 (certificate_list[i - 1], &certificate_list[i], 1, flags, - NULL, NULL, func)) == 0) + &output, NULL, now, func)) == 0) { + status |= output; status |= GNUTLS_CERT_INVALID; return status; } diff --git a/tests/chainverify.c b/tests/chainverify.c index 800b005a53..a7d5daf9f5 100644 --- a/tests/chainverify.c +++ b/tests/chainverify.c @@ -712,10 +712,10 @@ static struct GNUTLS_VERIFY_DISABLE_TIME_CHECKS | GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT, 0 }, { "rsa-md5 fail", mayfirst_chain, &mayfirst_chain[1], - 0, GNUTLS_CERT_INSECURE_ALGORITHM | GNUTLS_CERT_INVALID }, + 0, GNUTLS_CERT_INSECURE_ALGORITHM | GNUTLS_CERT_EXPIRED | GNUTLS_CERT_INVALID }, { "rsa-md5 not ok", mayfirst_chain, &mayfirst_chain[1], GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD2, - GNUTLS_CERT_INSECURE_ALGORITHM | GNUTLS_CERT_INVALID }, + GNUTLS_CERT_INSECURE_ALGORITHM | GNUTLS_CERT_EXPIRED | GNUTLS_CERT_INVALID }, { "rsa-md5 not ok2", mayfirst_chain, &mayfirst_chain[1], GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5, GNUTLS_CERT_EXPIRED | GNUTLS_CERT_INVALID },