summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaiki Ueno <ueno@gnu.org>2018-11-12 15:54:01 +0000
committerDaiki Ueno <ueno@gnu.org>2018-11-12 15:54:01 +0000
commit868a373f915f65259c9708023ed612beb513db21 (patch)
tree54555ab056b65c644ed26253b9e5cdbe4d707fbe
parent0e9e406c6d92a5cda2020ebda9bede0d3503f4bd (diff)
parent4429256c40161b088847f8e058c8a4cfb8d5b5f1 (diff)
downloadgnutls-868a373f915f65259c9708023ed612beb513db21.tar.gz
Merge branch 'tmp-0rtt' into 'master'
add support for 0-RTT Closes #127 See merge request gnutls/gnutls!775
-rw-r--r--.gitignore2
-rw-r--r--NEWS11
-rw-r--r--doc/Makefile.am18
-rw-r--r--doc/cha-gtls-app.texi144
-rw-r--r--doc/manpages/Makefile.am9
-rw-r--r--lib/Makefile.am4
-rw-r--r--lib/constate.c83
-rw-r--r--lib/constate.h2
-rw-r--r--lib/db.c61
-rw-r--r--lib/errors.c3
-rw-r--r--lib/ext/early_data.c49
-rw-r--r--lib/ext/pre_shared_key.c35
-rw-r--r--lib/gnutls_int.h24
-rw-r--r--lib/handshake-tls13.c175
-rw-r--r--lib/handshake.c120
-rw-r--r--lib/handshake.h2
-rw-r--r--lib/includes/gnutls/gnutls.h.in33
-rw-r--r--lib/libgnutls.map16
-rw-r--r--lib/record.c200
-rw-r--r--lib/session_pack.c14
-rw-r--r--lib/state.c7
-rw-r--r--lib/str.h2
-rw-r--r--lib/tls13/anti_replay.c221
-rw-r--r--lib/tls13/anti_replay.h26
-rw-r--r--lib/tls13/early_data.c101
-rw-r--r--lib/tls13/early_data.h25
-rw-r--r--lib/tls13/key_update.c2
-rw-r--r--lib/tls13/session_ticket.c70
-rw-r--r--src/cli-args.c.bak853
-rw-r--r--src/cli-args.def7
-rw-r--r--src/cli-args.h.bak190
-rw-r--r--src/cli.c21
-rw-r--r--src/serv-args.c.bak612
-rw-r--r--src/serv-args.def6
-rw-r--r--src/serv-args.h.bak130
-rw-r--r--src/serv.c182
-rw-r--r--src/socket.c16
-rw-r--r--src/socket.h9
-rw-r--r--symbols.last10
-rw-r--r--tests/Makefile.am15
-rw-r--r--tests/resume.c9
-rwxr-xr-xtests/suite/testcompat-tls13-openssl.sh54
-rw-r--r--tests/tls13-early-data.c432
-rw-r--r--tests/tls13/anti_replay.c145
44 files changed, 3093 insertions, 1057 deletions
diff --git a/.gitignore b/.gitignore
index 3fc64789dd..c8b8ff40a3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -760,10 +760,12 @@ tests/tls12-resume-psk
tests/tls12-resume-x509
tests/tls12-rollback-detection
tests/tls12-server-kx-neg
+tests/tls13/anti_replay
tests/tls13-cert-key-exchange
tests/tls13/change_cipher_spec
tests/tls13-cipher-neg
tests/tls13/cookie
+tests/tls13-early-data
tests/tls13-early-start
tests/tls13/hello_random_value
tests/tls13/hello_retry_request
diff --git a/NEWS b/NEWS
index ea9fb34697..3332ce7d16 100644
--- a/NEWS
+++ b/NEWS
@@ -27,6 +27,8 @@ See the end for copying conditions.
** gnutls-serv: It applies the default settings when no --priority option is given,
using gnutls_set_default_priority().
+** libgnutls: Added support for TLS 1.3 zero round-trip (0-RTT) mode (#127)
+
** API and ABI modifications:
GNUTLS_AUTO_REAUTH: Added
GNUTLS_CIPHER_AES_128_CFB8: Added
@@ -34,6 +36,15 @@ GNUTLS_CIPHER_AES_192_CFB8: Added
GNUTLS_CIPHER_AES_256_CFB8: Added
GNUTLS_MAC_AES_CMAC_128: Added
GNUTLS_MAC_AES_CMAC_256: Added
+gnutls_record_get_max_early_data_size: Added
+gnutls_record_send_early_data: Added
+gnutls_record_recv_early_data: Added
+gnutls_db_entry_is_expired: Added
+gnutls_db_set_add_function: Added
+gnutls_anti_replay_init: Added
+gnutls_anti_replay_deinit: Added
+gnutls_anti_replay_set_window: Added
+gnutls_anti_replay_enable: Added
* Version 3.6.4 (released 2018-09-24)
diff --git a/doc/Makefile.am b/doc/Makefile.am
index 130617fa74..6d6865fce9 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -673,6 +673,14 @@ FUNCS += functions/gnutls_anon_set_server_known_dh_params
FUNCS += functions/gnutls_anon_set_server_known_dh_params.short
FUNCS += functions/gnutls_anon_set_server_params_function
FUNCS += functions/gnutls_anon_set_server_params_function.short
+FUNCS += functions/gnutls_anti_replay_deinit
+FUNCS += functions/gnutls_anti_replay_deinit.short
+FUNCS += functions/gnutls_anti_replay_enable
+FUNCS += functions/gnutls_anti_replay_enable.short
+FUNCS += functions/gnutls_anti_replay_init
+FUNCS += functions/gnutls_anti_replay_init.short
+FUNCS += functions/gnutls_anti_replay_set_window
+FUNCS += functions/gnutls_anti_replay_set_window.short
FUNCS += functions/gnutls_auth_client_get_type
FUNCS += functions/gnutls_auth_client_get_type.short
FUNCS += functions/gnutls_auth_get_type
@@ -877,6 +885,8 @@ FUNCS += functions/gnutls_crypto_register_mac
FUNCS += functions/gnutls_crypto_register_mac.short
FUNCS += functions/gnutls_db_check_entry
FUNCS += functions/gnutls_db_check_entry.short
+FUNCS += functions/gnutls_db_check_entry_expire_time
+FUNCS += functions/gnutls_db_check_entry_expire_time.short
FUNCS += functions/gnutls_db_check_entry_time
FUNCS += functions/gnutls_db_check_entry_time.short
FUNCS += functions/gnutls_db_get_default_cache_expiration
@@ -885,6 +895,8 @@ FUNCS += functions/gnutls_db_get_ptr
FUNCS += functions/gnutls_db_get_ptr.short
FUNCS += functions/gnutls_db_remove_session
FUNCS += functions/gnutls_db_remove_session.short
+FUNCS += functions/gnutls_db_set_add_function
+FUNCS += functions/gnutls_db_set_add_function.short
FUNCS += functions/gnutls_db_set_cache_expiration
FUNCS += functions/gnutls_db_set_cache_expiration.short
FUNCS += functions/gnutls_db_set_ptr
@@ -1799,6 +1811,8 @@ FUNCS += functions/gnutls_record_get_direction
FUNCS += functions/gnutls_record_get_direction.short
FUNCS += functions/gnutls_record_get_discarded
FUNCS += functions/gnutls_record_get_discarded.short
+FUNCS += functions/gnutls_record_get_max_early_data_size
+FUNCS += functions/gnutls_record_get_max_early_data_size.short
FUNCS += functions/gnutls_record_get_max_size
FUNCS += functions/gnutls_record_get_max_size.short
FUNCS += functions/gnutls_record_get_state
@@ -1807,6 +1821,8 @@ FUNCS += functions/gnutls_record_overhead_size
FUNCS += functions/gnutls_record_overhead_size.short
FUNCS += functions/gnutls_record_recv
FUNCS += functions/gnutls_record_recv.short
+FUNCS += functions/gnutls_record_recv_early_data
+FUNCS += functions/gnutls_record_recv_early_data.short
FUNCS += functions/gnutls_record_recv_packet
FUNCS += functions/gnutls_record_recv_packet.short
FUNCS += functions/gnutls_record_recv_seq
@@ -1815,6 +1831,8 @@ FUNCS += functions/gnutls_record_send
FUNCS += functions/gnutls_record_send.short
FUNCS += functions/gnutls_record_send2
FUNCS += functions/gnutls_record_send2.short
+FUNCS += functions/gnutls_record_send_early_data
+FUNCS += functions/gnutls_record_send_early_data.short
FUNCS += functions/gnutls_record_send_range
FUNCS += functions/gnutls_record_send_range.short
FUNCS += functions/gnutls_record_set_max_early_data_size
diff --git a/doc/cha-gtls-app.texi b/doc/cha-gtls-app.texi
index 64c662ce00..b7b6d6a87e 100644
--- a/doc/cha-gtls-app.texi
+++ b/doc/cha-gtls-app.texi
@@ -814,6 +814,8 @@ remaining until the next retransmission, or better the time until
@menu
* Asynchronous operation::
* Reducing round-trips::
+* Zero-roundtrip mode::
+* Anti-replay protection::
* DTLS sessions::
* DTLS and SCTP::
@end menu
@@ -916,6 +918,142 @@ It can be enabled by setting the @acronym{GNUTLS_ENABLE_EARLY_START} on
return early, allowing the server to send data earlier.
+@node Zero-roundtrip mode
+@subsection Zero-roundtrip mode
+
+Under TLS 1.3, when the client has already connected to the server and
+is resuming a session, it can start transmitting application data during
+handshake. This is called zero round-trip time (0-RTT) mode, and the
+application data sent in this mode is called early data. The client can
+send early data with @funcref{gnutls_record_send_early_data}. The
+client should call this function before calling
+@funcref{gnutls_handshake} and after calling
+@funcref{gnutls_session_set_data}.
+
+Note, however, that early data has weaker security properties than
+normal application data sent after handshake, such as lack of forward
+secrecy, no guarantees of non-replay between connections. Thus it is
+disabled on the server side by default. To enable it, the server
+needs to:
+@enumerate
+@item Set @acronym{GNUTLS_ENABLE_EARLY_DATA} on @funcref{gnutls_init}. Note that this option only has effect on server.
+
+@item Enable anti-replay measure. See @ref{Anti-replay protection} for the details.
+@end enumerate
+
+The server caches the received early data until it is read. To set the
+maximum amount of data to be stored in the cache, use
+@funcref{gnutls_record_set_max_early_data_size}. After receiving the
+EndOfEarlyData handshake message, the server can start retrieving the
+received data with @funcref{gnutls_record_recv_early_data}. You can
+call the function either after the handshake is complete, or through a
+handshake hook (@funcref{gnutls_handshake_set_hook_function}).
+
+On the client side, to check whether the sent early data was accepted by
+the server, use @funcref{gnutls_session_get_flags} and compare the
+result with @acronym{GNUTLS_SFLAGS_EARLY_DATA}. Similarly, on the
+server side, the same function and flag can be used to check whether it
+has actually accepted early data.
+
+
+@node Anti-replay protection
+@subsection Anti-replay protection
+
+When 0-RTT mode is used, the server must protect itself from replay
+attacks, where adversary client reuses duplicate session ticket to send
+early data, before the server authenticates the client.
+
+GnuTLS provides a simple mechanism against replay attacks, following the
+method called ClientHello recording. When a session ticket is accepted,
+the server checks if the ClientHello message has been already seen. If
+there is a duplicate, the server rejects early data.
+
+The problem of this approach is that the number of recorded messages
+grows indefinitely. To prevent that, the server can limit the recording
+to a certain time window, which can be configured with
+@funcref{gnutls_anti_replay_set_window}.
+
+The anti-replay mechanism shall be globally initialized with
+@funcref{gnutls_anti_replay_init}, and then attached to a session using
+@funcref{gnutls_anti_replay_enable}. It can be deinitialized with
+@funcref{gnutls_anti_replay_deinit}.
+
+The server must also set up a database back-end to store ClientHello
+messages. That can be achieved using
+@funcref{gnutls_db_set_add_function} (see @ref{Session resumption}).
+
+Note that, if the back-end stores arbitrary number of ClientHello, it
+needs to periodically clean up the stored entries based on the time
+window set with @funcref{gnutls_anti_replay_set_window}. The cleanup
+can be implemented by iterating through the database entries and calling
+@funcref{gnutls_db_check_entry_expire_time}. This is similar to session
+database cleanup used by TLS1.2 sessions.
+
+The full set up of the server using early data would be like the
+following example:
+@example
+#define MAX_EARLY_DATA_SIZE 16384
+
+static int
+db_add_func(void *dbf, gnutls_datum_t key, gnutls_datum_t data)
+@{
+ /* Return GNUTLS_E_DB_ENTRY_EXISTS, if KEY is found in the database.
+ * Otherwise, store it and return 0.
+ */
+@}
+
+static int
+handshake_hook_func(gnutls_session_t session, unsigned int htype,
+ unsigned when, unsigned int incoming, const gnutls_datum_t *msg)
+@{
+ int ret;
+ char buf[MAX_EARLY_DATA_SIZE];
+
+ assert(htype == GNUTLS_HANDSHAKE_END_OF_EARLY_DATA);
+ assert(when == GNUTLS_HOOK_POST);
+
+ if (gnutls_session_get_flags(session) & GNUTLS_SFLAGS_EARLY_DATA) @{
+ ret = gnutls_record_recv_early_data(session, buf, sizeof(buf));
+ assert(ret >= 0);
+ @}
+
+ return ret;
+@}
+
+int main()
+@{
+ ...
+ /* Initialize anti-replay measure, which can be shared
+ * among multiple sessions.
+ */
+ gnutls_anti_replay_init(&anti_replay);
+
+ ...
+
+ gnutls_init(&server, GNUTLS_SERVER | GNUTLS_ENABLE_EARLY_DATA);
+ gnutls_record_set_max_early_data_size(server, MAX_EARLY_DATA_SIZE);
+ ...
+
+ /* Set the database back-end function for the session.
+ */
+ gnutls_db_set_add_function(server, db_add_func);
+ ...
+
+ /* Set the anti-replay measure to the session.
+ */
+ gnutls_anti_replay_enable(server, anti_replay);
+ ...
+
+ /* Retrieve early data in a handshake hook;
+ * you can also do that after handshake.
+ */
+ gnutls_handshake_set_hook_function(server, GNUTLS_HANDSHAKE_END_OF_EARLY_DATA,
+ GNUTLS_HOOK_POST, handshake_hook_func);
+ ...
+@}
+@end example
+
+
@node DTLS sessions
@subsection DTLS sessions
@@ -1637,6 +1775,8 @@ static int
handshake_hook_func(gnutls_session_t session, unsigned int htype,
unsigned when, unsigned int incoming, const gnutls_datum_t *msg)
@{
+ int ret;
+
assert(htype == GNUTLS_HANDSHAKE_CLIENT_HELLO);
assert(when == GNUTLS_HOOK_PRE);
@@ -1645,6 +1785,8 @@ handshake_hook_func(gnutls_session_t session, unsigned int htype,
assert(ret >= 0);
gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, cred);
+
+ return ret;
@}
int main()
@@ -1708,7 +1850,7 @@ A storing server needs to specify callback functions to store, retrieve and dele
registered with the functions below. The stored sessions in the database can be checked using @funcref{gnutls_db_check_entry}
for expiration.
-@showfuncD{gnutls_db_set_retrieve_function,gnutls_db_set_store_function,gnutls_db_set_ptr,gnutls_db_set_remove_function}
+@showfuncE{gnutls_db_set_retrieve_function,gnutls_db_set_store_function,gnutls_db_set_ptr,gnutls_db_set_remove_function,gnutls_db_set_add_function}
@showfuncA{gnutls_db_check_entry}
A server supporting session tickets must generate ticket encryption
diff --git a/doc/manpages/Makefile.am b/doc/manpages/Makefile.am
index d0544a14d4..75c3aa7793 100644
--- a/doc/manpages/Makefile.am
+++ b/doc/manpages/Makefile.am
@@ -138,6 +138,10 @@ APIMANS += gnutls_anon_set_params_function.3
APIMANS += gnutls_anon_set_server_dh_params.3
APIMANS += gnutls_anon_set_server_known_dh_params.3
APIMANS += gnutls_anon_set_server_params_function.3
+APIMANS += gnutls_anti_replay_deinit.3
+APIMANS += gnutls_anti_replay_enable.3
+APIMANS += gnutls_anti_replay_init.3
+APIMANS += gnutls_anti_replay_set_window.3
APIMANS += gnutls_auth_client_get_type.3
APIMANS += gnutls_auth_get_type.3
APIMANS += gnutls_auth_server_get_type.3
@@ -240,10 +244,12 @@ APIMANS += gnutls_crypto_register_cipher.3
APIMANS += gnutls_crypto_register_digest.3
APIMANS += gnutls_crypto_register_mac.3
APIMANS += gnutls_db_check_entry.3
+APIMANS += gnutls_db_check_entry_expire_time.3
APIMANS += gnutls_db_check_entry_time.3
APIMANS += gnutls_db_get_default_cache_expiration.3
APIMANS += gnutls_db_get_ptr.3
APIMANS += gnutls_db_remove_session.3
+APIMANS += gnutls_db_set_add_function.3
APIMANS += gnutls_db_set_cache_expiration.3
APIMANS += gnutls_db_set_ptr.3
APIMANS += gnutls_db_set_remove_function.3
@@ -701,14 +707,17 @@ APIMANS += gnutls_record_disable_padding.3
APIMANS += gnutls_record_discard_queued.3
APIMANS += gnutls_record_get_direction.3
APIMANS += gnutls_record_get_discarded.3
+APIMANS += gnutls_record_get_max_early_data_size.3
APIMANS += gnutls_record_get_max_size.3
APIMANS += gnutls_record_get_state.3
APIMANS += gnutls_record_overhead_size.3
APIMANS += gnutls_record_recv.3
+APIMANS += gnutls_record_recv_early_data.3
APIMANS += gnutls_record_recv_packet.3
APIMANS += gnutls_record_recv_seq.3
APIMANS += gnutls_record_send.3
APIMANS += gnutls_record_send2.3
+APIMANS += gnutls_record_send_early_data.3
APIMANS += gnutls_record_send_range.3
APIMANS += gnutls_record_set_max_early_data_size.3
APIMANS += gnutls_record_set_max_size.3
diff --git a/lib/Makefile.am b/lib/Makefile.am
index e101ec68f2..32a8511b33 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -97,8 +97,10 @@ COBJECTS += tls13/encrypted_extensions.c tls13/encrypted_extensions.h \
tls13/hello_retry.c tls13/hello_retry.h \
tls13/session_ticket.c tls13/session_ticket.h \
tls13/certificate.c tls13/certificate.h \
+ tls13/early_data.c tls13/early_data.h \
tls13/post_handshake.c \
- tls13/psk_ext_parser.c tls13/psk_ext_parser.h
+ tls13/psk_ext_parser.c tls13/psk_ext_parser.h \
+ tls13/anti_replay.c tls13/anti_replay.h
if ENABLE_PKCS11
COBJECTS += pkcs11.c pkcs11x.c pkcs11_privkey.c pkcs11_write.c pkcs11_secret.c \
diff --git a/lib/constate.c b/lib/constate.c
index 456316258b..11fedab533 100644
--- a/lib/constate.c
+++ b/lib/constate.c
@@ -322,6 +322,61 @@ _tls13_update_keys(gnutls_session_t session, hs_stage_t stage,
}
static int
+_tls13_set_early_keys(gnutls_session_t session,
+ record_parameters_st * params,
+ unsigned iv_size, unsigned key_size)
+{
+ uint8_t key_block[MAX_CIPHER_KEY_SIZE];
+ uint8_t iv_block[MAX_CIPHER_IV_SIZE];
+ char buf[65];
+ record_state_st *early_state;
+ int ret;
+
+ if (session->security_parameters.entity == GNUTLS_CLIENT &&
+ !(session->internals.hsk_flags & HSK_TLS13_TICKET_SENT)) {
+ return GNUTLS_E_INVALID_REQUEST;
+ }
+
+ ret = _tls13_expand_secret(session, "key", 3, NULL, 0, session->key.proto.tls13.e_ckey, key_size, key_block);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+
+ ret = _tls13_expand_secret(session, "iv", 2, NULL, 0, session->key.proto.tls13.e_ckey, iv_size, iv_block);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+
+ if (session->security_parameters.entity == GNUTLS_CLIENT) {
+ early_state = &params->write;
+ } else {
+ early_state = &params->read;
+ }
+
+ early_state->mac_key_size = 0;
+
+ assert(key_size <= sizeof(early_state->key));
+ memcpy(early_state->key, key_block, key_size);
+ early_state->key_size = key_size;
+
+ _gnutls_hard_log("INT: EARLY KEY [%d]: %s\n",
+ key_size,
+ _gnutls_bin2hex(key_block, key_size,
+ buf, sizeof(buf), NULL));
+
+ if (iv_size > 0) {
+ assert(iv_size <= sizeof(early_state->iv));
+ memcpy(early_state->iv, iv_block, iv_size);
+ early_state->iv_size = iv_size;
+
+ _gnutls_hard_log("INT: EARLY IV [%d]: %s\n",
+ iv_size,
+ _gnutls_bin2hex(iv_block, iv_size,
+ buf, sizeof(buf), NULL));
+ }
+
+ return 0;
+}
+
+static int
_tls13_set_keys(gnutls_session_t session, hs_stage_t stage,
record_parameters_st * params,
unsigned iv_size, unsigned key_size)
@@ -342,7 +397,11 @@ _tls13_set_keys(gnutls_session_t session, hs_stage_t stage,
return _tls13_update_keys(session, stage,
params, iv_size, key_size);
- if (stage == STAGE_HS) {
+ else if (stage == STAGE_EARLY)
+ return _tls13_set_early_keys(session,
+ params, iv_size, key_size);
+
+ else if (stage == STAGE_HS) {
label = HANDSHAKE_CLIENT_TRAFFIC_LABEL;
label_size = sizeof(HANDSHAKE_CLIENT_TRAFFIC_LABEL)-1;
hsk_len = session->internals.handshake_hash_buffer.length;
@@ -551,13 +610,13 @@ _gnutls_set_cipher_suite2(gnutls_session_t session,
/* Sets the next epoch to be a clone of the current one.
* The keys are not cloned, only the cipher and MAC.
*/
-int _gnutls_epoch_dup(gnutls_session_t session)
+int _gnutls_epoch_dup(gnutls_session_t session, unsigned int epoch_rel)
{
record_parameters_st *prev;
record_parameters_st *next;
int ret;
- ret = _gnutls_epoch_get(session, EPOCH_READ_CURRENT, &prev);
+ ret = _gnutls_epoch_get(session, epoch_rel, &prev);
if (ret < 0)
return gnutls_assert_val(ret);
@@ -621,13 +680,19 @@ int _gnutls_epoch_set_keys(gnutls_session_t session, uint16_t epoch, hs_stage_t
if (ret < 0)
return gnutls_assert_val(ret);
- ret = _tls13_init_record_state(params->cipher->id, &params->read);
- if (ret < 0)
- return gnutls_assert_val(ret);
+ if (stage != STAGE_EARLY ||
+ session->security_parameters.entity == GNUTLS_SERVER) {
+ ret = _tls13_init_record_state(params->cipher->id, &params->read);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+ }
- ret = _tls13_init_record_state(params->cipher->id, &params->write);
- if (ret < 0)
- return gnutls_assert_val(ret);
+ if (stage != STAGE_EARLY ||
+ session->security_parameters.entity == GNUTLS_CLIENT) {
+ ret = _tls13_init_record_state(params->cipher->id, &params->write);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+ }
} else {
ret = _gnutls_set_keys
(session, params, hash_size, IV_size, key_size);
diff --git a/lib/constate.h b/lib/constate.h
index 125a48f8f2..f8e1480410 100644
--- a/lib/constate.h
+++ b/lib/constate.h
@@ -34,7 +34,7 @@ int _gnutls_write_connection_state_init(gnutls_session_t session);
#define _gnutls_epoch_bump(session) \
(session)->security_parameters.epoch_next++
-int _gnutls_epoch_dup(gnutls_session_t session);
+int _gnutls_epoch_dup(gnutls_session_t session, unsigned int epoch_rel);
int _gnutls_epoch_get(gnutls_session_t session, unsigned int epoch_rel,
record_parameters_st ** params_out);
diff --git a/lib/db.c b/lib/db.c
index a029f351cd..414816fcc8 100644
--- a/lib/db.c
+++ b/lib/db.c
@@ -30,6 +30,7 @@
#include <session_pack.h>
#include <datum.h>
#include "ext/server_name.h"
+#include <intprops.h>
/**
* gnutls_db_set_retrieve_function:
@@ -55,6 +56,29 @@ gnutls_db_set_retrieve_function(gnutls_session_t session,
}
/**
+ * gnutls_db_set_add_function:
+ * @session: is a #gnutls_session_t type.
+ * @add_func: is the function.
+ *
+ * Sets the function that will be used to store an entry if it is not
+ * already present in the resumed sessions database. This function returns 0
+ * if the entry is successfully stored, and a negative error code
+ * otherwise. In particular, if the entry is found in the database,
+ * it returns %GNUTLS_E_DB_ENTRY_EXISTS.
+ *
+ * The first argument to @add_func will be null unless
+ * gnutls_db_set_ptr() has been called.
+ *
+ * Since: 3.6.5
+ **/
+void
+gnutls_db_set_add_function(gnutls_session_t session,
+ gnutls_db_add_func add_func)
+{
+ session->internals.db_add_func = add_func;
+}
+
+/**
* gnutls_db_set_remove_function:
* @session: is a #gnutls_session_t type.
* @rem_func: is the function.
@@ -155,6 +179,8 @@ unsigned gnutls_db_get_default_cache_expiration(void)
*
* Returns: Returns %GNUTLS_E_EXPIRED, if the database entry has
* expired or 0 otherwise.
+ *
+ * Deprecated: This function is deprecated.
**/
int
gnutls_db_check_entry(gnutls_session_t session,
@@ -166,7 +192,6 @@ gnutls_db_check_entry(gnutls_session_t session,
/**
* gnutls_db_check_entry_time:
* @entry: is a pointer to a #gnutls_datum_t type.
- * @t: is the time of the session handshake
*
* This function returns the time that this entry was active.
* It can be used for database entry expiration.
@@ -191,6 +216,40 @@ time_t gnutls_db_check_entry_time(gnutls_datum_t * entry)
return t;
}
+/**
+ * gnutls_db_check_entry_expire_time:
+ * @entry: is a pointer to a #gnutls_datum_t type.
+ *
+ * This function returns the time that this entry will expire.
+ * It can be used for database entry expiration.
+ *
+ * Returns: The time this entry will expire, or zero on error.
+ *
+ * Since: 3.6.5
+ **/
+time_t gnutls_db_check_entry_expire_time(gnutls_datum_t *entry)
+{
+ uint32_t t;
+ uint32_t e;
+ uint32_t magic;
+
+ if (entry->size < 12)
+ return gnutls_assert_val(0);
+
+ magic = _gnutls_read_uint32(entry->data);
+
+ if (magic != PACKED_SESSION_MAGIC)
+ return gnutls_assert_val(0);
+
+ t = _gnutls_read_uint32(&entry->data[4]);
+ e = _gnutls_read_uint32(&entry->data[8]);
+
+ if (INT_ADD_OVERFLOW(t, e))
+ return gnutls_assert_val(0);
+
+ return t + e;
+}
+
/* Checks if both db_store and db_retrieve functions have
* been set up.
*/
diff --git a/lib/errors.c b/lib/errors.c
index e579f46852..acdaf65bca 100644
--- a/lib/errors.c
+++ b/lib/errors.c
@@ -193,6 +193,7 @@ static const gnutls_error_entry error_entries[] = {
("TLS Application data were received, while expecting handshake data."),
GNUTLS_E_GOT_APPLICATION_DATA),
ERROR_ENTRY(N_("Error in Database backend."), GNUTLS_E_DB_ERROR),
+ ERROR_ENTRY(N_("The Database entry already exists."), GNUTLS_E_DB_ENTRY_EXISTS),
ERROR_ENTRY(N_("The certificate type is not supported."),
GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE),
ERROR_ENTRY(N_
@@ -430,6 +431,8 @@ static const gnutls_error_entry error_entries[] = {
GNUTLS_E_INSUFFICIENT_SECURITY),
ERROR_ENTRY(N_("No common key share with peer."),
GNUTLS_E_NO_COMMON_KEY_SHARE),
+ ERROR_ENTRY(N_("The early data were rejected."),
+ GNUTLS_E_EARLY_DATA_REJECTED),
{NULL, NULL, 0}
};
diff --git a/lib/ext/early_data.c b/lib/ext/early_data.c
index daa0d8fcb7..a58e473ae1 100644
--- a/lib/ext/early_data.c
+++ b/lib/ext/early_data.c
@@ -39,7 +39,7 @@ const hello_ext_entry_st ext_mod_early_data = {
.name = "Early Data",
.tls_id = 42,
.gid = GNUTLS_EXTENSION_EARLY_DATA,
- .validity = GNUTLS_EXT_FLAG_TLS | GNUTLS_EXT_FLAG_CLIENT_HELLO,
+ .validity = GNUTLS_EXT_FLAG_TLS | GNUTLS_EXT_FLAG_CLIENT_HELLO | GNUTLS_EXT_FLAG_EE,
.parse_type = GNUTLS_EXT_MANDATORY, /* force parsing prior to EXT_TLS extensions */
.recv_func = early_data_recv_params,
.send_func = early_data_send_params,
@@ -54,10 +54,23 @@ early_data_recv_params(gnutls_session_t session,
const uint8_t * data, size_t _data_size)
{
const version_entry_st *vers = get_version(session);
+
if (!vers || !vers->tls13_sem)
return gnutls_assert_val(0);
- if (session->security_parameters.entity == GNUTLS_SERVER)
+
+ if (session->security_parameters.entity == GNUTLS_SERVER) {
+ /* The flag may be cleared by pre_shared_key
+ * extension, when replay is detected. */
+ if ((session->internals.flags & GNUTLS_ENABLE_EARLY_DATA) &&
+ /* Refuse early data when this is a second CH after HRR */
+ !(session->internals.hsk_flags & HSK_HRR_SENT))
+ session->internals.hsk_flags |= HSK_EARLY_DATA_ACCEPTED;
+
session->internals.hsk_flags |= HSK_EARLY_DATA_IN_FLIGHT;
+ } else {
+ if (_gnutls_ext_get_msg(session) == GNUTLS_EXT_FLAG_EE)
+ session->internals.hsk_flags |= HSK_EARLY_DATA_ACCEPTED;
+ }
return 0;
}
@@ -68,10 +81,39 @@ static int
early_data_send_params(gnutls_session_t session,
gnutls_buffer_st * extdata)
{
+ if (session->security_parameters.entity == GNUTLS_SERVER) {
+ if (session->internals.hsk_flags & HSK_EARLY_DATA_ACCEPTED)
+ return GNUTLS_E_INT_RET_0;
+ } else {
+ if (session->internals.early_data_presend_buffer.length > 0) {
+ session->internals.hsk_flags |= HSK_EARLY_DATA_IN_FLIGHT;
+ return GNUTLS_E_INT_RET_0;
+ }
+ }
+
return 0;
}
/**
+ * gnutls_record_get_max_early_data_size:
+ * @session: is a #gnutls_session_t type.
+ *
+ * This function returns the maximum early data size in this connection.
+ * This property can only be set to servers. The client may be
+ * provided with the maximum allowed size through the "early_data"
+ * extension of the NewSessionTicket handshake message.
+ *
+ * Returns: The maximum early data size in this connection.
+ *
+ * Since: 3.6.5
+ **/
+size_t
+gnutls_record_get_max_early_data_size(gnutls_session_t session)
+{
+ return session->security_parameters.max_early_data_size;
+}
+
+/**
* gnutls_record_set_max_early_data_size:
* @session: is a #gnutls_session_t type.
* @size: is the new size
@@ -93,7 +135,8 @@ gnutls_record_set_max_early_data_size(gnutls_session_t session,
if (session->security_parameters.entity == GNUTLS_CLIENT)
return GNUTLS_E_INVALID_REQUEST;
- if (size > UINT32_MAX)
+ /* Reject zero as well, as it is useless. */
+ if (size == 0 || size > UINT32_MAX)
return GNUTLS_E_INVALID_REQUEST;
session->security_parameters.max_early_data_size = (uint32_t) size;
diff --git a/lib/ext/pre_shared_key.c b/lib/ext/pre_shared_key.c
index be18c264ff..bc7fc8aa95 100644
--- a/lib/ext/pre_shared_key.c
+++ b/lib/ext/pre_shared_key.c
@@ -23,7 +23,9 @@
#include "gnutls_int.h"
#include "auth/psk.h"
+#include "handshake.h"
#include "secrets.h"
+#include "tls13/anti_replay.h"
#include "tls13/psk_ext_parser.h"
#include "tls13/finished.h"
#include "tls13/session_ticket.h"
@@ -36,7 +38,6 @@ static int
compute_psk_from_ticket(const tls13_ticket_st *ticket, gnutls_datum_t *key)
{
int ret;
- char label[] = "resumption";
if (unlikely(ticket->prf == NULL || ticket->prf->output_size == 0))
return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
@@ -49,7 +50,7 @@ compute_psk_from_ticket(const tls13_ticket_st *ticket, gnutls_datum_t *key)
key->size = ticket->prf->output_size;
ret = _tls13_expand_secret2(ticket->prf,
- label, sizeof(label)-1,
+ RESUMPTION_LABEL, sizeof(RESUMPTION_LABEL)-1,
ticket->nonce, ticket->nonce_size,
ticket->resumption_master_secret,
key->size,
@@ -67,9 +68,9 @@ compute_binder_key(const mac_entry_st *prf,
void *out)
{
int ret;
- const char ext_label[] = "ext binder";
+ const char ext_label[] = EXT_BINDER_LABEL;
const size_t ext_label_len = sizeof(ext_label) - 1;
- const char res_label[] = "res binder";
+ const char res_label[] = RES_BINDER_LABEL;
const size_t res_label_len = sizeof(res_label) - 1;
const char *label = resuming ? res_label : ext_label;
size_t label_len = resuming ? res_label_len : ext_label_len;
@@ -482,7 +483,9 @@ static int server_recv_params(gnutls_session_t session,
struct psk_st psk;
psk_auth_info_t info;
tls13_ticket_st ticket_data;
- uint32_t ticket_age;
+ /* These values should be set properly when session ticket is accepted. */
+ uint32_t ticket_age = UINT32_MAX;
+ struct timespec ticket_creation_time = { 0, 0 };
bool resuming;
ret = _gnutls13_psk_ext_parser_init(&psk_parser, data, len);
@@ -526,6 +529,10 @@ static int server_recv_params(gnutls_session_t session,
continue;
}
+ memcpy(&ticket_creation_time,
+ &ticket_data.creation_time,
+ sizeof(struct timespec));
+
tls13_ticket_deinit(&ticket_data);
resuming = 1;
@@ -612,6 +619,24 @@ static int server_recv_params(gnutls_session_t session,
info->username[psk.identity.size] = 0;
_gnutls_handshake_log("EXT[%p]: selected PSK identity: %s (%d)\n", session, info->username, psk_index);
} else {
+ if (session->internals.hsk_flags & HSK_EARLY_DATA_ACCEPTED) {
+ if (session->internals.anti_replay) {
+ ret = _gnutls_anti_replay_check(session,
+ ticket_age,
+ &ticket_creation_time,
+ &binder_recvd);
+ if (ret < 0) {
+ session->internals.hsk_flags &= ~HSK_EARLY_DATA_ACCEPTED;
+ _gnutls_handshake_log("EXT[%p]: replay detected; rejecting early data\n",
+ session);
+ }
+ } else {
+ _gnutls_handshake_log("EXT[%p]: anti-replay is not enabled; rejecting early data\n",
+ session);
+ session->internals.hsk_flags &= ~HSK_EARLY_DATA_ACCEPTED;
+ }
+ }
+
session->internals.resumed = RESUME_TRUE;
_gnutls_handshake_log("EXT[%p]: selected resumption PSK identity (%d)\n", session, psk_index);
}
diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h
index 3eece0278f..e34bea85b8 100644
--- a/lib/gnutls_int.h
+++ b/lib/gnutls_int.h
@@ -169,7 +169,8 @@ typedef enum hs_stage_t {
STAGE_HS,
STAGE_APP,
STAGE_UPD_OURS,
- STAGE_UPD_PEERS
+ STAGE_UPD_PEERS,
+ STAGE_EARLY
} hs_stage_t;
typedef enum record_send_state_t {
@@ -272,7 +273,7 @@ typedef enum handshake_state_t { STATE0 = 0, STATE1, STATE2,
STATE90=90, STATE91, STATE92, STATE93, STATE94, STATE99=99,
STATE100=100, STATE101, STATE102, STATE103, STATE104,
STATE105, STATE106, STATE107, STATE108, STATE109, STATE110,
- STATE111, STATE112, STATE113, STATE114,
+ STATE111, STATE112, STATE113, STATE114, STATE115,
STATE150 /* key update */
} handshake_state_t;
@@ -538,6 +539,7 @@ struct gnutls_key_st {
* early_secret, client_early_traffic_secret, ... */
uint8_t temp_secret[MAX_HASH_SIZE];
unsigned temp_secret_size; /* depends on negotiated PRF size */
+ uint8_t e_ckey[MAX_HASH_SIZE]; /* client_early_traffic_secret */
uint8_t hs_ckey[MAX_HASH_SIZE]; /* client_hs_traffic_secret */
uint8_t hs_skey[MAX_HASH_SIZE]; /* server_hs_traffic_secret */
uint8_t ap_ckey[MAX_HASH_SIZE]; /* client_ap_traffic_secret */
@@ -1013,6 +1015,7 @@ typedef struct gnutls_dh_params_int {
*/
typedef struct {
struct timespec arrival_time;
+ struct timespec creation_time;
uint32_t lifetime;
uint32_t age_add;
uint8_t nonce[255];
@@ -1072,6 +1075,7 @@ typedef struct {
int handshake_hash_buffer_prev_len; /* keeps the length of handshake_hash_buffer, excluding
* the last received message */
+ unsigned handshake_hash_buffer_client_hello_len; /* if non-zero it is the length of data until the client hello message */
unsigned handshake_hash_buffer_client_kx_len;/* if non-zero it is the length of data until the
* the client key exchange message */
unsigned handshake_hash_buffer_server_finished_len;/* if non-zero it is the length of data until the
@@ -1159,6 +1163,9 @@ typedef struct {
* send.
*/
+ mbuffer_head_st early_data_recv_buffer;
+ gnutls_buffer_st early_data_presend_buffer;
+
record_send_state_t rsend_state;
/* buffer used temporarily during key update */
gnutls_buffer_st record_key_update_buffer;
@@ -1209,6 +1216,7 @@ typedef struct {
gnutls_db_store_func db_store_func;
gnutls_db_retr_func db_retrieve_func;
gnutls_db_remove_func db_remove_func;
+ gnutls_db_add_func db_add_func;
void *db_ptr;
/* post client hello callback (server side only)
@@ -1341,8 +1349,13 @@ typedef struct {
*/
#define HSK_TICKET_RECEIVED (1<<20) /* client: a session ticket was received */
#define HSK_EARLY_START_USED (1<<21)
-#define HSK_EARLY_DATA_IN_FLIGHT (1<<22) /* server: early_data extension was seen in ClientHello */
-#define HSK_RECORD_SIZE_LIMIT_NEGOTIATED (1<<23)
+#define HSK_EARLY_DATA_IN_FLIGHT (1<<22) /* client: sent early_data extension in ClientHello
+ * server: early_data extension was seen in ClientHello
+ */
+#define HSK_EARLY_DATA_ACCEPTED (1<<23) /* client: early_data extension was seen in EncryptedExtensions
+ * server: intend to process early data
+ */
+#define HSK_RECORD_SIZE_LIMIT_NEGOTIATED (1<<24)
/* The hsk_flags are for use within the ongoing handshake;
* they are reset to zero prior to handshake start by gnutls_handshake. */
@@ -1447,6 +1460,9 @@ typedef struct {
/* the amount of early data received so far */
uint32_t early_data_received;
+ /* anti-replay measure for 0-RTT mode */
+ gnutls_anti_replay_t anti_replay;
+
/* If you add anything here, check _gnutls_handshake_internal_state_clear().
*/
} internals_st;
diff --git a/lib/handshake-tls13.c b/lib/handshake-tls13.c
index 5fed553310..fedef6cbbc 100644
--- a/lib/handshake-tls13.c
+++ b/lib/handshake-tls13.c
@@ -52,12 +52,13 @@
#include "tls13/certificate_request.h"
#include "tls13/certificate_verify.h"
#include "tls13/certificate.h"
+#include "tls13/early_data.h"
#include "tls13/finished.h"
#include "tls13/key_update.h"
#include "ext/pre_shared_key.h"
static int generate_rms_keys(gnutls_session_t session);
-static int generate_and_set_hs_traffic_keys(gnutls_session_t session);
+static int generate_hs_traffic_keys(gnutls_session_t session);
static int generate_ap_traffic_keys(gnutls_session_t session);
#define SAVE_TRANSCRIPT \
@@ -90,59 +91,99 @@ int _gnutls13_handshake_client(gnutls_session_t session)
#endif
FALLTHROUGH;
case STATE101:
- ret =
- generate_and_set_hs_traffic_keys(session);
- STATE = STATE101;
- IMED_RET_FATAL("generate session keys", ret, 0);
+ /* Note that we check IN_FLIGHT, not ACCEPTED
+ * here. This is because the client sends early data
+ * speculatively. */
+ if (session->internals.hsk_flags & HSK_EARLY_DATA_IN_FLIGHT) {
+ ret = _tls13_write_connection_state_init(session, STAGE_EARLY);
+ if (ret == 0) {
+ _gnutls_epoch_bump(session);
+ ret = _gnutls_epoch_dup(session, EPOCH_WRITE_CURRENT);
+ }
+ STATE = STATE101;
+ IMED_RET_FATAL("set early traffic keys", ret, 0);
+ }
FALLTHROUGH;
case STATE102:
- ret = _gnutls13_recv_encrypted_extensions(session);
+ ret = _gnutls13_send_early_data(session);
STATE = STATE102;
- IMED_RET("recv encrypted extensions", ret, 0);
+ IMED_RET("send early data", ret, 0);
FALLTHROUGH;
case STATE103:
- ret = _gnutls13_recv_certificate_request(session);
STATE = STATE103;
- IMED_RET("recv certificate request", ret, 0);
+ ret = generate_hs_traffic_keys(session);
+ /* Note that we check IN_FLIGHT, not ACCEPTED
+ * here. This is because the client sends early data
+ * speculatively. */
+ IMED_RET_FATAL("generate hs traffic keys", ret, 0);
+ if (session->internals.hsk_flags & HSK_EARLY_DATA_IN_FLIGHT)
+ ret = _tls13_read_connection_state_init(session, STAGE_HS);
+ else
+ ret = _tls13_connection_state_init(session, STAGE_HS);
+ IMED_RET_FATAL("set hs traffic keys", ret, 0);
FALLTHROUGH;
case STATE104:
- ret = _gnutls13_recv_certificate(session);
+ ret = _gnutls13_recv_encrypted_extensions(session);
STATE = STATE104;
- IMED_RET("recv certificate", ret, 0);
+ IMED_RET("recv encrypted extensions", ret, 0);
FALLTHROUGH;
case STATE105:
- ret = _gnutls13_recv_certificate_verify(session);
+ ret = _gnutls13_recv_certificate_request(session);
STATE = STATE105;
- IMED_RET("recv server certificate verify", ret, 0);
+ IMED_RET("recv certificate request", ret, 0);
FALLTHROUGH;
case STATE106:
- ret = _gnutls_run_verify_callback(session, GNUTLS_CLIENT);
+ ret = _gnutls13_recv_certificate(session);
STATE = STATE106;
- if (ret < 0)
- return gnutls_assert_val(ret);
+ IMED_RET("recv certificate", ret, 0);
FALLTHROUGH;
case STATE107:
- ret = _gnutls13_recv_finished(session);
+ ret = _gnutls13_recv_certificate_verify(session);
STATE = STATE107;
- IMED_RET("recv finished", ret, 0);
+ IMED_RET("recv server certificate verify", ret, 0);
FALLTHROUGH;
case STATE108:
- ret = _gnutls13_send_certificate(session, AGAIN(STATE108));
+ ret = _gnutls_run_verify_callback(session, GNUTLS_CLIENT);
STATE = STATE108;
- IMED_RET("send certificate", ret, 0);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
FALLTHROUGH;
case STATE109:
- ret = _gnutls13_send_certificate_verify(session, AGAIN(STATE109));
+ ret = _gnutls13_recv_finished(session);
STATE = STATE109;
- IMED_RET("send certificate verify", ret, 0);
+ IMED_RET("recv finished", ret, 0);
FALLTHROUGH;
case STATE110:
- ret = _gnutls13_send_finished(session, AGAIN(STATE110));
+ ret = _gnutls13_send_end_of_early_data(session, AGAIN(STATE110));
STATE = STATE110;
- IMED_RET("send finished", ret, 0);
+ IMED_RET("send end of early data", ret, 0);
+
+ /* Note that we check IN_FLIGHT, not ACCEPTED
+ * here. This is because the client sends early data
+ * speculatively. */
+ if (session->internals.hsk_flags & HSK_EARLY_DATA_IN_FLIGHT) {
+ session->internals.hsk_flags &= ~HSK_EARLY_DATA_IN_FLIGHT;
+ ret = _tls13_write_connection_state_init(session, STAGE_HS);
+ IMED_RET_FATAL("set hs traffic key after sending early data", ret, 0);
+ }
FALLTHROUGH;
case STATE111:
+ ret = _gnutls13_send_certificate(session, AGAIN(STATE111));
STATE = STATE111;
+ IMED_RET("send certificate", ret, 0);
+ FALLTHROUGH;
+ case STATE112:
+ ret = _gnutls13_send_certificate_verify(session, AGAIN(STATE112));
+ STATE = STATE112;
+ IMED_RET("send certificate verify", ret, 0);
+ FALLTHROUGH;
+ case STATE113:
+ ret = _gnutls13_send_finished(session, AGAIN(STATE113));
+ STATE = STATE113;
+ IMED_RET("send finished", ret, 0);
+ FALLTHROUGH;
+ case STATE114:
+ STATE = STATE114;
ret =
generate_ap_traffic_keys(session);
@@ -255,14 +296,14 @@ static int generate_ap_traffic_keys(gnutls_session_t session)
session->security_parameters.prf->output_size);
_gnutls_epoch_bump(session);
- ret = _gnutls_epoch_dup(session);
+ ret = _gnutls_epoch_dup(session, EPOCH_READ_CURRENT);
if (ret < 0)
return gnutls_assert_val(ret);
return 0;
}
-static int generate_and_set_hs_traffic_keys(gnutls_session_t session)
+static int generate_hs_traffic_keys(gnutls_session_t session)
{
int ret;
unsigned null_key = 0;
@@ -270,6 +311,14 @@ static int generate_and_set_hs_traffic_keys(gnutls_session_t session)
if (unlikely(session->key.proto.tls13.temp_secret_size == 0))
return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
+ ret = _tls13_derive_secret(session, DERIVED_LABEL, sizeof(DERIVED_LABEL)-1,
+ NULL, 0, session->key.proto.tls13.temp_secret,
+ session->key.proto.tls13.temp_secret);
+ if (ret < 0) {
+ gnutls_assert();
+ return ret;
+ }
+
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) &&
@@ -309,12 +358,6 @@ static int generate_and_set_hs_traffic_keys(gnutls_session_t session)
}
}
- ret = _tls13_connection_state_init(session, STAGE_HS);
- if (ret < 0) {
- gnutls_assert();
- return ret;
- }
-
return 0;
}
@@ -380,10 +423,26 @@ int _gnutls13_handshake_server(gnutls_session_t session)
#endif
FALLTHROUGH;
case STATE101:
- ret =
- generate_and_set_hs_traffic_keys(session);
STATE = STATE101;
- IMED_RET_FATAL("generate session keys", ret, 0);
+ if (session->internals.hsk_flags & HSK_EARLY_DATA_ACCEPTED) {
+ ret = _tls13_read_connection_state_init(session, STAGE_EARLY);
+ if (ret == 0) {
+ _gnutls_epoch_bump(session);
+ ret = _gnutls_epoch_dup(session, EPOCH_READ_CURRENT);
+ }
+ IMED_RET_FATAL("set early traffic keys", ret, 0);
+
+ ret = generate_hs_traffic_keys(session);
+ IMED_RET_FATAL("generate hs traffic keys", ret, 0);
+
+ ret = _tls13_write_connection_state_init(session, STAGE_HS);
+ } else {
+ ret = generate_hs_traffic_keys(session);
+ IMED_RET_FATAL("generate hs traffic keys", ret, 0);
+
+ ret = _tls13_connection_state_init(session, STAGE_HS);
+ }
+ IMED_RET_FATAL("set hs traffic keys", ret, 0);
FALLTHROUGH;
case STATE102:
ret = _gnutls13_send_encrypted_extensions(session, AGAIN(STATE102));
@@ -411,6 +470,16 @@ int _gnutls13_handshake_server(gnutls_session_t session)
IMED_RET("send finished", ret, 0);
FALLTHROUGH;
case STATE107:
+ ret = _gnutls13_recv_end_of_early_data(session);
+ STATE = STATE107;
+ IMED_RET("recv end of early data", ret, 0);
+
+ if (session->internals.hsk_flags & HSK_EARLY_DATA_ACCEPTED) {
+ ret = _tls13_read_connection_state_init(session, STAGE_HS);
+ IMED_RET_FATAL("set hs traffic key after receiving early data", ret, 0);
+ }
+ FALLTHROUGH;
+ case STATE108:
/* At this point our sending keys should be the app keys
* see 4.4.4 at draft-ietf-tls-tls13-28 */
ret =
@@ -420,7 +489,7 @@ int _gnutls13_handshake_server(gnutls_session_t session)
/* If the session is unauthenticated, try to optimize the handshake by
* sending the session ticket early. */
if (!(session->internals.hsk_flags & (HSK_CRT_REQ_SENT|HSK_PSK_SELECTED))) {
- STATE = STATE107;
+ STATE = STATE108;
ret = generate_non_auth_rms_keys(session);
IMED_RET_FATAL("generate rms keys", ret, 0);
@@ -435,15 +504,15 @@ int _gnutls13_handshake_server(gnutls_session_t session)
_gnutls_handshake_log("HSK[%p]: switching early to application traffic keys\n", session);
FALLTHROUGH;
- case STATE108:
+ case STATE109:
if (session->internals.resumed != RESUME_FALSE)
_gnutls_set_resumed_parameters(session);
if (session->internals.hsk_flags & HSK_EARLY_START_USED) {
ret = _gnutls13_send_session_ticket(session, TICKETS_TO_SEND,
- AGAIN(STATE108));
+ AGAIN(STATE109));
- STATE = STATE108;
+ STATE = STATE109;
IMED_RET("send session ticket", ret, 0);
/* complete this phase of the handshake. We
@@ -451,7 +520,7 @@ int _gnutls13_handshake_server(gnutls_session_t session)
*/
if (session->internals.flags & GNUTLS_ENABLE_EARLY_START) {
- STATE = STATE112; /* finished */
+ STATE = STATE113; /* finished */
gnutls_assert();
session->internals.recv_state = RECV_STATE_EARLY_START;
@@ -459,31 +528,31 @@ int _gnutls13_handshake_server(gnutls_session_t session)
}
}
FALLTHROUGH;
- case STATE109:
+ case STATE110:
ret = _gnutls13_recv_certificate(session);
- STATE = STATE109;
+ STATE = STATE110;
IMED_RET("recv certificate", ret, 0);
FALLTHROUGH;
- case STATE110:
+ case STATE111:
ret = _gnutls13_recv_certificate_verify(session);
- STATE = STATE110;
+ STATE = STATE111;
IMED_RET("recv certificate verify", ret, 0);
FALLTHROUGH;
- case STATE111:
+ case STATE112:
ret = _gnutls_run_verify_callback(session, GNUTLS_CLIENT);
- STATE = STATE111;
+ STATE = STATE112;
if (ret < 0)
return gnutls_assert_val(ret);
FALLTHROUGH;
- case STATE112: /* can enter from STATE108 */
+ case STATE113: /* can enter from STATE109 */
ret = _gnutls13_recv_finished(session);
- STATE = STATE112;
+ STATE = STATE113;
IMED_RET("recv finished", ret, 0);
FALLTHROUGH;
- case STATE113:
+ case STATE114:
/* If we did request a client certificate, then we can
* only send the tickets here */
- STATE = STATE113;
+ STATE = STATE114;
if (!(session->internals.hsk_flags & HSK_EARLY_START_USED)) {
ret = generate_rms_keys(session);
@@ -494,11 +563,11 @@ int _gnutls13_handshake_server(gnutls_session_t session)
IMED_RET_FATAL("set read app keys", ret, 0);
FALLTHROUGH;
- case STATE114:
+ case STATE115:
if (!(session->internals.hsk_flags & (HSK_TLS13_TICKET_SENT|HSK_EARLY_START_USED))) {
ret = _gnutls13_send_session_ticket(session, TICKETS_TO_SEND,
- AGAIN(STATE114));
- STATE = STATE114;
+ AGAIN(STATE115));
+ STATE = STATE115;
IMED_RET("send session ticket", ret, 0);
}
diff --git a/lib/handshake.c b/lib/handshake.c
index a20c7a302a..5080756c28 100644
--- a/lib/handshake.c
+++ b/lib/handshake.c
@@ -80,6 +80,7 @@ handshake_hash_buffer_reset(gnutls_session_t session)
{
_gnutls_buffers_log("BUF[HSK]: Emptied buffer\n");
+ session->internals.handshake_hash_buffer_client_hello_len = 0;
session->internals.handshake_hash_buffer_client_kx_len = 0;
session->internals.handshake_hash_buffer_server_finished_len = 0;
session->internals.handshake_hash_buffer_client_finished_len = 0;
@@ -1408,6 +1409,9 @@ handshake_hash_add_recvd(gnutls_session_t session,
/* save the size until client KX. That is because the TLS
* session hash is calculated up to this message.
*/
+ if (recv_type == GNUTLS_HANDSHAKE_CLIENT_HELLO)
+ session->internals.handshake_hash_buffer_client_hello_len =
+ session->internals.handshake_hash_buffer.length;
if (recv_type == GNUTLS_HANDSHAKE_CLIENT_KEY_EXCHANGE)
session->internals.handshake_hash_buffer_client_kx_len =
session->internals.handshake_hash_buffer.length;
@@ -1459,6 +1463,9 @@ handshake_hash_add_sent(gnutls_session_t session,
if (ret < 0)
return gnutls_assert_val(ret);
+ if (type == GNUTLS_HANDSHAKE_CLIENT_HELLO)
+ session->internals.handshake_hash_buffer_client_hello_len =
+ session->internals.handshake_hash_buffer.length;
if (type == GNUTLS_HANDSHAKE_CLIENT_KEY_EXCHANGE)
session->internals.handshake_hash_buffer_client_kx_len =
session->internals.handshake_hash_buffer.length;
@@ -1613,6 +1620,7 @@ _gnutls_recv_handshake(gnutls_session_t session,
case GNUTLS_HANDSHAKE_CERTIFICATE_VERIFY:
case GNUTLS_HANDSHAKE_SUPPLEMENTAL:
case GNUTLS_HANDSHAKE_NEW_SESSION_TICKET:
+ case GNUTLS_HANDSHAKE_END_OF_EARLY_DATA:
ret = hsk.data.length;
break;
default:
@@ -1776,6 +1784,26 @@ no_resume:
}
+static int generate_early_traffic_secret(gnutls_session_t session,
+ const mac_entry_st *prf)
+{
+ int ret;
+
+ ret = _tls13_derive_secret2(prf, EARLY_TRAFFIC_LABEL, sizeof(EARLY_TRAFFIC_LABEL)-1,
+ session->internals.handshake_hash_buffer.data,
+ session->internals.handshake_hash_buffer_client_hello_len,
+ session->key.proto.tls13.temp_secret,
+ session->key.proto.tls13.e_ckey);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+
+ _gnutls_nss_keylog_write(session, "CLIENT_EARLY_TRAFFIC_SECRET",
+ session->key.proto.tls13.e_ckey,
+ prf->output_size);
+
+ return 0;
+}
+
/* This function reads and parses the server hello handshake message.
* This function also restores resumed parameters if we are resuming a
* session.
@@ -1964,7 +1992,8 @@ read_server_hello(gnutls_session_t session,
return gnutls_assert_val(ret);
/* Calculate TLS 1.3 Early Secret */
- if (vers->tls13_sem) {
+ if (vers->tls13_sem &&
+ !(session->internals.hsk_flags & HSK_EARLY_DATA_IN_FLIGHT)) {
if (session->internals.hsk_flags & HSK_PSK_SELECTED) {
psk = session->key.binders[0].psk.data;
psk_size = session->key.binders[0].psk.size;
@@ -1976,15 +2005,7 @@ read_server_hello(gnutls_session_t session,
ret = _tls13_init_secret(session, psk, psk_size);
if (ret < 0) {
gnutls_assert();
- goto cleanup;
- }
-
- ret = _tls13_derive_secret(session, DERIVED_LABEL, sizeof(DERIVED_LABEL)-1,
- NULL, 0, session->key.proto.tls13.temp_secret,
- session->key.proto.tls13.temp_secret);
- if (ret < 0) {
- gnutls_assert();
- goto cleanup;
+ return ret;
}
}
@@ -2020,6 +2041,56 @@ append_null_comp(gnutls_session_t session,
return ret;
}
+/* Calculate TLS 1.3 Early Secret and client_early_traffic_secret,
+ * assuming that the PSK we offer will be accepted by the server */
+static int
+generate_early_traffic_secret_from_ticket(gnutls_session_t session)
+{
+ int ret = 0;
+ const uint8_t *psk;
+ size_t psk_size;
+ const mac_entry_st *prf;
+
+ if (!(session->internals.hsk_flags & HSK_TLS13_TICKET_SENT)) {
+ ret = GNUTLS_E_INVALID_REQUEST;
+ gnutls_assert();
+ goto cleanup;
+ }
+
+ psk = session->key.binders[0].psk.data;
+ psk_size = session->key.binders[0].psk.size;
+ prf = session->key.binders[0].prf;
+
+ if (psk_size == 0) {
+ ret = GNUTLS_E_INVALID_REQUEST;
+ gnutls_assert();
+ goto cleanup;
+ }
+
+ ret = _tls13_init_secret2(prf, psk, psk_size,
+ session->key.proto.tls13.temp_secret);
+ if (ret < 0) {
+ gnutls_assert();
+ goto cleanup;
+ }
+ session->key.proto.tls13.temp_secret_size = prf->output_size;
+
+ ret = generate_early_traffic_secret(session, prf);
+ if (ret < 0) {
+ gnutls_assert();
+ goto cleanup;
+ }
+
+ return ret;
+
+ cleanup:
+ /* If any of the above calculation fails, we are not going to
+ * send early data. */
+ session->internals.hsk_flags &= ~HSK_EARLY_DATA_IN_FLIGHT;
+
+ return ret;
+}
+
/* This function sends the client hello handshake message.
*/
static int send_client_hello(gnutls_session_t session, int again)
@@ -2231,9 +2302,10 @@ static int send_client_hello(gnutls_session_t session, int again)
bufel = _gnutls_buffer_to_mbuffer(&extdata);
}
- return
- _gnutls_send_handshake(session, bufel,
- GNUTLS_HANDSHAKE_CLIENT_HELLO);
+ ret = _gnutls_send_handshake(session, bufel,
+ GNUTLS_HANDSHAKE_CLIENT_HELLO);
+
+ return ret;
cleanup:
_gnutls_buffer_clear(&extdata);
@@ -2253,6 +2325,7 @@ int _gnutls_send_server_hello(gnutls_session_t session, int again)
unsigned extflag = 0;
const uint8_t *psk = NULL;
size_t psk_size = 0;
+ const mac_entry_st *prf = session->security_parameters.prf;
gnutls_ext_parse_type_t etype;
_gnutls_buffer_init(&buf);
@@ -2267,6 +2340,7 @@ int _gnutls_send_server_hello(gnutls_session_t session, int again)
if (session->internals.hsk_flags & HSK_PSK_SELECTED) {
psk = session->key.binders[0].psk.data;
psk_size = session->key.binders[0].psk.size;
+ prf = session->key.binders[0].prf;
}
ret = _tls13_init_secret(session, psk, psk_size);
@@ -2275,6 +2349,12 @@ int _gnutls_send_server_hello(gnutls_session_t session, int again)
goto fail;
}
+ ret = generate_early_traffic_secret(session, prf);
+ if (ret < 0) {
+ gnutls_assert();
+ goto fail;
+ }
+
vbytes[0] = 0x03; /* TLS1.2 */
vbytes[1] = 0x03;
extflag |= GNUTLS_EXT_FLAG_TLS13_SERVER_HELLO;
@@ -2345,14 +2425,6 @@ int _gnutls_send_server_hello(gnutls_session_t session, int again)
}
if (vers->tls13_sem) {
- ret = _tls13_derive_secret(session, DERIVED_LABEL, sizeof(DERIVED_LABEL)-1,
- NULL, 0, session->key.proto.tls13.temp_secret,
- session->key.proto.tls13.temp_secret);
- if (ret < 0) {
- gnutls_assert();
- goto fail;
- }
-
/* Under TLS1.3, 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 */
@@ -2723,6 +2795,8 @@ int gnutls_handshake(gnutls_session_t session)
_gnutls_handshake_internal_state_clear(session);
+ _gnutls_buffer_clear(&session->internals.record_presend_buffer);
+
_gnutls_epoch_bump(session);
}
@@ -2850,6 +2924,10 @@ static int handshake_client(gnutls_session_t session)
ret = send_client_hello(session, AGAIN(STATE1));
STATE = STATE1;
IMED_RET("send hello", ret, 1);
+ if (session->internals.hsk_flags & HSK_EARLY_DATA_IN_FLIGHT) {
+ ret = generate_early_traffic_secret_from_ticket(session);
+ IMED_RET_FATAL("generate early traffic keys from ticket", ret, 0);
+ }
FALLTHROUGH;
case STATE2:
if (IS_DTLS(session)) {
diff --git a/lib/handshake.h b/lib/handshake.h
index ee5ee7a437..a82263aad1 100644
--- a/lib/handshake.h
+++ b/lib/handshake.h
@@ -159,7 +159,7 @@ int _gnutls_check_if_cert_hash_is_same(gnutls_session_t session, gnutls_certific
#define EXPORTER_MASTER_LABEL "exp master"
#define RMS_MASTER_LABEL "res master"
#define EXPORTER_LABEL "exp master"
-#define RES_LABEL "res master"
+#define RESUMPTION_LABEL "resumption"
int _gnutls_call_hook_func(gnutls_session_t session,
gnutls_handshake_description_t type,
diff --git a/lib/includes/gnutls/gnutls.h.in b/lib/includes/gnutls/gnutls.h.in
index 5dcbc1c986..2af09bb24a 100644
--- a/lib/includes/gnutls/gnutls.h.in
+++ b/lib/includes/gnutls/gnutls.h.in
@@ -399,6 +399,7 @@ typedef enum {
* finish; similarly to false start the handshake will be completed once data are received by the
* client, while the server is able to transmit sooner. This is not enabled by default as it could
* break certain existing server assumptions and use-cases. Since 3.6.4.
+ * @GNUTLS_ENABLE_EARLY_DATA: Under TLS1.3 allow the server to receive early data sent as part of the initial ClientHello (0-RTT). This is not enabled by default as early data has weaker security properties than other data. Since 3.6.5.
* @GNUTLS_FORCE_CLIENT_CERT: When in client side and only a single cert is specified, send that certificate irrespective of the issuers expected by the server. Since 3.5.0.
* @GNUTLS_NO_TICKETS: Flag to indicate that the session should not use resumption with session tickets.
* @GNUTLS_KEY_SHARE_TOP3: Generate key shares for the top-3 different groups which are enabled.
@@ -456,7 +457,8 @@ typedef enum {
GNUTLS_SAFE_PADDING_CHECK = (1<<16),
GNUTLS_ENABLE_EARLY_START = (1<<17),
GNUTLS_ENABLE_CERT_TYPE_NEG = (1<<18),
- GNUTLS_AUTO_REAUTH = (1<<19)
+ GNUTLS_AUTO_REAUTH = (1<<19),
+ GNUTLS_ENABLE_EARLY_DATA = (1<<20)
} gnutls_init_flags_t;
/* compatibility defines (previous versions of gnutls
@@ -1434,7 +1436,14 @@ ssize_t gnutls_record_set_max_size(gnutls_session_t session, size_t size);
size_t gnutls_record_check_pending(gnutls_session_t session);
size_t gnutls_record_check_corked(gnutls_session_t session);
+size_t gnutls_record_get_max_early_data_size(gnutls_session_t session);
int gnutls_record_set_max_early_data_size(gnutls_session_t session, size_t size);
+ssize_t gnutls_record_send_early_data(gnutls_session_t session,
+ const void *data,
+ size_t length);
+ssize_t gnutls_record_recv_early_data(gnutls_session_t session,
+ void *data,
+ size_t data_size);
void gnutls_session_force_valid(gnutls_session_t session);
@@ -1502,6 +1511,7 @@ unsigned gnutls_session_etm_status(gnutls_session_t session);
* @GNUTLS_SFLAGS_SESSION_TICKET: A session ticket has been received by the server.
* @GNUTLS_SFLAGS_POST_HANDSHAKE_AUTH: Indicates client capability for post-handshake auth; set only on server side.
* @GNUTLS_SFLAGS_EARLY_START: The TLS1.3 server session returned early.
+ * @GNUTLS_SFLAGS_EARLY_DATA: The TLS1.3 early data has been received by the server.
*
* Enumeration of different session parameters.
*/
@@ -1515,7 +1525,8 @@ typedef enum {
GNUTLS_SFLAGS_RFC7919 = 1<<6,
GNUTLS_SFLAGS_SESSION_TICKET = 1<<7,
GNUTLS_SFLAGS_POST_HANDSHAKE_AUTH = 1<<8,
- GNUTLS_SFLAGS_EARLY_START = 1<<9
+ GNUTLS_SFLAGS_EARLY_START = 1<<9,
+ GNUTLS_SFLAGS_EARLY_DATA = 1<<10
} gnutls_session_flags_t;
unsigned gnutls_session_get_flags(gnutls_session_t session);
@@ -1772,6 +1783,8 @@ typedef int (*gnutls_db_store_func) (void *, gnutls_datum_t key,
gnutls_datum_t data);
typedef int (*gnutls_db_remove_func) (void *, gnutls_datum_t key);
typedef gnutls_datum_t(*gnutls_db_retr_func) (void *, gnutls_datum_t key);
+typedef int (*gnutls_db_add_func) (void *, gnutls_datum_t key,
+ gnutls_datum_t data);
void gnutls_db_set_cache_expiration(gnutls_session_t session, int seconds);
unsigned gnutls_db_get_default_cache_expiration(void);
@@ -1783,11 +1796,14 @@ void gnutls_db_set_remove_function(gnutls_session_t session,
gnutls_db_remove_func rem_func);
void gnutls_db_set_store_function(gnutls_session_t session,
gnutls_db_store_func store_func);
+void gnutls_db_set_add_function(gnutls_session_t session,
+ gnutls_db_add_func add_func);
void gnutls_db_set_ptr(gnutls_session_t session, void *ptr);
void *gnutls_db_get_ptr(gnutls_session_t session);
int gnutls_db_check_entry(gnutls_session_t session,
gnutls_datum_t session_entry);
time_t gnutls_db_check_entry_time(gnutls_datum_t * entry);
+time_t gnutls_db_check_entry_expire_time(gnutls_datum_t * entry);
/**
* gnutls_handshake_hook_func:
@@ -2975,6 +2991,17 @@ void gnutls_supplemental_recv(gnutls_session_t session, unsigned do_recv_supplem
void gnutls_supplemental_send(gnutls_session_t session, unsigned do_send_supplemental);
+/* Anti-replay related functions */
+
+typedef struct gnutls_anti_replay_st *gnutls_anti_replay_t;
+
+int gnutls_anti_replay_init(gnutls_anti_replay_t *anti_replay);
+void gnutls_anti_replay_deinit(gnutls_anti_replay_t anti_replay);
+void gnutls_anti_replay_set_window(gnutls_anti_replay_t anti_replay,
+ unsigned int window);
+void gnutls_anti_replay_enable(gnutls_session_t session,
+ gnutls_anti_replay_t anti_replay);
+
/* FIPS140-2 related functions */
unsigned gnutls_fips140_mode_enabled(void);
@@ -3253,6 +3280,8 @@ void gnutls_fips140_set_mode(gnutls_fips_mode_t mode, unsigned flags);
#define GNUTLS_E_TOO_MANY_MATCHES -425
#define GNUTLS_E_CRL_VERIFICATION_ERROR -426
#define GNUTLS_E_MISSING_EXTENSION -427
+#define GNUTLS_E_DB_ENTRY_EXISTS -428
+#define GNUTLS_E_EARLY_DATA_REJECTED -429
#define GNUTLS_E_UNIMPLEMENTED_FEATURE -1250
diff --git a/lib/libgnutls.map b/lib/libgnutls.map
index ad6613b907..3cfc0c450b 100644
--- a/lib/libgnutls.map
+++ b/lib/libgnutls.map
@@ -1248,6 +1248,20 @@ GNUTLS_3_6_4
gnutls_priority_certificate_type_list2;
} GNUTLS_3_6_3;
+GNUTLS_3_6_5
+{
+ global:
+ gnutls_record_get_max_early_data_size;
+ gnutls_record_send_early_data;
+ gnutls_record_recv_early_data;
+ gnutls_db_check_entry_expire_time;
+ gnutls_db_set_add_function;
+ gnutls_anti_replay_init;
+ gnutls_anti_replay_deinit;
+ gnutls_anti_replay_set_window;
+ gnutls_anti_replay_enable;
+} GNUTLS_3_6_4;
+
GNUTLS_FIPS140_3_4 {
global:
gnutls_cipher_self_test;
@@ -1328,4 +1342,6 @@ GNUTLS_PRIVATE_3_4 {
_gnutls_set_session_ticket_key_rotation_callback;
# Internal symbols needed by tests/virt-time.h
_gnutls_global_set_gettime_function;
+ # Internal symbols needed by tests/tls13/anti_replay.c
+ _gnutls_anti_replay_check;
} GNUTLS_3_4;
diff --git a/lib/record.c b/lib/record.c
index 87b9dee304..5514ddcef1 100644
--- a/lib/record.c
+++ b/lib/record.c
@@ -1370,40 +1370,89 @@ _gnutls_recv_in_buffers(gnutls_session_t session, content_type_t type,
_mbuffer_head_remove_bytes(&session->internals.record_recv_buffer,
record.header_size + record.length);
- /* FIXME: as 0-RTT is not implemented yet, when early data is
- * indicated, skip decryption failure up to
- * max_early_data_size. Otherwise, if the record is properly
- * decrypted, treat it as the start of client's second flight.
- *
- * This implements the first way suggested in 4.2.10 of
- * draft-ietf-tls-tls13-28.
- */
- if (unlikely(session->internals.hsk_flags & HSK_EARLY_DATA_IN_FLIGHT)) {
- if (record.type == GNUTLS_APPLICATION_DATA &&
- (ret < 0 ||
- /* early data must always be encrypted, treat it
- * as decryption failure if otherwise */
- record_params->cipher->id == GNUTLS_CIPHER_NULL)) {
- if (record.length >
- session->security_parameters.max_early_data_size -
- session->internals.early_data_received) {
+ if (session->security_parameters.entity == GNUTLS_SERVER &&
+ session->internals.hsk_flags & HSK_EARLY_DATA_IN_FLIGHT) {
+ if (session->internals.hsk_flags & HSK_EARLY_DATA_ACCEPTED) {
+ if (ret < 0 ||
+ /* early data must always be encrypted, treat it
+ * as decryption failure if otherwise */
+ record_params->cipher->id == GNUTLS_CIPHER_NULL) {
_gnutls_record_log
- ("REC[%p]: max_early_data_size exceeded\n",
- session);
- ret = GNUTLS_E_UNEXPECTED_PACKET;
+ ("REC[%p]: failed to decrypt early data, in epoch %d\n",
+ session,
+ record_params->epoch);
+ ret = GNUTLS_E_DECRYPTION_FAILED;
goto sanity_check_error;
- }
+ } else if (record.type == GNUTLS_APPLICATION_DATA) {
+ size_t decrypted_length =
+ _mbuffer_get_udata_size(decrypted);
+ _gnutls_record_log
+ ("REC[%p]: decrypted early data with length: %d, in epoch %d\n",
+ session,
+ (int) decrypted_length,
+ record_params->epoch);
+ if (decrypted_length >
+ session->security_parameters.max_early_data_size -
+ session->internals.early_data_received) {
+ _gnutls_record_log
+ ("REC[%p]: max_early_data_size exceeded\n",
+ session);
+ ret = GNUTLS_E_UNEXPECTED_PACKET;
+ goto sanity_check_error;
+ }
+
+ _mbuffer_enqueue(&session->internals.early_data_recv_buffer, decrypted);
+ session->internals.early_data_received +=
+ decrypted_length;
+
+ /* Increase sequence number. We do both for TLS and DTLS, since in
+ * DTLS we also rely on that number (roughly) since it may get reported
+ * to application via gnutls_record_get_state().
+ */
+ if (sequence_increment(session, &record_state->sequence_number) != 0) {
+ session_invalidate(session);
+ gnutls_assert();
+ ret = GNUTLS_E_RECORD_LIMIT_REACHED;
+ goto sanity_check_error;
+ }
- _gnutls_record_log("REC[%p]: Discarded early data[%u] due to invalid decryption, length: %u\n",
- session,
- (unsigned int)
- _gnutls_uint64touint32(packet_sequence),
- (unsigned int)
- record.length);
- session->internals.early_data_received += record.length;
- goto discard;
+ /* decrypted is now accounted */
+ return GNUTLS_E_AGAIN;
+ }
} else {
- session->internals.hsk_flags &= ~HSK_EARLY_DATA_IN_FLIGHT;
+ /* We do not accept early data: skip decryption
+ * failure up to max_early_data_size. Otherwise,
+ * if the record is properly decrypted, treat it as
+ * the start of client's second flight.
+ */
+ if (record.type == GNUTLS_APPLICATION_DATA &&
+ (ret < 0 ||
+ /* early data must always be encrypted, treat it
+ * as decryption failure if otherwise */
+ record_params->cipher->id == GNUTLS_CIPHER_NULL)) {
+ if (record.length >
+ session->security_parameters.max_early_data_size -
+ session->internals.early_data_received) {
+ _gnutls_record_log
+ ("REC[%p]: max_early_data_size exceeded\n",
+ session);
+ ret = GNUTLS_E_UNEXPECTED_PACKET;
+ goto sanity_check_error;
+ }
+
+ _gnutls_record_log("REC[%p]: Discarded early data[%u] due to invalid decryption, length: %u\n",
+ session,
+ (unsigned int)
+ _gnutls_uint64touint32(packet_sequence),
+ (unsigned int)
+ record.length);
+ session->internals.early_data_received += record.length;
+ /* silently discard received data */
+ _mbuffer_xfree(&decrypted);
+ return gnutls_assert_val(GNUTLS_E_AGAIN);
+ } else {
+ session->internals.hsk_flags &= ~HSK_EARLY_DATA_IN_FLIGHT;
+ }
}
}
@@ -1924,7 +1973,8 @@ gnutls_record_send2(gnutls_session_t session, const void *data,
* data. We allow sending however, if we are in false start handshake
* state. */
if (session->internals.recv_state != RECV_STATE_FALSE_START &&
- session->internals.recv_state != RECV_STATE_EARLY_START)
+ session->internals.recv_state != RECV_STATE_EARLY_START &&
+ !(session->internals.hsk_flags & HSK_EARLY_DATA_IN_FLIGHT))
return gnutls_assert_val(GNUTLS_E_UNAVAILABLE_DURING_HANDSHAKE);
}
@@ -1980,6 +2030,94 @@ gnutls_record_send2(gnutls_session_t session, const void *data,
}
/**
+ * gnutls_record_send_early_data:
+ * @session: is a #gnutls_session_t type.
+ * @data: contains the data to send
+ * @data_size: is the length of the data
+ *
+ * This function can be used by a client to send data early in the
+ * handshake processes when resuming a session. This is used to
+ * implement a zero-roundtrip (0-RTT) mode. It has the same semantics
+ * as gnutls_record_send().
+ *
+ * There may be a limit to the amount of data sent as early data. Use
+ * gnutls_record_get_max_early_data_size() to check the limit.
+ *
+ * Returns: The number of bytes sent, or a negative error code. The
+ * number of bytes sent might be less than @data_size. The maximum
+ * number of bytes this function can send in a single call depends
+ * on the negotiated maximum record size.
+ *
+ * Since: 3.6.5
+ **/
+ssize_t gnutls_record_send_early_data(gnutls_session_t session,
+ const void *data,
+ size_t data_size)
+{
+ int ret;
+
+ if (session->security_parameters.entity != GNUTLS_CLIENT)
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+
+ ret =
+ _gnutls_buffer_append_data(&session->internals.
+ early_data_presend_buffer, data,
+ data_size);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+
+ return ret;
+}
+
+/**
+ * gnutls_record_recv_early_data:
+ * @session: is a #gnutls_session_t type.
+ * @data: the buffer that the data will be read into
+ * @data_size: the number of requested bytes
+ *
+ * This function can be used by a searver to retrieve data sent early
+ * in the handshake processes when resuming a session. This is used
+ * to implement a zero-roundtrip (0-RTT) mode. It has the same
+ * semantics as gnutls_record_recv().
+ *
+ * This function can be called either in a handshake hook, or after
+ * the handshake is complete.
+ *
+ * Returns: The number of bytes received and zero when early data
+ * reading is complete. A negative error code is returned in case of
+ * an error. If no early data is received during the handshake, this
+ * function returns %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE. The
+ * number of bytes received might be less than the requested
+ * @data_size.
+ *
+ * Since: 3.6.5
+ **/
+ssize_t
+gnutls_record_recv_early_data(gnutls_session_t session, void *data, size_t data_size)
+{
+ mbuffer_st *bufel;
+ gnutls_datum_t msg;
+ size_t length;
+
+ if (session->security_parameters.entity != GNUTLS_SERVER)
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+
+ bufel = _mbuffer_head_get_first(&session->internals.early_data_recv_buffer,
+ &msg);
+ if (bufel == NULL)
+ return
+ gnutls_assert_val
+ (GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
+
+ length = MIN(msg.size, data_size);
+ memcpy(data, msg.data, length);
+ _mbuffer_head_remove_bytes(&session->internals.early_data_recv_buffer,
+ length);
+
+ return length;
+}
+
+/**
* gnutls_record_cork:
* @session: is a #gnutls_session_t type.
*
diff --git a/lib/session_pack.c b/lib/session_pack.c
index b83c9c7440..1869f7740b 100644
--- a/lib/session_pack.c
+++ b/lib/session_pack.c
@@ -104,6 +104,7 @@ _gnutls_session_pack(gnutls_session_t session,
BUFFER_APPEND_NUM(&sb, PACKED_SESSION_MAGIC);
BUFFER_APPEND_NUM(&sb, session->security_parameters.timestamp);
+ BUFFER_APPEND_NUM(&sb, session->internals.expire_time);
BUFFER_APPEND(&sb, &id, 1);
switch (id) {
@@ -190,6 +191,7 @@ _gnutls_session_unpack(gnutls_session_t session,
int ret;
gnutls_buffer_st sb;
uint32_t magic;
+ uint32_t expire_time;
uint8_t id;
_gnutls_buffer_init(&sb);
@@ -220,6 +222,8 @@ _gnutls_session_unpack(gnutls_session_t session,
BUFFER_POP_NUM(&sb,
session->internals.resumed_security_parameters.
timestamp);
+ BUFFER_POP_NUM(&sb, expire_time);
+ (void) expire_time;
BUFFER_POP(&sb, &id, 1);
switch (id) {
@@ -311,8 +315,7 @@ _gnutls_session_unpack(gnutls_session_t session,
* 1 bytes the resumption master secret length
* x bytes the resumption master secret
* 12 bytes the ticket arrival time
- *
- * WE DON'T STORE NewSessionTicket EXTENSIONS, as we don't support them yet.
+ * 4 bytes the max early data size
*
* We only store that info if we received a TLS 1.3 NewSessionTicket at some point.
* If we didn't receive any NST then we cannot resume a TLS 1.3 session and hence
@@ -348,6 +351,10 @@ tls13_pack_security_parameters(gnutls_session_t session, gnutls_buffer_st *ps)
length += (1 + ticket->prf->output_size);
BUFFER_APPEND_TS(ps, ticket->arrival_time);
length += 12;
+ BUFFER_APPEND_NUM(ps,
+ session->security_parameters.
+ max_early_data_size);
+ length += 4;
/* Overwrite the length field */
_gnutls_write_uint32(length, ps->data + length_pos);
@@ -396,6 +403,9 @@ tls13_unpack_security_parameters(gnutls_session_t session, gnutls_buffer_st *ps)
ticket->prf = session->internals.resumed_security_parameters.prf;
BUFFER_POP_TS(ps, ticket->arrival_time);
+ BUFFER_POP_NUM(ps,
+ session->security_parameters.
+ max_early_data_size);
}
error:
diff --git a/lib/state.c b/lib/state.c
index 303a3ad2f8..01288ad474 100644
--- a/lib/state.c
+++ b/lib/state.c
@@ -485,6 +485,8 @@ int gnutls_init(gnutls_session_t * session, unsigned int flags)
_mbuffer_head_init(&(*session)->internals.record_buffer);
_mbuffer_head_init(&(*session)->internals.record_send_buffer);
_mbuffer_head_init(&(*session)->internals.record_recv_buffer);
+ _mbuffer_head_init(&(*session)->internals.early_data_recv_buffer);
+ _gnutls_buffer_init(&(*session)->internals.early_data_presend_buffer);
_mbuffer_head_init(&(*session)->internals.handshake_send_buffer);
_gnutls_handshake_recv_buffer_init(*session);
@@ -620,6 +622,9 @@ void gnutls_deinit(gnutls_session_t session)
_mbuffer_head_clear(&session->internals.record_recv_buffer);
_mbuffer_head_clear(&session->internals.record_send_buffer);
+ _mbuffer_head_clear(&session->internals.early_data_recv_buffer);
+ _gnutls_buffer_clear(&session->internals.early_data_presend_buffer);
+
_gnutls_free_datum(&session->internals.resumption_data);
_gnutls_free_datum(&session->internals.dtls.dcookie);
@@ -1542,6 +1547,8 @@ unsigned gnutls_session_get_flags(gnutls_session_t session)
flags |= GNUTLS_SFLAGS_SESSION_TICKET;
if (session->security_parameters.post_handshake_auth)
flags |= GNUTLS_SFLAGS_POST_HANDSHAKE_AUTH;
+ if (session->internals.hsk_flags & HSK_EARLY_DATA_ACCEPTED)
+ flags |= GNUTLS_SFLAGS_EARLY_DATA;
return flags;
}
diff --git a/lib/str.h b/lib/str.h
index c8be6c9913..a9cb48fd6e 100644
--- a/lib/str.h
+++ b/lib/str.h
@@ -234,7 +234,7 @@ int _gnutls_hostname_compare(const char *certname, size_t certnamesize,
}
#define BUFFER_APPEND_TS(b, s) { \
- ret = _gnutls_buffer_append_prefix(b, 32, s.tv_sec >> 32); \
+ ret = _gnutls_buffer_append_prefix(b, 32, (uint64_t) s.tv_sec >> 32); \
if (ret < 0) { \
gnutls_assert(); \
return ret; \
diff --git a/lib/tls13/anti_replay.c b/lib/tls13/anti_replay.c
new file mode 100644
index 0000000000..5ae9926afd
--- /dev/null
+++ b/lib/tls13/anti_replay.c
@@ -0,0 +1,221 @@
+/*
+ * Copyright (C) 2018 Red Hat, Inc.
+ *
+ * Author: Daiki Ueno
+ *
+ * This file is part of GnuTLS.
+ *
+ * The GnuTLS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser 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 <http://www.gnu.org/licenses/>
+ *
+ */
+
+#include "gnutls_int.h"
+#include "db.h"
+#include "system.h"
+#include "tls13/anti_replay.h"
+
+/* The default time window in milliseconds; RFC8446 suggests the order
+ * of ten seconds is sufficient for the clients on the Internet. */
+#define DEFAULT_WINDOW_MS 10000
+
+struct gnutls_anti_replay_st {
+ uint32_t window;
+ struct timespec start_time;
+};
+
+/**
+ * gnutls_anti_replay_init:
+ * @anti_replay: is a pointer to #gnutls_anti_replay_t type
+ *
+ * This function will allocate and initialize the @anti_replay context
+ * to be usable for detect replay attacks. The context can then be
+ * attached to a @gnutls_session_t with
+ * gnutls_anti_replay_enable().
+ *
+ * Returns: Zero or a negative error code on error.
+ *
+ * Since: 3.6.5
+ **/
+int
+gnutls_anti_replay_init(gnutls_anti_replay_t *anti_replay)
+{
+ *anti_replay = gnutls_calloc(1, sizeof(struct gnutls_anti_replay_st));
+ if (!*anti_replay)
+ return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+
+ (*anti_replay)->window = DEFAULT_WINDOW_MS;
+
+ gnutls_gettime(&(*anti_replay)->start_time);
+
+ return 0;
+}
+
+/**
+ * gnutls_anti_replay_set_window:
+ * @anti_replay: is a #gnutls_anti_replay_t type.
+ * @window: is the time window recording ClientHello, in milliseconds
+ *
+ * Sets the time window used for ClientHello recording. In order to
+ * protect against replay attacks, the server records ClientHello
+ * messages within this time period from the last update, and
+ * considers it a replay when a ClientHello outside of the period; if
+ * a ClientHello arrives within this period, the server checks the
+ * database and detects duplicates.
+ *
+ * For the details of the algorithm, see RFC 8446, section 8.2.
+ *
+ * Since: 3.6.5
+ */
+void
+gnutls_anti_replay_set_window(gnutls_anti_replay_t anti_replay,
+ unsigned int window)
+{
+ anti_replay->window = window;
+}
+
+/**
+ * gnutls_anti_replay_deinit:
+ * @anti_replay: is a #gnutls_anti_replay type
+ *
+ * This function will deinitialize all resources occupied by the given
+ * anti-replay context.
+ *
+ * Since: 3.6.5
+ **/
+void
+gnutls_anti_replay_deinit(gnutls_anti_replay_t anti_replay)
+{
+ gnutls_free(anti_replay);
+}
+
+/**
+ * gnutls_anti_replay_enable:
+ * @session: is a #gnutls_session_t type.
+ * @anti_replay: is a #gnutls_anti_replay_t type.
+ *
+ * Request that the server should use anti-replay mechanism.
+ *
+ * Since: 3.6.5
+ **/
+void
+gnutls_anti_replay_enable(gnutls_session_t session,
+ gnutls_anti_replay_t anti_replay)
+{
+ if (unlikely(session->security_parameters.entity != GNUTLS_SERVER)) {
+ gnutls_assert();
+ return;
+ }
+
+ session->internals.anti_replay = anti_replay;
+}
+
+int
+_gnutls_anti_replay_check(gnutls_session_t session,
+ uint32_t client_ticket_age,
+ struct timespec *ticket_creation_time,
+ gnutls_datum_t *id)
+{
+ gnutls_anti_replay_t anti_replay = session->internals.anti_replay;
+ struct timespec now;
+ uint32_t server_ticket_age, diff;
+ gnutls_datum_t key = { NULL, 0 };
+ gnutls_datum_t entry = { NULL, 0 };
+ unsigned char key_buffer[MAX_HASH_SIZE + 12];
+ unsigned char entry_buffer[12]; /* magic + timestamp + expire_time */
+ unsigned char *p;
+ int ret;
+
+ if (unlikely(id->size > MAX_HASH_SIZE))
+ return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
+
+ gnutls_gettime(&now);
+ server_ticket_age = timespec_sub_ms(&now, ticket_creation_time);
+
+ /* It shouldn't be possible that the server's view of ticket
+ * age is smaller than the client's view.
+ */
+ if (unlikely(server_ticket_age < client_ticket_age))
+ return gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER);
+
+ /* If ticket is created before recording has started, discard
+ * reject early data.
+ */
+ if (_gnutls_timespec_cmp(ticket_creation_time,
+ &anti_replay->start_time) < 0) {
+ _gnutls_handshake_log("anti_replay: ticket is created before recording has started\n");
+ return gnutls_assert_val(GNUTLS_E_EARLY_DATA_REJECTED);
+ }
+
+ /* If certain amount of time (window) has elapsed, rollover
+ * the recording.
+ */
+ diff = timespec_sub_ms(&now, &anti_replay->start_time);
+ if (diff > anti_replay->window)
+ gnutls_gettime(&anti_replay->start_time);
+
+ /* If expected_arrival_time is out of window, reject early
+ * data.
+ */
+ if (server_ticket_age - client_ticket_age > anti_replay->window) {
+ _gnutls_handshake_log("anti_replay: server ticket age: %u, client ticket age: %u\n",
+ server_ticket_age,
+ client_ticket_age);
+ return gnutls_assert_val(GNUTLS_E_EARLY_DATA_REJECTED);
+ }
+
+ /* Check if the ClientHello is stored in the database.
+ */
+ if (!session->internals.db_add_func)
+ return gnutls_assert_val(GNUTLS_E_EARLY_DATA_REJECTED);
+
+ /* Create a key for database lookup, prefixing window start
+ * time to ID. Note that this shouldn't clash with session ID
+ * used in TLS 1.2, because such IDs are 32 octets, while here
+ * the key becomes 44+ octets.
+ */
+ p = key_buffer;
+ _gnutls_write_uint32((uint64_t) anti_replay->start_time.tv_sec >> 32, p);
+ p += 4;
+ _gnutls_write_uint32(anti_replay->start_time.tv_sec & 0xFFFFFFFF, p);
+ p += 4;
+ _gnutls_write_uint32(anti_replay->start_time.tv_nsec, p);
+ p += 4;
+ memcpy(p, id->data, id->size);
+ p += id->size;
+ key.data = key_buffer;
+ key.size = p - key_buffer;
+
+ /* Create an entry to be stored on database if the lookup
+ * failed. This is formatted so that
+ * gnutls_db_entry_is_expired() work.
+ */
+ p = entry_buffer;
+ _gnutls_write_uint32(PACKED_SESSION_MAGIC, p);
+ p += 4;
+ _gnutls_write_uint32(now.tv_sec, p);
+ p += 4;
+ _gnutls_write_uint32(anti_replay->window / 1000, p);
+ p += 4;
+ entry.data = entry_buffer;
+ entry.size = p - entry_buffer;
+
+ ret = session->internals.db_add_func(session->internals.db_ptr,
+ key, entry);
+ if (ret < 0) {
+ _gnutls_handshake_log("anti_replay: duplicate ClientHello found\n");
+ return gnutls_assert_val(GNUTLS_E_EARLY_DATA_REJECTED);
+ }
+
+ return 0;
+}
diff --git a/lib/tls13/anti_replay.h b/lib/tls13/anti_replay.h
new file mode 100644
index 0000000000..e44186c910
--- /dev/null
+++ b/lib/tls13/anti_replay.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2018 Red Hat, Inc.
+ *
+ * Author: Daiki Ueno
+ *
+ * This file is part of GnuTLS.
+ *
+ * The GnuTLS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser 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 <http://www.gnu.org/licenses/>
+ *
+ */
+
+int _gnutls_anti_replay_check(gnutls_session_t session,
+ uint32_t client_ticket_age,
+ struct timespec *ticket_creation_time,
+ gnutls_datum_t *id);
diff --git a/lib/tls13/early_data.c b/lib/tls13/early_data.c
new file mode 100644
index 0000000000..dd977fc410
--- /dev/null
+++ b/lib/tls13/early_data.c
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2017 Red Hat, Inc.
+ *
+ * Author: Nikos Mavrogiannopoulos
+ *
+ * This file is part of GnuTLS.
+ *
+ * The GnuTLS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser 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 <http://www.gnu.org/licenses/>
+ *
+ */
+
+#include "gnutls_int.h"
+#include "handshake.h"
+#include "tls13/early_data.h"
+
+int _gnutls13_send_early_data(gnutls_session_t session)
+{
+ int ret;
+
+ if (!(session->security_parameters.entity == GNUTLS_CLIENT &&
+ session->internals.hsk_flags & HSK_EARLY_DATA_IN_FLIGHT))
+ return 0;
+
+ while (session->internals.early_data_presend_buffer.length > 0) {
+ ret =
+ gnutls_record_send(session,
+ session->internals.
+ early_data_presend_buffer.data,
+ session->internals.
+ early_data_presend_buffer.
+ length);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+
+ session->internals.early_data_presend_buffer.data += ret;
+ session->internals.early_data_presend_buffer.length -= ret;
+ }
+
+
+ return 0;
+}
+
+int _gnutls13_send_end_of_early_data(gnutls_session_t session, unsigned again)
+{
+ int ret;
+ mbuffer_st *bufel = NULL;
+ gnutls_buffer_st buf;
+
+ if (!(session->security_parameters.entity == GNUTLS_CLIENT &&
+ session->internals.hsk_flags & HSK_EARLY_DATA_ACCEPTED))
+ return 0;
+
+ if (again == 0) {
+ ret = _gnutls_buffer_init_handshake_mbuffer(&buf);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+
+ bufel = _gnutls_buffer_to_mbuffer(&buf);
+ }
+
+ return _gnutls_send_handshake(session, bufel, GNUTLS_HANDSHAKE_END_OF_EARLY_DATA);
+}
+
+int _gnutls13_recv_end_of_early_data(gnutls_session_t session)
+{
+ int ret;
+ gnutls_buffer_st buf;
+
+ if (!(session->security_parameters.entity == GNUTLS_SERVER &&
+ session->internals.hsk_flags & HSK_EARLY_DATA_ACCEPTED))
+ return 0;
+
+ ret = _gnutls_recv_handshake(session, GNUTLS_HANDSHAKE_END_OF_EARLY_DATA, 0, &buf);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+
+ if (buf.length != 0) {
+ gnutls_assert();
+ ret = GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
+ goto cleanup;
+ }
+
+ session->internals.hsk_flags &= ~HSK_EARLY_DATA_IN_FLIGHT;
+
+ ret = 0;
+cleanup:
+
+ _gnutls_buffer_clear(&buf);
+ return ret;
+}
diff --git a/lib/tls13/early_data.h b/lib/tls13/early_data.h
new file mode 100644
index 0000000000..ddbd983293
--- /dev/null
+++ b/lib/tls13/early_data.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2017 Red Hat, Inc.
+ *
+ * Author: Nikos Mavrogiannopoulos
+ *
+ * This file is part of GnuTLS.
+ *
+ * The GnuTLS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser 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 <http://www.gnu.org/licenses/>
+ *
+ */
+
+int _gnutls13_send_end_of_early_data(gnutls_session_t session, unsigned again);
+int _gnutls13_recv_end_of_early_data(gnutls_session_t session);
+int _gnutls13_send_early_data(gnutls_session_t session);
diff --git a/lib/tls13/key_update.c b/lib/tls13/key_update.c
index d9c495efdc..0c5c93734a 100644
--- a/lib/tls13/key_update.c
+++ b/lib/tls13/key_update.c
@@ -40,7 +40,7 @@ static int update_keys(gnutls_session_t session, hs_stage_t stage)
return gnutls_assert_val(ret);
_gnutls_epoch_bump(session);
- ret = _gnutls_epoch_dup(session);
+ ret = _gnutls_epoch_dup(session, EPOCH_READ_CURRENT);
if (ret < 0)
return gnutls_assert_val(ret);
diff --git a/lib/tls13/session_ticket.c b/lib/tls13/session_ticket.c
index ad04a60919..7ea2b00f82 100644
--- a/lib/tls13/session_ticket.c
+++ b/lib/tls13/session_ticket.c
@@ -46,7 +46,7 @@ pack_ticket(gnutls_session_t session, tls13_ticket_st *ticket, gnutls_datum_t *p
packed->size = 2 + 4 + 4 +
1 + ticket->prf->output_size +
- 1 + ticket->nonce_size + 2 + state.size;
+ 1 + ticket->nonce_size + 2 + state.size + 12;
packed->data = gnutls_malloc(packed->size);
if (!packed->data) {
@@ -77,6 +77,14 @@ pack_ticket(gnutls_session_t session, tls13_ticket_st *ticket, gnutls_datum_t *p
p += 2;
memcpy(p, state.data, state.size);
+ p += state.size;
+
+ _gnutls_write_uint32(ticket->creation_time.tv_sec >> 32, p);
+ p += 4;
+ _gnutls_write_uint32(ticket->creation_time.tv_sec & 0xFFFFFFFF, p);
+ p += 4;
+ _gnutls_write_uint32(ticket->creation_time.tv_nsec, p);
+
ret = 0;
cleanup:
@@ -88,6 +96,7 @@ static int
unpack_ticket(gnutls_session_t session, gnutls_datum_t *packed, tls13_ticket_st *data)
{
uint32_t age_add, lifetime;
+ struct timespec creation_time;
uint8_t resumption_master_secret[MAX_HASH_SIZE];
size_t resumption_master_secret_size;
uint8_t nonce[UINT8_MAX];
@@ -156,6 +165,15 @@ unpack_ticket(gnutls_session_t session, gnutls_datum_t *packed, tls13_ticket_st
DECR_LEN(len, state.size);
state.data = p;
+ p += state.size;
+
+ DECR_LEN(len, 12);
+ creation_time.tv_sec = _gnutls_read_uint32(p);
+ p += 4;
+ creation_time.tv_sec <<= 32;
+ creation_time.tv_sec |= _gnutls_read_uint32(p);
+ p += 4;
+ creation_time.tv_nsec = _gnutls_read_uint32(p);
ret = _gnutls_session_unpack(session, &state);
if (ret < 0)
@@ -169,6 +187,7 @@ unpack_ticket(gnutls_session_t session, gnutls_datum_t *packed, tls13_ticket_st
data->nonce_size = nonce_size;
data->age_add = age_add;
data->lifetime = lifetime;
+ memcpy(&data->creation_time, &creation_time, sizeof(struct timespec));
return 0;
}
@@ -178,17 +197,18 @@ generate_session_ticket(gnutls_session_t session, tls13_ticket_st *ticket)
{
int ret;
gnutls_datum_t packed = { NULL, 0 };
+ struct timespec now;
tls13_ticket_st ticket_data;
- time_t now = gnutls_time(0);
+ gnutls_gettime(&now);
if (session->internals.resumed != RESUME_FALSE) {
/* If we are resuming ensure that we don't extend the lifetime
* of the ticket past the original session expiration time */
- if (now >= session->security_parameters.timestamp + session->internals.expire_time)
+ if (now.tv_sec >= session->security_parameters.timestamp + session->internals.expire_time)
return GNUTLS_E_INT_RET_0; /* don't send ticket */
else
ticket->lifetime = session->security_parameters.timestamp +
- session->internals.expire_time - now;
+ session->internals.expire_time - now.tv_sec;
} else {
/* Set ticket lifetime to the default expiration time */
ticket->lifetime = session->internals.expire_time;
@@ -210,6 +230,7 @@ generate_session_ticket(gnutls_session_t session, tls13_ticket_st *ticket)
/* Encrypt the ticket and place the result in ticket->ticket */
ticket_data.lifetime = ticket->lifetime;
ticket_data.age_add = ticket->age_add;
+ memcpy(&ticket_data.creation_time, &now, sizeof(struct timespec));
memcpy(ticket_data.nonce, ticket->nonce, ticket->nonce_size);
ticket_data.nonce_size = ticket->nonce_size;
ticket_data.prf = ticket->prf;
@@ -229,6 +250,23 @@ generate_session_ticket(gnutls_session_t session, tls13_ticket_st *ticket)
return 0;
}
+static int append_nst_extension(void *ctx, gnutls_buffer_st *buf)
+{
+ gnutls_session_t session = ctx;
+ int ret;
+
+ if (!(session->internals.flags & GNUTLS_ENABLE_EARLY_DATA))
+ return 0;
+
+ ret = _gnutls_buffer_append_prefix(buf, 32,
+ session->security_parameters.
+ max_early_data_size);
+ if (ret < 0)
+ gnutls_assert();
+
+ return ret;
+}
+
int _gnutls13_send_session_ticket(gnutls_session_t session, unsigned nr, unsigned again)
{
int ret = 0;
@@ -253,6 +291,8 @@ int _gnutls13_send_session_ticket(gnutls_session_t session, unsigned nr, unsigne
if (again == 0) {
for (i=0;i<nr;i++) {
+ unsigned init_pos;
+
memset(&ticket, 0, sizeof(tls13_ticket_st));
bufel = NULL;
@@ -296,13 +336,28 @@ int _gnutls13_send_session_ticket(gnutls_session_t session, unsigned nr, unsigne
goto cleanup;
}
- ret = _gnutls_buffer_append_prefix(&buf, 16, 0);
+ _gnutls_free_datum(&ticket.ticket);
+
+ /* append extensions */
+ ret = _gnutls_extv_append_init(&buf);
if (ret < 0) {
gnutls_assert();
goto cleanup;
}
+ init_pos = ret;
- _gnutls_free_datum(&ticket.ticket);
+ ret = _gnutls_extv_append(&buf, ext_mod_early_data.tls_id, session,
+ (extv_append_func)append_nst_extension);
+ if (ret < 0) {
+ gnutls_assert();
+ goto cleanup;
+ }
+
+ ret = _gnutls_extv_append_final(&buf, init_pos);
+ if (ret < 0) {
+ gnutls_assert();
+ goto cleanup;
+ }
bufel = _gnutls_buffer_to_mbuffer(&buf);
@@ -337,7 +392,8 @@ static int parse_nst_extension(void *ctx, unsigned tls_id, const unsigned char *
if (data_size < 4)
return gnutls_assert_val(GNUTLS_E_TLS_PACKET_DECODING_ERROR);
size = _gnutls_read_uint32(data);
- session->security_parameters.max_early_data_size = size;
+ if (size < session->security_parameters.max_early_data_size)
+ session->security_parameters.max_early_data_size = size;
}
return 0;
}
diff --git a/src/cli-args.c.bak b/src/cli-args.c.bak
index 3e40c4f9b3..cb49046a9c 100644
--- a/src/cli-args.c.bak
+++ b/src/cli-args.c.bak
@@ -63,7 +63,7 @@ extern FILE * option_usage_fp;
/**
* static const strings for gnutls-cli options
*/
-static char const gnutls_cli_opt_strs[5102] =
+static char const gnutls_cli_opt_strs[5176] =
/* 0 */ "gnutls-cli 3.6.4\n"
"Copyright (C) 2000-2018 Free Software Foundation, and others, all rights reserved.\n"
"This is free software. It is licensed for use, modification and\n"
@@ -108,166 +108,169 @@ static char const gnutls_cli_opt_strs[5102] =
/* 1370 */ "Establish a session and resume\0"
/* 1401 */ "RESUME\0"
/* 1408 */ "resume\0"
-/* 1415 */ "Establish a session and rehandshake\0"
-/* 1451 */ "REHANDSHAKE\0"
-/* 1463 */ "rehandshake\0"
-/* 1475 */ "Server's hostname for server name indication extension\0"
-/* 1530 */ "SNI_HOSTNAME\0"
-/* 1543 */ "sni-hostname\0"
-/* 1556 */ "Server's hostname to use for validation\0"
-/* 1596 */ "VERIFY_HOSTNAME\0"
-/* 1612 */ "verify-hostname\0"
-/* 1628 */ "Connect, establish a plain session and start TLS\0"
-/* 1677 */ "STARTTLS\0"
-/* 1686 */ "starttls\0"
-/* 1695 */ "an alias for the 'starttls-proto' option\0"
-/* 1736 */ "app-proto\0"
-/* 1746 */ "The application protocol to be used to obtain the server's certificate\n"
+/* 1415 */ "Send early data on resumption from the specified file\0"
+/* 1469 */ "EARLYDATA\0"
+/* 1479 */ "earlydata\0"
+/* 1489 */ "Establish a session and rehandshake\0"
+/* 1525 */ "REHANDSHAKE\0"
+/* 1537 */ "rehandshake\0"
+/* 1549 */ "Server's hostname for server name indication extension\0"
+/* 1604 */ "SNI_HOSTNAME\0"
+/* 1617 */ "sni-hostname\0"
+/* 1630 */ "Server's hostname to use for validation\0"
+/* 1670 */ "VERIFY_HOSTNAME\0"
+/* 1686 */ "verify-hostname\0"
+/* 1702 */ "Connect, establish a plain session and start TLS\0"
+/* 1751 */ "STARTTLS\0"
+/* 1760 */ "starttls\0"
+/* 1769 */ "an alias for the 'starttls-proto' option\0"
+/* 1810 */ "app-proto\0"
+/* 1820 */ "The application protocol to be used to obtain the server's certificate\n"
"(https, ftp, smtp, imap, ldap, xmpp, lmtp, pop3, nntp, sieve, postgres)\0"
-/* 1889 */ "STARTTLS_PROTO\0"
-/* 1904 */ "starttls-proto\0"
-/* 1919 */ "Use DTLS (datagram TLS) over UDP\0"
-/* 1952 */ "UDP\0"
-/* 1956 */ "udp\0"
-/* 1960 */ "Set MTU for datagram TLS\0"
-/* 1985 */ "MTU\0"
-/* 1989 */ "mtu\0"
-/* 1993 */ "Send CR LF instead of LF\0"
-/* 2018 */ "CRLF\0"
-/* 2023 */ "crlf\0"
-/* 2028 */ "Enable TCP Fast Open\0"
-/* 2049 */ "FASTOPEN\0"
-/* 2058 */ "fastopen\0"
-/* 2067 */ "Use DER format for certificates to read from\0"
-/* 2112 */ "X509FMTDER\0"
-/* 2123 */ "x509fmtder\0"
-/* 2134 */ "Print peer's certificate in PEM format\0"
-/* 2173 */ "PRINT_CERT\0"
-/* 2184 */ "print-cert\0"
-/* 2195 */ "Save the peer's certificate chain in the specified file in PEM format\0"
-/* 2265 */ "SAVE_CERT\0"
-/* 2275 */ "save-cert\0"
-/* 2285 */ "Save the peer's OCSP status response in the provided file\0"
-/* 2343 */ "SAVE_OCSP\0"
-/* 2353 */ "save-ocsp\0"
-/* 2363 */ "Save the server-side TLS message trace in the provided file\0"
-/* 2423 */ "SAVE_SERVER_TRACE\0"
-/* 2441 */ "save-server-trace\0"
-/* 2459 */ "Save the client-side TLS message trace in the provided file\0"
-/* 2519 */ "SAVE_CLIENT_TRACE\0"
-/* 2537 */ "save-client-trace\0"
-/* 2555 */ "The minimum number of bits allowed for DH\0"
-/* 2597 */ "DH_BITS\0"
-/* 2605 */ "dh-bits\0"
-/* 2613 */ "Priorities string\0"
-/* 2631 */ "PRIORITY\0"
-/* 2640 */ "priority\0"
-/* 2649 */ "Certificate file or PKCS #11 URL to use\0"
-/* 2689 */ "X509CAFILE\0"
-/* 2700 */ "x509cafile\0"
-/* 2711 */ "CRL file to use\0"
-/* 2727 */ "X509CRLFILE\0"
-/* 2739 */ "x509crlfile\0"
-/* 2751 */ "X.509 key file or PKCS #11 URL to use\0"
-/* 2789 */ "X509KEYFILE\0"
-/* 2801 */ "x509keyfile\0"
-/* 2813 */ "X.509 Certificate file or PKCS #11 URL to use\0"
-/* 2859 */ "X509CERTFILE\0"
-/* 2872 */ "x509certfile\0"
-/* 2885 */ "SRP username to use\0"
-/* 2905 */ "SRPUSERNAME\0"
-/* 2917 */ "srpusername\0"
-/* 2929 */ "SRP password to use\0"
-/* 2949 */ "SRPPASSWD\0"
-/* 2959 */ "srppasswd\0"
-/* 2969 */ "PSK username to use\0"
-/* 2989 */ "PSKUSERNAME\0"
-/* 3001 */ "pskusername\0"
-/* 3013 */ "PSK key (in hex) to use\0"
-/* 3037 */ "PSKKEY\0"
-/* 3044 */ "pskkey\0"
-/* 3051 */ "The port or service to connect to\0"
-/* 3085 */ "PORT\0"
-/* 3090 */ "port\0"
-/* 3095 */ "Don't abort program if server certificate can't be validated\0"
-/* 3156 */ "INSECURE\0"
-/* 3165 */ "insecure\0"
-/* 3174 */ "Allow broken algorithms, such as MD5 for certificate verification\0"
-/* 3240 */ "VERIFY_ALLOW_BROKEN\0"
-/* 3260 */ "verify-allow-broken\0"
-/* 3280 */ "Use length-hiding padding to prevent traffic analysis (deprecated)\0"
-/* 3347 */ "RANGES\0"
-/* 3354 */ "ranges\0"
-/* 3361 */ "Benchmark individual ciphers\0"
-/* 3390 */ "BENCHMARK_CIPHERS\0"
-/* 3408 */ "benchmark-ciphers\0"
-/* 3426 */ "Benchmark TLS key exchange methods\0"
-/* 3461 */ "BENCHMARK_TLS_KX\0"
-/* 3478 */ "benchmark-tls-kx\0"
-/* 3495 */ "Benchmark TLS ciphers\0"
-/* 3517 */ "BENCHMARK_TLS_CIPHERS\0"
-/* 3539 */ "benchmark-tls-ciphers\0"
-/* 3561 */ "Print a list of the supported algorithms and modes\0"
-/* 3612 */ "LIST\0"
-/* 3617 */ "list\0"
-/* 3622 */ "Print a list of the supported priority strings\0"
-/* 3669 */ "PRIORITY_LIST\0"
-/* 3683 */ "priority-list\0"
-/* 3697 */ "Don't allow session tickets\0"
-/* 3725 */ "NOTICKET\0"
-/* 3734 */ "noticket\0"
-/* 3743 */ "Offer SRTP profiles\0"
-/* 3763 */ "SRTP_PROFILES\0"
-/* 3777 */ "srtp-profiles\0"
-/* 3791 */ "Application layer protocol\0"
-/* 3818 */ "ALPN\0"
-/* 3823 */ "alpn\0"
-/* 3828 */ "Activate heartbeat support\0"
-/* 3855 */ "HEARTBEAT\0"
-/* 3865 */ "heartbeat\0"
-/* 3875 */ "The maximum record size to advertize\0"
-/* 3912 */ "RECORDSIZE\0"
-/* 3923 */ "recordsize\0"
-/* 3934 */ "Do not send a Server Name Indication (SNI)\0"
-/* 3977 */ "DISABLE_SNI\0"
-/* 3989 */ "disable-sni\0"
-/* 4001 */ "Disable all the TLS extensions (deprecated)\0"
-/* 4045 */ "DISABLE_EXTENSIONS\0"
-/* 4064 */ "disable-extensions\0"
-/* 4083 */ "Send a single key share under TLS1.3\0"
-/* 4120 */ "SINGLE_KEY_SHARE\0"
-/* 4137 */ "single-key-share\0"
-/* 4154 */ "Enable post-handshake authentication under TLS1.3\0"
-/* 4204 */ "POST_HANDSHAKE_AUTH\0"
-/* 4224 */ "post-handshake-auth\0"
-/* 4244 */ "Inline commands of the form ^<cmd>^\0"
-/* 4280 */ "INLINE_COMMANDS\0"
-/* 4296 */ "inline-commands\0"
-/* 4312 */ "Change the default delimiter for inline commands.\0"
-/* 4362 */ "INLINE_COMMANDS_PREFIX\0"
-/* 4385 */ "inline-commands-prefix\0"
-/* 4408 */ "Specify the PKCS #11 provider library\0"
-/* 4446 */ "PROVIDER\0"
-/* 4455 */ "provider\0"
-/* 4464 */ "Reports the status of the FIPS140-2 mode in gnutls library\0"
-/* 4523 */ "FIPS140_MODE\0"
-/* 4536 */ "fips140-mode\0"
-/* 4549 */ "display extended usage information and exit\0"
-/* 4593 */ "help\0"
-/* 4598 */ "extended usage information passed thru pager\0"
-/* 4643 */ "more-help\0"
-/* 4653 */ "output version information and exit\0"
-/* 4689 */ "version\0"
-/* 4697 */ "GNUTLS_CLI\0"
-/* 4708 */ "gnutls-cli - GnuTLS client\n"
+/* 1963 */ "STARTTLS_PROTO\0"
+/* 1978 */ "starttls-proto\0"
+/* 1993 */ "Use DTLS (datagram TLS) over UDP\0"
+/* 2026 */ "UDP\0"
+/* 2030 */ "udp\0"
+/* 2034 */ "Set MTU for datagram TLS\0"
+/* 2059 */ "MTU\0"
+/* 2063 */ "mtu\0"
+/* 2067 */ "Send CR LF instead of LF\0"
+/* 2092 */ "CRLF\0"
+/* 2097 */ "crlf\0"
+/* 2102 */ "Enable TCP Fast Open\0"
+/* 2123 */ "FASTOPEN\0"
+/* 2132 */ "fastopen\0"
+/* 2141 */ "Use DER format for certificates to read from\0"
+/* 2186 */ "X509FMTDER\0"
+/* 2197 */ "x509fmtder\0"
+/* 2208 */ "Print peer's certificate in PEM format\0"
+/* 2247 */ "PRINT_CERT\0"
+/* 2258 */ "print-cert\0"
+/* 2269 */ "Save the peer's certificate chain in the specified file in PEM format\0"
+/* 2339 */ "SAVE_CERT\0"
+/* 2349 */ "save-cert\0"
+/* 2359 */ "Save the peer's OCSP status response in the provided file\0"
+/* 2417 */ "SAVE_OCSP\0"
+/* 2427 */ "save-ocsp\0"
+/* 2437 */ "Save the server-side TLS message trace in the provided file\0"
+/* 2497 */ "SAVE_SERVER_TRACE\0"
+/* 2515 */ "save-server-trace\0"
+/* 2533 */ "Save the client-side TLS message trace in the provided file\0"
+/* 2593 */ "SAVE_CLIENT_TRACE\0"
+/* 2611 */ "save-client-trace\0"
+/* 2629 */ "The minimum number of bits allowed for DH\0"
+/* 2671 */ "DH_BITS\0"
+/* 2679 */ "dh-bits\0"
+/* 2687 */ "Priorities string\0"
+/* 2705 */ "PRIORITY\0"
+/* 2714 */ "priority\0"
+/* 2723 */ "Certificate file or PKCS #11 URL to use\0"
+/* 2763 */ "X509CAFILE\0"
+/* 2774 */ "x509cafile\0"
+/* 2785 */ "CRL file to use\0"
+/* 2801 */ "X509CRLFILE\0"
+/* 2813 */ "x509crlfile\0"
+/* 2825 */ "X.509 key file or PKCS #11 URL to use\0"
+/* 2863 */ "X509KEYFILE\0"
+/* 2875 */ "x509keyfile\0"
+/* 2887 */ "X.509 Certificate file or PKCS #11 URL to use\0"
+/* 2933 */ "X509CERTFILE\0"
+/* 2946 */ "x509certfile\0"
+/* 2959 */ "SRP username to use\0"
+/* 2979 */ "SRPUSERNAME\0"
+/* 2991 */ "srpusername\0"
+/* 3003 */ "SRP password to use\0"
+/* 3023 */ "SRPPASSWD\0"
+/* 3033 */ "srppasswd\0"
+/* 3043 */ "PSK username to use\0"
+/* 3063 */ "PSKUSERNAME\0"
+/* 3075 */ "pskusername\0"
+/* 3087 */ "PSK key (in hex) to use\0"
+/* 3111 */ "PSKKEY\0"
+/* 3118 */ "pskkey\0"
+/* 3125 */ "The port or service to connect to\0"
+/* 3159 */ "PORT\0"
+/* 3164 */ "port\0"
+/* 3169 */ "Don't abort program if server certificate can't be validated\0"
+/* 3230 */ "INSECURE\0"
+/* 3239 */ "insecure\0"
+/* 3248 */ "Allow broken algorithms, such as MD5 for certificate verification\0"
+/* 3314 */ "VERIFY_ALLOW_BROKEN\0"
+/* 3334 */ "verify-allow-broken\0"
+/* 3354 */ "Use length-hiding padding to prevent traffic analysis (deprecated)\0"
+/* 3421 */ "RANGES\0"
+/* 3428 */ "ranges\0"
+/* 3435 */ "Benchmark individual ciphers\0"
+/* 3464 */ "BENCHMARK_CIPHERS\0"
+/* 3482 */ "benchmark-ciphers\0"
+/* 3500 */ "Benchmark TLS key exchange methods\0"
+/* 3535 */ "BENCHMARK_TLS_KX\0"
+/* 3552 */ "benchmark-tls-kx\0"
+/* 3569 */ "Benchmark TLS ciphers\0"
+/* 3591 */ "BENCHMARK_TLS_CIPHERS\0"
+/* 3613 */ "benchmark-tls-ciphers\0"
+/* 3635 */ "Print a list of the supported algorithms and modes\0"
+/* 3686 */ "LIST\0"
+/* 3691 */ "list\0"
+/* 3696 */ "Print a list of the supported priority strings\0"
+/* 3743 */ "PRIORITY_LIST\0"
+/* 3757 */ "priority-list\0"
+/* 3771 */ "Don't allow session tickets\0"
+/* 3799 */ "NOTICKET\0"
+/* 3808 */ "noticket\0"
+/* 3817 */ "Offer SRTP profiles\0"
+/* 3837 */ "SRTP_PROFILES\0"
+/* 3851 */ "srtp-profiles\0"
+/* 3865 */ "Application layer protocol\0"
+/* 3892 */ "ALPN\0"
+/* 3897 */ "alpn\0"
+/* 3902 */ "Activate heartbeat support\0"
+/* 3929 */ "HEARTBEAT\0"
+/* 3939 */ "heartbeat\0"
+/* 3949 */ "The maximum record size to advertize\0"
+/* 3986 */ "RECORDSIZE\0"
+/* 3997 */ "recordsize\0"
+/* 4008 */ "Do not send a Server Name Indication (SNI)\0"
+/* 4051 */ "DISABLE_SNI\0"
+/* 4063 */ "disable-sni\0"
+/* 4075 */ "Disable all the TLS extensions (deprecated)\0"
+/* 4119 */ "DISABLE_EXTENSIONS\0"
+/* 4138 */ "disable-extensions\0"
+/* 4157 */ "Send a single key share under TLS1.3\0"
+/* 4194 */ "SINGLE_KEY_SHARE\0"
+/* 4211 */ "single-key-share\0"
+/* 4228 */ "Enable post-handshake authentication under TLS1.3\0"
+/* 4278 */ "POST_HANDSHAKE_AUTH\0"
+/* 4298 */ "post-handshake-auth\0"
+/* 4318 */ "Inline commands of the form ^<cmd>^\0"
+/* 4354 */ "INLINE_COMMANDS\0"
+/* 4370 */ "inline-commands\0"
+/* 4386 */ "Change the default delimiter for inline commands.\0"
+/* 4436 */ "INLINE_COMMANDS_PREFIX\0"
+/* 4459 */ "inline-commands-prefix\0"
+/* 4482 */ "Specify the PKCS #11 provider library\0"
+/* 4520 */ "PROVIDER\0"
+/* 4529 */ "provider\0"
+/* 4538 */ "Reports the status of the FIPS140-2 mode in gnutls library\0"
+/* 4597 */ "FIPS140_MODE\0"
+/* 4610 */ "fips140-mode\0"
+/* 4623 */ "display extended usage information and exit\0"
+/* 4667 */ "help\0"
+/* 4672 */ "extended usage information passed thru pager\0"
+/* 4717 */ "more-help\0"
+/* 4727 */ "output version information and exit\0"
+/* 4763 */ "version\0"
+/* 4771 */ "GNUTLS_CLI\0"
+/* 4782 */ "gnutls-cli - GnuTLS client\n"
"Usage: %s [ -<flag> [<val>] | --<name>[{=| }<val>] ]... [hostname]\n\0"
-/* 4804 */ "bugs@gnutls.org\0"
-/* 4820 */ "\n\0"
-/* 4822 */ "Simple client program to set up a TLS connection to some other computer. It\n"
+/* 4878 */ "bugs@gnutls.org\0"
+/* 4894 */ "\n\0"
+/* 4896 */ "Simple client program to set up a TLS connection to some other computer. It\n"
"sets up a TLS connection and forwards data from the standard input to the\n"
"secured socket and vice versa.\n\0"
-/* 5005 */ "gnutls-cli 3.6.4\0"
-/* 5022 */ "Usage: gnutls-cli [options] hostname\n"
+/* 5079 */ "gnutls-cli 3.6.4\0"
+/* 5096 */ "Usage: gnutls-cli [options] hostname\n"
"gnutls-cli --help for usage instructions.\n";
/**
@@ -404,14 +407,27 @@ static char const gnutls_cli_opt_strs[5102] =
#define RESUME_FLAGS (OPTST_DISABLED)
/**
+ * earlydata option description:
+ */
+/** Descriptive text for the earlydata option */
+#define EARLYDATA_DESC (gnutls_cli_opt_strs+1415)
+/** Upper-cased name for the earlydata option */
+#define EARLYDATA_NAME (gnutls_cli_opt_strs+1469)
+/** Name string for the earlydata option */
+#define EARLYDATA_name (gnutls_cli_opt_strs+1479)
+/** Compiled in flag settings for the earlydata option */
+#define EARLYDATA_FLAGS (OPTST_DISABLED \
+ | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING))
+
+/**
* rehandshake option description:
*/
/** Descriptive text for the rehandshake option */
-#define REHANDSHAKE_DESC (gnutls_cli_opt_strs+1415)
+#define REHANDSHAKE_DESC (gnutls_cli_opt_strs+1489)
/** Upper-cased name for the rehandshake option */
-#define REHANDSHAKE_NAME (gnutls_cli_opt_strs+1451)
+#define REHANDSHAKE_NAME (gnutls_cli_opt_strs+1525)
/** Name string for the rehandshake option */
-#define REHANDSHAKE_name (gnutls_cli_opt_strs+1463)
+#define REHANDSHAKE_name (gnutls_cli_opt_strs+1537)
/** Compiled in flag settings for the rehandshake option */
#define REHANDSHAKE_FLAGS (OPTST_DISABLED)
@@ -419,11 +435,11 @@ static char const gnutls_cli_opt_strs[5102] =
* sni-hostname option description:
*/
/** Descriptive text for the sni-hostname option */
-#define SNI_HOSTNAME_DESC (gnutls_cli_opt_strs+1475)
+#define SNI_HOSTNAME_DESC (gnutls_cli_opt_strs+1549)
/** Upper-cased name for the sni-hostname option */
-#define SNI_HOSTNAME_NAME (gnutls_cli_opt_strs+1530)
+#define SNI_HOSTNAME_NAME (gnutls_cli_opt_strs+1604)
/** Name string for the sni-hostname option */
-#define SNI_HOSTNAME_name (gnutls_cli_opt_strs+1543)
+#define SNI_HOSTNAME_name (gnutls_cli_opt_strs+1617)
/** Compiled in flag settings for the sni-hostname option */
#define SNI_HOSTNAME_FLAGS (OPTST_DISABLED \
| OPTST_SET_ARGTYPE(OPARG_TYPE_STRING))
@@ -432,11 +448,11 @@ static char const gnutls_cli_opt_strs[5102] =
* verify-hostname option description:
*/
/** Descriptive text for the verify-hostname option */
-#define VERIFY_HOSTNAME_DESC (gnutls_cli_opt_strs+1556)
+#define VERIFY_HOSTNAME_DESC (gnutls_cli_opt_strs+1630)
/** Upper-cased name for the verify-hostname option */
-#define VERIFY_HOSTNAME_NAME (gnutls_cli_opt_strs+1596)
+#define VERIFY_HOSTNAME_NAME (gnutls_cli_opt_strs+1670)
/** Name string for the verify-hostname option */
-#define VERIFY_HOSTNAME_name (gnutls_cli_opt_strs+1612)
+#define VERIFY_HOSTNAME_name (gnutls_cli_opt_strs+1686)
/** Compiled in flag settings for the verify-hostname option */
#define VERIFY_HOSTNAME_FLAGS (OPTST_DISABLED \
| OPTST_SET_ARGTYPE(OPARG_TYPE_STRING))
@@ -445,11 +461,11 @@ static char const gnutls_cli_opt_strs[5102] =
* starttls option description:
*/
/** Descriptive text for the starttls option */
-#define STARTTLS_DESC (gnutls_cli_opt_strs+1628)
+#define STARTTLS_DESC (gnutls_cli_opt_strs+1702)
/** Upper-cased name for the starttls option */
-#define STARTTLS_NAME (gnutls_cli_opt_strs+1677)
+#define STARTTLS_NAME (gnutls_cli_opt_strs+1751)
/** Name string for the starttls option */
-#define STARTTLS_name (gnutls_cli_opt_strs+1686)
+#define STARTTLS_name (gnutls_cli_opt_strs+1760)
/** Compiled in flag settings for the starttls option */
#define STARTTLS_FLAGS (OPTST_DISABLED)
@@ -457,10 +473,10 @@ static char const gnutls_cli_opt_strs[5102] =
* app-proto option description:
*/
/** Descriptive text for the app-proto option */
-#define APP_PROTO_DESC (gnutls_cli_opt_strs+1695)
+#define APP_PROTO_DESC (gnutls_cli_opt_strs+1769)
#define APP_PROTO_NAME NULL
/** Unmodified name string for the app-proto option */
-#define APP_PROTO_name (gnutls_cli_opt_strs+1736)
+#define APP_PROTO_name (gnutls_cli_opt_strs+1810)
/** Compiled in flag settings for the app-proto option */
#define APP_PROTO_FLAGS (STARTTLS_PROTO_FLAGS | OPTST_ALIAS)
@@ -469,11 +485,11 @@ static char const gnutls_cli_opt_strs[5102] =
* "Must also have options" and "Incompatible options":
*/
/** Descriptive text for the starttls-proto option */
-#define STARTTLS_PROTO_DESC (gnutls_cli_opt_strs+1746)
+#define STARTTLS_PROTO_DESC (gnutls_cli_opt_strs+1820)
/** Upper-cased name for the starttls-proto option */
-#define STARTTLS_PROTO_NAME (gnutls_cli_opt_strs+1889)
+#define STARTTLS_PROTO_NAME (gnutls_cli_opt_strs+1963)
/** Name string for the starttls-proto option */
-#define STARTTLS_PROTO_name (gnutls_cli_opt_strs+1904)
+#define STARTTLS_PROTO_name (gnutls_cli_opt_strs+1978)
/** Other options that appear in conjunction with the starttls-proto option */
static int const aStarttls_ProtoCantList[] = {
INDEX_OPT_STARTTLS, NO_EQUIVALENT };
@@ -485,11 +501,11 @@ static int const aStarttls_ProtoCantList[] = {
* udp option description:
*/
/** Descriptive text for the udp option */
-#define UDP_DESC (gnutls_cli_opt_strs+1919)
+#define UDP_DESC (gnutls_cli_opt_strs+1993)
/** Upper-cased name for the udp option */
-#define UDP_NAME (gnutls_cli_opt_strs+1952)
+#define UDP_NAME (gnutls_cli_opt_strs+2026)
/** Name string for the udp option */
-#define UDP_name (gnutls_cli_opt_strs+1956)
+#define UDP_name (gnutls_cli_opt_strs+2030)
/** Compiled in flag settings for the udp option */
#define UDP_FLAGS (OPTST_DISABLED)
@@ -497,11 +513,11 @@ static int const aStarttls_ProtoCantList[] = {
* mtu option description:
*/
/** Descriptive text for the mtu option */
-#define MTU_DESC (gnutls_cli_opt_strs+1960)
+#define MTU_DESC (gnutls_cli_opt_strs+2034)
/** Upper-cased name for the mtu option */
-#define MTU_NAME (gnutls_cli_opt_strs+1985)
+#define MTU_NAME (gnutls_cli_opt_strs+2059)
/** Name string for the mtu option */
-#define MTU_name (gnutls_cli_opt_strs+1989)
+#define MTU_name (gnutls_cli_opt_strs+2063)
/** Compiled in flag settings for the mtu option */
#define MTU_FLAGS (OPTST_DISABLED \
| OPTST_SET_ARGTYPE(OPARG_TYPE_NUMERIC))
@@ -510,11 +526,11 @@ static int const aStarttls_ProtoCantList[] = {
* crlf option description:
*/
/** Descriptive text for the crlf option */
-#define CRLF_DESC (gnutls_cli_opt_strs+1993)
+#define CRLF_DESC (gnutls_cli_opt_strs+2067)
/** Upper-cased name for the crlf option */
-#define CRLF_NAME (gnutls_cli_opt_strs+2018)
+#define CRLF_NAME (gnutls_cli_opt_strs+2092)
/** Name string for the crlf option */
-#define CRLF_name (gnutls_cli_opt_strs+2023)
+#define CRLF_name (gnutls_cli_opt_strs+2097)
/** Compiled in flag settings for the crlf option */
#define CRLF_FLAGS (OPTST_DISABLED)
@@ -522,11 +538,11 @@ static int const aStarttls_ProtoCantList[] = {
* fastopen option description:
*/
/** Descriptive text for the fastopen option */
-#define FASTOPEN_DESC (gnutls_cli_opt_strs+2028)
+#define FASTOPEN_DESC (gnutls_cli_opt_strs+2102)
/** Upper-cased name for the fastopen option */
-#define FASTOPEN_NAME (gnutls_cli_opt_strs+2049)
+#define FASTOPEN_NAME (gnutls_cli_opt_strs+2123)
/** Name string for the fastopen option */
-#define FASTOPEN_name (gnutls_cli_opt_strs+2058)
+#define FASTOPEN_name (gnutls_cli_opt_strs+2132)
/** Compiled in flag settings for the fastopen option */
#define FASTOPEN_FLAGS (OPTST_DISABLED)
@@ -534,11 +550,11 @@ static int const aStarttls_ProtoCantList[] = {
* x509fmtder option description:
*/
/** Descriptive text for the x509fmtder option */
-#define X509FMTDER_DESC (gnutls_cli_opt_strs+2067)
+#define X509FMTDER_DESC (gnutls_cli_opt_strs+2141)
/** Upper-cased name for the x509fmtder option */
-#define X509FMTDER_NAME (gnutls_cli_opt_strs+2112)
+#define X509FMTDER_NAME (gnutls_cli_opt_strs+2186)
/** Name string for the x509fmtder option */
-#define X509FMTDER_name (gnutls_cli_opt_strs+2123)
+#define X509FMTDER_name (gnutls_cli_opt_strs+2197)
/** Compiled in flag settings for the x509fmtder option */
#define X509FMTDER_FLAGS (OPTST_DISABLED)
@@ -546,11 +562,11 @@ static int const aStarttls_ProtoCantList[] = {
* print-cert option description:
*/
/** Descriptive text for the print-cert option */
-#define PRINT_CERT_DESC (gnutls_cli_opt_strs+2134)
+#define PRINT_CERT_DESC (gnutls_cli_opt_strs+2208)
/** Upper-cased name for the print-cert option */
-#define PRINT_CERT_NAME (gnutls_cli_opt_strs+2173)
+#define PRINT_CERT_NAME (gnutls_cli_opt_strs+2247)
/** Name string for the print-cert option */
-#define PRINT_CERT_name (gnutls_cli_opt_strs+2184)
+#define PRINT_CERT_name (gnutls_cli_opt_strs+2258)
/** Compiled in flag settings for the print-cert option */
#define PRINT_CERT_FLAGS (OPTST_DISABLED)
@@ -558,11 +574,11 @@ static int const aStarttls_ProtoCantList[] = {
* save-cert option description:
*/
/** Descriptive text for the save-cert option */
-#define SAVE_CERT_DESC (gnutls_cli_opt_strs+2195)
+#define SAVE_CERT_DESC (gnutls_cli_opt_strs+2269)
/** Upper-cased name for the save-cert option */
-#define SAVE_CERT_NAME (gnutls_cli_opt_strs+2265)
+#define SAVE_CERT_NAME (gnutls_cli_opt_strs+2339)
/** Name string for the save-cert option */
-#define SAVE_CERT_name (gnutls_cli_opt_strs+2275)
+#define SAVE_CERT_name (gnutls_cli_opt_strs+2349)
/** Compiled in flag settings for the save-cert option */
#define SAVE_CERT_FLAGS (OPTST_DISABLED \
| OPTST_SET_ARGTYPE(OPARG_TYPE_STRING))
@@ -571,11 +587,11 @@ static int const aStarttls_ProtoCantList[] = {
* save-ocsp option description:
*/
/** Descriptive text for the save-ocsp option */
-#define SAVE_OCSP_DESC (gnutls_cli_opt_strs+2285)
+#define SAVE_OCSP_DESC (gnutls_cli_opt_strs+2359)
/** Upper-cased name for the save-ocsp option */
-#define SAVE_OCSP_NAME (gnutls_cli_opt_strs+2343)
+#define SAVE_OCSP_NAME (gnutls_cli_opt_strs+2417)
/** Name string for the save-ocsp option */
-#define SAVE_OCSP_name (gnutls_cli_opt_strs+2353)
+#define SAVE_OCSP_name (gnutls_cli_opt_strs+2427)
/** Compiled in flag settings for the save-ocsp option */
#define SAVE_OCSP_FLAGS (OPTST_DISABLED \
| OPTST_SET_ARGTYPE(OPARG_TYPE_STRING))
@@ -584,11 +600,11 @@ static int const aStarttls_ProtoCantList[] = {
* save-server-trace option description:
*/
/** Descriptive text for the save-server-trace option */
-#define SAVE_SERVER_TRACE_DESC (gnutls_cli_opt_strs+2363)
+#define SAVE_SERVER_TRACE_DESC (gnutls_cli_opt_strs+2437)
/** Upper-cased name for the save-server-trace option */
-#define SAVE_SERVER_TRACE_NAME (gnutls_cli_opt_strs+2423)
+#define SAVE_SERVER_TRACE_NAME (gnutls_cli_opt_strs+2497)
/** Name string for the save-server-trace option */
-#define SAVE_SERVER_TRACE_name (gnutls_cli_opt_strs+2441)
+#define SAVE_SERVER_TRACE_name (gnutls_cli_opt_strs+2515)
/** Compiled in flag settings for the save-server-trace option */
#define SAVE_SERVER_TRACE_FLAGS (OPTST_DISABLED \
| OPTST_SET_ARGTYPE(OPARG_TYPE_STRING))
@@ -597,11 +613,11 @@ static int const aStarttls_ProtoCantList[] = {
* save-client-trace option description:
*/
/** Descriptive text for the save-client-trace option */
-#define SAVE_CLIENT_TRACE_DESC (gnutls_cli_opt_strs+2459)
+#define SAVE_CLIENT_TRACE_DESC (gnutls_cli_opt_strs+2533)
/** Upper-cased name for the save-client-trace option */
-#define SAVE_CLIENT_TRACE_NAME (gnutls_cli_opt_strs+2519)
+#define SAVE_CLIENT_TRACE_NAME (gnutls_cli_opt_strs+2593)
/** Name string for the save-client-trace option */
-#define SAVE_CLIENT_TRACE_name (gnutls_cli_opt_strs+2537)
+#define SAVE_CLIENT_TRACE_name (gnutls_cli_opt_strs+2611)
/** Compiled in flag settings for the save-client-trace option */
#define SAVE_CLIENT_TRACE_FLAGS (OPTST_DISABLED \
| OPTST_SET_ARGTYPE(OPARG_TYPE_STRING))
@@ -610,11 +626,11 @@ static int const aStarttls_ProtoCantList[] = {
* dh-bits option description:
*/
/** Descriptive text for the dh-bits option */
-#define DH_BITS_DESC (gnutls_cli_opt_strs+2555)
+#define DH_BITS_DESC (gnutls_cli_opt_strs+2629)
/** Upper-cased name for the dh-bits option */
-#define DH_BITS_NAME (gnutls_cli_opt_strs+2597)
+#define DH_BITS_NAME (gnutls_cli_opt_strs+2671)
/** Name string for the dh-bits option */
-#define DH_BITS_name (gnutls_cli_opt_strs+2605)
+#define DH_BITS_name (gnutls_cli_opt_strs+2679)
/** Compiled in flag settings for the dh-bits option */
#define DH_BITS_FLAGS (OPTST_DISABLED \
| OPTST_SET_ARGTYPE(OPARG_TYPE_NUMERIC))
@@ -623,11 +639,11 @@ static int const aStarttls_ProtoCantList[] = {
* priority option description:
*/
/** Descriptive text for the priority option */
-#define PRIORITY_DESC (gnutls_cli_opt_strs+2613)
+#define PRIORITY_DESC (gnutls_cli_opt_strs+2687)
/** Upper-cased name for the priority option */
-#define PRIORITY_NAME (gnutls_cli_opt_strs+2631)
+#define PRIORITY_NAME (gnutls_cli_opt_strs+2705)
/** Name string for the priority option */
-#define PRIORITY_name (gnutls_cli_opt_strs+2640)
+#define PRIORITY_name (gnutls_cli_opt_strs+2714)
/** Compiled in flag settings for the priority option */
#define PRIORITY_FLAGS (OPTST_DISABLED \
| OPTST_SET_ARGTYPE(OPARG_TYPE_STRING))
@@ -636,11 +652,11 @@ static int const aStarttls_ProtoCantList[] = {
* x509cafile option description:
*/
/** Descriptive text for the x509cafile option */
-#define X509CAFILE_DESC (gnutls_cli_opt_strs+2649)
+#define X509CAFILE_DESC (gnutls_cli_opt_strs+2723)
/** Upper-cased name for the x509cafile option */
-#define X509CAFILE_NAME (gnutls_cli_opt_strs+2689)
+#define X509CAFILE_NAME (gnutls_cli_opt_strs+2763)
/** Name string for the x509cafile option */
-#define X509CAFILE_name (gnutls_cli_opt_strs+2700)
+#define X509CAFILE_name (gnutls_cli_opt_strs+2774)
/** Compiled in flag settings for the x509cafile option */
#define X509CAFILE_FLAGS (OPTST_DISABLED \
| OPTST_SET_ARGTYPE(OPARG_TYPE_STRING))
@@ -649,11 +665,11 @@ static int const aStarttls_ProtoCantList[] = {
* x509crlfile option description:
*/
/** Descriptive text for the x509crlfile option */
-#define X509CRLFILE_DESC (gnutls_cli_opt_strs+2711)
+#define X509CRLFILE_DESC (gnutls_cli_opt_strs+2785)
/** Upper-cased name for the x509crlfile option */
-#define X509CRLFILE_NAME (gnutls_cli_opt_strs+2727)
+#define X509CRLFILE_NAME (gnutls_cli_opt_strs+2801)
/** Name string for the x509crlfile option */
-#define X509CRLFILE_name (gnutls_cli_opt_strs+2739)
+#define X509CRLFILE_name (gnutls_cli_opt_strs+2813)
/** Compiled in flag settings for the x509crlfile option */
#define X509CRLFILE_FLAGS (OPTST_DISABLED \
| OPTST_SET_ARGTYPE(OPARG_TYPE_FILE))
@@ -662,11 +678,11 @@ static int const aStarttls_ProtoCantList[] = {
* x509keyfile option description:
*/
/** Descriptive text for the x509keyfile option */
-#define X509KEYFILE_DESC (gnutls_cli_opt_strs+2751)
+#define X509KEYFILE_DESC (gnutls_cli_opt_strs+2825)
/** Upper-cased name for the x509keyfile option */
-#define X509KEYFILE_NAME (gnutls_cli_opt_strs+2789)
+#define X509KEYFILE_NAME (gnutls_cli_opt_strs+2863)
/** Name string for the x509keyfile option */
-#define X509KEYFILE_name (gnutls_cli_opt_strs+2801)
+#define X509KEYFILE_name (gnutls_cli_opt_strs+2875)
/** Compiled in flag settings for the x509keyfile option */
#define X509KEYFILE_FLAGS (OPTST_DISABLED \
| OPTST_SET_ARGTYPE(OPARG_TYPE_STRING))
@@ -676,11 +692,11 @@ static int const aStarttls_ProtoCantList[] = {
* "Must also have options" and "Incompatible options":
*/
/** Descriptive text for the x509certfile option */
-#define X509CERTFILE_DESC (gnutls_cli_opt_strs+2813)
+#define X509CERTFILE_DESC (gnutls_cli_opt_strs+2887)
/** Upper-cased name for the x509certfile option */
-#define X509CERTFILE_NAME (gnutls_cli_opt_strs+2859)
+#define X509CERTFILE_NAME (gnutls_cli_opt_strs+2933)
/** Name string for the x509certfile option */
-#define X509CERTFILE_name (gnutls_cli_opt_strs+2872)
+#define X509CERTFILE_name (gnutls_cli_opt_strs+2946)
/** Other options that are required by the x509certfile option */
static int const aX509certfileMustList[] = {
INDEX_OPT_X509KEYFILE, NO_EQUIVALENT };
@@ -692,11 +708,11 @@ static int const aX509certfileMustList[] = {
* srpusername option description:
*/
/** Descriptive text for the srpusername option */
-#define SRPUSERNAME_DESC (gnutls_cli_opt_strs+2885)
+#define SRPUSERNAME_DESC (gnutls_cli_opt_strs+2959)
/** Upper-cased name for the srpusername option */
-#define SRPUSERNAME_NAME (gnutls_cli_opt_strs+2905)
+#define SRPUSERNAME_NAME (gnutls_cli_opt_strs+2979)
/** Name string for the srpusername option */
-#define SRPUSERNAME_name (gnutls_cli_opt_strs+2917)
+#define SRPUSERNAME_name (gnutls_cli_opt_strs+2991)
/** Compiled in flag settings for the srpusername option */
#define SRPUSERNAME_FLAGS (OPTST_DISABLED \
| OPTST_SET_ARGTYPE(OPARG_TYPE_STRING))
@@ -705,11 +721,11 @@ static int const aX509certfileMustList[] = {
* srppasswd option description:
*/
/** Descriptive text for the srppasswd option */
-#define SRPPASSWD_DESC (gnutls_cli_opt_strs+2929)
+#define SRPPASSWD_DESC (gnutls_cli_opt_strs+3003)
/** Upper-cased name for the srppasswd option */
-#define SRPPASSWD_NAME (gnutls_cli_opt_strs+2949)
+#define SRPPASSWD_NAME (gnutls_cli_opt_strs+3023)
/** Name string for the srppasswd option */
-#define SRPPASSWD_name (gnutls_cli_opt_strs+2959)
+#define SRPPASSWD_name (gnutls_cli_opt_strs+3033)
/** Compiled in flag settings for the srppasswd option */
#define SRPPASSWD_FLAGS (OPTST_DISABLED \
| OPTST_SET_ARGTYPE(OPARG_TYPE_STRING))
@@ -718,11 +734,11 @@ static int const aX509certfileMustList[] = {
* pskusername option description:
*/
/** Descriptive text for the pskusername option */
-#define PSKUSERNAME_DESC (gnutls_cli_opt_strs+2969)
+#define PSKUSERNAME_DESC (gnutls_cli_opt_strs+3043)
/** Upper-cased name for the pskusername option */
-#define PSKUSERNAME_NAME (gnutls_cli_opt_strs+2989)
+#define PSKUSERNAME_NAME (gnutls_cli_opt_strs+3063)
/** Name string for the pskusername option */
-#define PSKUSERNAME_name (gnutls_cli_opt_strs+3001)
+#define PSKUSERNAME_name (gnutls_cli_opt_strs+3075)
/** Compiled in flag settings for the pskusername option */
#define PSKUSERNAME_FLAGS (OPTST_DISABLED \
| OPTST_SET_ARGTYPE(OPARG_TYPE_STRING))
@@ -731,11 +747,11 @@ static int const aX509certfileMustList[] = {
* pskkey option description:
*/
/** Descriptive text for the pskkey option */
-#define PSKKEY_DESC (gnutls_cli_opt_strs+3013)
+#define PSKKEY_DESC (gnutls_cli_opt_strs+3087)
/** Upper-cased name for the pskkey option */
-#define PSKKEY_NAME (gnutls_cli_opt_strs+3037)
+#define PSKKEY_NAME (gnutls_cli_opt_strs+3111)
/** Name string for the pskkey option */
-#define PSKKEY_name (gnutls_cli_opt_strs+3044)
+#define PSKKEY_name (gnutls_cli_opt_strs+3118)
/** Compiled in flag settings for the pskkey option */
#define PSKKEY_FLAGS (OPTST_DISABLED \
| OPTST_SET_ARGTYPE(OPARG_TYPE_STRING))
@@ -744,11 +760,11 @@ static int const aX509certfileMustList[] = {
* port option description:
*/
/** Descriptive text for the port option */
-#define PORT_DESC (gnutls_cli_opt_strs+3051)
+#define PORT_DESC (gnutls_cli_opt_strs+3125)
/** Upper-cased name for the port option */
-#define PORT_NAME (gnutls_cli_opt_strs+3085)
+#define PORT_NAME (gnutls_cli_opt_strs+3159)
/** Name string for the port option */
-#define PORT_name (gnutls_cli_opt_strs+3090)
+#define PORT_name (gnutls_cli_opt_strs+3164)
/** Compiled in flag settings for the port option */
#define PORT_FLAGS (OPTST_DISABLED \
| OPTST_SET_ARGTYPE(OPARG_TYPE_STRING))
@@ -757,11 +773,11 @@ static int const aX509certfileMustList[] = {
* insecure option description:
*/
/** Descriptive text for the insecure option */
-#define INSECURE_DESC (gnutls_cli_opt_strs+3095)
+#define INSECURE_DESC (gnutls_cli_opt_strs+3169)
/** Upper-cased name for the insecure option */
-#define INSECURE_NAME (gnutls_cli_opt_strs+3156)
+#define INSECURE_NAME (gnutls_cli_opt_strs+3230)
/** Name string for the insecure option */
-#define INSECURE_name (gnutls_cli_opt_strs+3165)
+#define INSECURE_name (gnutls_cli_opt_strs+3239)
/** Compiled in flag settings for the insecure option */
#define INSECURE_FLAGS (OPTST_DISABLED)
@@ -769,11 +785,11 @@ static int const aX509certfileMustList[] = {
* verify-allow-broken option description:
*/
/** Descriptive text for the verify-allow-broken option */
-#define VERIFY_ALLOW_BROKEN_DESC (gnutls_cli_opt_strs+3174)
+#define VERIFY_ALLOW_BROKEN_DESC (gnutls_cli_opt_strs+3248)
/** Upper-cased name for the verify-allow-broken option */
-#define VERIFY_ALLOW_BROKEN_NAME (gnutls_cli_opt_strs+3240)
+#define VERIFY_ALLOW_BROKEN_NAME (gnutls_cli_opt_strs+3314)
/** Name string for the verify-allow-broken option */
-#define VERIFY_ALLOW_BROKEN_name (gnutls_cli_opt_strs+3260)
+#define VERIFY_ALLOW_BROKEN_name (gnutls_cli_opt_strs+3334)
/** Compiled in flag settings for the verify-allow-broken option */
#define VERIFY_ALLOW_BROKEN_FLAGS (OPTST_DISABLED)
@@ -781,11 +797,11 @@ static int const aX509certfileMustList[] = {
* ranges option description:
*/
/** Descriptive text for the ranges option */
-#define RANGES_DESC (gnutls_cli_opt_strs+3280)
+#define RANGES_DESC (gnutls_cli_opt_strs+3354)
/** Upper-cased name for the ranges option */
-#define RANGES_NAME (gnutls_cli_opt_strs+3347)
+#define RANGES_NAME (gnutls_cli_opt_strs+3421)
/** Name string for the ranges option */
-#define RANGES_name (gnutls_cli_opt_strs+3354)
+#define RANGES_name (gnutls_cli_opt_strs+3428)
/** Compiled in flag settings for the ranges option */
#define RANGES_FLAGS (OPTST_DISABLED | OPTST_DEPRECATED)
@@ -793,11 +809,11 @@ static int const aX509certfileMustList[] = {
* benchmark-ciphers option description:
*/
/** Descriptive text for the benchmark-ciphers option */
-#define BENCHMARK_CIPHERS_DESC (gnutls_cli_opt_strs+3361)
+#define BENCHMARK_CIPHERS_DESC (gnutls_cli_opt_strs+3435)
/** Upper-cased name for the benchmark-ciphers option */
-#define BENCHMARK_CIPHERS_NAME (gnutls_cli_opt_strs+3390)
+#define BENCHMARK_CIPHERS_NAME (gnutls_cli_opt_strs+3464)
/** Name string for the benchmark-ciphers option */
-#define BENCHMARK_CIPHERS_name (gnutls_cli_opt_strs+3408)
+#define BENCHMARK_CIPHERS_name (gnutls_cli_opt_strs+3482)
/** Compiled in flag settings for the benchmark-ciphers option */
#define BENCHMARK_CIPHERS_FLAGS (OPTST_DISABLED)
@@ -805,11 +821,11 @@ static int const aX509certfileMustList[] = {
* benchmark-tls-kx option description:
*/
/** Descriptive text for the benchmark-tls-kx option */
-#define BENCHMARK_TLS_KX_DESC (gnutls_cli_opt_strs+3426)
+#define BENCHMARK_TLS_KX_DESC (gnutls_cli_opt_strs+3500)
/** Upper-cased name for the benchmark-tls-kx option */
-#define BENCHMARK_TLS_KX_NAME (gnutls_cli_opt_strs+3461)
+#define BENCHMARK_TLS_KX_NAME (gnutls_cli_opt_strs+3535)
/** Name string for the benchmark-tls-kx option */
-#define BENCHMARK_TLS_KX_name (gnutls_cli_opt_strs+3478)
+#define BENCHMARK_TLS_KX_name (gnutls_cli_opt_strs+3552)
/** Compiled in flag settings for the benchmark-tls-kx option */
#define BENCHMARK_TLS_KX_FLAGS (OPTST_DISABLED)
@@ -817,11 +833,11 @@ static int const aX509certfileMustList[] = {
* benchmark-tls-ciphers option description:
*/
/** Descriptive text for the benchmark-tls-ciphers option */
-#define BENCHMARK_TLS_CIPHERS_DESC (gnutls_cli_opt_strs+3495)
+#define BENCHMARK_TLS_CIPHERS_DESC (gnutls_cli_opt_strs+3569)
/** Upper-cased name for the benchmark-tls-ciphers option */
-#define BENCHMARK_TLS_CIPHERS_NAME (gnutls_cli_opt_strs+3517)
+#define BENCHMARK_TLS_CIPHERS_NAME (gnutls_cli_opt_strs+3591)
/** Name string for the benchmark-tls-ciphers option */
-#define BENCHMARK_TLS_CIPHERS_name (gnutls_cli_opt_strs+3539)
+#define BENCHMARK_TLS_CIPHERS_name (gnutls_cli_opt_strs+3613)
/** Compiled in flag settings for the benchmark-tls-ciphers option */
#define BENCHMARK_TLS_CIPHERS_FLAGS (OPTST_DISABLED)
@@ -830,11 +846,11 @@ static int const aX509certfileMustList[] = {
* "Must also have options" and "Incompatible options":
*/
/** Descriptive text for the list option */
-#define LIST_DESC (gnutls_cli_opt_strs+3561)
+#define LIST_DESC (gnutls_cli_opt_strs+3635)
/** Upper-cased name for the list option */
-#define LIST_NAME (gnutls_cli_opt_strs+3612)
+#define LIST_NAME (gnutls_cli_opt_strs+3686)
/** Name string for the list option */
-#define LIST_name (gnutls_cli_opt_strs+3617)
+#define LIST_name (gnutls_cli_opt_strs+3691)
/** Other options that appear in conjunction with the list option */
static int const aListCantList[] = {
INDEX_OPT_PORT, NO_EQUIVALENT };
@@ -845,11 +861,11 @@ static int const aListCantList[] = {
* priority-list option description:
*/
/** Descriptive text for the priority-list option */
-#define PRIORITY_LIST_DESC (gnutls_cli_opt_strs+3622)
+#define PRIORITY_LIST_DESC (gnutls_cli_opt_strs+3696)
/** Upper-cased name for the priority-list option */
-#define PRIORITY_LIST_NAME (gnutls_cli_opt_strs+3669)
+#define PRIORITY_LIST_NAME (gnutls_cli_opt_strs+3743)
/** Name string for the priority-list option */
-#define PRIORITY_LIST_name (gnutls_cli_opt_strs+3683)
+#define PRIORITY_LIST_name (gnutls_cli_opt_strs+3757)
/** Compiled in flag settings for the priority-list option */
#define PRIORITY_LIST_FLAGS (OPTST_DISABLED)
@@ -857,11 +873,11 @@ static int const aListCantList[] = {
* noticket option description:
*/
/** Descriptive text for the noticket option */
-#define NOTICKET_DESC (gnutls_cli_opt_strs+3697)
+#define NOTICKET_DESC (gnutls_cli_opt_strs+3771)
/** Upper-cased name for the noticket option */
-#define NOTICKET_NAME (gnutls_cli_opt_strs+3725)
+#define NOTICKET_NAME (gnutls_cli_opt_strs+3799)
/** Name string for the noticket option */
-#define NOTICKET_name (gnutls_cli_opt_strs+3734)
+#define NOTICKET_name (gnutls_cli_opt_strs+3808)
/** Compiled in flag settings for the noticket option */
#define NOTICKET_FLAGS (OPTST_DISABLED)
@@ -869,11 +885,11 @@ static int const aListCantList[] = {
* srtp_profiles option description:
*/
/** Descriptive text for the srtp_profiles option */
-#define SRTP_PROFILES_DESC (gnutls_cli_opt_strs+3743)
+#define SRTP_PROFILES_DESC (gnutls_cli_opt_strs+3817)
/** Upper-cased name for the srtp_profiles option */
-#define SRTP_PROFILES_NAME (gnutls_cli_opt_strs+3763)
+#define SRTP_PROFILES_NAME (gnutls_cli_opt_strs+3837)
/** Name string for the srtp_profiles option */
-#define SRTP_PROFILES_name (gnutls_cli_opt_strs+3777)
+#define SRTP_PROFILES_name (gnutls_cli_opt_strs+3851)
/** Compiled in flag settings for the srtp_profiles option */
#define SRTP_PROFILES_FLAGS (OPTST_DISABLED \
| OPTST_SET_ARGTYPE(OPARG_TYPE_STRING))
@@ -882,11 +898,11 @@ static int const aListCantList[] = {
* alpn option description:
*/
/** Descriptive text for the alpn option */
-#define ALPN_DESC (gnutls_cli_opt_strs+3791)
+#define ALPN_DESC (gnutls_cli_opt_strs+3865)
/** Upper-cased name for the alpn option */
-#define ALPN_NAME (gnutls_cli_opt_strs+3818)
+#define ALPN_NAME (gnutls_cli_opt_strs+3892)
/** Name string for the alpn option */
-#define ALPN_name (gnutls_cli_opt_strs+3823)
+#define ALPN_name (gnutls_cli_opt_strs+3897)
/** Compiled in flag settings for the alpn option */
#define ALPN_FLAGS (OPTST_DISABLED | OPTST_STACKED \
| OPTST_SET_ARGTYPE(OPARG_TYPE_STRING))
@@ -895,11 +911,11 @@ static int const aListCantList[] = {
* heartbeat option description:
*/
/** Descriptive text for the heartbeat option */
-#define HEARTBEAT_DESC (gnutls_cli_opt_strs+3828)
+#define HEARTBEAT_DESC (gnutls_cli_opt_strs+3902)
/** Upper-cased name for the heartbeat option */
-#define HEARTBEAT_NAME (gnutls_cli_opt_strs+3855)
+#define HEARTBEAT_NAME (gnutls_cli_opt_strs+3929)
/** Name string for the heartbeat option */
-#define HEARTBEAT_name (gnutls_cli_opt_strs+3865)
+#define HEARTBEAT_name (gnutls_cli_opt_strs+3939)
/** Compiled in flag settings for the heartbeat option */
#define HEARTBEAT_FLAGS (OPTST_DISABLED)
@@ -907,11 +923,11 @@ static int const aListCantList[] = {
* recordsize option description:
*/
/** Descriptive text for the recordsize option */
-#define RECORDSIZE_DESC (gnutls_cli_opt_strs+3875)
+#define RECORDSIZE_DESC (gnutls_cli_opt_strs+3949)
/** Upper-cased name for the recordsize option */
-#define RECORDSIZE_NAME (gnutls_cli_opt_strs+3912)
+#define RECORDSIZE_NAME (gnutls_cli_opt_strs+3986)
/** Name string for the recordsize option */
-#define RECORDSIZE_name (gnutls_cli_opt_strs+3923)
+#define RECORDSIZE_name (gnutls_cli_opt_strs+3997)
/** Compiled in flag settings for the recordsize option */
#define RECORDSIZE_FLAGS (OPTST_DISABLED \
| OPTST_SET_ARGTYPE(OPARG_TYPE_NUMERIC))
@@ -920,11 +936,11 @@ static int const aListCantList[] = {
* disable-sni option description:
*/
/** Descriptive text for the disable-sni option */
-#define DISABLE_SNI_DESC (gnutls_cli_opt_strs+3934)
+#define DISABLE_SNI_DESC (gnutls_cli_opt_strs+4008)
/** Upper-cased name for the disable-sni option */
-#define DISABLE_SNI_NAME (gnutls_cli_opt_strs+3977)
+#define DISABLE_SNI_NAME (gnutls_cli_opt_strs+4051)
/** Name string for the disable-sni option */
-#define DISABLE_SNI_name (gnutls_cli_opt_strs+3989)
+#define DISABLE_SNI_name (gnutls_cli_opt_strs+4063)
/** Compiled in flag settings for the disable-sni option */
#define DISABLE_SNI_FLAGS (OPTST_DISABLED)
@@ -932,11 +948,11 @@ static int const aListCantList[] = {
* disable-extensions option description:
*/
/** Descriptive text for the disable-extensions option */
-#define DISABLE_EXTENSIONS_DESC (gnutls_cli_opt_strs+4001)
+#define DISABLE_EXTENSIONS_DESC (gnutls_cli_opt_strs+4075)
/** Upper-cased name for the disable-extensions option */
-#define DISABLE_EXTENSIONS_NAME (gnutls_cli_opt_strs+4045)
+#define DISABLE_EXTENSIONS_NAME (gnutls_cli_opt_strs+4119)
/** Name string for the disable-extensions option */
-#define DISABLE_EXTENSIONS_name (gnutls_cli_opt_strs+4064)
+#define DISABLE_EXTENSIONS_name (gnutls_cli_opt_strs+4138)
/** Compiled in flag settings for the disable-extensions option */
#define DISABLE_EXTENSIONS_FLAGS (OPTST_DISABLED | OPTST_DEPRECATED)
@@ -944,11 +960,11 @@ static int const aListCantList[] = {
* single-key-share option description:
*/
/** Descriptive text for the single-key-share option */
-#define SINGLE_KEY_SHARE_DESC (gnutls_cli_opt_strs+4083)
+#define SINGLE_KEY_SHARE_DESC (gnutls_cli_opt_strs+4157)
/** Upper-cased name for the single-key-share option */
-#define SINGLE_KEY_SHARE_NAME (gnutls_cli_opt_strs+4120)
+#define SINGLE_KEY_SHARE_NAME (gnutls_cli_opt_strs+4194)
/** Name string for the single-key-share option */
-#define SINGLE_KEY_SHARE_name (gnutls_cli_opt_strs+4137)
+#define SINGLE_KEY_SHARE_name (gnutls_cli_opt_strs+4211)
/** Compiled in flag settings for the single-key-share option */
#define SINGLE_KEY_SHARE_FLAGS (OPTST_DISABLED)
@@ -956,11 +972,11 @@ static int const aListCantList[] = {
* post-handshake-auth option description:
*/
/** Descriptive text for the post-handshake-auth option */
-#define POST_HANDSHAKE_AUTH_DESC (gnutls_cli_opt_strs+4154)
+#define POST_HANDSHAKE_AUTH_DESC (gnutls_cli_opt_strs+4228)
/** Upper-cased name for the post-handshake-auth option */
-#define POST_HANDSHAKE_AUTH_NAME (gnutls_cli_opt_strs+4204)
+#define POST_HANDSHAKE_AUTH_NAME (gnutls_cli_opt_strs+4278)
/** Name string for the post-handshake-auth option */
-#define POST_HANDSHAKE_AUTH_name (gnutls_cli_opt_strs+4224)
+#define POST_HANDSHAKE_AUTH_name (gnutls_cli_opt_strs+4298)
/** Compiled in flag settings for the post-handshake-auth option */
#define POST_HANDSHAKE_AUTH_FLAGS (OPTST_DISABLED)
@@ -968,11 +984,11 @@ static int const aListCantList[] = {
* inline-commands option description:
*/
/** Descriptive text for the inline-commands option */
-#define INLINE_COMMANDS_DESC (gnutls_cli_opt_strs+4244)
+#define INLINE_COMMANDS_DESC (gnutls_cli_opt_strs+4318)
/** Upper-cased name for the inline-commands option */
-#define INLINE_COMMANDS_NAME (gnutls_cli_opt_strs+4280)
+#define INLINE_COMMANDS_NAME (gnutls_cli_opt_strs+4354)
/** Name string for the inline-commands option */
-#define INLINE_COMMANDS_name (gnutls_cli_opt_strs+4296)
+#define INLINE_COMMANDS_name (gnutls_cli_opt_strs+4370)
/** Compiled in flag settings for the inline-commands option */
#define INLINE_COMMANDS_FLAGS (OPTST_DISABLED)
@@ -980,11 +996,11 @@ static int const aListCantList[] = {
* inline-commands-prefix option description:
*/
/** Descriptive text for the inline-commands-prefix option */
-#define INLINE_COMMANDS_PREFIX_DESC (gnutls_cli_opt_strs+4312)
+#define INLINE_COMMANDS_PREFIX_DESC (gnutls_cli_opt_strs+4386)
/** Upper-cased name for the inline-commands-prefix option */
-#define INLINE_COMMANDS_PREFIX_NAME (gnutls_cli_opt_strs+4362)
+#define INLINE_COMMANDS_PREFIX_NAME (gnutls_cli_opt_strs+4436)
/** Name string for the inline-commands-prefix option */
-#define INLINE_COMMANDS_PREFIX_name (gnutls_cli_opt_strs+4385)
+#define INLINE_COMMANDS_PREFIX_name (gnutls_cli_opt_strs+4459)
/** Compiled in flag settings for the inline-commands-prefix option */
#define INLINE_COMMANDS_PREFIX_FLAGS (OPTST_DISABLED \
| OPTST_SET_ARGTYPE(OPARG_TYPE_STRING))
@@ -993,11 +1009,11 @@ static int const aListCantList[] = {
* provider option description:
*/
/** Descriptive text for the provider option */
-#define PROVIDER_DESC (gnutls_cli_opt_strs+4408)
+#define PROVIDER_DESC (gnutls_cli_opt_strs+4482)
/** Upper-cased name for the provider option */
-#define PROVIDER_NAME (gnutls_cli_opt_strs+4446)
+#define PROVIDER_NAME (gnutls_cli_opt_strs+4520)
/** Name string for the provider option */
-#define PROVIDER_name (gnutls_cli_opt_strs+4455)
+#define PROVIDER_name (gnutls_cli_opt_strs+4529)
/** Compiled in flag settings for the provider option */
#define PROVIDER_FLAGS (OPTST_DISABLED \
| OPTST_SET_ARGTYPE(OPARG_TYPE_FILE))
@@ -1006,22 +1022,22 @@ static int const aListCantList[] = {
* fips140-mode option description:
*/
/** Descriptive text for the fips140-mode option */
-#define FIPS140_MODE_DESC (gnutls_cli_opt_strs+4464)
+#define FIPS140_MODE_DESC (gnutls_cli_opt_strs+4538)
/** Upper-cased name for the fips140-mode option */
-#define FIPS140_MODE_NAME (gnutls_cli_opt_strs+4523)
+#define FIPS140_MODE_NAME (gnutls_cli_opt_strs+4597)
/** Name string for the fips140-mode option */
-#define FIPS140_MODE_name (gnutls_cli_opt_strs+4536)
+#define FIPS140_MODE_name (gnutls_cli_opt_strs+4610)
/** Compiled in flag settings for the fips140-mode option */
#define FIPS140_MODE_FLAGS (OPTST_DISABLED)
/*
* Help/More_Help/Version option descriptions:
*/
-#define HELP_DESC (gnutls_cli_opt_strs+4549)
-#define HELP_name (gnutls_cli_opt_strs+4593)
+#define HELP_DESC (gnutls_cli_opt_strs+4623)
+#define HELP_name (gnutls_cli_opt_strs+4667)
#ifdef HAVE_WORKING_FORK
-#define MORE_HELP_DESC (gnutls_cli_opt_strs+4598)
-#define MORE_HELP_name (gnutls_cli_opt_strs+4643)
+#define MORE_HELP_DESC (gnutls_cli_opt_strs+4672)
+#define MORE_HELP_name (gnutls_cli_opt_strs+4717)
#define MORE_HELP_FLAGS (OPTST_IMM | OPTST_NO_INIT)
#else
#define MORE_HELP_DESC HELP_DESC
@@ -1034,8 +1050,8 @@ static int const aListCantList[] = {
# define VER_FLAGS (OPTST_SET_ARGTYPE(OPARG_TYPE_STRING) | \
OPTST_ARG_OPTIONAL | OPTST_IMM | OPTST_NO_INIT)
#endif
-#define VER_DESC (gnutls_cli_opt_strs+4653)
-#define VER_name (gnutls_cli_opt_strs+4689)
+#define VER_DESC (gnutls_cli_opt_strs+4727)
+#define VER_name (gnutls_cli_opt_strs+4763)
/**
* Declare option callback procedures
*/
@@ -1164,8 +1180,20 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ RESUME_DESC, RESUME_NAME, RESUME_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 9, VALUE_OPT_REHANDSHAKE,
- /* equiv idx, value */ 9, VALUE_OPT_REHANDSHAKE,
+ { /* entry idx, value */ 9, VALUE_OPT_EARLYDATA,
+ /* equiv idx, value */ 9, VALUE_OPT_EARLYDATA,
+ /* equivalenced to */ NO_EQUIVALENT,
+ /* min, max, act ct */ 0, 1, 0,
+ /* opt state flags */ EARLYDATA_FLAGS, 0,
+ /* last opt argumnt */ { NULL }, /* --earlydata */
+ /* arg list/cookie */ NULL,
+ /* must/cannot opts */ NULL, NULL,
+ /* option proc */ NULL,
+ /* desc, NAME, name */ EARLYDATA_DESC, EARLYDATA_NAME, EARLYDATA_name,
+ /* disablement strs */ NULL, NULL },
+
+ { /* entry idx, value */ 10, VALUE_OPT_REHANDSHAKE,
+ /* equiv idx, value */ 10, VALUE_OPT_REHANDSHAKE,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ REHANDSHAKE_FLAGS, 0,
@@ -1176,8 +1204,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ REHANDSHAKE_DESC, REHANDSHAKE_NAME, REHANDSHAKE_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 10, VALUE_OPT_SNI_HOSTNAME,
- /* equiv idx, value */ 10, VALUE_OPT_SNI_HOSTNAME,
+ { /* entry idx, value */ 11, VALUE_OPT_SNI_HOSTNAME,
+ /* equiv idx, value */ 11, VALUE_OPT_SNI_HOSTNAME,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ SNI_HOSTNAME_FLAGS, 0,
@@ -1188,8 +1216,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ SNI_HOSTNAME_DESC, SNI_HOSTNAME_NAME, SNI_HOSTNAME_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 11, VALUE_OPT_VERIFY_HOSTNAME,
- /* equiv idx, value */ 11, VALUE_OPT_VERIFY_HOSTNAME,
+ { /* entry idx, value */ 12, VALUE_OPT_VERIFY_HOSTNAME,
+ /* equiv idx, value */ 12, VALUE_OPT_VERIFY_HOSTNAME,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ VERIFY_HOSTNAME_FLAGS, 0,
@@ -1200,8 +1228,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ VERIFY_HOSTNAME_DESC, VERIFY_HOSTNAME_NAME, VERIFY_HOSTNAME_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 12, VALUE_OPT_STARTTLS,
- /* equiv idx, value */ 12, VALUE_OPT_STARTTLS,
+ { /* entry idx, value */ 13, VALUE_OPT_STARTTLS,
+ /* equiv idx, value */ 13, VALUE_OPT_STARTTLS,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ STARTTLS_FLAGS, 0,
@@ -1212,8 +1240,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ STARTTLS_DESC, STARTTLS_NAME, STARTTLS_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 13, VALUE_OPT_APP_PROTO,
- /* equiv idx, value */ 13, VALUE_OPT_APP_PROTO,
+ { /* entry idx, value */ 14, VALUE_OPT_APP_PROTO,
+ /* equiv idx, value */ 14, VALUE_OPT_APP_PROTO,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ APP_PROTO_FLAGS, 0,
@@ -1224,8 +1252,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ APP_PROTO_DESC, APP_PROTO_NAME, APP_PROTO_name,
/* disablement strs */ 0, 0 },
- { /* entry idx, value */ 14, VALUE_OPT_STARTTLS_PROTO,
- /* equiv idx, value */ 14, VALUE_OPT_STARTTLS_PROTO,
+ { /* entry idx, value */ 15, VALUE_OPT_STARTTLS_PROTO,
+ /* equiv idx, value */ 15, VALUE_OPT_STARTTLS_PROTO,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ STARTTLS_PROTO_FLAGS, 0,
@@ -1236,8 +1264,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ STARTTLS_PROTO_DESC, STARTTLS_PROTO_NAME, STARTTLS_PROTO_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 15, VALUE_OPT_UDP,
- /* equiv idx, value */ 15, VALUE_OPT_UDP,
+ { /* entry idx, value */ 16, VALUE_OPT_UDP,
+ /* equiv idx, value */ 16, VALUE_OPT_UDP,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ UDP_FLAGS, 0,
@@ -1248,8 +1276,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ UDP_DESC, UDP_NAME, UDP_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 16, VALUE_OPT_MTU,
- /* equiv idx, value */ 16, VALUE_OPT_MTU,
+ { /* entry idx, value */ 17, VALUE_OPT_MTU,
+ /* equiv idx, value */ 17, VALUE_OPT_MTU,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ MTU_FLAGS, 0,
@@ -1260,8 +1288,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ MTU_DESC, MTU_NAME, MTU_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 17, VALUE_OPT_CRLF,
- /* equiv idx, value */ 17, VALUE_OPT_CRLF,
+ { /* entry idx, value */ 18, VALUE_OPT_CRLF,
+ /* equiv idx, value */ 18, VALUE_OPT_CRLF,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ CRLF_FLAGS, 0,
@@ -1272,8 +1300,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ CRLF_DESC, CRLF_NAME, CRLF_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 18, VALUE_OPT_FASTOPEN,
- /* equiv idx, value */ 18, VALUE_OPT_FASTOPEN,
+ { /* entry idx, value */ 19, VALUE_OPT_FASTOPEN,
+ /* equiv idx, value */ 19, VALUE_OPT_FASTOPEN,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ FASTOPEN_FLAGS, 0,
@@ -1284,8 +1312,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ FASTOPEN_DESC, FASTOPEN_NAME, FASTOPEN_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 19, VALUE_OPT_X509FMTDER,
- /* equiv idx, value */ 19, VALUE_OPT_X509FMTDER,
+ { /* entry idx, value */ 20, VALUE_OPT_X509FMTDER,
+ /* equiv idx, value */ 20, VALUE_OPT_X509FMTDER,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ X509FMTDER_FLAGS, 0,
@@ -1296,8 +1324,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ X509FMTDER_DESC, X509FMTDER_NAME, X509FMTDER_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 20, VALUE_OPT_PRINT_CERT,
- /* equiv idx, value */ 20, VALUE_OPT_PRINT_CERT,
+ { /* entry idx, value */ 21, VALUE_OPT_PRINT_CERT,
+ /* equiv idx, value */ 21, VALUE_OPT_PRINT_CERT,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ PRINT_CERT_FLAGS, 0,
@@ -1308,8 +1336,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ PRINT_CERT_DESC, PRINT_CERT_NAME, PRINT_CERT_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 21, VALUE_OPT_SAVE_CERT,
- /* equiv idx, value */ 21, VALUE_OPT_SAVE_CERT,
+ { /* entry idx, value */ 22, VALUE_OPT_SAVE_CERT,
+ /* equiv idx, value */ 22, VALUE_OPT_SAVE_CERT,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ SAVE_CERT_FLAGS, 0,
@@ -1320,8 +1348,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ SAVE_CERT_DESC, SAVE_CERT_NAME, SAVE_CERT_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 22, VALUE_OPT_SAVE_OCSP,
- /* equiv idx, value */ 22, VALUE_OPT_SAVE_OCSP,
+ { /* entry idx, value */ 23, VALUE_OPT_SAVE_OCSP,
+ /* equiv idx, value */ 23, VALUE_OPT_SAVE_OCSP,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ SAVE_OCSP_FLAGS, 0,
@@ -1332,8 +1360,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ SAVE_OCSP_DESC, SAVE_OCSP_NAME, SAVE_OCSP_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 23, VALUE_OPT_SAVE_SERVER_TRACE,
- /* equiv idx, value */ 23, VALUE_OPT_SAVE_SERVER_TRACE,
+ { /* entry idx, value */ 24, VALUE_OPT_SAVE_SERVER_TRACE,
+ /* equiv idx, value */ 24, VALUE_OPT_SAVE_SERVER_TRACE,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ SAVE_SERVER_TRACE_FLAGS, 0,
@@ -1344,8 +1372,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ SAVE_SERVER_TRACE_DESC, SAVE_SERVER_TRACE_NAME, SAVE_SERVER_TRACE_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 24, VALUE_OPT_SAVE_CLIENT_TRACE,
- /* equiv idx, value */ 24, VALUE_OPT_SAVE_CLIENT_TRACE,
+ { /* entry idx, value */ 25, VALUE_OPT_SAVE_CLIENT_TRACE,
+ /* equiv idx, value */ 25, VALUE_OPT_SAVE_CLIENT_TRACE,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ SAVE_CLIENT_TRACE_FLAGS, 0,
@@ -1356,8 +1384,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ SAVE_CLIENT_TRACE_DESC, SAVE_CLIENT_TRACE_NAME, SAVE_CLIENT_TRACE_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 25, VALUE_OPT_DH_BITS,
- /* equiv idx, value */ 25, VALUE_OPT_DH_BITS,
+ { /* entry idx, value */ 26, VALUE_OPT_DH_BITS,
+ /* equiv idx, value */ 26, VALUE_OPT_DH_BITS,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ DH_BITS_FLAGS, 0,
@@ -1368,8 +1396,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ DH_BITS_DESC, DH_BITS_NAME, DH_BITS_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 26, VALUE_OPT_PRIORITY,
- /* equiv idx, value */ 26, VALUE_OPT_PRIORITY,
+ { /* entry idx, value */ 27, VALUE_OPT_PRIORITY,
+ /* equiv idx, value */ 27, VALUE_OPT_PRIORITY,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ PRIORITY_FLAGS, 0,
@@ -1380,8 +1408,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ PRIORITY_DESC, PRIORITY_NAME, PRIORITY_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 27, VALUE_OPT_X509CAFILE,
- /* equiv idx, value */ 27, VALUE_OPT_X509CAFILE,
+ { /* entry idx, value */ 28, VALUE_OPT_X509CAFILE,
+ /* equiv idx, value */ 28, VALUE_OPT_X509CAFILE,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ X509CAFILE_FLAGS, 0,
@@ -1392,8 +1420,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ X509CAFILE_DESC, X509CAFILE_NAME, X509CAFILE_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 28, VALUE_OPT_X509CRLFILE,
- /* equiv idx, value */ 28, VALUE_OPT_X509CRLFILE,
+ { /* entry idx, value */ 29, VALUE_OPT_X509CRLFILE,
+ /* equiv idx, value */ 29, VALUE_OPT_X509CRLFILE,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ X509CRLFILE_FLAGS, 0,
@@ -1404,8 +1432,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ X509CRLFILE_DESC, X509CRLFILE_NAME, X509CRLFILE_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 29, VALUE_OPT_X509KEYFILE,
- /* equiv idx, value */ 29, VALUE_OPT_X509KEYFILE,
+ { /* entry idx, value */ 30, VALUE_OPT_X509KEYFILE,
+ /* equiv idx, value */ 30, VALUE_OPT_X509KEYFILE,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ X509KEYFILE_FLAGS, 0,
@@ -1416,8 +1444,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ X509KEYFILE_DESC, X509KEYFILE_NAME, X509KEYFILE_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 30, VALUE_OPT_X509CERTFILE,
- /* equiv idx, value */ 30, VALUE_OPT_X509CERTFILE,
+ { /* entry idx, value */ 31, VALUE_OPT_X509CERTFILE,
+ /* equiv idx, value */ 31, VALUE_OPT_X509CERTFILE,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ X509CERTFILE_FLAGS, 0,
@@ -1428,8 +1456,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ X509CERTFILE_DESC, X509CERTFILE_NAME, X509CERTFILE_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 31, VALUE_OPT_SRPUSERNAME,
- /* equiv idx, value */ 31, VALUE_OPT_SRPUSERNAME,
+ { /* entry idx, value */ 32, VALUE_OPT_SRPUSERNAME,
+ /* equiv idx, value */ 32, VALUE_OPT_SRPUSERNAME,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ SRPUSERNAME_FLAGS, 0,
@@ -1440,8 +1468,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ SRPUSERNAME_DESC, SRPUSERNAME_NAME, SRPUSERNAME_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 32, VALUE_OPT_SRPPASSWD,
- /* equiv idx, value */ 32, VALUE_OPT_SRPPASSWD,
+ { /* entry idx, value */ 33, VALUE_OPT_SRPPASSWD,
+ /* equiv idx, value */ 33, VALUE_OPT_SRPPASSWD,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ SRPPASSWD_FLAGS, 0,
@@ -1452,8 +1480,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ SRPPASSWD_DESC, SRPPASSWD_NAME, SRPPASSWD_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 33, VALUE_OPT_PSKUSERNAME,
- /* equiv idx, value */ 33, VALUE_OPT_PSKUSERNAME,
+ { /* entry idx, value */ 34, VALUE_OPT_PSKUSERNAME,
+ /* equiv idx, value */ 34, VALUE_OPT_PSKUSERNAME,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ PSKUSERNAME_FLAGS, 0,
@@ -1464,8 +1492,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ PSKUSERNAME_DESC, PSKUSERNAME_NAME, PSKUSERNAME_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 34, VALUE_OPT_PSKKEY,
- /* equiv idx, value */ 34, VALUE_OPT_PSKKEY,
+ { /* entry idx, value */ 35, VALUE_OPT_PSKKEY,
+ /* equiv idx, value */ 35, VALUE_OPT_PSKKEY,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ PSKKEY_FLAGS, 0,
@@ -1476,8 +1504,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ PSKKEY_DESC, PSKKEY_NAME, PSKKEY_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 35, VALUE_OPT_PORT,
- /* equiv idx, value */ 35, VALUE_OPT_PORT,
+ { /* entry idx, value */ 36, VALUE_OPT_PORT,
+ /* equiv idx, value */ 36, VALUE_OPT_PORT,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ PORT_FLAGS, 0,
@@ -1488,8 +1516,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ PORT_DESC, PORT_NAME, PORT_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 36, VALUE_OPT_INSECURE,
- /* equiv idx, value */ 36, VALUE_OPT_INSECURE,
+ { /* entry idx, value */ 37, VALUE_OPT_INSECURE,
+ /* equiv idx, value */ 37, VALUE_OPT_INSECURE,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ INSECURE_FLAGS, 0,
@@ -1500,8 +1528,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ INSECURE_DESC, INSECURE_NAME, INSECURE_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 37, VALUE_OPT_VERIFY_ALLOW_BROKEN,
- /* equiv idx, value */ 37, VALUE_OPT_VERIFY_ALLOW_BROKEN,
+ { /* entry idx, value */ 38, VALUE_OPT_VERIFY_ALLOW_BROKEN,
+ /* equiv idx, value */ 38, VALUE_OPT_VERIFY_ALLOW_BROKEN,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ VERIFY_ALLOW_BROKEN_FLAGS, 0,
@@ -1512,8 +1540,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ VERIFY_ALLOW_BROKEN_DESC, VERIFY_ALLOW_BROKEN_NAME, VERIFY_ALLOW_BROKEN_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 38, VALUE_OPT_RANGES,
- /* equiv idx, value */ 38, VALUE_OPT_RANGES,
+ { /* entry idx, value */ 39, VALUE_OPT_RANGES,
+ /* equiv idx, value */ 39, VALUE_OPT_RANGES,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ RANGES_FLAGS, 0,
@@ -1524,8 +1552,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ RANGES_DESC, RANGES_NAME, RANGES_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 39, VALUE_OPT_BENCHMARK_CIPHERS,
- /* equiv idx, value */ 39, VALUE_OPT_BENCHMARK_CIPHERS,
+ { /* entry idx, value */ 40, VALUE_OPT_BENCHMARK_CIPHERS,
+ /* equiv idx, value */ 40, VALUE_OPT_BENCHMARK_CIPHERS,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ BENCHMARK_CIPHERS_FLAGS, 0,
@@ -1536,8 +1564,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ BENCHMARK_CIPHERS_DESC, BENCHMARK_CIPHERS_NAME, BENCHMARK_CIPHERS_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 40, VALUE_OPT_BENCHMARK_TLS_KX,
- /* equiv idx, value */ 40, VALUE_OPT_BENCHMARK_TLS_KX,
+ { /* entry idx, value */ 41, VALUE_OPT_BENCHMARK_TLS_KX,
+ /* equiv idx, value */ 41, VALUE_OPT_BENCHMARK_TLS_KX,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ BENCHMARK_TLS_KX_FLAGS, 0,
@@ -1548,8 +1576,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ BENCHMARK_TLS_KX_DESC, BENCHMARK_TLS_KX_NAME, BENCHMARK_TLS_KX_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 41, VALUE_OPT_BENCHMARK_TLS_CIPHERS,
- /* equiv idx, value */ 41, VALUE_OPT_BENCHMARK_TLS_CIPHERS,
+ { /* entry idx, value */ 42, VALUE_OPT_BENCHMARK_TLS_CIPHERS,
+ /* equiv idx, value */ 42, VALUE_OPT_BENCHMARK_TLS_CIPHERS,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ BENCHMARK_TLS_CIPHERS_FLAGS, 0,
@@ -1560,8 +1588,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ BENCHMARK_TLS_CIPHERS_DESC, BENCHMARK_TLS_CIPHERS_NAME, BENCHMARK_TLS_CIPHERS_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 42, VALUE_OPT_LIST,
- /* equiv idx, value */ 42, VALUE_OPT_LIST,
+ { /* entry idx, value */ 43, VALUE_OPT_LIST,
+ /* equiv idx, value */ 43, VALUE_OPT_LIST,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ LIST_FLAGS, 0,
@@ -1572,8 +1600,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ LIST_DESC, LIST_NAME, LIST_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 43, VALUE_OPT_PRIORITY_LIST,
- /* equiv idx, value */ 43, VALUE_OPT_PRIORITY_LIST,
+ { /* entry idx, value */ 44, VALUE_OPT_PRIORITY_LIST,
+ /* equiv idx, value */ 44, VALUE_OPT_PRIORITY_LIST,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ PRIORITY_LIST_FLAGS, 0,
@@ -1584,8 +1612,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ PRIORITY_LIST_DESC, PRIORITY_LIST_NAME, PRIORITY_LIST_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 44, VALUE_OPT_NOTICKET,
- /* equiv idx, value */ 44, VALUE_OPT_NOTICKET,
+ { /* entry idx, value */ 45, VALUE_OPT_NOTICKET,
+ /* equiv idx, value */ 45, VALUE_OPT_NOTICKET,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ NOTICKET_FLAGS, 0,
@@ -1596,8 +1624,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ NOTICKET_DESC, NOTICKET_NAME, NOTICKET_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 45, VALUE_OPT_SRTP_PROFILES,
- /* equiv idx, value */ 45, VALUE_OPT_SRTP_PROFILES,
+ { /* entry idx, value */ 46, VALUE_OPT_SRTP_PROFILES,
+ /* equiv idx, value */ 46, VALUE_OPT_SRTP_PROFILES,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ SRTP_PROFILES_FLAGS, 0,
@@ -1608,8 +1636,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ SRTP_PROFILES_DESC, SRTP_PROFILES_NAME, SRTP_PROFILES_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 46, VALUE_OPT_ALPN,
- /* equiv idx, value */ 46, VALUE_OPT_ALPN,
+ { /* entry idx, value */ 47, VALUE_OPT_ALPN,
+ /* equiv idx, value */ 47, VALUE_OPT_ALPN,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, NOLIMIT, 0,
/* opt state flags */ ALPN_FLAGS, 0,
@@ -1620,8 +1648,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ ALPN_DESC, ALPN_NAME, ALPN_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 47, VALUE_OPT_HEARTBEAT,
- /* equiv idx, value */ 47, VALUE_OPT_HEARTBEAT,
+ { /* entry idx, value */ 48, VALUE_OPT_HEARTBEAT,
+ /* equiv idx, value */ 48, VALUE_OPT_HEARTBEAT,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ HEARTBEAT_FLAGS, 0,
@@ -1632,8 +1660,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ HEARTBEAT_DESC, HEARTBEAT_NAME, HEARTBEAT_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 48, VALUE_OPT_RECORDSIZE,
- /* equiv idx, value */ 48, VALUE_OPT_RECORDSIZE,
+ { /* entry idx, value */ 49, VALUE_OPT_RECORDSIZE,
+ /* equiv idx, value */ 49, VALUE_OPT_RECORDSIZE,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ RECORDSIZE_FLAGS, 0,
@@ -1644,8 +1672,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ RECORDSIZE_DESC, RECORDSIZE_NAME, RECORDSIZE_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 49, VALUE_OPT_DISABLE_SNI,
- /* equiv idx, value */ 49, VALUE_OPT_DISABLE_SNI,
+ { /* entry idx, value */ 50, VALUE_OPT_DISABLE_SNI,
+ /* equiv idx, value */ 50, VALUE_OPT_DISABLE_SNI,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ DISABLE_SNI_FLAGS, 0,
@@ -1656,8 +1684,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ DISABLE_SNI_DESC, DISABLE_SNI_NAME, DISABLE_SNI_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 50, VALUE_OPT_DISABLE_EXTENSIONS,
- /* equiv idx, value */ 50, VALUE_OPT_DISABLE_EXTENSIONS,
+ { /* entry idx, value */ 51, VALUE_OPT_DISABLE_EXTENSIONS,
+ /* equiv idx, value */ 51, VALUE_OPT_DISABLE_EXTENSIONS,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ DISABLE_EXTENSIONS_FLAGS, 0,
@@ -1668,8 +1696,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ DISABLE_EXTENSIONS_DESC, DISABLE_EXTENSIONS_NAME, DISABLE_EXTENSIONS_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 51, VALUE_OPT_SINGLE_KEY_SHARE,
- /* equiv idx, value */ 51, VALUE_OPT_SINGLE_KEY_SHARE,
+ { /* entry idx, value */ 52, VALUE_OPT_SINGLE_KEY_SHARE,
+ /* equiv idx, value */ 52, VALUE_OPT_SINGLE_KEY_SHARE,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ SINGLE_KEY_SHARE_FLAGS, 0,
@@ -1680,8 +1708,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ SINGLE_KEY_SHARE_DESC, SINGLE_KEY_SHARE_NAME, SINGLE_KEY_SHARE_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 52, VALUE_OPT_POST_HANDSHAKE_AUTH,
- /* equiv idx, value */ 52, VALUE_OPT_POST_HANDSHAKE_AUTH,
+ { /* entry idx, value */ 53, VALUE_OPT_POST_HANDSHAKE_AUTH,
+ /* equiv idx, value */ 53, VALUE_OPT_POST_HANDSHAKE_AUTH,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ POST_HANDSHAKE_AUTH_FLAGS, 0,
@@ -1692,8 +1720,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ POST_HANDSHAKE_AUTH_DESC, POST_HANDSHAKE_AUTH_NAME, POST_HANDSHAKE_AUTH_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 53, VALUE_OPT_INLINE_COMMANDS,
- /* equiv idx, value */ 53, VALUE_OPT_INLINE_COMMANDS,
+ { /* entry idx, value */ 54, VALUE_OPT_INLINE_COMMANDS,
+ /* equiv idx, value */ 54, VALUE_OPT_INLINE_COMMANDS,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ INLINE_COMMANDS_FLAGS, 0,
@@ -1704,8 +1732,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ INLINE_COMMANDS_DESC, INLINE_COMMANDS_NAME, INLINE_COMMANDS_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 54, VALUE_OPT_INLINE_COMMANDS_PREFIX,
- /* equiv idx, value */ 54, VALUE_OPT_INLINE_COMMANDS_PREFIX,
+ { /* entry idx, value */ 55, VALUE_OPT_INLINE_COMMANDS_PREFIX,
+ /* equiv idx, value */ 55, VALUE_OPT_INLINE_COMMANDS_PREFIX,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ INLINE_COMMANDS_PREFIX_FLAGS, 0,
@@ -1716,8 +1744,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ INLINE_COMMANDS_PREFIX_DESC, INLINE_COMMANDS_PREFIX_NAME, INLINE_COMMANDS_PREFIX_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 55, VALUE_OPT_PROVIDER,
- /* equiv idx, value */ 55, VALUE_OPT_PROVIDER,
+ { /* entry idx, value */ 56, VALUE_OPT_PROVIDER,
+ /* equiv idx, value */ 56, VALUE_OPT_PROVIDER,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ PROVIDER_FLAGS, 0,
@@ -1728,8 +1756,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ PROVIDER_DESC, PROVIDER_NAME, PROVIDER_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 56, VALUE_OPT_FIPS140_MODE,
- /* equiv idx, value */ 56, VALUE_OPT_FIPS140_MODE,
+ { /* entry idx, value */ 57, VALUE_OPT_FIPS140_MODE,
+ /* equiv idx, value */ 57, VALUE_OPT_FIPS140_MODE,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ FIPS140_MODE_FLAGS, 0,
@@ -1782,21 +1810,21 @@ static tOptDesc optDesc[OPTION_CT] = {
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/** Reference to the upper cased version of gnutls-cli. */
-#define zPROGNAME (gnutls_cli_opt_strs+4697)
+#define zPROGNAME (gnutls_cli_opt_strs+4771)
/** Reference to the title line for gnutls-cli usage. */
-#define zUsageTitle (gnutls_cli_opt_strs+4708)
+#define zUsageTitle (gnutls_cli_opt_strs+4782)
/** There is no gnutls-cli configuration file. */
#define zRcName NULL
/** There are no directories to search for gnutls-cli config files. */
#define apzHomeList NULL
/** The gnutls-cli program bug email address. */
-#define zBugsAddr (gnutls_cli_opt_strs+4804)
+#define zBugsAddr (gnutls_cli_opt_strs+4878)
/** Clarification/explanation of what gnutls-cli does. */
-#define zExplain (gnutls_cli_opt_strs+4820)
+#define zExplain (gnutls_cli_opt_strs+4894)
/** Extra detail explaining what gnutls-cli does. */
-#define zDetail (gnutls_cli_opt_strs+4822)
+#define zDetail (gnutls_cli_opt_strs+4896)
/** The full version string for gnutls-cli. */
-#define zFullVersion (gnutls_cli_opt_strs+5005)
+#define zFullVersion (gnutls_cli_opt_strs+5079)
/* extracted from optcode.tlib near line 364 */
#if defined(ENABLE_NLS)
@@ -1808,7 +1836,7 @@ static tOptDesc optDesc[OPTION_CT] = {
#endif /* ENABLE_NLS */
#define gnutls_cli_full_usage (NULL)
-#define gnutls_cli_short_usage (gnutls_cli_opt_strs+5022)
+#define gnutls_cli_short_usage (gnutls_cli_opt_strs+5096)
#endif /* not defined __doxygen__ */
@@ -2067,7 +2095,7 @@ tOptions gnutls_cliOptions = {
NO_EQUIVALENT, /* '-#' option index */
NO_EQUIVALENT /* index of default opt */
},
- 60 /* full option count */, 57 /* user option count */,
+ 61 /* full option count */, 58 /* user option count */,
gnutls_cli_full_usage, gnutls_cli_short_usage,
NULL, NULL,
PKGDATADIR, gnutls_cli_packager_info
@@ -2249,6 +2277,9 @@ changed"));
puts(_("Establish a session and resume"));
/* referenced via gnutls_cliOptions.pOptDesc->pzText */
+ puts(_("Send early data on resumption from the specified file"));
+
+ /* referenced via gnutls_cliOptions.pOptDesc->pzText */
puts(_("Establish a session and rehandshake"));
/* referenced via gnutls_cliOptions.pOptDesc->pzText */
@@ -2441,7 +2472,7 @@ gnutls-cli --help for usage instructions.\n"));
puts(_("\tThis is less than the minimum library version: "));
#line 121 "../version.c"
puts(_("Automated Options version %s\n"
- "\tCopyright (C) 1999-2014 by Bruce Korb - all rights reserved\n"));
+ "\tCopyright (C) 1999-2017 by Bruce Korb - all rights reserved\n"));
#line 87 "../makeshell.c"
puts(_("(AutoOpts bug): %s.\n"));
#line 90 "../reset.c"
diff --git a/src/cli-args.def b/src/cli-args.def
index ee3eb86c79..1e06e12d3a 100644
--- a/src/cli-args.def
+++ b/src/cli-args.def
@@ -75,6 +75,13 @@ flag = {
};
flag = {
+ name = earlydata;
+ arg-type = string;
+ descrip = "Send early data on resumption from the specified file";
+ doc = "";
+};
+
+flag = {
name = rehandshake;
value = e;
descrip = "Establish a session and rehandshake";
diff --git a/src/cli-args.h.bak b/src/cli-args.h.bak
index 6a83f05651..a1788f6d86 100644
--- a/src/cli-args.h.bak
+++ b/src/cli-args.h.bak
@@ -75,60 +75,61 @@ typedef enum {
INDEX_OPT_CA_VERIFICATION = 6,
INDEX_OPT_OCSP = 7,
INDEX_OPT_RESUME = 8,
- INDEX_OPT_REHANDSHAKE = 9,
- INDEX_OPT_SNI_HOSTNAME = 10,
- INDEX_OPT_VERIFY_HOSTNAME = 11,
- INDEX_OPT_STARTTLS = 12,
- INDEX_OPT_APP_PROTO = 13,
- INDEX_OPT_STARTTLS_PROTO = 14,
- INDEX_OPT_UDP = 15,
- INDEX_OPT_MTU = 16,
- INDEX_OPT_CRLF = 17,
- INDEX_OPT_FASTOPEN = 18,
- INDEX_OPT_X509FMTDER = 19,
- INDEX_OPT_PRINT_CERT = 20,
- INDEX_OPT_SAVE_CERT = 21,
- INDEX_OPT_SAVE_OCSP = 22,
- INDEX_OPT_SAVE_SERVER_TRACE = 23,
- INDEX_OPT_SAVE_CLIENT_TRACE = 24,
- INDEX_OPT_DH_BITS = 25,
- INDEX_OPT_PRIORITY = 26,
- INDEX_OPT_X509CAFILE = 27,
- INDEX_OPT_X509CRLFILE = 28,
- INDEX_OPT_X509KEYFILE = 29,
- INDEX_OPT_X509CERTFILE = 30,
- INDEX_OPT_SRPUSERNAME = 31,
- INDEX_OPT_SRPPASSWD = 32,
- INDEX_OPT_PSKUSERNAME = 33,
- INDEX_OPT_PSKKEY = 34,
- INDEX_OPT_PORT = 35,
- INDEX_OPT_INSECURE = 36,
- INDEX_OPT_VERIFY_ALLOW_BROKEN = 37,
- INDEX_OPT_RANGES = 38,
- INDEX_OPT_BENCHMARK_CIPHERS = 39,
- INDEX_OPT_BENCHMARK_TLS_KX = 40,
- INDEX_OPT_BENCHMARK_TLS_CIPHERS = 41,
- INDEX_OPT_LIST = 42,
- INDEX_OPT_PRIORITY_LIST = 43,
- INDEX_OPT_NOTICKET = 44,
- INDEX_OPT_SRTP_PROFILES = 45,
- INDEX_OPT_ALPN = 46,
- INDEX_OPT_HEARTBEAT = 47,
- INDEX_OPT_RECORDSIZE = 48,
- INDEX_OPT_DISABLE_SNI = 49,
- INDEX_OPT_DISABLE_EXTENSIONS = 50,
- INDEX_OPT_SINGLE_KEY_SHARE = 51,
- INDEX_OPT_POST_HANDSHAKE_AUTH = 52,
- INDEX_OPT_INLINE_COMMANDS = 53,
- INDEX_OPT_INLINE_COMMANDS_PREFIX = 54,
- INDEX_OPT_PROVIDER = 55,
- INDEX_OPT_FIPS140_MODE = 56,
- INDEX_OPT_VERSION = 57,
- INDEX_OPT_HELP = 58,
- INDEX_OPT_MORE_HELP = 59
+ INDEX_OPT_EARLYDATA = 9,
+ INDEX_OPT_REHANDSHAKE = 10,
+ INDEX_OPT_SNI_HOSTNAME = 11,
+ INDEX_OPT_VERIFY_HOSTNAME = 12,
+ INDEX_OPT_STARTTLS = 13,
+ INDEX_OPT_APP_PROTO = 14,
+ INDEX_OPT_STARTTLS_PROTO = 15,
+ INDEX_OPT_UDP = 16,
+ INDEX_OPT_MTU = 17,
+ INDEX_OPT_CRLF = 18,
+ INDEX_OPT_FASTOPEN = 19,
+ INDEX_OPT_X509FMTDER = 20,
+ INDEX_OPT_PRINT_CERT = 21,
+ INDEX_OPT_SAVE_CERT = 22,
+ INDEX_OPT_SAVE_OCSP = 23,
+ INDEX_OPT_SAVE_SERVER_TRACE = 24,
+ INDEX_OPT_SAVE_CLIENT_TRACE = 25,
+ INDEX_OPT_DH_BITS = 26,
+ INDEX_OPT_PRIORITY = 27,
+ INDEX_OPT_X509CAFILE = 28,
+ INDEX_OPT_X509CRLFILE = 29,
+ INDEX_OPT_X509KEYFILE = 30,
+ INDEX_OPT_X509CERTFILE = 31,
+ INDEX_OPT_SRPUSERNAME = 32,
+ INDEX_OPT_SRPPASSWD = 33,
+ INDEX_OPT_PSKUSERNAME = 34,
+ INDEX_OPT_PSKKEY = 35,
+ INDEX_OPT_PORT = 36,
+ INDEX_OPT_INSECURE = 37,
+ INDEX_OPT_VERIFY_ALLOW_BROKEN = 38,
+ INDEX_OPT_RANGES = 39,
+ INDEX_OPT_BENCHMARK_CIPHERS = 40,
+ INDEX_OPT_BENCHMARK_TLS_KX = 41,
+ INDEX_OPT_BENCHMARK_TLS_CIPHERS = 42,
+ INDEX_OPT_LIST = 43,
+ INDEX_OPT_PRIORITY_LIST = 44,
+ INDEX_OPT_NOTICKET = 45,
+ INDEX_OPT_SRTP_PROFILES = 46,
+ INDEX_OPT_ALPN = 47,
+ INDEX_OPT_HEARTBEAT = 48,
+ INDEX_OPT_RECORDSIZE = 49,
+ INDEX_OPT_DISABLE_SNI = 50,
+ INDEX_OPT_DISABLE_EXTENSIONS = 51,
+ INDEX_OPT_SINGLE_KEY_SHARE = 52,
+ INDEX_OPT_POST_HANDSHAKE_AUTH = 53,
+ INDEX_OPT_INLINE_COMMANDS = 54,
+ INDEX_OPT_INLINE_COMMANDS_PREFIX = 55,
+ INDEX_OPT_PROVIDER = 56,
+ INDEX_OPT_FIPS140_MODE = 57,
+ INDEX_OPT_VERSION = 58,
+ INDEX_OPT_HELP = 59,
+ INDEX_OPT_MORE_HELP = 60
} teOptIndex;
/** count of all options for gnutls-cli */
-#define OPTION_CT 60
+#define OPTION_CT 61
/** gnutls-cli version */
#define GNUTLS_CLI_VERSION "3.6.4"
/** Full gnutls-cli version text */
@@ -194,60 +195,61 @@ typedef enum {
#define VALUE_OPT_CA_VERIFICATION 0x1005
#define VALUE_OPT_OCSP 0x1006
#define VALUE_OPT_RESUME 'r'
+#define VALUE_OPT_EARLYDATA 0x1007
#define VALUE_OPT_REHANDSHAKE 'e'
-#define VALUE_OPT_SNI_HOSTNAME 0x1007
-#define VALUE_OPT_VERIFY_HOSTNAME 0x1008
+#define VALUE_OPT_SNI_HOSTNAME 0x1008
+#define VALUE_OPT_VERIFY_HOSTNAME 0x1009
#define VALUE_OPT_STARTTLS 's'
-#define VALUE_OPT_APP_PROTO 0x1009
-#define VALUE_OPT_STARTTLS_PROTO 0x100A
+#define VALUE_OPT_APP_PROTO 0x100A
+#define VALUE_OPT_STARTTLS_PROTO 0x100B
#define VALUE_OPT_UDP 'u'
-#define VALUE_OPT_MTU 0x100B
+#define VALUE_OPT_MTU 0x100C
#define OPT_VALUE_MTU (DESC(MTU).optArg.argInt)
-#define VALUE_OPT_CRLF 0x100C
-#define VALUE_OPT_FASTOPEN 0x100D
-#define VALUE_OPT_X509FMTDER 0x100E
-#define VALUE_OPT_PRINT_CERT 0x100F
-#define VALUE_OPT_SAVE_CERT 0x1010
-#define VALUE_OPT_SAVE_OCSP 0x1011
-#define VALUE_OPT_SAVE_SERVER_TRACE 0x1012
-#define VALUE_OPT_SAVE_CLIENT_TRACE 0x1013
-#define VALUE_OPT_DH_BITS 0x1014
+#define VALUE_OPT_CRLF 0x100D
+#define VALUE_OPT_FASTOPEN 0x100E
+#define VALUE_OPT_X509FMTDER 0x100F
+#define VALUE_OPT_PRINT_CERT 0x1010
+#define VALUE_OPT_SAVE_CERT 0x1011
+#define VALUE_OPT_SAVE_OCSP 0x1012
+#define VALUE_OPT_SAVE_SERVER_TRACE 0x1013
+#define VALUE_OPT_SAVE_CLIENT_TRACE 0x1014
+#define VALUE_OPT_DH_BITS 0x1015
#define OPT_VALUE_DH_BITS (DESC(DH_BITS).optArg.argInt)
-#define VALUE_OPT_PRIORITY 0x1015
-#define VALUE_OPT_X509CAFILE 0x1016
-#define VALUE_OPT_X509CRLFILE 0x1017
-#define VALUE_OPT_X509KEYFILE 0x1018
-#define VALUE_OPT_X509CERTFILE 0x1019
-#define VALUE_OPT_SRPUSERNAME 0x101A
-#define VALUE_OPT_SRPPASSWD 0x101B
-#define VALUE_OPT_PSKUSERNAME 0x101C
-#define VALUE_OPT_PSKKEY 0x101D
+#define VALUE_OPT_PRIORITY 0x1016
+#define VALUE_OPT_X509CAFILE 0x1017
+#define VALUE_OPT_X509CRLFILE 0x1018
+#define VALUE_OPT_X509KEYFILE 0x1019
+#define VALUE_OPT_X509CERTFILE 0x101A
+#define VALUE_OPT_SRPUSERNAME 0x101B
+#define VALUE_OPT_SRPPASSWD 0x101C
+#define VALUE_OPT_PSKUSERNAME 0x101D
+#define VALUE_OPT_PSKKEY 0x101E
#define VALUE_OPT_PORT 'p'
-#define VALUE_OPT_INSECURE 0x101E
-#define VALUE_OPT_VERIFY_ALLOW_BROKEN 0x101F
-#define VALUE_OPT_RANGES 0x1020
-#define VALUE_OPT_BENCHMARK_CIPHERS 0x1021
-#define VALUE_OPT_BENCHMARK_TLS_KX 0x1022
-#define VALUE_OPT_BENCHMARK_TLS_CIPHERS 0x1023
+#define VALUE_OPT_INSECURE 0x101F
+#define VALUE_OPT_VERIFY_ALLOW_BROKEN 0x1020
+#define VALUE_OPT_RANGES 0x1021
+#define VALUE_OPT_BENCHMARK_CIPHERS 0x1022
+#define VALUE_OPT_BENCHMARK_TLS_KX 0x1023
+#define VALUE_OPT_BENCHMARK_TLS_CIPHERS 0x1024
#define VALUE_OPT_LIST 'l'
-#define VALUE_OPT_PRIORITY_LIST 0x1024
-#define VALUE_OPT_NOTICKET 0x1025
-#define VALUE_OPT_SRTP_PROFILES 0x1026
-#define VALUE_OPT_ALPN 0x1027
+#define VALUE_OPT_PRIORITY_LIST 0x1025
+#define VALUE_OPT_NOTICKET 0x1026
+#define VALUE_OPT_SRTP_PROFILES 0x1027
+#define VALUE_OPT_ALPN 0x1028
#define VALUE_OPT_HEARTBEAT 'b'
-#define VALUE_OPT_RECORDSIZE 0x1028
+#define VALUE_OPT_RECORDSIZE 0x1029
#define OPT_VALUE_RECORDSIZE (DESC(RECORDSIZE).optArg.argInt)
-#define VALUE_OPT_DISABLE_SNI 0x1029
-#define VALUE_OPT_DISABLE_EXTENSIONS 0x102A
-#define VALUE_OPT_SINGLE_KEY_SHARE 0x102B
-#define VALUE_OPT_POST_HANDSHAKE_AUTH 0x102C
-#define VALUE_OPT_INLINE_COMMANDS 0x102D
-#define VALUE_OPT_INLINE_COMMANDS_PREFIX 0x102E
-#define VALUE_OPT_PROVIDER 0x102F
-#define VALUE_OPT_FIPS140_MODE 0x1030
+#define VALUE_OPT_DISABLE_SNI 0x102A
+#define VALUE_OPT_DISABLE_EXTENSIONS 0x102B
+#define VALUE_OPT_SINGLE_KEY_SHARE 0x102C
+#define VALUE_OPT_POST_HANDSHAKE_AUTH 0x102D
+#define VALUE_OPT_INLINE_COMMANDS 0x102E
+#define VALUE_OPT_INLINE_COMMANDS_PREFIX 0x102F
+#define VALUE_OPT_PROVIDER 0x1030
+#define VALUE_OPT_FIPS140_MODE 0x1031
/** option flag (value) for help-value option */
#define VALUE_OPT_HELP 'h'
/** option flag (value) for more-help-value option */
diff --git a/src/cli.c b/src/cli.c
index 60de6bc68f..ec8b759f67 100644
--- a/src/cli.c
+++ b/src/cli.c
@@ -839,6 +839,7 @@ static int try_resume(socket_st * hd)
{
int ret, socket_flags = SOCKET_FLAG_DONT_PRINT_ERRORS;
gnutls_datum_t rdata = {NULL, 0};
+ gnutls_datum_t edata = {NULL, 0};
if (gnutls_session_is_resumed(hd->session) == 0) {
/* not resumed - obtain the session data */
@@ -868,8 +869,22 @@ static int try_resume(socket_st * hd)
if (udp)
socket_flags |= SOCKET_FLAG_UDP;
- socket_open(hd, hostname, service, OPT_ARG(STARTTLS_PROTO),
- socket_flags, CONNECT_MSG, &rdata);
+ if (HAVE_OPT(EARLYDATA)) {
+ FILE *fp;
+ size_t size;
+
+ fp = fopen(OPT_ARG(EARLYDATA), "r");
+ if (fp == NULL) {
+ fprintf(stderr, "could not open %s\n", OPT_ARG(EARLYDATA));
+ exit(1);
+ }
+ edata.data = (void *) fread_file(fp, &size);
+ edata.size = size;
+ fclose(fp);
+ }
+
+ socket_open3(hd, hostname, service, OPT_ARG(STARTTLS_PROTO),
+ socket_flags, CONNECT_MSG, &rdata, &edata);
printf("- Resume Handshake was completed\n");
if (gnutls_session_is_resumed(hd->session) != 0)
@@ -1157,7 +1172,7 @@ int main(int argc, char **argv)
}
socket_open2(&hd, hostname, service, OPT_ARG(STARTTLS_PROTO),
- socket_flags, CONNECT_MSG, NULL,
+ socket_flags, CONNECT_MSG, NULL, NULL,
server_fp, client_fp);
hd.verbose = verbose;
diff --git a/src/serv-args.c.bak b/src/serv-args.c.bak
index 27e8e91353..2cd2173e8a 100644
--- a/src/serv-args.c.bak
+++ b/src/serv-args.c.bak
@@ -63,7 +63,7 @@ extern FILE * option_usage_fp;
/**
* static const strings for gnutls-serv options
*/
-static char const gnutls_serv_opt_strs[3428] =
+static char const gnutls_serv_opt_strs[3466] =
/* 0 */ "gnutls-serv 3.6.4\n"
"Copyright (C) 2000-2018 Free Software Foundation, and others, all rights reserved.\n"
"This is free software. It is licensed for use, modification and\n"
@@ -97,116 +97,119 @@ static char const gnutls_serv_opt_strs[3428] =
/* 1201 */ "Don't accept session tickets\0"
/* 1230 */ "NOTICKET\0"
/* 1239 */ "noticket\0"
-/* 1248 */ "Don't require cookie on DTLS sessions\0"
-/* 1286 */ "NOCOOKIE\0"
-/* 1295 */ "nocookie\0"
-/* 1304 */ "Generate Diffie-Hellman parameters\0"
-/* 1339 */ "GENERATE\0"
-/* 1348 */ "generate\0"
-/* 1357 */ "Suppress some messages\0"
-/* 1380 */ "QUIET\0"
-/* 1386 */ "quiet\0"
-/* 1392 */ "Do not use a resumption database\0"
-/* 1425 */ "NODB\0"
-/* 1430 */ "nodb\0"
-/* 1435 */ "Act as an HTTP server\0"
-/* 1457 */ "HTTP\0"
-/* 1462 */ "http\0"
-/* 1467 */ "Act as an Echo server\0"
-/* 1489 */ "ECHO\0"
-/* 1494 */ "echo\0"
-/* 1499 */ "Use DTLS (datagram TLS) over UDP\0"
-/* 1532 */ "UDP\0"
-/* 1536 */ "udp\0"
-/* 1540 */ "Set MTU for datagram TLS\0"
-/* 1565 */ "MTU\0"
-/* 1569 */ "mtu\0"
-/* 1573 */ "Offer SRTP profiles\0"
-/* 1593 */ "SRTP_PROFILES\0"
-/* 1607 */ "srtp-profiles\0"
-/* 1621 */ "Do not request a client certificate\0"
-/* 1657 */ "DISABLE_CLIENT_CERT\0"
-/* 1677 */ "disable-client-cert\0"
-/* 1697 */ "Require a client certificate\0"
-/* 1726 */ "REQUIRE_CLIENT_CERT\0"
-/* 1746 */ "require-client-cert\0"
-/* 1766 */ "If a client certificate is sent then verify it.\0"
-/* 1814 */ "VERIFY_CLIENT_CERT\0"
-/* 1833 */ "verify-client-cert\0"
-/* 1852 */ "Activate heartbeat support\0"
-/* 1879 */ "HEARTBEAT\0"
-/* 1889 */ "heartbeat\0"
-/* 1899 */ "Use DER format for certificates to read from\0"
-/* 1944 */ "X509FMTDER\0"
-/* 1955 */ "x509fmtder\0"
-/* 1966 */ "Priorities string\0"
-/* 1984 */ "PRIORITY\0"
-/* 1993 */ "priority\0"
-/* 2002 */ "DH params file to use\0"
-/* 2024 */ "DHPARAMS\0"
-/* 2033 */ "dhparams\0"
-/* 2042 */ "Certificate file or PKCS #11 URL to use\0"
-/* 2082 */ "X509CAFILE\0"
-/* 2093 */ "x509cafile\0"
-/* 2104 */ "CRL file to use\0"
-/* 2120 */ "X509CRLFILE\0"
-/* 2132 */ "x509crlfile\0"
-/* 2144 */ "PGP Key file to use (deprecated)\0"
-/* 2177 */ "PGPKEYFILE\0"
-/* 2188 */ "pgpkeyfile\0"
-/* 2199 */ "X.509 key file or PKCS #11 URL to use\0"
-/* 2237 */ "X509KEYFILE\0"
-/* 2249 */ "x509keyfile\0"
-/* 2261 */ "X.509 Certificate file or PKCS #11 URL to use\0"
-/* 2307 */ "X509CERTFILE\0"
-/* 2320 */ "x509certfile\0"
-/* 2333 */ "an alias for the 'x509keyfile' option (deprecated)\0"
-/* 2384 */ "x509dsakeyfile\0"
-/* 2399 */ "an alias for the 'x509certfile' option (deprecated)\0"
-/* 2451 */ "x509dsacertfile\0"
-/* 2467 */ "x509ecckeyfile\0"
-/* 2482 */ "x509ecccertfile\0"
-/* 2498 */ "SRP password file to use\0"
-/* 2523 */ "SRPPASSWD\0"
-/* 2533 */ "srppasswd\0"
-/* 2543 */ "SRP password configuration file to use\0"
-/* 2582 */ "SRPPASSWDCONF\0"
-/* 2596 */ "srppasswdconf\0"
-/* 2610 */ "PSK password file to use\0"
-/* 2635 */ "PSKPASSWD\0"
-/* 2645 */ "pskpasswd\0"
-/* 2655 */ "PSK identity hint to use\0"
-/* 2680 */ "PSKHINT\0"
-/* 2688 */ "pskhint\0"
-/* 2696 */ "The OCSP response to send to client\0"
-/* 2732 */ "OCSP_RESPONSE\0"
-/* 2746 */ "ocsp-response\0"
-/* 2760 */ "Ignore any errors when setting the OCSP response\0"
-/* 2809 */ "IGNORE_OCSP_RESPONSE_ERRORS\0"
-/* 2837 */ "ignore-ocsp-response-errors\0"
-/* 2865 */ "The port to connect to\0"
-/* 2888 */ "PORT\0"
-/* 2893 */ "port\0"
-/* 2898 */ "Print a list of the supported algorithms and modes\0"
-/* 2949 */ "LIST\0"
-/* 2954 */ "list\0"
-/* 2959 */ "Specify the PKCS #11 provider library\0"
-/* 2997 */ "PROVIDER\0"
-/* 3006 */ "provider\0"
-/* 3015 */ "display extended usage information and exit\0"
-/* 3059 */ "help\0"
-/* 3064 */ "extended usage information passed thru pager\0"
-/* 3109 */ "more-help\0"
-/* 3119 */ "output version information and exit\0"
-/* 3155 */ "version\0"
-/* 3163 */ "GNUTLS_SERV\0"
-/* 3175 */ "gnutls-serv - GnuTLS server\n"
+/* 1248 */ "Accept early data\0"
+/* 1266 */ "EARLYDATA\0"
+/* 1276 */ "earlydata\0"
+/* 1286 */ "Don't require cookie on DTLS sessions\0"
+/* 1324 */ "NOCOOKIE\0"
+/* 1333 */ "nocookie\0"
+/* 1342 */ "Generate Diffie-Hellman parameters\0"
+/* 1377 */ "GENERATE\0"
+/* 1386 */ "generate\0"
+/* 1395 */ "Suppress some messages\0"
+/* 1418 */ "QUIET\0"
+/* 1424 */ "quiet\0"
+/* 1430 */ "Do not use a resumption database\0"
+/* 1463 */ "NODB\0"
+/* 1468 */ "nodb\0"
+/* 1473 */ "Act as an HTTP server\0"
+/* 1495 */ "HTTP\0"
+/* 1500 */ "http\0"
+/* 1505 */ "Act as an Echo server\0"
+/* 1527 */ "ECHO\0"
+/* 1532 */ "echo\0"
+/* 1537 */ "Use DTLS (datagram TLS) over UDP\0"
+/* 1570 */ "UDP\0"
+/* 1574 */ "udp\0"
+/* 1578 */ "Set MTU for datagram TLS\0"
+/* 1603 */ "MTU\0"
+/* 1607 */ "mtu\0"
+/* 1611 */ "Offer SRTP profiles\0"
+/* 1631 */ "SRTP_PROFILES\0"
+/* 1645 */ "srtp-profiles\0"
+/* 1659 */ "Do not request a client certificate\0"
+/* 1695 */ "DISABLE_CLIENT_CERT\0"
+/* 1715 */ "disable-client-cert\0"
+/* 1735 */ "Require a client certificate\0"
+/* 1764 */ "REQUIRE_CLIENT_CERT\0"
+/* 1784 */ "require-client-cert\0"
+/* 1804 */ "If a client certificate is sent then verify it.\0"
+/* 1852 */ "VERIFY_CLIENT_CERT\0"
+/* 1871 */ "verify-client-cert\0"
+/* 1890 */ "Activate heartbeat support\0"
+/* 1917 */ "HEARTBEAT\0"
+/* 1927 */ "heartbeat\0"
+/* 1937 */ "Use DER format for certificates to read from\0"
+/* 1982 */ "X509FMTDER\0"
+/* 1993 */ "x509fmtder\0"
+/* 2004 */ "Priorities string\0"
+/* 2022 */ "PRIORITY\0"
+/* 2031 */ "priority\0"
+/* 2040 */ "DH params file to use\0"
+/* 2062 */ "DHPARAMS\0"
+/* 2071 */ "dhparams\0"
+/* 2080 */ "Certificate file or PKCS #11 URL to use\0"
+/* 2120 */ "X509CAFILE\0"
+/* 2131 */ "x509cafile\0"
+/* 2142 */ "CRL file to use\0"
+/* 2158 */ "X509CRLFILE\0"
+/* 2170 */ "x509crlfile\0"
+/* 2182 */ "PGP Key file to use (deprecated)\0"
+/* 2215 */ "PGPKEYFILE\0"
+/* 2226 */ "pgpkeyfile\0"
+/* 2237 */ "X.509 key file or PKCS #11 URL to use\0"
+/* 2275 */ "X509KEYFILE\0"
+/* 2287 */ "x509keyfile\0"
+/* 2299 */ "X.509 Certificate file or PKCS #11 URL to use\0"
+/* 2345 */ "X509CERTFILE\0"
+/* 2358 */ "x509certfile\0"
+/* 2371 */ "an alias for the 'x509keyfile' option (deprecated)\0"
+/* 2422 */ "x509dsakeyfile\0"
+/* 2437 */ "an alias for the 'x509certfile' option (deprecated)\0"
+/* 2489 */ "x509dsacertfile\0"
+/* 2505 */ "x509ecckeyfile\0"
+/* 2520 */ "x509ecccertfile\0"
+/* 2536 */ "SRP password file to use\0"
+/* 2561 */ "SRPPASSWD\0"
+/* 2571 */ "srppasswd\0"
+/* 2581 */ "SRP password configuration file to use\0"
+/* 2620 */ "SRPPASSWDCONF\0"
+/* 2634 */ "srppasswdconf\0"
+/* 2648 */ "PSK password file to use\0"
+/* 2673 */ "PSKPASSWD\0"
+/* 2683 */ "pskpasswd\0"
+/* 2693 */ "PSK identity hint to use\0"
+/* 2718 */ "PSKHINT\0"
+/* 2726 */ "pskhint\0"
+/* 2734 */ "The OCSP response to send to client\0"
+/* 2770 */ "OCSP_RESPONSE\0"
+/* 2784 */ "ocsp-response\0"
+/* 2798 */ "Ignore any errors when setting the OCSP response\0"
+/* 2847 */ "IGNORE_OCSP_RESPONSE_ERRORS\0"
+/* 2875 */ "ignore-ocsp-response-errors\0"
+/* 2903 */ "The port to connect to\0"
+/* 2926 */ "PORT\0"
+/* 2931 */ "port\0"
+/* 2936 */ "Print a list of the supported algorithms and modes\0"
+/* 2987 */ "LIST\0"
+/* 2992 */ "list\0"
+/* 2997 */ "Specify the PKCS #11 provider library\0"
+/* 3035 */ "PROVIDER\0"
+/* 3044 */ "provider\0"
+/* 3053 */ "display extended usage information and exit\0"
+/* 3097 */ "help\0"
+/* 3102 */ "extended usage information passed thru pager\0"
+/* 3147 */ "more-help\0"
+/* 3157 */ "output version information and exit\0"
+/* 3193 */ "version\0"
+/* 3201 */ "GNUTLS_SERV\0"
+/* 3213 */ "gnutls-serv - GnuTLS server\n"
"Usage: %s [ -<flag> [<val>] | --<name>[{=| }<val>] ]...\n\0"
-/* 3261 */ "bugs@gnutls.org\0"
-/* 3277 */ "\n\0"
-/* 3279 */ "Server program that listens to incoming TLS connections.\n\0"
-/* 3337 */ "gnutls-serv 3.6.4\0"
-/* 3355 */ "Usage: gnutls-serv [options]\n"
+/* 3299 */ "bugs@gnutls.org\0"
+/* 3315 */ "\n\0"
+/* 3317 */ "Server program that listens to incoming TLS connections.\n\0"
+/* 3375 */ "gnutls-serv 3.6.4\0"
+/* 3393 */ "Usage: gnutls-serv [options]\n"
"gnutls-serv --help for usage instructions.\n";
/**
@@ -285,14 +288,26 @@ static char const gnutls_serv_opt_strs[3428] =
#define NOTICKET_FLAGS (OPTST_DISABLED)
/**
+ * earlydata option description:
+ */
+/** Descriptive text for the earlydata option */
+#define EARLYDATA_DESC (gnutls_serv_opt_strs+1248)
+/** Upper-cased name for the earlydata option */
+#define EARLYDATA_NAME (gnutls_serv_opt_strs+1266)
+/** Name string for the earlydata option */
+#define EARLYDATA_name (gnutls_serv_opt_strs+1276)
+/** Compiled in flag settings for the earlydata option */
+#define EARLYDATA_FLAGS (OPTST_DISABLED)
+
+/**
* nocookie option description:
*/
/** Descriptive text for the nocookie option */
-#define NOCOOKIE_DESC (gnutls_serv_opt_strs+1248)
+#define NOCOOKIE_DESC (gnutls_serv_opt_strs+1286)
/** Upper-cased name for the nocookie option */
-#define NOCOOKIE_NAME (gnutls_serv_opt_strs+1286)
+#define NOCOOKIE_NAME (gnutls_serv_opt_strs+1324)
/** Name string for the nocookie option */
-#define NOCOOKIE_name (gnutls_serv_opt_strs+1295)
+#define NOCOOKIE_name (gnutls_serv_opt_strs+1333)
/** Compiled in flag settings for the nocookie option */
#define NOCOOKIE_FLAGS (OPTST_DISABLED)
@@ -300,11 +315,11 @@ static char const gnutls_serv_opt_strs[3428] =
* generate option description:
*/
/** Descriptive text for the generate option */
-#define GENERATE_DESC (gnutls_serv_opt_strs+1304)
+#define GENERATE_DESC (gnutls_serv_opt_strs+1342)
/** Upper-cased name for the generate option */
-#define GENERATE_NAME (gnutls_serv_opt_strs+1339)
+#define GENERATE_NAME (gnutls_serv_opt_strs+1377)
/** Name string for the generate option */
-#define GENERATE_name (gnutls_serv_opt_strs+1348)
+#define GENERATE_name (gnutls_serv_opt_strs+1386)
/** Compiled in flag settings for the generate option */
#define GENERATE_FLAGS (OPTST_DISABLED)
@@ -312,11 +327,11 @@ static char const gnutls_serv_opt_strs[3428] =
* quiet option description:
*/
/** Descriptive text for the quiet option */
-#define QUIET_DESC (gnutls_serv_opt_strs+1357)
+#define QUIET_DESC (gnutls_serv_opt_strs+1395)
/** Upper-cased name for the quiet option */
-#define QUIET_NAME (gnutls_serv_opt_strs+1380)
+#define QUIET_NAME (gnutls_serv_opt_strs+1418)
/** Name string for the quiet option */
-#define QUIET_name (gnutls_serv_opt_strs+1386)
+#define QUIET_name (gnutls_serv_opt_strs+1424)
/** Compiled in flag settings for the quiet option */
#define QUIET_FLAGS (OPTST_DISABLED)
@@ -324,11 +339,11 @@ static char const gnutls_serv_opt_strs[3428] =
* nodb option description:
*/
/** Descriptive text for the nodb option */
-#define NODB_DESC (gnutls_serv_opt_strs+1392)
+#define NODB_DESC (gnutls_serv_opt_strs+1430)
/** Upper-cased name for the nodb option */
-#define NODB_NAME (gnutls_serv_opt_strs+1425)
+#define NODB_NAME (gnutls_serv_opt_strs+1463)
/** Name string for the nodb option */
-#define NODB_name (gnutls_serv_opt_strs+1430)
+#define NODB_name (gnutls_serv_opt_strs+1468)
/** Compiled in flag settings for the nodb option */
#define NODB_FLAGS (OPTST_DISABLED)
@@ -336,11 +351,11 @@ static char const gnutls_serv_opt_strs[3428] =
* http option description:
*/
/** Descriptive text for the http option */
-#define HTTP_DESC (gnutls_serv_opt_strs+1435)
+#define HTTP_DESC (gnutls_serv_opt_strs+1473)
/** Upper-cased name for the http option */
-#define HTTP_NAME (gnutls_serv_opt_strs+1457)
+#define HTTP_NAME (gnutls_serv_opt_strs+1495)
/** Name string for the http option */
-#define HTTP_name (gnutls_serv_opt_strs+1462)
+#define HTTP_name (gnutls_serv_opt_strs+1500)
/** Compiled in flag settings for the http option */
#define HTTP_FLAGS (OPTST_DISABLED)
@@ -348,11 +363,11 @@ static char const gnutls_serv_opt_strs[3428] =
* echo option description:
*/
/** Descriptive text for the echo option */
-#define ECHO_DESC (gnutls_serv_opt_strs+1467)
+#define ECHO_DESC (gnutls_serv_opt_strs+1505)
/** Upper-cased name for the echo option */
-#define ECHO_NAME (gnutls_serv_opt_strs+1489)
+#define ECHO_NAME (gnutls_serv_opt_strs+1527)
/** Name string for the echo option */
-#define ECHO_name (gnutls_serv_opt_strs+1494)
+#define ECHO_name (gnutls_serv_opt_strs+1532)
/** Compiled in flag settings for the echo option */
#define ECHO_FLAGS (OPTST_DISABLED)
@@ -360,11 +375,11 @@ static char const gnutls_serv_opt_strs[3428] =
* udp option description:
*/
/** Descriptive text for the udp option */
-#define UDP_DESC (gnutls_serv_opt_strs+1499)
+#define UDP_DESC (gnutls_serv_opt_strs+1537)
/** Upper-cased name for the udp option */
-#define UDP_NAME (gnutls_serv_opt_strs+1532)
+#define UDP_NAME (gnutls_serv_opt_strs+1570)
/** Name string for the udp option */
-#define UDP_name (gnutls_serv_opt_strs+1536)
+#define UDP_name (gnutls_serv_opt_strs+1574)
/** Compiled in flag settings for the udp option */
#define UDP_FLAGS (OPTST_DISABLED)
@@ -372,11 +387,11 @@ static char const gnutls_serv_opt_strs[3428] =
* mtu option description:
*/
/** Descriptive text for the mtu option */
-#define MTU_DESC (gnutls_serv_opt_strs+1540)
+#define MTU_DESC (gnutls_serv_opt_strs+1578)
/** Upper-cased name for the mtu option */
-#define MTU_NAME (gnutls_serv_opt_strs+1565)
+#define MTU_NAME (gnutls_serv_opt_strs+1603)
/** Name string for the mtu option */
-#define MTU_name (gnutls_serv_opt_strs+1569)
+#define MTU_name (gnutls_serv_opt_strs+1607)
/** Compiled in flag settings for the mtu option */
#define MTU_FLAGS (OPTST_DISABLED \
| OPTST_SET_ARGTYPE(OPARG_TYPE_NUMERIC))
@@ -385,11 +400,11 @@ static char const gnutls_serv_opt_strs[3428] =
* srtp_profiles option description:
*/
/** Descriptive text for the srtp_profiles option */
-#define SRTP_PROFILES_DESC (gnutls_serv_opt_strs+1573)
+#define SRTP_PROFILES_DESC (gnutls_serv_opt_strs+1611)
/** Upper-cased name for the srtp_profiles option */
-#define SRTP_PROFILES_NAME (gnutls_serv_opt_strs+1593)
+#define SRTP_PROFILES_NAME (gnutls_serv_opt_strs+1631)
/** Name string for the srtp_profiles option */
-#define SRTP_PROFILES_name (gnutls_serv_opt_strs+1607)
+#define SRTP_PROFILES_name (gnutls_serv_opt_strs+1645)
/** Compiled in flag settings for the srtp_profiles option */
#define SRTP_PROFILES_FLAGS (OPTST_DISABLED \
| OPTST_SET_ARGTYPE(OPARG_TYPE_STRING))
@@ -399,11 +414,11 @@ static char const gnutls_serv_opt_strs[3428] =
* "Must also have options" and "Incompatible options":
*/
/** Descriptive text for the disable-client-cert option */
-#define DISABLE_CLIENT_CERT_DESC (gnutls_serv_opt_strs+1621)
+#define DISABLE_CLIENT_CERT_DESC (gnutls_serv_opt_strs+1659)
/** Upper-cased name for the disable-client-cert option */
-#define DISABLE_CLIENT_CERT_NAME (gnutls_serv_opt_strs+1657)
+#define DISABLE_CLIENT_CERT_NAME (gnutls_serv_opt_strs+1695)
/** Name string for the disable-client-cert option */
-#define DISABLE_CLIENT_CERT_name (gnutls_serv_opt_strs+1677)
+#define DISABLE_CLIENT_CERT_name (gnutls_serv_opt_strs+1715)
/** Other options that appear in conjunction with the disable-client-cert option */
static int const aDisable_Client_CertCantList[] = {
INDEX_OPT_REQUIRE_CLIENT_CERT, NO_EQUIVALENT };
@@ -414,11 +429,11 @@ static int const aDisable_Client_CertCantList[] = {
* require-client-cert option description:
*/
/** Descriptive text for the require-client-cert option */
-#define REQUIRE_CLIENT_CERT_DESC (gnutls_serv_opt_strs+1697)
+#define REQUIRE_CLIENT_CERT_DESC (gnutls_serv_opt_strs+1735)
/** Upper-cased name for the require-client-cert option */
-#define REQUIRE_CLIENT_CERT_NAME (gnutls_serv_opt_strs+1726)
+#define REQUIRE_CLIENT_CERT_NAME (gnutls_serv_opt_strs+1764)
/** Name string for the require-client-cert option */
-#define REQUIRE_CLIENT_CERT_name (gnutls_serv_opt_strs+1746)
+#define REQUIRE_CLIENT_CERT_name (gnutls_serv_opt_strs+1784)
/** Compiled in flag settings for the require-client-cert option */
#define REQUIRE_CLIENT_CERT_FLAGS (OPTST_DISABLED)
@@ -426,11 +441,11 @@ static int const aDisable_Client_CertCantList[] = {
* verify-client-cert option description:
*/
/** Descriptive text for the verify-client-cert option */
-#define VERIFY_CLIENT_CERT_DESC (gnutls_serv_opt_strs+1766)
+#define VERIFY_CLIENT_CERT_DESC (gnutls_serv_opt_strs+1804)
/** Upper-cased name for the verify-client-cert option */
-#define VERIFY_CLIENT_CERT_NAME (gnutls_serv_opt_strs+1814)
+#define VERIFY_CLIENT_CERT_NAME (gnutls_serv_opt_strs+1852)
/** Name string for the verify-client-cert option */
-#define VERIFY_CLIENT_CERT_name (gnutls_serv_opt_strs+1833)
+#define VERIFY_CLIENT_CERT_name (gnutls_serv_opt_strs+1871)
/** Compiled in flag settings for the verify-client-cert option */
#define VERIFY_CLIENT_CERT_FLAGS (OPTST_DISABLED)
@@ -438,11 +453,11 @@ static int const aDisable_Client_CertCantList[] = {
* heartbeat option description:
*/
/** Descriptive text for the heartbeat option */
-#define HEARTBEAT_DESC (gnutls_serv_opt_strs+1852)
+#define HEARTBEAT_DESC (gnutls_serv_opt_strs+1890)
/** Upper-cased name for the heartbeat option */
-#define HEARTBEAT_NAME (gnutls_serv_opt_strs+1879)
+#define HEARTBEAT_NAME (gnutls_serv_opt_strs+1917)
/** Name string for the heartbeat option */
-#define HEARTBEAT_name (gnutls_serv_opt_strs+1889)
+#define HEARTBEAT_name (gnutls_serv_opt_strs+1927)
/** Compiled in flag settings for the heartbeat option */
#define HEARTBEAT_FLAGS (OPTST_DISABLED)
@@ -450,11 +465,11 @@ static int const aDisable_Client_CertCantList[] = {
* x509fmtder option description:
*/
/** Descriptive text for the x509fmtder option */
-#define X509FMTDER_DESC (gnutls_serv_opt_strs+1899)
+#define X509FMTDER_DESC (gnutls_serv_opt_strs+1937)
/** Upper-cased name for the x509fmtder option */
-#define X509FMTDER_NAME (gnutls_serv_opt_strs+1944)
+#define X509FMTDER_NAME (gnutls_serv_opt_strs+1982)
/** Name string for the x509fmtder option */
-#define X509FMTDER_name (gnutls_serv_opt_strs+1955)
+#define X509FMTDER_name (gnutls_serv_opt_strs+1993)
/** Compiled in flag settings for the x509fmtder option */
#define X509FMTDER_FLAGS (OPTST_DISABLED)
@@ -462,11 +477,11 @@ static int const aDisable_Client_CertCantList[] = {
* priority option description:
*/
/** Descriptive text for the priority option */
-#define PRIORITY_DESC (gnutls_serv_opt_strs+1966)
+#define PRIORITY_DESC (gnutls_serv_opt_strs+2004)
/** Upper-cased name for the priority option */
-#define PRIORITY_NAME (gnutls_serv_opt_strs+1984)
+#define PRIORITY_NAME (gnutls_serv_opt_strs+2022)
/** Name string for the priority option */
-#define PRIORITY_name (gnutls_serv_opt_strs+1993)
+#define PRIORITY_name (gnutls_serv_opt_strs+2031)
/** Compiled in flag settings for the priority option */
#define PRIORITY_FLAGS (OPTST_DISABLED \
| OPTST_SET_ARGTYPE(OPARG_TYPE_STRING))
@@ -475,11 +490,11 @@ static int const aDisable_Client_CertCantList[] = {
* dhparams option description:
*/
/** Descriptive text for the dhparams option */
-#define DHPARAMS_DESC (gnutls_serv_opt_strs+2002)
+#define DHPARAMS_DESC (gnutls_serv_opt_strs+2040)
/** Upper-cased name for the dhparams option */
-#define DHPARAMS_NAME (gnutls_serv_opt_strs+2024)
+#define DHPARAMS_NAME (gnutls_serv_opt_strs+2062)
/** Name string for the dhparams option */
-#define DHPARAMS_name (gnutls_serv_opt_strs+2033)
+#define DHPARAMS_name (gnutls_serv_opt_strs+2071)
/** Compiled in flag settings for the dhparams option */
#define DHPARAMS_FLAGS (OPTST_DISABLED \
| OPTST_SET_ARGTYPE(OPARG_TYPE_FILE))
@@ -488,11 +503,11 @@ static int const aDisable_Client_CertCantList[] = {
* x509cafile option description:
*/
/** Descriptive text for the x509cafile option */
-#define X509CAFILE_DESC (gnutls_serv_opt_strs+2042)
+#define X509CAFILE_DESC (gnutls_serv_opt_strs+2080)
/** Upper-cased name for the x509cafile option */
-#define X509CAFILE_NAME (gnutls_serv_opt_strs+2082)
+#define X509CAFILE_NAME (gnutls_serv_opt_strs+2120)
/** Name string for the x509cafile option */
-#define X509CAFILE_name (gnutls_serv_opt_strs+2093)
+#define X509CAFILE_name (gnutls_serv_opt_strs+2131)
/** Compiled in flag settings for the x509cafile option */
#define X509CAFILE_FLAGS (OPTST_DISABLED \
| OPTST_SET_ARGTYPE(OPARG_TYPE_STRING))
@@ -501,11 +516,11 @@ static int const aDisable_Client_CertCantList[] = {
* x509crlfile option description:
*/
/** Descriptive text for the x509crlfile option */
-#define X509CRLFILE_DESC (gnutls_serv_opt_strs+2104)
+#define X509CRLFILE_DESC (gnutls_serv_opt_strs+2142)
/** Upper-cased name for the x509crlfile option */
-#define X509CRLFILE_NAME (gnutls_serv_opt_strs+2120)
+#define X509CRLFILE_NAME (gnutls_serv_opt_strs+2158)
/** Name string for the x509crlfile option */
-#define X509CRLFILE_name (gnutls_serv_opt_strs+2132)
+#define X509CRLFILE_name (gnutls_serv_opt_strs+2170)
/** Compiled in flag settings for the x509crlfile option */
#define X509CRLFILE_FLAGS (OPTST_DISABLED \
| OPTST_SET_ARGTYPE(OPARG_TYPE_FILE))
@@ -514,11 +529,11 @@ static int const aDisable_Client_CertCantList[] = {
* pgpkeyfile option description:
*/
/** Descriptive text for the pgpkeyfile option */
-#define PGPKEYFILE_DESC (gnutls_serv_opt_strs+2144)
+#define PGPKEYFILE_DESC (gnutls_serv_opt_strs+2182)
/** Upper-cased name for the pgpkeyfile option */
-#define PGPKEYFILE_NAME (gnutls_serv_opt_strs+2177)
+#define PGPKEYFILE_NAME (gnutls_serv_opt_strs+2215)
/** Name string for the pgpkeyfile option */
-#define PGPKEYFILE_name (gnutls_serv_opt_strs+2188)
+#define PGPKEYFILE_name (gnutls_serv_opt_strs+2226)
/** Compiled in flag settings for the pgpkeyfile option */
#define PGPKEYFILE_FLAGS (OPTST_DISABLED | OPTST_DEPRECATED \
| OPTST_SET_ARGTYPE(OPARG_TYPE_FILE))
@@ -527,11 +542,11 @@ static int const aDisable_Client_CertCantList[] = {
* x509keyfile option description:
*/
/** Descriptive text for the x509keyfile option */
-#define X509KEYFILE_DESC (gnutls_serv_opt_strs+2199)
+#define X509KEYFILE_DESC (gnutls_serv_opt_strs+2237)
/** Upper-cased name for the x509keyfile option */
-#define X509KEYFILE_NAME (gnutls_serv_opt_strs+2237)
+#define X509KEYFILE_NAME (gnutls_serv_opt_strs+2275)
/** Name string for the x509keyfile option */
-#define X509KEYFILE_name (gnutls_serv_opt_strs+2249)
+#define X509KEYFILE_name (gnutls_serv_opt_strs+2287)
/** Compiled in flag settings for the x509keyfile option */
#define X509KEYFILE_FLAGS (OPTST_DISABLED | OPTST_STACKED \
| OPTST_SET_ARGTYPE(OPARG_TYPE_STRING))
@@ -540,11 +555,11 @@ static int const aDisable_Client_CertCantList[] = {
* x509certfile option description:
*/
/** Descriptive text for the x509certfile option */
-#define X509CERTFILE_DESC (gnutls_serv_opt_strs+2261)
+#define X509CERTFILE_DESC (gnutls_serv_opt_strs+2299)
/** Upper-cased name for the x509certfile option */
-#define X509CERTFILE_NAME (gnutls_serv_opt_strs+2307)
+#define X509CERTFILE_NAME (gnutls_serv_opt_strs+2345)
/** Name string for the x509certfile option */
-#define X509CERTFILE_name (gnutls_serv_opt_strs+2320)
+#define X509CERTFILE_name (gnutls_serv_opt_strs+2358)
/** Compiled in flag settings for the x509certfile option */
#define X509CERTFILE_FLAGS (OPTST_DISABLED | OPTST_STACKED \
| OPTST_SET_ARGTYPE(OPARG_TYPE_STRING))
@@ -553,10 +568,10 @@ static int const aDisable_Client_CertCantList[] = {
* x509dsakeyfile option description:
*/
/** Descriptive text for the x509dsakeyfile option */
-#define X509DSAKEYFILE_DESC (gnutls_serv_opt_strs+2333)
+#define X509DSAKEYFILE_DESC (gnutls_serv_opt_strs+2371)
#define X509DSAKEYFILE_NAME NULL
/** Unmodified name string for the x509dsakeyfile option */
-#define X509DSAKEYFILE_name (gnutls_serv_opt_strs+2384)
+#define X509DSAKEYFILE_name (gnutls_serv_opt_strs+2422)
/** Compiled in flag settings for the x509dsakeyfile option */
#define X509DSAKEYFILE_FLAGS (X509KEYFILE_FLAGS | OPTST_ALIAS | OPTST_DEPRECATED)
@@ -564,10 +579,10 @@ static int const aDisable_Client_CertCantList[] = {
* x509dsacertfile option description:
*/
/** Descriptive text for the x509dsacertfile option */
-#define X509DSACERTFILE_DESC (gnutls_serv_opt_strs+2399)
+#define X509DSACERTFILE_DESC (gnutls_serv_opt_strs+2437)
#define X509DSACERTFILE_NAME NULL
/** Unmodified name string for the x509dsacertfile option */
-#define X509DSACERTFILE_name (gnutls_serv_opt_strs+2451)
+#define X509DSACERTFILE_name (gnutls_serv_opt_strs+2489)
/** Compiled in flag settings for the x509dsacertfile option */
#define X509DSACERTFILE_FLAGS (X509CERTFILE_FLAGS | OPTST_ALIAS | OPTST_DEPRECATED)
@@ -575,10 +590,10 @@ static int const aDisable_Client_CertCantList[] = {
* x509ecckeyfile option description:
*/
/** Descriptive text for the x509ecckeyfile option */
-#define X509ECCKEYFILE_DESC (gnutls_serv_opt_strs+2333)
+#define X509ECCKEYFILE_DESC (gnutls_serv_opt_strs+2371)
#define X509ECCKEYFILE_NAME NULL
/** Unmodified name string for the x509ecckeyfile option */
-#define X509ECCKEYFILE_name (gnutls_serv_opt_strs+2467)
+#define X509ECCKEYFILE_name (gnutls_serv_opt_strs+2505)
/** Compiled in flag settings for the x509ecckeyfile option */
#define X509ECCKEYFILE_FLAGS (X509KEYFILE_FLAGS | OPTST_ALIAS | OPTST_DEPRECATED)
@@ -586,10 +601,10 @@ static int const aDisable_Client_CertCantList[] = {
* x509ecccertfile option description:
*/
/** Descriptive text for the x509ecccertfile option */
-#define X509ECCCERTFILE_DESC (gnutls_serv_opt_strs+2399)
+#define X509ECCCERTFILE_DESC (gnutls_serv_opt_strs+2437)
#define X509ECCCERTFILE_NAME NULL
/** Unmodified name string for the x509ecccertfile option */
-#define X509ECCCERTFILE_name (gnutls_serv_opt_strs+2482)
+#define X509ECCCERTFILE_name (gnutls_serv_opt_strs+2520)
/** Compiled in flag settings for the x509ecccertfile option */
#define X509ECCCERTFILE_FLAGS (X509CERTFILE_FLAGS | OPTST_ALIAS | OPTST_DEPRECATED)
@@ -597,11 +612,11 @@ static int const aDisable_Client_CertCantList[] = {
* srppasswd option description:
*/
/** Descriptive text for the srppasswd option */
-#define SRPPASSWD_DESC (gnutls_serv_opt_strs+2498)
+#define SRPPASSWD_DESC (gnutls_serv_opt_strs+2536)
/** Upper-cased name for the srppasswd option */
-#define SRPPASSWD_NAME (gnutls_serv_opt_strs+2523)
+#define SRPPASSWD_NAME (gnutls_serv_opt_strs+2561)
/** Name string for the srppasswd option */
-#define SRPPASSWD_name (gnutls_serv_opt_strs+2533)
+#define SRPPASSWD_name (gnutls_serv_opt_strs+2571)
/** Compiled in flag settings for the srppasswd option */
#define SRPPASSWD_FLAGS (OPTST_DISABLED \
| OPTST_SET_ARGTYPE(OPARG_TYPE_FILE))
@@ -610,11 +625,11 @@ static int const aDisable_Client_CertCantList[] = {
* srppasswdconf option description:
*/
/** Descriptive text for the srppasswdconf option */
-#define SRPPASSWDCONF_DESC (gnutls_serv_opt_strs+2543)
+#define SRPPASSWDCONF_DESC (gnutls_serv_opt_strs+2581)
/** Upper-cased name for the srppasswdconf option */
-#define SRPPASSWDCONF_NAME (gnutls_serv_opt_strs+2582)
+#define SRPPASSWDCONF_NAME (gnutls_serv_opt_strs+2620)
/** Name string for the srppasswdconf option */
-#define SRPPASSWDCONF_name (gnutls_serv_opt_strs+2596)
+#define SRPPASSWDCONF_name (gnutls_serv_opt_strs+2634)
/** Compiled in flag settings for the srppasswdconf option */
#define SRPPASSWDCONF_FLAGS (OPTST_DISABLED \
| OPTST_SET_ARGTYPE(OPARG_TYPE_FILE))
@@ -623,11 +638,11 @@ static int const aDisable_Client_CertCantList[] = {
* pskpasswd option description:
*/
/** Descriptive text for the pskpasswd option */
-#define PSKPASSWD_DESC (gnutls_serv_opt_strs+2610)
+#define PSKPASSWD_DESC (gnutls_serv_opt_strs+2648)
/** Upper-cased name for the pskpasswd option */
-#define PSKPASSWD_NAME (gnutls_serv_opt_strs+2635)
+#define PSKPASSWD_NAME (gnutls_serv_opt_strs+2673)
/** Name string for the pskpasswd option */
-#define PSKPASSWD_name (gnutls_serv_opt_strs+2645)
+#define PSKPASSWD_name (gnutls_serv_opt_strs+2683)
/** Compiled in flag settings for the pskpasswd option */
#define PSKPASSWD_FLAGS (OPTST_DISABLED \
| OPTST_SET_ARGTYPE(OPARG_TYPE_FILE))
@@ -636,11 +651,11 @@ static int const aDisable_Client_CertCantList[] = {
* pskhint option description:
*/
/** Descriptive text for the pskhint option */
-#define PSKHINT_DESC (gnutls_serv_opt_strs+2655)
+#define PSKHINT_DESC (gnutls_serv_opt_strs+2693)
/** Upper-cased name for the pskhint option */
-#define PSKHINT_NAME (gnutls_serv_opt_strs+2680)
+#define PSKHINT_NAME (gnutls_serv_opt_strs+2718)
/** Name string for the pskhint option */
-#define PSKHINT_name (gnutls_serv_opt_strs+2688)
+#define PSKHINT_name (gnutls_serv_opt_strs+2726)
/** Compiled in flag settings for the pskhint option */
#define PSKHINT_FLAGS (OPTST_DISABLED \
| OPTST_SET_ARGTYPE(OPARG_TYPE_STRING))
@@ -649,11 +664,11 @@ static int const aDisable_Client_CertCantList[] = {
* ocsp-response option description:
*/
/** Descriptive text for the ocsp-response option */
-#define OCSP_RESPONSE_DESC (gnutls_serv_opt_strs+2696)
+#define OCSP_RESPONSE_DESC (gnutls_serv_opt_strs+2734)
/** Upper-cased name for the ocsp-response option */
-#define OCSP_RESPONSE_NAME (gnutls_serv_opt_strs+2732)
+#define OCSP_RESPONSE_NAME (gnutls_serv_opt_strs+2770)
/** Name string for the ocsp-response option */
-#define OCSP_RESPONSE_name (gnutls_serv_opt_strs+2746)
+#define OCSP_RESPONSE_name (gnutls_serv_opt_strs+2784)
/** Compiled in flag settings for the ocsp-response option */
#define OCSP_RESPONSE_FLAGS (OPTST_DISABLED | OPTST_STACKED \
| OPTST_SET_ARGTYPE(OPARG_TYPE_STRING))
@@ -662,11 +677,11 @@ static int const aDisable_Client_CertCantList[] = {
* ignore-ocsp-response-errors option description:
*/
/** Descriptive text for the ignore-ocsp-response-errors option */
-#define IGNORE_OCSP_RESPONSE_ERRORS_DESC (gnutls_serv_opt_strs+2760)
+#define IGNORE_OCSP_RESPONSE_ERRORS_DESC (gnutls_serv_opt_strs+2798)
/** Upper-cased name for the ignore-ocsp-response-errors option */
-#define IGNORE_OCSP_RESPONSE_ERRORS_NAME (gnutls_serv_opt_strs+2809)
+#define IGNORE_OCSP_RESPONSE_ERRORS_NAME (gnutls_serv_opt_strs+2847)
/** Name string for the ignore-ocsp-response-errors option */
-#define IGNORE_OCSP_RESPONSE_ERRORS_name (gnutls_serv_opt_strs+2837)
+#define IGNORE_OCSP_RESPONSE_ERRORS_name (gnutls_serv_opt_strs+2875)
/** Compiled in flag settings for the ignore-ocsp-response-errors option */
#define IGNORE_OCSP_RESPONSE_ERRORS_FLAGS (OPTST_DISABLED)
@@ -674,11 +689,11 @@ static int const aDisable_Client_CertCantList[] = {
* port option description:
*/
/** Descriptive text for the port option */
-#define PORT_DESC (gnutls_serv_opt_strs+2865)
+#define PORT_DESC (gnutls_serv_opt_strs+2903)
/** Upper-cased name for the port option */
-#define PORT_NAME (gnutls_serv_opt_strs+2888)
+#define PORT_NAME (gnutls_serv_opt_strs+2926)
/** Name string for the port option */
-#define PORT_name (gnutls_serv_opt_strs+2893)
+#define PORT_name (gnutls_serv_opt_strs+2931)
/** Compiled in flag settings for the port option */
#define PORT_FLAGS (OPTST_DISABLED \
| OPTST_SET_ARGTYPE(OPARG_TYPE_NUMERIC))
@@ -687,11 +702,11 @@ static int const aDisable_Client_CertCantList[] = {
* list option description:
*/
/** Descriptive text for the list option */
-#define LIST_DESC (gnutls_serv_opt_strs+2898)
+#define LIST_DESC (gnutls_serv_opt_strs+2936)
/** Upper-cased name for the list option */
-#define LIST_NAME (gnutls_serv_opt_strs+2949)
+#define LIST_NAME (gnutls_serv_opt_strs+2987)
/** Name string for the list option */
-#define LIST_name (gnutls_serv_opt_strs+2954)
+#define LIST_name (gnutls_serv_opt_strs+2992)
/** Compiled in flag settings for the list option */
#define LIST_FLAGS (OPTST_DISABLED)
@@ -699,11 +714,11 @@ static int const aDisable_Client_CertCantList[] = {
* provider option description:
*/
/** Descriptive text for the provider option */
-#define PROVIDER_DESC (gnutls_serv_opt_strs+2959)
+#define PROVIDER_DESC (gnutls_serv_opt_strs+2997)
/** Upper-cased name for the provider option */
-#define PROVIDER_NAME (gnutls_serv_opt_strs+2997)
+#define PROVIDER_NAME (gnutls_serv_opt_strs+3035)
/** Name string for the provider option */
-#define PROVIDER_name (gnutls_serv_opt_strs+3006)
+#define PROVIDER_name (gnutls_serv_opt_strs+3044)
/** Compiled in flag settings for the provider option */
#define PROVIDER_FLAGS (OPTST_DISABLED \
| OPTST_SET_ARGTYPE(OPARG_TYPE_FILE))
@@ -711,11 +726,11 @@ static int const aDisable_Client_CertCantList[] = {
/*
* Help/More_Help/Version option descriptions:
*/
-#define HELP_DESC (gnutls_serv_opt_strs+3015)
-#define HELP_name (gnutls_serv_opt_strs+3059)
+#define HELP_DESC (gnutls_serv_opt_strs+3053)
+#define HELP_name (gnutls_serv_opt_strs+3097)
#ifdef HAVE_WORKING_FORK
-#define MORE_HELP_DESC (gnutls_serv_opt_strs+3064)
-#define MORE_HELP_name (gnutls_serv_opt_strs+3109)
+#define MORE_HELP_DESC (gnutls_serv_opt_strs+3102)
+#define MORE_HELP_name (gnutls_serv_opt_strs+3147)
#define MORE_HELP_FLAGS (OPTST_IMM | OPTST_NO_INIT)
#else
#define MORE_HELP_DESC HELP_DESC
@@ -728,8 +743,8 @@ static int const aDisable_Client_CertCantList[] = {
# define VER_FLAGS (OPTST_SET_ARGTYPE(OPARG_TYPE_STRING) | \
OPTST_ARG_OPTIONAL | OPTST_IMM | OPTST_NO_INIT)
#endif
-#define VER_DESC (gnutls_serv_opt_strs+3119)
-#define VER_name (gnutls_serv_opt_strs+3155)
+#define VER_DESC (gnutls_serv_opt_strs+3157)
+#define VER_name (gnutls_serv_opt_strs+3193)
/**
* Declare option callback procedures
*/
@@ -825,8 +840,20 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ NOTICKET_DESC, NOTICKET_NAME, NOTICKET_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 6, VALUE_OPT_NOCOOKIE,
- /* equiv idx, value */ 6, VALUE_OPT_NOCOOKIE,
+ { /* entry idx, value */ 6, VALUE_OPT_EARLYDATA,
+ /* equiv idx, value */ 6, VALUE_OPT_EARLYDATA,
+ /* equivalenced to */ NO_EQUIVALENT,
+ /* min, max, act ct */ 0, 1, 0,
+ /* opt state flags */ EARLYDATA_FLAGS, 0,
+ /* last opt argumnt */ { NULL }, /* --earlydata */
+ /* arg list/cookie */ NULL,
+ /* must/cannot opts */ NULL, NULL,
+ /* option proc */ NULL,
+ /* desc, NAME, name */ EARLYDATA_DESC, EARLYDATA_NAME, EARLYDATA_name,
+ /* disablement strs */ NULL, NULL },
+
+ { /* entry idx, value */ 7, VALUE_OPT_NOCOOKIE,
+ /* equiv idx, value */ 7, VALUE_OPT_NOCOOKIE,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ NOCOOKIE_FLAGS, 0,
@@ -837,8 +864,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ NOCOOKIE_DESC, NOCOOKIE_NAME, NOCOOKIE_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 7, VALUE_OPT_GENERATE,
- /* equiv idx, value */ 7, VALUE_OPT_GENERATE,
+ { /* entry idx, value */ 8, VALUE_OPT_GENERATE,
+ /* equiv idx, value */ 8, VALUE_OPT_GENERATE,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ GENERATE_FLAGS, 0,
@@ -849,8 +876,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ GENERATE_DESC, GENERATE_NAME, GENERATE_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 8, VALUE_OPT_QUIET,
- /* equiv idx, value */ 8, VALUE_OPT_QUIET,
+ { /* entry idx, value */ 9, VALUE_OPT_QUIET,
+ /* equiv idx, value */ 9, VALUE_OPT_QUIET,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ QUIET_FLAGS, 0,
@@ -861,8 +888,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ QUIET_DESC, QUIET_NAME, QUIET_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 9, VALUE_OPT_NODB,
- /* equiv idx, value */ 9, VALUE_OPT_NODB,
+ { /* entry idx, value */ 10, VALUE_OPT_NODB,
+ /* equiv idx, value */ 10, VALUE_OPT_NODB,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ NODB_FLAGS, 0,
@@ -873,8 +900,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ NODB_DESC, NODB_NAME, NODB_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 10, VALUE_OPT_HTTP,
- /* equiv idx, value */ 10, VALUE_OPT_HTTP,
+ { /* entry idx, value */ 11, VALUE_OPT_HTTP,
+ /* equiv idx, value */ 11, VALUE_OPT_HTTP,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ HTTP_FLAGS, 0,
@@ -885,8 +912,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ HTTP_DESC, HTTP_NAME, HTTP_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 11, VALUE_OPT_ECHO,
- /* equiv idx, value */ 11, VALUE_OPT_ECHO,
+ { /* entry idx, value */ 12, VALUE_OPT_ECHO,
+ /* equiv idx, value */ 12, VALUE_OPT_ECHO,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ ECHO_FLAGS, 0,
@@ -897,8 +924,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ ECHO_DESC, ECHO_NAME, ECHO_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 12, VALUE_OPT_UDP,
- /* equiv idx, value */ 12, VALUE_OPT_UDP,
+ { /* entry idx, value */ 13, VALUE_OPT_UDP,
+ /* equiv idx, value */ 13, VALUE_OPT_UDP,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ UDP_FLAGS, 0,
@@ -909,8 +936,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ UDP_DESC, UDP_NAME, UDP_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 13, VALUE_OPT_MTU,
- /* equiv idx, value */ 13, VALUE_OPT_MTU,
+ { /* entry idx, value */ 14, VALUE_OPT_MTU,
+ /* equiv idx, value */ 14, VALUE_OPT_MTU,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ MTU_FLAGS, 0,
@@ -921,8 +948,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ MTU_DESC, MTU_NAME, MTU_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 14, VALUE_OPT_SRTP_PROFILES,
- /* equiv idx, value */ 14, VALUE_OPT_SRTP_PROFILES,
+ { /* entry idx, value */ 15, VALUE_OPT_SRTP_PROFILES,
+ /* equiv idx, value */ 15, VALUE_OPT_SRTP_PROFILES,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ SRTP_PROFILES_FLAGS, 0,
@@ -933,8 +960,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ SRTP_PROFILES_DESC, SRTP_PROFILES_NAME, SRTP_PROFILES_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 15, VALUE_OPT_DISABLE_CLIENT_CERT,
- /* equiv idx, value */ 15, VALUE_OPT_DISABLE_CLIENT_CERT,
+ { /* entry idx, value */ 16, VALUE_OPT_DISABLE_CLIENT_CERT,
+ /* equiv idx, value */ 16, VALUE_OPT_DISABLE_CLIENT_CERT,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ DISABLE_CLIENT_CERT_FLAGS, 0,
@@ -945,8 +972,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ DISABLE_CLIENT_CERT_DESC, DISABLE_CLIENT_CERT_NAME, DISABLE_CLIENT_CERT_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 16, VALUE_OPT_REQUIRE_CLIENT_CERT,
- /* equiv idx, value */ 16, VALUE_OPT_REQUIRE_CLIENT_CERT,
+ { /* entry idx, value */ 17, VALUE_OPT_REQUIRE_CLIENT_CERT,
+ /* equiv idx, value */ 17, VALUE_OPT_REQUIRE_CLIENT_CERT,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ REQUIRE_CLIENT_CERT_FLAGS, 0,
@@ -957,8 +984,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ REQUIRE_CLIENT_CERT_DESC, REQUIRE_CLIENT_CERT_NAME, REQUIRE_CLIENT_CERT_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 17, VALUE_OPT_VERIFY_CLIENT_CERT,
- /* equiv idx, value */ 17, VALUE_OPT_VERIFY_CLIENT_CERT,
+ { /* entry idx, value */ 18, VALUE_OPT_VERIFY_CLIENT_CERT,
+ /* equiv idx, value */ 18, VALUE_OPT_VERIFY_CLIENT_CERT,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ VERIFY_CLIENT_CERT_FLAGS, 0,
@@ -969,8 +996,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ VERIFY_CLIENT_CERT_DESC, VERIFY_CLIENT_CERT_NAME, VERIFY_CLIENT_CERT_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 18, VALUE_OPT_HEARTBEAT,
- /* equiv idx, value */ 18, VALUE_OPT_HEARTBEAT,
+ { /* entry idx, value */ 19, VALUE_OPT_HEARTBEAT,
+ /* equiv idx, value */ 19, VALUE_OPT_HEARTBEAT,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ HEARTBEAT_FLAGS, 0,
@@ -981,8 +1008,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ HEARTBEAT_DESC, HEARTBEAT_NAME, HEARTBEAT_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 19, VALUE_OPT_X509FMTDER,
- /* equiv idx, value */ 19, VALUE_OPT_X509FMTDER,
+ { /* entry idx, value */ 20, VALUE_OPT_X509FMTDER,
+ /* equiv idx, value */ 20, VALUE_OPT_X509FMTDER,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ X509FMTDER_FLAGS, 0,
@@ -993,8 +1020,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ X509FMTDER_DESC, X509FMTDER_NAME, X509FMTDER_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 20, VALUE_OPT_PRIORITY,
- /* equiv idx, value */ 20, VALUE_OPT_PRIORITY,
+ { /* entry idx, value */ 21, VALUE_OPT_PRIORITY,
+ /* equiv idx, value */ 21, VALUE_OPT_PRIORITY,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ PRIORITY_FLAGS, 0,
@@ -1005,8 +1032,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ PRIORITY_DESC, PRIORITY_NAME, PRIORITY_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 21, VALUE_OPT_DHPARAMS,
- /* equiv idx, value */ 21, VALUE_OPT_DHPARAMS,
+ { /* entry idx, value */ 22, VALUE_OPT_DHPARAMS,
+ /* equiv idx, value */ 22, VALUE_OPT_DHPARAMS,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ DHPARAMS_FLAGS, 0,
@@ -1017,8 +1044,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ DHPARAMS_DESC, DHPARAMS_NAME, DHPARAMS_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 22, VALUE_OPT_X509CAFILE,
- /* equiv idx, value */ 22, VALUE_OPT_X509CAFILE,
+ { /* entry idx, value */ 23, VALUE_OPT_X509CAFILE,
+ /* equiv idx, value */ 23, VALUE_OPT_X509CAFILE,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ X509CAFILE_FLAGS, 0,
@@ -1029,8 +1056,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ X509CAFILE_DESC, X509CAFILE_NAME, X509CAFILE_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 23, VALUE_OPT_X509CRLFILE,
- /* equiv idx, value */ 23, VALUE_OPT_X509CRLFILE,
+ { /* entry idx, value */ 24, VALUE_OPT_X509CRLFILE,
+ /* equiv idx, value */ 24, VALUE_OPT_X509CRLFILE,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ X509CRLFILE_FLAGS, 0,
@@ -1041,8 +1068,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ X509CRLFILE_DESC, X509CRLFILE_NAME, X509CRLFILE_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 24, VALUE_OPT_PGPKEYFILE,
- /* equiv idx, value */ 24, VALUE_OPT_PGPKEYFILE,
+ { /* entry idx, value */ 25, VALUE_OPT_PGPKEYFILE,
+ /* equiv idx, value */ 25, VALUE_OPT_PGPKEYFILE,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ PGPKEYFILE_FLAGS, 0,
@@ -1053,8 +1080,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ PGPKEYFILE_DESC, PGPKEYFILE_NAME, PGPKEYFILE_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 25, VALUE_OPT_X509KEYFILE,
- /* equiv idx, value */ 25, VALUE_OPT_X509KEYFILE,
+ { /* entry idx, value */ 26, VALUE_OPT_X509KEYFILE,
+ /* equiv idx, value */ 26, VALUE_OPT_X509KEYFILE,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, NOLIMIT, 0,
/* opt state flags */ X509KEYFILE_FLAGS, 0,
@@ -1065,8 +1092,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ X509KEYFILE_DESC, X509KEYFILE_NAME, X509KEYFILE_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 26, VALUE_OPT_X509CERTFILE,
- /* equiv idx, value */ 26, VALUE_OPT_X509CERTFILE,
+ { /* entry idx, value */ 27, VALUE_OPT_X509CERTFILE,
+ /* equiv idx, value */ 27, VALUE_OPT_X509CERTFILE,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, NOLIMIT, 0,
/* opt state flags */ X509CERTFILE_FLAGS, 0,
@@ -1077,8 +1104,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ X509CERTFILE_DESC, X509CERTFILE_NAME, X509CERTFILE_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 27, VALUE_OPT_X509DSAKEYFILE,
- /* equiv idx, value */ 27, VALUE_OPT_X509DSAKEYFILE,
+ { /* entry idx, value */ 28, VALUE_OPT_X509DSAKEYFILE,
+ /* equiv idx, value */ 28, VALUE_OPT_X509DSAKEYFILE,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ X509DSAKEYFILE_FLAGS, 0,
@@ -1089,8 +1116,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ X509DSAKEYFILE_DESC, X509DSAKEYFILE_NAME, X509DSAKEYFILE_name,
/* disablement strs */ 0, 0 },
- { /* entry idx, value */ 28, VALUE_OPT_X509DSACERTFILE,
- /* equiv idx, value */ 28, VALUE_OPT_X509DSACERTFILE,
+ { /* entry idx, value */ 29, VALUE_OPT_X509DSACERTFILE,
+ /* equiv idx, value */ 29, VALUE_OPT_X509DSACERTFILE,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ X509DSACERTFILE_FLAGS, 0,
@@ -1101,8 +1128,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ X509DSACERTFILE_DESC, X509DSACERTFILE_NAME, X509DSACERTFILE_name,
/* disablement strs */ 0, 0 },
- { /* entry idx, value */ 29, VALUE_OPT_X509ECCKEYFILE,
- /* equiv idx, value */ 29, VALUE_OPT_X509ECCKEYFILE,
+ { /* entry idx, value */ 30, VALUE_OPT_X509ECCKEYFILE,
+ /* equiv idx, value */ 30, VALUE_OPT_X509ECCKEYFILE,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ X509ECCKEYFILE_FLAGS, 0,
@@ -1113,8 +1140,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ X509ECCKEYFILE_DESC, X509ECCKEYFILE_NAME, X509ECCKEYFILE_name,
/* disablement strs */ 0, 0 },
- { /* entry idx, value */ 30, VALUE_OPT_X509ECCCERTFILE,
- /* equiv idx, value */ 30, VALUE_OPT_X509ECCCERTFILE,
+ { /* entry idx, value */ 31, VALUE_OPT_X509ECCCERTFILE,
+ /* equiv idx, value */ 31, VALUE_OPT_X509ECCCERTFILE,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ X509ECCCERTFILE_FLAGS, 0,
@@ -1125,8 +1152,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ X509ECCCERTFILE_DESC, X509ECCCERTFILE_NAME, X509ECCCERTFILE_name,
/* disablement strs */ 0, 0 },
- { /* entry idx, value */ 31, VALUE_OPT_SRPPASSWD,
- /* equiv idx, value */ 31, VALUE_OPT_SRPPASSWD,
+ { /* entry idx, value */ 32, VALUE_OPT_SRPPASSWD,
+ /* equiv idx, value */ 32, VALUE_OPT_SRPPASSWD,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ SRPPASSWD_FLAGS, 0,
@@ -1137,8 +1164,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ SRPPASSWD_DESC, SRPPASSWD_NAME, SRPPASSWD_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 32, VALUE_OPT_SRPPASSWDCONF,
- /* equiv idx, value */ 32, VALUE_OPT_SRPPASSWDCONF,
+ { /* entry idx, value */ 33, VALUE_OPT_SRPPASSWDCONF,
+ /* equiv idx, value */ 33, VALUE_OPT_SRPPASSWDCONF,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ SRPPASSWDCONF_FLAGS, 0,
@@ -1149,8 +1176,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ SRPPASSWDCONF_DESC, SRPPASSWDCONF_NAME, SRPPASSWDCONF_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 33, VALUE_OPT_PSKPASSWD,
- /* equiv idx, value */ 33, VALUE_OPT_PSKPASSWD,
+ { /* entry idx, value */ 34, VALUE_OPT_PSKPASSWD,
+ /* equiv idx, value */ 34, VALUE_OPT_PSKPASSWD,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ PSKPASSWD_FLAGS, 0,
@@ -1161,8 +1188,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ PSKPASSWD_DESC, PSKPASSWD_NAME, PSKPASSWD_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 34, VALUE_OPT_PSKHINT,
- /* equiv idx, value */ 34, VALUE_OPT_PSKHINT,
+ { /* entry idx, value */ 35, VALUE_OPT_PSKHINT,
+ /* equiv idx, value */ 35, VALUE_OPT_PSKHINT,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ PSKHINT_FLAGS, 0,
@@ -1173,8 +1200,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ PSKHINT_DESC, PSKHINT_NAME, PSKHINT_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 35, VALUE_OPT_OCSP_RESPONSE,
- /* equiv idx, value */ 35, VALUE_OPT_OCSP_RESPONSE,
+ { /* entry idx, value */ 36, VALUE_OPT_OCSP_RESPONSE,
+ /* equiv idx, value */ 36, VALUE_OPT_OCSP_RESPONSE,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, NOLIMIT, 0,
/* opt state flags */ OCSP_RESPONSE_FLAGS, 0,
@@ -1185,8 +1212,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ OCSP_RESPONSE_DESC, OCSP_RESPONSE_NAME, OCSP_RESPONSE_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 36, VALUE_OPT_IGNORE_OCSP_RESPONSE_ERRORS,
- /* equiv idx, value */ 36, VALUE_OPT_IGNORE_OCSP_RESPONSE_ERRORS,
+ { /* entry idx, value */ 37, VALUE_OPT_IGNORE_OCSP_RESPONSE_ERRORS,
+ /* equiv idx, value */ 37, VALUE_OPT_IGNORE_OCSP_RESPONSE_ERRORS,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ IGNORE_OCSP_RESPONSE_ERRORS_FLAGS, 0,
@@ -1197,8 +1224,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ IGNORE_OCSP_RESPONSE_ERRORS_DESC, IGNORE_OCSP_RESPONSE_ERRORS_NAME, IGNORE_OCSP_RESPONSE_ERRORS_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 37, VALUE_OPT_PORT,
- /* equiv idx, value */ 37, VALUE_OPT_PORT,
+ { /* entry idx, value */ 38, VALUE_OPT_PORT,
+ /* equiv idx, value */ 38, VALUE_OPT_PORT,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ PORT_FLAGS, 0,
@@ -1209,8 +1236,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ PORT_DESC, PORT_NAME, PORT_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 38, VALUE_OPT_LIST,
- /* equiv idx, value */ 38, VALUE_OPT_LIST,
+ { /* entry idx, value */ 39, VALUE_OPT_LIST,
+ /* equiv idx, value */ 39, VALUE_OPT_LIST,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ LIST_FLAGS, 0,
@@ -1221,8 +1248,8 @@ static tOptDesc optDesc[OPTION_CT] = {
/* desc, NAME, name */ LIST_DESC, LIST_NAME, LIST_name,
/* disablement strs */ NULL, NULL },
- { /* entry idx, value */ 39, VALUE_OPT_PROVIDER,
- /* equiv idx, value */ 39, VALUE_OPT_PROVIDER,
+ { /* entry idx, value */ 40, VALUE_OPT_PROVIDER,
+ /* equiv idx, value */ 40, VALUE_OPT_PROVIDER,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ PROVIDER_FLAGS, 0,
@@ -1275,21 +1302,21 @@ static tOptDesc optDesc[OPTION_CT] = {
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/** Reference to the upper cased version of gnutls-serv. */
-#define zPROGNAME (gnutls_serv_opt_strs+3163)
+#define zPROGNAME (gnutls_serv_opt_strs+3201)
/** Reference to the title line for gnutls-serv usage. */
-#define zUsageTitle (gnutls_serv_opt_strs+3175)
+#define zUsageTitle (gnutls_serv_opt_strs+3213)
/** There is no gnutls-serv configuration file. */
#define zRcName NULL
/** There are no directories to search for gnutls-serv config files. */
#define apzHomeList NULL
/** The gnutls-serv program bug email address. */
-#define zBugsAddr (gnutls_serv_opt_strs+3261)
+#define zBugsAddr (gnutls_serv_opt_strs+3299)
/** Clarification/explanation of what gnutls-serv does. */
-#define zExplain (gnutls_serv_opt_strs+3277)
+#define zExplain (gnutls_serv_opt_strs+3315)
/** Extra detail explaining what gnutls-serv does. */
-#define zDetail (gnutls_serv_opt_strs+3279)
+#define zDetail (gnutls_serv_opt_strs+3317)
/** The full version string for gnutls-serv. */
-#define zFullVersion (gnutls_serv_opt_strs+3337)
+#define zFullVersion (gnutls_serv_opt_strs+3375)
/* extracted from optcode.tlib near line 364 */
#if defined(ENABLE_NLS)
@@ -1301,7 +1328,7 @@ static tOptDesc optDesc[OPTION_CT] = {
#endif /* ENABLE_NLS */
#define gnutls_serv_full_usage (NULL)
-#define gnutls_serv_short_usage (gnutls_serv_opt_strs+3355)
+#define gnutls_serv_short_usage (gnutls_serv_opt_strs+3393)
#endif /* not defined __doxygen__ */
@@ -1692,7 +1719,7 @@ tOptions gnutls_servOptions = {
NO_EQUIVALENT, /* '-#' option index */
NO_EQUIVALENT /* index of default opt */
},
- 43 /* full option count */, 40 /* user option count */,
+ 44 /* full option count */, 41 /* user option count */,
gnutls_serv_full_usage, gnutls_serv_short_usage,
NULL, NULL,
PKGDATADIR, gnutls_serv_packager_info
@@ -1864,6 +1891,9 @@ with this program. If not, see <http://www.gnu.org/licenses/>.\n"));
puts(_("Don't accept session tickets"));
/* referenced via gnutls_servOptions.pOptDesc->pzText */
+ puts(_("Accept early data"));
+
+ /* referenced via gnutls_servOptions.pOptDesc->pzText */
puts(_("Don't require cookie on DTLS sessions"));
/* referenced via gnutls_servOptions.pOptDesc->pzText */
@@ -2011,7 +2041,7 @@ gnutls-serv --help for usage instructions.\n"));
puts(_("\tThis is less than the minimum library version: "));
#line 121 "../version.c"
puts(_("Automated Options version %s\n"
- "\tCopyright (C) 1999-2014 by Bruce Korb - all rights reserved\n"));
+ "\tCopyright (C) 1999-2017 by Bruce Korb - all rights reserved\n"));
#line 87 "../makeshell.c"
puts(_("(AutoOpts bug): %s.\n"));
#line 90 "../reset.c"
diff --git a/src/serv-args.def b/src/serv-args.def
index e7bb574d2e..6c17998da0 100644
--- a/src/serv-args.def
+++ b/src/serv-args.def
@@ -43,6 +43,12 @@ flag = {
};
flag = {
+ name = earlydata;
+ descrip = "Accept early data";
+ doc = "";
+};
+
+flag = {
name = nocookie;
descrip = "Don't require cookie on DTLS sessions";
doc = "";
diff --git a/src/serv-args.h.bak b/src/serv-args.h.bak
index a2244c351c..2a8d7d0c89 100644
--- a/src/serv-args.h.bak
+++ b/src/serv-args.h.bak
@@ -72,46 +72,47 @@ typedef enum {
INDEX_OPT_ALPN = 3,
INDEX_OPT_ALPN_FATAL = 4,
INDEX_OPT_NOTICKET = 5,
- INDEX_OPT_NOCOOKIE = 6,
- INDEX_OPT_GENERATE = 7,
- INDEX_OPT_QUIET = 8,
- INDEX_OPT_NODB = 9,
- INDEX_OPT_HTTP = 10,
- INDEX_OPT_ECHO = 11,
- INDEX_OPT_UDP = 12,
- INDEX_OPT_MTU = 13,
- INDEX_OPT_SRTP_PROFILES = 14,
- INDEX_OPT_DISABLE_CLIENT_CERT = 15,
- INDEX_OPT_REQUIRE_CLIENT_CERT = 16,
- INDEX_OPT_VERIFY_CLIENT_CERT = 17,
- INDEX_OPT_HEARTBEAT = 18,
- INDEX_OPT_X509FMTDER = 19,
- INDEX_OPT_PRIORITY = 20,
- INDEX_OPT_DHPARAMS = 21,
- INDEX_OPT_X509CAFILE = 22,
- INDEX_OPT_X509CRLFILE = 23,
- INDEX_OPT_PGPKEYFILE = 24,
- INDEX_OPT_X509KEYFILE = 25,
- INDEX_OPT_X509CERTFILE = 26,
- INDEX_OPT_X509DSAKEYFILE = 27,
- INDEX_OPT_X509DSACERTFILE = 28,
- INDEX_OPT_X509ECCKEYFILE = 29,
- INDEX_OPT_X509ECCCERTFILE = 30,
- INDEX_OPT_SRPPASSWD = 31,
- INDEX_OPT_SRPPASSWDCONF = 32,
- INDEX_OPT_PSKPASSWD = 33,
- INDEX_OPT_PSKHINT = 34,
- INDEX_OPT_OCSP_RESPONSE = 35,
- INDEX_OPT_IGNORE_OCSP_RESPONSE_ERRORS = 36,
- INDEX_OPT_PORT = 37,
- INDEX_OPT_LIST = 38,
- INDEX_OPT_PROVIDER = 39,
- INDEX_OPT_VERSION = 40,
- INDEX_OPT_HELP = 41,
- INDEX_OPT_MORE_HELP = 42
+ INDEX_OPT_EARLYDATA = 6,
+ INDEX_OPT_NOCOOKIE = 7,
+ INDEX_OPT_GENERATE = 8,
+ INDEX_OPT_QUIET = 9,
+ INDEX_OPT_NODB = 10,
+ INDEX_OPT_HTTP = 11,
+ INDEX_OPT_ECHO = 12,
+ INDEX_OPT_UDP = 13,
+ INDEX_OPT_MTU = 14,
+ INDEX_OPT_SRTP_PROFILES = 15,
+ INDEX_OPT_DISABLE_CLIENT_CERT = 16,
+ INDEX_OPT_REQUIRE_CLIENT_CERT = 17,
+ INDEX_OPT_VERIFY_CLIENT_CERT = 18,
+ INDEX_OPT_HEARTBEAT = 19,
+ INDEX_OPT_X509FMTDER = 20,
+ INDEX_OPT_PRIORITY = 21,
+ INDEX_OPT_DHPARAMS = 22,
+ INDEX_OPT_X509CAFILE = 23,
+ INDEX_OPT_X509CRLFILE = 24,
+ INDEX_OPT_PGPKEYFILE = 25,
+ INDEX_OPT_X509KEYFILE = 26,
+ INDEX_OPT_X509CERTFILE = 27,
+ INDEX_OPT_X509DSAKEYFILE = 28,
+ INDEX_OPT_X509DSACERTFILE = 29,
+ INDEX_OPT_X509ECCKEYFILE = 30,
+ INDEX_OPT_X509ECCCERTFILE = 31,
+ INDEX_OPT_SRPPASSWD = 32,
+ INDEX_OPT_SRPPASSWDCONF = 33,
+ INDEX_OPT_PSKPASSWD = 34,
+ INDEX_OPT_PSKHINT = 35,
+ INDEX_OPT_OCSP_RESPONSE = 36,
+ INDEX_OPT_IGNORE_OCSP_RESPONSE_ERRORS = 37,
+ INDEX_OPT_PORT = 38,
+ INDEX_OPT_LIST = 39,
+ INDEX_OPT_PROVIDER = 40,
+ INDEX_OPT_VERSION = 41,
+ INDEX_OPT_HELP = 42,
+ INDEX_OPT_MORE_HELP = 43
} teOptIndex;
/** count of all options for gnutls-serv */
-#define OPTION_CT 43
+#define OPTION_CT 44
/** gnutls-serv version */
#define GNUTLS_SERV_VERSION "3.6.4"
/** Full gnutls-serv version text */
@@ -174,44 +175,45 @@ typedef enum {
#define VALUE_OPT_ALPN 0x1003
#define VALUE_OPT_ALPN_FATAL 0x1004
#define VALUE_OPT_NOTICKET 0x1005
-#define VALUE_OPT_NOCOOKIE 0x1006
+#define VALUE_OPT_EARLYDATA 0x1006
+#define VALUE_OPT_NOCOOKIE 0x1007
#define VALUE_OPT_GENERATE 'g'
#define VALUE_OPT_QUIET 'q'
-#define VALUE_OPT_NODB 0x1007
-#define VALUE_OPT_HTTP 0x1008
-#define VALUE_OPT_ECHO 0x1009
+#define VALUE_OPT_NODB 0x1008
+#define VALUE_OPT_HTTP 0x1009
+#define VALUE_OPT_ECHO 0x100A
#define VALUE_OPT_UDP 'u'
-#define VALUE_OPT_MTU 0x100A
+#define VALUE_OPT_MTU 0x100B
#define OPT_VALUE_MTU (DESC(MTU).optArg.argInt)
-#define VALUE_OPT_SRTP_PROFILES 0x100B
+#define VALUE_OPT_SRTP_PROFILES 0x100C
#define VALUE_OPT_DISABLE_CLIENT_CERT 'a'
#define VALUE_OPT_REQUIRE_CLIENT_CERT 'r'
-#define VALUE_OPT_VERIFY_CLIENT_CERT 0x100C
+#define VALUE_OPT_VERIFY_CLIENT_CERT 0x100D
#define VALUE_OPT_HEARTBEAT 'b'
-#define VALUE_OPT_X509FMTDER 0x100D
-#define VALUE_OPT_PRIORITY 0x100E
-#define VALUE_OPT_DHPARAMS 0x100F
-#define VALUE_OPT_X509CAFILE 0x1010
-#define VALUE_OPT_X509CRLFILE 0x1011
-#define VALUE_OPT_PGPKEYFILE 0x1012
-#define VALUE_OPT_X509KEYFILE 0x1013
-#define VALUE_OPT_X509CERTFILE 0x1014
-#define VALUE_OPT_X509DSAKEYFILE 0x1015
-#define VALUE_OPT_X509DSACERTFILE 0x1016
-#define VALUE_OPT_X509ECCKEYFILE 0x1017
-#define VALUE_OPT_X509ECCCERTFILE 0x1018
-#define VALUE_OPT_SRPPASSWD 0x1019
-#define VALUE_OPT_SRPPASSWDCONF 0x101A
-#define VALUE_OPT_PSKPASSWD 0x101B
-#define VALUE_OPT_PSKHINT 0x101C
-#define VALUE_OPT_OCSP_RESPONSE 0x101D
-#define VALUE_OPT_IGNORE_OCSP_RESPONSE_ERRORS 0x101E
+#define VALUE_OPT_X509FMTDER 0x100E
+#define VALUE_OPT_PRIORITY 0x100F
+#define VALUE_OPT_DHPARAMS 0x1010
+#define VALUE_OPT_X509CAFILE 0x1011
+#define VALUE_OPT_X509CRLFILE 0x1012
+#define VALUE_OPT_PGPKEYFILE 0x1013
+#define VALUE_OPT_X509KEYFILE 0x1014
+#define VALUE_OPT_X509CERTFILE 0x1015
+#define VALUE_OPT_X509DSAKEYFILE 0x1016
+#define VALUE_OPT_X509DSACERTFILE 0x1017
+#define VALUE_OPT_X509ECCKEYFILE 0x1018
+#define VALUE_OPT_X509ECCCERTFILE 0x1019
+#define VALUE_OPT_SRPPASSWD 0x101A
+#define VALUE_OPT_SRPPASSWDCONF 0x101B
+#define VALUE_OPT_PSKPASSWD 0x101C
+#define VALUE_OPT_PSKHINT 0x101D
+#define VALUE_OPT_OCSP_RESPONSE 0x101E
+#define VALUE_OPT_IGNORE_OCSP_RESPONSE_ERRORS 0x101F
#define VALUE_OPT_PORT 'p'
#define OPT_VALUE_PORT (DESC(PORT).optArg.argInt)
#define VALUE_OPT_LIST 'l'
-#define VALUE_OPT_PROVIDER 0x101F
+#define VALUE_OPT_PROVIDER 0x1020
/** option flag (value) for help-value option */
#define VALUE_OPT_HELP 'h'
/** option flag (value) for more-help-value option */
diff --git a/src/serv.c b/src/serv.c
index af58edd9cb..75871270a5 100644
--- a/src/serv.c
+++ b/src/serv.c
@@ -61,6 +61,7 @@ static int debug = 0;
unsigned int verbose = 1;
static int nodb;
static int noticket;
+static int earlydata;
int require_cert;
int disable_client_cert;
@@ -86,6 +87,7 @@ const char **alpn_protos = NULL;
unsigned alpn_protos_size = 0;
gnutls_datum_t session_ticket_key;
+gnutls_anti_replay_t anti_replay;
static void tcp_server(const char *name, int port);
/* end of globals */
@@ -116,7 +118,7 @@ gnutls_psk_server_credentials_t psk_cred = NULL;
gnutls_anon_server_credentials_t dh_cred = NULL;
gnutls_certificate_credentials_t cert_cred = NULL;
-const int ssl_session_cache = 128;
+const int ssl_session_cache = 2048;
static void wrap_db_init(void);
static void wrap_db_deinit(void);
@@ -124,6 +126,8 @@ static int wrap_db_store(void *dbf, gnutls_datum_t key,
gnutls_datum_t data);
static gnutls_datum_t wrap_db_fetch(void *dbf, gnutls_datum_t key);
static int wrap_db_delete(void *dbf, gnutls_datum_t key);
+static int wrap_db_add(void *dbf, gnutls_datum_t key,
+ gnutls_datum_t data);
static void cmd_parser(int argc, char **argv);
@@ -140,6 +144,7 @@ LIST_TYPE_DECLARE(listener_item, char *http_request; char *http_response;
int handshake_ok;
int close_ok;
time_t start;
+ int earlydata_eof;
);
static const char *safe_strerror(int value)
@@ -375,11 +380,15 @@ gnutls_session_t initialize_session(int dtls)
const char *err;
gnutls_datum_t alpn[MAX_ALPN_PROTOCOLS];
unsigned alpn_size;
+ unsigned flags = GNUTLS_SERVER | GNUTLS_POST_HANDSHAKE_AUTH;
if (dtls)
- gnutls_init(&session, GNUTLS_SERVER | GNUTLS_DATAGRAM | GNUTLS_POST_HANDSHAKE_AUTH);
- else
- gnutls_init(&session, GNUTLS_SERVER | GNUTLS_POST_HANDSHAKE_AUTH);
+ flags |= GNUTLS_DATAGRAM;
+
+ if (earlydata)
+ flags |= GNUTLS_ENABLE_EARLY_DATA;
+
+ gnutls_init(&session, flags);
/* allow the use of private ciphersuites.
*/
@@ -392,6 +401,7 @@ gnutls_session_t initialize_session(int dtls)
gnutls_db_set_retrieve_function(session, wrap_db_fetch);
gnutls_db_set_remove_function(session, wrap_db_delete);
gnutls_db_set_store_function(session, wrap_db_store);
+ gnutls_db_set_add_function(session, wrap_db_add);
gnutls_db_set_ptr(session, NULL);
}
@@ -399,6 +409,9 @@ gnutls_session_t initialize_session(int dtls)
gnutls_session_ticket_enable_server(session,
&session_ticket_key);
+ if (earlydata)
+ gnutls_anti_replay_enable(session, anti_replay);
+
if (sni_hostname != NULL)
gnutls_handshake_set_post_client_hello_function(session,
&post_client_hello);
@@ -1251,6 +1264,14 @@ int main(int argc, char **argv)
if (noticket == 0)
gnutls_session_ticket_key_generate(&session_ticket_key);
+ if (earlydata) {
+ ret = gnutls_anti_replay_init(&anti_replay);
+ if (ret < 0) {
+ fprintf(stderr, "Error while initializing anti-replay: %s\n", gnutls_strerror(ret));
+ exit(1);
+ }
+ }
+
if (HAVE_OPT(MTU))
mtu = OPT_VALUE_MTU;
else
@@ -1463,11 +1484,27 @@ static void tcp_server(const char *name, int port)
}
if (j->handshake_ok == 1) {
- r = gnutls_record_recv(j->
- tls_session,
- buf,
- MIN(sizeof(buf),
- SMALL_READ_TEST));
+ int earlydata_read = 0;
+ if (earlydata && !j->earlydata_eof) {
+ r = gnutls_record_recv_early_data(j->
+ tls_session,
+ buf,
+ MIN(sizeof(buf),
+ SMALL_READ_TEST));
+ if (r == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
+ j->earlydata_eof = 1;
+ }
+ if (r == 0) {
+ earlydata_read = 1;
+ }
+ }
+ if (!earlydata_read) {
+ r = gnutls_record_recv(j->
+ tls_session,
+ buf,
+ MIN(sizeof(buf),
+ SMALL_READ_TEST));
+ }
if (r == GNUTLS_E_INTERRUPTED || r == GNUTLS_E_AGAIN) {
/* do nothing */
} else if (r <= 0) {
@@ -1631,6 +1668,9 @@ static void tcp_server(const char *name, int port)
if (noticket == 0)
gnutls_free(session_ticket_key.data);
+ if (earlydata)
+ gnutls_anti_replay_deinit(anti_replay);
+
if (nodb == 0)
wrap_db_deinit();
gnutls_global_deinit();
@@ -1659,6 +1699,7 @@ static void cmd_parser(int argc, char **argv)
nodb = HAVE_OPT(NODB);
noticket = HAVE_OPT(NOTICKET);
+ earlydata = HAVE_OPT(EARLYDATA);
if (HAVE_OPT(ECHO))
http = 0;
@@ -1723,50 +1764,86 @@ static void cmd_parser(int argc, char **argv)
/* session resuming support */
-#define SESSION_ID_SIZE 32
+#define SESSION_ID_SIZE 128
#define SESSION_DATA_SIZE (16*1024)
typedef struct {
- char session_id[SESSION_ID_SIZE];
+ unsigned char session_id[SESSION_ID_SIZE];
unsigned int session_id_size;
- char session_data[SESSION_DATA_SIZE];
- unsigned int session_data_size;
+ gnutls_datum_t session_data;
} CACHE;
static CACHE *cache_db;
-int cache_db_ptr = 0;
+static int cache_db_ptr;
+static int cache_db_alloc;
static void wrap_db_init(void)
{
- /* allocate cache_db */
- cache_db = calloc(1, ssl_session_cache * sizeof(CACHE));
}
static void wrap_db_deinit(void)
{
+ int i;
+
+ for (i = 0; i < cache_db_ptr; i++)
+ free(cache_db[i].session_data.data);
+ free(cache_db);
}
static int
wrap_db_store(void *dbf, gnutls_datum_t key, gnutls_datum_t data)
{
-
- if (cache_db == NULL)
- return -1;
+ int i;
+ time_t now = time(0);
if (key.size > SESSION_ID_SIZE)
- return -1;
+ return GNUTLS_E_DB_ERROR;
if (data.size > SESSION_DATA_SIZE)
- return -1;
+ return GNUTLS_E_DB_ERROR;
- memcpy(cache_db[cache_db_ptr].session_id, key.data, key.size);
- cache_db[cache_db_ptr].session_id_size = key.size;
+ if (cache_db_ptr < cache_db_alloc)
+ i = cache_db_ptr++;
+ else {
+ /* find empty or expired slot to store the new entry */
+ for (i = 0; i < cache_db_ptr; i++)
+ if (cache_db[i].session_id_size == 0 ||
+ !(now <
+ gnutls_db_check_entry_expire_time(&cache_db[i].
+ session_data)))
+ break;
+
+ if (i == cache_db_ptr) {
+ /* try to allocate additional slots */
+ if (cache_db_ptr == ssl_session_cache) {
+ fprintf(stderr,
+ "Error: too many sessions\n");
+ return GNUTLS_E_DB_ERROR;
+ }
+ cache_db_alloc = cache_db_alloc * 2 + 1;
+ cache_db = realloc(cache_db,
+ cache_db_alloc * sizeof(CACHE));
+ if (!cache_db)
+ return GNUTLS_E_MEMORY_ERROR;
+ memset(cache_db + cache_db_ptr, 0,
+ (cache_db_alloc - cache_db_ptr) * sizeof(CACHE));
+ cache_db_ptr++;
+ }
+ }
- memcpy(cache_db[cache_db_ptr].session_data, data.data, data.size);
- cache_db[cache_db_ptr].session_data_size = data.size;
+ memcpy(cache_db[i].session_id, key.data, key.size);
+ cache_db[i].session_id_size = key.size;
- cache_db_ptr++;
- cache_db_ptr %= ssl_session_cache;
+ /* resize the data slot if needed */
+ if (cache_db[i].session_data.size < data.size) {
+ cache_db[i].session_data.data =
+ realloc(cache_db[i].session_data.data,
+ data.size);
+ if (!cache_db[i].session_data.data)
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+ memcpy(cache_db[i].session_data.data, data.data, data.size);
+ cache_db[i].session_data.size = data.size;
return 0;
}
@@ -1774,22 +1851,22 @@ wrap_db_store(void *dbf, gnutls_datum_t key, gnutls_datum_t data)
static gnutls_datum_t wrap_db_fetch(void *dbf, gnutls_datum_t key)
{
gnutls_datum_t res = { NULL, 0 };
+ time_t now = time(0);
int i;
- if (cache_db == NULL)
- return res;
-
- for (i = 0; i < ssl_session_cache; i++) {
+ for (i = 0; i < cache_db_ptr; i++) {
if (key.size == cache_db[i].session_id_size &&
memcmp(key.data, cache_db[i].session_id,
- key.size) == 0) {
- res.size = cache_db[i].session_data_size;
+ key.size) == 0 &&
+ now < gnutls_db_check_entry_expire_time(&cache_db[i].
+ session_data)) {
+ res.size = cache_db[i].session_data.size;
- res.data = gnutls_malloc(res.size);
+ res.data = malloc(res.size);
if (res.data == NULL)
return res;
- memcpy(res.data, cache_db[i].session_data,
+ memcpy(res.data, cache_db[i].session_data.data,
res.size);
return res;
@@ -1802,20 +1879,37 @@ static int wrap_db_delete(void *dbf, gnutls_datum_t key)
{
int i;
- if (cache_db == NULL)
- return -1;
-
- for (i = 0; i < ssl_session_cache; i++) {
- if (key.size == (unsigned int) cache_db[i].session_id_size
- && memcmp(key.data, cache_db[i].session_id,
- key.size) == 0) {
+ for (i = 0; i < cache_db_ptr; i++) {
+ if (key.size == cache_db[i].session_id_size &&
+ memcmp(key.data, cache_db[i].session_id,
+ key.size) == 0) {
cache_db[i].session_id_size = 0;
- cache_db[i].session_data_size = 0;
+ free(cache_db[i].session_data.data);
+ cache_db[i].session_data.data = NULL;
+ cache_db[i].session_data.size = 0;
return 0;
}
}
- return -1;
+ return GNUTLS_E_DB_ERROR;
+}
+
+static int
+wrap_db_add(void *dbf, gnutls_datum_t key, gnutls_datum_t data)
+{
+ time_t now = time(0);
+ int i;
+
+ for (i = 0; i < cache_db_ptr; i++) {
+ if (key.size == cache_db[i].session_id_size &&
+ memcmp(key.data, cache_db[i].session_id,
+ key.size) == 0 &&
+ now < gnutls_db_check_entry_expire_time(&cache_db[i].
+ session_data))
+ return GNUTLS_E_DB_ENTRY_EXISTS;
+ }
+
+ return wrap_db_store(dbf, key, data);
}
diff --git a/src/socket.c b/src/socket.c
index f488c531e5..be60f9458c 100644
--- a/src/socket.c
+++ b/src/socket.c
@@ -456,7 +456,7 @@ inline static int wrap_pull_timeout_func(gnutls_transport_ptr_t ptr,
void
socket_open2(socket_st * hd, const char *hostname, const char *service,
- const char *app_proto, int flags, const char *msg, gnutls_datum_t *rdata,
+ const char *app_proto, int flags, const char *msg, gnutls_datum_t *rdata, gnutls_datum_t *edata,
FILE *server_trace, FILE *client_trace)
{
struct addrinfo hints, *res, *ptr;
@@ -479,6 +479,11 @@ socket_open2(socket_st * hd, const char *hostname, const char *service,
hd->rdata.size = rdata->size;
}
+ if (edata) {
+ hd->edata.data = edata->data;
+ hd->edata.size = edata->size;
+ }
+
ret = gnutls_idna_map(hostname, strlen(hostname), &idna, 0);
if (ret < 0) {
fprintf(stderr, "Cannot convert %s to IDNA: %s\n", hostname, gnutls_strerror(ret));
@@ -564,6 +569,13 @@ socket_open2(socket_st * hd, const char *hostname, const char *service,
}
if (hd->session) {
+ if (hd->edata.data) {
+ ret = gnutls_record_send_early_data(hd->session, hd->edata.data, hd->edata.size);
+ if (ret < 0) {
+ fprintf(stderr, "error sending early data\n");
+ exit(1);
+ }
+ }
if (hd->rdata.data) {
gnutls_session_set_data(hd->session, hd->rdata.data, hd->rdata.size);
}
@@ -621,6 +633,8 @@ socket_open2(socket_st * hd, const char *hostname, const char *service,
hd->addr_info = res;
gnutls_free(hd->rdata.data);
hd->rdata.data = NULL;
+ gnutls_free(hd->edata.data);
+ hd->edata.data = NULL;
gnutls_free(idna.data);
return;
}
diff --git a/src/socket.h b/src/socket.h
index b66e5c512d..ce64f0bb66 100644
--- a/src/socket.h
+++ b/src/socket.h
@@ -31,6 +31,8 @@ typedef struct {
/* resumption data */
gnutls_datum_t rdata;
+ /* early data */
+ gnutls_datum_t edata;
} socket_st;
/* calling program must provide that */
@@ -47,11 +49,14 @@ ssize_t socket_send_range(const socket_st * socket, const void *buffer,
int buffer_size, gnutls_range_st * range);
void
socket_open2(socket_st * hd, const char *hostname, const char *service,
- const char *app_proto, int flags, const char *msg, gnutls_datum_t *rdata,
+ const char *app_proto, int flags, const char *msg, gnutls_datum_t *rdata, gnutls_datum_t *edata,
FILE *server_trace, FILE *client_trace);
#define socket_open(hd, host, service, app_proto, flags, msg, rdata) \
- socket_open2(hd, host, service, app_proto, flags, msg, rdata, NULL, NULL)
+ socket_open2(hd, host, service, app_proto, flags, msg, rdata, NULL, NULL, NULL)
+
+#define socket_open3(hd, host, service, app_proto, flags, msg, rdata, edata) \
+ socket_open2(hd, host, service, app_proto, flags, msg, rdata, edata, NULL, NULL)
void socket_bye(socket_st * socket, unsigned polite);
diff --git a/symbols.last b/symbols.last
index f55663209f..878c5c30b7 100644
--- a/symbols.last
+++ b/symbols.last
@@ -3,6 +3,7 @@ GNUTLS_3_6_0@GNUTLS_3_6_0
GNUTLS_3_6_2@GNUTLS_3_6_2
GNUTLS_3_6_3@GNUTLS_3_6_3
GNUTLS_3_6_4@GNUTLS_3_6_4
+GNUTLS_3_6_5@GNUTLS_3_6_5
_gnutls_global_init_skip@GNUTLS_3_4
gnutls_aead_cipher_decrypt@GNUTLS_3_4
gnutls_aead_cipher_deinit@GNUTLS_3_4
@@ -24,6 +25,10 @@ gnutls_anon_set_params_function@GNUTLS_3_4
gnutls_anon_set_server_dh_params@GNUTLS_3_4
gnutls_anon_set_server_known_dh_params@GNUTLS_3_4
gnutls_anon_set_server_params_function@GNUTLS_3_4
+gnutls_anti_replay_deinit@GNUTLS_3_6_5
+gnutls_anti_replay_enable@GNUTLS_3_6_5
+gnutls_anti_replay_init@GNUTLS_3_6_5
+gnutls_anti_replay_set_window@GNUTLS_3_6_5
gnutls_auth_client_get_type@GNUTLS_3_4
gnutls_auth_get_type@GNUTLS_3_4
gnutls_auth_server_get_type@GNUTLS_3_4
@@ -136,10 +141,12 @@ gnutls_crypto_register_cipher@GNUTLS_3_4
gnutls_crypto_register_digest@GNUTLS_3_4
gnutls_crypto_register_mac@GNUTLS_3_4
gnutls_db_check_entry@GNUTLS_3_4
+gnutls_db_check_entry_expire_time@GNUTLS_3_6_5
gnutls_db_check_entry_time@GNUTLS_3_4
gnutls_db_get_default_cache_expiration@GNUTLS_3_4
gnutls_db_get_ptr@GNUTLS_3_4
gnutls_db_remove_session@GNUTLS_3_4
+gnutls_db_set_add_function@GNUTLS_3_6_5
gnutls_db_set_cache_expiration@GNUTLS_3_4
gnutls_db_set_ptr@GNUTLS_3_4
gnutls_db_set_remove_function@GNUTLS_3_4
@@ -677,14 +684,17 @@ gnutls_record_disable_padding@GNUTLS_3_4
gnutls_record_discard_queued@GNUTLS_3_4
gnutls_record_get_direction@GNUTLS_3_4
gnutls_record_get_discarded@GNUTLS_3_4
+gnutls_record_get_max_early_data_size@GNUTLS_3_6_5
gnutls_record_get_max_size@GNUTLS_3_4
gnutls_record_get_state@GNUTLS_3_4
gnutls_record_overhead_size@GNUTLS_3_4
gnutls_record_recv@GNUTLS_3_4
+gnutls_record_recv_early_data@GNUTLS_3_6_5
gnutls_record_recv_packet@GNUTLS_3_4
gnutls_record_recv_seq@GNUTLS_3_4
gnutls_record_send2@GNUTLS_3_6_3
gnutls_record_send@GNUTLS_3_4
+gnutls_record_send_early_data@GNUTLS_3_6_5
gnutls_record_send_range@GNUTLS_3_4
gnutls_record_set_max_early_data_size@GNUTLS_3_6_4
gnutls_record_set_max_size@GNUTLS_3_4
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 021da722ae..1ccba11028 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -109,7 +109,8 @@ ctests = tls13/supported_versions tls13/tls12-no-tls13-exts \
tls13/cookie tls13/key_share tls13/prf tls13/post-handshake-with-cert-ticket \
tls12-rollback-detection tls11-rollback-detection \
tls12-check-rollback-val tls11-check-rollback-val tls13/hello_random_value \
- tls13/post-handshake-with-psk tls13/post-handshake-with-cert-auto
+ tls13/post-handshake-with-psk tls13/post-handshake-with-cert-auto \
+ tls13/anti_replay
ctests += tls13/hello_retry_request
@@ -397,7 +398,7 @@ endif
if HAVE_FORK
ctests += x509self x509dn anonself pskself dhepskself \
setcredcrash tls12-resume-x509 tls12-resume-psk tls12-resume-anon \
- tls13-resume-x509 tls13-resume-psk
+ tls13-resume-x509 tls13-resume-psk tls13-early-data
endif
gc_CPPFLAGS = $(AM_CPPFLAGS) \
@@ -425,6 +426,16 @@ name_constraints_merge_CPPFLAGS = $(AM_CPPFLAGS) \
-I$(top_builddir)/gl \
$(NETTLE_CFLAGS)
+murmur3_CPPFLAGS = $(AM_CPPFLAGS) \
+ -I$(top_srcdir)/gl \
+ -I$(top_builddir)/gl \
+ $(NETTLE_CFLAGS)
+
+tls13_anti_replay_CPPFLAGS = $(AM_CPPFLAGS) \
+ -I$(top_srcdir)/gl \
+ -I$(top_builddir)/gl \
+ $(NETTLE_CFLAGS)
+
dist_check_SCRIPTS = rfc2253-escape-test rsa-md5-collision/rsa-md5-collision.sh systemkey.sh
if !WINDOWS
diff --git a/tests/resume.c b/tests/resume.c
index 0e582f603d..5e545cc658 100644
--- a/tests/resume.c
+++ b/tests/resume.c
@@ -995,7 +995,7 @@ static void wrap_db_deinit(void)
static int
wrap_db_store(void *dbf, gnutls_datum_t key, gnutls_datum_t data)
{
- time_t t, now = time(0);
+ time_t t, e, now = time(0);
#ifdef DEBUG_CACHE
if (debug) {
@@ -1021,6 +1021,13 @@ wrap_db_store(void *dbf, gnutls_datum_t key, gnutls_datum_t data)
exit(1);
}
+ /* check the correctness of gnutls_db_check_entry_expire_time() */
+ e = gnutls_db_check_entry_expire_time(&data);
+ if (e < t) {
+ fail("Time returned by gnutls_db_check_entry_expire_time is bogus\n");
+ exit(1);
+ }
+
if (cache_db == NULL)
return -1;
diff --git a/tests/suite/testcompat-tls13-openssl.sh b/tests/suite/testcompat-tls13-openssl.sh
index 8f385f515e..c573182870 100755
--- a/tests/suite/testcompat-tls13-openssl.sh
+++ b/tests/suite/testcompat-tls13-openssl.sh
@@ -230,6 +230,40 @@ run_client_suite() {
kill ${PID}
wait
+ # Try resumption with early data
+ echo_cmd "${PREFIX}Checking TLS 1.3 with resumption with early data..."
+ testdir=`create_testdir tls13-openssl-resumption`
+ eval "${GETPORT}"
+ launch_bare_server $$ s_server -quiet -accept "${PORT}" -keyform pem -certform pem ${OPENSSL_DH_PARAMS_OPT} -key "${RSA_KEY}" -cert "${RSA_CERT}" -CAfile "${CA_CERT}" -early_data
+ PID=$!
+ wait_server ${PID}
+
+ echo "This file contains early data sent by the client" > "${testdir}/earlydata.txt"
+ ${VALGRIND} "${CLI}" ${DEBUG} -p "${PORT}" 127.0.0.1 --priority "NORMAL:-VERS-ALL:+VERS-TLS1.3:+GROUP-ALL${ADD}" --earlydata "${testdir}/earlydata.txt" --insecure --inline-commands <<< '^resume^'| tee "${testdir}/client.out" >> ${OUTPUT}
+ grep '^\*\*\* This is a resumed session' "${testdir}/client.out" || \
+ fail ${PID} "Failed"
+
+ kill ${PID}
+ wait
+
+ # Try resumption with early data with small limit
+ echo_cmd "${PREFIX}Checking TLS 1.3 with resumption with early data..."
+ testdir=`create_testdir tls13-openssl-resumption`
+ eval "${GETPORT}"
+ launch_bare_server $$ s_server -quiet -accept "${PORT}" -keyform pem -certform pem ${OPENSSL_DH_PARAMS_OPT} -key "${RSA_KEY}" -cert "${RSA_CERT}" -CAfile "${CA_CERT}" -early_data -max_early_data 1
+ PID=$!
+ wait_server ${PID}
+
+ echo "This file contains early data sent by the client" > "${testdir}/earlydata.txt"
+ ${VALGRIND} "${CLI}" ${DEBUG} -p "${PORT}" 127.0.0.1 --priority "NORMAL:-VERS-ALL:+VERS-TLS1.3:+GROUP-ALL${ADD}" --earlydata "${testdir}/earlydata.txt" --insecure --inline-commands <<< '^resume^'|& tee "${testdir}/client.out" >> ${OUTPUT}
+ grep '^\*\*\* This is a resumed session' "${testdir}/client.out" || \
+ fail ${PID} "Failed"
+ grep '^\*\*\* Received alert \[10\]: Unexpected message' "${testdir}/client.out" || \
+ fail ${PID} "Failed"
+
+ kill ${PID}
+ wait
+
rm -rf "${testdir}"
}
@@ -476,6 +510,26 @@ _EOF_
kill ${PID}
wait
+
+ echo_cmd "${PREFIX}Checking TLS 1.3 with resumption and early data..."
+ testdir=`create_testdir tls13-openssl-resumption`
+ eval "${GETPORT}"
+ launch_server $$ --priority "NORMAL:-VERS-ALL:+VERS-TLS1.3${ADD}" --x509certfile "${RSA_CERT}" --x509keyfile "${RSA_KEY}" --x509cafile "${CA_CERT}" --earlydata >>${OUTPUT} 2>&1
+ PID=$!
+ wait_server ${PID}
+
+ echo "This file contains early data sent by the client" > "${testdir}/earlydata.txt"
+ { echo a; sleep 1; } | \
+ ${OPENSSL_CLI} s_client -host localhost -port "${PORT}" -CAfile "${CA_CERT}" -sess_out "${testdir}/sess-earlydata.pem" 2>&1 | grep "\:error\:" && \
+ fail ${PID} "Failed"
+ ${OPENSSL_CLI} s_client -host localhost -port "${PORT}" -CAfile "${CA_CERT}" -sess_in "${testdir}/sess-earlydata.pem" -early_data "${testdir}/earlydata.txt" </dev/null 2>&1 > "${testdir}/server.out"
+ grep "\:error\:" "${testdir}/server.out" && \
+ fail ${PID} "Failed"
+ grep "^Reused, TLSv1.3" "${testdir}/server.out" || \
+ fail ${PID} "Failed"
+
+ kill ${PID}
+ wait
rm -rf "${testdir}"
}
diff --git a/tests/tls13-early-data.c b/tests/tls13-early-data.c
new file mode 100644
index 0000000000..f23aec77fa
--- /dev/null
+++ b/tests/tls13-early-data.c
@@ -0,0 +1,432 @@
+/*
+ * Copyright (C) 2012-2018 Free Software Foundation, 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 <http://www.gnu.org/licenses/>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#if defined(_WIN32)
+
+int main(void)
+{
+ 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 <gnutls/crypto.h>
+#include <gnutls/dtls.h>
+#include <signal.h>
+#include <assert.h>
+
+#include "cert-common.h"
+#include "utils.h"
+#include "virt-time.h"
+
+/* This program tests the robustness of record sending with padding.
+ */
+
+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);
+}
+
+
+/* A very basic TLS client.
+ */
+
+#define SESSIONS 3
+#define MAX_BUF 1024
+#define MSG "Hello TLS"
+#define EARLY_MSG "Hello TLS, it's early"
+#define PRIORITY "NORMAL:-VERS-ALL:+VERS-TLS1.3"
+
+static const
+gnutls_datum_t hrnd = {(void*)"\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 32};
+
+static int gnutls_rnd_works;
+
+int __attribute__ ((visibility ("protected")))
+gnutls_rnd(gnutls_rnd_level_t level, void *data, size_t len)
+{
+ gnutls_rnd_works = 1;
+
+ memset(data, 0xff, len);
+
+ /* Flip the first byte to avoid infinite loop in the RSA
+ * blinding code of Nettle */
+ if (len > 0)
+ memset(data, 0x0, 1);
+ return 0;
+}
+
+static void client(int sds[])
+{
+ int ret;
+ char buffer[MAX_BUF + 1];
+ gnutls_certificate_credentials_t x509_cred;
+ gnutls_session_t session;
+ int t;
+ gnutls_datum_t session_data = {NULL, 0};
+
+ if (debug) {
+ gnutls_global_set_log_function(client_log_func);
+ gnutls_global_set_log_level(7);
+ }
+
+ /* Generate the same ob_ticket_age value, which affects the
+ * binder calculation.
+ */
+ virt_time_init();
+
+ gnutls_certificate_allocate_credentials(&x509_cred);
+
+ for (t = 0; t < SESSIONS; t++) {
+ int sd = sds[t];
+
+ assert(gnutls_init(&session, GNUTLS_CLIENT)>=0);
+ assert(gnutls_priority_set_direct(session, PRIORITY, NULL)>=0);
+
+ gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, x509_cred);
+
+ gnutls_transport_set_int(session, sd);
+
+ if (t > 0) {
+ assert(gnutls_session_set_data(session, session_data.data, session_data.size) >= 0);
+ assert(gnutls_record_send_early_data(session, EARLY_MSG, sizeof(EARLY_MSG)) >= 0);
+ assert(gnutls_handshake_set_random(session, &hrnd) >= 0);
+ }
+
+ /* Perform the TLS handshake
+ */
+ gnutls_handshake_set_timeout(session, 20 * 1000);
+ do {
+ ret = gnutls_handshake(session);
+ }
+ while (ret < 0 && gnutls_error_is_fatal(ret) == 0);
+
+ if (ret < 0) {
+ fail("client: Handshake failed\n");
+ gnutls_perror(ret);
+ exit(1);
+ } else {
+ if (debug)
+ success("client: Handshake was completed\n");
+ }
+
+ if (t == 0) {
+ /* get the session data size */
+ ret =
+ gnutls_session_get_data2(session,
+ &session_data);
+ if (ret < 0)
+ fail("client: Getting resume data failed\n");
+ }
+
+ if (t > 0) {
+ if (!gnutls_session_is_resumed(session)) {
+ fail("client: session_is_resumed error (%d)\n", t);
+ }
+ }
+
+ gnutls_record_send(session, MSG, strlen(MSG));
+
+ do {
+ ret = gnutls_record_recv(session, buffer, sizeof(buffer));
+ } while (ret == GNUTLS_E_AGAIN);
+ if (ret == 0) {
+ if (debug)
+ success
+ ("client: Peer has closed the TLS connection\n");
+ goto end;
+ } else if (ret < 0) {
+ fail("client: Error: %s\n", gnutls_strerror(ret));
+ goto end;
+ }
+
+ gnutls_bye(session, GNUTLS_SHUT_WR);
+
+ close(sd);
+
+ gnutls_deinit(session);
+ }
+
+ end:
+ gnutls_free(session_data.data);
+ gnutls_certificate_free_credentials(x509_cred);
+}
+
+
+static pid_t child;
+
+#define MAX_CLIENT_HELLO_RECORDED 10
+
+struct storage_st {
+ gnutls_datum_t entries[MAX_CLIENT_HELLO_RECORDED];
+ size_t num_entries;
+};
+
+static int
+storage_add(void *ptr, gnutls_datum_t key, gnutls_datum_t value)
+{
+ struct storage_st *storage = ptr;
+ gnutls_datum_t *datum;
+ size_t i;
+
+ for (i = 0; i < storage->num_entries; i++) {
+ if (key.size == storage->entries[i].size &&
+ memcmp(storage->entries[i].data, key.data, key.size) == 0) {
+ return GNUTLS_E_DB_ENTRY_EXISTS;
+ }
+ }
+
+ /* If the maximum number of ClientHello exceeded, reject early
+ * data until next time.
+ */
+ if (storage->num_entries == MAX_CLIENT_HELLO_RECORDED)
+ return GNUTLS_E_DB_ERROR;
+
+ datum = &storage->entries[storage->num_entries];
+ datum->data = gnutls_malloc(key.size);
+ if (!datum->data)
+ return GNUTLS_E_MEMORY_ERROR;
+ memcpy(datum->data, key.data, key.size);
+ datum->size = key.size;
+
+ storage->num_entries++;
+
+ return 0;
+}
+
+static void
+storage_clear(struct storage_st *storage)
+{
+ size_t i;
+
+ for (i = 0; i < storage->num_entries; i++)
+ gnutls_free(storage->entries[i].data);
+ storage->num_entries = 0;
+}
+
+static void server(int sds[])
+{
+ int ret;
+ char buffer[MAX_BUF + 1];
+ gnutls_session_t session;
+ gnutls_certificate_credentials_t x509_cred;
+ gnutls_datum_t session_ticket_key = { NULL, 0 };
+ struct storage_st storage;
+ gnutls_anti_replay_t anti_replay;
+ int t;
+
+ /* this must be called once in the program
+ */
+ global_init();
+ memset(buffer, 0, sizeof(buffer));
+ memset(&storage, 0, sizeof(storage));
+
+ 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);
+
+ gnutls_session_ticket_key_generate(&session_ticket_key);
+
+ ret = gnutls_anti_replay_init(&anti_replay);
+ if (ret < 0)
+ fail("server: failed to initialize anti-replay\n");
+
+ for (t = 0; t < SESSIONS; t++) {
+ int sd = sds[t];
+
+ assert(gnutls_init(&session, GNUTLS_SERVER|GNUTLS_ENABLE_EARLY_DATA)>=0);
+
+ assert(gnutls_priority_set_direct(session, PRIORITY, NULL)>=0);
+
+ gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, x509_cred);
+
+ gnutls_session_ticket_enable_server(session,
+ &session_ticket_key);
+
+ gnutls_db_set_add_function(session, storage_add);
+ gnutls_db_set_ptr(session, &storage);
+ gnutls_anti_replay_enable(session, anti_replay);
+
+ gnutls_transport_set_int(session, sd);
+
+ do {
+ ret = gnutls_handshake(session);
+ }
+ while (ret < 0 && gnutls_error_is_fatal(ret) == 0);
+ if (ret < 0) {
+ close(sd);
+ gnutls_deinit(session);
+ fail("server: Handshake has failed (%s)\n\n",
+ gnutls_strerror(ret));
+ return;
+ }
+ if (debug)
+ success("server: Handshake was completed\n");
+
+ if (t > 0) {
+ if (!gnutls_session_is_resumed(session)) {
+ fail("server: session_is_resumed error (%d)\n", t);
+ }
+
+ /* as we reuse the same ticket twice, expect
+ * early data only on the first resumption */
+ if (t == 1) {
+ if (gnutls_rnd_works) {
+ if (!(gnutls_session_get_flags(session) & GNUTLS_SFLAGS_EARLY_DATA)) {
+ fail("server: early data is not received (%d)\n", t);
+ }
+ } else {
+ success("server: gnutls_rnd() could not be overridden, skip checking replay (%d)\n", t);
+ }
+
+ ret = gnutls_record_recv_early_data(session, buffer, sizeof(buffer));
+ if (ret < 0) {
+ fail("server: failed to retrieve early data: %s\n",
+ gnutls_strerror(ret));
+ }
+
+ if (ret != sizeof(EARLY_MSG) || memcmp(buffer, EARLY_MSG, ret))
+ fail("server: early data mismatch\n");
+ } else {
+ if (gnutls_rnd_works) {
+ if (gnutls_session_get_flags(session) & GNUTLS_SFLAGS_EARLY_DATA) {
+ fail("server: early data is not rejected (%d)\n", t);
+ }
+ } else {
+ success("server: gnutls_rnd() could not be overridden, skip checking replay (%d)\n", t);
+ }
+ }
+ }
+
+ /* see the Getting peer's information example */
+ /* print_info(session); */
+
+ for (;;) {
+ memset(buffer, 0, MAX_BUF + 1);
+ ret = gnutls_record_recv(session, buffer, MAX_BUF);
+
+ if (ret == 0) {
+ if (debug)
+ success
+ ("server: Peer has closed the GnuTLS connection\n");
+ break;
+ } else if (ret < 0) {
+ kill(child, SIGTERM);
+ fail("server: Received corrupted data(%d). Closing...\n", ret);
+ break;
+ } else if (ret > 0) {
+ /* echo data back to the client
+ */
+ gnutls_record_send(session, buffer,
+ strlen(buffer));
+ }
+ }
+ /* do not wait for the peer to close the connection.
+ */
+ gnutls_bye(session, GNUTLS_SHUT_WR);
+
+ close(sd);
+
+ gnutls_deinit(session);
+ }
+
+ gnutls_anti_replay_deinit(anti_replay);
+
+ storage_clear(&storage);
+
+ gnutls_free(session_ticket_key.data);
+
+ gnutls_certificate_free_credentials(x509_cred);
+
+ if (debug)
+ success("server: finished\n");
+}
+
+void doit(void)
+{
+ int client_sds[SESSIONS], server_sds[SESSIONS];
+ int i;
+ int ret;
+
+ signal(SIGCHLD, SIG_IGN);
+ signal(SIGPIPE, SIG_IGN);
+
+ for (i = 0; i < SESSIONS; i++) {
+ int sockets[2];
+
+ ret = socketpair(AF_UNIX, SOCK_STREAM, 0, sockets);
+ if (ret < 0) {
+ perror("socketpair");
+ exit(1);
+ }
+
+ server_sds[i] = sockets[0];
+ client_sds[i] = sockets[1];
+ }
+
+ child = fork();
+ if (child < 0) {
+ perror("fork");
+ fail("fork");
+ exit(1);
+ }
+
+ if (child) {
+ /* parent */
+ for (i = 0; i < SESSIONS; i++)
+ close(client_sds[i]);
+ server(server_sds);
+ kill(child, SIGTERM);
+ } else {
+ for (i = 0; i < SESSIONS; i++)
+ close(server_sds[i]);
+ client(client_sds);
+ exit(0);
+ }
+}
+
+#endif /* _WIN32 */
diff --git a/tests/tls13/anti_replay.c b/tests/tls13/anti_replay.c
new file mode 100644
index 0000000000..090dcabbdb
--- /dev/null
+++ b/tests/tls13/anti_replay.c
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2015-2018 Red Hat, Inc.
+ *
+ * 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 <http://www.gnu.org/licenses/>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <assert.h>
+#include <stdint.h>
+
+#include "utils.h"
+#include "virt-time.h"
+#include "../../lib/tls13/anti_replay.h"
+#include "../../lib/system.h"
+
+#define MAX_CLIENT_HELLO_RECORDED 10
+
+struct storage_st {
+ gnutls_datum_t entries[MAX_CLIENT_HELLO_RECORDED];
+ size_t num_entries;
+};
+
+static int
+storage_add(void *ptr, gnutls_datum_t key, gnutls_datum_t value)
+{
+ struct storage_st *storage = ptr;
+ gnutls_datum_t *datum;
+ size_t i;
+
+ for (i = 0; i < storage->num_entries; i++) {
+ if (key.size == storage->entries[i].size &&
+ memcmp(storage->entries[i].data, key.data, key.size) == 0) {
+ return GNUTLS_E_DB_ENTRY_EXISTS;
+ }
+ }
+
+ /* If the maximum number of ClientHello exceeded, reject early
+ * data until next time.
+ */
+ if (storage->num_entries == MAX_CLIENT_HELLO_RECORDED)
+ return GNUTLS_E_DB_ERROR;
+
+ datum = &storage->entries[storage->num_entries];
+ datum->data = gnutls_malloc(key.size);
+ if (!datum->data)
+ return GNUTLS_E_MEMORY_ERROR;
+ memcpy(datum->data, key.data, key.size);
+ datum->size = key.size;
+
+ storage->num_entries++;
+
+ return 0;
+}
+
+static void
+storage_clear(struct storage_st *storage)
+{
+ size_t i;
+
+ for (i = 0; i < storage->num_entries; i++)
+ gnutls_free(storage->entries[i].data);
+ storage->num_entries = 0;
+}
+
+void doit(void)
+{
+ gnutls_anti_replay_t anti_replay;
+ gnutls_datum_t key = { (unsigned char *) "\xFF\xFF\xFF\xFF", 4 };
+ struct timespec creation_time;
+ struct storage_st storage;
+ gnutls_session_t session;
+ int ret;
+
+ virt_time_init();
+ memset(&storage, 0, sizeof(storage));
+
+ /* server_ticket_age < client_ticket_age */
+ ret = gnutls_anti_replay_init(&anti_replay);
+ assert(ret == 0);
+ gnutls_anti_replay_set_window(anti_replay, 10000);
+ gnutls_init(&session, GNUTLS_SERVER);
+ gnutls_db_set_add_function(session, storage_add);
+ gnutls_db_set_ptr(session, &storage);
+ gnutls_anti_replay_enable(session, anti_replay);
+ mygettime(&creation_time);
+ ret = _gnutls_anti_replay_check(session, 10000, &creation_time, &key);
+ if (ret != GNUTLS_E_ILLEGAL_PARAMETER)
+ fail("error is not returned, while server_ticket_age < client_ticket_age\n");
+ gnutls_deinit(session);
+ gnutls_anti_replay_deinit(anti_replay);
+ storage_clear(&storage);
+
+ /* server_ticket_age - client_ticket_age > window */
+ ret = gnutls_anti_replay_init(&anti_replay);
+ assert(ret == 0);
+ gnutls_anti_replay_set_window(anti_replay, 10000);
+ gnutls_init(&session, GNUTLS_SERVER);
+ gnutls_db_set_add_function(session, storage_add);
+ gnutls_db_set_ptr(session, &storage);
+ gnutls_anti_replay_enable(session, anti_replay);
+ mygettime(&creation_time);
+ virt_sec_sleep(30);
+ ret = _gnutls_anti_replay_check(session, 10000, &creation_time, &key);
+ if (ret != GNUTLS_E_EARLY_DATA_REJECTED)
+ fail("early data is NOT rejected, while freshness check fails\n");
+ gnutls_deinit(session);
+ gnutls_anti_replay_deinit(anti_replay);
+ storage_clear(&storage);
+
+ /* server_ticket_age - client_ticket_age < window */
+ ret = gnutls_anti_replay_init(&anti_replay);
+ assert(ret == 0);
+ gnutls_anti_replay_set_window(anti_replay, 10000);
+ gnutls_init(&session, GNUTLS_SERVER);
+ gnutls_db_set_add_function(session, storage_add);
+ gnutls_db_set_ptr(session, &storage);
+ gnutls_anti_replay_enable(session, anti_replay);
+ mygettime(&creation_time);
+ virt_sec_sleep(15);
+ ret = _gnutls_anti_replay_check(session, 10000, &creation_time, &key);
+ if (ret != 0)
+ fail("early data is rejected, while freshness check succeeds\n");
+ ret = _gnutls_anti_replay_check(session, 10000, &creation_time, &key);
+ if (ret != GNUTLS_E_EARLY_DATA_REJECTED)
+ fail("early data is NOT rejected for a duplicate key\n");
+ gnutls_deinit(session);
+ gnutls_anti_replay_deinit(anti_replay);
+ storage_clear(&storage);
+}