Added the match-tls-and-dtls-ciphers config option

That when enable, it will prevent any DTLS negotiation other than the
DTLS-PSK, and will ensure that the cipher/mac combination matches on
the TLS and DTLS connections. The cisco-client-compat config option
when disabled, it will disable the pre-draft-DTLS negotiation.
This commit is contained in:
Nikos Mavrogiannopoulos
2016-09-13 13:25:35 +02:00
parent 56e82a2f31
commit 555d2cb03e
6 changed files with 51 additions and 13 deletions

View File

@@ -263,6 +263,14 @@ tls-priorities = "NORMAL:%SERVER_PRECEDENCE:%COMPAT:-VERS-SSL3.0"
# on the main channel.
#tls-priorities = "NORMAL:%SERVER_PRECEDENCE:%COMPAT:-RSA:-VERS-SSL3.0:-ARCFOUR-128"
# That option requires the established DTLS channel to use the same
# cipher as the primary TLS channel. This cannot be combined with
# listen-clear-file since the ciphersuite information is not available
# in that configuration. Note also, that this option implies that
# cisco-client-compat is false; this protection cannot be enforced
# in the legacy/compat protocol.
#match-tls-and-dtls-ciphers = true
# The time (in seconds) that a client is allowed to stay connected prior
# to authentication
auth-timeout = 240
@@ -574,11 +582,10 @@ no-route = 192.168.5.0/255.255.255.0
# The following options are for (experimental) AnyConnect client
# compatibility.
# This option must be set to true to support legacy CISCO clients.
# A side effect of this option is that it will no longer be required
# for clients to present their certificate on every connection.
# That is they may resume a cookie without presenting a certificate
# (when certificate authentication is used).
# This option will enable the pre-draft-DTLS version of DTLS, and
# will not require clients to present their certificate on every TLS
# connection. It must be set to true to support legacy CISCO clients
# and openconnect clients < 7.08.
cisco-client-compat = true
# Client profile xml. A sample file exists in doc/profile.xml.

View File

@@ -185,6 +185,7 @@ static struct cfg_options available_options[] = {
{ .name = "config-per-group", .type = OPTION_STRING, .mandatory = 0 },
{ .name = "default-user-config", .type = OPTION_STRING, .mandatory = 0 },
{ .name = "default-group-config", .type = OPTION_STRING, .mandatory = 0 },
{ .name = "match-tls-and-dtls-ciphers", .type = OPTION_BOOLEAN, .mandatory = 0 },
};
static const tOptionValue* get_option(const char* name, unsigned * mand)
@@ -815,6 +816,7 @@ size_t urlfw_size = 0;
}
READ_STRING("banner", config->banner);
READ_TF("cisco-client-compat", config->cisco_client_compat, 0);
READ_TF("always-require-cert", force_cert_auth, 1);
if (force_cert_auth == 0) {
@@ -822,6 +824,14 @@ size_t urlfw_size = 0;
config->cisco_client_compat = 1;
}
READ_TF("match-tls-and-dtls-ciphers", config->match_dtls_and_tls, 0);
if (config->match_dtls_and_tls) {
if (config->cisco_client_compat) {
fprintf(stderr, "note that 'match-tls-and-dtls-ciphers' cannot be applied when 'cisco-client-compat' is on; disabling\n");
}
config->cisco_client_compat = 0;
}
READ_TF("compression", config->enable_compression, 0);
READ_NUMERIC("no-compress-limit", config->no_compress_limit);
if (config->no_compress_limit == 0)

View File

