/** * Create OCSP check * * @v cert Certificate to check * @v issuer Issuing certificate * @ret ocsp OCSP check * @ret rc Return status code */ int ocsp_check ( struct x509_certificate *cert, struct x509_certificate *issuer, struct ocsp_check **ocsp ) { int rc; /* Sanity checks */ assert ( cert != NULL ); assert ( issuer != NULL ); assert ( x509_is_valid ( issuer ) ); /* Allocate and initialise check */ *ocsp = zalloc ( sizeof ( **ocsp ) ); if ( ! *ocsp ) { rc = -ENOMEM; goto err_alloc; } ref_init ( &(*ocsp)->refcnt, ocsp_free ); (*ocsp)->cert = x509_get ( cert ); (*ocsp)->issuer = x509_get ( issuer ); /* Build request */ if ( ( rc = ocsp_request ( *ocsp ) ) != 0 ) goto err_request; /* Build URI string */ if ( ( rc = ocsp_uri_string ( *ocsp ) ) != 0 ) goto err_uri_string; return 0; err_uri_string: err_request: ocsp_put ( *ocsp ); err_alloc: *ocsp = NULL; return rc; }
NOEXPORT int ocsp_check(X509_STORE_CTX *callback_ctx) { SSL *ssl; CLI *c; X509 *cert; OCSP_CERTID *cert_id; STACK_OF(OPENSSL_STRING) *aia; int i, status=V_OCSP_CERTSTATUS_UNKNOWN; /* get the current certificate ID */ cert=X509_STORE_CTX_get_current_cert(callback_ctx); if(!cert) { s_log(LOG_ERR, "OCSP: Failed to get the current certificate"); X509_STORE_CTX_set_error(callback_ctx, X509_V_ERR_APPLICATION_VERIFICATION); return 0; /* reject */ } if(!X509_NAME_cmp(X509_get_subject_name(cert), X509_get_issuer_name(cert))) { s_log(LOG_DEBUG, "OCSP: Ignoring root certificate"); return 1; /* accept */ } cert_id=OCSP_cert_to_id(NULL, cert, get_current_issuer(callback_ctx)); if(!cert_id) { sslerror("OCSP: OCSP_cert_to_id"); X509_STORE_CTX_set_error(callback_ctx, X509_V_ERR_APPLICATION_VERIFICATION); return 0; /* reject */ } ssl=X509_STORE_CTX_get_ex_data(callback_ctx, SSL_get_ex_data_X509_STORE_CTX_idx()); c=SSL_get_ex_data(ssl, cli_index); /* use the responder specified in the configuration file */ if(c->opt->ocsp_url) { s_log(LOG_DEBUG, "OCSP: Connecting configured responder \"%s\"", c->opt->ocsp_url); if(ocsp_request(c, callback_ctx, cert_id, c->opt->ocsp_url)!= V_OCSP_CERTSTATUS_GOOD) return 0; /* reject */ } /* use the responder from AIA (Authority Information Access) */ if(!c->opt->option.aia) return 1; /* accept */ aia=X509_get1_ocsp(cert); if(!aia) return 1; /* accept */ for(i=0; i<sk_OPENSSL_STRING_num(aia); i++) { s_log(LOG_DEBUG, "OCSP: Connecting AIA responder \"%s\"", sk_OPENSSL_STRING_value(aia, i)); status=ocsp_request(c, callback_ctx, cert_id, sk_OPENSSL_STRING_value(aia, i)); if(status!=V_OCSP_CERTSTATUS_UNKNOWN) break; /* we received a definitive response */ } X509_email_free(aia); if(status==V_OCSP_CERTSTATUS_GOOD) return 1; /* accept */ return 0; /* reject */ }