}
/* check peer verification */
dtio->ssl_handshake_done = 1;
+
+ if((SSL_get_verify_mode(dtio->ssl)&SSL_VERIFY_PEER)) {
+ /* verification */
+ if(SSL_get_verify_result(dtio->ssl) == X509_V_OK) {
+ X509* x = SSL_get_peer_certificate(dtio->ssl);
+ if(!x) {
+ verbose(VERB_ALGO, "dnstap io, %s, SSL "
+ "connection failed no certificate",
+ dtio->ip_str);
+ /* closed */
+ if(info) dtio_stop_flush_exit(info);
+ dtio_del_output_event(dtio);
+ dtio_close_output(dtio);
+ return 0;
+ }
+ log_cert(VERB_ALGO, "dnstap io, peer certificate",
+ x);
+#ifdef HAVE_SSL_GET0_PEERNAME
+ if(SSL_get0_peername(dtio->ssl)) {
+ verbose(VERB_ALGO, "dnstap io, %s, SSL "
+ "connection to %s authenticated",
+ dtio->ip_str,
+ SSL_get0_peername(dtio->ssl));
+ } else {
+#endif
+ verbose(VERB_ALGO, "dnstap io, %s, SSL "
+ "connection authenticated",
+ dtio->ip_str);
+#ifdef HAVE_SSL_GET0_PEERNAME
+ }
+#endif
+ X509_free(x);
+ } else {
+ X509* x = SSL_get_peer_certificate(dtio->ssl);
+ if(x) {
+ log_cert(VERB_ALGO, "dnstap io, peer "
+ "certificate", x);
+ X509_free(x);
+ }
+ verbose(VERB_ALGO, "dnstap io, %s, SSL connection "
+ "failed: failed to authenticate",
+ dtio->ip_str);
+ /* closed */
+ if(info) dtio_stop_flush_exit(info);
+ dtio_del_output_event(dtio);
+ dtio_close_output(dtio);
+ return 0;
+ }
+ } else {
+ /* unauthenticated, the verify peer flag was not set
+ * in ssl when the ssl object was created from ssl_ctx */
+ verbose(VERB_ALGO, "dnstap io, %s, SSL connection",
+ dtio->ip_str);
+ }
return 1;
}
#endif /* HAVE_SSL */
}
+#ifdef HAVE_SSL
+/** log certificate details */
+void
+log_cert(unsigned level, const char* str, void* cert)
+{
+ BIO* bio;
+ char nul = 0;
+ char* pp = NULL;
+ long len;
+ if(verbosity < level) return;
+ bio = BIO_new(BIO_s_mem());
+ if(!bio) return;
+ X509_print_ex(bio, (X509*)cert, 0, (unsigned long)-1
+ ^(X509_FLAG_NO_SUBJECT
+ |X509_FLAG_NO_ISSUER|X509_FLAG_NO_VALIDITY
+ |X509_FLAG_NO_EXTENSIONS|X509_FLAG_NO_AUX
+ |X509_FLAG_NO_ATTRIBUTES));
+ BIO_write(bio, &nul, (int)sizeof(nul));
+ len = BIO_get_mem_data(bio, &pp);
+ if(len != 0 && pp) {
+ verbose(level, "%s: \n%s", str, pp);
+ }
+ BIO_free(bio);
+}
+#endif /* HAVE_SSL */
+
int
listen_sslctx_setup(void* ctxt)
{
*/
void log_crypto_err_code(const char* str, unsigned long err);
+/**
+ * Log certificate details verbosity, string, of X509 cert
+ * @param level: verbosity level
+ * @param str: string to prefix on output
+ * @param cert: X509* structure.
+ */
+void log_cert(unsigned level, const char* str, void* cert);
+
/**
* Set SSL_OP_NOxxx options on SSL context to disable bad crypto
* @param ctxt: SSL_CTX*
}
}
-#ifdef HAVE_SSL
-/** log certificate details */
-static void
-log_cert(unsigned level, const char* str, X509* cert)
-{
- BIO* bio;
- char nul = 0;
- char* pp = NULL;
- long len;
- if(verbosity < level) return;
- bio = BIO_new(BIO_s_mem());
- if(!bio) return;
- X509_print_ex(bio, cert, 0, (unsigned long)-1
- ^(X509_FLAG_NO_SUBJECT
- |X509_FLAG_NO_ISSUER|X509_FLAG_NO_VALIDITY
- |X509_FLAG_NO_EXTENSIONS|X509_FLAG_NO_AUX
- |X509_FLAG_NO_ATTRIBUTES));
- BIO_write(bio, &nul, (int)sizeof(nul));
- len = BIO_get_mem_data(bio, &pp);
- if(len != 0 && pp) {
- verbose(level, "%s: \n%s", str, pp);
- }
- BIO_free(bio);
-}
-#endif /* HAVE_SSL */
-
#ifdef HAVE_SSL
/** true if the ssl handshake error has to be squelched from the logs */
int