summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaiki Ueno <ueno@gnu.org>2021-02-10 19:17:03 +0000
committerDaiki Ueno <ueno@gnu.org>2021-02-10 19:17:03 +0000
commit6a1028ca5c0dd106e34155d7e195f8895cff0a5a (patch)
treeb20b452511338d6f4a7b46cd8a76ce495ac4b61e
parentd8cb3f2e88b45edf0ba5b9e2a17d3cd7a31ff723 (diff)
parent37e54a05221e076ba905d2d53fc7d885dc9e9ebc (diff)
downloadgnutls-6a1028ca5c0dd106e34155d7e195f8895cff0a5a.tar.gz
Merge branch 'wip/dueno/hrr-resumption' into 'master'
handshake: TLS 1.3: don't generate session ID in resumption mode See merge request gnutls/gnutls!1381
-rw-r--r--.gitignore1
-rw-r--r--.gitlab-ci.yml1
-rw-r--r--lib/constate.c4
-rw-r--r--lib/db.c2
-rw-r--r--lib/dtls.h4
-rw-r--r--lib/ext/pre_shared_key.c4
-rw-r--r--lib/ext/session_ticket.c4
-rw-r--r--lib/gnutls_int.h9
-rw-r--r--lib/handshake-tls13.c6
-rw-r--r--lib/handshake.c114
-rw-r--r--lib/kx.c2
-rw-r--r--lib/record.c2
-rw-r--r--lib/session.c2
-rw-r--r--lib/sslv2_compat.c4
-rw-r--r--lib/state.c17
-rw-r--r--lib/state.h4
-rw-r--r--lib/tls13/session_ticket.c2
-rw-r--r--tests/Makefile.am2
-rw-r--r--tests/resume-with-previous-stek.c2
-rw-r--r--tests/resume-with-stek-expiration.c2
-rw-r--r--tests/tls13/hello_retry_request_resume.c318
21 files changed, 407 insertions, 99 deletions
diff --git a/.gitignore b/.gitignore
index b721fee238..f473a6fd04 100644
--- a/.gitignore
+++ b/.gitignore
@@ -857,6 +857,7 @@ tests/tls13/change_cipher_spec
tests/tls13/cookie
tests/tls13/hello_random_value
tests/tls13/hello_retry_request
+tests/tls13/hello_retry_request_resume
tests/tls13/key_limits
tests/tls13/key_share
tests/tls13/key_update
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 22edca6ada..72d08de7d7 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -329,7 +329,6 @@ fedora-FIPS140-2/build:
- ./bootstrap
- dash ./configure --disable-gcc-warnings --cache-file $CCACHE_FILE --disable-non-suiteb-curves --enable-fips140-mode --disable-doc --disable-full-test-suite --disable-guile
- make -j$BUILDJOBS
- - make -j$CHECKJOBS check
- mkdir -p lib/.libs/fipscheck
- |
for i in lib/.libs/libgnutls.so*; do
diff --git a/lib/constate.c b/lib/constate.c
index 3717522d38..fc56a7569a 100644
--- a/lib/constate.c
+++ b/lib/constate.c
@@ -814,7 +814,7 @@ int _gnutls_read_connection_state_init(gnutls_session_t session)
/* Update internals from CipherSuite selected.
* If we are resuming just copy the connection session
*/
- if (session->internals.resumed != RESUME_FALSE &&
+ if (session->internals.resumed &&
session->security_parameters.entity == GNUTLS_CLIENT)
_gnutls_set_resumed_parameters(session);
@@ -850,7 +850,7 @@ int _gnutls_write_connection_state_init(gnutls_session_t session)
/* Update internals from CipherSuite selected.
* If we are resuming just copy the connection session
*/
- if (session->internals.resumed != RESUME_FALSE &&
+ if (session->internals.resumed &&
session->security_parameters.entity == GNUTLS_SERVER)
_gnutls_set_resumed_parameters(session);
diff --git a/lib/db.c b/lib/db.c
index fc0699a4bd..4ff76126cd 100644
--- a/lib/db.c
+++ b/lib/db.c
@@ -272,7 +272,7 @@ int _gnutls_server_register_current_session(gnutls_session_t session)
key.data = session->security_parameters.session_id;
key.size = session->security_parameters.session_id_size;
- if (session->internals.resumable == RESUME_FALSE) {
+ if (!session->internals.resumable) {
gnutls_assert();
return GNUTLS_E_INVALID_SESSION;
}
diff --git a/lib/dtls.h b/lib/dtls.h
index 88fba4f3d1..7d9fb40094 100644
--- a/lib/dtls.h
+++ b/lib/dtls.h
@@ -68,9 +68,9 @@ int _dtls_wait_and_retransmit(gnutls_session_t session);
inline static int _dtls_is_async(gnutls_session_t session)
{
if ((session->security_parameters.entity == GNUTLS_SERVER
- && session->internals.resumed == RESUME_FALSE)
+ && !session->internals.resumed)
|| (session->security_parameters.entity == GNUTLS_CLIENT
- && session->internals.resumed == RESUME_TRUE))
+ && session->internals.resumed))
return 1;
else
return 0;
diff --git a/lib/ext/pre_shared_key.c b/lib/ext/pre_shared_key.c
index b5a86b7db1..a042c6488e 100644
--- a/lib/ext/pre_shared_key.c
+++ b/lib/ext/pre_shared_key.c
@@ -696,7 +696,7 @@ static int server_recv_params(gnutls_session_t session,
}
}
- session->internals.resumed = RESUME_TRUE;
+ session->internals.resumed = true;
_gnutls_handshake_log("EXT[%p]: selected resumption PSK identity (%d)\n", session, psk_index);
}
@@ -819,7 +819,7 @@ static int _gnutls_psk_recv_params(gnutls_session_t session,
for (i=0;i<sizeof(session->key.binders)/sizeof(session->key.binders[0]);i++) {
if (session->key.binders[i].prf != NULL && session->key.binders[i].idx == selected_identity) {
if (session->key.binders[i].resumption) {
- session->internals.resumed = RESUME_TRUE;
+ session->internals.resumed = true;
_gnutls_handshake_log("EXT[%p]: selected PSK-resumption mode\n", session);
} else {
_gnutls_handshake_log("EXT[%p]: selected PSK mode\n", session);
diff --git a/lib/ext/session_ticket.c b/lib/ext/session_ticket.c
index 8f22462fae..5877f8fa12 100644
--- a/lib/ext/session_ticket.c
+++ b/lib/ext/session_ticket.c
@@ -370,7 +370,7 @@ unpack_session(gnutls_session_t session, const gnutls_datum_t *state)
if (ret < 0)
return gnutls_assert_val(ret);
- session->internals.resumed = RESUME_TRUE;
+ session->internals.resumed = true;
return 0;
}
@@ -656,7 +656,7 @@ int _gnutls_send_new_session_ticket(gnutls_session_t session, int again)
/* Under TLS1.2 with session tickets, the session ID is used for different
* purposes than the TLS1.0 session ID. Ensure that there is an internally
* set value which the server will see on the original and resumed sessions */
- if (session->internals.resumed != RESUME_TRUE) {
+ if (!session->internals.resumed) {
ret = _gnutls_generate_session_id(session->security_parameters.
session_id,
&session->security_parameters.
diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h
index b9134dcbdd..5eb47b4bdf 100644
--- a/lib/gnutls_int.h
+++ b/lib/gnutls_int.h
@@ -361,9 +361,6 @@ verify(GNUTLS_EXTENSION_MAX_VALUE - GNUTLS_EXTENSION_MAX >= 16);
typedef enum { CIPHER_STREAM, CIPHER_BLOCK, CIPHER_AEAD } cipher_type_t;
-#define RESUME_TRUE 1
-#define RESUME_FALSE 0
-
/* Record Protocol */
typedef enum content_type_t {
GNUTLS_CHANGE_CIPHER_SPEC = 20, GNUTLS_ALERT,
@@ -1086,7 +1083,7 @@ typedef struct {
gnutls_buffer_st handshake_hash_buffer; /* used to keep the last received handshake
* message */
- bool resumable; /* TRUE or FALSE - if we can resume that session */
+ bool resumable; /* if we can resume that session */
send_ticket_state_t ticket_state; /* used by gnutls_session_ticket_send() */
bye_state_t bye_state; /* used by gnutls_bye() */
@@ -1100,7 +1097,7 @@ typedef struct {
* no interruption has happened.
*/
- bool invalid_connection; /* true or FALSE - if this session is valid */
+ bool invalid_connection; /* if this session is valid */
bool may_not_read; /* if it's 0 then we can read/write, otherwise it's forbidden to read/write
*/
@@ -1135,7 +1132,7 @@ typedef struct {
uint16_t dh_prime_bits; /* srp_prime_bits */
/* resumed session */
- bool resumed; /* RESUME_TRUE or FALSE - if we are resuming a session */
+ bool resumed; /* if we are resuming a session */
/* server side: non-zero if resumption was requested by client
* client side: non-zero if we set resumption parameters */
diff --git a/lib/handshake-tls13.c b/lib/handshake-tls13.c
index ea236c803c..7dd42becf1 100644
--- a/lib/handshake-tls13.c
+++ b/lib/handshake-tls13.c
@@ -210,7 +210,7 @@ int _gnutls13_handshake_client(gnutls_session_t session)
SAVE_TRANSCRIPT;
- if (session->internals.resumed != RESUME_FALSE)
+ if (session->internals.resumed)
_gnutls_set_resumed_parameters(session);
return 0;
@@ -325,7 +325,7 @@ static int generate_hs_traffic_keys(gnutls_session_t session)
if ((session->security_parameters.entity == GNUTLS_CLIENT &&
(!(session->internals.hsk_flags & HSK_KEY_SHARE_RECEIVED) ||
(!(session->internals.hsk_flags & HSK_PSK_KE_MODE_DHE_PSK) &&
- session->internals.resumed != RESUME_FALSE))) ||
+ session->internals.resumed))) ||
(session->security_parameters.entity == GNUTLS_SERVER &&
!(session->internals.hsk_flags & HSK_KEY_SHARE_SENT))) {
@@ -506,7 +506,7 @@ int _gnutls13_handshake_server(gnutls_session_t session)
FALLTHROUGH;
case STATE109:
- if (session->internals.resumed != RESUME_FALSE)
+ if (session->internals.resumed)
_gnutls_set_resumed_parameters(session);
if (session->internals.hsk_flags & HSK_EARLY_START_USED) {
diff --git a/lib/handshake.c b/lib/handshake.c
index 52bb20bfe2..6c894eb68a 100644
--- a/lib/handshake.c
+++ b/lib/handshake.c
@@ -61,9 +61,6 @@
#include <valgrind/memcheck.h>
#endif
-#define TRUE 1
-#define FALSE 0
-
static int check_if_null_comp_present(gnutls_session_t session,
uint8_t * data, int datalen);
static int handshake_client(gnutls_session_t session);
@@ -532,7 +529,7 @@ _gnutls_user_hello_func(gnutls_session_t session,
* server, and that includes switching version which we have already
* negotiated; note that this doesn't apply when resuming as the version
* negotiation is already complete. */
- if (session->internals.resumed != RESUME_TRUE) {
+ if (!session->internals.resumed) {
new_max = _gnutls_version_max(session);
old_vers = get_version(session);
@@ -580,7 +577,7 @@ static int set_auth_types(gnutls_session_t session)
/* 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)
+ if (!session->internals.resumed)
kx = gnutls_kx_get(session);
else
kx = GNUTLS_KX_UNKNOWN;
@@ -592,7 +589,7 @@ static int set_auth_types(gnutls_session_t session)
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 (unlikely(session->internals.resumed == RESUME_FALSE)) {
+ } else if (unlikely(!session->internals.resumed)) {
/* Here we can only arrive if something we received
* prevented the session from completing. */
return gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER);
@@ -740,7 +737,7 @@ read_client_hello(gnutls_session_t session, uint8_t * data,
if (ret < 0)
return gnutls_assert_val(ret);
- session->internals.resumed = RESUME_TRUE;
+ session->internals.resumed = true;
return _gnutls_user_hello_func(session, major, minor);
} else {
@@ -751,7 +748,7 @@ read_client_hello(gnutls_session_t session, uint8_t * data,
if (ret < 0)
return gnutls_assert_val(ret);
- session->internals.resumed = RESUME_FALSE;
+ session->internals.resumed = false;
}
} else { /* TLS1.3 */
/* we echo client's session ID - length was checked previously */
@@ -792,7 +789,7 @@ read_client_hello(gnutls_session_t session, uint8_t * data,
}
/* resumed by session_ticket extension */
- if (!vers->tls13_sem && session->internals.resumed != RESUME_FALSE) {
+ if (!vers->tls13_sem && session->internals.resumed) {
session->internals.resumed_security_parameters.
max_record_recv_size =
session->security_parameters.max_record_recv_size;
@@ -930,10 +927,10 @@ int _gnutls_send_finished(gnutls_session_t session, int again)
return ret;
}
- if ((session->internals.resumed == RESUME_FALSE
+ if ((!session->internals.resumed
&& session->security_parameters.entity ==
GNUTLS_CLIENT)
- || (session->internals.resumed != RESUME_FALSE
+ || (session->internals.resumed
&& session->security_parameters.entity ==
GNUTLS_SERVER)) {
/* if we are a client not resuming - or we are a server resuming */
@@ -1034,9 +1031,9 @@ int _gnutls_recv_finished(gnutls_session_t session)
goto cleanup;
}
- if ((session->internals.resumed != RESUME_FALSE
+ if ((session->internals.resumed
&& session->security_parameters.entity == GNUTLS_CLIENT)
- || (session->internals.resumed == RESUME_FALSE
+ || (!session->internals.resumed
&& session->security_parameters.entity == GNUTLS_SERVER)) {
/* if we are a client resuming - or we are a server not resuming */
_gnutls_handshake_log
@@ -1845,13 +1842,13 @@ client_check_if_resuming(gnutls_session_t session,
goto no_resume;
}
- session->internals.resumed = RESUME_TRUE; /* we are resuming */
+ session->internals.resumed = true; /* we are resuming */
return 0;
} else {
no_resume:
/* keep the new session id */
- session->internals.resumed = RESUME_FALSE; /* we are not resuming */
+ session->internals.resumed = false; /* we are not resuming */
return -1;
}
}
@@ -2097,17 +2094,19 @@ static int send_client_hello(gnutls_session_t session, int again)
const version_entry_st *hver, *min_ver, *max_ver;
uint8_t tver[2];
gnutls_buffer_st extdata;
- int rehandshake = 0;
+ bool rehandshake = false;
+ bool resuming = false;
unsigned add_sr_scsv = 0;
+ uint8_t *session_id =
+ session->internals.resumed_security_parameters.session_id;
uint8_t session_id_len =
- session->internals.resumed_security_parameters.session_id_size;
-
+ session->internals.resumed_security_parameters.session_id_size;
if (again == 0) {
/* note that rehandshake is different than resuming
*/
if (session->internals.initial_negotiation_completed)
- rehandshake = 1;
+ rehandshake = true;
ret = _gnutls_buffer_init_handshake_mbuffer(&extdata);
if (ret < 0)
@@ -2124,6 +2123,8 @@ static int send_client_hello(gnutls_session_t session, int again)
hver = _gnutls_legacy_version_max(session);
} else {
/* we are resuming a session */
+ resuming = true;
+
hver =
session->internals.resumed_security_parameters.
pversion;
@@ -2211,11 +2212,8 @@ static int send_client_hello(gnutls_session_t session, int again)
goto cleanup;
}
- uint8_t *resumed_session_id = session->internals.resumed_security_parameters.session_id;
#ifdef TLS13_APPENDIX_D4
- if (max_ver->tls13_sem &&
- session->security_parameters.session_id_size == 0) {
-
+ if (max_ver->tls13_sem && !resuming) {
/* Under TLS1.3 we generate a random session ID to make
* the TLS1.3 session look like a resumed TLS1.2 session */
ret = _gnutls_generate_session_id(session->security_parameters.
@@ -2226,7 +2224,7 @@ static int send_client_hello(gnutls_session_t session, int again)
gnutls_assert();
goto cleanup;
}
- resumed_session_id = session->security_parameters.session_id;
+ session_id = session->security_parameters.session_id;
session_id_len = session->security_parameters.session_id_size;
}
#endif
@@ -2234,7 +2232,7 @@ static int send_client_hello(gnutls_session_t session, int again)
/* Copy the Session ID - if any
*/
ret = _gnutls_buffer_append_data_prefix(&extdata, 8,
- resumed_session_id,
+ session_id,
session_id_len);
if (ret < 0) {
gnutls_assert();
@@ -2393,7 +2391,7 @@ int _gnutls_send_server_hello(gnutls_session_t session, int again)
goto fail;
}
- if (!vers->tls13_sem && session->internals.resumed != RESUME_FALSE)
+ if (!vers->tls13_sem && session->internals.resumed)
etype = GNUTLS_EXT_MANDATORY;
else
etype = GNUTLS_EXT_ANY;
@@ -3002,7 +3000,7 @@ static int handshake_client(gnutls_session_t session)
FALLTHROUGH;
case STATE6:
/* RECV CERTIFICATE */
- if (session->internals.resumed == RESUME_FALSE) /* if we are not resuming */
+ if (!session->internals.resumed) /* if we are not resuming */
ret = _gnutls_recv_server_certificate(session);
STATE = STATE6;
IMED_RET("recv server certificate", ret, 1);
@@ -3010,7 +3008,7 @@ static int handshake_client(gnutls_session_t session)
case STATE7:
#ifdef ENABLE_OCSP
/* RECV CERTIFICATE STATUS */
- if (session->internals.resumed == RESUME_FALSE) /* if we are not resuming */
+ if (!session->internals.resumed) /* if we are not resuming */
ret =
_gnutls_recv_server_certificate_status
(session);
@@ -3027,7 +3025,7 @@ static int handshake_client(gnutls_session_t session)
FALLTHROUGH;
case STATE9:
/* receive the server key exchange */
- if (session->internals.resumed == RESUME_FALSE) /* if we are not resuming */
+ if (!session->internals.resumed) /* if we are not resuming */
ret = _gnutls_recv_server_kx_message(session);
STATE = STATE9;
IMED_RET("recv server kx message", ret, 1);
@@ -3036,7 +3034,7 @@ static int handshake_client(gnutls_session_t session)
/* receive the server certificate request - if any
*/
- if (session->internals.resumed == RESUME_FALSE) /* if we are not resuming */
+ if (!session->internals.resumed) /* if we are not resuming */
ret = _gnutls_recv_server_crt_request(session);
STATE = STATE10;
IMED_RET("recv server certificate request message", ret,
@@ -3044,7 +3042,7 @@ static int handshake_client(gnutls_session_t session)
FALLTHROUGH;
case STATE11:
/* receive the server hello done */
- if (session->internals.resumed == RESUME_FALSE) /* if we are not resuming */
+ if (!session->internals.resumed) /* if we are not resuming */
ret =
_gnutls_recv_handshake(session,
GNUTLS_HANDSHAKE_SERVER_HELLO_DONE,
@@ -3064,7 +3062,7 @@ static int handshake_client(gnutls_session_t session)
case STATE13:
/* send our certificate - if any and if requested
*/
- if (session->internals.resumed == RESUME_FALSE) /* if we are not resuming */
+ if (!session->internals.resumed) /* if we are not resuming */
ret =
_gnutls_send_client_certificate(session,
AGAIN
@@ -3073,7 +3071,7 @@ static int handshake_client(gnutls_session_t session)
IMED_RET("send client certificate", ret, 0);
FALLTHROUGH;
case STATE14:
- if (session->internals.resumed == RESUME_FALSE) /* if we are not resuming */
+ if (!session->internals.resumed) /* if we are not resuming */
ret =
_gnutls_send_client_kx_message(session,
AGAIN(STATE14));
@@ -3082,7 +3080,7 @@ static int handshake_client(gnutls_session_t session)
FALLTHROUGH;
case STATE15:
/* send client certificate verify */
- if (session->internals.resumed == RESUME_FALSE) /* if we are not resuming */
+ if (!session->internals.resumed) /* if we are not resuming */
ret =
_gnutls_send_client_certificate_verify(session,
AGAIN
@@ -3092,8 +3090,8 @@ static int handshake_client(gnutls_session_t session)
FALLTHROUGH;
case STATE16:
STATE = STATE16;
- if (session->internals.resumed == RESUME_FALSE) {
- ret = send_handshake_final(session, TRUE);
+ if (!session->internals.resumed) {
+ ret = send_handshake_final(session, true);
IMED_RET("send handshake final 2", ret, 1);
} else {
ret = _gnutls_recv_new_session_ticket(session);
@@ -3103,7 +3101,7 @@ static int handshake_client(gnutls_session_t session)
FALLTHROUGH;
case STATE17:
STATE = STATE17;
- if (session->internals.resumed == RESUME_FALSE && (session->internals.flags & GNUTLS_ENABLE_FALSE_START) && can_send_false_start(session)) {
+ if (!session->internals.resumed && (session->internals.flags & GNUTLS_ENABLE_FALSE_START) && can_send_false_start(session)) {
session->internals.hsk_flags |= HSK_FALSE_START_USED;
session->internals.recv_state = RECV_STATE_FALSE_START;
/* complete this phase of the handshake. We
@@ -3118,22 +3116,22 @@ static int handshake_client(gnutls_session_t session)
case STATE18:
STATE = STATE18;
- if (session->internals.resumed == RESUME_FALSE) {
+ if (!session->internals.resumed) {
ret = _gnutls_recv_new_session_ticket(session);
IMED_RET("recv handshake new session ticket", ret,
1);
} else {
- ret = recv_handshake_final(session, TRUE);
+ ret = recv_handshake_final(session, true);
IMED_RET("recv handshake final", ret, 1);
}
FALLTHROUGH;
case STATE19:
STATE = STATE19;
- if (session->internals.resumed == RESUME_FALSE) {
- ret = recv_handshake_final(session, FALSE);
+ if (!session->internals.resumed) {
+ ret = recv_handshake_final(session, false);
IMED_RET("recv handshake final 2", ret, 1);
} else {
- ret = send_handshake_final(session, FALSE);
+ ret = send_handshake_final(session, false);
IMED_RET("send handshake final", ret, 1);
}
@@ -3245,7 +3243,7 @@ static int send_handshake_final(gnutls_session_t session, int init)
}
/* Initialize the connection session (start encryption) - in case of client
*/
- if (init == TRUE) {
+ if (init) {
ret = _gnutls_connection_state_init(session);
if (ret < 0) {
gnutls_assert();
@@ -3330,7 +3328,7 @@ static int recv_handshake_final(gnutls_session_t session, int init)
session->internals.dtls.hsk_read_seq++;
/* Initialize the connection session (start encryption) - in case of server */
- if (init == TRUE) {
+ if (init) {
ret = _gnutls_connection_state_init(session);
if (ret < 0) {
gnutls_assert();
@@ -3438,7 +3436,7 @@ static int handshake_server(gnutls_session_t session)
case STATE5:
/* NOTE: these should not be send if we are resuming */
- if (session->internals.resumed == RESUME_FALSE)
+ if (!session->internals.resumed)
ret =
_gnutls_send_server_certificate(session,
AGAIN(STATE5));
@@ -3447,7 +3445,7 @@ static int handshake_server(gnutls_session_t session)
FALLTHROUGH;
case STATE6:
#ifdef ENABLE_OCSP
- if (session->internals.resumed == RESUME_FALSE)
+ if (!session->internals.resumed)
ret =
_gnutls_send_server_certificate_status(session,
AGAIN
@@ -3458,7 +3456,7 @@ static int handshake_server(gnutls_session_t session)
FALLTHROUGH;
case STATE7:
/* send server key exchange (A) */
- if (session->internals.resumed == RESUME_FALSE)
+ if (!session->internals.resumed)
ret =
_gnutls_send_server_kx_message(session,
AGAIN(STATE7));
@@ -3467,7 +3465,7 @@ static int handshake_server(gnutls_session_t session)
FALLTHROUGH;
case STATE8:
/* Send certificate request - if requested to */
- if (session->internals.resumed == RESUME_FALSE)
+ if (!session->internals.resumed)
ret =
_gnutls_send_server_crt_request(session,
AGAIN(STATE8));
@@ -3476,7 +3474,7 @@ static int handshake_server(gnutls_session_t session)
FALLTHROUGH;
case STATE9:
/* send the server hello done */
- if (session->internals.resumed == RESUME_FALSE) /* if we are not resuming */
+ if (!session->internals.resumed) /* if we are not resuming */
ret =
_gnutls_send_empty_handshake(session,
GNUTLS_HANDSHAKE_SERVER_HELLO_DONE,
@@ -3494,7 +3492,7 @@ static int handshake_server(gnutls_session_t session)
FALLTHROUGH;
case STATE11:
/* receive the client certificate message */
- if (session->internals.resumed == RESUME_FALSE) /* if we are not resuming */
+ if (!session->internals.resumed) /* if we are not resuming */
ret = _gnutls_recv_client_certificate(session);
STATE = STATE11;
IMED_RET("recv client certificate", ret, 1);
@@ -3507,14 +3505,14 @@ static int handshake_server(gnutls_session_t session)
FALLTHROUGH;
case STATE13:
/* receive the client key exchange message */
- if (session->internals.resumed == RESUME_FALSE) /* if we are not resuming */
+ if (!session->internals.resumed) /* if we are not resuming */
ret = _gnutls_recv_client_kx_message(session);
STATE = STATE13;
IMED_RET("recv client kx", ret, 1);
FALLTHROUGH;
case STATE14:
/* receive the client certificate verify message */
- if (session->internals.resumed == RESUME_FALSE) /* if we are not resuming */
+ if (!session->internals.resumed) /* if we are not resuming */
ret =
_gnutls_recv_client_certificate_verify_message
(session);
@@ -3523,11 +3521,11 @@ static int handshake_server(gnutls_session_t session)
FALLTHROUGH;
case STATE15:
STATE = STATE15;
- if (session->internals.resumed == RESUME_FALSE) { /* if we are not resuming */
- ret = recv_handshake_final(session, TRUE);
+ if (!session->internals.resumed) { /* if we are not resuming */
+ ret = recv_handshake_final(session, true);
IMED_RET("recv handshake final", ret, 1);
} else {
- ret = send_handshake_final(session, TRUE);
+ ret = send_handshake_final(session, true);
IMED_RET("send handshake final 2", ret, 1);
}
FALLTHROUGH;
@@ -3540,8 +3538,8 @@ static int handshake_server(gnutls_session_t session)
FALLTHROUGH;
case STATE17:
STATE = STATE17;
- if (session->internals.resumed == RESUME_FALSE) { /* if we are not resuming */
- ret = send_handshake_final(session, FALSE);
+ if (!session->internals.resumed) { /* if we are not resuming */
+ ret = send_handshake_final(session, false);
IMED_RET("send handshake final", ret, 1);
if (session->security_parameters.entity ==
@@ -3552,7 +3550,7 @@ static int handshake_server(gnutls_session_t session)
(session);
}
} else {
- ret = recv_handshake_final(session, FALSE);
+ ret = recv_handshake_final(session, false);
IMED_RET("recv handshake final 2", ret, 1);
}
diff --git a/lib/kx.c b/lib/kx.c
index 1eda14d3d6..9f3c14b6db 100644
--- a/lib/kx.c
+++ b/lib/kx.c
@@ -54,7 +54,7 @@ static int generate_normal_master(gnutls_session_t session,
int _gnutls_generate_master(gnutls_session_t session, int keep_premaster)
{
- if (session->internals.resumed == RESUME_FALSE)
+ if (!session->internals.resumed)
return generate_normal_master(session, &session->key.key,
keep_premaster);
else if (session->internals.premaster_set) {
diff --git a/lib/record.c b/lib/record.c
index 8b0d2bc60e..cd9df80520 100644
--- a/lib/record.c
+++ b/lib/record.c
@@ -341,7 +341,7 @@ int gnutls_bye(gnutls_session_t session, gnutls_close_request_t how)
inline static void session_unresumable(gnutls_session_t session)
{
- session->internals.resumable = RESUME_FALSE;
+ session->internals.resumable = false;
}
/* returns 0 if session is valid
diff --git a/lib/session.c b/lib/session.c
index b9a23e8d02..bdaf572b0e 100644
--- a/lib/session.c
+++ b/lib/session.c
@@ -166,7 +166,7 @@ gnutls_session_get_data2(gnutls_session_t session, gnutls_datum_t *data)
}
}
- if (session->internals.resumable == RESUME_FALSE)
+ if (!session->internals.resumable)
return GNUTLS_E_INVALID_SESSION;
ret = _gnutls_session_pack(session, data);
diff --git a/lib/sslv2_compat.c b/lib/sslv2_compat.c
index 4dd62d01c1..c4a0143b92 100644
--- a/lib/sslv2_compat.c
+++ b/lib/sslv2_compat.c
@@ -238,7 +238,7 @@ _gnutls_read_client_hello_v2(gnutls_session_t session, uint8_t * data,
session->security_parameters.client_random,
GNUTLS_RANDOM_SIZE);
- session->internals.resumed = RESUME_TRUE;
+ session->internals.resumed = true;
return 0;
} else {
ret = _gnutls_generate_session_id(
@@ -247,7 +247,7 @@ _gnutls_read_client_hello_v2(gnutls_session_t session, uint8_t * data,
if (ret < 0)
return gnutls_assert_val(ret);
- session->internals.resumed = RESUME_FALSE;
+ session->internals.resumed = false;
}
return sret;
diff --git a/lib/state.c b/lib/state.c
index fcf6183fa4..9f306faf70 100644
--- a/lib/state.c
+++ b/lib/state.c
@@ -419,7 +419,7 @@ static void handshake_internal_state_clear1(gnutls_session_t session)
session->internals.last_handshake_in = -1;
session->internals.last_handshake_out = -1;
- session->internals.resumable = RESUME_TRUE;
+ session->internals.resumable = true;
session->internals.handshake_suspicious_loops = 0;
session->internals.dtls.hsk_read_seq = 0;
@@ -640,13 +640,6 @@ int gnutls_init(gnutls_session_t * session, unsigned int flags)
return 0;
}
-/* returns RESUME_FALSE or RESUME_TRUE.
- */
-int _gnutls_session_is_resumable(gnutls_session_t session)
-{
- return session->internals.resumable;
-}
-
/**
* gnutls_deinit:
@@ -988,9 +981,9 @@ int gnutls_session_is_resumed(gnutls_session_t session)
{
if (session->security_parameters.entity == GNUTLS_CLIENT) {
const version_entry_st *ver = get_version(session);
- if (ver && ver->tls13_sem &&
- session->internals.resumed != RESUME_FALSE)
- return 1;
+ if (ver && ver->tls13_sem) {
+ return session->internals.resumed;
+ }
if (session->security_parameters.session_id_size > 0 &&
session->security_parameters.session_id_size ==
@@ -1004,7 +997,7 @@ int gnutls_session_is_resumed(gnutls_session_t session)
session_id_size) == 0)
return 1;
} else {
- if (session->internals.resumed != RESUME_FALSE)
+ if (session->internals.resumed)
return 1;
}
diff --git a/lib/state.h b/lib/state.h
index 819df21ec6..ff945b0690 100644
--- a/lib/state.h
+++ b/lib/state.h
@@ -99,12 +99,8 @@ static inline int _gnutls_dh_get_min_prime_bits(gnutls_session_t session)
void _gnutls_handshake_internal_state_clear(gnutls_session_t);
-int _gnutls_session_is_resumable(gnutls_session_t session);
-
int _gnutls_session_is_psk(gnutls_session_t session);
-int _gnutls_openpgp_send_fingerprint(gnutls_session_t session);
-
void reset_binders(gnutls_session_t session);
inline static int
diff --git a/lib/tls13/session_ticket.c b/lib/tls13/session_ticket.c
index 072a56d9c1..3f64d8c32e 100644
--- a/lib/tls13/session_ticket.c
+++ b/lib/tls13/session_ticket.c
@@ -201,7 +201,7 @@ generate_session_ticket(gnutls_session_t session, tls13_ticket_st *ticket)
tls13_ticket_st ticket_data;
gnutls_gettime(&now);
- if (session->internals.resumed != RESUME_FALSE) {
+ if (session->internals.resumed) {
/* If we are resuming ensure that we don't extend the lifetime
* of the ticket past the original session expiration time */
if (now.tv_sec >= session->security_parameters.timestamp + session->internals.expire_time)
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 35d06db8fc..8f7972a7d5 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -118,6 +118,8 @@ ctests = tls13/supported_versions tls13/tls12-no-tls13-exts \
ctests += tls13/hello_retry_request
+ctests += tls13/hello_retry_request_resume
+
ctests += tls13/psk-ext
ctests += tls13/key_update
diff --git a/tests/resume-with-previous-stek.c b/tests/resume-with-previous-stek.c
index 05c1c90868..3bbba8f896 100644
--- a/tests/resume-with-previous-stek.c
+++ b/tests/resume-with-previous-stek.c
@@ -227,11 +227,13 @@ static void run(const char *name, const char *prio, int resume[], int rounds)
if (child) {
/* We are the parent */
+ close(sockets[1]);
server(sockets[0], rounds, prio);
waitpid(child, &status, 0);
check_wait_status(status);
} else {
/* We are the child */
+ close(sockets[0]);
client(sockets[1], resume, rounds, prio);
exit(0);
}
diff --git a/tests/resume-with-stek-expiration.c b/tests/resume-with-stek-expiration.c
index 80445d64d0..de0f07012b 100644
--- a/tests/resume-with-stek-expiration.c
+++ b/tests/resume-with-stek-expiration.c
@@ -297,11 +297,13 @@ static void run(const char *name, const char *prio, int resumption_should_succee
if (child) {
/* We are the parent */
+ close(sockets[1]);
server(sockets[0], resumption_should_succeed, rounds, prio);
waitpid(child, &status, 0);
check_wait_status(status);
} else {
/* We are the child */
+ close(sockets[0]);
client(sockets[1], resumption_should_succeed, rounds, prio);
exit(0);
}
diff --git a/tests/tls13/hello_retry_request_resume.c b/tests/tls13/hello_retry_request_resume.c
new file mode 100644
index 0000000000..6672bc7a9c
--- /dev/null
+++ b/tests/tls13/hello_retry_request_resume.c
@@ -0,0 +1,318 @@
+/*
+ * Copyright (C) 2017-2020 Red Hat, Inc.
+ *
+ * Author: Nikos Mavrogiannopoulos, Daiki Ueno
+ *
+ * This file is part of GnuTLS.
+ *
+ * GnuTLS is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuTLS is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#if defined(_WIN32)
+
+int main()
+{
+ exit(77);
+}
+
+#else
+
+#include <string.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/wait.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+#include <gnutls/gnutls.h>
+#include <signal.h>
+#include <assert.h>
+
+#include "../lib/handshake-defs.h"
+#include "cert-common.h"
+#include "utils.h"
+
+/* This program tests whether the certificate seen in Post Handshake Auth
+ * is found in a resumed session under TLS 1.3.
+ */
+
+static void server_log_func(int level, const char *str)
+{
+ fprintf(stderr, "server|<%d>| %s", level, str);
+}
+
+static void client_log_func(int level, const char *str)
+{
+ fprintf(stderr, "client|<%d>| %s", level, str);
+}
+
+static int ticket_callback(gnutls_session_t session, unsigned int htype,
+ unsigned post, unsigned int incoming, const gnutls_datum_t *msg)
+{
+ gnutls_datum *d;
+ int ret;
+
+ assert(htype == GNUTLS_HANDSHAKE_NEW_SESSION_TICKET);
+
+ d = gnutls_session_get_ptr(session);
+
+ if (post == GNUTLS_HOOK_POST) {
+ if (d->data)
+ gnutls_free(d->data);
+ ret = gnutls_session_get_data2(session, d);
+ assert(ret >= 0);
+ assert(d->size > 4);
+
+ return 0;
+ }
+
+ return 0;
+}
+
+static void client(int fd)
+{
+ int ret;
+ gnutls_session_t session;
+ unsigned try = 0;
+ gnutls_datum_t session_data = {NULL, 0};
+ gnutls_certificate_credentials_t x509_cred;
+
+ global_init();
+
+ if (debug) {
+ gnutls_global_set_log_function(client_log_func);
+ gnutls_global_set_log_level(7);
+ }
+
+ assert(gnutls_certificate_allocate_credentials(&x509_cred)>=0);
+
+ retry:
+ /* Initialize TLS session
+ */
+ assert(gnutls_init(&session, GNUTLS_CLIENT)>=0);
+
+ gnutls_handshake_set_timeout(session, 20 * 1000);
+
+ ret = gnutls_priority_set_direct(session, "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-SECP256R1:+GROUP-X25519", NULL);
+ if (ret < 0)
+ fail("cannot set TLS 1.3 priorities\n");
+
+
+ if (try == 0) {
+ gnutls_session_set_ptr(session, &session_data);
+ gnutls_handshake_set_hook_function(session, GNUTLS_HANDSHAKE_NEW_SESSION_TICKET,
+ GNUTLS_HOOK_BOTH,
+ ticket_callback);
+ } else {
+ assert(gnutls_session_set_data(session, session_data.data, session_data.size) >= 0);
+ }
+
+ gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, x509_cred);
+
+ gnutls_transport_set_int(session, fd);
+
+ /* Perform the TLS handshake
+ */
+ do {
+ ret = gnutls_handshake(session);
+ }
+ while (ret < 0 && gnutls_error_is_fatal(ret) == 0);
+
+ if (ret != 0)
+ fail("handshake failed: %s\n", gnutls_strerror(ret));
+
+ do {
+ ret = gnutls_bye(session, GNUTLS_SHUT_RDWR);
+ } while(ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED);
+
+ if (ret != 0) {
+ fail("error in recv: %s\n", gnutls_strerror(ret));
+ }
+
+ gnutls_deinit(session);
+
+ if (try == 0) {
+ try++;
+ goto retry;
+ }
+
+ gnutls_free(session_data.data);
+ close(fd);
+ gnutls_certificate_free_credentials(x509_cred);
+
+ gnutls_global_deinit();
+}
+
+#define HANDSHAKE_SESSION_ID_POS 34
+
+static int client_hello_callback(gnutls_session_t session, unsigned int htype,
+ unsigned post, unsigned int incoming,
+ const gnutls_datum_t *msg)
+{
+ gnutls_datum *d;
+
+ assert(post == GNUTLS_HOOK_POST);
+ assert(msg->size >= HANDSHAKE_SESSION_ID_POS + 1);
+
+ d = gnutls_session_get_ptr(session);
+ d->size = msg->data[HANDSHAKE_SESSION_ID_POS];
+ d->data = gnutls_malloc(d->size);
+ memcpy(d->data, &msg->data[HANDSHAKE_SESSION_ID_POS], d->size);
+
+ return 0;
+}
+
+static void server(int fd)
+{
+ int ret;
+ gnutls_session_t session;
+ unsigned try = 0;
+ gnutls_certificate_credentials_t x509_cred;
+ gnutls_datum_t skey;
+ gnutls_datum_t session_id = {NULL, 0};
+ gnutls_datum_t retry_session_id = {NULL, 0};
+
+ /* this must be called once in the program
+ */
+ global_init();
+
+ assert(gnutls_session_ticket_key_generate(&skey)>=0);
+
+ if (debug) {
+ gnutls_global_set_log_function(server_log_func);
+ gnutls_global_set_log_level(4711);
+ }
+
+ gnutls_certificate_allocate_credentials(&x509_cred);
+ gnutls_certificate_set_x509_key_mem(x509_cred, &server_cert,
+ &server_key,
+ GNUTLS_X509_FMT_PEM);
+
+ retry:
+ assert(gnutls_init(&session, GNUTLS_SERVER)>=0);
+
+ assert(gnutls_session_ticket_enable_server(session, &skey) >= 0);
+ gnutls_handshake_set_timeout(session, 20 * 1000);
+
+ /* server only supports x25519, client advertises secp256r1 */
+ assert(gnutls_priority_set_direct(session, "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-X25519", NULL)>=0);
+
+ gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, x509_cred);
+
+ gnutls_transport_set_int(session, fd);
+
+ if (try == 0) {
+ gnutls_session_set_ptr(session, &session_id);
+ } else {
+ gnutls_session_set_ptr(session, &retry_session_id);
+ }
+
+ gnutls_handshake_set_hook_function(session, GNUTLS_HANDSHAKE_CLIENT_HELLO,
+ GNUTLS_HOOK_POST,
+ client_hello_callback);
+
+ do {
+ ret = gnutls_handshake(session);
+ } while (ret < 0 && gnutls_error_is_fatal(ret) == 0);
+
+ if (ret != 0)
+ fail("handshake failed: %s\n", gnutls_strerror(ret));
+
+ if (try > 0) {
+ assert(gnutls_session_is_resumed(session) != 0);
+
+ /* Check that the same (non-empty) session ID is used in both
+ * initial and resumption handshakes. This assumes
+ * TLS13_APPENDIX_D4 is set to 1 in lib/handshake-defs.h. Once
+ * it's turned off, both session IDs should be empty. */
+ if (session_id.size == 0 ||
+ session_id.size != retry_session_id.size ||
+ memcmp(session_id.data, retry_session_id.data, session_id.size)) {
+ fail("session ids are different after resumption: %u, %u\n",
+ session_id.size, retry_session_id.size);
+ }
+ }
+
+ do {
+ ret = gnutls_bye(session, GNUTLS_SHUT_RDWR);
+ } while(ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED);
+ gnutls_deinit(session);
+
+ if (try == 0) {
+ try++;
+ goto retry;
+ }
+
+ gnutls_free(skey.data);
+ close(fd);
+ gnutls_certificate_free_credentials(x509_cred);
+ gnutls_free(session_id.data);
+ gnutls_free(retry_session_id.data);
+
+ gnutls_global_deinit();
+
+ if (debug)
+ success("server: client/server hello were verified\n");
+}
+
+static void ch_handler(int sig)
+{
+ int status = 0;
+ wait(&status);
+ check_wait_status(status);
+ return;
+}
+
+void doit(void)
+{
+ int fd[2];
+ int ret;
+ pid_t child;
+
+ signal(SIGCHLD, ch_handler);
+ signal(SIGPIPE, SIG_IGN);
+
+ ret = socketpair(AF_UNIX, SOCK_STREAM, 0, fd);
+ if (ret < 0) {
+ perror("socketpair");
+ exit(1);
+ }
+
+ child = fork();
+ if (child < 0) {
+ perror("fork");
+ fail("fork");
+ exit(1);
+ }
+
+ if (child) {
+ /* parent */
+ close(fd[1]);
+ server(fd[0]);
+ kill(child, SIGTERM);
+ } else {
+ close(fd[0]);
+ client(fd[1]);
+ exit(0);
+ }
+
+}
+#endif /* _WIN32 */