Browse Source

TLS 1.3: send ticket

Can send a new session ticket any time after handshake is complete with
TLS v1.3.
Added API for server application to do this.
Added tests.
Sean Parkinson 1 year ago
parent
commit
be743b2204
6 changed files with 116 additions and 5 deletions
  1. 32 1
      doc/dox_comments/header_files/ssl.h
  2. 35 3
      examples/server/server.c
  3. 6 1
      src/internal.c
  4. 31 0
      src/tls13.c
  5. 9 0
      tests/test-tls13.conf
  6. 3 0
      wolfssl/ssl.h

+ 32 - 1
doc/dox_comments/header_files/ssl.h

@@ -11337,13 +11337,44 @@ int wolfSSL_set_SessionTicket(WOLFSSL* ssl, const unsigned char* buf,
     wolfSSL_set_SessionTicket_cb(ssl, sessionTicketCB, (void*)”initial session”);
     \endcode
 
-    \sa wolfSSL_set_SessionTicket
+    \sa wolfSSL_get_SessionTicket
     \sa CallbackSessionTicket
     \sa sessionTicketCB
 */
 int wolfSSL_set_SessionTicket_cb(WOLFSSL* ssl,
                                  CallbackSessionTicket cb, void* ctx);
 
+/*!
+    \brief This function sends a session ticket to the client after a TLS v1.3
+    handhsake has been established.
+
+    \return WOLFSSL_SUCCESS returned if a new session ticket was sent.
+    \return BAD_FUNC_ARG returned if WOLFSSL structure is NULL, or not using
+    TLS v1.3.
+    \return SIDE_ERROR returned if not a server.
+    \return NOT_READY_ERROR returned if the handshake has not completed.
+    \return WOLFSSL_FATAL_ERROR returned if creating or sending message fails.
+
+    \param ssl a pointer to a WOLFSSL structure, created using wolfSSL_new().
+
+    _Example_
+    \code
+    int ret;
+    WOLFSSL_CTX* ctx = wolfSSL_CTX_new( method );
+    WOLFSSL* ssl = wolfSSL_new(ctx);
+    …
+    ret = wolfSSL_send_SessionTicket(ssl);
+    if (ret != WOLFSSL_SUCCESS) {
+        // New session ticket not sent.
+    }
+    \endcode
+
+    \sa wolfSSL_get_SessionTicket
+    \sa CallbackSessionTicket
+    \sa sessionTicketCB
+ */
+int wolfSSL_send_SessionTicket(WOLFSSL* ssl);
+
 /*!
     \brief This function sets the session ticket key encrypt callback function
     for a server to support session tickets as specified in RFC 5077.

+ 35 - 3
examples/server/server.c

@@ -788,7 +788,7 @@ static void SetKeyShare(WOLFSSL* ssl, int onlyKeyShare, int useX25519,
 /*  4. add the same message into Japanese section         */
 /*     (will be translated later)                         */
 /*  5. add printf() into suitable position of Usage()     */
-static const char* server_usage_msg[][63] = {
+static const char* server_usage_msg[][64] = {
     /* English */
     {
         " NOTE: All files relative to wolfSSL home dir\n",               /* 0 */
@@ -943,10 +943,14 @@ static const char* server_usage_msg[][63] = {
 #endif
 #ifdef WOLFSSL_SRTP
         "--srtp <profile> (default is SRTP_AES128_CM_SHA1_80)\n",       /* 61 */
+#endif
+#if defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET)
+        "--send-ticket    Send a new session ticket during application data\n",
+                                                                        /* 62 */
 #endif
         "\n"
            "For simpler wolfSSL TLS server examples, visit\n"
-           "https://github.com/wolfSSL/wolfssl-examples/tree/master/tls\n", /* 62 */
+           "https://github.com/wolfSSL/wolfssl-examples/tree/master/tls\n", /* 63 */
         NULL,
     },
 #ifndef NO_MULTIBYTE_PRINT
@@ -1111,10 +1115,14 @@ static const char* server_usage_msg[][63] = {
 #endif
 #ifdef WOLFSSL_SRTP
         "--srtp <profile> (default is SRTP_AES128_CM_SHA1_80)\n", /* 61 */
+#endif
+#if defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET)
+        "--send-ticket    Send a new session ticket during application data\n",
+                                                                        /* 62 */
 #endif
         "\n"
         "For simpler wolfSSL TLS server examples, visit\n"
-        "https://github.com/wolfSSL/wolfssl-examples/tree/master/tls\n", /* 62 */
+        "https://github.com/wolfSSL/wolfssl-examples/tree/master/tls\n", /* 63 */
         NULL,
     },
 #endif
@@ -1263,6 +1271,9 @@ static void Usage(void)
 #ifdef WOLFSSL_SRTP
     printf("%s", msg[++msgId]);     /* dtls-srtp */
 #endif
+#if defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET)
+    printf("%s", msg[++msgId]);     /* send-ticket */
+#endif
 }
 
 #ifdef WOLFSSL_SRTP
@@ -1358,6 +1369,9 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
 #endif
 #ifdef WOLFSSL_SRTP
         { "srtp", 2, 260 }, /* optional argument */
+#endif
+#if defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET)
+        { "send-ticket", 0, 261 },
 #endif
         { 0, 0, 0 }
     };
@@ -1457,6 +1471,7 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
     int mutualAuth = 0;
 #endif
     int postHandAuth = 0;
+    int sendTicket = 0;
 #ifdef WOLFSSL_EARLY_DATA
     int earlyData = 0;
 #endif
@@ -1572,6 +1587,7 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
     (void)mutualAuth;
 #endif
     (void)postHandAuth;
+    (void)sendTicket;
     (void)mcastID;
     (void)loadCertKeyIntoSSLObj;
     (void)nonBlocking;
@@ -2108,6 +2124,12 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
                 break;
 #endif
 
+#if defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET)
+            case 261:
+                sendTicket = 1;
+                break;
+#endif
+
             default:
                 Usage();
                 XEXIT_T(MY_EX_USAGE);
@@ -3312,6 +3334,16 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
             if (postHandAuth)
                 wolfSSL_request_certificate(ssl);
 #endif
+#if defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET)
+            if (sendTicket) {
+                if (wolfSSL_send_SessionTicket(ssl) != WOLFSSL_SUCCESS) {
+                    fprintf(stderr, "Sending new session ticket failed\n");
+                }
+                else {
+                    fprintf(stderr, "New session ticket sent\n");
+                }
+            }
+#endif
 
             /* Write data */
             if (!useWebServerMsg) {

+ 6 - 1
src/internal.c

@@ -7378,8 +7378,13 @@ void FreeHandshakeResources(WOLFSSL* ssl)
         || ssl->specs.cipher_type == stream
 #endif
 #if defined(WOLFSSL_TLS13)
-    #if !defined(WOLFSSL_POST_HANDSHAKE_AUTH)
+    /* Post-handshake auth requires random on client side for TLS 1.3.
+     * Session ticket requires random on server side.
+     */
+    #if !defined(WOLFSSL_POST_HANDSHAKE_AUTH) && !defined(HAVE_SESSION_TICKET)
         || ssl->options.tls1_3
+    #elif !defined(WOLFSSL_POST_HANDSHAKE_AUTH) && defined(HAVE_SESSION_TICKET)
+        || (ssl->options.tls1_3 && ssl->options.side == WOLFSSL_CLIENT_END)
     #elif !defined(HAVE_SESSION_TICKET)
         || (ssl->options.tls1_3 && ssl->options.side == WOLFSSL_SERVER_END)
     #endif

+ 31 - 0
src/tls13.c

@@ -9897,6 +9897,37 @@ int wolfSSL_accept_TLSv13(WOLFSSL* ssl)
 }
 #endif
 
+#if !defined(NO_WOLFSSL_SERVER) && defined(HAVE_SESSION_TICKET)
+/* Server sends a session ticket to the peer.
+ *
+ * RFC 8446, section 4.6.1, para 1.
+ *
+ * ssl  The SSL/TLS object.
+ * returns BAD_FUNC_ARG when ssl is NULL, or not using TLS v1.3,
+ *         SIDE_ERROR when not a server,
+ *         NOT_READY_ERROR when handshake not complete,
+ *         WOLFSSL_FATAL_ERROR when creating or sending message fails, and
+ *         WOLFSSL_SUCCESS on success.
+ */
+int wolfSSL_send_SessionTicket(WOLFSSL* ssl)
+{
+    if (ssl == NULL || !IsAtLeastTLSv1_3(ssl->version))
+        return BAD_FUNC_ARG;
+    if (ssl->options.side == WOLFSSL_CLIENT_END)
+        return SIDE_ERROR;
+    if (ssl->options.handShakeState != HANDSHAKE_DONE)
+        return NOT_READY_ERROR;
+
+    if ((ssl->error = SendTls13NewSessionTicket(ssl)) != 0) {
+        WOLFSSL_ERROR(ssl->error);
+        return WOLFSSL_FATAL_ERROR;
+    }
+    ssl->options.ticketsSent++;
+
+    return WOLFSSL_SUCCESS;
+}
+#endif
+
 #ifdef WOLFSSL_EARLY_DATA
 /* Sets the maximum amount of early data that can be seen by server when using
  * session tickets for resumption.

+ 9 - 0
tests/test-tls13.conf

@@ -205,6 +205,15 @@
 -l TLS13-AES128-GCM-SHA256
 -Q
 
+# server TLSv1.3 Send Ticket explicitly
+-v 4
+-l TLS13-AES128-GCM-SHA256
+--send-ticket
+
+# client TLSv1.3 Send Ticket explicitly
+-v 4
+-l TLS13-AES128-GCM-SHA256
+
 # server TLSv1.3 Integrity-only SHA256
 -v 4
 -l TLS13-SHA256-SHA256

+ 3 - 0
wolfssl/ssl.h

@@ -3876,6 +3876,9 @@ typedef int (*CallbackSessionTicket)(WOLFSSL* ssl, const unsigned char*, int, vo
 WOLFSSL_API int wolfSSL_set_SessionTicket_cb(WOLFSSL* ssl,
                                                   CallbackSessionTicket cb, void* ctx);
 #endif /* NO_WOLFSSL_CLIENT */
+#ifndef NO_WOLFSSL_SERVER
+WOLFSSL_API int wolfSSL_send_SessionTicket(WOLFSSL* ssl);
+#endif /* !NO_WOLFSSL_SERVER */
 
 
 #define WOLFSSL_TICKET_NAME_SZ 16