Upstream specific tls_cipher_list's

This commit is contained in:
Willem Toorop 2017-12-21 12:30:15 +01:00
parent 8f88981efe
commit ae38a29a50
5 changed files with 48 additions and 13 deletions

View File

@ -1,6 +1,9 @@
* 2017-12-??: Version 1.3.0
* Specify available cipher suites for authenticated TLS upstreams
with getdns_context_set_tls_ciphers_list()
* Specify default available cipher suites for authenticated TLS
upstreams with getdns_context_set_tls_ciphers_list()
An upstream specific available cipher suite may also be given
with the tls_cipher_list setting in the upstream dict with
getdns_context_set_upstream_recursive_servers()
* PR #366: Add support for TLS 1.3 and Chacha20-Poly1305
Thanks Pascal Ernster
* Bugfix #356: Do Zero configuration DNSSEC meta queries over on the

View File

@ -165,6 +165,17 @@ static void set_ub_dnssec_allowed_skew(struct getdns_context*, uint32_t);
/* Stuff to make it compile pedantically */
#define RETURN_IF_NULL(ptr, code) if(ptr == NULL) return code;
static char *
_getdns_strdup2(const struct mem_funcs *mfs, const getdns_bindata *s)
{
char *r;
if (!s || !(r = GETDNS_XMALLOC(*mfs, char, s->size + 1)))
return NULL;
else {
r[s->size] = '\0';
return memcpy(r, s, s->size);
}
}
#ifdef USE_WINSOCK
/* For windows, the CA trust store is not read by openssl.
@ -723,6 +734,8 @@ _getdns_upstreams_dereference(getdns_upstreams *upstreams)
pin = nextpin;
}
upstream->tls_pubkey_pinset = NULL;
if (upstream->tls_cipher_list)
GETDNS_FREE(upstreams->mf, upstream->tls_cipher_list);
}
GETDNS_FREE(upstreams->mf, upstreams);
}
@ -1006,6 +1019,7 @@ upstream_init(getdns_upstream *upstream,
upstream->fd = -1;
upstream->tls_obj = NULL;
upstream->tls_session = NULL;
upstream->tls_cipher_list = NULL;
upstream->transport = GETDNS_TRANSPORT_TCP;
upstream->tls_hs_state = GETDNS_HS_NONE;
upstream->tls_auth_name[0] = '\0';
@ -2977,16 +2991,19 @@ getdns_context_set_upstream_recursive_servers(struct getdns_context *context,
upstream->addr.ss_family = addr.ss_family;
upstream_init(upstream, upstreams, ai);
upstream->transport = getdns_upstream_transports[j];
if (getdns_upstream_transports[j] == GETDNS_TRANSPORT_TLS) {
if (dict && getdns_upstream_transports[j] == GETDNS_TRANSPORT_TLS) {
getdns_list *pubkey_pinset = NULL;
if (dict && (r = getdns_dict_get_bindata(
getdns_bindata *tls_cipher_list = NULL;
if ((r = getdns_dict_get_bindata(
dict, "tls_auth_name", &tls_auth_name)) == GETDNS_RETURN_GOOD) {
if (tls_auth_name->size >= sizeof(upstream->tls_auth_name)) {
/* tls_auth_name's are just
* domain names and should
* thus not be larger than 256
* bytes.
/* tls_auth_name's are
* domain names in presentation
* format and, taking escaping
* into account, should not
* be larger than 1024 bytes.
*/
goto invalid_parameter;
}
@ -2996,7 +3013,7 @@ getdns_context_set_upstream_recursive_servers(struct getdns_context *context,
upstream->tls_auth_name
[tls_auth_name->size] = '\0';
}
if (dict && (r = getdns_dict_get_list(dict, "tls_pubkey_pinset",
if ((r = getdns_dict_get_list(dict, "tls_pubkey_pinset",
&pubkey_pinset)) == GETDNS_RETURN_GOOD) {
/* TODO: what if the user supplies tls_pubkey_pinset with
* something other than a list? */
@ -3006,6 +3023,12 @@ getdns_context_set_upstream_recursive_servers(struct getdns_context *context,
if (r != GETDNS_RETURN_GOOD)
goto invalid_parameter;
}
(void) getdns_dict_get_bindata(
dict, "tls_cipher_list", &tls_cipher_list);
upstream->tls_cipher_list = tls_cipher_list
? _getdns_strdup2(&upstreams->mf
, tls_cipher_list)
: NULL;
}
if ((upstream->tsig_alg = tsig_alg)) {
if (tsig_name) {
@ -3631,7 +3654,7 @@ _getdns_context_prepare_for_resolution(getdns_context *context)
return r;
} /* _getdns_context_prepare_for_resolution */
char *
static char *
_getdns_strdup(const struct mem_funcs *mfs, const char *s)
{
size_t sz;
@ -4483,6 +4506,11 @@ getdns_context_get_upstream_recursive_servers(getdns_context *context,
break;
}
}
if (upstream->tls_cipher_list) {
(void) getdns_dict_util_set_string(
d, "tls_cipher_list",
upstream->tls_cipher_list);
}
}
}
if (!r)

View File

@ -205,6 +205,7 @@ typedef struct getdns_upstream {
getdns_tls_hs_state_t tls_hs_state;
getdns_auth_state_t tls_auth_state;
unsigned tls_fallback_ok : 1;
char *tls_cipher_list;
/* Auth credentials*/
char tls_auth_name[256];
sha256_pin_t *tls_pubkey_pinset;
@ -528,8 +529,6 @@ void _getdns_context_cancel_request(getdns_dns_req *dnsreq);
*/
void _getdns_context_request_timed_out(getdns_dns_req *dnsreq);
char *_getdns_strdup(const struct mem_funcs *mfs, const char *str);
struct getdns_bindata *_getdns_bindata_copy(
struct mem_funcs *mfs, size_t size, const uint8_t *data);

View File

@ -1687,6 +1687,8 @@ getdns_context_set_dnssec_allowed_skew(getdns_context *context,
* - `value` A SHA256 hash of the `SubjectPublicKeyInfo`
* of the upstream, which will be used to authenticate
* it.
* - `tls_cipher_list` (a bindata) that is the string
* of available ciphers specific for this upstream.
* @return GETDNS_RETURN_GOOD when successful.
* @return GETDNS_RETURN_INVALID_PARAMETER when `context` or `upstream_list` was `NULL`
* @return GETDNS_RETURN_CONTEXT_UPDATE_FAIL when there were problems parsing

View File

@ -986,9 +986,12 @@ tls_create_object(getdns_dns_req *dnsreq, int fd, getdns_upstream *upstream)
SSL_set_cipher_list(ssl, "DEFAULT");
DEBUG_STUB("%s %-35s: WARNING: Using Oppotunistic TLS (fallback allowed)!\n",
STUB_DEBUG_SETUP_TLS, __FUNC__);
} else
} else {
if (upstream->tls_cipher_list)
SSL_set_cipher_list(ssl, upstream->tls_cipher_list);
DEBUG_STUB("%s %-35s: Using Strict TLS \n", STUB_DEBUG_SETUP_TLS,
__FUNC__);
}
SSL_set_verify(ssl, SSL_VERIFY_PEER, tls_verify_callback);
SSL_set_connect_state(ssl);