Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TLS1.3 early data test code #8606

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
177 changes: 162 additions & 15 deletions programs/ssl/ssl_client2.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ int main(void)
#define DFL_KEY_OPAQUE 0
#define DFL_KEY_PWD ""
#define DFL_PSK ""
#define DFL_EARLY_DATA MBEDTLS_SSL_EARLY_DATA_DISABLED
#define DFL_EARLY_DATA_FILE ""
#define DFL_PSK_OPAQUE 0
#define DFL_PSK_IDENTITY "Client_identity"
#define DFL_ECJPAKE_PW NULL
Expand Down Expand Up @@ -347,8 +347,9 @@ int main(void)

#if defined(MBEDTLS_SSL_EARLY_DATA)
#define USAGE_EARLY_DATA \
" early_data=%%d default: 0 (disabled)\n" \
" options: 0 (disabled), 1 (enabled)\n"
" early_data=%%s The file path to read early data from\n" \
" default: \"\" (do nothing)\n" \
" option: a file path\n"
#else
#define USAGE_EARLY_DATA ""
#endif /* MBEDTLS_SSL_EARLY_DATA && MBEDTLS_SSL_PROTO_TLS1_3 */
Expand Down Expand Up @@ -543,7 +544,7 @@ struct options {
int reproducible; /* make communication reproducible */
int skip_close_notify; /* skip sending the close_notify alert */
#if defined(MBEDTLS_SSL_EARLY_DATA)
int early_data; /* support for early data */
const char *early_data_file; /* the file path of early data */
#endif
int query_config_mode; /* whether to read config */
int use_srtp; /* Support SRTP */
Expand Down Expand Up @@ -716,6 +717,119 @@ static int ssl_save_session_serialize(mbedtls_ssl_context *ssl,
return ret;
}

#if defined(MBEDTLS_SSL_EARLY_DATA)

#define MBEDTLS_ERR_EARLY_FILE_IO_ERROR -2

int ssl_early_data_read_file(const char *path, unsigned char **buffer, size_t *length)
{
FILE *f;
long size;

if ((f = fopen(path, "rb")) == NULL) {
return MBEDTLS_ERR_EARLY_FILE_IO_ERROR;
}

fseek(f, 0, SEEK_END);
if ((size = ftell(f)) == -1) {
fclose(f);
return MBEDTLS_ERR_EARLY_FILE_IO_ERROR;
}
fseek(f, 0, SEEK_SET);

*length = (size_t) size;
if (*length + 1 == 0 ||
(*buffer = mbedtls_calloc(1, *length + 1)) == NULL) {
fclose(f);
return MBEDTLS_ERR_SSL_ALLOC_FAILED;
}

if (fread(*buffer, 1, *length, f) != *length) {
fclose(f);
return MBEDTLS_ERR_EARLY_FILE_IO_ERROR;
}

fclose(f);

(*buffer)[*length] = '\0';

return 0;
}

static int internal_write_early_data(mbedtls_ssl_context *ssl,
const unsigned char *data_to_write,
size_t data_to_write_len,
size_t *data_written)
{
*data_written = 0;
((void) ssl);
((void) data_to_write);

while (*data_written < data_to_write_len) {
*data_written += data_to_write_len;
/*
* TODO: call mbedtls_ssl_write_early_data() here, and remove the above two lines.
* This is currently not possible because mbedtls_ssl_write_early_data() will
* be implemented in the next PR.
* mbedtls_ssl_write_early_data() will initial the handshake and only step to
* the client hello.
*/
}

return 0;
}

static int ssl_write_early_data(mbedtls_ssl_context *ssl,
const unsigned char *data_to_write,
size_t data_to_write_len,
int *data_written)
{
int ret = 0;
size_t early_data_written = 0;
ret = internal_write_early_data(ssl, data_to_write, data_to_write_len,
&early_data_written);
if (ret < 0 &&
ret != MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA) {
return ret;
}

/*
* Make sure the handshake is completed as it is a requisite to
* mbedtls_ssl_get_early_data_status().
* mbedtls_ssl_write_early_data will initial the handshake and only step to
* the client hello.
*/
while (!mbedtls_ssl_is_handshake_over(ssl)) {
ret = mbedtls_ssl_handshake(ssl);
if (ret < 0 &&
ret != MBEDTLS_ERR_SSL_WANT_READ &&
ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
return ret;
}
}

/* TODO:
* We will call mbedtls_ssl_get_early_data_status() to tell whether the early data is rejected
* or not. Once it's rejected, we will revert early_data_written to 0 and call mbedtls_ssl_write()
* to send the data.
*/
if (ret == MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED) {
early_data_written = 0;
}

*data_written += (int) early_data_written;

ret = mbedtls_ssl_write(ssl, data_to_write + early_data_written,
data_to_write_len - early_data_written);
if (ret < 0) {
return ret;
}

*data_written += ret;
return ret;
}
#endif /* MBEDTLS_SSL_EARLY_DATA */

int main(int argc, char *argv[])
{
int ret = 0, len, tail_len, i, written, frags, retry_left;
Expand All @@ -741,6 +855,10 @@ int main(int argc, char *argv[])
size_t cid_renego_len = 0;
#endif

#if defined(MBEDTLS_SSL_EARLY_DATA)
unsigned char *early_data = NULL;
#endif /* MBEDTLS_SSL_EARLY_DATA */

#if defined(MBEDTLS_SSL_ALPN)
const char *alpn_list[ALPN_LIST_SIZE];
#endif
Expand Down Expand Up @@ -912,7 +1030,7 @@ int main(int argc, char *argv[])
opt.groups = DFL_GROUPS;
opt.sig_algs = DFL_SIG_ALGS;
#if defined(MBEDTLS_SSL_EARLY_DATA)
opt.early_data = DFL_EARLY_DATA;
opt.early_data_file = DFL_EARLY_DATA_FILE;
#endif
opt.transport = DFL_TRANSPORT;
opt.hs_to_min = DFL_HS_TO_MIN;
Expand Down Expand Up @@ -1196,15 +1314,7 @@ int main(int argc, char *argv[])
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
#if defined(MBEDTLS_SSL_EARLY_DATA)
else if (strcmp(p, "early_data") == 0) {
switch (atoi(q)) {
case 0:
opt.early_data = MBEDTLS_SSL_EARLY_DATA_DISABLED;
break;
case 1:
opt.early_data = MBEDTLS_SSL_EARLY_DATA_ENABLED;
break;
default: goto usage;
}
opt.early_data_file = q;
}
#endif /* MBEDTLS_SSL_EARLY_DATA */

Expand Down Expand Up @@ -1971,7 +2081,16 @@ int main(int argc, char *argv[])
}

#if defined(MBEDTLS_SSL_EARLY_DATA)
mbedtls_ssl_conf_early_data(&conf, opt.early_data);
int early_data_enabled = 0;
size_t early_data_len;
if (strlen(opt.early_data_file) > 0 &&
ssl_early_data_read_file(opt.early_data_file,
&early_data, &early_data_len) == 0) {
early_data_enabled = MBEDTLS_SSL_EARLY_DATA_ENABLED;
} else {
early_data_enabled = MBEDTLS_SSL_EARLY_DATA_DISABLED;
}
mbedtls_ssl_conf_early_data(&conf, early_data_enabled);
#endif /* MBEDTLS_SSL_EARLY_DATA */

if ((ret = mbedtls_ssl_setup(&ssl, &conf)) != 0) {
Expand Down Expand Up @@ -2349,6 +2468,13 @@ int main(int argc, char *argv[])
}
}

