Revise all TLS interfaces to pass in GetDNS memory functions where necessary.

This means we can remove OpenSSL_free() calls from request-internal.c and util-internal.c.
This commit is contained in:
Jim Hague 2018-11-27 14:41:46 +00:00
parent bc3106af94
commit 5e390a4b23
6 changed files with 105 additions and 70 deletions

View File

@ -633,11 +633,11 @@ _getdns_upstreams_dereference(getdns_upstreams *upstreams)
} }
} }
if (upstream->tls_session != NULL) if (upstream->tls_session != NULL)
_getdns_tls_session_free(upstream->tls_session); _getdns_tls_session_free(&upstreams->mf, upstream->tls_session);
if (upstream->tls_obj != NULL) { if (upstream->tls_obj != NULL) {
_getdns_tls_connection_shutdown(upstream->tls_obj); _getdns_tls_connection_shutdown(upstream->tls_obj);
_getdns_tls_connection_free(upstream->tls_obj); _getdns_tls_connection_free(&upstreams->mf, upstream->tls_obj);
} }
if (upstream->fd != -1) if (upstream->fd != -1)
{ {
@ -750,7 +750,7 @@ _getdns_upstream_reset(getdns_upstream *upstream)
} }
if (upstream->tls_obj != NULL) { if (upstream->tls_obj != NULL) {
_getdns_tls_connection_shutdown(upstream->tls_obj); _getdns_tls_connection_shutdown(upstream->tls_obj);
_getdns_tls_connection_free(upstream->tls_obj); _getdns_tls_connection_free(&upstream->upstreams->mf, upstream->tls_obj);
upstream->tls_obj = NULL; upstream->tls_obj = NULL;
} }
if (upstream->fd != -1) { if (upstream->fd != -1) {
@ -1681,7 +1681,7 @@ getdns_context_destroy(struct getdns_context *context)
GETDNS_FREE(context->my_mf, context->dns_transports); GETDNS_FREE(context->my_mf, context->dns_transports);
if (context->tls_ctx) if (context->tls_ctx)
_getdns_tls_context_free(context->tls_ctx); _getdns_tls_context_free(&context->my_mf, context->tls_ctx);
getdns_list_destroy(context->dns_root_servers); getdns_list_destroy(context->dns_root_servers);
@ -3544,13 +3544,13 @@ _getdns_context_prepare_for_resolution(getdns_context *context)
} }
if (context->tls_ctx == NULL) { if (context->tls_ctx == NULL) {
context->tls_ctx = _getdns_tls_context_new(); context->tls_ctx = _getdns_tls_context_new(&context->my_mf);
if (context->tls_ctx == NULL) if (context->tls_ctx == NULL)
return GETDNS_RETURN_BAD_CONTEXT; return GETDNS_RETURN_BAD_CONTEXT;
r = _getdns_tls_context_set_min_proto_1_2(context->tls_ctx); r = _getdns_tls_context_set_min_proto_1_2(context->tls_ctx);
if (r && r != GETDNS_RETURN_NOT_IMPLEMENTED) { if (r && r != GETDNS_RETURN_NOT_IMPLEMENTED) {
_getdns_tls_context_free(context->tls_ctx); _getdns_tls_context_free(&context->my_mf, context->tls_ctx);
context->tls_ctx = NULL; context->tls_ctx = NULL;
return GETDNS_RETURN_BAD_CONTEXT; return GETDNS_RETURN_BAD_CONTEXT;
} }

View File

@ -73,14 +73,14 @@ static int _getdns_tls_verify_always_ok(int ok, X509_STORE_CTX *ctx)
return 1; return 1;
} }
static _getdns_tls_x509* _getdns_tls_x509_new(X509* cert) static _getdns_tls_x509* _getdns_tls_x509_new(struct mem_funcs* mfs, X509* cert)
{ {
_getdns_tls_x509* res; _getdns_tls_x509* res;
if (!cert) if (!cert)
return NULL; return NULL;
res = malloc(sizeof(_getdns_tls_x509)); res = GETDNS_MALLOC(*mfs, _getdns_tls_x509);
if (res) if (res)
res->ssl = cert; res->ssl = cert;
@ -187,11 +187,11 @@ void _getdns_tls_init()
(void)OPENSSL_init_ssl(0, NULL); (void)OPENSSL_init_ssl(0, NULL);
} }
_getdns_tls_context* _getdns_tls_context_new() _getdns_tls_context* _getdns_tls_context_new(struct mem_funcs* mfs)
{ {
_getdns_tls_context* res; _getdns_tls_context* res;
if (!(res = malloc(sizeof(struct _getdns_tls_context)))) if (!(res = GETDNS_MALLOC(*mfs, struct _getdns_tls_context)))
return NULL; return NULL;
/* Create client context, use TLS v1.2 only for now */ /* Create client context, use TLS v1.2 only for now */
@ -201,18 +201,18 @@ _getdns_tls_context* _getdns_tls_context_new()
res->ssl = SSL_CTX_new(TLSv1_2_client_method()); res->ssl = SSL_CTX_new(TLSv1_2_client_method());
# endif # endif
if(res->ssl == NULL) { if(res->ssl == NULL) {
free(res); GETDNS_FREE(*mfs, res);
return NULL; return NULL;
} }
return res; return res;
} }
getdns_return_t _getdns_tls_context_free(_getdns_tls_context* ctx) getdns_return_t _getdns_tls_context_free(struct mem_funcs* mfs, _getdns_tls_context* ctx)
{ {
if (!ctx || !ctx->ssl) if (!ctx || !ctx->ssl)
return GETDNS_RETURN_INVALID_PARAMETER; return GETDNS_RETURN_INVALID_PARAMETER;
SSL_CTX_free(ctx->ssl); SSL_CTX_free(ctx->ssl);
free(ctx); GETDNS_FREE(*mfs, ctx);
return GETDNS_RETURN_GOOD; return GETDNS_RETURN_GOOD;
} }
@ -270,25 +270,25 @@ getdns_return_t _getdns_tls_context_set_ca(_getdns_tls_context* ctx, const char*
return GETDNS_RETURN_GENERIC_ERROR; return GETDNS_RETURN_GENERIC_ERROR;
} }
_getdns_tls_connection* _getdns_tls_connection_new(_getdns_tls_context* ctx, int fd) _getdns_tls_connection* _getdns_tls_connection_new(struct mem_funcs* mfs, _getdns_tls_context* ctx, int fd)
{ {
_getdns_tls_connection* res; _getdns_tls_connection* res;
if (!ctx || !ctx->ssl) if (!ctx || !ctx->ssl)
return NULL; return NULL;
if (!(res = malloc(sizeof(struct _getdns_tls_connection)))) if (!(res = GETDNS_MALLOC(*mfs, struct _getdns_tls_connection)))
return NULL; return NULL;
res->ssl = SSL_new(ctx->ssl); res->ssl = SSL_new(ctx->ssl);
if (!res->ssl) { if (!res->ssl) {
free(res); GETDNS_FREE(*mfs, res);
return NULL; return NULL;
} }
if (!SSL_set_fd(res->ssl, fd)) { if (!SSL_set_fd(res->ssl, fd)) {
SSL_free(res->ssl); SSL_free(res->ssl);
free(res); GETDNS_FREE(*mfs, res);
return NULL; return NULL;
} }
@ -300,12 +300,12 @@ _getdns_tls_connection* _getdns_tls_connection_new(_getdns_tls_context* ctx, int
return res; return res;
} }
getdns_return_t _getdns_tls_connection_free(_getdns_tls_connection* conn) getdns_return_t _getdns_tls_connection_free(struct mem_funcs* mfs, _getdns_tls_connection* conn)
{ {
if (!conn || !conn->ssl) if (!conn || !conn->ssl)
return GETDNS_RETURN_INVALID_PARAMETER; return GETDNS_RETURN_INVALID_PARAMETER;
SSL_free(conn->ssl); SSL_free(conn->ssl);
free(conn); GETDNS_FREE(*mfs, conn);
return GETDNS_RETURN_GOOD; return GETDNS_RETURN_GOOD;
} }
@ -353,19 +353,19 @@ getdns_return_t _getdns_tls_connection_set_session(_getdns_tls_connection* conn,
return GETDNS_RETURN_GOOD; return GETDNS_RETURN_GOOD;
} }
_getdns_tls_session* _getdns_tls_connection_get_session(_getdns_tls_connection* conn) _getdns_tls_session* _getdns_tls_connection_get_session(struct mem_funcs* mfs, _getdns_tls_connection* conn)
{ {
_getdns_tls_session* res; _getdns_tls_session* res;
if (!conn || !conn->ssl) if (!conn || !conn->ssl)
return NULL; return NULL;
if (!(res = malloc(sizeof(struct _getdns_tls_session)))) if (!(res = GETDNS_MALLOC(*mfs, struct _getdns_tls_session)))
return NULL; return NULL;
res->ssl = SSL_get1_session(conn->ssl); res->ssl = SSL_get1_session(conn->ssl);
if (!res->ssl) { if (!res->ssl) {
free(res); GETDNS_FREE(*mfs, res);
return NULL; return NULL;
} }
@ -404,12 +404,12 @@ getdns_return_t _getdns_tls_connection_do_handshake(_getdns_tls_connection* conn
} }
} }
_getdns_tls_x509* _getdns_tls_connection_get_peer_certificate(_getdns_tls_connection* conn) _getdns_tls_x509* _getdns_tls_connection_get_peer_certificate(struct mem_funcs* mfs, _getdns_tls_connection* conn)
{ {
if (!conn || !conn->ssl) if (!conn || !conn->ssl)
return NULL; return NULL;
return _getdns_tls_x509_new(SSL_get_peer_certificate(conn->ssl)); return _getdns_tls_x509_new(mfs, SSL_get_peer_certificate(conn->ssl));
} }
getdns_return_t _getdns_tls_connection_is_session_reused(_getdns_tls_connection* conn) getdns_return_t _getdns_tls_connection_is_session_reused(_getdns_tls_connection* conn)
@ -552,12 +552,12 @@ getdns_return_t _getdns_tls_connection_write(_getdns_tls_connection* conn, uint8
return GETDNS_RETURN_GOOD; return GETDNS_RETURN_GOOD;
} }
getdns_return_t _getdns_tls_session_free(_getdns_tls_session* s) getdns_return_t _getdns_tls_session_free(struct mem_funcs* mfs, _getdns_tls_session* s)
{ {
if (!s || !s->ssl) if (!s || !s->ssl)
return GETDNS_RETURN_INVALID_PARAMETER; return GETDNS_RETURN_INVALID_PARAMETER;
SSL_SESSION_free(s->ssl); SSL_SESSION_free(s->ssl);
free(s); GETDNS_FREE(*mfs, s);
return GETDNS_RETURN_GOOD; return GETDNS_RETURN_GOOD;
} }
@ -594,22 +594,38 @@ getdns_return_t _getdns_tls_get_api_information(getdns_dict* dict)
return GETDNS_RETURN_GENERIC_ERROR; return GETDNS_RETURN_GENERIC_ERROR;
} }
void _getdns_tls_x509_free(_getdns_tls_x509* cert) void _getdns_tls_x509_free(struct mem_funcs* mfs, _getdns_tls_x509* cert)
{ {
if (cert && cert->ssl) if (cert && cert->ssl)
X509_free(cert->ssl); X509_free(cert->ssl);
free(cert); GETDNS_FREE(*mfs, cert);
} }
int _getdns_tls_x509_to_der(_getdns_tls_x509* cert, uint8_t** buf) int _getdns_tls_x509_to_der(struct mem_funcs* mfs, _getdns_tls_x509* cert, getdns_bindata* bindata)
{ {
if (!cert || !cert->ssl) unsigned char* buf = NULL;
int len;
if (!cert || !cert->ssl )
return 0; return 0;
return i2d_X509(cert->ssl, buf); if (bindata == NULL)
return i2d_X509(cert->ssl, NULL);
len = i2d_X509(cert->ssl, &buf);
if (len == 0 || (bindata->data = GETDNS_XMALLOC(*mfs, uint8_t, len)) == NULL) {
bindata->size = 0;
bindata->data = NULL;
} else {
bindata->size = len;
(void) memcpy(bindata->data, buf, len);
OPENSSL_free(buf);
}
return len;
} }
unsigned char* _getdns_tls_hmac_hash(int algorithm, const void* key, size_t key_size, const void* data, size_t data_size, size_t* output_size) unsigned char* _getdns_tls_hmac_hash(struct mem_funcs* mfs, int algorithm, const void* key, size_t key_size, const void* data, size_t data_size, size_t* output_size)
{ {
const EVP_MD* digester; const EVP_MD* digester;
unsigned char* res; unsigned char* res;
@ -637,7 +653,7 @@ unsigned char* _getdns_tls_hmac_hash(int algorithm, const void* key, size_t key_
default : return NULL; default : return NULL;
} }
res = (unsigned char*) malloc(EVP_MAX_MD_SIZE); res = (unsigned char*) GETDNS_XMALLOC(*mfs, unsigned char, EVP_MAX_MD_SIZE);
if (!res) if (!res)
return NULL; return NULL;
@ -648,7 +664,7 @@ unsigned char* _getdns_tls_hmac_hash(int algorithm, const void* key, size_t key_
return res; return res;
} }
_getdns_tls_hmac* _getdns_tls_hmac_new(int algorithm, const void* key, size_t key_size) _getdns_tls_hmac* _getdns_tls_hmac_new(struct mem_funcs* mfs, int algorithm, const void* key, size_t key_size)
{ {
const EVP_MD *digester; const EVP_MD *digester;
_getdns_tls_hmac* res; _getdns_tls_hmac* res;
@ -675,13 +691,13 @@ _getdns_tls_hmac* _getdns_tls_hmac_new(int algorithm, const void* key, size_t ke
default : return NULL; default : return NULL;
} }
if (!(res = malloc(sizeof(struct _getdns_tls_hmac)))) if (!(res = GETDNS_MALLOC(*mfs, struct _getdns_tls_hmac)))
return NULL; return NULL;
#ifdef HAVE_HMAC_CTX_NEW #ifdef HAVE_HMAC_CTX_NEW
res->ctx = HMAC_CTX_new(); res->ctx = HMAC_CTX_new();
if (!res->ctx) { if (!res->ctx) {
free(res); GETDNS_FREE(*mfs, res);
return NULL; return NULL;
} }
#else #else
@ -692,7 +708,7 @@ _getdns_tls_hmac* _getdns_tls_hmac_new(int algorithm, const void* key, size_t ke
#ifdef HAVE_HMAC_CTX_NEW #ifdef HAVE_HMAC_CTX_NEW
HMAC_CTX_free(res->ctx); HMAC_CTX_free(res->ctx);
#endif #endif
free(res); GETDNS_FREE(*mfs, res);
return NULL; return NULL;
} }
@ -710,12 +726,12 @@ getdns_return_t _getdns_tls_hmac_add(_getdns_tls_hmac* h, const void* data, size
return GETDNS_RETURN_GOOD; return GETDNS_RETURN_GOOD;
} }
unsigned char* _getdns_tls_hmac_end(_getdns_tls_hmac* h, size_t* output_size) unsigned char* _getdns_tls_hmac_end(struct mem_funcs* mfs, _getdns_tls_hmac* h, size_t* output_size)
{ {
unsigned char* res; unsigned char* res;
unsigned int md_len; unsigned int md_len;
res = (unsigned char*) malloc(EVP_MAX_MD_SIZE); res = (unsigned char*) GETDNS_XMALLOC(*mfs, unsigned char, EVP_MAX_MD_SIZE);
if (!res) if (!res)
return NULL; return NULL;
@ -724,7 +740,7 @@ unsigned char* _getdns_tls_hmac_end(_getdns_tls_hmac* h, size_t* output_size)
#ifdef HAVE_HMAC_CTX_NEW #ifdef HAVE_HMAC_CTX_NEW
HMAC_CTX_free(h->ctx); HMAC_CTX_free(h->ctx);
#endif #endif
free(h); GETDNS_FREE(*mfs, h);
if (output_size) if (output_size)
*output_size = md_len; *output_size = md_len;

View File

@ -125,7 +125,7 @@ network_req_cleanup(getdns_network_req *net_req)
GETDNS_FREE(net_req->owner->my_mf, net_req->response); GETDNS_FREE(net_req->owner->my_mf, net_req->response);
if (net_req->debug_tls_peer_cert.size && if (net_req->debug_tls_peer_cert.size &&
net_req->debug_tls_peer_cert.data) net_req->debug_tls_peer_cert.data)
OPENSSL_free(net_req->debug_tls_peer_cert.data); GETDNS_FREE(net_req->owner->my_mf, net_req->debug_tls_peer_cert.data);
} }
static uint8_t * static uint8_t *
@ -435,7 +435,7 @@ _getdns_network_req_add_tsig(getdns_network_req *req)
gldns_buffer_write_u16(&gbuf, 0); /* Error */ gldns_buffer_write_u16(&gbuf, 0); /* Error */
gldns_buffer_write_u16(&gbuf, 0); /* Other len */ gldns_buffer_write_u16(&gbuf, 0); /* Other len */
md_buf = _getdns_tls_hmac_hash(upstream->tsig_alg, upstream->tsig_key, upstream->tsig_size, (void *)req->query, gldns_buffer_current(&gbuf) - req->query, &md_len); md_buf = _getdns_tls_hmac_hash(&req->owner->my_mf, upstream->tsig_alg, upstream->tsig_key, upstream->tsig_size, (void *)req->query, gldns_buffer_current(&gbuf) - req->query, &md_len);
if (!md_buf) if (!md_buf)
return req->response - req->query; return req->response - req->query;
@ -457,7 +457,7 @@ _getdns_network_req_add_tsig(getdns_network_req *req)
gldns_buffer_write_u16(&gbuf, 0); /* Error */ gldns_buffer_write_u16(&gbuf, 0); /* Error */
gldns_buffer_write_u16(&gbuf, 0); /* Other len */ gldns_buffer_write_u16(&gbuf, 0); /* Other len */
free(md_buf); GETDNS_FREE(req->owner->my_mf, md_buf);
if (gldns_buffer_position(&gbuf) > gldns_buffer_limit(&gbuf)) if (gldns_buffer_position(&gbuf) > gldns_buffer_limit(&gbuf))
return req->response - req->query; return req->response - req->query;
@ -595,14 +595,14 @@ _getdns_network_validate_tsig(getdns_network_req *req)
gldns_read_uint16(req->response + 10) - 1); gldns_read_uint16(req->response + 10) - 1);
gldns_write_uint16(req->response, original_id); gldns_write_uint16(req->response, original_id);
hmac = _getdns_tls_hmac_new(req->upstream->tsig_alg, req->upstream->tsig_key, req->upstream->tsig_size); hmac = _getdns_tls_hmac_new(&req->owner->my_mf, req->upstream->tsig_alg, req->upstream->tsig_key, req->upstream->tsig_size);
if (!hmac) if (!hmac)
return; return;
_getdns_tls_hmac_add(hmac, request_mac - 2, request_mac_len + 2); _getdns_tls_hmac_add(hmac, request_mac - 2, request_mac_len + 2);
_getdns_tls_hmac_add(hmac, req->response, rr->pos - req->response); _getdns_tls_hmac_add(hmac, req->response, rr->pos - req->response);
_getdns_tls_hmac_add(hmac, tsig_vars, gldns_buffer_position(&gbuf)); _getdns_tls_hmac_add(hmac, tsig_vars, gldns_buffer_position(&gbuf));
result_mac = _getdns_tls_hmac_end(hmac, &result_mac_len); result_mac = _getdns_tls_hmac_end(&req->owner->my_mf, hmac, &result_mac_len);
if (!result_mac) if (!result_mac)
return; return;
@ -612,6 +612,8 @@ _getdns_network_validate_tsig(getdns_network_req *req)
memcmp(result_mac, response_mac, result_mac_len) == 0) memcmp(result_mac, response_mac, result_mac_len) == 0)
req->tsig_status = GETDNS_DNSSEC_SECURE; req->tsig_status = GETDNS_DNSSEC_SECURE;
GETDNS_FREE(req->owner->my_mf, result_mac);
gldns_write_uint16(req->response, gldns_read_uint16(req->query)); gldns_write_uint16(req->response, gldns_read_uint16(req->query));
gldns_write_uint16(req->response + 10, gldns_write_uint16(req->response + 10,
gldns_read_uint16(req->response + 10) + 1); gldns_read_uint16(req->response + 10) + 1);

