Commit ffc5bbaa authored by Matt Caswell's avatar Matt Caswell
Browse files

Complain if we are writing early data but SNI or ALPN is incorrect



SNI and ALPN must be set to be consistent with the PSK. Otherwise this is
an error.

Reviewed-by: default avatarBen Kaduk <kaduk@mit.edu>
(Merged from https://github.com/openssl/openssl/pull/3926)
parent 67738645
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -2320,6 +2320,8 @@ SSL_R_ILLEGAL_POINT_COMPRESSION:162:illegal point compression
SSL_R_ILLEGAL_SUITEB_DIGEST:380:illegal Suite B digest
SSL_R_INAPPROPRIATE_FALLBACK:373:inappropriate fallback
SSL_R_INCONSISTENT_COMPRESSION:340:inconsistent compression
SSL_R_INCONSISTENT_EARLY_DATA_ALPN:222:inconsistent early data alpn
SSL_R_INCONSISTENT_EARLY_DATA_SNI:231:inconsistent early data sni
SSL_R_INCONSISTENT_EXTMS:104:inconsistent extms
SSL_R_INVALID_ALERT:205:invalid alert
SSL_R_INVALID_COMMAND:280:invalid command
+2 −0
Original line number Diff line number Diff line
@@ -458,6 +458,8 @@ int ERR_load_SSL_strings(void);
# define SSL_R_ILLEGAL_SUITEB_DIGEST                      380
# define SSL_R_INAPPROPRIATE_FALLBACK                     373
# define SSL_R_INCONSISTENT_COMPRESSION                   340
# define SSL_R_INCONSISTENT_EARLY_DATA_ALPN               222
# define SSL_R_INCONSISTENT_EARLY_DATA_SNI                231
# define SSL_R_INCONSISTENT_EXTMS                         104
# define SSL_R_INVALID_ALERT                              205
# define SSL_R_INVALID_COMMAND                            280
+4 −0
Original line number Diff line number Diff line
@@ -724,6 +724,10 @@ static const ERR_STRING_DATA SSL_str_reasons[] = {
    "inappropriate fallback"},
    {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INCONSISTENT_COMPRESSION),
    "inconsistent compression"},
    {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INCONSISTENT_EARLY_DATA_ALPN),
    "inconsistent early data alpn"},
    {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INCONSISTENT_EARLY_DATA_SNI),
    "inconsistent early data sni"},
    {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INCONSISTENT_EXTMS), "inconsistent extms"},
    {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INVALID_ALERT), "invalid alert"},
    {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INVALID_COMMAND), "invalid command"},
+48 −4
Original line number Diff line number Diff line
@@ -682,13 +682,17 @@ EXT_RETURN tls_construct_ctos_early_data(SSL *s, WPACKET *pkt,
    const unsigned char *id;
    size_t idlen;
    SSL_SESSION *psksess = NULL;
    SSL_SESSION *edsess = NULL;
    const EVP_MD *handmd = NULL;

    if (s->hello_retry_request)
        handmd = ssl_handshake_md(s);

    if (s->psk_use_session_cb != NULL
            && !s->psk_use_session_cb(s, handmd, &id, &idlen, &psksess)) {
            && (!s->psk_use_session_cb(s, handmd, &id, &idlen, &psksess)
                || (psksess != NULL
                    && psksess->ssl_version != TLS1_3_VERSION))) {
        SSL_SESSION_free(psksess);
        SSLerr(SSL_F_TLS_CONSTRUCT_CTOS_EARLY_DATA, SSL_R_BAD_PSK);
        return EXT_RETURN_FAIL;
    }
@@ -711,9 +715,49 @@ EXT_RETURN tls_construct_ctos_early_data(SSL *s, WPACKET *pkt,
        s->max_early_data = 0;
        return EXT_RETURN_NOT_SENT;
    }
    s->max_early_data = s->session->ext.max_early_data != 0 ?
                        s->session->ext.max_early_data
                        : psksess->ext.max_early_data;
    edsess = s->session->ext.max_early_data != 0 ? s->session : psksess;
    s->max_early_data = edsess->ext.max_early_data;

    if ((s->ext.hostname == NULL && edsess->ext.hostname != NULL)
            || (s->ext.hostname != NULL
                && (edsess->ext.hostname == NULL
                    || strcmp(s->ext.hostname, edsess->ext.hostname) != 0))) {
        SSLerr(SSL_F_TLS_CONSTRUCT_CTOS_EARLY_DATA,
               SSL_R_INCONSISTENT_EARLY_DATA_SNI);
        return EXT_RETURN_FAIL;
    }

    if ((s->ext.alpn == NULL && edsess->ext.alpn_selected != NULL)) {
        SSLerr(SSL_F_TLS_CONSTRUCT_CTOS_EARLY_DATA,
               SSL_R_INCONSISTENT_EARLY_DATA_ALPN);
        return EXT_RETURN_FAIL;
    }

    /*
     * Verify that we are offering an ALPN protocol consistent with the early
     * data.
     */
    if (edsess->ext.alpn_selected != NULL) {
        PACKET prots, alpnpkt;
        int found = 0;

        if (!PACKET_buf_init(&prots, s->ext.alpn, s->ext.alpn_len)) {
            SSLerr(SSL_F_TLS_CONSTRUCT_CTOS_EARLY_DATA, ERR_R_INTERNAL_ERROR);
            return EXT_RETURN_FAIL;
        }
        while (PACKET_get_length_prefixed_1(&prots, &alpnpkt)) {
            if (PACKET_equal(&alpnpkt, edsess->ext.alpn_selected,
                             edsess->ext.alpn_selected_len)) {
                found = 1;
                break;
            }
        }
        if (!found) {
            SSLerr(SSL_F_TLS_CONSTRUCT_CTOS_EARLY_DATA,
                   SSL_R_INCONSISTENT_EARLY_DATA_ALPN);
            return EXT_RETURN_FAIL;
        }
    }

    if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_early_data)
            || !WPACKET_start_sub_packet_u16(pkt)