in native/src/sslutils.c [295:386]
int SSL_callback_SSL_verify(int ok, X509_STORE_CTX *ctx)
{
/* Get Apache context back through OpenSSL context */
SSL *ssl = X509_STORE_CTX_get_ex_data(ctx,
SSL_get_ex_data_X509_STORE_CTX_idx());
tcn_ssl_conn_t *con = (tcn_ssl_conn_t *)SSL_get_app_data(ssl);
/* Get verify ingredients */
int errnum = X509_STORE_CTX_get_error(ctx);
int errdepth = X509_STORE_CTX_get_error_depth(ctx);
int verify = con->ctx->verify_mode;
int depth = con->ctx->verify_depth;
int ocsp_check_type = con->ctx->no_ocsp_check;
#if defined(SSL_OP_NO_TLSv1_3)
con->pha_state = PHA_COMPLETE;
#endif
if (verify == SSL_CVERIFY_UNSET ||
verify == SSL_CVERIFY_NONE) {
return 1;
}
if (SSL_VERIFY_ERROR_IS_OPTIONAL(errnum) &&
(verify == SSL_CVERIFY_OPTIONAL_NO_CA)) {
ok = 1;
SSL_set_verify_result(ssl, X509_V_OK);
}
/*
* Expired certificates vs. "expired" CRLs: by default, OpenSSL
* turns X509_V_ERR_CRL_HAS_EXPIRED into a "certificate_expired(45)"
* SSL alert, but that's not really the message we should convey to the
* peer (at the very least, it's confusing, and in many cases, it's also
* inaccurate, as the certificate itself may very well not have expired
* yet). We set the X509_STORE_CTX error to something which OpenSSL's
* s3_both.c:ssl_verify_alarm_type() maps to SSL_AD_CERTIFICATE_UNKNOWN,
* i.e. the peer will receive a "certificate_unknown(46)" alert.
* We do not touch errnum, though, so that later on we will still log
* the "real" error, as returned by OpenSSL.
*/
if (!ok && errnum == X509_V_ERR_CRL_HAS_EXPIRED) {
X509_STORE_CTX_set_error(ctx, -1);
}
#ifdef HAVE_OCSP
/* First perform OCSP validation if possible */
if (ocsp_check_type == 0) {
if (ok) {
/* If there was an optional verification error, it's not
* possible to perform OCSP validation since the issuer may be
* missing/untrusted. Fail in that case.
*/
if (SSL_VERIFY_ERROR_IS_OPTIONAL(errnum)) {
X509_STORE_CTX_set_error(ctx, X509_V_ERR_APPLICATION_VERIFICATION);
errnum = X509_V_ERR_APPLICATION_VERIFICATION;
ok = 0;
}
else {
int ocsp_response = ssl_verify_OCSP(ctx);
if (ocsp_response == OCSP_STATUS_REVOKED) {
ok = 0 ;
errnum = X509_STORE_CTX_get_error(ctx);
}
else if (ocsp_response == OCSP_STATUS_UNKNOWN) {
errnum = X509_STORE_CTX_get_error(ctx);
if (errnum)
ok = 0 ;
}
}
}
}
#endif
/*
* If we already know it's not ok, log the real reason
*/
if (!ok) {
/* TODO: Some logging
* Certificate Verification: Error
*/
if (con->peer) {
X509_free(con->peer);
con->peer = NULL;
}
}
if (errdepth > depth) {
/* TODO: Some logging
* Certificate Verification: Certificate Chain too long
*/
ok = 0;
}
return ok;
}