diff --git a/examples/client/client.c b/examples/client/client.c index 79aece83e..06b4fc449 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -329,6 +329,29 @@ static void SetKeyShare(WOLFSSL* ssl, int onlyKeyShare, int useX25519, #endif #ifdef WOLFSSL_EARLY_DATA +static void EarlyDataStatus(WOLFSSL* ssl) +{ + int earlyData_status; + + earlyData_status = wolfSSL_get_early_data_status(ssl); + if (earlyData_status < 0) return; + + printf("Early Data was "); + + switch(earlyData_status) { + case WOLFSSL_EARLY_DATA_NOT_SENT: + printf("not setn.\n"); + break; + case WOLFSSL_EARLY_DATA_REJECTED: + printf("rejected.\n"); + break; + case WOLFSSL_EARLY_DATA_ACCEPTED: + printf("accepted\n"); + break; + default: + printf("unknown...\n"); + } +} static void EarlyData(WOLFSSL_CTX* ctx, WOLFSSL* ssl, const char* msg, int msgSz, char* buffer) { @@ -466,6 +489,9 @@ static int ClientBenchmarkConnections(WOLFSSL_CTX* ctx, char* host, word16 port, do { err = 0; /* reset error */ ret = wolfSSL_connect(ssl); +#ifdef WOLFSSL_EARLY_DATA + EarlyDataStatus(ssl); +#endif if (ret != WOLFSSL_SUCCESS) { err = wolfSSL_get_error(ssl, 0); #ifdef WOLFSSL_ASYNC_CRYPT diff --git a/examples/server/server.c b/examples/server/server.c index 05b6f2f54..ad63565b0 100644 --- a/examples/server/server.c +++ b/examples/server/server.c @@ -844,6 +844,32 @@ static const char* server_usage_msg[][56] = { #endif }; +#ifdef WOLFSSL_EARLY_DATA +static void EarlyDataStatus(WOLFSSL* ssl) +{ + int earlyData_status; + + earlyData_status = wolfSSL_get_early_data_status(ssl); + if (earlyData_status < 0) return; + + printf("Early Data was "); + + switch(earlyData_status) { + case WOLFSSL_EARLY_DATA_NOT_SENT: + printf("not sent.\n"); + break; + case WOLFSSL_EARLY_DATA_REJECTED: + printf("rejected.\n"); + break; + case WOLFSSL_EARLY_DATA_ACCEPTED: + printf("accepted.\n"); + break; + default: + printf("unknown...\n"); + } +} +#endif + static void Usage(void) { int msgId = 0; @@ -2501,6 +2527,9 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) do { err = 0; /* reset error */ ret = SSL_accept(ssl); +#ifdef WOLFSSL_EARLY_DATA + EarlyDataStatus(ssl); +#endif if (ret != WOLFSSL_SUCCESS) { err = SSL_get_error(ssl, 0); #ifdef WOLFSSL_ASYNC_CRYPT diff --git a/scripts/tls13.test b/scripts/tls13.test index 7f4c927d3..e7a2b3618 100755 --- a/scripts/tls13.test +++ b/scripts/tls13.test @@ -257,7 +257,7 @@ if [ "$early_data" = "yes" ]; then grep 'Session Ticket' $client_out_file session_ticket=$? early_data_cnt=`grep 'Early Data' $server_out_file | wc -l` - if [ $session_ticket -eq 0 -a $early_data_cnt -ne 2 ]; then + if [ $session_ticket -eq 0 -a $early_data_cnt -ne 4 ]; then RESULT=1 fi if [ $RESULT -ne 0 ]; then diff --git a/src/internal.c b/src/internal.c index 7baad8c51..eeebe5302 100644 --- a/src/internal.c +++ b/src/internal.c @@ -18927,6 +18927,9 @@ const char* wolfSSL_ERR_reason_error_string(unsigned long e) case NO_CERT_ERROR: return "TLS1.3 No Certificate Set Error"; + case TOO_MUCH_EARLY_DATA: + return "Too much early data"; + default : return "unknown error number"; } diff --git a/src/tls.c b/src/tls.c index 0df44fc9b..38ebfbf02 100644 --- a/src/tls.c +++ b/src/tls.c @@ -9110,6 +9110,9 @@ static int TLSX_EarlyData_Parse(WOLFSSL* ssl, byte* input, word16 length, if (ssl->earlyData == expecting_early_data) return TLSX_EarlyData_Use(ssl, 0); ssl->earlyData = early_data_ext; + /* client wants to send early data. set this to rejected here. */ + /* Later, it is set to accepted if the server accepts the data. */ + ssl->earlyDataStatus = WOLFSSL_EARLY_DATA_REJECTED; return 0; } if (msgType == encrypted_extensions) { @@ -9122,6 +9125,10 @@ static int TLSX_EarlyData_Parse(WOLFSSL* ssl, byte* input, word16 length, if (ssl->options.pskIdIndex != 1) return PSK_KEY_ERROR; + if (ssl->options.side == WOLFSSL_CLIENT_END) + /* server could accept early data. */ + ssl->earlyDataStatus = WOLFSSL_EARLY_DATA_ACCEPTED; + return TLSX_EarlyData_Use(ssl, 1); } if (msgType == session_ticket) { diff --git a/src/tls13.c b/src/tls13.c index 83e78a7ab..718630e5f 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -6497,6 +6497,7 @@ static int DoTls13EndOfEarlyData(WOLFSSL* ssl, const byte* input, } ssl->earlyData = done_early_data; + ssl->earlyDataStatus = WOLFSSL_EARLY_DATA_ACCEPTED; /* Always encrypted. */ *inOutIdx += ssl->keys.padSz; @@ -8656,11 +8657,24 @@ int wolfSSL_write_early_data(WOLFSSL* ssl, const void* data, int sz, int* outSz) ret = wolfSSL_connect_TLSv13(ssl); if (ret != WOLFSSL_SUCCESS) return WOLFSSL_FATAL_ERROR; + /* on client side, status is set to rejected */ + /* until sever accepts early data */ + ssl->earlyDataStatus = WOLFSSL_EARLY_DATA_REJECTED; } if (ssl->options.handShakeState == CLIENT_HELLO_COMPLETE) { +#ifdef OPENSSL_EXTRA + /* when processed early data exceeds max size */ + if (ssl->earlyDataSz + sz > ssl->session.maxEarlyDataSz) { + ssl->error = TOO_MUCH_EARLY_DATA; + return WOLFSSL_FATAL_ERROR; + } +#endif ret = SendData(ssl, data, sz); - if (ret > 0) + if (ret > 0) { *outSz = ret; + /* store amount of processed early data from client */ + ssl->earlyDataSz += ret; + } } #else return SIDE_ERROR; @@ -8724,6 +8738,21 @@ int wolfSSL_read_early_data(WOLFSSL* ssl, void* data, int sz, int* outSz) ret = WOLFSSL_FATAL_ERROR; return ret; } + +/* Returns early data status + * + * ssl The SSL/TLS object. + * returns WOLFSSL_EARLY_DATA_ACCEPTED if the data was accepted + * WOLFSSL_EARLY_DATA_REJECTED if the data was rejected + * WOLFSSL_EARLY_DATA_NOT_SENT if no early data was sent + */ +int wolfSSL_get_early_data_status(const WOLFSSL* ssl) +{ + if (ssl == NULL || !IsAtLeastTLSv1_3(ssl->version)) + return BAD_FUNC_ARG; + + return ssl->earlyDataStatus; +} #endif #ifdef HAVE_SECRET_CALLBACK diff --git a/wolfssl/error-ssl.h b/wolfssl/error-ssl.h index 88c47b9c6..68ace3053 100644 --- a/wolfssl/error-ssl.h +++ b/wolfssl/error-ssl.h @@ -170,7 +170,8 @@ enum wolfSSL_ErrorCodes { DTLS_SIZE_ERROR = -439, /* Trying to send too much data */ NO_CERT_ERROR = -440, /* TLS1.3 - no cert set error */ APP_DATA_READY = -441, /* DTLS1.2 application data ready for read */ - + TOO_MUCH_EARLY_DATA = -442, /* Too much Early data */ + /* add strings to wolfSSL_ERR_reason_error_string in internal.c !!!!! */ /* begin negotiation parameter errors */ diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 8a124dd01..96ba70dcf 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -4367,6 +4367,7 @@ struct WOLFSSL { #ifdef WOLFSSL_EARLY_DATA EarlyDataState earlyData; word32 earlyDataSz; + word32 earlyDataStatus; #endif #ifdef OPENSSL_ALL long verifyCallbackResult; diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index db4940107..2668fd891 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -1333,6 +1333,11 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_ #define SSL_get_rbio wolfSSL_SSL_get_rbio #define SSL_get_wbio wolfSSL_SSL_get_wbio #define SSL_do_handshake wolfSSL_SSL_do_handshake + +#if defined(WOLFSSL_EARLY_DATA) +#define SSL_get_early_data_status wolfSSL_get_early_data_status +#endif + #endif /* OPENSSL_EXTRA */ /* cipher suites for compatibility */ diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 61adac213..f36f38be8 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -947,6 +947,11 @@ WOLFSSL_API int wolfSSL_connect_TLSv13(WOLFSSL*); WOLFSSL_API int wolfSSL_accept_TLSv13(WOLFSSL*); #ifdef WOLFSSL_EARLY_DATA + +#define WOLFSSL_EARLY_DATA_NOT_SENT 0 +#define WOLFSSL_EARLY_DATA_REJECTED 1 +#define WOLFSSL_EARLY_DATA_ACCEPTED 2 + 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); @@ -954,6 +959,7 @@ WOLFSSL_API int wolfSSL_write_early_data(WOLFSSL* ssl, const void* data, int sz, int* outSz); WOLFSSL_API int wolfSSL_read_early_data(WOLFSSL* ssl, void* data, int sz, int* outSz); +WOLFSSL_API int wolfSSL_get_early_data_status(const WOLFSSL* ssl); #endif /* WOLFSSL_EARLY_DATA */ #endif /* WOLFSSL_TLS13 */ WOLFSSL_ABI WOLFSSL_API void wolfSSL_CTX_free(WOLFSSL_CTX*);