summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Caswell <matt@openssl.org>2017-02-22 13:01:48 +0000
committerMatt Caswell <matt@openssl.org>2017-03-02 17:44:15 +0000
commit1ea4d09a3c049cd3b0748410e0c53b98082980cb (patch)
treea6c2a4a8292f36a3c0ab18adad3c7fef3becc14d
parentd781d247d1ef9331983f456d616659108c857d0d (diff)
Construct the server side early_data extension
Reviewed-by: Rich Salz <rsalz@openssl.org> (Merged from https://github.com/openssl/openssl/pull/2737)
-rw-r--r--include/openssl/ssl.h7
-rw-r--r--ssl/ssl_err.c2
-rw-r--r--ssl/ssl_lib.c5
-rw-r--r--ssl/ssl_locl.h4
-rw-r--r--ssl/statem/extensions.c2
-rw-r--r--ssl/statem/extensions_srvr.c29
-rw-r--r--ssl/statem/statem.c2
-rw-r--r--ssl/statem/statem_clnt.c2
-rw-r--r--ssl/statem/statem_locl.h2
-rw-r--r--util/libssl.num1
10 files changed, 50 insertions, 6 deletions
diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h
index 597f77380d..d2f9fc6daa 100644
--- a/include/openssl/ssl.h
+++ b/include/openssl/ssl.h
@@ -1629,6 +1629,12 @@ long SSL_callback_ctrl(SSL *, int, void (*)(void));
long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg);
long SSL_CTX_callback_ctrl(SSL_CTX *, int, void (*)(void));
+# define SSL_EARLY_DATA_NOT_SENT 0
+# define SSL_EARLY_DATA_REJECTED 1
+# define SSL_EARLY_DATA_ACCEPTED 2
+
+__owur int SSL_get_early_data_status(SSL *s);
+
__owur int SSL_get_error(const SSL *s, int ret_code);
__owur const char *SSL_get_version(const SSL *s);
@@ -2374,6 +2380,7 @@ int ERR_load_SSL_strings(void);
# define SSL_F_TLS_CONSTRUCT_STOC_CERTIFICATE 374
# define SSL_F_TLS_CONSTRUCT_STOC_CRYPTOPRO_BUG 452
# define SSL_F_TLS_CONSTRUCT_STOC_DONE 375
+# define SSL_F_TLS_CONSTRUCT_STOC_EARLY_DATA 531
# define SSL_F_TLS_CONSTRUCT_STOC_EARLY_DATA_INFO 525
# define SSL_F_TLS_CONSTRUCT_STOC_EC_PT_FORMATS 453
# define SSL_F_TLS_CONSTRUCT_STOC_EMS 454
diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c
index 0620966172..d896ff9e58 100644
--- a/ssl/ssl_err.c
+++ b/ssl/ssl_err.c
@@ -362,6 +362,8 @@ static ERR_STRING_DATA SSL_str_functs[] = {
{ERR_FUNC(SSL_F_TLS_CONSTRUCT_STOC_CRYPTOPRO_BUG),
"tls_construct_stoc_cryptopro_bug"},
{ERR_FUNC(SSL_F_TLS_CONSTRUCT_STOC_DONE), "TLS_CONSTRUCT_STOC_DONE"},
+ {ERR_FUNC(SSL_F_TLS_CONSTRUCT_STOC_EARLY_DATA),
+ "tls_construct_stoc_early_data"},
{ERR_FUNC(SSL_F_TLS_CONSTRUCT_STOC_EARLY_DATA_INFO),
"tls_construct_stoc_early_data_info"},
{ERR_FUNC(SSL_F_TLS_CONSTRUCT_STOC_EC_PT_FORMATS),
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index e3e7853d60..a774452a61 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -1663,6 +1663,11 @@ int ssl_end_of_early_data_seen(SSL *s)
return 0;
}
+int SSL_get_early_data_status(SSL *s)
+{
+ return s->ext.early_data;
+}
+
static int ssl_peek_internal(SSL *s, void *buf, size_t num, size_t *readbytes)
{
if (s->handshake_func == NULL) {
diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h
index db1d7cfad3..3175009d80 100644
--- a/ssl/ssl_locl.h
+++ b/ssl/ssl_locl.h
@@ -1182,8 +1182,8 @@ struct ssl_st {
/* Set to one if we have negotiated ETM */
int use_etm;
- /* Set to 1 if we are expecting to receive early data */
- int expect_early_data;
+ /* Are we expecting to receive early data? */
+ int early_data;
} ext;
/* Parsed form of the ClientHello, kept around across early_cb calls. */
diff --git a/ssl/statem/extensions.c b/ssl/statem/extensions.c
index ccc60b6a26..f8bd47a1e0 100644
--- a/ssl/statem/extensions.c
+++ b/ssl/statem/extensions.c
@@ -138,7 +138,7 @@ static const EXTENSION_DEFINITION ext_defs[] = {
{
TLSEXT_TYPE_early_data,
EXT_CLIENT_HELLO | EXT_TLS1_3_ENCRYPTED_EXTENSIONS,
- NULL, tls_parse_ctos_early_data, NULL, NULL,
+ NULL, tls_parse_ctos_early_data, NULL, tls_construct_stoc_early_data,
tls_construct_ctos_early_data, NULL
},
#ifndef OPENSSL_NO_EC
diff --git a/ssl/statem/extensions_srvr.c b/ssl/statem/extensions_srvr.c
index 8994ab9cc1..57f38738d8 100644
--- a/ssl/statem/extensions_srvr.c
+++ b/ssl/statem/extensions_srvr.c
@@ -170,7 +170,18 @@ int tls_parse_ctos_early_data(SSL *s, PACKET *pkt, unsigned int context,
return 0;
}
- s->ext.expect_early_data = 1;
+ if (s->max_early_data == 0 || !s->hit || s->session->ext.tick_identity != 0
+ || s->early_data_state != SSL_EARLY_DATA_ACCEPTING) {
+ s->ext.early_data = SSL_EARLY_DATA_REJECTED;
+ } else {
+ s->ext.early_data = SSL_EARLY_DATA_ACCEPTED;
+
+ if (!tls13_change_cipher_state(s,
+ SSL3_CC_EARLY | SSL3_CHANGE_CIPHER_SERVER_READ)) {
+ *al = SSL_AD_INTERNAL_ERROR;
+ return 0;
+ }
+ }
return 1;
}
@@ -832,6 +843,22 @@ int tls_construct_stoc_early_data_info(SSL *s, WPACKET *pkt,
return 1;
}
+int tls_construct_stoc_early_data(SSL *s, WPACKET *pkt, unsigned int context,
+ X509 *x, size_t chainidx, int *al)
+{
+ if (s->ext.early_data != SSL_EARLY_DATA_ACCEPTED)
+ return 1;
+
+ if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_early_data)
+ || !WPACKET_start_sub_packet_u16(pkt)
+ || !WPACKET_close(pkt)) {
+ SSLerr(SSL_F_TLS_CONSTRUCT_STOC_EARLY_DATA, ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
+
+ return 1;
+}
+
#ifndef OPENSSL_NO_EC
int tls_construct_stoc_ec_pt_formats(SSL *s, WPACKET *pkt, unsigned int context,
X509 *x, size_t chainidx, int *al)
diff --git a/ssl/statem/statem.c b/ssl/statem/statem.c
index 26c9273210..9c74a2932e 100644
--- a/ssl/statem/statem.c
+++ b/ssl/statem/statem.c
@@ -154,7 +154,7 @@ void ossl_statem_set_in_handshake(SSL *s, int inhand)
/* Are we in a sensible state to skip over unreadable early data? */
int ossl_statem_skip_early_data(SSL *s)
{
- if (!s->ext.expect_early_data)
+ if (s->ext.early_data != SSL_EARLY_DATA_REJECTED)
return 0;
if (s->statem.hand_state != TLS_ST_SW_FINISHED)
diff --git a/ssl/statem/statem_clnt.c b/ssl/statem/statem_clnt.c
index e70ed10932..4f4409300e 100644
--- a/ssl/statem/statem_clnt.c
+++ b/ssl/statem/statem_clnt.c
@@ -714,7 +714,7 @@ WORK_STATE ossl_statem_client_post_work(SSL *s, WORK_STATE wst)
*/
if (!tls13_change_cipher_state(s,
SSL3_CC_EARLY | SSL3_CHANGE_CIPHER_CLIENT_WRITE))
- return WORK_ERROR;
+ return WORK_ERROR;
}
break;
diff --git a/ssl/statem/statem_locl.h b/ssl/statem/statem_locl.h
index 02c367910b..9dc9b1f515 100644
--- a/ssl/statem/statem_locl.h
+++ b/ssl/statem/statem_locl.h
@@ -235,6 +235,8 @@ int tls_construct_stoc_server_name(SSL *s, WPACKET *pkt, unsigned int context,
int tls_construct_stoc_early_data_info(SSL *s, WPACKET *pkt,
unsigned int context, X509 *x,
size_t chainidx, int *al);
+int tls_construct_stoc_early_data(SSL *s, WPACKET *pkt, unsigned int context,
+ X509 *x, size_t chainidx, int *al);
#ifndef OPENSSL_NO_EC
int tls_construct_stoc_ec_pt_formats(SSL *s, WPACKET *pkt, unsigned int context,
X509 *x, size_t chainidx, int *al);
diff --git a/util/libssl.num b/util/libssl.num
index 8d1f0b88b7..1d59a60dd0 100644
--- a/util/libssl.num
+++ b/util/libssl.num
@@ -431,3 +431,4 @@ SSL_CTX_get_max_early_data 431 1_1_1 EXIST::FUNCTION:
SSL_write_early 432 1_1_1 EXIST::FUNCTION:
SSL_write_early_finish 433 1_1_1 EXIST::FUNCTION:
SSL_read_early 434 1_1_1 EXIST::FUNCTION:
+SSL_get_early_data_status 435 1_1_1 EXIST::FUNCTION: