+ DEBUG(D_tls) bp = BIO_new(BIO_s_mem());
+
+ /* Use the CA & chain that verified the server cert to verify the stapled info */
+ /*XXX could we do an event here, for observability of ocsp? What reasonable data could we give access to? */
+ /* Dates would be a start. Do we need another opaque variable type, as for certs, plus an extract expansion? */
+
+ {
+ /* If this routine is not available, we've avoided [in tls_client_start()]
+ asking for certificate-status under DANE, so this callback won't run for
+ that combination. It still will for non-DANE. */
+
+#if defined(EXIM_HAVE_OPENSSL_OCSP_RESP_GET0_SIGNER) && defined(SUPPORT_DANE)
+ X509 * signer;
+
+ if ( tls_out.dane_verified
+ && (have_verified_OCSP_signer =
+ OCSP_resp_get0_signer(bs, &signer, SSL_get0_verified_chain(ssl)) == 1))
+ {
+ DEBUG(D_tls)
+ debug_printf("signer for OCSP basicres is in the verified chain;"
+ " shortcut its verification\n");
+ }
+ else
+#endif
+ {
+ STACK_OF(X509) * verified_chain;
+
+ verify_store = X509_STORE_new();
+
+ SSL_get0_chain_certs(ssl, &verified_chain);
+ add_chain_to_store(verify_store, verified_chain,
+ "'current cert' per SSL_get0_chain_certs()");
+#ifdef EXIM_HAVE_SSL_GET0_VERIFIED_CHAIN
+ verified_chain = SSL_get0_verified_chain(ssl);
+ add_chain_to_store(verify_store, verified_chain,
+ "SSL_get0_verified_chain()");
+#endif
+ }
+ }
+
+ DEBUG(D_tls)
+ {
+ debug_printf("Untrusted intermediate cert stack (from SSL_get_peer_cert_chain()):\n");
+ x509_stack_dump_cert_s_names(SSL_get_peer_cert_chain(ssl));
+
+ debug_printf("will use this CA store for verifying basicresp:\n");
+ x509_store_dump_cert_s_names(verify_store);
+
+ /* OCSP_RESPONSE_print(bp, rsp, 0); extreme debug: stapling content */
+
+ debug_printf("certs contained in basicresp:\n");
+ x509_stack_dump_cert_s_names(
+#ifdef EXIM_HAVE_OPESSL_OCSP_RESP_GET0_CERTS
+ OCSP_resp_get0_certs(bs)
+#else
+ bs->certs
+#endif
+ );
+
+#ifdef EXIM_HAVE_OPENSSL_X509_STORE_GET1_ALL_CERTS
+/* could do via X509_STORE_get0_objects(); not worth it just for debug info */
+ {
+ X509 * signer;
+ if (OCSP_resp_get0_signer(bs, &signer, X509_STORE_get1_all_certs(verify_store)) == 1)
+ {
+ debug_printf("found signer for basicres:\n");
+ debug_print_sn(signer);
+ }
+ else
+ {
+ debug_printf("failed to find signer for basicres:\n");
+ ERR_print_errors(bp);
+ }
+ }
+#endif
+
+ }
+
+ ERR_clear_error();
+
+ /* Under DANE the trust-anchor (at least in TA mode) is indicated by the TLSA
+ record in DNS, and probably is not the root of the chain of certificates. So
+ accept a partial chain for that case (and hope that anchor is visible for
+ verifying the OCSP stapling).
+ XXX for EE mode it won't even be that. Does that make OCSP useless for EE?