TLS v1.3 0-RTT
This commit is contained in:
parent
97906bfdb2
commit
350ce5fcef
21
configure.ac
21
configure.ac
@ -2326,6 +2326,26 @@ then
|
||||
AM_CFLAGS="$AM_CFLAGS -DHAVE_SUPPORTED_CURVES"])
|
||||
fi
|
||||
|
||||
# Early Data handshake in TLS v1.3 and above
|
||||
AC_ARG_ENABLE([earlydata],
|
||||
[AS_HELP_STRING([--enable-earlydata],[Enable Early Data handshake with wolfSSL TLS v1.3 (default: disabled)])],
|
||||
[ ENABLED_EARLY_DATA=$enableval ],
|
||||
[ ENABLED_EARLY_DATA=no ]
|
||||
)
|
||||
if test "$ENABLED_EARLY_DATA" = "yes"
|
||||
then
|
||||
if test "x$ENABLED_TLS13" = "xno"
|
||||
then
|
||||
AC_MSG_ERROR([cannot enable earlydata without enabling tls13.])
|
||||
fi
|
||||
if test "x$ENABLED_SESSION_TICKET" = "xno" && test "x$ENABLED_PSK" = "xno"
|
||||
then
|
||||
AC_MSG_ERROR([cannot enable earlydata without enabling session tickets and/or PSK.])
|
||||
fi
|
||||
AM_CFLAGS="-DWOLFSSL_EARLY_DATA $AM_CFLAGS"
|
||||
fi
|
||||
|
||||
|
||||
# PKCS7
|
||||
AC_ARG_ENABLE([pkcs7],
|
||||
[AS_HELP_STRING([--enable-pkcs7],[Enable PKCS7 (default: disabled)])],
|
||||
@ -3740,6 +3760,7 @@ echo " * SCTP: $ENABLED_SCTP"
|
||||
echo " * Old TLS Versions: $ENABLED_OLD_TLS"
|
||||
echo " * SSL version 3.0: $ENABLED_SSLV3"
|
||||
echo " * TLS v1.3: $ENABLED_TLS13"
|
||||
echo " * Early Data: $ENABLED_EARLY_DATA"
|
||||
echo " * OCSP: $ENABLED_OCSP"
|
||||
echo " * OCSP Stapling: $ENABLED_CERTIFICATE_STATUS_REQUEST"
|
||||
echo " * OCSP Stapling v2: $ENABLED_CERTIFICATE_STATUS_REQUEST_V2"
|
||||
|
@ -716,6 +716,9 @@ static void Usage(void)
|
||||
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
|
||||
printf("-Q Support requesting certificate post-handshake\n");
|
||||
#endif
|
||||
#ifdef WOLFSSL_EARLY_DATA
|
||||
printf("-0 Early data sent to server (0-RTT handshake)\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
|
||||
@ -817,6 +820,9 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
|
||||
#endif
|
||||
#endif
|
||||
int updateKeysIVs = 0;
|
||||
#ifdef WOLFSSL_EARLY_DATA
|
||||
int earlyData = 0;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OCSP
|
||||
int useOcsp = 0;
|
||||
@ -864,7 +870,8 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
|
||||
/* Not used: All used */
|
||||
while ((ch = mygetopt(argc, argv, "?"
|
||||
"ab:c:defgh:ijk:l:mnop:q:rstuv:wxyz"
|
||||
"A:B:CDE:F:GHIJKL:M:NO:PQRS:TUVW:XYZ:")) != -1) {
|
||||
"A:B:CDE:F:GHIJKL:M:NO:PQRS:TUVW:XYZ:"
|
||||
"0")) != -1) {
|
||||
switch (ch) {
|
||||
case '?' :
|
||||
Usage();
|
||||
@ -1184,6 +1191,12 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
|
||||
#endif
|
||||
break;
|
||||
|
||||
case '0' :
|
||||
#ifdef WOLFSSL_EARLY_DATA
|
||||
earlyData = 1;
|
||||
#endif
|
||||
break;
|
||||
|
||||
default:
|
||||
Usage();
|
||||
exit(MY_EX_USAGE);
|
||||
@ -2027,6 +2040,59 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
|
||||
ret = NonBlockingSSL_Connect(sslResume);
|
||||
}
|
||||
else {
|
||||
#ifdef WOLFSSL_EARLY_DATA
|
||||
#ifndef HAVE_SESSION_TICKET
|
||||
if (!usePsk) {
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (earlyData) {
|
||||
do {
|
||||
err = 0; /* reset error */
|
||||
ret = wolfSSL_write_early_data(sslResume, msg, msgSz,
|
||||
&msgSz);
|
||||
if (ret <= 0) {
|
||||
err = wolfSSL_get_error(sslResume, 0);
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
if (err == WC_PENDING_E) {
|
||||
ret = wolfSSL_AsyncPoll(sslResume,
|
||||
WOLF_POLL_FLAG_CHECK_HW);
|
||||
if (ret < 0) break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
} while (err == WC_PENDING_E);
|
||||
if (ret != msgSz) {
|
||||
printf("SSL_write_early_data msg error %d, %s\n", err,
|
||||
wolfSSL_ERR_error_string(err, buffer));
|
||||
wolfSSL_free(sslResume);
|
||||
wolfSSL_CTX_free(ctx);
|
||||
err_sys("SSL_write_early_data failed");
|
||||
}
|
||||
do {
|
||||
err = 0; /* reset error */
|
||||
ret = wolfSSL_write_early_data(sslResume, msg, msgSz,
|
||||
&msgSz);
|
||||
if (ret <= 0) {
|
||||
err = wolfSSL_get_error(sslResume, 0);
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
if (err == WC_PENDING_E) {
|
||||
ret = wolfSSL_AsyncPoll(sslResume,
|
||||
WOLF_POLL_FLAG_CHECK_HW);
|
||||
if (ret < 0) break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
} while (err == WC_PENDING_E);
|
||||
if (ret != msgSz) {
|
||||
printf("SSL_write_early_data msg error %d, %s\n", err,
|
||||
wolfSSL_ERR_error_string(err, buffer));
|
||||
wolfSSL_free(sslResume);
|
||||
wolfSSL_CTX_free(ctx);
|
||||
err_sys("SSL_write_early_data failed");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
do {
|
||||
err = 0; /* reset error */
|
||||
ret = wolfSSL_connect(sslResume);
|
||||
|
@ -368,6 +368,9 @@ static void Usage(void)
|
||||
printf("-Q Request certificate from client post-handshake\n");
|
||||
#endif
|
||||
#endif
|
||||
#ifdef WOLFSSL_EARLY_DATA
|
||||
printf("-0 Early data read from client (0-RTT handshake)\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
THREAD_RETURN CYASSL_THREAD server_test(void* args)
|
||||
@ -456,6 +459,9 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args)
|
||||
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
|
||||
int postHandAuth = 0;
|
||||
#endif
|
||||
#ifdef WOLFSSL_EARLY_DATA
|
||||
int earlyData = 0;
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_STATIC_MEMORY
|
||||
#if (defined(HAVE_ECC) && !defined(ALT_ECC_SIZE)) \
|
||||
@ -503,7 +509,8 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args)
|
||||
/* Not Used: h, m, t, x, y, z, F, J, M, T, V, W, X, Y */
|
||||
while ((ch = mygetopt(argc, argv, "?"
|
||||
"abc:defgijk:l:nop:q:rsuv:w"
|
||||
"A:B:C:D:E:GHIKL:NO:PQR:S:UYZ:")) != -1) {
|
||||
"A:B:C:D:E:GHIKL:NO:PQR:S:UYZ:"
|
||||
"0")) != -1) {
|
||||
switch (ch) {
|
||||
case '?' :
|
||||
Usage();
|
||||
@ -724,6 +731,12 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args)
|
||||
#endif
|
||||
break;
|
||||
|
||||
case '0' :
|
||||
#ifdef WOLFSSL_EARLY_DATA
|
||||
earlyData = 1;
|
||||
#endif
|
||||
break;
|
||||
|
||||
default:
|
||||
Usage();
|
||||
exit(MY_EX_USAGE);
|
||||
@ -1167,6 +1180,29 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args)
|
||||
ret = NonBlockingSSL_Accept(ssl);
|
||||
}
|
||||
else {
|
||||
#ifdef WOLFSSL_EARLY_DATA
|
||||
if (earlyData) {
|
||||
do {
|
||||
int len;
|
||||
err = 0; /* reset error */
|
||||
ret = wolfSSL_read_early_data(ssl, input, sizeof(input)-1,
|
||||
&len);
|
||||
if (ret != SSL_SUCCESS) {
|
||||
err = SSL_get_error(ssl, 0);
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
if (err == WC_PENDING_E) {
|
||||
ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
|
||||
if (ret < 0) break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (ret > 0) {
|
||||
input[ret] = 0; /* null terminate message */
|
||||
printf("Early Data Client message: %s\n", input);
|
||||
}
|
||||
} while (err == WC_PENDING_E || ret > 0);
|
||||
}
|
||||
#endif
|
||||
do {
|
||||
err = 0; /* reset error */
|
||||
ret = SSL_accept(ssl);
|
||||
|
@ -1433,6 +1433,10 @@ int InitSSL_Ctx(WOLFSSL_CTX* ctx, WOLFSSL_METHOD* method, void* heap)
|
||||
ret = wolfEventQueue_Init(&ctx->event_queue);
|
||||
#endif /* HAVE_WOLF_EVENT */
|
||||
|
||||
#ifdef WOLFSSL_EARLY_DATA
|
||||
ctx->maxEarlyDataSz = MAX_EARLY_DATA_SZ;
|
||||
#endif
|
||||
|
||||
ctx->heap = heap; /* wolfSSL_CTX_load_static_memory sets */
|
||||
|
||||
return ret;
|
||||
@ -3782,6 +3786,10 @@ int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup)
|
||||
ssl->options.client_psk_cb = ctx->client_psk_cb;
|
||||
ssl->options.server_psk_cb = ctx->server_psk_cb;
|
||||
#endif /* NO_PSK */
|
||||
#ifdef WOLFSSL_EARLY_DATA
|
||||
if (ssl->options.side == WOLFSSL_SERVER_END)
|
||||
ssl->options.maxEarlyDataSz = ctx->maxEarlyDataSz;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ANON
|
||||
ssl->options.haveAnon = ctx->haveAnon;
|
||||
@ -10898,6 +10906,11 @@ int DoApplicationData(WOLFSSL* ssl, byte* input, word32* inOutIdx)
|
||||
byte decomp[MAX_RECORD_SIZE + MAX_COMP_EXTRA];
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_EARLY_DATA
|
||||
if (ssl->earlyData) {
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (ssl->options.handShakeDone == 0) {
|
||||
WOLFSSL_MSG("Received App data before a handshake completed");
|
||||
SendAlert(ssl, alert_fatal, unexpected_message);
|
||||
@ -10918,6 +10931,15 @@ int DoApplicationData(WOLFSSL* ssl, byte* input, word32* inOutIdx)
|
||||
WOLFSSL_MSG("App data buffer error, malicious input?");
|
||||
return BUFFER_ERROR;
|
||||
}
|
||||
#ifdef WOLFSSL_EARLY_DATA
|
||||
if (ssl->earlyData) {
|
||||
if (ssl->earlyDataSz + dataSz > ssl->options.maxEarlyDataSz) {
|
||||
SendAlert(ssl, alert_fatal, unexpected_message);
|
||||
return SSL_FATAL_ERROR;
|
||||
}
|
||||
ssl->earlyDataSz += dataSz;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* read data */
|
||||
if (dataSz) {
|
||||
@ -11375,6 +11397,19 @@ int ProcessReply(WOLFSSL* ssl)
|
||||
else {
|
||||
WOLFSSL_MSG("Decrypt failed");
|
||||
WOLFSSL_ERROR(ret);
|
||||
#ifdef WOLFSSL_EARLY_DATA
|
||||
if (ssl->options.tls1_3) {
|
||||
ssl->earlyDataSz += ssl->curSize;
|
||||
if (ssl->earlyDataSz <= ssl->options.maxEarlyDataSz) {
|
||||
if (ssl->keys.peer_sequence_number_lo-- == 0)
|
||||
ssl->keys.peer_sequence_number_hi--;
|
||||
ssl->options.processReply = doProcessInit;
|
||||
ssl->buffers.inputBuffer.idx =
|
||||
ssl->buffers.inputBuffer.length;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef WOLFSSL_DTLS
|
||||
/* If in DTLS mode, if the decrypt fails for any
|
||||
* reason, pretend the datagram never happened. */
|
||||
@ -11461,6 +11496,17 @@ int ProcessReply(WOLFSSL* ssl)
|
||||
ssl->buffers.inputBuffer.buffer,
|
||||
&ssl->buffers.inputBuffer.idx,
|
||||
ssl->buffers.inputBuffer.length);
|
||||
#ifdef WOLFSSL_EARLY_DATA
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
if (ssl->options.side == WOLFSSL_SERVER_END &&
|
||||
ssl->earlyData &&
|
||||
ssl->options.handShakeState == HANDSHAKE_DONE) {
|
||||
ssl->earlyData = 0;
|
||||
ssl->options.processReply = doProcessInit;
|
||||
return ZERO_RETURN;
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
ret = BUFFER_ERROR;
|
||||
#endif
|
||||
@ -13153,6 +13199,15 @@ int SendData(WOLFSSL* ssl, const void* data, int sz)
|
||||
if (ssl->error == WANT_WRITE || ssl->error == WC_PENDING_E)
|
||||
ssl->error = 0;
|
||||
|
||||
#ifdef WOLFSSL_EARLY_DATA
|
||||
if (ssl->earlyData) {
|
||||
if (ssl->options.handShakeState == HANDSHAKE_DONE) {
|
||||
WOLFSSL_MSG("handshake complete, trying to send early data");
|
||||
return BUILD_MSG_ERROR;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (ssl->options.handShakeState != HANDSHAKE_DONE) {
|
||||
int err;
|
||||
WOLFSSL_MSG("handshake not complete, trying to finish");
|
||||
@ -13305,6 +13360,11 @@ int ReceiveData(WOLFSSL* ssl, byte* output, int sz, int peek)
|
||||
return ssl->error;
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_EARLY_DATA
|
||||
if (ssl->earlyData) {
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (ssl->options.handShakeState != HANDSHAKE_DONE) {
|
||||
int err;
|
||||
WOLFSSL_MSG("Handshake not complete, trying to finish");
|
||||
@ -22472,6 +22532,9 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
#ifdef WOLFSSL_TLS13
|
||||
word32 ageAdd; /* Obfuscation of age */
|
||||
byte namedGroup; /* Named group used */
|
||||
#ifdef WOLFSSL_EARLY_DATA
|
||||
word32 maxEarlyDataSz; /* Max size of early data */
|
||||
#endif
|
||||
#endif
|
||||
} InternalTicket;
|
||||
|
||||
@ -22503,6 +22566,10 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
it.suite[0] = ssl->options.cipherSuite0;
|
||||
it.suite[1] = ssl->options.cipherSuite;
|
||||
|
||||
#ifdef WOLFSSL_EARLY_DATA
|
||||
it.maxEarlyDataSz = ssl->options.maxEarlyDataSz;
|
||||
#endif
|
||||
|
||||
if (!ssl->options.tls1_3) {
|
||||
XMEMCPY(it.msecret, ssl->arrays->masterSecret, SECRET_LEN);
|
||||
c32toa(LowResTimer(), (byte*)&it.timestamp);
|
||||
@ -22627,6 +22694,9 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
ssl->session.ticketAdd = it->ageAdd;
|
||||
ssl->session.cipherSuite0 = it->suite[0];
|
||||
ssl->session.cipherSuite = it->suite[1];
|
||||
#ifdef WOLFSSL_EARLY_DATA
|
||||
ssl->session.maxEarlyDataSz = it->maxEarlyDataSz;
|
||||
#endif
|
||||
/* Resumption master secret. */
|
||||
XMEMCPY(ssl->session.masterSecret, it->msecret, SECRET_LEN);
|
||||
ssl->session.namedGroup = it->namedGroup;
|
||||
|
65
src/keys.c
65
src/keys.c
@ -2900,14 +2900,42 @@ int SetKeysSide(WOLFSSL* ssl, enum encrypt_side side)
|
||||
|
||||
switch (side) {
|
||||
case ENCRYPT_SIDE_ONLY:
|
||||
WOLFSSL_MSG("Provisioning ENCRYPT key");
|
||||
if (ssl->options.side == WOLFSSL_CLIENT_END) {
|
||||
WOLFSSL_BUFFER(ssl->keys.client_write_key, AES_256_KEY_SIZE);
|
||||
}
|
||||
else {
|
||||
WOLFSSL_BUFFER(ssl->keys.server_write_key, AES_256_KEY_SIZE);
|
||||
}
|
||||
wc_encrypt = &ssl->encrypt;
|
||||
break;
|
||||
|
||||
case DECRYPT_SIDE_ONLY:
|
||||
WOLFSSL_MSG("Provisioning DECRYPT key");
|
||||
if (ssl->options.side == WOLFSSL_CLIENT_END) {
|
||||
WOLFSSL_BUFFER(ssl->keys.server_write_key, AES_256_KEY_SIZE);
|
||||
}
|
||||
else {
|
||||
WOLFSSL_BUFFER(ssl->keys.client_write_key, AES_256_KEY_SIZE);
|
||||
}
|
||||
wc_decrypt = &ssl->decrypt;
|
||||
break;
|
||||
|
||||
case ENCRYPT_AND_DECRYPT_SIDE:
|
||||
WOLFSSL_MSG("Provisioning ENCRYPT key");
|
||||
if (ssl->options.side == WOLFSSL_CLIENT_END) {
|
||||
WOLFSSL_BUFFER(ssl->keys.client_write_key, AES_256_KEY_SIZE);
|
||||
}
|
||||
else {
|
||||
WOLFSSL_BUFFER(ssl->keys.server_write_key, AES_256_KEY_SIZE);
|
||||
}
|
||||
WOLFSSL_MSG("Provisioning DECRYPT key");
|
||||
if (ssl->options.side == WOLFSSL_CLIENT_END) {
|
||||
WOLFSSL_BUFFER(ssl->keys.server_write_key, AES_256_KEY_SIZE);
|
||||
}
|
||||
else {
|
||||
WOLFSSL_BUFFER(ssl->keys.client_write_key, AES_256_KEY_SIZE);
|
||||
}
|
||||
wc_encrypt = &ssl->encrypt;
|
||||
wc_decrypt = &ssl->decrypt;
|
||||
break;
|
||||
@ -2996,7 +3024,7 @@ int SetKeysSide(WOLFSSL* ssl, enum encrypt_side side)
|
||||
|
||||
|
||||
/* TLS can call too */
|
||||
int StoreKeys(WOLFSSL* ssl, const byte* keyData)
|
||||
int StoreKeys(WOLFSSL* ssl, const byte* keyData, int side)
|
||||
{
|
||||
int sz, i = 0;
|
||||
Keys* keys = &ssl->keys;
|
||||
@ -3011,21 +3039,32 @@ int StoreKeys(WOLFSSL* ssl, const byte* keyData)
|
||||
|
||||
if (ssl->specs.cipher_type != aead) {
|
||||
sz = ssl->specs.hash_size;
|
||||
XMEMCPY(keys->client_write_MAC_secret,&keyData[i], sz);
|
||||
i += sz;
|
||||
XMEMCPY(keys->server_write_MAC_secret,&keyData[i], sz);
|
||||
i += sz;
|
||||
if (side & PROVISION_CLIENT) {
|
||||
XMEMCPY(keys->client_write_MAC_secret,&keyData[i], sz);
|
||||
i += sz;
|
||||
}
|
||||
if (side & PROVISION_SERVER) {
|
||||
XMEMCPY(keys->server_write_MAC_secret,&keyData[i], sz);
|
||||
i += sz;
|
||||
}
|
||||
}
|
||||
sz = ssl->specs.key_size;
|
||||
XMEMCPY(keys->client_write_key, &keyData[i], sz);
|
||||
i += sz;
|
||||
XMEMCPY(keys->server_write_key, &keyData[i], sz);
|
||||
i += sz;
|
||||
if (side & PROVISION_CLIENT) {
|
||||
XMEMCPY(keys->client_write_key, &keyData[i], sz);
|
||||
i += sz;
|
||||
}
|
||||
if (side & PROVISION_SERVER) {
|
||||
XMEMCPY(keys->server_write_key, &keyData[i], sz);
|
||||
i += sz;
|
||||
}
|
||||
|
||||
sz = ssl->specs.iv_size;
|
||||
XMEMCPY(keys->client_write_IV, &keyData[i], sz);
|
||||
i += sz;
|
||||
XMEMCPY(keys->server_write_IV, &keyData[i], sz);
|
||||
if (side & PROVISION_CLIENT) {
|
||||
XMEMCPY(keys->client_write_IV, &keyData[i], sz);
|
||||
i += sz;
|
||||
}
|
||||
if (side & PROVISION_SERVER)
|
||||
XMEMCPY(keys->server_write_IV, &keyData[i], sz);
|
||||
|
||||
#ifdef HAVE_AEAD
|
||||
if (ssl->specs.cipher_type == aead) {
|
||||
@ -3126,7 +3165,7 @@ int DeriveKeys(WOLFSSL* ssl)
|
||||
}
|
||||
|
||||
if (ret == 0)
|
||||
ret = StoreKeys(ssl, keyData);
|
||||
ret = StoreKeys(ssl, keyData, PROVISION_CLIENT_SERVER);
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
|
36
src/ssl.c
36
src/ssl.c
@ -1313,6 +1313,14 @@ int wolfSSL_write(WOLFSSL* ssl, const void* data, int sz)
|
||||
if (ssl == NULL || data == NULL || sz < 0)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
#ifdef WOLFSSL_EARLY_DATA
|
||||
if (ssl->earlyData && (ret = wolfSSL_negotiate(ssl)) < 0) {
|
||||
ssl->error = ret;
|
||||
return SSL_FATAL_ERROR;
|
||||
}
|
||||
ssl->earlyData = 0;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_WRITE_DUP
|
||||
{ /* local variable scope */
|
||||
int dupErr = 0; /* local copy */
|
||||
@ -1357,7 +1365,6 @@ int wolfSSL_write(WOLFSSL* ssl, const void* data, int sz)
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int wolfSSL_read_internal(WOLFSSL* ssl, void* data, int sz, int peek)
|
||||
{
|
||||
int ret;
|
||||
@ -8273,6 +8280,11 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_TLS13
|
||||
if (ssl->options.tls1_3)
|
||||
return wolfSSL_connect_TLSv13(ssl);
|
||||
#endif
|
||||
|
||||
switch (ssl->options.connectState) {
|
||||
|
||||
case CONNECT_BEGIN :
|
||||
@ -9222,11 +9234,14 @@ static int GetDeepCopySession(WOLFSSL* ssl, WOLFSSL_SESSION* copyFrom)
|
||||
return BAD_MUTEX_E;
|
||||
}
|
||||
|
||||
copyInto->cipherSuite0 = copyFrom->cipherSuite0;
|
||||
copyInto->cipherSuite = copyFrom->cipherSuite;
|
||||
copyInto->namedGroup = copyFrom->namedGroup;
|
||||
copyInto->ticketSeen = copyFrom->ticketSeen;
|
||||
copyInto->ticketAdd = copyFrom->ticketAdd;
|
||||
copyInto->cipherSuite0 = copyFrom->cipherSuite0;
|
||||
copyInto->cipherSuite = copyFrom->cipherSuite;
|
||||
copyInto->namedGroup = copyFrom->namedGroup;
|
||||
copyInto->ticketSeen = copyFrom->ticketSeen;
|
||||
copyInto->ticketAdd = copyFrom->ticketAdd;
|
||||
#ifdef WOLFSSL_EARLY_DATA
|
||||
copyInto->maxEarlyDataSz = copyFrom->maxEarlyDataSz;
|
||||
#endif
|
||||
XMEMCPY(copyInto->masterSecret, copyFrom->masterSecret, SECRET_LEN);
|
||||
|
||||
if (wc_UnLockMutex(&session_mutex) != 0) {
|
||||
@ -9453,9 +9468,12 @@ int AddSession(WOLFSSL* ssl)
|
||||
#endif /* SESSION_CERTS || (WOLFSSL_TLS13 & HAVE_SESSION_TICKET) */
|
||||
#if defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET)
|
||||
if (error == 0) {
|
||||
session->namedGroup = ssl->session.namedGroup;
|
||||
session->ticketSeen = ssl->session.ticketSeen;
|
||||
session->ticketAdd = ssl->session.ticketAdd;
|
||||
session->namedGroup = ssl->session.namedGroup;
|
||||
session->ticketSeen = ssl->session.ticketSeen;
|
||||
session->ticketAdd = ssl->session.ticketAdd;
|
||||
#ifdef WOLFSSL_EARLY_DATA
|
||||
session->maxEarlyDataSz = ssl->session.maxEarlyDataSz;
|
||||
#endif
|
||||
}
|
||||
#endif /* WOLFSSL_TLS13 && HAVE_SESSION_TICKET */
|
||||
#ifdef HAVE_EXT_CACHE
|
||||
|
232
src/tls.c
232
src/tls.c
@ -533,7 +533,7 @@ int DeriveTlsKeys(WOLFSSL* ssl)
|
||||
IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm,
|
||||
ssl->heap, ssl->devId);
|
||||
if (ret == 0)
|
||||
ret = StoreKeys(ssl, key_dig);
|
||||
ret = StoreKeys(ssl, key_dig, PROVISION_CLIENT_SERVER);
|
||||
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(key_dig, ssl->heap, DYNAMIC_TYPE_DIGEST);
|
||||
@ -5992,7 +5992,7 @@ static int TLSX_PreSharedKey_Parse(WOLFSSL* ssl, byte* input, word16 length,
|
||||
idx += OPAQUE32_LEN;
|
||||
|
||||
ret = TLSX_PreSharedKey_Use(ssl, identity, identityLen, age, no_mac,
|
||||
1, NULL);
|
||||
0, 0, 1, NULL);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
@ -6145,12 +6145,15 @@ static INLINE byte GetHmacLength(int hmac)
|
||||
* len The length of the identity data.
|
||||
* age The age of the identity.
|
||||
* hmac The HMAC algorithm.
|
||||
* ciphersuite0 The first byte of the ciphersuite to use.
|
||||
* ciphersuite The second byte of the ciphersuite to use.
|
||||
* resumption The PSK is for resumption of a session.
|
||||
* preSharedKey The new pre-shared key object.
|
||||
* returns 0 on success and other values indicate failure.
|
||||
*/
|
||||
int TLSX_PreSharedKey_Use(WOLFSSL* ssl, byte* identity, word16 len, word32 age,
|
||||
byte hmac, byte resumption,
|
||||
byte hmac, byte cipherSuite0,
|
||||
byte cipherSuite, byte resumption,
|
||||
PreSharedKey **preSharedKey)
|
||||
{
|
||||
int ret = 0;
|
||||
@ -6189,10 +6192,12 @@ int TLSX_PreSharedKey_Use(WOLFSSL* ssl, byte* identity, word16 len, word32 age,
|
||||
}
|
||||
|
||||
/* Update/set age and HMAC algorithm. */
|
||||
psk->ticketAge = age;
|
||||
psk->hmac = hmac;
|
||||
psk->resumption = resumption;
|
||||
psk->binderLen = GetHmacLength(psk->hmac);
|
||||
psk->ticketAge = age;
|
||||
psk->hmac = hmac;
|
||||
psk->cipherSuite0 = cipherSuite0;
|
||||
psk->cipherSuite = cipherSuite;
|
||||
psk->resumption = resumption;
|
||||
psk->binderLen = GetHmacLength(psk->hmac);
|
||||
|
||||
if (preSharedKey != NULL)
|
||||
*preSharedKey = psk;
|
||||
@ -6224,7 +6229,7 @@ int TLSX_PreSharedKey_Use(WOLFSSL* ssl, byte* identity, word16 len, word32 age,
|
||||
*
|
||||
* modes The PSK KE mode bit string.
|
||||
* msgType The type of the message this extension is being written into.
|
||||
* returns the number of bytes of the encoded key share extension.
|
||||
* returns the number of bytes of the encoded PSK KE mode extension.
|
||||
*/
|
||||
static word16 TLSX_PskKeModes_GetSize(byte modes, byte msgType)
|
||||
{
|
||||
@ -6436,8 +6441,8 @@ static int TLSX_PostHandAuth_Parse(WOLFSSL* ssl, byte* input, word16 length,
|
||||
*/
|
||||
static int TLSX_PostHandAuth_Use(WOLFSSL* ssl)
|
||||
{
|
||||
int ret = 0;
|
||||
TLSX* extension;
|
||||
int ret = 0;
|
||||
TLSX* extension;
|
||||
|
||||
/* Find the PSK key exchange modes extension if it exists. */
|
||||
extension = TLSX_Find(ssl->extensions, TLSX_POST_HANDSHAKE_AUTH);
|
||||
@ -6464,6 +6469,129 @@ static int TLSX_PostHandAuth_Use(WOLFSSL* ssl)
|
||||
|
||||
#endif
|
||||
|
||||
/******************************************************************************/
|
||||
/* Early Data Indication */
|
||||
/******************************************************************************/
|
||||
|
||||
#ifdef WOLFSSL_EARLY_DATA
|
||||
/* Get the size of the encoded Early Data Indication extension.
|
||||
* In messages: ClientHello, EncryptedExtensions and NewSessionTicket.
|
||||
*
|
||||
* msgType The type of the message this extension is being written into.
|
||||
* returns the number of bytes of the encoded key share extension.
|
||||
*/
|
||||
static word16 TLSX_EarlyData_GetSize(byte msgType)
|
||||
{
|
||||
if (msgType == client_hello || msgType == encrypted_extensions)
|
||||
return 0;
|
||||
if (msgType == session_ticket)
|
||||
return OPAQUE32_LEN;
|
||||
|
||||
return SANITY_MSG_E;
|
||||
}
|
||||
|
||||
/* Writes the Early Data Indicator extension into the output buffer.
|
||||
* Assumes that the the output buffer is big enough to hold data.
|
||||
* In messages: ClientHello, EncryptedExtensions and NewSessionTicket.
|
||||
*
|
||||
* max The maximum early data size.
|
||||
* output The buffer to write into.
|
||||
* msgType The type of the message this extension is being written into.
|
||||
* returns the number of bytes written into the buffer.
|
||||
*/
|
||||
static word16 TLSX_EarlyData_Write(word32 max, byte* output, byte msgType)
|
||||
{
|
||||
if (msgType == client_hello || msgType == encrypted_extensions) {
|
||||
return 0;
|
||||
}
|
||||
if (msgType == session_ticket) {
|
||||
c32toa(max, output);
|
||||
return OPAQUE32_LEN;
|
||||
}
|
||||
|
||||
return SANITY_MSG_E;
|
||||
}
|
||||
|
||||
/* Parse the Early Data Indicator extension.
|
||||
* In messages: ClientHello, EncryptedExtensions and NewSessionTicket.
|
||||
*
|
||||
* ssl The SSL/TLS object.
|
||||
* input The extension data.
|
||||
* length The length of the extension data.
|
||||
* msgType The type of the message this extension is being parsed from.
|
||||
* returns 0 on success and other values indicate failure.
|
||||
*/
|
||||
static int TLSX_EarlyData_Parse(WOLFSSL* ssl, byte* input, word16 length,
|
||||
byte msgType)
|
||||
{
|
||||
if (msgType == client_hello) {
|
||||
if (length != 0)
|
||||
return BUFFER_E;
|
||||
|
||||
return TLSX_EarlyData_Use(ssl, 0);
|
||||
}
|
||||
if (msgType == encrypted_extensions) {
|
||||
if (length != 0)
|
||||
return BUFFER_E;
|
||||
|
||||
return TLSX_EarlyData_Use(ssl, 1);
|
||||
}
|
||||
if (msgType == session_ticket) {
|
||||
word32 max;
|
||||
|
||||
if (length != OPAQUE32_LEN)
|
||||
return BUFFER_E;
|
||||
ato32(input, &max);
|
||||
|
||||
ssl->session.maxEarlyDataSz = max;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return SANITY_MSG_E;
|
||||
}
|
||||
|
||||
/* Use the data to create a new Early Data object in the extensions.
|
||||
*
|
||||
* ssl The SSL/TLS object.
|
||||
* max The maximum early data size.
|
||||
* returns 0 on success and other values indicate failure.
|
||||
*/
|
||||
int TLSX_EarlyData_Use(WOLFSSL* ssl, word32 max)
|
||||
{
|
||||
int ret = 0;
|
||||
TLSX* extension;
|
||||
|
||||
/* Find the early extension if it exists. */
|
||||
extension = TLSX_Find(ssl->extensions, TLSX_EARLY_DATA);
|
||||
if (extension == NULL) {
|
||||
/* Push new early extension. */
|
||||
ret = TLSX_Push(&ssl->extensions, TLSX_EARLY_DATA, NULL, ssl->heap);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
extension = TLSX_Find(ssl->extensions, TLSX_EARLY_DATA);
|
||||
if (extension == NULL)
|
||||
return MEMORY_E;
|
||||
}
|
||||
|
||||
extension->resp = 1;
|
||||
extension->val = max;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define EDI_GET_SIZE TLSX_EarlyData_GetSize
|
||||
#define EDI_WRITE TLSX_EarlyData_Write
|
||||
#define EDI_PARSE TLSX_EarlyData_Parse
|
||||
|
||||
#else
|
||||
|
||||
#define EDI_GET_SIZE(a) 0
|
||||
#define EDI_WRITE(a, b, c) 0
|
||||
#define EDI_PARSE(a, b, c, d) 0
|
||||
|
||||
#endif
|
||||
|
||||
/******************************************************************************/
|
||||
/* TLS Extensions Framework */
|
||||
/******************************************************************************/
|
||||
@ -6550,6 +6678,11 @@ void TLSX_FreeAll(TLSX* list, void* heap)
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_EARLY_DATA
|
||||
case TLSX_EARLY_DATA:
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_POST_HANDSHAKE_AUTH
|
||||
case TLSX_POST_HANDSHAKE_AUTH:
|
||||
break;
|
||||
@ -6662,6 +6795,13 @@ static word16 TLSX_GetSize(TLSX* list, byte* semaphore, byte msgType)
|
||||
length += PKM_GET_SIZE(extension->val, msgType);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_EARLY_DATA
|
||||
case TLSX_EARLY_DATA:
|
||||
length += EDI_GET_SIZE(msgType);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_POST_HANDSHAKE_AUTH
|
||||
case TLSX_POST_HANDSHAKE_AUTH:
|
||||
length += PHA_GET_SIZE(msgType);
|
||||
@ -6797,6 +6937,14 @@ static word16 TLSX_Write(TLSX* list, byte* output, byte* semaphore,
|
||||
offset += PKM_WRITE(extension->val, output + offset, msgType);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_EARLY_DATA
|
||||
case TLSX_EARLY_DATA:
|
||||
WOLFSSL_MSG("Early Data extension to write");
|
||||
offset += EDI_WRITE(extension->val, output + offset, msgType);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_POST_HANDSHAKE_AUTH
|
||||
case TLSX_POST_HANDSHAKE_AUTH:
|
||||
WOLFSSL_MSG("Post-Handshake Authentication extension to write");
|
||||
@ -7292,12 +7440,16 @@ int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer)
|
||||
/* Determine the MAC algorithm for the cipher suite used. */
|
||||
ssl->options.cipherSuite0 = sess->cipherSuite0;
|
||||
ssl->options.cipherSuite = sess->cipherSuite;
|
||||
SetCipherSpecs(ssl);
|
||||
ret = SetCipherSpecs(ssl);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
milli = TimeNowInMilliseconds() - sess->ticketSeen +
|
||||
sess->ticketAdd;
|
||||
/* Pre-shared key is mandatory extension for resumption. */
|
||||
ret = TLSX_PreSharedKey_Use(ssl, sess->ticket, sess->ticketLen,
|
||||
milli, ssl->specs.mac_algorithm, 1,
|
||||
milli, ssl->specs.mac_algorithm,
|
||||
ssl->options.cipherSuite0,
|
||||
ssl->options.cipherSuite, 1,
|
||||
NULL);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
@ -7307,7 +7459,9 @@ int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer)
|
||||
#endif
|
||||
#ifndef NO_PSK
|
||||
if (ssl->options.client_psk_cb != NULL) {
|
||||
byte mac = sha256_mac;
|
||||
/* Default ciphersuite. */
|
||||
byte cipherSuite0 = TLS13_BYTE;
|
||||
byte cipherSuite = WOLFSSL_DEF_PSK_CIPHER;
|
||||
|
||||
ssl->arrays->psk_keySz = ssl->options.client_psk_cb(ssl,
|
||||
ssl->arrays->server_hint, ssl->arrays->client_identity,
|
||||
@ -7317,12 +7471,19 @@ int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer)
|
||||
return PSK_KEY_ERROR;
|
||||
}
|
||||
ssl->arrays->client_identity[MAX_PSK_ID_LEN] = '\0';
|
||||
/* Hash algorithm defaults to SHA-256 unless cb specifies. */
|
||||
/* TODO: Callback should be able to change ciphersuite. */
|
||||
ssl->options.cipherSuite0 = cipherSuite0;
|
||||
ssl->options.cipherSuite = cipherSuite;
|
||||
ret = SetCipherSpecs(ssl);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
ret = TLSX_PreSharedKey_Use(ssl,
|
||||
(byte*)ssl->arrays->client_identity,
|
||||
XSTRLEN(ssl->arrays->client_identity),
|
||||
0, mac, 0, NULL);
|
||||
0, ssl->specs.mac_algorithm,
|
||||
cipherSuite0, cipherSuite, 0,
|
||||
NULL);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
@ -7500,7 +7661,9 @@ word16 TLSX_GetResponseSize(WOLFSSL* ssl, byte msgType)
|
||||
TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY));
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
#ifdef WOLFSSL_TLS13
|
||||
case encrypted_extensions:
|
||||
TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SESSION_TICKET));
|
||||
TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
|
||||
@ -7512,9 +7675,17 @@ word16 TLSX_GetResponseSize(WOLFSSL* ssl, byte msgType)
|
||||
case certificate_request:
|
||||
XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE);
|
||||
TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_SIGNATURE_ALGORITHMS));
|
||||
break;
|
||||
#endif
|
||||
#ifdef WOLFSSL_EARLY_DATA
|
||||
case session_ticket:
|
||||
if (ssl->options.tls1_3) {
|
||||
XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE);
|
||||
TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_EARLY_DATA));
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef HAVE_QSH
|
||||
@ -7561,7 +7732,9 @@ word16 TLSX_WriteResponse(WOLFSSL *ssl, byte* output, byte msgType)
|
||||
TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY));
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
#ifdef WOLFSSL_TLS13
|
||||
case encrypted_extensions:
|
||||
TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SESSION_TICKET));
|
||||
TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
|
||||
@ -7574,9 +7747,17 @@ word16 TLSX_WriteResponse(WOLFSSL *ssl, byte* output, byte msgType)
|
||||
XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE);
|
||||
TURN_OFF(semaphore,
|
||||
TLSX_ToSemaphore(TLSX_SIGNATURE_ALGORITHMS));
|
||||
break;
|
||||
#endif
|
||||
#ifdef WOLFSSL_EARLY_DATA
|
||||
case session_ticket:
|
||||
if (ssl->options.tls1_3) {
|
||||
XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE);
|
||||
TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_EARLY_DATA));
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
offset += OPAQUE16_LEN; /* extensions length */
|
||||
@ -7837,6 +8018,23 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte msgType,
|
||||
ret = PKM_PARSE(ssl, input + offset, size, msgType);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_EARLY_DATA
|
||||
case TLSX_EARLY_DATA:
|
||||
WOLFSSL_MSG("Early Data extension received");
|
||||
|
||||
if (!IsAtLeastTLSv1_3(ssl->version))
|
||||
break;
|
||||
|
||||
if (IsAtLeastTLSv1_3(ssl->version) &&
|
||||
msgType != client_hello && msgType != session_ticket &&
|
||||
msgType != encrypted_extensions) {
|
||||
return EXT_NOT_ALLOWED;
|
||||
}
|
||||
ret = EDI_PARSE(ssl, input + offset, size, msgType);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_POST_HANDSHAKE_AUTH
|
||||
case TLSX_POST_HANDSHAKE_AUTH:
|
||||
WOLFSSL_MSG("PSK Key Exchange Modes extension received");
|
||||
|
765
src/tls13.c
765
src/tls13.c
File diff suppressed because it is too large
Load Diff
@ -261,3 +261,43 @@
|
||||
-v 4
|
||||
-l TLS13-AES128-GCM-SHA256
|
||||
|
||||
# server TLSv1.3 accepting EarlyData using PSK
|
||||
-v 4
|
||||
-l TLS13-AES128-GCM-SHA256
|
||||
-r
|
||||
-s
|
||||
-0
|
||||
|
||||
# client TLSv1.3 sending EarlyData using PSK
|
||||
-v 4
|
||||
-l TLS13-AES128-GCM-SHA256
|
||||
-r
|
||||
-s
|
||||
-0
|
||||
|
||||
# server TLSv1.3 not accepting EarlyData using PSK
|
||||
-v 4
|
||||
-l TLS13-AES128-GCM-SHA256
|
||||
-r
|
||||
-s
|
||||
|
||||
# client TLSv1.3 sending EarlyData using PSK
|
||||
-v 4
|
||||
-l TLS13-AES128-GCM-SHA256
|
||||
-r
|
||||
-s
|
||||
-0
|
||||
|
||||
# server TLSv1.3 accepting EarlyData using PSK
|
||||
-v 4
|
||||
-l TLS13-AES128-GCM-SHA256
|
||||
-r
|
||||
-s
|
||||
-0
|
||||
|
||||
# client TLSv1.3 not sending EarlyData using PSK
|
||||
-v 4
|
||||
-l TLS13-AES128-GCM-SHA256
|
||||
-r
|
||||
-s
|
||||
|
||||
|
@ -105,3 +105,37 @@
|
||||
-A ./certs/server-ecc.pem
|
||||
-t
|
||||
|
||||
# server TLSv1.3 accepting EarlyData
|
||||
-v 4
|
||||
-l TLS13-AES128-GCM-SHA256
|
||||
-r
|
||||
-0
|
||||
|
||||
# client TLSv1.3 sending EarlyData
|
||||
-v 4
|
||||
-l TLS13-AES128-GCM-SHA256
|
||||
-r
|
||||
-0
|
||||
|
||||
# server TLSv1.3 not accepting EarlyData
|
||||
-v 4
|
||||
-l TLS13-AES128-GCM-SHA256
|
||||
-r
|
||||
|
||||
# client TLSv1.3 sending EarlyData
|
||||
-v 4
|
||||
-l TLS13-AES128-GCM-SHA256
|
||||
-r
|
||||
-0
|
||||
|
||||
# server TLSv1.3 accepting EarlyData
|
||||
-v 4
|
||||
-l TLS13-AES128-GCM-SHA256
|
||||
-r
|
||||
-0
|
||||
|
||||
# client TLSv1.3 not sending EarlyData
|
||||
-v 4
|
||||
-l TLS13-AES128-GCM-SHA256
|
||||
-r
|
||||
|
||||
|
@ -978,6 +978,7 @@ enum Misc {
|
||||
SESSION_HINT_SZ = 4, /* session timeout hint */
|
||||
SESSION_ADD_SZ = 4, /* session age add */
|
||||
MAX_LIFETIME = 604800, /* maximum ticket lifetime */
|
||||
MAX_EARLY_DATA_SZ = 4096, /* maximum early data size */
|
||||
|
||||
RAN_LEN = 32, /* random length */
|
||||
SEED_LEN = RAN_LEN * 2, /* tls prf seed length */
|
||||
@ -1784,6 +1785,9 @@ typedef enum {
|
||||
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
|
||||
TLSX_PRE_SHARED_KEY = 0x0029,
|
||||
#endif
|
||||
#ifdef WOLFSSL_EARLY_DATA
|
||||
TLSX_EARLY_DATA = 0x002a,
|
||||
#endif
|
||||
TLSX_SUPPORTED_VERSIONS = 0x002b,
|
||||
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
|
||||
TLSX_PSK_KEY_EXCHANGE_MODES = 0x002d,
|
||||
@ -2082,6 +2086,8 @@ typedef struct PreSharedKey {
|
||||
word16 identityLen; /* Length of identity */
|
||||
byte* identity; /* PSK identity */
|
||||
word32 ticketAge; /* Age of the ticket */
|
||||
byte cipherSuite0; /* Cipher Suite */
|
||||
byte cipherSuite; /* Cipher Suite */
|
||||
word32 binderLen; /* Length of HMAC */
|
||||
byte binder[MAX_DIGEST_SIZE]; /* HMAC of hanshake */
|
||||
byte hmac; /* HMAC algorithm */
|
||||
@ -2096,6 +2102,7 @@ WOLFSSL_LOCAL word16 TLSX_PreSharedKey_GetSizeBinders(PreSharedKey* list,
|
||||
byte msgType);
|
||||
WOLFSSL_LOCAL int TLSX_PreSharedKey_Use(WOLFSSL* ssl, byte* identity,
|
||||
word16 len, word32 age, byte hmac,
|
||||
byte cipherSuite0, byte cipherSuite,
|
||||
byte resumption,
|
||||
PreSharedKey **preSharedKey);
|
||||
|
||||
@ -2104,11 +2111,22 @@ enum PskKeyExchangeMode {
|
||||
PSK_DHE_KE
|
||||
};
|
||||
|
||||
/* User can define this. */
|
||||
#ifndef WOLFSSL_DEF_PSK_CIPHER
|
||||
#define WOLFSSL_DEF_PSK_CIPHER TLS_AES_128_GCM_SHA256
|
||||
#endif
|
||||
|
||||
WOLFSSL_LOCAL int TLSX_PskKeModes_Use(WOLFSSL* ssl, byte modes);
|
||||
|
||||
#ifdef WOLFSSL_EARLY_DATA
|
||||
WOLFSSL_LOCAL int TLSX_EarlyData_Use(WOLFSSL* ssl, word32 max);
|
||||
#endif
|
||||
#endif /* HAVE_SESSION_TICKET || !NO_PSK */
|
||||
|
||||
/* The types of keys to derive for. */
|
||||
enum DeriveKeyType {
|
||||
no_key,
|
||||
early_data_key,
|
||||
handshake_key,
|
||||
traffic_key,
|
||||
update_traffic_key
|
||||
@ -2225,6 +2243,9 @@ struct WOLFSSL_CTX {
|
||||
wc_psk_server_callback server_psk_cb; /* server callback */
|
||||
char server_hint[MAX_PSK_ID_LEN + NULL_TERM_LEN];
|
||||
#endif /* HAVE_SESSION_TICKET || !NO_PSK */
|
||||
#ifdef WOLFSSL_EARLY_DATA
|
||||
word32 maxEarlyDataSz;
|
||||
#endif
|
||||
#ifdef HAVE_ANON
|
||||
byte haveAnon; /* User wants to allow Anon suites */
|
||||
#endif /* HAVE_ANON */
|
||||
@ -2556,6 +2577,9 @@ struct WOLFSSL_SESSION {
|
||||
word32 ticketSeen; /* Time ticket seen (ms) */
|
||||
word32 ticketAdd; /* Added by client */
|
||||
#endif
|
||||
#ifdef WOLFSSL_EARLY_DATA
|
||||
word32 maxEarlyDataSz;
|
||||
#endif
|
||||
byte* ticket;
|
||||
word16 ticketLen;
|
||||
byte staticTicket[SESSION_TICKET_LEN];
|
||||
@ -2806,6 +2830,9 @@ typedef struct Options {
|
||||
#ifdef HAVE_ECC
|
||||
short minEccKeySz; /* minimum ECC key size */
|
||||
#endif
|
||||
#ifdef WOLFSSL_EARLY_DATA
|
||||
word32 maxEarlyDataSz;
|
||||
#endif
|
||||
|
||||
} Options;
|
||||
|
||||
@ -3017,6 +3044,7 @@ typedef struct MsgsReceived {
|
||||
word16 got_server_hello:1;
|
||||
word16 got_hello_verify_request:1;
|
||||
word16 got_session_ticket:1;
|
||||
word16 got_end_of_early_data:1;
|
||||
word16 got_hello_retry_request:1;
|
||||
word16 got_encrypted_extensions:1;
|
||||
word16 got_certificate:1;
|
||||
@ -3326,6 +3354,10 @@ struct WOLFSSL {
|
||||
#ifdef WOLFSSL_JNI
|
||||
void* jObjectRef; /* reference to WolfSSLSession in JNI wrapper */
|
||||
#endif /* WOLFSSL_JNI */
|
||||
#ifdef WOLFSSL_EARLY_DATA
|
||||
int earlyData;
|
||||
word32 earlyDataSz;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@ -3426,27 +3458,34 @@ typedef struct DtlsHandShakeHeader {
|
||||
|
||||
|
||||
enum HandShakeType {
|
||||
hello_request = 0,
|
||||
client_hello = 1,
|
||||
server_hello = 2,
|
||||
hello_verify_request = 3, /* DTLS addition */
|
||||
session_ticket = 4,
|
||||
hello_retry_request = 6,
|
||||
encrypted_extensions = 8,
|
||||
certificate = 11,
|
||||
server_key_exchange = 12,
|
||||
certificate_request = 13,
|
||||
server_hello_done = 14,
|
||||
certificate_verify = 15,
|
||||
client_key_exchange = 16,
|
||||
finished = 20,
|
||||
certificate_status = 22,
|
||||
key_update = 24,
|
||||
change_cipher_hs = 55, /* simulate unique handshake type for sanity
|
||||
checks. record layer change_cipher
|
||||
conflicts with handshake finished */
|
||||
message_hash = 254, /* synthetic message type for TLS v1.3 */
|
||||
no_shake = 255 /* used to initialize the DtlsMsg record */
|
||||
hello_request = 0,
|
||||
client_hello = 1,
|
||||
server_hello = 2,
|
||||
hello_verify_request = 3, /* DTLS addition */
|
||||
session_ticket = 4,
|
||||
end_of_early_data = 5,
|
||||
hello_retry_request = 6,
|
||||
encrypted_extensions = 8,
|
||||
certificate = 11,
|
||||
server_key_exchange = 12,
|
||||
certificate_request = 13,
|
||||
server_hello_done = 14,
|
||||
certificate_verify = 15,
|
||||
client_key_exchange = 16,
|
||||
finished = 20,
|
||||
certificate_status = 22,
|
||||
key_update = 24,
|
||||
change_cipher_hs = 55, /* simulate unique handshake type for sanity
|
||||
checks. record layer change_cipher
|
||||
conflicts with handshake finished */
|
||||
message_hash = 254, /* synthetic message type for TLS v1.3 */
|
||||
no_shake = 255 /* used to initialize the DtlsMsg record */
|
||||
};
|
||||
|
||||
enum ProvisionSide {
|
||||
PROVISION_CLIENT = 1,
|
||||
PROVISION_SERVER = 2,
|
||||
PROVISION_CLIENT_SERVER = 3
|
||||
};
|
||||
|
||||
|
||||
@ -3492,7 +3531,7 @@ WOLFSSL_LOCAL int MakeMasterSecret(WOLFSSL*);
|
||||
|
||||
WOLFSSL_LOCAL int AddSession(WOLFSSL*);
|
||||
WOLFSSL_LOCAL int DeriveKeys(WOLFSSL* ssl);
|
||||
WOLFSSL_LOCAL int StoreKeys(WOLFSSL* ssl, const byte* keyData);
|
||||
WOLFSSL_LOCAL int StoreKeys(WOLFSSL* ssl, const byte* keyData, int side);
|
||||
|
||||
WOLFSSL_LOCAL int IsTLS(const WOLFSSL* ssl);
|
||||
WOLFSSL_LOCAL int IsAtLeastTLSv1_2(const WOLFSSL* ssl);
|
||||
|
@ -399,9 +399,6 @@ WOLFSSL_API void wolfSSL_set_using_nonblock(WOLFSSL*, int);
|
||||
WOLFSSL_API int wolfSSL_get_using_nonblock(WOLFSSL*);
|
||||
/* please see note at top of README if you get an error from connect */
|
||||
WOLFSSL_API int wolfSSL_connect(WOLFSSL*);
|
||||
#ifdef WOLFSSL_TLS13
|
||||
WOLFSSL_API int wolfSSL_connect_TLSv13(WOLFSSL*);
|
||||
#endif
|
||||
WOLFSSL_API int wolfSSL_write(WOLFSSL*, const void*, int);
|
||||
WOLFSSL_API int wolfSSL_read(WOLFSSL*, void*, int);
|
||||
WOLFSSL_API int wolfSSL_peek(WOLFSSL*, void*, int);
|
||||
@ -415,7 +412,17 @@ WOLFSSL_API int wolfSSL_update_keys(WOLFSSL* ssl);
|
||||
WOLFSSL_API int wolfSSL_CTX_allow_post_handshake_auth(WOLFSSL_CTX* ctx);
|
||||
WOLFSSL_API int wolfSSL_allow_post_handshake_auth(WOLFSSL* ssl);
|
||||
WOLFSSL_API int wolfSSL_request_certificate(WOLFSSL* ssl);
|
||||
|
||||
WOLFSSL_API int wolfSSL_connect_TLSv13(WOLFSSL*);
|
||||
WOLFSSL_API int wolfSSL_accept_TLSv13(WOLFSSL*);
|
||||
|
||||
#ifdef WOLFSSL_EARLY_DATA
|
||||
WOLFSSL_API int wolfSSL_CTX_set_max_early_data(WOLFSSL_CTX* ctx,
|
||||
unsigned int sz);
|
||||
WOLFSSL_API int wolfSSL_set_max_early_data(WOLFSSL* ssl, unsigned int sz);
|
||||
WOLFSSL_API int wolfSSL_write_early_data(WOLFSSL*, const void*, int, int*);
|
||||
WOLFSSL_API int wolfSSL_read_early_data(WOLFSSL*, void*, int, int*);
|
||||
#endif
|
||||
#endif
|
||||
WOLFSSL_API void wolfSSL_CTX_free(WOLFSSL_CTX*);
|
||||
WOLFSSL_API void wolfSSL_free(WOLFSSL*);
|
||||
|
Loading…
Reference in New Issue
Block a user