/* * check peer cert against CRL */ result_t x509_verify_crl(const char *crl_file, const char* crl_inline, x509_crt *cert, const char *subject) { result_t retval = FAILURE; x509_crl crl = {0}; struct gc_arena gc = gc_new(); char *serial; if (!strcmp (crl_file, INLINE_FILE_TAG) && crl_inline) { if (!polar_ok(x509_crl_parse(&crl, crl_inline, strlen(crl_inline)))) { msg (M_WARN, "CRL: cannot parse inline CRL"); goto end; } } else { if (!polar_ok(x509_crl_parse_file(&crl, crl_file))) { msg (M_WARN, "CRL: cannot read CRL from file %s", crl_file); goto end; } } if(cert->issuer_raw.len != crl.issuer_raw.len || memcmp(crl.issuer_raw.p, cert->issuer_raw.p, crl.issuer_raw.len) != 0) { msg (M_WARN, "CRL: CRL %s is from a different issuer than the issuer of " "certificate %s", crl_file, subject); retval = SUCCESS; goto end; } if (!polar_ok(x509_crt_revoked(cert, &crl))) { serial = backend_x509_get_serial_hex(cert, &gc); msg (D_HANDSHAKE, "CRL CHECK FAILED: %s (serial %s) is REVOKED", subject, (serial ? serial : "NOT AVAILABLE")); goto end; } retval = SUCCESS; msg (D_HANDSHAKE, "CRL CHECK OK: %s",subject); end: gc_free(&gc); x509_crl_free(&crl); return retval; }
/* * check peer cert against CRL */ result_t x509_verify_crl(const char *crl_file, x509_crt *cert, const char *subject) { result_t retval = FAILURE; x509_crl crl = {0}; struct gc_arena gc = gc_new(); char *serial; int polar_retval = x509_crl_parse_file(&crl, crl_file); if (polar_retval != 0) { char errstr[128]; polarssl_strerror(polar_retval, errstr, sizeof(errstr)); msg (M_WARN, "CRL: cannot read CRL from file %s (%s)", crl_file, errstr); goto end; } if(cert->issuer_raw.len != crl.issuer_raw.len || memcmp(crl.issuer_raw.p, cert->issuer_raw.p, crl.issuer_raw.len) != 0) { msg (M_WARN, "CRL: CRL %s is from a different issuer than the issuer of " "certificate %s", crl_file, subject); retval = SUCCESS; goto end; } if (0 != x509_crt_revoked(cert, &crl)) { serial = backend_x509_get_serial_hex(cert, &gc); msg (D_HANDSHAKE, "CRL CHECK FAILED: %s (serial %s) is REVOKED", subject, (serial ? serial : "NOT AVAILABLE")); goto end; } retval = SUCCESS; msg (D_HANDSHAKE, "CRL CHECK OK: %s",subject); end: gc_free(&gc); x509_crl_free(&crl); return retval; }
/* * Check that the given certificate is valid according to the CRL. */ static int x509_crt_verifycrl( x509_crt *crt, x509_crt *ca, x509_crl *crl_list) { int flags = 0; unsigned char hash[POLARSSL_MD_MAX_SIZE]; const md_info_t *md_info; if( ca == NULL ) return( flags ); /* * TODO: What happens if no CRL is present? * Suggestion: Revocation state should be unknown if no CRL is present. * For backwards compatibility this is not yet implemented. */ while( crl_list != NULL ) { if( crl_list->version == 0 || crl_list->issuer_raw.len != ca->subject_raw.len || memcmp( crl_list->issuer_raw.p, ca->subject_raw.p, crl_list->issuer_raw.len ) != 0 ) { crl_list = crl_list->next; continue; } /* * Check if CRL is correctly signed by the trusted CA */ md_info = md_info_from_type( crl_list->sig_md ); if( md_info == NULL ) { /* * Cannot check 'unknown' hash */ flags |= BADCRL_NOT_TRUSTED; break; } md( md_info, crl_list->tbs.p, crl_list->tbs.len, hash ); if( pk_can_do( &ca->pk, crl_list->sig_pk ) == 0 || pk_verify( &ca->pk, crl_list->sig_md, hash, md_info->size, crl_list->sig.p, crl_list->sig.len ) != 0 ) { flags |= BADCRL_NOT_TRUSTED; break; } /* * Check for validity of CRL (Do not drop out) */ if( x509_time_expired( &crl_list->next_update ) ) flags |= BADCRL_EXPIRED; /* * Check if certificate is revoked */ if( x509_crt_revoked(crt, crl_list) ) { flags |= BADCERT_REVOKED; break; } crl_list = crl_list->next; } return flags; }