summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/alert.c6
-rw-r--r--lib/errors.c2
-rw-r--r--lib/ext/key_share.c1
-rw-r--r--lib/gnutls_int.h7
-rw-r--r--lib/handshake.c29
-rw-r--r--lib/includes/gnutls/gnutls.h.in9
-rw-r--r--tests/suite/tls-fuzzer/gnutls-nocert-tls13.json31
-rw-r--r--tests/suite/tls-fuzzer/gnutls-nocert.json43
-rwxr-xr-xtests/suite/tls-fuzzer/tls-fuzzer-nocert-tls13.sh2
m---------tests/suite/tls-fuzzer/tlsfuzzer0
m---------tests/suite/tls-fuzzer/tlslite-ng0
11 files changed, 115 insertions, 15 deletions
diff --git a/lib/alert.c b/lib/alert.c
index 9b10123345..b9aa7bd9ba 100644
--- a/lib/alert.c
+++ b/lib/alert.c
@@ -79,6 +79,8 @@ static const gnutls_alert_entry sup_alerts[] = {
N_("The server name sent was not recognized")),
ALERT_ENTRY(GNUTLS_A_UNKNOWN_PSK_IDENTITY,
N_("The SRP/PSK username is missing or not known")),
+ ALERT_ENTRY(GNUTLS_A_MISSING_EXTENSION,
+ N_("An extension was expected but was not seen")),
ALERT_ENTRY(GNUTLS_A_NO_APPLICATION_PROTOCOL,
N_
("No supported application protocol could be negotiated")),
@@ -262,6 +264,10 @@ int gnutls_error_to_alert(int err, int *level)
ret = GNUTLS_A_UNSUPPORTED_EXTENSION;
_level = GNUTLS_AL_FATAL;
break;
+ case GNUTLS_E_MISSING_EXTENSION:
+ ret = GNUTLS_A_MISSING_EXTENSION;
+ _level = GNUTLS_AL_FATAL;
+ break;
case GNUTLS_E_USER_ERROR:
ret = GNUTLS_A_USER_CANCELED;
_level = GNUTLS_AL_FATAL;
diff --git a/lib/errors.c b/lib/errors.c
index fb6b54b4b0..e579f46852 100644
--- a/lib/errors.c
+++ b/lib/errors.c
@@ -81,6 +81,8 @@ static const gnutls_error_entry error_entries[] = {
GNUTLS_E_INAPPROPRIATE_FALLBACK),
ERROR_ENTRY(N_("An illegal TLS extension was received."),
GNUTLS_E_RECEIVED_ILLEGAL_EXTENSION),
+ ERROR_ENTRY(N_("An required TLS extension was received."),
+ GNUTLS_E_MISSING_EXTENSION),
ERROR_ENTRY(N_("A TLS fatal alert has been received."),
GNUTLS_E_FATAL_ALERT_RECEIVED),
ERROR_ENTRY(N_("An unexpected TLS packet was received."),
diff --git a/lib/ext/key_share.c b/lib/ext/key_share.c
index c5b104f9ac..6a9e6513a9 100644
--- a/lib/ext/key_share.c
+++ b/lib/ext/key_share.c
@@ -575,6 +575,7 @@ key_share_recv_params(gnutls_session_t session,
return gnutls_assert_val(GNUTLS_E_NO_COMMON_KEY_SHARE);
}
+ session->internals.hsk_flags |= HSK_KEY_SHARE_RECEIVED;
} else { /* Client */
ver = get_version(session);
if (unlikely(ver == NULL || ver->key_shares == 0))
diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h
index 3fb4ccb80b..f32eba181d 100644
--- a/lib/gnutls_int.h
+++ b/lib/gnutls_int.h
@@ -1332,9 +1332,12 @@ typedef struct {
#define HSK_PSK_KE_MODE_DHE_PSK (1<<14) /* server: whether PSK with DH is selected
* client: whether PSK with DH is allowed
*/
-#define HSK_PSK_SELECTED (1<<15)
+#define HSK_PSK_SELECTED (1<<15) /* server: whether PSK was selected, either for resumption or not;
+ * on resumption session->internals.resumed will be set as well.
+ * client: the same */
#define HSK_KEY_SHARE_SENT (1<<16) /* server: key share was sent to client */
-#define HSK_KEY_SHARE_RECEIVED (1<<17) /* client: key share was received */
+#define HSK_KEY_SHARE_RECEIVED (1<<17) /* client: key share was received
+ * server: key share was received and accepted */
#define HSK_TLS13_TICKET_SENT (1<<18) /* client: sent a ticket under TLS1.3;
* server: a ticket was sent to client.
*/
diff --git a/lib/handshake.c b/lib/handshake.c
index 7db134a638..841c88385d 100644
--- a/lib/handshake.c
+++ b/lib/handshake.c
@@ -539,23 +539,40 @@ _gnutls_user_hello_func(gnutls_session_t session,
return sret;
}
+/* Associates the right credential types for the session, and
+ * performs sanity checks. */
static int set_auth_types(gnutls_session_t session)
{
const version_entry_st *ver = get_version(session);
gnutls_kx_algorithm_t kx;
- kx = session->security_parameters.cs->kx_algorithm;
- if (kx == 0 && ver->tls13_sem) {
- /* if we are resuming then the KX seen doesn't match the original */
+ /* sanity check:
+ * we see TLS1.3 negotiated but no key share was sent */
+ if (ver->tls13_sem) {
+ if (unlikely(!(session->internals.hsk_flags & HSK_PSK_KE_MODE_PSK) &&
+ !(session->internals.hsk_flags & HSK_KEY_SHARE_RECEIVED))) {
+ return gnutls_assert_val(GNUTLS_E_MISSING_EXTENSION);
+ }
+
+ /* Under TLS1.3 this returns a KX which matches the negotiated
+ * groups from the key shares; if we are resuming then the KX seen
+ * here doesn't match the original session. */
if (session->internals.resumed == RESUME_FALSE)
kx = gnutls_kx_get(session);
+ else
+ kx = GNUTLS_KX_UNKNOWN;
+ } else {
+ /* TLS1.2 or earlier, kx is associated with ciphersuite */
+ kx = session->security_parameters.cs->kx_algorithm;
}
- if (kx) {
+ if (kx != GNUTLS_KX_UNKNOWN) {
session->security_parameters.server_auth_type = _gnutls_map_kx_get_cred(kx, 1);
session->security_parameters.client_auth_type = _gnutls_map_kx_get_cred(kx, 0);
- } else if (session->internals.resumed == RESUME_FALSE) {
- return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
+ } else if (unlikely(session->internals.resumed == RESUME_FALSE)) {
+ /* Here we can only arrive if something we received
+ * prevented the session from completing. */
+ return gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER);
}
return 0;
diff --git a/lib/includes/gnutls/gnutls.h.in b/lib/includes/gnutls/gnutls.h.in
index 01cf9a880e..b4903bb97c 100644
--- a/lib/includes/gnutls/gnutls.h.in
+++ b/lib/includes/gnutls/gnutls.h.in
@@ -498,14 +498,15 @@ typedef enum {
* @GNUTLS_A_EXPORT_RESTRICTION: Export restriction.
* @GNUTLS_A_PROTOCOL_VERSION: Error in protocol version.
* @GNUTLS_A_INSUFFICIENT_SECURITY: Insufficient security.
- * @GNUTLS_A_USER_CANCELED: User canceled.
* @GNUTLS_A_INTERNAL_ERROR: Internal error.
* @GNUTLS_A_INAPPROPRIATE_FALLBACK: Inappropriate fallback,
+ * @GNUTLS_A_USER_CANCELED: User canceled.
* @GNUTLS_A_NO_RENEGOTIATION: No renegotiation is allowed.
- * @GNUTLS_A_CERTIFICATE_UNOBTAINABLE: Could not retrieve the
- * specified certificate.
+ * @GNUTLS_A_MISSING_EXTENSION: An extension was expected but was not seen
* @GNUTLS_A_UNSUPPORTED_EXTENSION: An unsupported extension was
* sent.
+ * @GNUTLS_A_CERTIFICATE_UNOBTAINABLE: Could not retrieve the
+ * specified certificate.
* @GNUTLS_A_UNRECOGNIZED_NAME: The server name sent was not
* recognized.
* @GNUTLS_A_UNKNOWN_PSK_IDENTITY: The SRP/PSK username is missing
@@ -541,6 +542,7 @@ typedef enum {
GNUTLS_A_INAPPROPRIATE_FALLBACK = 86,
GNUTLS_A_USER_CANCELED = 90,
GNUTLS_A_NO_RENEGOTIATION = 100,
+ GNUTLS_A_MISSING_EXTENSION = 109,
GNUTLS_A_UNSUPPORTED_EXTENSION = 110,
GNUTLS_A_CERTIFICATE_UNOBTAINABLE = 111,
GNUTLS_A_UNRECOGNIZED_NAME = 112,
@@ -3230,6 +3232,7 @@ void gnutls_fips140_set_mode(gnutls_fips_mode_t mode, unsigned flags);
#define GNUTLS_E_REAUTH_REQUEST -424
#define GNUTLS_E_TOO_MANY_MATCHES -425
#define GNUTLS_E_CRL_VERIFICATION_ERROR -426
+#define GNUTLS_E_MISSING_EXTENSION -427
#define GNUTLS_E_UNIMPLEMENTED_FEATURE -1250
diff --git a/tests/suite/tls-fuzzer/gnutls-nocert-tls13.json b/tests/suite/tls-fuzzer/gnutls-nocert-tls13.json
index 7b01c25ae8..d0d142e7a2 100644
--- a/tests/suite/tls-fuzzer/gnutls-nocert-tls13.json
+++ b/tests/suite/tls-fuzzer/gnutls-nocert-tls13.json
@@ -14,10 +14,26 @@
"tests" : [
{"name" : "test-tls13-0rtt-garbage.py",
"arguments": ["-p", "@PORT@"]},
+ {"name" : "test-tls13-crfg-curves.py",
+ "comment": "We do not support x448",
+ "arguments": ["-p", "@PORT@",
+ "-e", "empty x448 key share",
+ "-e", "sanity x448 with compression ansiX962_compressed_char2",
+ "-e", "sanity x448 with compression ansiX962_compressed_prime",
+ "-e", "sanity x448 with compression uncompressed",
+ "-e", "too big x448 key share",
+ "-e", "too small x448 key share",
+ "-e", "x448 key share of \"1\"",
+ "-e", "all zero x448 key share"]},
{"name" : "test-tls13-conversation.py",
"arguments": ["-p", "@PORT@"]},
{"name" : "test-tls13-count-tickets.py",
"arguments": ["-p", "@PORT@", "-t", "1"]},
+ {"name" : "test-tls13-dhe-shared-secret-padding.py",
+ "comment": "We do not support x448",
+ "arguments": ["-p", "@PORT@",
+ "-e", "TLS 1.3 with x448",
+ "-n", "5"]},
{"name" : "test-tls13-empty-alert.py",
"arguments": ["-p", "@PORT@"]},
{"name" : "test-tls13-ffdhe-sanity.py",
@@ -29,6 +45,10 @@
"-e", "padding - cipher TLS_AES_256_GCM_SHA384, pad_byte 0, pad_left 0, pad_right 16777167"]},
{"name" : "test-tls13-hrr.py",
"arguments": ["-p", "@PORT@"]},
+ {"name" : "test-tls13-invalid-ciphers.py",
+ "arguments": ["-p", "@PORT@"]},
+ {"name" : "test-tls13-keyshare-omitted.py",
+ "arguments": ["-p", "@PORT@"]},
{"name" : "test-tls13-legacy-version.py",
"arguments": ["-p", "@PORT@"]},
{"name" : "test-tls13-nociphers.py",
@@ -43,8 +63,17 @@
"arguments": ["-p", "@PORT@", "-b"]},
{"name" : "test-tls13-session-resumption.py",
"arguments": ["-p", "@PORT@"]},
+ {"name" : "test-tls13-serverhello-random.py",
+ "arguments": ["-p", "@PORT@",
+ "-e", "TLS 1.3 with x448"]},
{"name" : "test-tls13-signature-algorithms.py",
- "arguments": ["-p", "@PORT@"]},
+ "comment" : "gnutls doesn't handle well duplicated signature algorithms; this is not an issue in practice",
+ "arguments": ["-p", "@PORT@",
+ "-e", "213 invalid schemes",
+ "-e", "2353 invalid schemes",
+ "-e", "8130 invalid schemes",
+ "-e", "23752 invalid schemes",
+ "-e", "32715 invalid schemes"]},
{"name" : "test-tls13-unrecognised-groups.py",
"arguments": ["-p", "@PORT@"]},
{"name" : "test-tls13-version-negotiation.py",
diff --git a/tests/suite/tls-fuzzer/gnutls-nocert.json b/tests/suite/tls-fuzzer/gnutls-nocert.json
index 6ddb6ebbe0..6e2a2ea47c 100644
--- a/tests/suite/tls-fuzzer/gnutls-nocert.json
+++ b/tests/suite/tls-fuzzer/gnutls-nocert.json
@@ -96,6 +96,21 @@
"-e", "Check if DHE preferred"]},
{"name" : "test-cve-2016-2107.py",
"arguments" : ["-p", "@PORT@"] },
+ {"name" : "test-dhe-key-share-random.py",
+ "comment": "This test assumes that record splitting is performed under SSLv3 and TLS1.0",
+ "arguments" : ["-p", "@PORT@",
+ "-e", "Protocol (3, 1)",
+ "-e", "Protocol (3, 1) in SSLv2 compatible ClientHello",
+ "-e", "Protocol (3, 0)",
+ "-e", "Protocol (3, 0) in SSLv2 compatible ClientHello"]},
+ {"name" : "test-dhe-no-shared-secret-padding.py",
+ "comment": "This test assumes that record splitting is performed under SSLv3 and TLS1.0",
+ "arguments" : ["-p", "@PORT@",
+ "-e", "Protocol (3, 1)",
+ "-e", "Protocol (3, 1) in SSLv2 compatible ClientHello",
+ "-e", "Protocol (3, 0)",
+ "-e", "Protocol (3, 0) in SSLv2 compatible ClientHello",
+ "-n", "4"]},
{"name" : "test-dhe-rsa-key-exchange.py",
"arguments" : ["-p", "@PORT@"] },
{"name" : "test-dhe-rsa-key-exchange-signatures.py",
@@ -111,10 +126,24 @@
"arguments" : ["-p", "@PORT@"] },
{"name" : "test-early-application-data.py",
"arguments" : ["-p", "@PORT@"] },
+ {"name" : "test-ecdhe-padded-shared-secret.py",
+ "comment": "This test assumes that record splitting is performed under SSLv3 and TLS1.0; we don't support x448",
+ "arguments" : ["-p", "@PORT@",
+ "-e", "Protocol (3, 0) in SSLv2 compatible ClientHello",
+ "-e", "Protocol (3, 1) in SSLv2 compatible ClientHello",
+ "-e", "Protocol (3, 2) with x448 group",
+ "-n", "4"]},
{"name" : "test-ecdhe-rsa-key-exchange.py",
"arguments" : ["-p", "@PORT@"] },
{"name" : "test-ecdhe-rsa-key-exchange-with-bad-messages.py",
"arguments" : ["-p", "@PORT@"] },
+ {"name" : "test-ecdhe-rsa-key-share-random.py",
+ "comment": "This test assumes that record splitting is performed under SSLv3 and TLS1.0; we don't support x448",
+ "arguments" : ["-p", "@PORT@",
+ "-e", "Protocol (3, 0) in SSLv2 compatible ClientHello",
+ "-e", "Protocol (3, 1) in SSLv2 compatible ClientHello",
+ "-e", "Protocol (3, 2) with x448 group",
+ "-n", "4"]},
{"name" : "test-empty-extensions.py",
"arguments" : ["-p", "@PORT@"] },
{"name" : "test-export-ciphers-rejected.py",
@@ -203,11 +232,23 @@
"-e", "medium, maximum fragmentation: 1 fragment - 1024B extension"]},
{"name" : "test-sessionID-resumption.py",
"arguments" : ["-p", "@PORT@"] },
+ {"name" : "test-serverhello-random.py",
+ "comment": "This test assumes that record splitting is performed under SSLv3 and TLS1.0; we don't support x448",
+ "arguments" : ["-p", "@PORT@",
+ "-e", "Protocol (3, 0) in SSLv2 compatible ClientHello",
+ "-e", "Protocol (3, 1) in SSLv2 compatible ClientHello",
+ "-e", "Protocol (3, 2) with x448 group",
+ "-n", "4"]},
{"name" : "test-sig-algs.py",
"arguments" : ["-p", "@PORT@"] },
{"name" : "test-signature-algorithms.py",
- "comment" : "gnutls doesn't tolerate that much",
+ "comment" : "gnutls doesn't handle well duplicated sign algorithms; this is not an issue in practice",
"arguments" : ["-p", "@PORT@",
+ "-e", "duplicated 202 non-rsa schemes",
+ "-e", "duplicated 2342 non-rsa schemes",
+ "-e", "duplicated 8119 non-rsa schemes",
+ "-e", "duplicated 23741 non-rsa schemes",
+ "-e", "duplicated 32748 non-rsa schemes",
"-e", "tolerance max (32764) number of methods"]
},
{"name" : "test-sslv2-connection.py",
diff --git a/tests/suite/tls-fuzzer/tls-fuzzer-nocert-tls13.sh b/tests/suite/tls-fuzzer/tls-fuzzer-nocert-tls13.sh
index aab37db5e2..1b9b0f1765 100755
--- a/tests/suite/tls-fuzzer/tls-fuzzer-nocert-tls13.sh
+++ b/tests/suite/tls-fuzzer/tls-fuzzer-nocert-tls13.sh
@@ -24,8 +24,6 @@ tls_fuzzer_prepare() {
PRIORITY="NORMAL:-VERS-ALL:+VERS-TLS1.3:+VERS-TLS1.2:+VERS-TLS1.1"
sed -e "s|@SERVER@|$SERV|g" -e "s/@PORT@/$PORT/g" -e "s/@PRIORITY@/$PRIORITY/g" ../gnutls-nocert-tls13.json >${TMPFILE}
-
-sed -i 's/(127, 28)/(3, 4)/g' ./tlslite/constants.py
}
. "${srcdir}/tls-fuzzer/tls-fuzzer-common.sh"
diff --git a/tests/suite/tls-fuzzer/tlsfuzzer b/tests/suite/tls-fuzzer/tlsfuzzer
-Subproject 01f44ce66c54193176dac7c9e87afd248c58c08
+Subproject 64f4a6e94c6cc1357fdb9fb36b8467456509df6
diff --git a/tests/suite/tls-fuzzer/tlslite-ng b/tests/suite/tls-fuzzer/tlslite-ng
-Subproject bad2b98b2c382674f71aff617a9274e2a095951
+Subproject af466651a7795ac5a6cf54932d496ca8e79b49b