1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-20 14:39:02 +00:00

Nsock: Use separate SSL_CTX for SSL vs DTLS

This commit is contained in:
dmiller
2022-08-25 16:29:49 +00:00
parent 49005f99a2
commit d43df98ab1
5 changed files with 33 additions and 15 deletions

View File

@@ -473,11 +473,14 @@ nsock_event_id nsock_connect_ssl(nsock_pool nsp, nsock_iod nsiod, nsock_ev_handl
struct npool *ms = (struct npool *)nsp; struct npool *ms = (struct npool *)nsp;
struct nevent *nse; struct nevent *nse;
if (!ms->sslctx) if (proto == IPPROTO_UDP)
{ {
if (proto == IPPROTO_UDP) if (!ms->dtlsctx)
nsock_pool_dtls_init(ms, 0); nsock_pool_dtls_init(ms, 0);
else }
else
{
if (!ms->sslctx)
nsock_pool_ssl_init(ms, 0); nsock_pool_ssl_init(ms, 0);
} }
@@ -523,6 +526,8 @@ nsock_event_id nsock_reconnect_ssl(nsock_pool nsp, nsock_iod nsiod, nsock_ev_han
struct niod *nsi = (struct niod *)nsiod; struct niod *nsi = (struct niod *)nsiod;
struct npool *ms = (struct npool *)nsp; struct npool *ms = (struct npool *)nsp;
struct nevent *nse; struct nevent *nse;
/* nsock_reconnect_ssl not supported for DTLS (yet?) */
assert(nsi->lastproto != IPPROTO_UDP);
if (!ms->sslctx) if (!ms->sslctx)
nsock_pool_ssl_init(ms, 0); nsock_pool_ssl_init(ms, 0);

View File

@@ -340,6 +340,7 @@ void handle_connect_result(struct npool *ms, struct nevent *nse, enum nse_status
int sslconnect_inprogress = nse->type == NSE_TYPE_CONNECT_SSL && nse->iod && int sslconnect_inprogress = nse->type == NSE_TYPE_CONNECT_SSL && nse->iod &&
(nse->sslinfo.ssl_desire == SSL_ERROR_WANT_READ || (nse->sslinfo.ssl_desire == SSL_ERROR_WANT_READ ||
nse->sslinfo.ssl_desire == SSL_ERROR_WANT_WRITE); nse->sslinfo.ssl_desire == SSL_ERROR_WANT_WRITE);
SSL_CTX *sslctx = NULL;
#else #else
int sslconnect_inprogress = 0; int sslconnect_inprogress = 0;
#endif #endif
@@ -366,11 +367,12 @@ void handle_connect_result(struct npool *ms, struct nevent *nse, enum nse_status
if (nse->type == NSE_TYPE_CONNECT_SSL && if (nse->type == NSE_TYPE_CONNECT_SSL &&
nse->status == NSE_STATUS_SUCCESS) { nse->status == NSE_STATUS_SUCCESS) {
#if HAVE_OPENSSL #if HAVE_OPENSSL
assert(ms->sslctx != NULL); sslctx = iod->lastproto == IPPROTO_UDP ? ms->dtlsctx : ms->sslctx;
assert(sslctx != NULL);
/* Reuse iod->ssl if present. If set, this is the second try at connection /* Reuse iod->ssl if present. If set, this is the second try at connection
without the SSL_OP_NO_SSLv2 option set. */ without the SSL_OP_NO_SSLv2 option set. */
if (iod->ssl == NULL) { if (iod->ssl == NULL) {
iod->ssl = SSL_new(ms->sslctx); iod->ssl = SSL_new(sslctx);
if (!iod->ssl) if (!iod->ssl)
fatal("SSL_new failed: %s", ERR_error_string(ERR_get_error(), NULL)); fatal("SSL_new failed: %s", ERR_error_string(ERR_get_error(), NULL));
} }

View File

@@ -202,6 +202,9 @@ struct npool {
#if HAVE_OPENSSL #if HAVE_OPENSSL
/* The SSL Context (options and such) */ /* The SSL Context (options and such) */
SSL_CTX *sslctx; SSL_CTX *sslctx;
#ifdef HAVE_DTLS_CLIENT_METHOD
SSL_CTX *dtlsctx;
#endif
#endif #endif
/* Optional proxy chain (NULL is not set). Can only be set once per NSP (using /* Optional proxy chain (NULL is not set). Can only be set once per NSP (using

View File

@@ -181,6 +181,7 @@ nsock_pool nsock_pool_new(void *userdata) {
#if HAVE_OPENSSL #if HAVE_OPENSSL
nsp->sslctx = NULL; nsp->sslctx = NULL;
nsp->dtlsctx = NULL;
#endif #endif
nsp->px_chain = NULL; nsp->px_chain = NULL;

View File

@@ -98,8 +98,15 @@ void nsp_ssl_cleanup(struct npool *nsp)
{ {
if (nsp->sslctx != NULL) if (nsp->sslctx != NULL)
SSL_CTX_free(nsp->sslctx); SSL_CTX_free(nsp->sslctx);
#ifdef HAVE_DTLS_CLIENT_METHOD
if (nsp->dtlsctx != NULL)
SSL_CTX_free(nsp->dtlsctx);
#endif
} }
nsp->sslctx = NULL; nsp->sslctx = NULL;
#ifdef HAVE_DTLS_CLIENT_METHOD
nsp->dtlsctx = NULL;
#endif
} }
static SSL_CTX *ssl_init_helper(const SSL_METHOD *method) { static SSL_CTX *ssl_init_helper(const SSL_METHOD *method) {
@@ -152,7 +159,7 @@ static SSL_CTX *ssl_init_common() {
* are made from it. The connections made from this context will use only secure * are made from it. The connections made from this context will use only secure
* ciphers but no server certificate verification is done. Returns the SSL_CTX * ciphers but no server certificate verification is done. Returns the SSL_CTX
* so you can set your own options. */ * so you can set your own options. */
static nsock_ssl_ctx nsock_pool_ssl_init_helper(struct npool *ms, int flags) { static nsock_ssl_ctx nsock_pool_ssl_init_helper(SSL_CTX *ctx, int flags) {
char rndbuf[128]; char rndbuf[128];
/* Get_random_bytes may or may not provide high-quality randomness. Add it to /* Get_random_bytes may or may not provide high-quality randomness. Add it to
@@ -171,17 +178,17 @@ static nsock_ssl_ctx nsock_pool_ssl_init_helper(struct npool *ms, int flags) {
/* SSL_OP_ALL sets bug-compatibility for pretty much everything. /* SSL_OP_ALL sets bug-compatibility for pretty much everything.
* SSL_OP_NO_SSLv2 disables the less-secure SSLv2 while allowing us to use the * SSL_OP_NO_SSLv2 disables the less-secure SSLv2 while allowing us to use the
* SSLv2-compatible SSLv23_client_method. */ * SSLv2-compatible SSLv23_client_method. */
SSL_CTX_set_verify(ms->sslctx, SSL_VERIFY_NONE, NULL); SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL);
SSL_CTX_clear_options(ms->sslctx, SSL_OP_NO_SSLv2); SSL_CTX_clear_options(ctx, SSL_OP_NO_SSLv2);
SSL_CTX_set_options(ms->sslctx, flags & NSOCK_SSL_MAX_SPEED ? SSL_CTX_set_options(ctx, flags & NSOCK_SSL_MAX_SPEED ?
SSL_OP_ALL : SSL_OP_ALL|SSL_OP_NO_SSLv2); SSL_OP_ALL : SSL_OP_ALL|SSL_OP_NO_SSLv2);
if (!SSL_CTX_set_cipher_list(ms->sslctx, flags & NSOCK_SSL_MAX_SPEED ? if (!SSL_CTX_set_cipher_list(ctx, flags & NSOCK_SSL_MAX_SPEED ?
CIPHERS_FAST : CIPHERS_SECURE)) CIPHERS_FAST : CIPHERS_SECURE))
fatal("Unable to set OpenSSL cipher list: %s", fatal("Unable to set OpenSSL cipher list: %s",
ERR_error_string(ERR_get_error(), NULL)); ERR_error_string(ERR_get_error(), NULL));
return ms->sslctx; return ctx;
} }
nsock_ssl_ctx nsock_pool_ssl_init(nsock_pool ms_pool, int flags) { nsock_ssl_ctx nsock_pool_ssl_init(nsock_pool ms_pool, int flags) {
@@ -189,7 +196,7 @@ nsock_ssl_ctx nsock_pool_ssl_init(nsock_pool ms_pool, int flags) {
if (ms->sslctx == NULL) if (ms->sslctx == NULL)
ms->sslctx = ssl_init_common(); ms->sslctx = ssl_init_common();
return nsock_pool_ssl_init_helper(ms, flags); return nsock_pool_ssl_init_helper(ms->sslctx, flags);
} }
#ifdef HAVE_DTLS_CLIENT_METHOD #ifdef HAVE_DTLS_CLIENT_METHOD
@@ -205,9 +212,9 @@ nsock_ssl_ctx nsock_pool_dtls_init(nsock_pool ms_pool, int flags) {
SSL_CTX *dtls_ctx = NULL; SSL_CTX *dtls_ctx = NULL;
struct npool *ms = (struct npool *)ms_pool; struct npool *ms = (struct npool *)ms_pool;
if (ms->sslctx == NULL) if (ms->dtlsctx == NULL)
ms->sslctx = dtls_init_common(); ms->dtlsctx = dtls_init_common();
dtls_ctx = (SSL_CTX *) nsock_pool_ssl_init_helper(ms, flags); dtls_ctx = (SSL_CTX *) nsock_pool_ssl_init_helper(ms->dtlsctx, flags);
/* Don't add padding or the ClientHello will fragment and not connect properly. */ /* Don't add padding or the ClientHello will fragment and not connect properly. */
SSL_CTX_clear_options(dtls_ctx, SSL_OP_TLSEXT_PADDING); SSL_CTX_clear_options(dtls_ctx, SSL_OP_TLSEXT_PADDING);