Loading ssl/ssl_asn1.c +20 −4 Original line number Diff line number Diff line Loading @@ -66,6 +66,7 @@ typedef struct { #endif long flags; uint32_t max_early_data; ASN1_OCTET_STRING *alpn_selected; } SSL_SESSION_ASN1; ASN1_SEQUENCE(SSL_SESSION_ASN1) = { Loading Loading @@ -93,7 +94,8 @@ ASN1_SEQUENCE(SSL_SESSION_ASN1) = { #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, max_early_data, ZLONG, 15) ASN1_EXP_OPT(SSL_SESSION_ASN1, max_early_data, ZLONG, 15), ASN1_EXP_OPT(SSL_SESSION_ASN1, alpn_selected, ASN1_OCTET_STRING, 16) } static_ASN1_SEQUENCE_END(SSL_SESSION_ASN1) IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(SSL_SESSION_ASN1) Loading Loading @@ -134,16 +136,14 @@ int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp) ASN1_OCTET_STRING comp_id; unsigned char comp_id_data; #endif ASN1_OCTET_STRING tlsext_hostname, tlsext_tick; #ifndef OPENSSL_NO_SRP ASN1_OCTET_STRING srp_username; #endif #ifndef OPENSSL_NO_PSK ASN1_OCTET_STRING psk_identity, psk_identity_hint; #endif ASN1_OCTET_STRING alpn_selected; long l; Loading Loading @@ -207,6 +207,12 @@ int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp) as.flags = in->flags; as.max_early_data = in->ext.max_early_data; if (in->ext.alpn_selected == NULL) as.alpn_selected = NULL; else ssl_session_oinit(&as.alpn_selected, &alpn_selected, in->ext.alpn_selected, in->ext.alpn_selected_len); return i2d_SSL_SESSION_ASN1(&as, pp); } Loading Loading @@ -362,6 +368,16 @@ SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, ret->flags = as->flags; ret->ext.max_early_data = as->max_early_data; if (as->alpn_selected != NULL) { if (!ssl_session_strndup((char **)&ret->ext.alpn_selected, as->alpn_selected)) goto err; ret->ext.alpn_selected_len = as->alpn_selected->length; } else { ret->ext.alpn_selected = NULL; ret->ext.alpn_selected_len = 0; } M_ASN1_free_of(as, SSL_SESSION_ASN1); if ((a != NULL) && (*a == NULL)) Loading ssl/ssl_locl.h +3 −0 Original line number Diff line number Diff line Loading @@ -580,6 +580,9 @@ struct ssl_session_st { int tick_identity; /* Max number of bytes that can be sent as early data */ uint32_t max_early_data; /* The ALPN protocol selected for this session */ unsigned char *alpn_selected; size_t alpn_selected_len; } ext; # ifndef OPENSSL_NO_SRP char *srp_username; Loading ssl/ssl_sess.c +1 −0 Original line number Diff line number Diff line Loading @@ -791,6 +791,7 @@ void SSL_SESSION_free(SSL_SESSION *ss) #ifndef OPENSSL_NO_SRP OPENSSL_free(ss->srp_username); #endif OPENSSL_free(ss->ext.alpn_selected); CRYPTO_THREAD_lock_free(ss->lock); OPENSSL_clear_free(ss, sizeof(*ss)); } Loading ssl/statem/extensions.c +5 −1 Original line number Diff line number Diff line Loading @@ -7,6 +7,7 @@ * https://www.openssl.org/source/license.html */ #include <string.h> #include "../ssl_locl.h" #include "statem_locl.h" Loading Loading @@ -1242,7 +1243,10 @@ static int final_early_data(SSL *s, unsigned int context, int sent, int *al) || s->session->ext.tick_identity != 0 || s->early_data_state != SSL_EARLY_DATA_ACCEPTING || !s->ext.early_data_ok || s->hello_retry_request) { || s->hello_retry_request || s->s3->alpn_selected_len != s->session->ext.alpn_selected_len || memcmp(s->s3->alpn_selected, s->session->ext.alpn_selected, s->s3->alpn_selected_len) != 0){ s->ext.early_data = SSL_EARLY_DATA_REJECTED; } else { s->ext.early_data = SSL_EARLY_DATA_ACCEPTED; Loading ssl/statem/statem_srvr.c +17 −4 Original line number Diff line number Diff line Loading @@ -3401,6 +3401,18 @@ int tls_construct_new_session_ticket(SSL *s, WPACKET *pkt) goto err; s->session->ext.tick_age_add = age_add_u.age_add; s->session->time = (long)time(NULL); if (s->s3->alpn_selected != NULL) { OPENSSL_free(s->session->ext.alpn_selected); s->session->ext.alpn_selected = OPENSSL_memdup(s->s3->alpn_selected, s->s3->alpn_selected_len); if (s->session->ext.alpn_selected == NULL) { SSLerr(SSL_F_TLS_CONSTRUCT_NEW_SESSION_TICKET, ERR_R_MALLOC_FAILURE); goto err; } s->session->ext.alpn_selected_len = s->s3->alpn_selected_len; } s->session->ext.max_early_data = s->max_early_data; } /* get session encoding length */ Loading @@ -3410,13 +3422,13 @@ int tls_construct_new_session_ticket(SSL *s, WPACKET *pkt) * long */ if (slen_full == 0 || slen_full > 0xFF00) { ossl_statem_set_error(s); return 0; SSLerr(SSL_F_TLS_CONSTRUCT_NEW_SESSION_TICKET, ERR_R_INTERNAL_ERROR); goto err; } senc = OPENSSL_malloc(slen_full); if (senc == NULL) { ossl_statem_set_error(s); return 0; SSLerr(SSL_F_TLS_CONSTRUCT_NEW_SESSION_TICKET, ERR_R_MALLOC_FAILURE); goto err; } ctx = EVP_CIPHER_CTX_new(); Loading Loading @@ -3545,6 +3557,7 @@ int tls_construct_new_session_ticket(SSL *s, WPACKET *pkt) return 1; err: ossl_statem_set_error(s); OPENSSL_free(senc); EVP_CIPHER_CTX_free(ctx); HMAC_CTX_free(hctx); Loading Loading
ssl/ssl_asn1.c +20 −4 Original line number Diff line number Diff line Loading @@ -66,6 +66,7 @@ typedef struct { #endif long flags; uint32_t max_early_data; ASN1_OCTET_STRING *alpn_selected; } SSL_SESSION_ASN1; ASN1_SEQUENCE(SSL_SESSION_ASN1) = { Loading Loading @@ -93,7 +94,8 @@ ASN1_SEQUENCE(SSL_SESSION_ASN1) = { #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, max_early_data, ZLONG, 15) ASN1_EXP_OPT(SSL_SESSION_ASN1, max_early_data, ZLONG, 15), ASN1_EXP_OPT(SSL_SESSION_ASN1, alpn_selected, ASN1_OCTET_STRING, 16) } static_ASN1_SEQUENCE_END(SSL_SESSION_ASN1) IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(SSL_SESSION_ASN1) Loading Loading @@ -134,16 +136,14 @@ int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp) ASN1_OCTET_STRING comp_id; unsigned char comp_id_data; #endif ASN1_OCTET_STRING tlsext_hostname, tlsext_tick; #ifndef OPENSSL_NO_SRP ASN1_OCTET_STRING srp_username; #endif #ifndef OPENSSL_NO_PSK ASN1_OCTET_STRING psk_identity, psk_identity_hint; #endif ASN1_OCTET_STRING alpn_selected; long l; Loading Loading @@ -207,6 +207,12 @@ int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp) as.flags = in->flags; as.max_early_data = in->ext.max_early_data; if (in->ext.alpn_selected == NULL) as.alpn_selected = NULL; else ssl_session_oinit(&as.alpn_selected, &alpn_selected, in->ext.alpn_selected, in->ext.alpn_selected_len); return i2d_SSL_SESSION_ASN1(&as, pp); } Loading Loading @@ -362,6 +368,16 @@ SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, ret->flags = as->flags; ret->ext.max_early_data = as->max_early_data; if (as->alpn_selected != NULL) { if (!ssl_session_strndup((char **)&ret->ext.alpn_selected, as->alpn_selected)) goto err; ret->ext.alpn_selected_len = as->alpn_selected->length; } else { ret->ext.alpn_selected = NULL; ret->ext.alpn_selected_len = 0; } M_ASN1_free_of(as, SSL_SESSION_ASN1); if ((a != NULL) && (*a == NULL)) Loading
ssl/ssl_locl.h +3 −0 Original line number Diff line number Diff line Loading @@ -580,6 +580,9 @@ struct ssl_session_st { int tick_identity; /* Max number of bytes that can be sent as early data */ uint32_t max_early_data; /* The ALPN protocol selected for this session */ unsigned char *alpn_selected; size_t alpn_selected_len; } ext; # ifndef OPENSSL_NO_SRP char *srp_username; Loading
ssl/ssl_sess.c +1 −0 Original line number Diff line number Diff line Loading @@ -791,6 +791,7 @@ void SSL_SESSION_free(SSL_SESSION *ss) #ifndef OPENSSL_NO_SRP OPENSSL_free(ss->srp_username); #endif OPENSSL_free(ss->ext.alpn_selected); CRYPTO_THREAD_lock_free(ss->lock); OPENSSL_clear_free(ss, sizeof(*ss)); } Loading
ssl/statem/extensions.c +5 −1 Original line number Diff line number Diff line Loading @@ -7,6 +7,7 @@ * https://www.openssl.org/source/license.html */ #include <string.h> #include "../ssl_locl.h" #include "statem_locl.h" Loading Loading @@ -1242,7 +1243,10 @@ static int final_early_data(SSL *s, unsigned int context, int sent, int *al) || s->session->ext.tick_identity != 0 || s->early_data_state != SSL_EARLY_DATA_ACCEPTING || !s->ext.early_data_ok || s->hello_retry_request) { || s->hello_retry_request || s->s3->alpn_selected_len != s->session->ext.alpn_selected_len || memcmp(s->s3->alpn_selected, s->session->ext.alpn_selected, s->s3->alpn_selected_len) != 0){ s->ext.early_data = SSL_EARLY_DATA_REJECTED; } else { s->ext.early_data = SSL_EARLY_DATA_ACCEPTED; Loading
ssl/statem/statem_srvr.c +17 −4 Original line number Diff line number Diff line Loading @@ -3401,6 +3401,18 @@ int tls_construct_new_session_ticket(SSL *s, WPACKET *pkt) goto err; s->session->ext.tick_age_add = age_add_u.age_add; s->session->time = (long)time(NULL); if (s->s3->alpn_selected != NULL) { OPENSSL_free(s->session->ext.alpn_selected); s->session->ext.alpn_selected = OPENSSL_memdup(s->s3->alpn_selected, s->s3->alpn_selected_len); if (s->session->ext.alpn_selected == NULL) { SSLerr(SSL_F_TLS_CONSTRUCT_NEW_SESSION_TICKET, ERR_R_MALLOC_FAILURE); goto err; } s->session->ext.alpn_selected_len = s->s3->alpn_selected_len; } s->session->ext.max_early_data = s->max_early_data; } /* get session encoding length */ Loading @@ -3410,13 +3422,13 @@ int tls_construct_new_session_ticket(SSL *s, WPACKET *pkt) * long */ if (slen_full == 0 || slen_full > 0xFF00) { ossl_statem_set_error(s); return 0; SSLerr(SSL_F_TLS_CONSTRUCT_NEW_SESSION_TICKET, ERR_R_INTERNAL_ERROR); goto err; } senc = OPENSSL_malloc(slen_full); if (senc == NULL) { ossl_statem_set_error(s); return 0; SSLerr(SSL_F_TLS_CONSTRUCT_NEW_SESSION_TICKET, ERR_R_MALLOC_FAILURE); goto err; } ctx = EVP_CIPHER_CTX_new(); Loading Loading @@ -3545,6 +3557,7 @@ int tls_construct_new_session_ticket(SSL *s, WPACKET *pkt) return 1; err: ossl_statem_set_error(s); OPENSSL_free(senc); EVP_CIPHER_CTX_free(ctx); HMAC_CTX_free(hctx); Loading