@@ -361,6 +361,14 @@ tls-priorities = "NORMAL:%SERVER_PRECEDENCE:%COMPAT:-VERS-SSL3.0"
# on the main channel.
#tls-priorities = "NORMAL:%SERVER_PRECEDENCE:%COMPAT:-RSA:-VERS-SSL3.0:-ARCFOUR-128"
# That option requires the established DTLS channel to use the same
# cipher as the primary TLS channel. This cannot be combined with
# listen-clear-file since the ciphersuite information is not available
# in that configuration. Note also, that this option implies that
# cisco-client-compat is false; this protection cannot be enforced
# in the legacy/compat protocol.
#match-tls-and-dtls-ciphers = true
# The time (in seconds) that a client is allowed to stay connected prior
# to authentication
auth-timeout = 240
@@ -696,11 +704,10 @@ no-route = 192.168.5.0/255.255.255.0
# The following options are for (experimental) AnyConnect client
# compatibility.
# This option must be set to true to support legacy CISCO clients.
# A side effect of this option is that it will no longer be required
# for clients to present their certificate on every connection.
# That is they may resume a cookie without presenting a certificate
# (when certificate authentication is used).
# This option will enable the pre-draft-DTLS version of DTLS, and
# will not require clients to present their certificate on every TLS
# connection. It must be set to true to support legacy CISCO clients
# and openconnect clients < 7.08.
cisco-client-compat = true
# Client profile xml. A sample file exists in doc/profile.xml.

View File

@@ -346,6 +346,10 @@ struct cfg_st {
unsigned ban_points_connect;
unsigned ban_points_kkdcp;
/* when using the new PSK DTLS negotiation make sure that
* the negotiated DTLS cipher/mac matches the TLS cipher/mac. */
unsigned match_dtls_and_tls;
unsigned isolate; /* whether seccomp should be enabled or not */
unsigned auth_timeout; /* timeout of HTTP auth */

View File

@@ -199,7 +199,7 @@ void header_value_check(struct worker_st *ws, struct http_req_st *req)
switch (req->next_header) {
case HEADER_MASTER_SECRET:
if (req->use_psk) /* ignored */
if (req->use_psk || !ws->config->cisco_client_compat) /* ignored */
break;
if (value_length < TLS_MASTER_SIZE * 2) {

View File

@@ -211,13 +211,18 @@ static int setup_dtls_psk_keys(gnutls_session_t session, struct worker_st *ws)
gnutls_mac_algorithm_t mac;
gnutls_cipher_algorithm_t cipher;
if (ws->session) {
if (ws->session && ws->config->match_dtls_and_tls) {
cipher = gnutls_cipher_get(ws->session);
mac = gnutls_mac_get(ws->session);
snprintf(prio_string, sizeof(prio_string), "%s:-VERS-ALL:-CIPHER-ALL:-MAC-ALL:-KX-ALL:+PSK:+VERS-DTLS-ALL:+%s:+%s",
ws->config->priorities, gnutls_mac_get_name(mac), gnutls_cipher_get_name(cipher));
} else {
if (ws->config->match_dtls_and_tls) {
oclog(ws, LOG_ERR, "cannot determine ciphersuite from CSTP channel (unset match-tls-and-dtls-ciphers)");
return -1;
}
/* if we haven't an associated session, enable all ciphers we would have enabled
* otherwise for TLS. */
snprintf(prio_string, sizeof(prio_string), "%s:-VERS-ALL:-KX-ALL:+PSK:+VERS-DTLS-ALL",
@@ -327,6 +332,11 @@ static int setup_dtls_connection(struct worker_st *ws)
oclog(ws, LOG_INFO, "setting up DTLS-PSK connection");
ret = setup_dtls_psk_keys(session, ws);
} else {
if (!ws->config->cisco_client_compat) {
oclog(ws, LOG_INFO, "CISCO client compatibility is disabled; will not setup a legacy DTLS session");
ret = -1;
goto fail;
}
oclog(ws, LOG_INFO, "setting up DTLS-0.9 connection");
ret = setup_dtls0_9_keys(session, ws);
}
@@ -1958,7 +1968,7 @@ static int connect_handler(worker_st * ws)
ws->user_config->keepalive);
SEND_ERR(ret);
if (ws->req.use_psk) {
if (ws->req.use_psk || !ws->config->cisco_client_compat) {
oclog(ws, LOG_INFO, "DTLS ciphersuite: PSK");
ret =
cstp_printf(ws, "X-DTLS-CipherSuite: PSK\r\n");