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

Fix changing of the cipher state when dealing with early data

parent 1ea4d09a
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -1657,6 +1657,7 @@ int ssl_end_of_early_data_seen(SSL *s)
{
    if (s->early_data_state == SSL_EARLY_DATA_READING) {
        s->early_data_state = SSL_EARLY_DATA_FINISHED_READING;
        ossl_statem_finish_early_data(s);
        return 1;
    }

+1 −0
Original line number Diff line number Diff line
@@ -1027,6 +1027,7 @@ struct ssl_st {
    unsigned char client_finished_secret[EVP_MAX_MD_SIZE];
    unsigned char server_finished_secret[EVP_MAX_MD_SIZE];
    unsigned char server_finished_hash[EVP_MAX_MD_SIZE];
    unsigned char handshake_traffic_hash[EVP_MAX_MD_SIZE];
    unsigned char client_app_traffic_secret[EVP_MAX_MD_SIZE];
    unsigned char server_app_traffic_secret[EVP_MAX_MD_SIZE];
    EVP_CIPHER_CTX *enc_read_ctx; /* cryptographic state */
+1 −0
Original line number Diff line number Diff line
@@ -129,3 +129,4 @@ __owur int ossl_statem_app_data_allowed(SSL *s);
void ossl_statem_set_sctp_read_sock(SSL *s, int read_sock);
__owur int ossl_statem_in_sctp_read_sock(SSL *s);
#endif
int ossl_statem_finish_early_data(SSL *s);
+15 −3
Original line number Diff line number Diff line
@@ -787,8 +787,11 @@ WORK_STATE ossl_statem_server_post_work(SSL *s, WORK_STATE wst)
        if (SSL_IS_TLS13(s)) {
            if (!s->method->ssl3_enc->setup_key_block(s)
                || !s->method->ssl3_enc->change_cipher_state(s,
                        SSL3_CC_HANDSHAKE | SSL3_CHANGE_CIPHER_SERVER_WRITE)
                || !s->method->ssl3_enc->change_cipher_state(s,
                        SSL3_CC_HANDSHAKE | SSL3_CHANGE_CIPHER_SERVER_WRITE))
                return WORK_ERROR;

            if (s->ext.early_data != SSL_EARLY_DATA_ACCEPTED
                && !s->method->ssl3_enc->change_cipher_state(s,
                        SSL3_CC_HANDSHAKE |SSL3_CHANGE_CIPHER_SERVER_READ))
                return WORK_ERROR;
        }
@@ -1104,6 +1107,15 @@ WORK_STATE ossl_statem_server_post_process_message(SSL *s, WORK_STATE wst)
    return WORK_FINISHED_CONTINUE;
}

int ossl_statem_finish_early_data(SSL *s)
{
    if (!s->method->ssl3_enc->change_cipher_state(s,
                SSL3_CC_HANDSHAKE | SSL3_CHANGE_CIPHER_SERVER_READ))
        return 0;

    return 1;
}

#ifndef OPENSSL_NO_SRP
static int ssl_check_srp_ext_ClientHello(SSL *s, int *al)
{
+13 −0
Original line number Diff line number Diff line
@@ -422,6 +422,16 @@ int tls13_change_cipher_state(SSL *s, int which)
            label = client_handshake_traffic;
            labellen = sizeof(client_handshake_traffic) - 1;
            log_label = CLIENT_HANDSHAKE_LABEL;
            /*
             * The hanshake hash used for the server read handshake traffic
             * secret is the same as the hash for the server write handshake
             * traffic secret. However, if we processed early data then we delay
             * changing the server read cipher state until later, and the
             * handshake hashes have moved on. Therefore we use the value saved
             * earlier when we did the server write change cipher state.
             */
            if (s->server)
                hash = s->handshake_traffic_hash;
        } else {
            insecret = s->master_secret;
            label = client_application_traffic;
@@ -469,6 +479,9 @@ int tls13_change_cipher_state(SSL *s, int which)
    if (label == server_application_traffic)
        memcpy(s->server_finished_hash, hashval, hashlen);

    if (s->server && label == server_handshake_traffic)
        memcpy(s->handshake_traffic_hash, hashval, hashlen);

    if (label == client_application_traffic) {
        /*
         * We also create the resumption master secret, but this time use the