#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_CLI_C)
/* TODO:
* Call mbedtls_ssl_get_early_data_status() to get current status of
* early data.
*/
#endif /* MBEDTLS_SSL_EARLY_DATA && MBEDTLS_SSL_CLI_C */

#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED)
/*
* 5. Verify the server certificate
Expand Down Expand Up @@ -2996,6 +3122,13 @@ int main(int argc, char *argv[])
goto exit;
}

#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && defined(MBEDTLS_SSL_EARLY_DATA)
if (early_data_enabled == MBEDTLS_SSL_EARLY_DATA_ENABLED) {
int data_written = 0;
ssl_write_early_data(&ssl, (const unsigned char *) early_data,
early_data_len, &data_written);
} else
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 && MBEDTLS_SSL_EARLY_DATA */
while ((ret = mbedtls_ssl_handshake(&ssl)) != 0) {
if (ret != MBEDTLS_ERR_SSL_WANT_READ &&
ret != MBEDTLS_ERR_SSL_WANT_WRITE &&
Expand All @@ -3008,6 +3141,13 @@ int main(int argc, char *argv[])

mbedtls_printf(" ok\n");

#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_CLI_C)
/* TODO:
* Call mbedtls_ssl_get_early_data_status() to get current status of
* early data.
*/
#endif /* MBEDTLS_SSL_EARLY_DATA && MBEDTLS_SSL_CLI_C */

goto send_request;
}

Expand All @@ -3029,6 +3169,13 @@ int main(int argc, char *argv[])
mbedtls_ssl_config_free(&conf);
mbedtls_ssl_session_free(&saved_session);

#if defined(MBEDTLS_SSL_EARLY_DATA)
if (early_data != NULL) {
mbedtls_platform_zeroize(early_data, early_data_len);
}
mbedtls_free(early_data);
#endif

if (session_data != NULL) {
mbedtls_platform_zeroize(session_data, session_data_len);
}
Expand Down
4 changes: 2 additions & 2 deletions tests/opt-testcases/tls13-misc.sh
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_
run_test "TLS 1.3 m->G: EarlyData: basic check, good" \
"$G_NEXT_SRV -d 10 --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:+CIPHER-ALL:+ECDHE-PSK:+PSK \
--earlydata --maxearlydata 16384 --disable-client-cert" \
"$P_CLI debug_level=4 early_data=1 reco_mode=1 reconnect=1 reco_delay=900" \
"$P_CLI debug_level=4 early_data=$EARLY_DATA_INPUT reco_mode=1 reconnect=1 reco_delay=900" \
0 \
-c "received max_early_data_size: 16384" \
-c "Reconnecting with saved session" \
Expand All @@ -287,7 +287,7 @@ requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED
run_test "TLS 1.3 m->G: EarlyData: no early_data in NewSessionTicket, good" \
"$G_NEXT_SRV -d 10 --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:+CIPHER-ALL:+ECDHE-PSK:+PSK --disable-client-cert" \
"$P_CLI debug_level=4 early_data=1 reco_mode=1 reconnect=1" \
"$P_CLI debug_level=4 early_data=$EARLY_DATA_INPUT reco_mode=1 reconnect=1" \
0 \
-c "Reconnecting with saved session" \
-C "NewSessionTicket: early_data(42) extension received." \
Expand Down