Parse the ticket_early_data_info extension
authorMatt Caswell <matt@openssl.org>
Mon, 20 Feb 2017 14:56:51 +0000 (14:56 +0000)
committerMatt Caswell <matt@openssl.org>
Thu, 2 Mar 2017 17:44:14 +0000 (17:44 +0000)
Reviewed-by: Rich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/2737)

include/openssl/ssl.h
ssl/ssl_asn1.c
ssl/ssl_err.c
ssl/ssl_locl.h
ssl/statem/extensions.c
ssl/statem/extensions_clnt.c
ssl/statem/statem_locl.h

index a4dc2c97ab6041dafbcb40e2a39818601bc38882..7f84e0a265c6bd0c1eac869d88539894bec0283e 100644 (file)
@@ -2382,6 +2382,7 @@ int ERR_load_SSL_strings(void);
 # define SSL_F_TLS_PARSE_CTOS_PSK                         505
 # define SSL_F_TLS_PARSE_CTOS_RENEGOTIATE                 464
 # define SSL_F_TLS_PARSE_CTOS_USE_SRTP                    465
+# define SSL_F_TLS_PARSE_STOC_EARLY_DATA_INFO             520
 # define SSL_F_TLS_PARSE_STOC_KEY_SHARE                   445
 # define SSL_F_TLS_PARSE_STOC_PSK                         502
 # define SSL_F_TLS_PARSE_STOC_RENEGOTIATE                 448
@@ -2525,6 +2526,7 @@ int ERR_load_SSL_strings(void);
 # define SSL_R_INVALID_CONFIGURATION_NAME                 113
 # define SSL_R_INVALID_CT_VALIDATION_TYPE                 212
 # define SSL_R_INVALID_KEY_UPDATE_TYPE                    120
+# define SSL_R_INVALID_MAX_EARLY_DATA                     174
 # define SSL_R_INVALID_NULL_CMD_NAME                      385
 # define SSL_R_INVALID_SEQUENCE_NUMBER                    402
 # define SSL_R_INVALID_SERVERINFO_DATA                    388
index 81414719151d461ff108dcc29678f98d6c1b5e3a..705db16470481e2af55c5ab98c2d9455c3a1f975 100644 (file)
@@ -65,6 +65,7 @@ typedef struct {
     ASN1_OCTET_STRING *srp_username;
 #endif
     long flags;
+    uint32_t max_early_data;
 } SSL_SESSION_ASN1;
 
 ASN1_SEQUENCE(SSL_SESSION_ASN1) = {
@@ -91,7 +92,8 @@ ASN1_SEQUENCE(SSL_SESSION_ASN1) = {
     ASN1_EXP_OPT(SSL_SESSION_ASN1, srp_username, ASN1_OCTET_STRING, 12),
 #endif
     ASN1_EXP_OPT(SSL_SESSION_ASN1, flags, ZLONG, 13),
-    ASN1_EXP_OPT(SSL_SESSION_ASN1, tlsext_tick_age_add, ZLONG, 14)
+    ASN1_EXP_OPT(SSL_SESSION_ASN1, tlsext_tick_age_add, ZLONG, 14),
+    ASN1_EXP_OPT(SSL_SESSION_ASN1, max_early_data, ZLONG, 15)
 } static_ASN1_SEQUENCE_END(SSL_SESSION_ASN1)
 
 IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(SSL_SESSION_ASN1)
@@ -203,6 +205,7 @@ int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp)
 #endif                          /* OPENSSL_NO_SRP */
 
     as.flags = in->flags;
+    as.max_early_data = in->ext.max_early_data;
 
     return i2d_SSL_SESSION_ASN1(&as, pp);
 
@@ -357,6 +360,7 @@ SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp,
 #endif                          /* OPENSSL_NO_SRP */
     /* Flags defaults to zero which is fine */
     ret->flags = as->flags;
+    ret->ext.max_early_data = as->max_early_data;
 
     M_ASN1_free_of(as, SSL_SESSION_ASN1);
 
index 788417ecdf012fea5576c59d2d039e1e58e93ff8..69d9adc9d744c235a780b7df81c78c511df39ffd 100644 (file)
@@ -392,6 +392,8 @@ static ERR_STRING_DATA SSL_str_functs[] = {
     {ERR_FUNC(SSL_F_TLS_PARSE_CTOS_RENEGOTIATE),
      "tls_parse_ctos_renegotiate"},
     {ERR_FUNC(SSL_F_TLS_PARSE_CTOS_USE_SRTP), "tls_parse_ctos_use_srtp"},
+    {ERR_FUNC(SSL_F_TLS_PARSE_STOC_EARLY_DATA_INFO),
+     "tls_parse_stoc_early_data_info"},
     {ERR_FUNC(SSL_F_TLS_PARSE_STOC_KEY_SHARE), "tls_parse_stoc_key_share"},
     {ERR_FUNC(SSL_F_TLS_PARSE_STOC_PSK), "tls_parse_stoc_psk"},
     {ERR_FUNC(SSL_F_TLS_PARSE_STOC_RENEGOTIATE),
@@ -587,6 +589,7 @@ static ERR_STRING_DATA SSL_str_reasons[] = {
     {ERR_REASON(SSL_R_INVALID_CT_VALIDATION_TYPE),
      "invalid ct validation type"},
     {ERR_REASON(SSL_R_INVALID_KEY_UPDATE_TYPE), "invalid key update type"},
+    {ERR_REASON(SSL_R_INVALID_MAX_EARLY_DATA), "invalid max early data"},
     {ERR_REASON(SSL_R_INVALID_NULL_CMD_NAME), "invalid null cmd name"},
     {ERR_REASON(SSL_R_INVALID_SEQUENCE_NUMBER), "invalid sequence number"},
     {ERR_REASON(SSL_R_INVALID_SERVERINFO_DATA), "invalid serverinfo data"},
index f8350afda2e40f536b0ee056429edf18da2d96e4..a7fa0b52c28022452d95729108de466d2ed77e6c 100644 (file)
@@ -575,6 +575,8 @@ struct ssl_session_st {
         unsigned long tick_lifetime_hint;
         uint32_t tick_age_add;
         int tick_identity;
+        /* Max number of bytes that can be sent as early data */
+        uint32_t max_early_data;
     } ext;
 # ifndef OPENSSL_NO_SRP
     char *srp_username;
index 19795b1595ba71f46080871983432e87a799c984..05e6acf340709df12f7166d9527a962dcc990991 100644 (file)
@@ -132,7 +132,8 @@ static const EXTENSION_DEFINITION ext_defs[] = {
     {
         TLSEXT_TYPE_early_data_info,
         EXT_TLS1_3_NEW_SESSION_TICKET,
-        NULL, NULL, NULL, tls_construct_stoc_early_data_info, NULL, NULL
+        NULL, NULL, tls_parse_stoc_early_data_info,
+        tls_construct_stoc_early_data_info, NULL, NULL
     },
 #ifndef OPENSSL_NO_EC
     {
index 09780a949548136ff58ac861cbcaf676a20aa6b5..7ef4c716cca5db2d5adbf434f50dd3c6abca17dd 100644 (file)
@@ -879,6 +879,24 @@ int tls_parse_stoc_server_name(SSL *s, PACKET *pkt, unsigned int context,
     return 1;
 }
 
+int tls_parse_stoc_early_data_info(SSL *s, PACKET *pkt, unsigned int context,
+                                   X509 *x, size_t chainidx, int *al)
+{
+    unsigned long max_early_data;
+
+    if (!PACKET_get_net_4(pkt, &max_early_data)
+            || PACKET_remaining(pkt) != 0) {
+        SSLerr(SSL_F_TLS_PARSE_STOC_EARLY_DATA_INFO,
+               SSL_R_INVALID_MAX_EARLY_DATA);
+        *al = SSL_AD_DECODE_ERROR;
+        return 0;
+    }
+
+    s->session->ext.max_early_data = max_early_data;
+
+    return 1;
+}
+
 #ifndef OPENSSL_NO_EC
 int tls_parse_stoc_ec_pt_formats(SSL *s, PACKET *pkt, unsigned int context,
                                  X509 *x, size_t chainidx, int *al)
index 41ebbbcbc500da950d5094be7774e74de6188a6b..0274dcbcbe0bd61c6a4fd90708898f5f6a99d838 100644 (file)
@@ -331,6 +331,8 @@ int tls_parse_stoc_renegotiate(SSL *s, PACKET *pkt, unsigned int context,
                                X509 *x, size_t chainidx, int *al);
 int tls_parse_stoc_server_name(SSL *s, PACKET *pkt, unsigned int context,
                                X509 *x, size_t chainidx, int *al);
+int tls_parse_stoc_early_data_info(SSL *s, PACKET *pkt, unsigned int context,
+                              X509 *x, size_t chainidx, int *al);
 #ifndef OPENSSL_NO_EC
 int tls_parse_stoc_ec_pt_formats(SSL *s, PACKET *pkt, unsigned int context,
                                  X509 *x, size_t chainidx, int *al);