diff --git a/src/request-internal.c b/src/request-internal.c index a74fe8f0..d52ad585 100644 --- a/src/request-internal.c +++ b/src/request-internal.c @@ -182,6 +182,8 @@ network_req_init(getdns_network_req *net_req, getdns_dns_req *owner, net_req->write_queue_tail = NULL; /* Some fields to record info for return_call_reporting */ net_req->debug_tls_auth_status = GETDNS_AUTH_NONE; + net_req->debug_tls_peer_cert.size = 0; + net_req->debug_tls_peer_cert.data = NULL; net_req->debug_udp = 0; /* Scheduling, touch only via _getdns_netreq_change_state! diff --git a/src/stub.c b/src/stub.c index 29112cc3..17b7e1d6 100644 --- a/src/stub.c +++ b/src/stub.c @@ -1618,6 +1618,7 @@ upstream_write_cb(void *userarg) getdns_upstream *upstream = (getdns_upstream *)userarg; getdns_network_req *netreq = upstream->write_queue; int q; + X509 *cert; if (!netreq) { GETDNS_CLEAR_EVENT(upstream->loop, &upstream->event); @@ -1672,8 +1673,13 @@ upstream_write_cb(void *userarg) return; default: + cert = SSL_get_peer_certificate(netreq->upstream->tls_obj); + assert(netreq->debug_tls_peer_cert.data == NULL); + /* Need this because auth status is reset on connection close */ netreq->debug_tls_auth_status = netreq->upstream->tls_auth_state; + netreq->debug_tls_peer_cert.size = i2d_X509( + cert, &netreq->debug_tls_peer_cert.data); upstream->queries_sent++; netreq->query_id = (uint16_t) q; /* Unqueue the netreq from the write_queue */ diff --git a/src/types-internal.h b/src/types-internal.h index 57286bed..5e1961ac 100644 --- a/src/types-internal.h +++ b/src/types-internal.h @@ -240,6 +240,7 @@ typedef struct getdns_network_req uint64_t debug_start_time; uint64_t debug_end_time; getdns_auth_state_t debug_tls_auth_status; + getdns_bindata debug_tls_peer_cert; size_t debug_udp; /* When more space is needed for the wire_data response than is diff --git a/src/util-internal.c b/src/util-internal.c index 48242eb1..5c1d92c7 100644 --- a/src/util-internal.c +++ b/src/util-internal.c @@ -904,6 +904,15 @@ _getdns_create_call_reporting_dict( getdns_dict_destroy(netreq_debug); return NULL; } + if (getdns_dict_set_bindata(netreq_debug, "tls_peer_cert", + &netreq->debug_tls_peer_cert)) { + + getdns_dict_destroy(netreq_debug); + return NULL; + } + netreq->debug_tls_peer_cert.size = 0; + OPENSSL_free(netreq->debug_tls_peer_cert.data); + return netreq_debug; }