aboutsummaryrefslogtreecommitdiff
path: root/util/net_help.c
diff options
context:
space:
mode:
authorCy Schubert <cy@FreeBSD.org>2020-08-21 22:56:05 +0000
committerCy Schubert <cy@FreeBSD.org>2020-08-21 22:56:05 +0000
commit7973006f41cdaf144441d1a39f9f075053435e2f (patch)
tree157d55b04796bb6f041656c0e84dd5106f4bc4be /util/net_help.c
parent6a53c00e64c4cf911eb00846733d9e6a47b2e7f4 (diff)
Diffstat (limited to 'util/net_help.c')
-rw-r--r--util/net_help.c159
1 files changed, 152 insertions, 7 deletions
diff --git a/util/net_help.c b/util/net_help.c
index 0869f91f954e..f59a4d65370d 100644
--- a/util/net_help.c
+++ b/util/net_help.c
@@ -55,6 +55,9 @@
#ifdef HAVE_OPENSSL_ERR_H
#include <openssl/err.h>
#endif
+#ifdef HAVE_OPENSSL_CORE_NAMES_H
+#include <openssl/core_names.h>
+#endif
#ifdef USE_WINSOCK
#include <wincrypt.h>
#endif
@@ -67,8 +70,8 @@ uint16_t EDNS_ADVERTISED_SIZE = 4096;
/** minimal responses when positive answer: default is no */
int MINIMAL_RESPONSES = 0;
-/** rrset order roundrobin: default is no */
-int RRSET_ROUNDROBIN = 0;
+/** rrset order roundrobin: default is yes */
+int RRSET_ROUNDROBIN = 1;
/** log tag queries with name instead of 'info' for filtering */
int LOG_TAG_QUERYREPLY = 0;
@@ -79,6 +82,32 @@ static struct tls_session_ticket_key {
unsigned char *hmac_key;
} *ticket_keys;
+/**
+ * callback TLS session ticket encrypt and decrypt
+ * For use with SSL_CTX_set_tlsext_ticket_key_cb or
+ * SSL_CTX_set_tlsext_ticket_key_evp_cb
+ * @param s: the SSL_CTX to use (from connect_sslctx_create())
+ * @param key_name: secret name, 16 bytes
+ * @param iv: up to EVP_MAX_IV_LENGTH.
+ * @param evp_ctx: the evp cipher context, function sets this.
+ * @param hmac_ctx: the hmac context, function sets this.
+ * with ..key_cb it is of type HMAC_CTX*
+ * with ..key_evp_cb it is of type EVP_MAC_CTX*
+ * @param enc: 1 is encrypt, 0 is decrypt
+ * @return 0 on no ticket, 1 for okay, and 2 for okay but renew the ticket
+ * (the ticket is decrypt only). and <0 for failures.
+ */
+#ifdef HAVE_SSL
+int tls_session_ticket_key_cb(SSL *s, unsigned char* key_name,
+ unsigned char* iv, EVP_CIPHER_CTX *evp_ctx,
+#ifdef HAVE_SSL_CTX_SET_TLSEXT_TICKET_KEY_EVP_CB
+ EVP_MAC_CTX *hmac_ctx,
+#else
+ HMAC_CTX* hmac_ctx,
+#endif
+ int enc);
+#endif /* HAVE_SSL */
+
/* returns true is string addr is an ip6 specced address */
int
str_is_ip6(const char* str)
@@ -829,6 +858,32 @@ void log_crypto_err_code(const char* str, unsigned long err)
#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)
{
@@ -970,7 +1025,7 @@ void* listen_sslctx_create(char* key, char* pem, char* verifypem)
}
SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(
verifypem));
- SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);
+ SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
}
return ctx;
#else
@@ -1191,6 +1246,60 @@ void* outgoing_ssl_fd(void* sslctx, int fd)
#endif
}
+int check_auth_name_for_ssl(char* auth_name)
+{
+ if(!auth_name) return 1;
+#if defined(HAVE_SSL) && !defined(HAVE_SSL_SET1_HOST) && !defined(HAVE_X509_VERIFY_PARAM_SET1_HOST)
+ log_err("the query has an auth_name %s, but libssl has no call to "
+ "perform TLS authentication. Remove that name from config "
+ "or upgrade the ssl crypto library.", auth_name);
+ return 0;
+#else
+ return 1;
+#endif
+}
+
+/** set the authname on an SSL structure, SSL* ssl */
+int set_auth_name_on_ssl(void* ssl, char* auth_name, int use_sni)
+{
+ if(!auth_name) return 1;
+#ifdef HAVE_SSL
+ if(use_sni) {
+ (void)SSL_set_tlsext_host_name(ssl, auth_name);
+ }
+#else
+ (void)ssl;
+ (void)use_sni;
+#endif
+#ifdef HAVE_SSL_SET1_HOST
+ SSL_set_verify(ssl, SSL_VERIFY_PEER, NULL);
+ /* setting the hostname makes openssl verify the
+ * host name in the x509 certificate in the
+ * SSL connection*/
+ if(!SSL_set1_host(ssl, auth_name)) {
+ log_err("SSL_set1_host failed");
+ return 0;
+ }
+#elif defined(HAVE_X509_VERIFY_PARAM_SET1_HOST)
+ /* openssl 1.0.2 has this function that can be used for
+ * set1_host like verification */
+ if(auth_name) {
+ X509_VERIFY_PARAM* param = SSL_get0_param(ssl);
+# ifdef X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS
+ X509_VERIFY_PARAM_set_hostflags(param, X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS);
+# endif
+ if(!X509_VERIFY_PARAM_set1_host(param, auth_name, strlen(auth_name))) {
+ log_err("X509_VERIFY_PARAM_set1_host failed");
+ return 0;
+ }
+ SSL_set_verify(ssl, SSL_VERIFY_PEER, NULL);
+ }
+#else
+ verbose(VERB_ALGO, "the query has an auth_name, but libssl has no call to perform TLS authentication");
+#endif /* HAVE_SSL_SET1_HOST */
+ return 1;
+}
+
#if defined(HAVE_SSL) && defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED) && defined(CRYPTO_LOCK) && OPENSSL_VERSION_NUMBER < 0x10100000L
/** global lock list for openssl locks */
static lock_basic_type *ub_openssl_locks = NULL;
@@ -1285,7 +1394,7 @@ int listen_sslctx_setup_ticket_keys(void* sslctx, struct config_strlist* tls_ses
if(!data)
return 0;
- f = fopen(p->str, "r");
+ f = fopen(p->str, "rb");
if(!f) {
log_err("could not read tls-session-ticket-key %s: %s", p->str, strerror(errno));
free(data);
@@ -1308,10 +1417,17 @@ int listen_sslctx_setup_ticket_keys(void* sslctx, struct config_strlist* tls_ses
}
/* terminate array with NULL key name entry */
keys->key_name = NULL;
+# ifdef HAVE_SSL_CTX_SET_TLSEXT_TICKET_KEY_EVP_CB
+ if(SSL_CTX_set_tlsext_ticket_key_evp_cb(sslctx, tls_session_ticket_key_cb) == 0) {
+ log_err("no support for TLS session ticket");
+ return 0;
+ }
+# else
if(SSL_CTX_set_tlsext_ticket_key_cb(sslctx, tls_session_ticket_key_cb) == 0) {
log_err("no support for TLS session ticket");
return 0;
}
+# endif
return 1;
#else
(void)sslctx;
@@ -1321,13 +1437,27 @@ int listen_sslctx_setup_ticket_keys(void* sslctx, struct config_strlist* tls_ses
}
-int tls_session_ticket_key_cb(void *ATTR_UNUSED(sslctx), unsigned char* key_name, unsigned char* iv, void *evp_sctx, void *hmac_ctx, int enc)
+#ifdef HAVE_SSL
+int tls_session_ticket_key_cb(SSL *ATTR_UNUSED(sslctx), unsigned char* key_name,
+ unsigned char* iv, EVP_CIPHER_CTX *evp_sctx,
+#ifdef HAVE_SSL_CTX_SET_TLSEXT_TICKET_KEY_EVP_CB
+ EVP_MAC_CTX *hmac_ctx,
+#else
+ HMAC_CTX* hmac_ctx,
+#endif
+ int enc)
{
#ifdef HAVE_SSL
+# ifdef HAVE_SSL_CTX_SET_TLSEXT_TICKET_KEY_EVP_CB
+ OSSL_PARAM params[3];
+# else
const EVP_MD *digest;
+# endif
const EVP_CIPHER *cipher;
int evp_cipher_length;
+# ifndef HAVE_SSL_CTX_SET_TLSEXT_TICKET_KEY_EVP_CB
digest = EVP_sha256();
+# endif
cipher = EVP_aes_256_cbc();
evp_cipher_length = EVP_CIPHER_iv_length(cipher);
if( enc == 1 ) {
@@ -1342,7 +1472,14 @@ int tls_session_ticket_key_cb(void *ATTR_UNUSED(sslctx), unsigned char* key_name
verbose(VERB_CLIENT, "EVP_EncryptInit_ex failed");
return -1;
}
-#ifndef HMAC_INIT_EX_RETURNS_VOID
+#ifdef HAVE_SSL_CTX_SET_TLSEXT_TICKET_KEY_EVP_CB
+ params[0] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
+ ticket_keys->hmac_key, 32);
+ params[1] = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST,
+ "sha256", 0);
+ params[2] = OSSL_PARAM_construct_end();
+ EVP_MAC_set_ctx_params(hmac_ctx, params);
+#elif !defined(HMAC_INIT_EX_RETURNS_VOID)
if (HMAC_Init_ex(hmac_ctx, ticket_keys->hmac_key, 32, digest, NULL) != 1) {
verbose(VERB_CLIENT, "HMAC_Init_ex failed");
return -1;
@@ -1366,7 +1503,14 @@ int tls_session_ticket_key_cb(void *ATTR_UNUSED(sslctx), unsigned char* key_name
return 0;
}
-#ifndef HMAC_INIT_EX_RETURNS_VOID
+#ifdef HAVE_SSL_CTX_SET_TLSEXT_TICKET_KEY_EVP_CB
+ params[0] = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY,
+ key->hmac_key, 32);
+ params[1] = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST,
+ "sha256", 0);
+ params[2] = OSSL_PARAM_construct_end();
+ EVP_MAC_set_ctx_params(hmac_ctx, params);
+#elif !defined(HMAC_INIT_EX_RETURNS_VOID)
if (HMAC_Init_ex(hmac_ctx, key->hmac_key, 32, digest, NULL) != 1) {
verbose(VERB_CLIENT, "HMAC_Init_ex failed");
return -1;
@@ -1391,6 +1535,7 @@ int tls_session_ticket_key_cb(void *ATTR_UNUSED(sslctx), unsigned char* key_name
return 0;
#endif
}
+#endif /* HAVE_SSL */
void
listen_sslctx_delete_ticket_keys(void)