mirror of
https://github.com/openssl/openssl.git
synced 2024-11-27 05:21:51 +08:00
Convert SSLv3 code to use the new read side record layer
Reviewed-by: Hugo Landau <hlandau@openssl.org> Reviewed-by: Tomas Mraz <tomas@openssl.org> (Merged from https://github.com/openssl/openssl/pull/18132)
This commit is contained in:
parent
4840c2a5e6
commit
10560aed15
@ -101,6 +101,9 @@ struct ossl_record_layer_st
|
||||
/* uncompress */
|
||||
COMP_CTX *expand;
|
||||
|
||||
/* Only used by SSLv3 */
|
||||
unsigned char mac_secret[EVP_MAX_MD_SIZE];
|
||||
|
||||
/* Function pointers for version specific functions */
|
||||
/* Function pointers for version specific functions */
|
||||
struct record_functions_st *funcs;
|
||||
@ -206,6 +209,69 @@ static int tls_any_set_crypto_state(OSSL_RECORD_LAYER *rl, int level,
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* TODO(RECLAYER): Handle OPENSSL_NO_COMP */
|
||||
static int ssl3_set_crypto_state(OSSL_RECORD_LAYER *rl, int level,
|
||||
unsigned char *key, size_t keylen,
|
||||
unsigned char *iv, size_t ivlen,
|
||||
unsigned char *mackey, size_t mackeylen,
|
||||
const EVP_CIPHER *ciph,
|
||||
size_t taglen,
|
||||
/* TODO(RECLAYER): This probably should not be an int */
|
||||
int mactype,
|
||||
const EVP_MD *md,
|
||||
const SSL_COMP *comp,
|
||||
/* TODO(RECLAYER): Remove me */
|
||||
SSL_CONNECTION *s)
|
||||
{
|
||||
EVP_CIPHER_CTX *ciph_ctx;
|
||||
|
||||
if (md == NULL) {
|
||||
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((rl->enc_read_ctx = EVP_CIPHER_CTX_new()) == NULL) {
|
||||
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
ciph_ctx = rl->enc_read_ctx;
|
||||
|
||||
rl->read_hash = EVP_MD_CTX_new();
|
||||
if (rl->read_hash == NULL) {
|
||||
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
#ifndef OPENSSL_NO_COMP
|
||||
if (comp != NULL) {
|
||||
rl->expand = COMP_CTX_new(comp->method);
|
||||
if (rl->expand == NULL) {
|
||||
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR,
|
||||
SSL_R_COMPRESSION_LIBRARY_ERROR);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!EVP_DecryptInit_ex(ciph_ctx, ciph, NULL, key, iv)) {
|
||||
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (EVP_CIPHER_get0_provider(ciph) != NULL
|
||||
&& !tls_provider_set_tls_parameters(rl, ciph_ctx, ciph, md, s)) {
|
||||
/* RLAYERfatal already called */
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (mackeylen > sizeof(rl->mac_secret)) {
|
||||
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
memcpy(rl->mac_secret, mackey, mackeylen);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* TODO(RECLAYER): Handle OPENSSL_NO_COMP */
|
||||
static int tls1_set_crypto_state(OSSL_RECORD_LAYER *rl, int level,
|
||||
unsigned char *key, size_t keylen,
|
||||
@ -337,7 +403,7 @@ static int tls1_set_crypto_state(OSSL_RECORD_LAYER *rl, int level,
|
||||
}
|
||||
if (EVP_CIPHER_get0_provider(ciph) != NULL
|
||||
&& !tls_provider_set_tls_parameters(rl, ciph_ctx, ciph, md, s)) {
|
||||
/* SSLfatal already called */
|
||||
/* RLAYERfatal already called */
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -358,6 +424,125 @@ static int tls_any_cipher(OSSL_RECORD_LAYER *rl, SSL3_RECORD *recs, size_t n_rec
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*-
|
||||
* ssl3_enc encrypts/decrypts |n_recs| records in |inrecs|. Calls SSLfatal on
|
||||
* internal error, but not otherwise. It is the responsibility of the caller to
|
||||
* report a bad_record_mac
|
||||
*
|
||||
* Returns:
|
||||
* 0: if the record is publicly invalid, or an internal error
|
||||
* 1: Success or Mac-then-encrypt decryption failed (MAC will be randomised)
|
||||
*/
|
||||
static int ssl3_cipher(OSSL_RECORD_LAYER *rl, SSL3_RECORD *inrecs, size_t n_recs,
|
||||
int sending, SSL_MAC_BUF *mac, size_t macsize,
|
||||
/* TODO(RECLAYER): Remove me */ SSL_CONNECTION *s)
|
||||
{
|
||||
SSL3_RECORD *rec;
|
||||
EVP_CIPHER_CTX *ds;
|
||||
size_t l, i;
|
||||
size_t bs;
|
||||
const EVP_CIPHER *enc;
|
||||
int provided;
|
||||
|
||||
rec = inrecs;
|
||||
/*
|
||||
* We shouldn't ever be called with more than one record in the SSLv3 case
|
||||
*/
|
||||
if (n_recs != 1)
|
||||
return 0;
|
||||
if (sending) {
|
||||
ds = s->enc_write_ctx;
|
||||
if (s->enc_write_ctx == NULL)
|
||||
enc = NULL;
|
||||
else
|
||||
enc = EVP_CIPHER_CTX_get0_cipher(s->enc_write_ctx);
|
||||
} else {
|
||||
ds = rl->enc_read_ctx;
|
||||
if (rl->enc_read_ctx == NULL)
|
||||
enc = NULL;
|
||||
else
|
||||
enc = EVP_CIPHER_CTX_get0_cipher(rl->enc_read_ctx);
|
||||
}
|
||||
|
||||
provided = (EVP_CIPHER_get0_provider(enc) != NULL);
|
||||
|
||||
l = rec->length;
|
||||
bs = EVP_CIPHER_CTX_get_block_size(ds);
|
||||
|
||||
/* COMPRESS */
|
||||
|
||||
if ((bs != 1) && sending && !provided) {
|
||||
/*
|
||||
* We only do this for legacy ciphers. Provided ciphers add the
|
||||
* padding on the provider side.
|
||||
*/
|
||||
i = bs - (l % bs);
|
||||
|
||||
/* we need to add 'i-1' padding bytes */
|
||||
l += i;
|
||||
/*
|
||||
* the last of these zero bytes will be overwritten with the
|
||||
* padding length.
|
||||
*/
|
||||
memset(&rec->input[rec->length], 0, i);
|
||||
rec->length += i;
|
||||
rec->input[l - 1] = (unsigned char)(i - 1);
|
||||
}
|
||||
|
||||
if (!sending) {
|
||||
if (l == 0 || l % bs != 0) {
|
||||
/* Publicly invalid */
|
||||
return 0;
|
||||
}
|
||||
/* otherwise, rec->length >= bs */
|
||||
}
|
||||
|
||||
if (provided) {
|
||||
int outlen;
|
||||
|
||||
if (!EVP_CipherUpdate(ds, rec->data, &outlen, rec->input,
|
||||
(unsigned int)l))
|
||||
return 0;
|
||||
rec->length = outlen;
|
||||
|
||||
if (!sending && mac != NULL) {
|
||||
/* Now get a pointer to the MAC */
|
||||
OSSL_PARAM params[2], *p = params;
|
||||
|
||||
/* Get the MAC */
|
||||
mac->alloced = 0;
|
||||
|
||||
*p++ = OSSL_PARAM_construct_octet_ptr(OSSL_CIPHER_PARAM_TLS_MAC,
|
||||
(void **)&mac->mac,
|
||||
macsize);
|
||||
*p = OSSL_PARAM_construct_end();
|
||||
|
||||
if (!EVP_CIPHER_CTX_get_params(ds, params)) {
|
||||
/* Shouldn't normally happen */
|
||||
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (EVP_Cipher(ds, rec->data, rec->input, (unsigned int)l) < 1) {
|
||||
/* Shouldn't happen */
|
||||
RLAYERfatal(rl, SSL_AD_BAD_RECORD_MAC, ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!sending)
|
||||
return ssl3_cbc_remove_padding_and_mac(&rec->length,
|
||||
rec->orig_len,
|
||||
rec->data,
|
||||
(mac != NULL) ? &mac->mac : NULL,
|
||||
(mac != NULL) ? &mac->alloced : NULL,
|
||||
bs,
|
||||
macsize,
|
||||
rl->libctx);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define MAX_PADDING 256
|
||||
/*-
|
||||
@ -690,6 +875,125 @@ static int tls1_cipher(OSSL_RECORD_LAYER *rl, SSL3_RECORD *recs, size_t n_recs,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const unsigned char ssl3_pad_1[48] = {
|
||||
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
|
||||
};
|
||||
|
||||
static const unsigned char ssl3_pad_2[48] = {
|
||||
0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
|
||||
0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
|
||||
0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
|
||||
0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
|
||||
0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
|
||||
0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c
|
||||
};
|
||||
|
||||
static int ssl3_mac(OSSL_RECORD_LAYER *rl, SSL3_RECORD *rec, unsigned char *md,
|
||||
int sending, SSL_CONNECTION *ssl)
|
||||
{
|
||||
unsigned char *mac_sec, *seq;
|
||||
const EVP_MD_CTX *hash;
|
||||
unsigned char *p, rec_char;
|
||||
size_t md_size;
|
||||
size_t npad;
|
||||
int t;
|
||||
|
||||
if (sending) {
|
||||
mac_sec = &(ssl->s3.write_mac_secret[0]);
|
||||
seq = RECORD_LAYER_get_write_sequence(&ssl->rlayer);
|
||||
hash = ssl->write_hash;
|
||||
} else {
|
||||
mac_sec = &(rl->mac_secret[0]);
|
||||
seq = RECORD_LAYER_get_read_sequence(&ssl->rlayer);
|
||||
hash = rl->read_hash;
|
||||
}
|
||||
|
||||
t = EVP_MD_CTX_get_size(hash);
|
||||
if (t < 0)
|
||||
return 0;
|
||||
md_size = t;
|
||||
npad = (48 / md_size) * md_size;
|
||||
|
||||
if (!sending
|
||||
&& EVP_CIPHER_CTX_get_mode(rl->enc_read_ctx) == EVP_CIPH_CBC_MODE
|
||||
&& ssl3_cbc_record_digest_supported(hash)) {
|
||||
#ifdef OPENSSL_NO_DEPRECATED_3_0
|
||||
return 0;
|
||||
#else
|
||||
/*
|
||||
* This is a CBC-encrypted record. We must avoid leaking any
|
||||
* timing-side channel information about how many blocks of data we
|
||||
* are hashing because that gives an attacker a timing-oracle.
|
||||
*/
|
||||
|
||||
/*-
|
||||
* npad is, at most, 48 bytes and that's with MD5:
|
||||
* 16 + 48 + 8 (sequence bytes) + 1 + 2 = 75.
|
||||
*
|
||||
* With SHA-1 (the largest hash speced for SSLv3) the hash size
|
||||
* goes up 4, but npad goes down by 8, resulting in a smaller
|
||||
* total size.
|
||||
*/
|
||||
unsigned char header[75];
|
||||
size_t j = 0;
|
||||
memcpy(header + j, mac_sec, md_size);
|
||||
j += md_size;
|
||||
memcpy(header + j, ssl3_pad_1, npad);
|
||||
j += npad;
|
||||
memcpy(header + j, seq, 8);
|
||||
j += 8;
|
||||
header[j++] = rec->type;
|
||||
header[j++] = (unsigned char)(rec->length >> 8);
|
||||
header[j++] = (unsigned char)(rec->length & 0xff);
|
||||
|
||||
/* Final param == is SSLv3 */
|
||||
if (ssl3_cbc_digest_record(EVP_MD_CTX_get0_md(hash),
|
||||
md, &md_size,
|
||||
header, rec->input,
|
||||
rec->length, rec->orig_len,
|
||||
mac_sec, md_size, 1) <= 0)
|
||||
return 0;
|
||||
#endif
|
||||
} else {
|
||||
unsigned int md_size_u;
|
||||
/* Chop the digest off the end :-) */
|
||||
EVP_MD_CTX *md_ctx = EVP_MD_CTX_new();
|
||||
|
||||
if (md_ctx == NULL)
|
||||
return 0;
|
||||
|
||||
rec_char = rec->type;
|
||||
p = md;
|
||||
s2n(rec->length, p);
|
||||
if (EVP_MD_CTX_copy_ex(md_ctx, hash) <= 0
|
||||
|| EVP_DigestUpdate(md_ctx, mac_sec, md_size) <= 0
|
||||
|| EVP_DigestUpdate(md_ctx, ssl3_pad_1, npad) <= 0
|
||||
|| EVP_DigestUpdate(md_ctx, seq, 8) <= 0
|
||||
|| EVP_DigestUpdate(md_ctx, &rec_char, 1) <= 0
|
||||
|| EVP_DigestUpdate(md_ctx, md, 2) <= 0
|
||||
|| EVP_DigestUpdate(md_ctx, rec->input, rec->length) <= 0
|
||||
|| EVP_DigestFinal_ex(md_ctx, md, NULL) <= 0
|
||||
|| EVP_MD_CTX_copy_ex(md_ctx, hash) <= 0
|
||||
|| EVP_DigestUpdate(md_ctx, mac_sec, md_size) <= 0
|
||||
|| EVP_DigestUpdate(md_ctx, ssl3_pad_2, npad) <= 0
|
||||
|| EVP_DigestUpdate(md_ctx, md, md_size) <= 0
|
||||
|| EVP_DigestFinal_ex(md_ctx, md, &md_size_u) <= 0) {
|
||||
EVP_MD_CTX_free(md_ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
EVP_MD_CTX_free(md_ctx);
|
||||
}
|
||||
|
||||
ssl3_record_sequence_update(seq);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int tls1_mac(OSSL_RECORD_LAYER *rl, SSL3_RECORD *rec, unsigned char *md,
|
||||
int sending, SSL_CONNECTION *ssl)
|
||||
{
|
||||
@ -830,9 +1134,9 @@ struct record_functions_st tls_1_0_funcs = {
|
||||
};
|
||||
|
||||
struct record_functions_st ssl_3_0_funcs = {
|
||||
tls_fail_set_crypto_state,
|
||||
NULL,
|
||||
NULL
|
||||
ssl3_set_crypto_state,
|
||||
ssl3_cipher,
|
||||
ssl3_mac
|
||||
};
|
||||
|
||||
static int tls_set1_bio(OSSL_RECORD_LAYER *rl, BIO *bio);
|
||||
|
181
ssl/s3_enc.c
181
ssl/s3_enc.c
@ -90,128 +90,55 @@ static int ssl3_generate_key_block(SSL_CONNECTION *s, unsigned char *km, int num
|
||||
int ssl3_change_cipher_state(SSL_CONNECTION *s, int which)
|
||||
{
|
||||
unsigned char *p, *mac_secret;
|
||||
unsigned char *ms, *key, *iv;
|
||||
size_t md_len;
|
||||
unsigned char *key, *iv;
|
||||
EVP_CIPHER_CTX *dd;
|
||||
const EVP_CIPHER *c;
|
||||
const EVP_CIPHER *ciph;
|
||||
#ifndef OPENSSL_NO_COMP
|
||||
COMP_METHOD *comp;
|
||||
const SSL_COMP *comp;
|
||||
#endif
|
||||
const EVP_MD *m;
|
||||
const EVP_MD *md;
|
||||
int mdi;
|
||||
size_t n, i, j, k, cl;
|
||||
size_t n, iv_len, key_len;
|
||||
int reuse_dd = 0;
|
||||
SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s);
|
||||
|
||||
c = s->s3.tmp.new_sym_enc;
|
||||
m = s->s3.tmp.new_hash;
|
||||
ciph = s->s3.tmp.new_sym_enc;
|
||||
md = s->s3.tmp.new_hash;
|
||||
/* m == NULL will lead to a crash later */
|
||||
if (!ossl_assert(m != NULL)) {
|
||||
if (!ossl_assert(md != NULL)) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
#ifndef OPENSSL_NO_COMP
|
||||
if (s->s3.tmp.new_compression == NULL)
|
||||
comp = NULL;
|
||||
else
|
||||
comp = s->s3.tmp.new_compression->method;
|
||||
comp = s->s3.tmp.new_compression;
|
||||
#endif
|
||||
|
||||
if (which & SSL3_CC_READ) {
|
||||
if (s->enc_read_ctx != NULL) {
|
||||
reuse_dd = 1;
|
||||
} else if ((s->enc_read_ctx = EVP_CIPHER_CTX_new()) == NULL) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
} else {
|
||||
/*
|
||||
* make sure it's initialised in case we exit later with an error
|
||||
*/
|
||||
EVP_CIPHER_CTX_reset(s->enc_read_ctx);
|
||||
}
|
||||
dd = s->enc_read_ctx;
|
||||
|
||||
if (ssl_replace_hash(&s->read_hash, m) == NULL) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
#ifndef OPENSSL_NO_COMP
|
||||
/* COMPRESS */
|
||||
COMP_CTX_free(s->expand);
|
||||
s->expand = NULL;
|
||||
if (comp != NULL) {
|
||||
s->expand = COMP_CTX_new(comp);
|
||||
if (s->expand == NULL) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR,
|
||||
SSL_R_COMPRESSION_LIBRARY_ERROR);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
RECORD_LAYER_reset_read_sequence(&s->rlayer);
|
||||
mac_secret = &(s->s3.read_mac_secret[0]);
|
||||
} else {
|
||||
s->statem.enc_write_state = ENC_WRITE_STATE_INVALID;
|
||||
if (s->enc_write_ctx != NULL) {
|
||||
reuse_dd = 1;
|
||||
} else if ((s->enc_write_ctx = EVP_CIPHER_CTX_new()) == NULL) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
} else {
|
||||
/*
|
||||
* make sure it's initialised in case we exit later with an error
|
||||
*/
|
||||
EVP_CIPHER_CTX_reset(s->enc_write_ctx);
|
||||
}
|
||||
dd = s->enc_write_ctx;
|
||||
if (ssl_replace_hash(&s->write_hash, m) == NULL) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
#ifndef OPENSSL_NO_COMP
|
||||
/* COMPRESS */
|
||||
COMP_CTX_free(s->compress);
|
||||
s->compress = NULL;
|
||||
if (comp != NULL) {
|
||||
s->compress = COMP_CTX_new(comp);
|
||||
if (s->compress == NULL) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR,
|
||||
SSL_R_COMPRESSION_LIBRARY_ERROR);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
RECORD_LAYER_reset_write_sequence(&s->rlayer);
|
||||
mac_secret = &(s->s3.write_mac_secret[0]);
|
||||
}
|
||||
|
||||
if (reuse_dd)
|
||||
EVP_CIPHER_CTX_reset(dd);
|
||||
|
||||
p = s->s3.tmp.key_block;
|
||||
mdi = EVP_MD_get_size(m);
|
||||
mdi = EVP_MD_get_size(md);
|
||||
if (mdi < 0) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
i = mdi;
|
||||
cl = EVP_CIPHER_get_key_length(c);
|
||||
j = cl;
|
||||
k = EVP_CIPHER_get_iv_length(c);
|
||||
md_len = (size_t)mdi;
|
||||
key_len = EVP_CIPHER_get_key_length(ciph);
|
||||
iv_len = EVP_CIPHER_get_iv_length(ciph);
|
||||
if ((which == SSL3_CHANGE_CIPHER_CLIENT_WRITE) ||
|
||||
(which == SSL3_CHANGE_CIPHER_SERVER_READ)) {
|
||||
ms = &(p[0]);
|
||||
n = i + i;
|
||||
mac_secret = &(p[0]);
|
||||
n = md_len + md_len;
|
||||
key = &(p[n]);
|
||||
n += j + j;
|
||||
n += key_len + key_len;
|
||||
iv = &(p[n]);
|
||||
n += k + k;
|
||||
n += iv_len + iv_len;
|
||||
} else {
|
||||
n = i;
|
||||
ms = &(p[n]);
|
||||
n += i + j;
|
||||
n = md_len;
|
||||
mac_secret = &(p[n]);
|
||||
n += md_len + key_len;
|
||||
key = &(p[n]);
|
||||
n += j + k;
|
||||
n += key_len + iv_len;
|
||||
iv = &(p[n]);
|
||||
n += k;
|
||||
n += iv_len;
|
||||
}
|
||||
|
||||
if (n > s->s3.tmp.key_block_length) {
|
||||
@ -219,15 +146,67 @@ int ssl3_change_cipher_state(SSL_CONNECTION *s, int which)
|
||||
goto err;
|
||||
}
|
||||
|
||||
memcpy(mac_secret, ms, i);
|
||||
if (which & SSL3_CC_READ) {
|
||||
s->rrlmethod->free(s->rrl);
|
||||
s->rrl = s->rrlmethod->new_record_layer(sctx->libctx,
|
||||
sctx->propq,
|
||||
SSL3_VERSION, s->server,
|
||||
OSSL_RECORD_DIRECTION_READ,
|
||||
OSSL_RECORD_PROTECTION_LEVEL_APPLICATION,
|
||||
key, key_len, iv, iv_len,
|
||||
mac_secret, md_len, ciph, 0,
|
||||
NID_undef, md, comp, s->rbio,
|
||||
NULL, NULL, NULL, NULL, s);
|
||||
if (s->rrl == NULL) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!EVP_CipherInit_ex(dd, c, NULL, key, iv, (which & SSL3_CC_WRITE))) {
|
||||
s->statem.enc_write_state = ENC_WRITE_STATE_VALID;
|
||||
return 1;
|
||||
}
|
||||
|
||||
s->statem.enc_write_state = ENC_WRITE_STATE_INVALID;
|
||||
if (s->enc_write_ctx != NULL) {
|
||||
reuse_dd = 1;
|
||||
} else if ((s->enc_write_ctx = EVP_CIPHER_CTX_new()) == NULL) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
} else {
|
||||
/* make sure it's initialised in case we exit later with an error */
|
||||
EVP_CIPHER_CTX_reset(s->enc_write_ctx);
|
||||
}
|
||||
dd = s->enc_write_ctx;
|
||||
if (ssl_replace_hash(&s->write_hash, md) == NULL) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
#ifndef OPENSSL_NO_COMP
|
||||
/* COMPRESS */
|
||||
COMP_CTX_free(s->compress);
|
||||
s->compress = NULL;
|
||||
if (comp != NULL) {
|
||||
s->compress = COMP_CTX_new(comp->method);
|
||||
if (s->compress == NULL) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR,
|
||||
SSL_R_COMPRESSION_LIBRARY_ERROR);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
RECORD_LAYER_reset_write_sequence(&s->rlayer);
|
||||
memcpy(&(s->s3.write_mac_secret[0]), mac_secret, md_len);
|
||||
|
||||
if (reuse_dd)
|
||||
EVP_CIPHER_CTX_reset(dd);
|
||||
|
||||
if (!EVP_CipherInit_ex(dd, ciph, NULL, key, iv, (which & SSL3_CC_WRITE))) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (EVP_CIPHER_get0_provider(c) != NULL
|
||||
&& !tls_provider_set_tls_params(s, dd, c, m)) {
|
||||
if (EVP_CIPHER_get0_provider(ciph) != NULL
|
||||
&& !tls_provider_set_tls_params(s, dd, ciph, md)) {
|
||||
/* SSLfatal already called */
|
||||
goto err;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user