View File

@ -830,7 +830,7 @@ tls_create_object(getdns_dns_req *dnsreq, int fd, getdns_upstream *upstream)
getdns_context *context = dnsreq->context; getdns_context *context = dnsreq->context;
if (context->tls_ctx == NULL) if (context->tls_ctx == NULL)
return NULL; return NULL;
_getdns_tls_connection* tls = _getdns_tls_connection_new(context->tls_ctx, fd); _getdns_tls_connection* tls = _getdns_tls_connection_new(&context->my_mf, context->tls_ctx, fd);
if(!tls) if(!tls)
return NULL; return NULL;
#if HAVE_TLS_CONN_CURVES_LIST #if HAVE_TLS_CONN_CURVES_LIST
@ -839,7 +839,7 @@ tls_create_object(getdns_dns_req *dnsreq, int fd, getdns_upstream *upstream)
#endif #endif
/* make sure we'll be able to find the context again when we need it */ /* make sure we'll be able to find the context again when we need it */
if (_getdns_associate_upstream_with_connection(tls, upstream) != GETDNS_RETURN_GOOD) { if (_getdns_associate_upstream_with_connection(tls, upstream) != GETDNS_RETURN_GOOD) {
_getdns_tls_connection_free(tls); _getdns_tls_connection_free(&context->my_mf, tls);
return NULL; return NULL;
} }
@ -871,7 +871,7 @@ tls_create_object(getdns_dns_req *dnsreq, int fd, getdns_upstream *upstream)
"%-40s : Verify fail: *CONFIG ERROR* - No auth name or pinset provided for this upstream for Strict TLS authentication\n", "%-40s : Verify fail: *CONFIG ERROR* - No auth name or pinset provided for this upstream for Strict TLS authentication\n",
upstream->addr_str); upstream->addr_str);
upstream->tls_hs_state = GETDNS_HS_FAILED; upstream->tls_hs_state = GETDNS_HS_FAILED;
_getdns_tls_connection_free(tls); _getdns_tls_connection_free(&upstream->upstreams->mf, tls);
upstream->tls_auth_state = GETDNS_AUTH_FAILED; upstream->tls_auth_state = GETDNS_AUTH_FAILED;
return NULL; return NULL;
} }
@ -947,7 +947,7 @@ tls_do_handshake(getdns_upstream *upstream)
upstream->tls_auth_state = upstream->last_tls_auth_state; upstream->tls_auth_state = upstream->last_tls_auth_state;
else if (upstream->tls_pubkey_pinset || upstream->tls_auth_name[0]) { else if (upstream->tls_pubkey_pinset || upstream->tls_auth_name[0]) {
_getdns_tls_x509* peer_cert = _getdns_tls_connection_get_peer_certificate(upstream->tls_obj); _getdns_tls_x509* peer_cert = _getdns_tls_connection_get_peer_certificate(&upstream->upstreams->mf, upstream->tls_obj);
if (!peer_cert) { if (!peer_cert) {
_getdns_upstream_log(upstream, _getdns_upstream_log(upstream,
@ -994,7 +994,7 @@ tls_do_handshake(getdns_upstream *upstream)
"%-40s : Verify passed : TLS\n", "%-40s : Verify passed : TLS\n",
upstream->addr_str); upstream->addr_str);
} }
_getdns_tls_x509_free(peer_cert); _getdns_tls_x509_free(&upstream->upstreams->mf, peer_cert);
} }
if (upstream->tls_auth_state == GETDNS_AUTH_FAILED if (upstream->tls_auth_state == GETDNS_AUTH_FAILED
&& !upstream->tls_fallback_ok) && !upstream->tls_fallback_ok)
@ -1008,8 +1008,8 @@ tls_do_handshake(getdns_upstream *upstream)
upstream->conn_state = GETDNS_CONN_OPEN; upstream->conn_state = GETDNS_CONN_OPEN;
upstream->conn_completed++; upstream->conn_completed++;
if (upstream->tls_session != NULL) if (upstream->tls_session != NULL)
_getdns_tls_session_free(upstream->tls_session); _getdns_tls_session_free(&upstream->upstreams->mf, upstream->tls_session);
upstream->tls_session = _getdns_tls_connection_get_session(upstream->tls_obj); upstream->tls_session = _getdns_tls_connection_get_session(&upstream->upstreams->mf, upstream->tls_obj);
/* Reset timeout on success*/ /* Reset timeout on success*/
GETDNS_CLEAR_EVENT(upstream->loop, &upstream->event); GETDNS_CLEAR_EVENT(upstream->loop, &upstream->event);
upstream->event.read_cb = NULL; upstream->event.read_cb = NULL;
@ -1634,10 +1634,9 @@ upstream_write_cb(void *userarg)
if (netreq->owner->return_call_reporting && if (netreq->owner->return_call_reporting &&
netreq->upstream->tls_obj) { netreq->upstream->tls_obj) {
if (netreq->debug_tls_peer_cert.data == NULL && if (netreq->debug_tls_peer_cert.data == NULL &&
(cert = _getdns_tls_connection_get_peer_certificate(netreq->upstream->tls_obj))) { (cert = _getdns_tls_connection_get_peer_certificate(&upstream->upstreams->mf, netreq->upstream->tls_obj))) {
netreq->debug_tls_peer_cert.size = _getdns_tls_x509_to_der( _getdns_tls_x509_to_der(&upstream->upstreams->mf, cert, &netreq->debug_tls_peer_cert);
cert, &netreq->debug_tls_peer_cert.data); _getdns_tls_x509_free(&upstream->upstreams->mf, cert);
_getdns_tls_x509_free(cert);
} }
netreq->debug_tls_version = _getdns_tls_connection_get_version(netreq->upstream->tls_obj); netreq->debug_tls_version = _getdns_tls_connection_get_version(netreq->upstream->tls_obj);
} }

