GnuTLS: Suite B validation
This allows OpenSSL-style configuration of Suite B parameters to be used in the wpa_supplicant network profile. 128-bit and 192-bit level requirements for ECDHE-ECDSA cases are supported. RSA >=3K case is enforced using GnuTLS %PROFILE_HIGH special priority string keyword. Signed-off-by: Jouni Malinen <j@w1.fi>
This commit is contained in:
parent
dd227e67ab
commit
c36d822418
1 changed files with 55 additions and 11 deletions
|
@ -346,6 +346,9 @@ int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn,
|
|||
const struct tls_connection_params *params)
|
||||
{
|
||||
int ret;
|
||||
const char *err;
|
||||
char prio_buf[100];
|
||||
const char *prio = NULL;
|
||||
|
||||
if (conn == NULL || params == NULL)
|
||||
return -1;
|
||||
|
@ -400,16 +403,46 @@ int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn,
|
|||
if (params->flags & (TLS_CONN_DISABLE_TLSv1_0 |
|
||||
TLS_CONN_DISABLE_TLSv1_1 |
|
||||
TLS_CONN_DISABLE_TLSv1_2)) {
|
||||
const char *err;
|
||||
char prio[100];
|
||||
|
||||
os_snprintf(prio, sizeof(prio), "NORMAL:-VERS-SSL3.0%s%s%s",
|
||||
os_snprintf(prio_buf, sizeof(prio_buf),
|
||||
"NORMAL:-VERS-SSL3.0%s%s%s",
|
||||
params->flags & TLS_CONN_DISABLE_TLSv1_0 ?
|
||||
":-VERS-TLS1.0" : "",
|
||||
params->flags & TLS_CONN_DISABLE_TLSv1_1 ?
|
||||
":-VERS-TLS1.1" : "",
|
||||
params->flags & TLS_CONN_DISABLE_TLSv1_2 ?
|
||||
":-VERS-TLS1.2" : "");
|
||||
prio = prio_buf;
|
||||
}
|
||||
|
||||
if (params->openssl_ciphers) {
|
||||
if (os_strcmp(params->openssl_ciphers, "SUITEB128") == 0) {
|
||||
prio = "SUITEB128";
|
||||
} else if (os_strcmp(params->openssl_ciphers,
|
||||
"SUITEB192") == 0) {
|
||||
prio = "SUITEB192";
|
||||
} else if ((params->flags & TLS_CONN_SUITEB) &&
|
||||
os_strcmp(params->openssl_ciphers,
|
||||
"ECDHE-RSA-AES256-GCM-SHA384") == 0) {
|
||||
prio = "NONE:+VERS-TLS1.2:+AEAD:+ECDHE-RSA:+AES-256-GCM:+SIGN-RSA-SHA384:+CURVE-SECP384R1:+COMP-NULL";
|
||||
} else if (os_strcmp(params->openssl_ciphers,
|
||||
"ECDHE-RSA-AES256-GCM-SHA384") == 0) {
|
||||
prio = "NONE:+VERS-TLS1.2:+AEAD:+ECDHE-RSA:+AES-256-GCM:+SIGN-RSA-SHA384:+CURVE-SECP384R1:+COMP-NULL";
|
||||
} else if (os_strcmp(params->openssl_ciphers,
|
||||
"DHE-RSA-AES256-GCM-SHA384") == 0) {
|
||||
prio = "NONE:+VERS-TLS1.2:+AEAD:+DHE-RSA:+AES-256-GCM:+SIGN-RSA-SHA384:+CURVE-SECP384R1:+COMP-NULL:%PROFILE_HIGH";
|
||||
} else if (os_strcmp(params->openssl_ciphers,
|
||||
"ECDHE-ECDSA-AES256-GCM-SHA384") == 0) {
|
||||
prio = "NONE:+VERS-TLS1.2:+AEAD:+ECDHE-ECDSA:+AES-256-GCM:+SIGN-RSA-SHA384:+CURVE-SECP384R1:+COMP-NULL";
|
||||
} else {
|
||||
wpa_printf(MSG_INFO,
|
||||
"GnuTLS: openssl_ciphers not supported");
|
||||
return -1;
|
||||
}
|
||||
} else if (params->flags & TLS_CONN_SUITEB) {
|
||||
prio = "NONE:+VERS-TLS1.2:+AEAD:+ECDHE-ECDSA:+ECDHE-RSA:+DHE-RSA:+AES-256-GCM:+SIGN-RSA-SHA384:+CURVE-SECP384R1:+COMP-NULL:%PROFILE_HIGH";
|
||||
}
|
||||
|
||||
if (prio) {
|
||||
wpa_printf(MSG_DEBUG, "GnuTLS: Set priority string: %s", prio);
|
||||
ret = gnutls_priority_set_direct(conn->session, prio, &err);
|
||||
if (ret < 0) {
|
||||
|
@ -420,11 +453,6 @@ int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn,
|
|||
}
|
||||
}
|
||||
|
||||
if (params->openssl_ciphers) {
|
||||
wpa_printf(MSG_INFO, "GnuTLS: openssl_ciphers not supported");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* TODO: gnutls_certificate_set_verify_flags(xcred, flags);
|
||||
* to force peer validation(?) */
|
||||
|
||||
|
@ -1375,6 +1403,7 @@ struct wpabuf * tls_connection_handshake(void *tls_ctx,
|
|||
ret = gnutls_handshake(conn->session);
|
||||
if (ret < 0) {
|
||||
gnutls_alert_description_t alert;
|
||||
union tls_event_data ev;
|
||||
|
||||
switch (ret) {
|
||||
case GNUTLS_E_AGAIN:
|
||||
|
@ -1385,14 +1414,29 @@ struct wpabuf * tls_connection_handshake(void *tls_ctx,
|
|||
conn->push_buf = wpabuf_alloc(0);
|
||||
}
|
||||
break;
|
||||
case GNUTLS_E_DH_PRIME_UNACCEPTABLE:
|
||||
wpa_printf(MSG_DEBUG, "GnuTLS: Unacceptable DH prime");
|
||||
if (conn->global->event_cb) {
|
||||
os_memset(&ev, 0, sizeof(ev));
|
||||
ev.alert.is_local = 1;
|
||||
ev.alert.type = "fatal";
|
||||
ev.alert.description = "insufficient security";
|
||||
conn->global->event_cb(conn->global->cb_ctx,
|
||||
TLS_ALERT, &ev);
|
||||
}
|
||||
/*
|
||||
* Could send a TLS Alert to the server, but for now,
|
||||
* simply terminate handshake.
|
||||
*/
|
||||
conn->failed++;
|
||||
conn->write_alerts++;
|
||||
break;
|
||||
case GNUTLS_E_FATAL_ALERT_RECEIVED:
|
||||
alert = gnutls_alert_get(conn->session);
|
||||
wpa_printf(MSG_DEBUG, "%s - received fatal '%s' alert",
|
||||
__func__, gnutls_alert_get_name(alert));
|
||||
conn->read_alerts++;
|
||||
if (conn->global->event_cb != NULL) {
|
||||
union tls_event_data ev;
|
||||
|
||||
os_memset(&ev, 0, sizeof(ev));
|
||||
ev.alert.is_local = 0;
|
||||
ev.alert.type = gnutls_alert_get_name(alert);
|
||||
|
|
Loading…
Reference in a new issue