summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@redhat.com>2017-07-13 10:33:18 +0200
committerNikos Mavrogiannopoulos <nmav@redhat.com>2017-09-11 15:51:53 +0200
commit05581efadc4fa22139e8adbaf01ed3abae6a1157 (patch)
tree7139270dfeab7fd247614bacac1e2e03d69a4fb7 /lib
parent9e848e7bc752e785b68327805b9ebddee531c634 (diff)
downloadgnutls-05581efadc4fa22139e8adbaf01ed3abae6a1157.tar.gz
handshake: send client and server hellos according to TLS 1.3
That is, when TLS 1.3 is negotiated the compression algorithms and session ID fields are no longer sent. Signed-off-by: Nikos Mavrogiannopoulos <nmav@redhat.com>
Diffstat (limited to 'lib')
-rw-r--r--lib/algorithms/protocols.c1
-rw-r--r--lib/gnutls_int.h1
-rw-r--r--lib/handshake.c117
3 files changed, 67 insertions, 52 deletions
diff --git a/lib/algorithms/protocols.c b/lib/algorithms/protocols.c
index 9294594182..44b44d82d3 100644
--- a/lib/algorithms/protocols.c
+++ b/lib/algorithms/protocols.c
@@ -98,6 +98,7 @@ static const version_entry_st sup_versions[] = {
.extensions = 1,
.selectable_sighash = 1,
.selectable_prf = 1,
+ .compact_hello = 1,
.obsolete = 0,
.only_extension = 1,
.false_start = 0, /* doesn't make sense */
diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h
index 03f5104f5b..724516bed3 100644
--- a/lib/gnutls_int.h
+++ b/lib/gnutls_int.h
@@ -520,6 +520,7 @@ typedef struct {
/* if SSL3 is disabled this flag indicates that this protocol is a placeholder,
* otherwise it prevents this protocol from being set as record version */
bool obsolete;
+ bool compact_hello; /* The TLS 1.3 client and server hello form */
bool false_start; /* That version can be used with false start */
bool only_extension; /* negotiated only with an extension */
/*
diff --git a/lib/handshake.c b/lib/handshake.c
index 3d2fcf0ab0..c87b74917c 100644
--- a/lib/handshake.c
+++ b/lib/handshake.c
@@ -1498,8 +1498,8 @@ read_server_hello(gnutls_session_t session,
int ret = 0;
gnutls_protocol_t version;
int len = datalen;
-
- if (datalen < 38) {
+ const version_entry_st *vers;
+ if (datalen < GNUTLS_RANDOM_SIZE+2) {
gnutls_assert();
return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
}
@@ -1517,6 +1517,8 @@ read_server_hello(gnutls_session_t session,
if (_gnutls_set_current_version(session, version) < 0)
return gnutls_assert_val(GNUTLS_E_UNSUPPORTED_VERSION_PACKET);
+ vers = get_version(session);
+
pos += 2;
DECR_LEN(len, GNUTLS_RANDOM_SIZE);
@@ -1526,37 +1528,38 @@ read_server_hello(gnutls_session_t session,
pos += GNUTLS_RANDOM_SIZE;
+ if (!vers->compact_hello) {
+ /* Read session ID
+ */
+ DECR_LEN(len, 1);
+ session_id_len = data[pos++];
- /* Read session ID
- */
- DECR_LEN(len, 1);
- session_id_len = data[pos++];
-
- if (len < session_id_len || session_id_len > GNUTLS_MAX_SESSION_ID_SIZE) {
- gnutls_assert();
- return GNUTLS_E_ILLEGAL_PARAMETER;
- }
- DECR_LEN(len, session_id_len);
+ if (len < session_id_len || session_id_len > GNUTLS_MAX_SESSION_ID_SIZE) {
+ gnutls_assert();
+ return GNUTLS_E_ILLEGAL_PARAMETER;
+ }
+ DECR_LEN(len, session_id_len);
- /* check if we are resuming and set the appropriate
- * values;
- */
- if (client_check_if_resuming
- (session, &data[pos], session_id_len) == 0) {
- pos += session_id_len + 2 + 1;
- DECR_LEN(len, 2 + 1);
+ /* check if we are resuming and set the appropriate
+ * values;
+ */
+ if (client_check_if_resuming
+ (session, &data[pos], session_id_len) == 0) {
+ pos += session_id_len + 2 + 1;
+ DECR_LEN(len, 2 + 1);
- ret =
- _gnutls_parse_extensions(session, GNUTLS_EXT_MANDATORY,
- &data[pos], len);
- if (ret < 0) {
- gnutls_assert();
- return ret;
+ ret =
+ _gnutls_parse_extensions(session, GNUTLS_EXT_MANDATORY,
+ &data[pos], len);
+ if (ret < 0) {
+ gnutls_assert();
+ return ret;
+ }
+ return 0;
}
- return 0;
- }
- pos += session_id_len;
+ pos += session_id_len;
+ }
/* Check if the given cipher suite is supported and copy
* it to the session.
@@ -1570,10 +1573,12 @@ read_server_hello(gnutls_session_t session,
}
pos += 2;
- /* move to compression
- */
- DECR_LEN(len, 1);
- pos++;
+ if (!vers->compact_hello) {
+ /* move to compression
+ */
+ DECR_LEN(len, 1);
+ pos++;
+ }
/* Parse extensions.
*/
@@ -1834,7 +1839,10 @@ static int send_server_hello(gnutls_session_t session, int again)
_gnutls_buffer_init(&extdata);
if (again == 0) {
- datalen = 2 + session_id_len + 1 + GNUTLS_RANDOM_SIZE + 3;
+ vers = get_version(session);
+ if (unlikely(vers == NULL))
+ return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
+
ret =
_gnutls_gen_extensions(session, &extdata,
(session->internals.resumed ==
@@ -1846,9 +1854,14 @@ static int send_server_hello(gnutls_session_t session, int again)
goto fail;
}
+ if (!vers->compact_hello) {
+ datalen = 2 + session_id_len + 1 + GNUTLS_RANDOM_SIZE + 3 + extdata.length;
+ } else {
+ datalen = 2 + GNUTLS_RANDOM_SIZE + 2 + extdata.length;
+ }
+
bufel =
- _gnutls_handshake_alloc(session,
- datalen + extdata.length);
+ _gnutls_handshake_alloc(session, datalen);
if (bufel == NULL) {
gnutls_assert();
ret = GNUTLS_E_MEMORY_ERROR;
@@ -1856,10 +1869,6 @@ static int send_server_hello(gnutls_session_t session, int again)
}
data = _mbuffer_get_udata_ptr(bufel);
- vers = get_version(session);
- if (unlikely(vers == NULL))
- return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
-
data[pos++] = vers->major;
data[pos++] = vers->minor;
@@ -1868,25 +1877,29 @@ static int send_server_hello(gnutls_session_t session, int again)
GNUTLS_RANDOM_SIZE);
pos += GNUTLS_RANDOM_SIZE;
- data[pos++] = session_id_len;
- if (session_id_len > 0) {
- memcpy(&data[pos],
- session->security_parameters.session_id,
- session_id_len);
- }
- pos += session_id_len;
+ if (!vers->compact_hello) {
+ data[pos++] = session_id_len;
+ if (session_id_len > 0) {
+ memcpy(&data[pos],
+ session->security_parameters.session_id,
+ session_id_len);
+ }
+ pos += session_id_len;
- _gnutls_handshake_log("HSK[%p]: SessionID: %s\n", session,
- _gnutls_bin2hex(session->
- security_parameters.session_id,
- session_id_len, buf,
- sizeof(buf), NULL));
+ _gnutls_handshake_log("HSK[%p]: SessionID: %s\n", session,
+ _gnutls_bin2hex(session->
+ security_parameters.session_id,
+ session_id_len, buf,
+ sizeof(buf), NULL));
+ }
memcpy(&data[pos],
session->security_parameters.cs->id, 2);
pos += 2;
- data[pos++] = 0x00;
+ if (!vers->compact_hello) {
+ data[pos++] = 0x00;
+ }
if (extdata.length > 0) {
memcpy(&data[pos], extdata.data, extdata.length);