Commit 49e7fe12 authored by Matt Caswell's avatar Matt Caswell
Browse files

Provide functions to write early data



We provide SSL_write_early() which *must* be called first on a connection
(prior to any other IO function including SSL_connect()/SSL_do_handshake()).
Also SSL_write_early_finish() which signals the end of early data.

Reviewed-by: default avatarRich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/2737)
parent 5d5b3fba
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -1025,6 +1025,7 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
# define SSL_AD_INTERNAL_ERROR           TLS1_AD_INTERNAL_ERROR
# define SSL_AD_USER_CANCELLED           TLS1_AD_USER_CANCELLED
# define SSL_AD_NO_RENEGOTIATION         TLS1_AD_NO_RENEGOTIATION
# define SSL_AD_END_OF_EARLY_DATA        TLS13_AD_END_OF_EARLY_DATA
# define SSL_AD_MISSING_EXTENSION        TLS13_AD_MISSING_EXTENSION
# define SSL_AD_UNSUPPORTED_EXTENSION    TLS1_AD_UNSUPPORTED_EXTENSION
# define SSL_AD_CERTIFICATE_UNOBTAINABLE TLS1_AD_CERTIFICATE_UNOBTAINABLE
@@ -1614,6 +1615,9 @@ __owur int SSL_peek(SSL *ssl, void *buf, int num);
__owur int SSL_peek_ex(SSL *ssl, void *buf, size_t num, size_t *readbytes);
__owur int SSL_write(SSL *ssl, const void *buf, int num);
__owur int SSL_write_ex(SSL *s, const void *buf, size_t num, size_t *written);
__owur int SSL_write_early(SSL *s, const void *buf, size_t num,
                           size_t *written);
__owur int SSL_write_early_finish(SSL *s);
long SSL_ctrl(SSL *ssl, int cmd, long larg, void *parg);
long SSL_callback_ctrl(SSL *, int, void (*)(void));
long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg);
@@ -2290,6 +2294,8 @@ int ERR_load_SSL_strings(void);
# define SSL_F_SSL_VALIDATE_CT                            400
# define SSL_F_SSL_VERIFY_CERT_CHAIN                      207
# define SSL_F_SSL_WRITE                                  208
# define SSL_F_SSL_WRITE_EARLY                            526
# define SSL_F_SSL_WRITE_EARLY_FINISH                     527
# define SSL_F_SSL_WRITE_EX                               433
# define SSL_F_SSL_WRITE_INTERNAL                         524
# define SSL_F_STATE_MACHINE                              353
@@ -2382,7 +2388,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_EARLY_DATA_INFO             528
# 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
+1 −0
Original line number Diff line number Diff line
@@ -104,6 +104,7 @@ extern "C" {
# define TLS1_AD_USER_CANCELLED          90
# define TLS1_AD_NO_RENEGOTIATION        100
/* TLSv1.3 alerts */
# define TLS13_AD_END_OF_EARLY_DATA      1
# define TLS13_AD_MISSING_EXTENSION      109 /* fatal */
/* codes 110-114 are from RFC3546 */
# define TLS1_AD_UNSUPPORTED_EXTENSION   110
+15 −6
Original line number Diff line number Diff line
@@ -745,7 +745,7 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
    }

    /* Explicit IV length, block ciphers appropriate version flag */
    if (s->enc_write_ctx && SSL_USE_EXPLICIT_IV(s)) {
    if (s->enc_write_ctx && SSL_USE_EXPLICIT_IV(s) && !SSL_TREAT_AS_TLS13(s)) {
        int mode = EVP_CIPHER_CTX_mode(s->enc_write_ctx);
        if (mode == EVP_CIPH_CBC_MODE) {
            /* TODO(size_t): Convert me */
@@ -764,7 +764,7 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
    /* Clear our SSL3_RECORD structures */
    memset(wr, 0, sizeof wr);
    for (j = 0; j < numpipes; j++) {
        unsigned int version = SSL_IS_TLS13(s) ? TLS1_VERSION : s->version;
        unsigned int version = SSL_TREAT_AS_TLS13(s) ? TLS1_VERSION : s->version;
        unsigned char *compressdata = NULL;
        size_t maxcomplen;
        unsigned int rectype;
@@ -777,7 +777,7 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
         * In TLSv1.3, once encrypting, we always use application data for the
         * record type
         */
        if (SSL_IS_TLS13(s) && s->enc_write_ctx != NULL)
        if (SSL_TREAT_AS_TLS13(s) && s->enc_write_ctx != NULL)
            rectype = SSL3_RT_APPLICATION_DATA;
        else
            rectype = type;
@@ -835,7 +835,7 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
            SSL3_RECORD_reset_input(&wr[j]);
        }

        if (SSL_IS_TLS13(s) && s->enc_write_ctx != NULL) {
        if (SSL_TREAT_AS_TLS13(s) && s->enc_write_ctx != NULL) {
            if (!WPACKET_put_bytes_u8(thispkt, type)) {
                SSLerr(SSL_F_DO_SSL3_WRITE, ERR_R_INTERNAL_ERROR);
                goto err;
@@ -887,8 +887,17 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
        SSL3_RECORD_set_length(thiswr, len);
    }

    if (s->early_data_state == SSL_EARLY_DATA_WRITING) {
        /*
         * We haven't actually negotiated the version yet, but we're trying to
         * send early data - so we need to use the the tls13enc function.
         */
        if (tls13_enc(s, wr, numpipes, 1) < 1)
            goto err;
    } else {
        if (s->method->ssl3_enc->enc(s, wr, numpipes, 1) < 1)
            goto err;
    }

    for (j = 0; j < numpipes; j++) {
        size_t origlen;
+12 −8
Original line number Diff line number Diff line
@@ -56,6 +56,9 @@ int tls13_enc(SSL *s, SSL3_RECORD *recs, size_t n_recs, int send)

    ivlen = EVP_CIPHER_CTX_iv_length(ctx);

    if (s->early_data_state == SSL_EARLY_DATA_WRITING) {
        alg_enc = s->session->cipher->algorithm_enc;
    } else {
        /*
         * To get here we must have selected a ciphersuite - otherwise ctx would
         * be NULL
@@ -64,6 +67,7 @@ int tls13_enc(SSL *s, SSL3_RECORD *recs, size_t n_recs, int send)
        if (s->s3->tmp.new_cipher == NULL)
            return -1;
        alg_enc = s->s3->tmp.new_cipher->algorithm_enc;
    }

    if (alg_enc & SSL_AESCCM) {
        if (alg_enc & (SSL_AES128CCM8 | SSL_AES256CCM8))
+4 −1
Original line number Diff line number Diff line
@@ -63,6 +63,9 @@ int ssl3_do_change_cipher_spec(SSL *s)
int ssl3_send_alert(SSL *s, int level, int desc)
{
    /* Map tls/ssl alert value to correct one */
    if (SSL_TREAT_AS_TLS13(s))
        desc = tls13_alert_code(desc);
    else
        desc = s->method->ssl3_enc->alert_value(desc);
    if (s->version == SSL3_VERSION && desc == SSL_AD_PROTOCOL_VERSION)
        desc = SSL_AD_HANDSHAKE_FAILURE; /* SSL 3.0 does not have
Loading