Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add: flag to set cipher suite preferences on a TLS session (backport #1020) #1029

Merged
merged 1 commit into from
Feb 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 54 additions & 15 deletions misc/network.c
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ ovas_get_tlssession_from_connection (int fd)
*/
static int
set_gnutls_protocol (gnutls_session_t session, openvas_encaps_t encaps,
const char *priority)
const char *priority, unsigned int flags)
{
const char *priorities;
const char *errloc;
Expand Down Expand Up @@ -445,6 +445,11 @@ set_gnutls_protocol (gnutls_session_t session, openvas_encaps_t encaps,
return -1;
}

/* Set extra priorities from flags.
Only for encaps == OPENVAS_ENCAPS_TLScustom. */
if (encaps == OPENVAS_ENCAPS_TLScustom && flags & INSECURE_DH_PRIME_BITS)
gnutls_dh_set_prime_bits (session, 128);

return 0;
}

Expand Down Expand Up @@ -560,10 +565,28 @@ is_ip_address (const char *str)
return inet_pton (AF_INET6, str, &(sa6.sin6_addr)) == 1;
}

/**
* @brief Open an TLS/SSL connection.
*
* @param fp File structure for a the openvas connection
* @param cert The certificate.
* @param key The key
* @param passwd The password
* @param cafile The CA file
* @param hostname Targets hostname
* @param flags Extra options which can not be set via the priority string
* Supported flags are:
* - NO_PRIORITY_FLAGS
* - INSECURE_DH_PRIME_BITS
*
* @return 1 on success. -1 on general error or timeout. -2 if DH prime bits on
* server side are lower than minimum allowed.
*
*/
static int
open_SSL_connection (openvas_connection *fp, const char *cert, const char *key,
const char *passwd, const char *cafile,
const char *hostname)
const char *hostname, unsigned int flags)
{
int ret, err, d;
time_t tictac;
Expand All @@ -584,7 +607,8 @@ open_SSL_connection (openvas_connection *fp, const char *cert, const char *key,
* OPENVAS_ENCAPS_SSLv2, so it should never end up calling
* open_SSL_connection with OPENVAS_ENCAPS_SSLv2.
*/
if (set_gnutls_protocol (fp->tls_session, fp->transport, fp->priority) < 0)
if (set_gnutls_protocol (fp->tls_session, fp->transport, fp->priority, flags)
< 0)
return -1;

if (hostname && !is_ip_address (hostname))
Expand Down Expand Up @@ -636,8 +660,17 @@ open_SSL_connection (openvas_connection *fp, const char *cert, const char *key,
if (err == 0)
return 1;

if (err != GNUTLS_E_INTERRUPTED && err != GNUTLS_E_AGAIN
&& err != GNUTLS_E_WARNING_ALERT_RECEIVED)
/* Set min number of bits for Deffie-Hellman prime
to force a connection to a legacy server. */
if (err == GNUTLS_E_DH_PRIME_UNACCEPTABLE
&& fp->transport == OPENVAS_ENCAPS_TLScustom)
{
g_message ("[%d] gnutls_handshake: %s", getpid (),
gnutls_strerror (err));
return -2;
}
else if (err != GNUTLS_E_INTERRUPTED && err != GNUTLS_E_AGAIN
&& err != GNUTLS_E_WARNING_ALERT_RECEIVED)
{
g_debug ("[%d] gnutls_handshake: %s", getpid (),
gnutls_strerror (err));
Expand Down Expand Up @@ -811,7 +844,9 @@ socket_negotiate_ssl (int fd, openvas_encaps_t transport,

fp->transport = transport;
fp->priority = NULL;
if (open_SSL_connection (fp, cert, key, passwd, cafile, hostname) <= 0)
if (open_SSL_connection (fp, cert, key, passwd, cafile, hostname,
NO_PRIORITY_FLAGS)
<= 0)
{
g_free (hostname);
g_free (cert);
Expand Down Expand Up @@ -1002,14 +1037,16 @@ socket_get_ssl_ciphersuite (int fd)
}

/* Extended version of open_stream_connection to allow passing a
priority string.
priority string and a bit flag variable for setting extra options
which can't be set via the priority string.

ABI_BREAK_NOTE: Merge this with open_stream_connection. */
int
open_stream_connection_ext (struct script_infos *args, unsigned int port,
int transport, int timeout, const char *priority)
int transport, int timeout, const char *priority,
int flags)
{
int fd;
int fd, ret;
openvas_connection *fp;
char *cert = NULL;
char *key = NULL;
Expand All @@ -1032,6 +1069,7 @@ open_stream_connection_ext (struct script_infos *args, unsigned int port,
if (timeout == -2)
timeout = TIMEOUT;

ret = -1;
switch (transport)
{
case OPENVAS_ENCAPS_IP:
Expand All @@ -1053,13 +1091,13 @@ open_stream_connection_ext (struct script_infos *args, unsigned int port,
errno = EINVAL;

g_free (hostname_aux);
return -1;
return ret;
}

if ((fd = get_connection_fd ()) < 0)
{
g_free (hostname_aux);
return -1;
return ret;
}
fp = OVAS_CONNECTION_FROM_FD (fd);

Expand All @@ -1080,7 +1118,6 @@ open_stream_connection_ext (struct script_infos *args, unsigned int port,
kb_t kb = plug_get_kb (args);
switch (transport)
{
int ret;
char buf[1024];

case OPENVAS_ENCAPS_IP:
Expand All @@ -1106,7 +1143,8 @@ open_stream_connection_ext (struct script_infos *args, unsigned int port,
if (kb_item_get_int (kb, buf) <= 0)
hostname = hostname_aux;

ret = open_SSL_connection (fp, cert, key, passwd, cafile, hostname);
ret =
open_SSL_connection (fp, cert, key, passwd, cafile, hostname, flags);
g_free (cert);
g_free (key);
g_free (passwd);
Expand All @@ -1122,15 +1160,16 @@ open_stream_connection_ext (struct script_infos *args, unsigned int port,

failed:
release_connection_fd (fd, 0);
return -1;
return ret;
}

int
open_stream_connection (struct script_infos *args, unsigned int port,
int transport, int timeout)
{
return open_stream_connection_ext (args, port, transport, timeout,
"NORMAL:+ARCFOUR-128:%COMPAT");
"NORMAL:+ARCFOUR-128:%COMPAT",
NO_PRIORITY_FLAGS);
}

/* Same as open_stream_auto_encaps but allows to force auto detection
Expand Down
7 changes: 6 additions & 1 deletion misc/network.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ typedef enum openvas_encaps
#define IS_ENCAPS_SSL(x) \
((x) >= OPENVAS_ENCAPS_SSLv23 && (x) <= OPENVAS_ENCAPS_TLScustom)

/* Define FLAGS for setting other priorities in
open_stream_connection_ext */
#define NO_PRIORITY_FLAGS 0
#define INSECURE_DH_PRIME_BITS (1 << 0) // 1

/* Plugin specific network functions */
int
open_sock_tcp (struct script_infos *, unsigned int, int);
Expand Down Expand Up @@ -84,7 +89,7 @@ open_stream_connection (struct script_infos *, unsigned int, int, int);

int
open_stream_connection_ext (struct script_infos *, unsigned int, int, int,
const char *);
const char *, int);

int
open_stream_auto_encaps_ext (struct script_infos *, unsigned int port,
Expand Down
11 changes: 10 additions & 1 deletion nasl/nasl_builtin_find_service.c
Original file line number Diff line number Diff line change
Expand Up @@ -1608,7 +1608,16 @@ plugin_do_run (struct script_infos *desc, GSList *h, int test_ssl)
trp = OPENVAS_ENCAPS_IP;
gettimeofday (&tv1, NULL);
cnx = open_stream_connection (desc, port, trp, cnx_timeout);
if (cnx < 0 && test_ssl)
if (cnx == -2 && test_ssl)
{
unsigned int flags = INSECURE_DH_PRIME_BITS;

gettimeofday (&tv1, NULL);
cnx = open_stream_connection_ext (
desc, port, trp, cnx_timeout, "NORMAL:+ARCFOUR-128:%COMPAT",
flags);
}
else if (cnx < 0 && test_ssl)
{
trp = OPENVAS_ENCAPS_IP;
gettimeofday (&tv1, NULL);
Expand Down
4 changes: 2 additions & 2 deletions nasl/nasl_socket.c
Original file line number Diff line number Diff line change
Expand Up @@ -465,8 +465,8 @@ nasl_open_sock_tcp_bufsz (lex_ctxt *lexic, int bufsz)
else if (transport == 0)
soc = open_stream_auto_encaps_ext (script_infos, port, to, 1);
else
soc =
open_stream_connection_ext (script_infos, port, transport, to, priority);
soc = open_stream_connection_ext (script_infos, port, transport, to,
priority, NO_PRIORITY_FLAGS);
if (bufsz > 0 && soc >= 0)
{
if (stream_set_buffer (soc, bufsz) < 0)
Expand Down