int s2n_record_parse()

in tls/s2n_record_read.c [166:224]


int s2n_record_parse(struct s2n_connection *conn)
{
    uint8_t content_type = 0;
    uint16_t encrypted_length = 0;
    POSIX_GUARD(s2n_record_header_parse(conn, &content_type, &encrypted_length));

    struct s2n_crypto_parameters *current_client_crypto = conn->client;
    struct s2n_crypto_parameters *current_server_crypto = conn->server;
    if (s2n_is_tls13_plaintext_content(conn, content_type)) {
        POSIX_ENSURE_REF(conn->initial);
        conn->client = conn->initial;
        conn->server = conn->initial;
    }

    const struct s2n_cipher_suite *cipher_suite = conn->client->cipher_suite;
    uint8_t *implicit_iv = conn->client->client_implicit_iv;
    struct s2n_hmac_state *mac = &conn->client->client_record_mac;
    uint8_t *sequence_number = conn->client->client_sequence_number;
    struct s2n_session_key *session_key = &conn->client->client_key;

    if (conn->mode == S2N_CLIENT) {
        cipher_suite = conn->server->cipher_suite;
        implicit_iv = conn->server->server_implicit_iv;
        mac = &conn->server->server_record_mac;
        sequence_number = conn->server->server_sequence_number;
        session_key = &conn->server->server_key;
    }

    if (s2n_is_tls13_plaintext_content(conn, content_type)) {
        conn->client = current_client_crypto;
        conn->server = current_server_crypto;
    }

    /* The NULL stream cipher MUST NEVER be used for ApplicationData.
     * If ApplicationData is unencrypted, we can't trust it. */
    if (cipher_suite->record_alg->cipher == &s2n_null_cipher) {
        POSIX_ENSURE(content_type != TLS_APPLICATION_DATA, S2N_ERR_DECRYPT);
    }

    switch (cipher_suite->record_alg->cipher->type) {
        case S2N_AEAD:
            POSIX_GUARD(s2n_record_parse_aead(cipher_suite, conn, content_type, encrypted_length, implicit_iv, mac, sequence_number, session_key));
            break;
        case S2N_CBC:
            POSIX_GUARD(s2n_record_parse_cbc(cipher_suite, conn, content_type, encrypted_length, implicit_iv, mac, sequence_number, session_key));
            break;
        case S2N_COMPOSITE:
            POSIX_GUARD(s2n_record_parse_composite(cipher_suite, conn, content_type, encrypted_length, implicit_iv, mac, sequence_number, session_key));
            break;
        case S2N_STREAM:
            POSIX_GUARD(s2n_record_parse_stream(cipher_suite, conn, content_type, encrypted_length, implicit_iv, mac, sequence_number, session_key));
            break;
        default:
            POSIX_BAIL(S2N_ERR_CIPHER_TYPE);
            break;
    }

    return 0;
}