View File

@ -55,18 +55,20 @@ void _getdns_tls_init();
/** /**
* Create a new TLS context. * Create a new TLS context.
* *
* @param mfs point to getdns memory functions.
* @return pointer to new context or NULL on error. * @return pointer to new context or NULL on error.
*/ */
_getdns_tls_context* _getdns_tls_context_new(); _getdns_tls_context* _getdns_tls_context_new(struct mem_funcs* mfs);
/** /**
* Free a TLS context. * Free a TLS context.
* *
* @param mfs point to getdns memory functions.
* @param ctx the context to free. * @param ctx the context to free.
* @return GETDNS_RETURN_GOOD on success. * @return GETDNS_RETURN_GOOD on success.
* @return GETDNS_RETURN_INVALID_PARAMETER if <code>ctx</code> is invalid. * @return GETDNS_RETURN_INVALID_PARAMETER if <code>ctx</code> is invalid.
*/ */
getdns_return_t _getdns_tls_context_free(_getdns_tls_context* ctx); getdns_return_t _getdns_tls_context_free(struct mem_funcs* mfs, _getdns_tls_context* ctx);
/** /**
* Set TLS 1.2 as minimum TLS version. * Set TLS 1.2 as minimum TLS version.
@ -121,20 +123,22 @@ getdns_return_t _getdns_tls_context_set_ca(_getdns_tls_context* ctx, const char*
/** /**
* Create a new TLS connection and associate it with a file descriptior. * Create a new TLS connection and associate it with a file descriptior.
* *
* @param mfs pointer to getdns memory functions.
* @param ctx the context. * @param ctx the context.
* @param fd the file descriptor to associate with the connection. * @param fd the file descriptor to associate with the connection.
* @return pointer to new connection or NULL on error. * @return pointer to new connection or NULL on error.
*/ */
_getdns_tls_connection* _getdns_tls_connection_new(_getdns_tls_context* ctx, int fd); _getdns_tls_connection* _getdns_tls_connection_new(struct mem_funcs* mfs, _getdns_tls_context* ctx, int fd);
/** /**
* Free a TLS connection. * Free a TLS connection.
* *
* @param mfs pointer to getdns memory functions.
* @param conn the connection to free. * @param conn the connection to free.
* @return GETDNS_RETURN_GOOD on success. * @return GETDNS_RETURN_GOOD on success.
* @return GETDNS_RETURN_INVALID_PARAMETER if <code>conn</code> is invalid. * @return GETDNS_RETURN_INVALID_PARAMETER if <code>conn</code> is invalid.
*/ */
getdns_return_t _getdns_tls_connection_free(_getdns_tls_connection* ctx); getdns_return_t _getdns_tls_connection_free(struct mem_funcs* mfs, _getdns_tls_connection* conn);
/** /**
* Shut down a TLS connection. * Shut down a TLS connection.
@ -184,10 +188,11 @@ getdns_return_t _getdns_tls_connection_set_session(_getdns_tls_connection* conn,
/** /**
* Get the session for this connection. * Get the session for this connection.
* *
* @param mfs pointer to getdns memory functions.
* @param conn the connection. * @param conn the connection.
* @return pointer to the session or NULL on error. * @return pointer to the session or NULL on error.
*/ */
_getdns_tls_session* _getdns_tls_connection_get_session(_getdns_tls_connection* conn); _getdns_tls_session* _getdns_tls_connection_get_session(struct mem_funcs* mfs, _getdns_tls_connection* conn);
/** /**
* Report the TLS version of the connection. * Report the TLS version of the connection.
@ -212,10 +217,11 @@ getdns_return_t _getdns_tls_connection_do_handshake(_getdns_tls_connection* conn
/** /**
* Get the connection peer certificate. * Get the connection peer certificate.
* *
* @param mfs pointer to getdns memory functions.
* @param conn the connection. * @param conn the connection.
* @return certificate or NULL on error. * @return certificate or NULL on error.
*/ */
_getdns_tls_x509* _getdns_tls_connection_get_peer_certificate(_getdns_tls_connection* conn); _getdns_tls_x509* _getdns_tls_connection_get_peer_certificate(struct mem_funcs* mfs, _getdns_tls_connection* conn);
/** /**
* See whether the connection is reusing a session. * See whether the connection is reusing a session.
@ -289,23 +295,32 @@ getdns_return_t _getdns_tls_connection_read(_getdns_tls_connection* conn, uint8_
*/ */
getdns_return_t _getdns_tls_connection_write(_getdns_tls_connection* conn, uint8_t* buf, size_t to_write, size_t* written); getdns_return_t _getdns_tls_connection_write(_getdns_tls_connection* conn, uint8_t* buf, size_t to_write, size_t* written);
getdns_return_t _getdns_tls_session_free(_getdns_tls_session* s); /**
* Free a session.
*
* @param mfs pointer to getdns memory functions.
* @param s the session.
* @return GETDNS_RETURN_GOOD on success.
* @return GETDNS_RETURN_INVALID_PARAMETER if s is null or has no SSL.
*/
getdns_return_t _getdns_tls_session_free(struct mem_funcs* mfs, _getdns_tls_session* s);
/** /**
* Free X509 certificate. * Free X509 certificate.
* *
* @param mfs pointer to getdns memory functions.
* @param cert the certificate. * @param cert the certificate.
*/ */
void _getdns_tls_x509_free(_getdns_tls_x509* cert); void _getdns_tls_x509_free(struct mem_funcs* mfs, _getdns_tls_x509* cert);
/** /**
* Convert X509 to DER. * Convert X509 to DER.
* *
* @param cert the certificate. * @param cert the certificate.
* @param buf buffer to receive conversion. NULL to just get the length. * @param buf buffer to receive conversion.
* @return length of conversion, 0 on error. * @return length of conversion, 0 on error.
*/ */
int _getdns_tls_x509_to_der(_getdns_tls_x509* cert, uint8_t** buf); int _getdns_tls_x509_to_der(struct mem_funcs* mfs, _getdns_tls_x509* cert, getdns_bindata* bindata);
/** /**
* Fill in dictionary with TLS API information. * Fill in dictionary with TLS API information.
@ -319,6 +334,7 @@ getdns_return_t _getdns_tls_get_api_information(getdns_dict* dict);
/** /**
* Return buffer with HMAC hash. * Return buffer with HMAC hash.
* *
* @param mfs pointer to getdns memory functions.
* @param algorithm hash algorithm to use (<code>GETDNS_HMAC_?</code>). * @param algorithm hash algorithm to use (<code>GETDNS_HMAC_?</code>).
* @param key the key. * @param key the key.
* @param key_size the key size. * @param key_size the key size.
@ -327,17 +343,18 @@ getdns_return_t _getdns_tls_get_api_information(getdns_dict* dict);
* @param output_size the output size will be written here if not NULL. * @param output_size the output size will be written here if not NULL.
* @return output malloc'd buffer with output, NULL on error. * @return output malloc'd buffer with output, NULL on error.
*/ */
unsigned char* _getdns_tls_hmac_hash(int algorithm, const void* key, size_t key_size, const void* data, size_t data_size, size_t* output_size); unsigned char* _getdns_tls_hmac_hash(struct mem_funcs* mfs, int algorithm, const void* key, size_t key_size, const void* data, size_t data_size, size_t* output_size);
/** /**
* Return a new HMAC handle. * Return a new HMAC handle.
* *
* @param mfs pointer to getdns memory functions.
* @param algorithm hash algorithm to use (<code>GETDNS_HMAC_?</code>). * @param algorithm hash algorithm to use (<code>GETDNS_HMAC_?</code>).
* @param key the key. * @param key the key.
* @param key_size the key size. * @param key_size the key size.
* @return HMAC handle or NULL on error. * @return HMAC handle or NULL on error.
*/ */
_getdns_tls_hmac* _getdns_tls_hmac_new(int algorithm, const void* key, size_t key_size); _getdns_tls_hmac* _getdns_tls_hmac_new(struct mem_funcs* mfs, int algorithm, const void* key, size_t key_size);
/** /**
* Add data to a HMAC. * Add data to a HMAC.
@ -354,10 +371,11 @@ getdns_return_t _getdns_tls_hmac_add(_getdns_tls_hmac* h, const void* data, size
/** /**
* Return the HMAC digest and free the handle. * Return the HMAC digest and free the handle.
* *
* @param mfs pointer to getdns memory functions.
* @param h the HMAC. * @param h the HMAC.
* @param output_size the output size will be written here if not NULL. * @param output_size the output size will be written here if not NULL.
* @return output malloc'd buffer with output, NULL on error. * @return output malloc'd buffer with output, NULL on error.
*/ */
unsigned char* _getdns_tls_hmac_end(_getdns_tls_hmac* h, size_t* output_size); unsigned char* _getdns_tls_hmac_end(struct mem_funcs* mfs, _getdns_tls_hmac* h, size_t* output_size);
#endif /* _GETDNS_TLS_H */ #endif /* _GETDNS_TLS_H */

View File

@ -933,7 +933,7 @@ _getdns_create_call_reporting_dict(
return NULL; return NULL;
} }
netreq->debug_tls_peer_cert.size = 0; netreq->debug_tls_peer_cert.size = 0;
OPENSSL_free(netreq->debug_tls_peer_cert.data); GETDNS_FREE(context->my_mf, netreq->debug_tls_peer_cert.data);
netreq->debug_tls_peer_cert.data = NULL; netreq->debug_tls_peer_cert.data = NULL;
return netreq_debug; return netreq_debug;
} }