mirror of
https://github.com/openssl/openssl.git
synced 2025-04-12 20:30:52 +08:00
Distinguish between fatal and non-fatal errors when creating a 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
cc110a0aae
commit
7c2939999f
@ -30,18 +30,22 @@ static int ktls_set_crypto_state(OSSL_RECORD_LAYER *rl, int level,
|
||||
void *rl_sequence;
|
||||
ktls_crypto_info_t crypto_info;
|
||||
|
||||
/* Check if we are suitable for KTLS */
|
||||
/*
|
||||
* Check if we are suitable for KTLS. If not suitable we return
|
||||
* OSSL_RECORD_RETURN_NON_FATAL_ERR so that other record layers can be tried
|
||||
* instead
|
||||
*/
|
||||
|
||||
if (comp != NULL)
|
||||
return 0;
|
||||
return OSSL_RECORD_RETURN_NON_FATAL_ERR;
|
||||
|
||||
/* ktls supports only the maximum fragment size */
|
||||
if (ssl_get_max_send_fragment(s) != SSL3_RT_MAX_PLAIN_LENGTH)
|
||||
return 0;
|
||||
return OSSL_RECORD_RETURN_NON_FATAL_ERR;
|
||||
|
||||
/* check that cipher is supported */
|
||||
if (!ktls_check_supported_cipher(s, ciph, taglen))
|
||||
return 0;
|
||||
return OSSL_RECORD_RETURN_NON_FATAL_ERR;
|
||||
|
||||
/*
|
||||
* TODO(RECLAYER): For the write side we need to add a check for
|
||||
@ -51,7 +55,7 @@ static int ktls_set_crypto_state(OSSL_RECORD_LAYER *rl, int level,
|
||||
/* All future data will get encrypted by ktls. Flush the BIO or skip ktls */
|
||||
if (rl->direction == OSSL_RECORD_DIRECTION_WRITE) {
|
||||
if (BIO_flush(rl->bio) <= 0)
|
||||
return 0;
|
||||
return OSSL_RECORD_RETURN_NON_FATAL_ERR;
|
||||
}
|
||||
|
||||
if (rl->direction == OSSL_RECORD_DIRECTION_WRITE)
|
||||
@ -62,12 +66,12 @@ static int ktls_set_crypto_state(OSSL_RECORD_LAYER *rl, int level,
|
||||
if (!ktls_configure_crypto(s, ciph, rl_sequence, &crypto_info,
|
||||
rl->direction == OSSL_RECORD_DIRECTION_WRITE,
|
||||
iv, ivlen, key, keylen, mackey, mackeylen))
|
||||
return 0;
|
||||
return OSSL_RECORD_RETURN_NON_FATAL_ERR;
|
||||
|
||||
if (!BIO_set_ktls(rl->bio, &crypto_info, rl->direction))
|
||||
return 0;
|
||||
return OSSL_RECORD_RETURN_NON_FATAL_ERR;
|
||||
|
||||
return 1;
|
||||
return OSSL_RECORD_RETURN_SUCCESS;
|
||||
}
|
||||
|
||||
static int ktls_cipher(OSSL_RECORD_LAYER *rl, SSL3_RECORD *inrecs, size_t n_recs,
|
||||
|
@ -16,6 +16,11 @@
|
||||
/* Protocol version specific function pointers */
|
||||
struct record_functions_st
|
||||
{
|
||||
/*
|
||||
* Returns either OSSL_RECORD_RETURN_SUCCESS, OSSL_RECORD_RETURN_FATAL or
|
||||
* OSSL_RECORD_RETURN_NON_FATAL_ERR if we can keep trying to find an
|
||||
* alternative record layer.
|
||||
*/
|
||||
int (*set_crypto_state)(OSSL_RECORD_LAYER *rl, int level,
|
||||
unsigned char *key, size_t keylen,
|
||||
unsigned char *iv, size_t ivlen,
|
||||
@ -28,9 +33,16 @@ struct record_functions_st
|
||||
const SSL_COMP *comp,
|
||||
/* TODO(RECLAYER): Remove me */
|
||||
SSL_CONNECTION *s);
|
||||
/*
|
||||
* Returns:
|
||||
* 0: if the record is publicly invalid, or an internal error, or AEAD
|
||||
* decryption failed, or EtM decryption failed.
|
||||
* 1: Success or MtE decryption failed (MAC will be randomised)
|
||||
*/
|
||||
int (*cipher)(OSSL_RECORD_LAYER *rl, SSL3_RECORD *recs, size_t n_recs,
|
||||
int sending, SSL_MAC_BUF *macs, size_t macsize,
|
||||
/* TODO(RECLAYER): Remove me */ SSL_CONNECTION *s);
|
||||
/* Returns 1 for success or 0 for error */
|
||||
int (*mac)(OSSL_RECORD_LAYER *rl, SSL3_RECORD *rec, unsigned char *md,
|
||||
int sending, /* TODO(RECLAYER): Remove me */SSL_CONNECTION *ssl);
|
||||
};
|
||||
|
@ -30,50 +30,48 @@ static int ssl3_set_crypto_state(OSSL_RECORD_LAYER *rl, int level,
|
||||
EVP_CIPHER_CTX *ciph_ctx;
|
||||
|
||||
if (md == NULL) {
|
||||
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR);
|
||||
return OSSL_RECORD_RETURN_FATAL;
|
||||
}
|
||||
|
||||
if ((rl->enc_read_ctx = EVP_CIPHER_CTX_new()) == NULL) {
|
||||
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR);
|
||||
return OSSL_RECORD_RETURN_FATAL;
|
||||
}
|
||||
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;
|
||||
ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR);
|
||||
return OSSL_RECORD_RETURN_FATAL;
|
||||
}
|
||||
#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;
|
||||
ERR_raise(ERR_LIB_SSL, SSL_R_COMPRESSION_LIBRARY_ERROR);
|
||||
return OSSL_RECORD_RETURN_FATAL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!EVP_DecryptInit_ex(ciph_ctx, ciph, NULL, key, iv)) {
|
||||
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR);
|
||||
return OSSL_RECORD_RETURN_FATAL;
|
||||
}
|
||||
|
||||
if (EVP_CIPHER_get0_provider(ciph) != NULL
|
||||
&& !ossl_set_tls_provider_parameters(rl, ciph_ctx, ciph, md, s)) {
|
||||
/* RLAYERfatal already called */
|
||||
return 0;
|
||||
return OSSL_RECORD_RETURN_FATAL;
|
||||
}
|
||||
|
||||
if (mackeylen > sizeof(rl->mac_secret)) {
|
||||
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR);
|
||||
return OSSL_RECORD_RETURN_FATAL;
|
||||
}
|
||||
memcpy(rl->mac_secret, mackey, mackeylen);
|
||||
|
||||
return 1;
|
||||
return OSSL_RECORD_RETURN_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -30,15 +30,15 @@ static int tls13_set_crypto_state(OSSL_RECORD_LAYER *rl, int level,
|
||||
int mode;
|
||||
|
||||
if (ivlen > sizeof(rl->iv)) {
|
||||
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR);
|
||||
return OSSL_RECORD_RETURN_FATAL;
|
||||
}
|
||||
memcpy(rl->iv, iv, ivlen);
|
||||
|
||||
ciph_ctx = rl->enc_read_ctx = EVP_CIPHER_CTX_new();
|
||||
if (ciph_ctx == NULL) {
|
||||
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR);
|
||||
return OSSL_RECORD_RETURN_FATAL;
|
||||
}
|
||||
|
||||
RECORD_LAYER_reset_read_sequence(&s->rlayer);
|
||||
@ -51,11 +51,11 @@ static int tls13_set_crypto_state(OSSL_RECORD_LAYER *rl, int level,
|
||||
|| (mode == EVP_CIPH_CCM_MODE
|
||||
&& EVP_CIPHER_CTX_ctrl(ciph_ctx, EVP_CTRL_AEAD_SET_TAG, taglen, NULL) <= 0)
|
||||
|| EVP_DecryptInit_ex(ciph_ctx, NULL, NULL, key, NULL) <= 0) {
|
||||
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB);
|
||||
return 0;
|
||||
ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR);
|
||||
return OSSL_RECORD_RETURN_FATAL;
|
||||
}
|
||||
|
||||
return 1;
|
||||
return OSSL_RECORD_RETURN_SUCCESS;
|
||||
}
|
||||
|
||||
static int tls13_cipher(OSSL_RECORD_LAYER *rl, SSL3_RECORD *recs, size_t n_recs,
|
||||
|
@ -32,7 +32,7 @@ static int tls1_set_crypto_state(OSSL_RECORD_LAYER *rl, int level,
|
||||
EVP_PKEY *mac_key;
|
||||
|
||||
if (level != OSSL_RECORD_PROTECTION_LEVEL_APPLICATION)
|
||||
return 0;
|
||||
return OSSL_RECORD_RETURN_FATAL;
|
||||
|
||||
if (s->ext.use_etm)
|
||||
s->s3.flags |= TLS1_FLAGS_ENCRYPT_THEN_MAC_READ;
|
||||
@ -51,7 +51,7 @@ static int tls1_set_crypto_state(OSSL_RECORD_LAYER *rl, int level,
|
||||
|
||||
if ((rl->enc_read_ctx = EVP_CIPHER_CTX_new()) == NULL) {
|
||||
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
return OSSL_RECORD_RETURN_FATAL;
|
||||
}
|
||||
|
||||
ciph_ctx = rl->enc_read_ctx;
|
||||
@ -59,15 +59,14 @@ static int tls1_set_crypto_state(OSSL_RECORD_LAYER *rl, int level,
|
||||
rl->read_hash = EVP_MD_CTX_new();
|
||||
if (rl->read_hash == NULL) {
|
||||
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
return OSSL_RECORD_RETURN_FATAL;
|
||||
}
|
||||
#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;
|
||||
ERR_raise(ERR_LIB_SSL, SSL_R_COMPRESSION_LIBRARY_ERROR);
|
||||
return OSSL_RECORD_RETURN_FATAL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -100,8 +99,8 @@ static int tls1_set_crypto_state(OSSL_RECORD_LAYER *rl, int level,
|
||||
rl->libctx, rl->propq, mac_key,
|
||||
NULL) <= 0) {
|
||||
EVP_PKEY_free(mac_key);
|
||||
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR);
|
||||
return OSSL_RECORD_RETURN_FATAL;
|
||||
}
|
||||
EVP_PKEY_free(mac_key);
|
||||
}
|
||||
@ -109,9 +108,9 @@ static int tls1_set_crypto_state(OSSL_RECORD_LAYER *rl, int level,
|
||||
if (EVP_CIPHER_get_mode(ciph) == EVP_CIPH_GCM_MODE) {
|
||||
if (!EVP_DecryptInit_ex(ciph_ctx, ciph, NULL, key, NULL)
|
||||
|| EVP_CIPHER_CTX_ctrl(ciph_ctx, EVP_CTRL_GCM_SET_IV_FIXED,
|
||||
(int)ivlen, iv) <= 0) {
|
||||
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
(int)ivlen, iv) <= 0) {
|
||||
ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR);
|
||||
return OSSL_RECORD_RETURN_FATAL;
|
||||
}
|
||||
} else if (EVP_CIPHER_get_mode(ciph) == EVP_CIPH_CCM_MODE) {
|
||||
if (!EVP_DecryptInit_ex(ciph_ctx, ciph, NULL, NULL, NULL)
|
||||
@ -126,13 +125,13 @@ static int tls1_set_crypto_state(OSSL_RECORD_LAYER *rl, int level,
|
||||
* why not in the initial EVP_DecryptInit_ex() call?
|
||||
*/
|
||||
|| !EVP_DecryptInit_ex(ciph_ctx, NULL, NULL, key, NULL)) {
|
||||
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR);
|
||||
return OSSL_RECORD_RETURN_FATAL;
|
||||
}
|
||||
} else {
|
||||
if (!EVP_DecryptInit_ex(ciph_ctx, ciph, NULL, key, iv)) {
|
||||
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR);
|
||||
return OSSL_RECORD_RETURN_FATAL;
|
||||
}
|
||||
}
|
||||
/* Needed for "composite" AEADs, such as RC4-HMAC-MD5 */
|
||||
@ -140,16 +139,14 @@ static int tls1_set_crypto_state(OSSL_RECORD_LAYER *rl, int level,
|
||||
&& mackeylen != 0
|
||||
&& EVP_CIPHER_CTX_ctrl(ciph_ctx, EVP_CTRL_AEAD_SET_MAC_KEY,
|
||||
(int)mackeylen, mackey) <= 0) {
|
||||
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR);
|
||||
return OSSL_RECORD_RETURN_FATAL;
|
||||
}
|
||||
if (EVP_CIPHER_get0_provider(ciph) != NULL
|
||||
&& !ossl_set_tls_provider_parameters(rl, ciph_ctx, ciph, md, s)) {
|
||||
/* RLAYERfatal already called */
|
||||
return 0;
|
||||
}
|
||||
&& !ossl_set_tls_provider_parameters(rl, ciph_ctx, ciph, md, s))
|
||||
return OSSL_RECORD_RETURN_FATAL;
|
||||
|
||||
return 1;
|
||||
return OSSL_RECORD_RETURN_SUCCESS;
|
||||
}
|
||||
|
||||
#define MAX_PADDING 256
|
||||
|
@ -63,7 +63,7 @@ int ossl_set_tls_provider_parameters(OSSL_RECORD_LAYER *rl,
|
||||
*pprm = OSSL_PARAM_construct_end();
|
||||
|
||||
if (!EVP_CIPHER_CTX_set_params(ctx, params)) {
|
||||
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
|
||||
ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1102,7 +1102,7 @@ static int tls_release_record(OSSL_RECORD_LAYER *rl, void *rechandle)
|
||||
return OSSL_RECORD_RETURN_SUCCESS;
|
||||
}
|
||||
|
||||
static OSSL_RECORD_LAYER *
|
||||
static int
|
||||
tls_int_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers,
|
||||
int role, int direction, int level, unsigned char *key,
|
||||
size_t keylen, unsigned char *iv, size_t ivlen,
|
||||
@ -1113,15 +1113,18 @@ tls_int_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers,
|
||||
const EVP_MD *md, const SSL_COMP *comp, BIO *transport,
|
||||
BIO_ADDR *local, BIO_ADDR *peer,
|
||||
const OSSL_PARAM *settings, const OSSL_PARAM *options,
|
||||
OSSL_RECORD_LAYER **retrl,
|
||||
/* TODO(RECLAYER): Remove me */
|
||||
SSL_CONNECTION *s)
|
||||
{
|
||||
OSSL_RECORD_LAYER *rl = OPENSSL_zalloc(sizeof(*rl));
|
||||
const OSSL_PARAM *p;
|
||||
|
||||
*retrl = NULL;
|
||||
|
||||
if (rl == NULL) {
|
||||
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
return OSSL_RECORD_RETURN_FATAL;
|
||||
}
|
||||
|
||||
if (transport != NULL && !BIO_up_ref(transport)) {
|
||||
@ -1176,13 +1179,14 @@ tls_int_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers,
|
||||
if (!tls_set1_bio(rl, transport))
|
||||
goto err;
|
||||
|
||||
return rl;
|
||||
*retrl = rl;
|
||||
return OSSL_RECORD_RETURN_SUCCESS;
|
||||
err:
|
||||
OPENSSL_free(rl);
|
||||
return NULL;
|
||||
return OSSL_RECORD_RETURN_FATAL;
|
||||
}
|
||||
|
||||
static OSSL_RECORD_LAYER *
|
||||
static int
|
||||
tls_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers,
|
||||
int role, int direction, int level, unsigned char *key,
|
||||
size_t keylen, unsigned char *iv, size_t ivlen,
|
||||
@ -1193,54 +1197,55 @@ tls_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers,
|
||||
const EVP_MD *md, const SSL_COMP *comp, BIO *transport,
|
||||
BIO_ADDR *local, BIO_ADDR *peer,
|
||||
const OSSL_PARAM *settings, const OSSL_PARAM *options,
|
||||
OSSL_RECORD_LAYER **retrl,
|
||||
/* TODO(RECLAYER): Remove me */
|
||||
SSL_CONNECTION *s)
|
||||
{
|
||||
OSSL_RECORD_LAYER *rl = tls_int_new_record_layer(libctx, propq, vers, role,
|
||||
direction, level, key,
|
||||
keylen, iv, ivlen, mackey,
|
||||
mackeylen, ciph, taglen,
|
||||
mactype, md, comp,
|
||||
transport, local, peer,
|
||||
settings, options, s);
|
||||
int ret;
|
||||
|
||||
ret = tls_int_new_record_layer(libctx, propq, vers, role, direction, level,
|
||||
key, keylen, iv, ivlen, mackey, mackeylen,
|
||||
ciph, taglen, mactype, md, comp, transport,
|
||||
local, peer, settings, options, retrl, s);
|
||||
|
||||
if (rl == NULL)
|
||||
return NULL;
|
||||
if (ret != OSSL_RECORD_RETURN_SUCCESS)
|
||||
return ret;
|
||||
|
||||
switch (vers) {
|
||||
case TLS_ANY_VERSION:
|
||||
rl->funcs = &tls_any_funcs;
|
||||
(*retrl)->funcs = &tls_any_funcs;
|
||||
break;
|
||||
case TLS1_3_VERSION:
|
||||
rl->funcs = &tls_1_3_funcs;
|
||||
(*retrl)->funcs = &tls_1_3_funcs;
|
||||
break;
|
||||
case TLS1_2_VERSION:
|
||||
case TLS1_1_VERSION:
|
||||
case TLS1_VERSION:
|
||||
rl->funcs = &tls_1_funcs;
|
||||
(*retrl)->funcs = &tls_1_funcs;
|
||||
break;
|
||||
case SSL3_VERSION:
|
||||
rl->funcs = &ssl_3_0_funcs;
|
||||
(*retrl)->funcs = &ssl_3_0_funcs;
|
||||
break;
|
||||
default:
|
||||
/* Should not happen */
|
||||
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
|
||||
ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR);
|
||||
ret = OSSL_RECORD_RETURN_FATAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!rl->funcs->set_crypto_state(rl, level, key, keylen, iv, ivlen,
|
||||
mackey, mackeylen, ciph, taglen,
|
||||
mactype, md, comp, s))
|
||||
goto err;
|
||||
ret = (*retrl)->funcs->set_crypto_state(*retrl, level, key, keylen, iv,
|
||||
ivlen, mackey, mackeylen, ciph,
|
||||
taglen, mactype, md, comp, s);
|
||||
|
||||
return rl;
|
||||
err:
|
||||
/* TODO(RECLAYER): How do we distinguish between fatal and non-fatal errors? */
|
||||
OPENSSL_free(rl);
|
||||
return NULL;
|
||||
if (ret != OSSL_RECORD_RETURN_SUCCESS) {
|
||||
OPENSSL_free(*retrl);
|
||||
*retrl = NULL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static OSSL_RECORD_LAYER *
|
||||
static int
|
||||
dtls_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers,
|
||||
int role, int direction, int level, unsigned char *key,
|
||||
size_t keylen, unsigned char *iv, size_t ivlen,
|
||||
@ -1251,27 +1256,27 @@ dtls_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers,
|
||||
const EVP_MD *md, const SSL_COMP *comp, BIO *transport,
|
||||
BIO_ADDR *local, BIO_ADDR *peer,
|
||||
const OSSL_PARAM *settings, const OSSL_PARAM *options,
|
||||
OSSL_RECORD_LAYER **retrl,
|
||||
/* TODO(RECLAYER): Remove me */
|
||||
SSL_CONNECTION *s)
|
||||
{
|
||||
OSSL_RECORD_LAYER *rl = tls_int_new_record_layer(libctx, propq, vers, role,
|
||||
direction, level, key,
|
||||
keylen, iv, ivlen, mackey,
|
||||
mackeylen, ciph, taglen,
|
||||
mactype, md, comp,
|
||||
transport, local, peer,
|
||||
settings, options, s);
|
||||
int ret;
|
||||
|
||||
if (rl == NULL)
|
||||
return NULL;
|
||||
ret = tls_int_new_record_layer(libctx, propq, vers, role, direction, level,
|
||||
key, keylen, iv, ivlen, mackey, mackeylen,
|
||||
ciph, taglen, mactype, md, comp, transport,
|
||||
local, peer, settings, options, retrl, s);
|
||||
|
||||
rl->isdtls = 1;
|
||||
if (ret != OSSL_RECORD_RETURN_SUCCESS)
|
||||
return ret;
|
||||
|
||||
return rl;
|
||||
(*retrl)->isdtls = 1;
|
||||
|
||||
return OSSL_RECORD_RETURN_SUCCESS;
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_KTLS
|
||||
static OSSL_RECORD_LAYER *
|
||||
static int
|
||||
ktls_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers,
|
||||
int role, int direction, int level, unsigned char *key,
|
||||
size_t keylen, unsigned char *iv, size_t ivlen,
|
||||
@ -1282,32 +1287,31 @@ ktls_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers,
|
||||
const EVP_MD *md, const SSL_COMP *comp, BIO *transport,
|
||||
BIO_ADDR *local, BIO_ADDR *peer,
|
||||
const OSSL_PARAM *settings, const OSSL_PARAM *options,
|
||||
OSSL_RECORD_LAYER **retrl,
|
||||
/* TODO(RECLAYER): Remove me */
|
||||
SSL_CONNECTION *s)
|
||||
{
|
||||
OSSL_RECORD_LAYER *rl = tls_int_new_record_layer(libctx, propq, vers, role,
|
||||
direction, level, key,
|
||||
keylen, iv, ivlen, mackey,
|
||||
mackeylen, ciph, taglen,
|
||||
mactype, md, comp,
|
||||
transport, local, peer,
|
||||
settings, options, s);
|
||||
int ret;
|
||||
|
||||
if (rl == NULL)
|
||||
return NULL;
|
||||
ret = tls_int_new_record_layer(libctx, propq, vers, role, direction, level,
|
||||
key, keylen, iv, ivlen, mackey, mackeylen,
|
||||
ciph, taglen, mactype, md, comp, transport,
|
||||
local, peer, settings, options, retrl, s);
|
||||
|
||||
rl->funcs = &ossl_ktls_funcs;
|
||||
if (ret != OSSL_RECORD_RETURN_SUCCESS)
|
||||
return ret;
|
||||
|
||||
if (!rl->funcs->set_crypto_state(rl, level, key, keylen, iv, ivlen,
|
||||
mackey, mackeylen, ciph, taglen,
|
||||
mactype, md, comp, s))
|
||||
goto err;
|
||||
(*retrl)->funcs = &ossl_ktls_funcs;
|
||||
|
||||
return rl;
|
||||
err:
|
||||
/* TODO(RECLAYER): How do we distinguish between fatal and non-fatal errors? */
|
||||
OPENSSL_free(rl);
|
||||
return NULL;
|
||||
ret = (*retrl)->funcs->set_crypto_state(*retrl, level, key, keylen, iv,
|
||||
ivlen, mackey, mackeylen, ciph,
|
||||
taglen, mactype, md, comp, s);
|
||||
|
||||
if (ret != OSSL_RECORD_RETURN_SUCCESS) {
|
||||
OPENSSL_free(*retrl);
|
||||
*retrl = NULL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -26,13 +26,13 @@ static int tls_any_set_crypto_state(OSSL_RECORD_LAYER *rl, int level,
|
||||
SSL_CONNECTION *s)
|
||||
{
|
||||
if (level != OSSL_RECORD_PROTECTION_LEVEL_NONE) {
|
||||
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR);
|
||||
return OSSL_RECORD_RETURN_FATAL;
|
||||
}
|
||||
|
||||
/* No crypto protection at the "NONE" level so nothing to be done */
|
||||
|
||||
return 1;
|
||||
return OSSL_RECORD_RETURN_SUCCESS;
|
||||
}
|
||||
|
||||
static int tls_any_cipher(OSSL_RECORD_LAYER *rl, SSL3_RECORD *recs,
|
||||
|
@ -1831,13 +1831,21 @@ int ssl_set_new_record_layer(SSL_CONNECTION *s, int version,
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
s->rrl = s->rrlmethod->new_record_layer(sctx->libctx, sctx->propq,
|
||||
version, s->server, direction,
|
||||
level, key, keylen, iv, ivlen,
|
||||
mackey, mackeylen, ciph, taglen,
|
||||
mactype, md, comp, s->rbio,
|
||||
NULL, NULL, NULL, options, s);
|
||||
if (s->rrl == NULL) {
|
||||
int rlret;
|
||||
|
||||
rlret = s->rrlmethod->new_record_layer(sctx->libctx, sctx->propq,
|
||||
version, s->server, direction,
|
||||
level, key, keylen, iv, ivlen,
|
||||
mackey, mackeylen, ciph, taglen,
|
||||
mactype, md, comp, s->rbio,
|
||||
NULL, NULL, NULL, options,
|
||||
&s->rrl, s);
|
||||
switch (rlret) {
|
||||
case OSSL_RECORD_RETURN_FATAL:
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_RECORD_LAYER_FAILURE);
|
||||
goto err;
|
||||
|
||||
case OSSL_RECORD_RETURN_NON_FATAL_ERR:
|
||||
if (s->rrlmethod != origmeth && origmeth != NULL) {
|
||||
/*
|
||||
* We tried a new record layer method, but it didn't work out,
|
||||
@ -1846,7 +1854,15 @@ int ssl_set_new_record_layer(SSL_CONNECTION *s, int version,
|
||||
s->rrlmethod = origmeth;
|
||||
continue;
|
||||
}
|
||||
ERR_raise(ERR_LIB_SSL, SSL_R_NO_SUITABLE_RECORD_LAYER);
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_NO_SUITABLE_RECORD_LAYER);
|
||||
goto err;
|
||||
|
||||
case OSSL_RECORD_RETURN_SUCCESS:
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Should not happen */
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
break;
|
||||
|
@ -129,6 +129,13 @@ struct ossl_record_method_st {
|
||||
* force at any one time (one for reading and one for writing). In some
|
||||
* protocols more than 2 might be used (e.g. in DTLS for retransmitting
|
||||
* messages from an earlier epoch).
|
||||
*
|
||||
* The created OSSL_RECORD_LAYER object is stored in *ret on success (or
|
||||
* NULL otherwise). The return value will be one of
|
||||
* OSSL_RECORD_RETURN_SUCCESS, OSSL_RECORD_RETURN_FATAL or
|
||||
* OSSL_RECORD_RETURN_NON_FATAL. A non-fatal return means that creation of
|
||||
* the record layer has failed because it is unsuitable, but an alternative
|
||||
* record layer can be tried instead.
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -136,27 +143,28 @@ struct ossl_record_method_st {
|
||||
* make this fetchable
|
||||
* TODO(RECLAYER): mactype should not be an int
|
||||
*/
|
||||
OSSL_RECORD_LAYER *(*new_record_layer)(OSSL_LIB_CTX *libctx,
|
||||
const char *propq, int vers,
|
||||
int role, int direction,
|
||||
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,
|
||||
BIO *transport, BIO_ADDR *local,
|
||||
BIO_ADDR *peer,
|
||||
const OSSL_PARAM *settings,
|
||||
const OSSL_PARAM *options,
|
||||
/* TODO(RECLAYER): Remove me */
|
||||
SSL_CONNECTION *s);
|
||||
int (*new_record_layer)(OSSL_LIB_CTX *libctx,
|
||||
const char *propq, int vers,
|
||||
int role, int direction,
|
||||
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,
|
||||
BIO *transport, BIO_ADDR *local,
|
||||
BIO_ADDR *peer,
|
||||
const OSSL_PARAM *settings,
|
||||
const OSSL_PARAM *options,
|
||||
OSSL_RECORD_LAYER **ret,
|
||||
/* TODO(RECLAYER): Remove me */
|
||||
SSL_CONNECTION *s);
|
||||
void (*free)(OSSL_RECORD_LAYER *rl);
|
||||
|
||||
int (*reset)(OSSL_RECORD_LAYER *rl); /* Is this needed? */
|
||||
|
@ -151,7 +151,7 @@ int ssl3_change_cipher_state(SSL_CONNECTION *s, int which)
|
||||
OSSL_RECORD_PROTECTION_LEVEL_APPLICATION,
|
||||
key, key_len, iv, iv_len, mac_secret,
|
||||
md_len, ciph, 0, NID_undef, md, comp)) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_NO_SUITABLE_RECORD_LAYER);
|
||||
/* SSLfatal already called */
|
||||
goto err;
|
||||
}
|
||||
|
||||
|
@ -668,7 +668,7 @@ int ossl_ssl_connection_reset(SSL *s)
|
||||
OSSL_RECORD_PROTECTION_LEVEL_NONE,
|
||||
NULL, 0, NULL, 0, NULL, 0, NULL, 0,
|
||||
NID_undef, NULL, NULL)) {
|
||||
SSLfatal(sc, SSL_AD_INTERNAL_ERROR, SSL_R_NO_SUITABLE_RECORD_LAYER);
|
||||
/* SSLfatal already called */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -286,7 +286,7 @@ int tls1_change_cipher_state(SSL_CONNECTION *s, int which)
|
||||
key, cl, iv, (size_t)k, mac_secret,
|
||||
mac_secret_size, c, taglen, mac_type,
|
||||
m, comp)) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_NO_SUITABLE_RECORD_LAYER);
|
||||
/* SSLfatal already called */
|
||||
goto err;
|
||||
}
|
||||
|
||||
|
@ -721,7 +721,7 @@ int tls13_change_cipher_state(SSL_CONNECTION *s, int which)
|
||||
OSSL_RECORD_DIRECTION_READ,
|
||||
level, key, keylen, iv, ivlen, NULL, 0,
|
||||
cipher, taglen, NID_undef, NULL, NULL)) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_NO_SUITABLE_RECORD_LAYER);
|
||||
/* SSLfatal already called */
|
||||
goto err;
|
||||
}
|
||||
/* TODO(RECLAYER): Remove me */
|
||||
@ -842,7 +842,7 @@ int tls13_update_key(SSL_CONNECTION *s, int sending)
|
||||
key, keylen, iv, ivlen, NULL, 0,
|
||||
s->s3.tmp.new_sym_enc, taglen, NID_undef, NULL,
|
||||
NULL)) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_NO_SUITABLE_RECORD_LAYER);
|
||||
/* SSLfatal already called */
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user