Remove unneccesary KTLS code from non-KTLS specific files

This also moves other protocol specific code to the protocol specific
files.

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:
Matt Caswell 2022-05-12 17:21:25 +01:00
parent 5b24990ba4
commit 1853d20a00
12 changed files with 640 additions and 378 deletions

View File

@ -408,6 +408,35 @@ static int ktls_set_crypto_state(OSSL_RECORD_LAYER *rl, int level,
return OSSL_RECORD_RETURN_SUCCESS;
}
static int ktls_read_n(OSSL_RECORD_LAYER *rl, size_t n, size_t max, int extend,
int clearold, size_t *readbytes)
{
int ret;
ret = tls_default_read_n(rl, n, max, extend, clearold, readbytes);
if (ret < OSSL_RECORD_RETURN_RETRY) {
switch (errno) {
case EBADMSG:
RLAYERfatal(rl, SSL_AD_BAD_RECORD_MAC,
SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC);
break;
case EMSGSIZE:
RLAYERfatal(rl, SSL_AD_RECORD_OVERFLOW,
SSL_R_PACKET_LENGTH_TOO_LONG);
break;
case EINVAL:
RLAYERfatal(rl, SSL_AD_PROTOCOL_VERSION,
SSL_R_WRONG_VERSION_NUMBER);
break;
default:
break;
}
}
return ret;
}
static int ktls_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)
@ -415,8 +444,108 @@ static int ktls_cipher(OSSL_RECORD_LAYER *rl, SSL3_RECORD *inrecs, size_t n_recs
return 1;
}
struct record_functions_st ossl_ktls_funcs = {
static int ktls_validate_record_header(OSSL_RECORD_LAYER *rl, SSL3_RECORD *rec)
{
if (rec->rec_version != TLS1_2_VERSION) {
RLAYERfatal(rl, SSL_AD_DECODE_ERROR, SSL_R_WRONG_VERSION_NUMBER);
return 0;
}
return 1;
}
static int ktls_post_process_record(OSSL_RECORD_LAYER *rl, SSL3_RECORD *rec,
SSL_CONNECTION *s)
{
if (rl->version == TLS1_3_VERSION)
return tls13_common_post_process_record(rl, rec, s);
return 1;
}
static struct record_functions_st ossl_ktls_funcs = {
ktls_set_crypto_state,
ktls_read_n,
ktls_cipher,
NULL
NULL,
tls_default_set_protocol_version,
ktls_validate_record_header,
ktls_post_process_record
};
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,
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 **retrl,
/* TODO(RECLAYER): Remove me */
SSL_CONNECTION *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 (ret != OSSL_RECORD_RETURN_SUCCESS)
return ret;
(*retrl)->funcs = &ossl_ktls_funcs;
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;
} else {
/*
* With KTLS we always try and read as much as possible and fill the
* buffer
*/
(*retrl)->read_ahead = 1;
}
return ret;
}
const OSSL_RECORD_METHOD ossl_ktls_record_method = {
ktls_new_record_layer,
tls_free,
tls_reset,
tls_unprocessed_read_pending,
tls_processed_read_pending,
tls_app_data_pending,
tls_write_pending,
tls_get_max_record_len,
tls_get_max_records,
tls_write_records,
tls_retry_write_records,
tls_read_record,
tls_release_record,
tls_get_alert_code,
tls_set1_bio,
tls_set_protocol_version,
tls_set_plain_alerts,
tls_set_first_handshake,
/*
* TODO(RECLAYER): Remove these. These function pointers are temporary hacks
* during the record layer refactoring. They need to be removed before the
* refactor is complete.
*/
tls_default_read_n,
tls_get0_rbuf,
tls_get0_packet,
tls_set0_packet,
tls_get_packet_length,
tls_reset_packet_length
};

View File

@ -33,6 +33,9 @@ struct record_functions_st
const SSL_COMP *comp,
/* TODO(RECLAYER): Remove me */
SSL_CONNECTION *s);
int (*read_n)(OSSL_RECORD_LAYER *rl, size_t n, size_t max, int extend,
int clearold, size_t *readbytes);
/*
* Returns:
* 0: if the record is publicly invalid, or an internal error, or AEAD
@ -45,6 +48,16 @@ struct record_functions_st
/* 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);
/* Return 1 for success or 0 for error */
int (*set_protocol_version)(OSSL_RECORD_LAYER *rl, int version);
/* Return 1 for success or 0 for error */
int (*validate_record_header)(OSSL_RECORD_LAYER *rl, SSL3_RECORD *rec);
/* Return 1 for success or 0 for error */
int (*post_process_record)(OSSL_RECORD_LAYER *rl, SSL3_RECORD *rec,
/* TODO(RECLAYER): Remove me */ SSL_CONNECTION *s);
};
struct ossl_record_layer_st
@ -78,9 +91,6 @@ struct ossl_record_layer_st
/* The number of records that have been released via tls_release_record */
size_t num_released;
/* Set to true if this is the first record in a connection */
unsigned int is_first_record;
/* where we are when reading */
int rstate;
@ -102,18 +112,28 @@ struct ossl_record_layer_st
/* cryptographic state */
EVP_CIPHER_CTX *enc_read_ctx;
/* TLSv1.3 static read IV */
unsigned char read_iv[EVP_MAX_IV_LENGTH];
/* used for mac generation */
EVP_MD_CTX *read_hash;
/* uncompress */
COMP_CTX *expand;
/* Set to 1 if this is the first handshake. 0 otherwise */
int is_first_handshake;
/* Only used by SSLv3 */
unsigned char mac_secret[EVP_MAX_MD_SIZE];
/* TLSv1.3 static IV */
/* TLSv1.3 fields */
/* static IV */
unsigned char iv[EVP_MAX_IV_LENGTH];
/* static read IV */
unsigned char read_iv[EVP_MAX_IV_LENGTH];
int allow_plain_alerts;
/* TLS "any" fields */
/* Set to true if this is the first record in a connection */
unsigned int is_first_record;
size_t taglen;
@ -125,7 +145,6 @@ struct ossl_record_layer_st
extern struct record_functions_st ssl_3_0_funcs;
extern struct record_functions_st tls_1_funcs;
extern struct record_functions_st tls_1_3_funcs;
extern struct record_functions_st ossl_ktls_funcs;
extern struct record_functions_st tls_any_funcs;
void ossl_rlayer_fatal(OSSL_RECORD_LAYER *rl, int al, int reason,
@ -153,3 +172,56 @@ __owur int ssl3_cbc_digest_record(const EVP_MD *md,
size_t data_plus_mac_plus_padding_size,
const unsigned char *mac_secret,
size_t mac_secret_length, char is_sslv3);
int tls_default_read_n(OSSL_RECORD_LAYER *rl, size_t n, size_t max, int extend,
int clearold, size_t *readbytes);
int tls_default_set_protocol_version(OSSL_RECORD_LAYER *rl, int version);
int tls_default_validate_record_header(OSSL_RECORD_LAYER *rl, SSL3_RECORD *re);
int tls_default_post_process_record(OSSL_RECORD_LAYER *rl, SSL3_RECORD *rec, SSL_CONNECTION *s);
int tls13_common_post_process_record(OSSL_RECORD_LAYER *rl, SSL3_RECORD *rec,
SSL_CONNECTION *s);
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,
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 **retrl,
/* TODO(RECLAYER): Remove me */
SSL_CONNECTION *s);
void tls_free(OSSL_RECORD_LAYER *rl);
int tls_reset(OSSL_RECORD_LAYER *rl);
int tls_unprocessed_read_pending(OSSL_RECORD_LAYER *rl);
int tls_processed_read_pending(OSSL_RECORD_LAYER *rl);
size_t tls_app_data_pending(OSSL_RECORD_LAYER *rl);
int tls_write_pending(OSSL_RECORD_LAYER *rl);
size_t tls_get_max_record_len(OSSL_RECORD_LAYER *rl);
size_t tls_get_max_records(OSSL_RECORD_LAYER *rl);
int tls_write_records(OSSL_RECORD_LAYER *rl, OSSL_RECORD_TEMPLATE **templates,
size_t numtempl, size_t allowance, size_t *sent);
int tls_retry_write_records(OSSL_RECORD_LAYER *rl, size_t allowance,
size_t *sent);
int tls_get_alert_code(OSSL_RECORD_LAYER *rl);
int tls_set1_bio(OSSL_RECORD_LAYER *rl, BIO *bio);
int tls_read_record(OSSL_RECORD_LAYER *rl, void **rechandle, int *rversion,
int *type, unsigned char **data, size_t *datalen,
uint16_t *epoch, unsigned char *seq_num,
/* TODO(RECLAYER): Remove me */ SSL_CONNECTION *s);
int tls_release_record(OSSL_RECORD_LAYER *rl, void *rechandle);
int tls_default_set_protocol_version(OSSL_RECORD_LAYER *rl, int version);
int tls_set_protocol_version(OSSL_RECORD_LAYER *rl, int version);
void tls_set_plain_alerts(OSSL_RECORD_LAYER *rl, int allow);
void tls_set_first_handshake(OSSL_RECORD_LAYER *rl, int first);
SSL3_BUFFER *tls_get0_rbuf(OSSL_RECORD_LAYER *rl);
unsigned char *tls_get0_packet(OSSL_RECORD_LAYER *rl);
void tls_set0_packet(OSSL_RECORD_LAYER *rl, unsigned char *packet,
size_t packetlen);
size_t tls_get_packet_length(OSSL_RECORD_LAYER *rl);
void tls_reset_packet_length(OSSL_RECORD_LAYER *rl);

View File

@ -315,6 +315,10 @@ static int ssl3_mac(OSSL_RECORD_LAYER *rl, SSL3_RECORD *rec, unsigned char *md,
struct record_functions_st ssl_3_0_funcs = {
ssl3_set_crypto_state,
tls_default_read_n,
ssl3_cipher,
ssl3_mac
ssl3_mac,
tls_default_set_protocol_version,
tls_default_validate_record_header,
tls_default_post_process_record
};

View File

@ -191,8 +191,71 @@ static int tls13_cipher(OSSL_RECORD_LAYER *rl, SSL3_RECORD *recs, size_t n_recs,
return 1;
}
static int tls13_validate_record_header(OSSL_RECORD_LAYER *rl, SSL3_RECORD *rec)
{
if (rec->type != SSL3_RT_APPLICATION_DATA
&& (rec->type != SSL3_RT_CHANGE_CIPHER_SPEC
|| !rl->is_first_handshake)
&& (rec->type != SSL3_RT_ALERT || !rl->allow_plain_alerts)) {
RLAYERfatal(rl, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_BAD_RECORD_TYPE);
return 0;
}
if (rec->rec_version != TLS1_2_VERSION) {
RLAYERfatal(rl, SSL_AD_DECODE_ERROR, SSL_R_WRONG_VERSION_NUMBER);
return 0;
}
if (rec->length > SSL3_RT_MAX_TLS13_ENCRYPTED_LENGTH) {
RLAYERfatal(rl, SSL_AD_RECORD_OVERFLOW,
SSL_R_ENCRYPTED_LENGTH_TOO_LONG);
return 0;
}
return 1;
}
static int tls13_post_process_record(OSSL_RECORD_LAYER *rl, SSL3_RECORD *rec,
SSL_CONNECTION *s)
{
/* Skip this if we've received a plaintext alert */
if (rec->type != SSL3_RT_ALERT) {
size_t end;
if (rec->length == 0
|| rec->type != SSL3_RT_APPLICATION_DATA) {
RLAYERfatal(rl, SSL_AD_UNEXPECTED_MESSAGE,
SSL_R_BAD_RECORD_TYPE);
return 0;
}
/* Strip trailing padding */
for (end = rec->length - 1; end > 0 && rec->data[end] == 0;
end--)
continue;
rec->length = end;
rec->type = rec->data[end];
}
if (rec->length > SSL3_RT_MAX_PLAIN_LENGTH) {
RLAYERfatal(rl, SSL_AD_RECORD_OVERFLOW, SSL_R_DATA_LENGTH_TOO_LONG);
return 0;
}
if (!tls13_common_post_process_record(rl, rec, s)) {
/* RLAYERfatal already called */
return 0;
}
return 1;
}
struct record_functions_st tls_1_3_funcs = {
tls13_set_crypto_state,
tls_default_read_n,
tls13_cipher,
NULL
NULL,
tls_default_set_protocol_version,
tls13_validate_record_header,
tls13_post_process_record
};

View File

@ -591,6 +591,10 @@ static int tls1_mac(OSSL_RECORD_LAYER *rl, SSL3_RECORD *rec, unsigned char *md,
/* TLSv1.0, TLSv1.1 and TLSv1.2 all use the same funcs */
struct record_functions_st tls_1_funcs = {
tls1_set_crypto_state,
tls_default_read_n,
tls1_cipher,
tls1_mac
tls1_mac,
tls_default_set_protocol_version,
tls_default_validate_record_header,
tls_default_post_process_record
};

View File

@ -89,8 +89,6 @@ char ssl3_cbc_record_digest_supported(const EVP_MD_CTX *ctx)
}
}
static int tls_set1_bio(OSSL_RECORD_LAYER *rl, BIO *bio);
static int rlayer_allow_compression(OSSL_RECORD_LAYER *rl)
{
if (rl->options & SSL_OP_NO_COMPRESSION)
@ -157,7 +155,7 @@ static int rlayer_release_read_buffer(OSSL_RECORD_LAYER *rl)
return 1;
}
static void tls_reset_packet_length(OSSL_RECORD_LAYER *rl)
void tls_reset_packet_length(OSSL_RECORD_LAYER *rl)
{
rl->packet_length = 0;
}
@ -165,8 +163,8 @@ static void tls_reset_packet_length(OSSL_RECORD_LAYER *rl)
/*
* Return values are as per SSL_read()
*/
static int tls_read_n(OSSL_RECORD_LAYER *rl, size_t n, size_t max, int extend,
int clearold, size_t *readbytes)
int tls_default_read_n(OSSL_RECORD_LAYER *rl, size_t n, size_t max, int extend,
int clearold, size_t *readbytes)
{
/*
* If extend == 0, obtain new n-byte packet; if extend == 1, increase
@ -272,12 +270,8 @@ static int tls_read_n(OSSL_RECORD_LAYER *rl, size_t n, size_t max, int extend,
return OSSL_RECORD_RETURN_FATAL;
}
/*
* Ktls always reads full records.
* Also, we always act like read_ahead is set for DTLS.
*/
if (!BIO_get_ktls_recv(rl->bio) && !rl->read_ahead
&& !rl->isdtls) {
/* We always act like read_ahead is set for DTLS */
if (!rl->read_ahead && !rl->isdtls) {
/* ignore max parameter */
max = n;
} else {
@ -419,7 +413,6 @@ static int tls_get_more_records(OSSL_RECORD_LAYER *rl,
int imac_size;
size_t num_recs = 0, max_recs, j;
PACKET pkt, sslv2pkt;
int using_ktls;
SSL_MAC_BUF *macbufs = NULL;
int ret = OSSL_RECORD_RETURN_FATAL;
SSL *ssl = SSL_CONNECTION_GET_SSL(s);
@ -438,12 +431,6 @@ static int tls_get_more_records(OSSL_RECORD_LAYER *rl,
max_recs = 1;
sess = s->session;
/*
* KTLS reads full records. If there is any data left,
* then it is from before enabling ktls.
*/
using_ktls = BIO_get_ktls_recv(rl->bio) && SSL3_BUFFER_get_left(rbuf) == 0;
do {
thisrr = &rr[num_recs];
@ -453,33 +440,13 @@ static int tls_get_more_records(OSSL_RECORD_LAYER *rl,
size_t sslv2len;
unsigned int type;
rret = tls_read_n(rl, SSL3_RT_HEADER_LENGTH,
SSL3_BUFFER_get_len(rbuf), 0,
num_recs == 0 ? 1 : 0, &n);
rret = rl->funcs->read_n(rl, SSL3_RT_HEADER_LENGTH,
SSL3_BUFFER_get_len(rbuf), 0,
num_recs == 0 ? 1 : 0, &n);
if (rret < OSSL_RECORD_RETURN_SUCCESS)
return rret; /* error or non-blocking */
if (rret < OSSL_RECORD_RETURN_SUCCESS) {
#ifndef OPENSSL_NO_KTLS
if (!BIO_get_ktls_recv(rl->bio) || rret == 0)
return rret; /* error or non-blocking */
switch (errno) {
case EBADMSG:
RLAYERfatal(rl, SSL_AD_BAD_RECORD_MAC,
SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC);
break;
case EMSGSIZE:
RLAYERfatal(rl, SSL_AD_RECORD_OVERFLOW,
SSL_R_PACKET_LENGTH_TOO_LONG);
break;
case EINVAL:
RLAYERfatal(rl, SSL_AD_PROTOCOL_VERSION,
SSL_R_WRONG_VERSION_NUMBER);
break;
default:
break;
}
#endif
return rret;
}
rl->rstate = SSL_ST_READ_BODY;
p = rl->packet;
@ -520,11 +487,6 @@ static int tls_get_more_records(OSSL_RECORD_LAYER *rl,
SSL_R_PACKET_LENGTH_TOO_LONG);
return OSSL_RECORD_RETURN_FATAL;
}
if (thisrr->length < MIN_SSL2_RECORD_LEN) {
RLAYERfatal(rl, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_TOO_SHORT);
return OSSL_RECORD_RETURN_FATAL;
}
} else {
/* SSLv3+ style record */
@ -545,89 +507,6 @@ static int tls_get_more_records(OSSL_RECORD_LAYER *rl,
s->msg_callback(0, version, SSL3_RT_HEADER, p, 5, ssl,
s->msg_callback_arg);
/*
* Lets check version. In TLSv1.3 we only check this field
* when encryption is occurring (see later check). For the
* ServerHello after an HRR we haven't actually selected TLSv1.3
* yet, but we still treat it as TLSv1.3, so we must check for
* that explicitly
*/
if (!s->first_packet && !SSL_CONNECTION_IS_TLS13(s)
&& s->hello_retry_request != SSL_HRR_PENDING
&& version != (unsigned int)s->version) {
if ((s->version & 0xFF00) == (version & 0xFF00)
&& !s->enc_write_ctx && !s->write_hash) {
if (thisrr->type == SSL3_RT_ALERT) {
/*
* The record is using an incorrect version number,
* but what we've got appears to be an alert. We
* haven't read the body yet to check whether its a
* fatal or not - but chances are it is. We probably
* shouldn't send a fatal alert back. We'll just
* end.
*/
RLAYERfatal(rl, SSL_AD_NO_ALERT,
SSL_R_WRONG_VERSION_NUMBER);
return OSSL_RECORD_RETURN_FATAL;
}
/*
* Send back error using their minor version number :-)
*/
s->version = (unsigned short)version;
}
RLAYERfatal(rl, SSL_AD_PROTOCOL_VERSION,
SSL_R_WRONG_VERSION_NUMBER);
return OSSL_RECORD_RETURN_FATAL;
}
if ((version >> 8) != SSL3_VERSION_MAJOR) {
if (rl->is_first_record) {
/* Go back to start of packet, look at the five bytes
* that we have. */
p = rl->packet;
if (HAS_PREFIX((char *)p, "GET ") ||
HAS_PREFIX((char *)p, "POST ") ||
HAS_PREFIX((char *)p, "HEAD ") ||
HAS_PREFIX((char *)p, "PUT ")) {
RLAYERfatal(rl, SSL_AD_NO_ALERT, SSL_R_HTTP_REQUEST);
return OSSL_RECORD_RETURN_FATAL;
} else if (HAS_PREFIX((char *)p, "CONNE")) {
RLAYERfatal(rl, SSL_AD_NO_ALERT,
SSL_R_HTTPS_PROXY_REQUEST);
return OSSL_RECORD_RETURN_FATAL;
}
/* Doesn't look like TLS - don't send an alert */
RLAYERfatal(rl, SSL_AD_NO_ALERT,
SSL_R_WRONG_VERSION_NUMBER);
return OSSL_RECORD_RETURN_FATAL;
} else {
RLAYERfatal(rl, SSL_AD_PROTOCOL_VERSION,
SSL_R_WRONG_VERSION_NUMBER);
return OSSL_RECORD_RETURN_FATAL;
}
}
if (SSL_CONNECTION_IS_TLS13(s)
&& rl->enc_read_ctx != NULL
&& !using_ktls) {
if (thisrr->type != SSL3_RT_APPLICATION_DATA
&& (thisrr->type != SSL3_RT_CHANGE_CIPHER_SPEC
|| !SSL_IS_FIRST_HANDSHAKE(s))
&& (thisrr->type != SSL3_RT_ALERT
|| s->statem.enc_read_state
!= ENC_READ_STATE_ALLOW_PLAIN_ALERTS)) {
RLAYERfatal(rl, SSL_AD_UNEXPECTED_MESSAGE,
SSL_R_BAD_RECORD_TYPE);
return OSSL_RECORD_RETURN_FATAL;
}
if (thisrr->rec_version != TLS1_2_VERSION) {
RLAYERfatal(rl, SSL_AD_DECODE_ERROR,
SSL_R_WRONG_VERSION_NUMBER);
return OSSL_RECORD_RETURN_FATAL;
}
}
if (thisrr->length >
SSL3_BUFFER_get_len(rbuf) - SSL3_RT_HEADER_LENGTH) {
RLAYERfatal(rl, SSL_AD_RECORD_OVERFLOW,
@ -636,44 +515,14 @@ static int tls_get_more_records(OSSL_RECORD_LAYER *rl,
}
}
if (!rl->funcs->validate_record_header(rl, thisrr)) {
/* RLAYERfatal already called */
return OSSL_RECORD_RETURN_FATAL;
}
/* now rl->rstate == SSL_ST_READ_BODY */
}
if (SSL_CONNECTION_IS_TLS13(s)) {
size_t len = SSL3_RT_MAX_TLS13_ENCRYPTED_LENGTH;
/* KTLS strips the inner record type. */
if (using_ktls)
len = SSL3_RT_MAX_ENCRYPTED_LENGTH;
if (thisrr->length > len) {
RLAYERfatal(rl, SSL_AD_RECORD_OVERFLOW,
SSL_R_ENCRYPTED_LENGTH_TOO_LONG);
return OSSL_RECORD_RETURN_FATAL;
}
} else {
size_t len = SSL3_RT_MAX_ENCRYPTED_LENGTH;
#ifndef OPENSSL_NO_COMP
/*
* If OPENSSL_NO_COMP is defined then SSL3_RT_MAX_ENCRYPTED_LENGTH
* does not include the compression overhead anyway.
*/
if (s->expand == NULL)
len -= SSL3_RT_MAX_COMPRESSED_OVERHEAD;
#endif
/* KTLS may use all of the buffer */
if (using_ktls)
len = SSL3_BUFFER_get_left(rbuf);
if (thisrr->length > len) {
RLAYERfatal(rl, SSL_AD_RECORD_OVERFLOW,
SSL_R_ENCRYPTED_LENGTH_TOO_LONG);
return OSSL_RECORD_RETURN_FATAL;
}
}
/*
* rl->rstate == SSL_ST_READ_BODY, get and decode the data. Calculate
* how much more data we need to read for the rest of the record
@ -688,7 +537,7 @@ static int tls_get_more_records(OSSL_RECORD_LAYER *rl,
if (more > 0) {
/* now rl->packet_length == SSL3_RT_HEADER_LENGTH */
rret = tls_read_n(rl, more, more, 1, 0, &n);
rret = rl->funcs->read_n(rl, more, more, 1, 0, &n);
if (rret < OSSL_RECORD_RETURN_SUCCESS)
return rret; /* error or non-blocking io */
}
@ -742,7 +591,7 @@ static int tls_get_more_records(OSSL_RECORD_LAYER *rl,
if (num_recs == 1
&& thisrr->type == SSL3_RT_CHANGE_CIPHER_SPEC
&& (SSL_CONNECTION_IS_TLS13(s) || s->hello_retry_request != SSL_HRR_NONE)
&& SSL_IS_FIRST_HANDSHAKE(s)) {
&& rl->is_first_handshake) {
/*
* CCS messages must be exactly 1 byte long, containing the value 0x01
*/
@ -769,9 +618,6 @@ static int tls_get_more_records(OSSL_RECORD_LAYER *rl,
return OSSL_RECORD_RETURN_SUCCESS;
}
if (using_ktls)
goto skip_decryption;
if (rl->read_hash != NULL) {
const EVP_MD *tmpmd = EVP_MD_CTX_get0_md(rl->read_hash);
@ -908,85 +754,11 @@ static int tls_get_more_records(OSSL_RECORD_LAYER *rl,
goto end;
}
skip_decryption:
for (j = 0; j < num_recs; j++) {
thisrr = &rr[j];
/* thisrr->length is now just compressed */
if (s->expand != NULL) {
if (thisrr->length > SSL3_RT_MAX_COMPRESSED_LENGTH) {
RLAYERfatal(rl, SSL_AD_RECORD_OVERFLOW,
SSL_R_COMPRESSED_LENGTH_TOO_LONG);
goto end;
}
if (!ssl3_do_uncompress(s, thisrr)) {
RLAYERfatal(rl, SSL_AD_DECOMPRESSION_FAILURE,
SSL_R_BAD_DECOMPRESSION);
goto end;
}
}
if (SSL_CONNECTION_IS_TLS13(s)
&& rl->enc_read_ctx != NULL
&& thisrr->type != SSL3_RT_ALERT) {
/*
* The following logic are irrelevant in KTLS: the kernel provides
* unprotected record and thus record type represent the actual
* content type, and padding is already removed and thisrr->type and
* thisrr->length should have the correct values.
*/
if (!using_ktls) {
size_t end;
if (thisrr->length == 0
|| thisrr->type != SSL3_RT_APPLICATION_DATA) {
RLAYERfatal(rl, SSL_AD_UNEXPECTED_MESSAGE,
SSL_R_BAD_RECORD_TYPE);
goto end;
}
/* Strip trailing padding */
for (end = thisrr->length - 1; end > 0 && thisrr->data[end] == 0;
end--)
continue;
thisrr->length = end;
thisrr->type = thisrr->data[end];
}
if (thisrr->type != SSL3_RT_APPLICATION_DATA
&& thisrr->type != SSL3_RT_ALERT
&& thisrr->type != SSL3_RT_HANDSHAKE) {
RLAYERfatal(rl, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_BAD_RECORD_TYPE);
goto end;
}
if (s->msg_callback)
s->msg_callback(0, s->version, SSL3_RT_INNER_CONTENT_TYPE,
&thisrr->type, 1, ssl, s->msg_callback_arg);
}
/*
* TLSv1.3 alert and handshake records are required to be non-zero in
* length.
*/
if (SSL_CONNECTION_IS_TLS13(s)
&& (thisrr->type == SSL3_RT_HANDSHAKE
|| thisrr->type == SSL3_RT_ALERT)
&& thisrr->length == 0) {
RLAYERfatal(rl, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_BAD_LENGTH);
goto end;
}
/*
* Usually thisrr->length is the length of a single record, but when
* KTLS handles the decryption, thisrr->length may be larger than
* SSL3_RT_MAX_PLAIN_LENGTH because the kernel may have coalesced
* multiple records.
* Therefore we have to rely on KTLS to check the plaintext length
* limit in the kernel.
*/
if (thisrr->length > SSL3_RT_MAX_PLAIN_LENGTH && !using_ktls) {
RLAYERfatal(rl, SSL_AD_RECORD_OVERFLOW, SSL_R_DATA_LENGTH_TOO_LONG);
if (!rl->funcs->post_process_record(rl, thisrr, s)) {
/* RLAYERfatal already called */
goto end;
}
@ -1045,11 +817,118 @@ static int tls_get_more_records(OSSL_RECORD_LAYER *rl,
return ret;
}
static int tls_read_record(OSSL_RECORD_LAYER *rl, void **rechandle,
int *rversion, int *type, unsigned char **data,
size_t *datalen, uint16_t *epoch,
unsigned char *seq_num,
/* TODO(RECLAYER): Remove me */ SSL_CONNECTION *s)
/* Shared by ssl3_meth and tls1_meth */
int tls_default_validate_record_header(OSSL_RECORD_LAYER *rl, SSL3_RECORD *rec)
{
size_t len = SSL3_RT_MAX_ENCRYPTED_LENGTH;
if (rec->rec_version != rl->version) {
RLAYERfatal(rl, SSL_AD_PROTOCOL_VERSION, SSL_R_WRONG_VERSION_NUMBER);
return 0;
}
#ifndef OPENSSL_NO_COMP
/*
* If OPENSSL_NO_COMP is defined then SSL3_RT_MAX_ENCRYPTED_LENGTH
* does not include the compression overhead anyway.
*/
if (rl->expand == NULL)
len -= SSL3_RT_MAX_COMPRESSED_OVERHEAD;
#endif
if (rec->length > len) {
RLAYERfatal(rl, SSL_AD_RECORD_OVERFLOW,
SSL_R_ENCRYPTED_LENGTH_TOO_LONG);
return 0;
}
return 1;
}
static int tls_do_uncompress(OSSL_RECORD_LAYER *rl, SSL3_RECORD *rec)
{
#ifndef OPENSSL_NO_COMP
int i;
if (rec->comp == NULL) {
rec->comp = (unsigned char *)
OPENSSL_malloc(SSL3_RT_MAX_ENCRYPTED_LENGTH);
}
if (rec->comp == NULL)
return 0;
i = COMP_expand_block(rl->expand, rec->comp,
SSL3_RT_MAX_PLAIN_LENGTH, rec->data, (int)rec->length);
if (i < 0)
return 0;
else
rec->length = i;
rec->data = rec->comp;
return 1;
#else
return 0;
#endif
}
/* Shared by tlsany_meth, ssl3_meth and tls1_meth */
int tls_default_post_process_record(OSSL_RECORD_LAYER *rl, SSL3_RECORD *rec, SSL_CONNECTION *s)
{
if (rl->expand != NULL) {
if (rec->length > SSL3_RT_MAX_COMPRESSED_LENGTH) {
RLAYERfatal(rl, SSL_AD_RECORD_OVERFLOW,
SSL_R_COMPRESSED_LENGTH_TOO_LONG);
return 0;
}
if (!tls_do_uncompress(rl, rec)) {
RLAYERfatal(rl, SSL_AD_DECOMPRESSION_FAILURE,
SSL_R_BAD_DECOMPRESSION);
return 0;
}
}
if (rec->length > SSL3_RT_MAX_PLAIN_LENGTH) {
RLAYERfatal(rl, SSL_AD_RECORD_OVERFLOW, SSL_R_DATA_LENGTH_TOO_LONG);
return 0;
}
return 1;
}
/* Shared by tls13_meth and ktls_meth */
int tls13_common_post_process_record(OSSL_RECORD_LAYER *rl, SSL3_RECORD *rec,
SSL_CONNECTION *s)
{
SSL *ssl = SSL_CONNECTION_GET_SSL(s);
if (rec->type != SSL3_RT_APPLICATION_DATA
&& rec->type != SSL3_RT_ALERT
&& rec->type != SSL3_RT_HANDSHAKE) {
RLAYERfatal(rl, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_BAD_RECORD_TYPE);
return 0;
}
if (s->msg_callback)
s->msg_callback(0, rl->version, SSL3_RT_INNER_CONTENT_TYPE,
&rec->type, 1, ssl, s->msg_callback_arg);
/*
* TLSv1.3 alert and handshake records are required to be non-zero in
* length.
*/
if ((rec->type == SSL3_RT_HANDSHAKE
|| rec->type == SSL3_RT_ALERT)
&& rec->length == 0) {
RLAYERfatal(rl, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_BAD_LENGTH);
return 0;
}
return 1;
}
int tls_read_record(OSSL_RECORD_LAYER *rl, void **rechandle, int *rversion,
int *type, unsigned char **data, size_t *datalen,
uint16_t *epoch, unsigned char *seq_num,
/* TODO(RECLAYER): Remove me */ SSL_CONNECTION *s)
{
SSL3_RECORD *rec;
@ -1088,7 +967,7 @@ static int tls_read_record(OSSL_RECORD_LAYER *rl, void **rechandle,
return OSSL_RECORD_RETURN_SUCCESS;
}
static int tls_release_record(OSSL_RECORD_LAYER *rl, void *rechandle)
int tls_release_record(OSSL_RECORD_LAYER *rl, void *rechandle)
{
if (!ossl_assert(rl->num_released < rl->curr_rec)
|| !ossl_assert(rechandle == &rl->rrec[rl->num_released])) {
@ -1102,7 +981,7 @@ static int tls_release_record(OSSL_RECORD_LAYER *rl, void *rechandle)
return OSSL_RECORD_RETURN_SUCCESS;
}
static int
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,
@ -1173,7 +1052,7 @@ tls_int_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers,
rl->role = role;
rl->direction = direction;
if (level == 0)
if (level == OSSL_RECORD_PROTECTION_LEVEL_NONE)
rl->is_first_record = 1;
if (!tls_set1_bio(rl, transport))
@ -1245,6 +1124,21 @@ tls_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers,
return ret;
}
/* TODO(RECLAYER): Temporary funcs */
static int dtls_set_protocol_version(OSSL_RECORD_LAYER *rl, int version)
{
rl->version = version;
return 1;
}
static struct record_functions_st dtls_funcs = {
NULL,
NULL,
NULL,
NULL,
dtls_set_protocol_version,
NULL
};
static int
dtls_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers,
int role, int direction, int level, unsigned char *key,
@ -1262,6 +1156,7 @@ dtls_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers,
{
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,
@ -1271,113 +1166,73 @@ dtls_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers,
return ret;
(*retrl)->isdtls = 1;
(*retrl)->funcs = &dtls_funcs;
return OSSL_RECORD_RETURN_SUCCESS;
}
#ifndef OPENSSL_NO_KTLS
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,
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 **retrl,
/* TODO(RECLAYER): Remove me */
SSL_CONNECTION *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 (ret != OSSL_RECORD_RETURN_SUCCESS)
return ret;
(*retrl)->funcs = &ossl_ktls_funcs;
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
static void tls_free(OSSL_RECORD_LAYER *rl)
void tls_free(OSSL_RECORD_LAYER *rl)
{
/* TODO(RECLAYER): Cleanse sensitive fields */
BIO_free(rl->bio);
OPENSSL_free(rl);
}
static int tls_reset(OSSL_RECORD_LAYER *rl)
int tls_reset(OSSL_RECORD_LAYER *rl)
{
memset(rl, 0, sizeof(*rl));
return 1;
}
static int tls_unprocessed_read_pending(OSSL_RECORD_LAYER *rl)
int tls_unprocessed_read_pending(OSSL_RECORD_LAYER *rl)
{
return SSL3_BUFFER_get_left(&rl->rbuf) != 0;;
}
static int tls_processed_read_pending(OSSL_RECORD_LAYER *rl)
int tls_processed_read_pending(OSSL_RECORD_LAYER *rl)
{
return rl->curr_rec < rl->num_recs;
}
static size_t tls_app_data_pending(OSSL_RECORD_LAYER *rl)
size_t tls_app_data_pending(OSSL_RECORD_LAYER *rl)
{
return 0;
}
static int tls_write_pending(OSSL_RECORD_LAYER *rl)
int tls_write_pending(OSSL_RECORD_LAYER *rl)
{
return 0;
}
static size_t tls_get_max_record_len(OSSL_RECORD_LAYER *rl)
size_t tls_get_max_record_len(OSSL_RECORD_LAYER *rl)
{
return 0;
}
static size_t tls_get_max_records(OSSL_RECORD_LAYER *rl)
size_t tls_get_max_records(OSSL_RECORD_LAYER *rl)
{
return 0;
}
static int tls_write_records(OSSL_RECORD_LAYER *rl,
OSSL_RECORD_TEMPLATE **templates, size_t numtempl,
size_t allowance, size_t *sent)
int tls_write_records(OSSL_RECORD_LAYER *rl, OSSL_RECORD_TEMPLATE **templates,
size_t numtempl, size_t allowance, size_t *sent)
{
return 0;
}
static int tls_retry_write_records(OSSL_RECORD_LAYER *rl, size_t allowance,
size_t *sent)
int tls_retry_write_records(OSSL_RECORD_LAYER *rl, size_t allowance,
size_t *sent)
{
return 0;
}
static int tls_get_alert_code(OSSL_RECORD_LAYER *rl)
int tls_get_alert_code(OSSL_RECORD_LAYER *rl)
{
return rl->alert;
}
static int tls_set1_bio(OSSL_RECORD_LAYER *rl, BIO *bio)
int tls_set1_bio(OSSL_RECORD_LAYER *rl, BIO *bio)
{
if (bio != NULL && !BIO_up_ref(bio))
return 0;
@ -1387,24 +1242,48 @@ static int tls_set1_bio(OSSL_RECORD_LAYER *rl, BIO *bio)
return 1;
}
static SSL3_BUFFER *tls_get0_rbuf(OSSL_RECORD_LAYER *rl)
/* Shared by most methods except tlsany_meth */
int tls_default_set_protocol_version(OSSL_RECORD_LAYER *rl, int version)
{
if (rl->version != version)
return 0;
return 1;
}
int tls_set_protocol_version(OSSL_RECORD_LAYER *rl, int version)
{
return rl->funcs->set_protocol_version(rl, version);
}
void tls_set_plain_alerts(OSSL_RECORD_LAYER *rl, int allow)
{
rl->allow_plain_alerts = allow;
}
void tls_set_first_handshake(OSSL_RECORD_LAYER *rl, int first)
{
rl->is_first_handshake = first;
}
SSL3_BUFFER *tls_get0_rbuf(OSSL_RECORD_LAYER *rl)
{
return &rl->rbuf;
}
static unsigned char *tls_get0_packet(OSSL_RECORD_LAYER *rl)
unsigned char *tls_get0_packet(OSSL_RECORD_LAYER *rl)
{
return rl->packet;
}
static void tls_set0_packet(OSSL_RECORD_LAYER *rl, unsigned char *packet,
size_t packetlen)
void tls_set0_packet(OSSL_RECORD_LAYER *rl, unsigned char *packet,
size_t packetlen)
{
rl->packet = packet;
rl->packet_length = packetlen;
}
static size_t tls_get_packet_length(OSSL_RECORD_LAYER *rl)
size_t tls_get_packet_length(OSSL_RECORD_LAYER *rl)
{
return rl->packet_length;
}
@ -1425,13 +1304,16 @@ const OSSL_RECORD_METHOD ossl_tls_record_method = {
tls_release_record,
tls_get_alert_code,
tls_set1_bio,
tls_set_protocol_version,
tls_set_plain_alerts,
tls_set_first_handshake,
/*
* TODO(RECLAYER): Remove these. These function pointers are temporary hacks
* during the record layer refactoring. They need to be removed before the
* refactor is complete.
*/
tls_read_n,
tls_default_read_n,
tls_get0_rbuf,
tls_get0_packet,
tls_set0_packet,
@ -1439,38 +1321,6 @@ const OSSL_RECORD_METHOD ossl_tls_record_method = {
tls_reset_packet_length
};
#ifndef OPENSSL_NO_KTLS
const OSSL_RECORD_METHOD ossl_ktls_record_method = {
ktls_new_record_layer,
tls_free,
tls_reset,
tls_unprocessed_read_pending,
tls_processed_read_pending,
tls_app_data_pending,
tls_write_pending,
tls_get_max_record_len,
tls_get_max_records,
tls_write_records,
tls_retry_write_records,
tls_read_record,
tls_release_record,
tls_get_alert_code,
tls_set1_bio,
/*
* TODO(RECLAYER): Remove these. These function pointers are temporary hacks
* during the record layer refactoring. They need to be removed before the
* refactor is complete.
*/
tls_read_n,
tls_get0_rbuf,
tls_get0_packet,
tls_set0_packet,
tls_get_packet_length,
tls_reset_packet_length
};
#endif
const OSSL_RECORD_METHOD ossl_dtls_record_method = {
dtls_new_record_layer,
tls_free,
@ -1487,13 +1337,16 @@ const OSSL_RECORD_METHOD ossl_dtls_record_method = {
tls_release_record,
tls_get_alert_code,
tls_set1_bio,
tls_set_protocol_version,
NULL,
tls_set_first_handshake,
/*
* TODO(RECLAYER): Remove these. These function pointers are temporary hacks
* during the record layer refactoring. They need to be removed before the
* refactor is complete.
*/
tls_read_n,
tls_default_read_n,
tls_get0_rbuf,
tls_get0_packet,
tls_set0_packet,

View File

@ -43,8 +43,113 @@ static int tls_any_cipher(OSSL_RECORD_LAYER *rl, SSL3_RECORD *recs,
return 1;
}
static int tls_validate_record_header(OSSL_RECORD_LAYER *rl, SSL3_RECORD *rec)
{
if (rec->rec_version == SSL2_VERSION) {
/* SSLv2 format ClientHello */
if (!ossl_assert(rl->version == TLS_ANY_VERSION)) {
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return 0;
}
if (rec->length < MIN_SSL2_RECORD_LEN) {
RLAYERfatal(rl, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_TOO_SHORT);
return 0;
}
} else {
if (rl->version == TLS_ANY_VERSION) {
if ((rec->rec_version >> 8) != SSL3_VERSION_MAJOR) {
if (rl->is_first_record) {
unsigned char *p;
/*
* Go back to start of packet, look at the five bytes that
* we have.
*/
p = rl->packet;
if (HAS_PREFIX((char *)p, "GET ") ||
HAS_PREFIX((char *)p, "POST ") ||
HAS_PREFIX((char *)p, "HEAD ") ||
HAS_PREFIX((char *)p, "PUT ")) {
RLAYERfatal(rl, SSL_AD_NO_ALERT, SSL_R_HTTP_REQUEST);
return 0;
} else if (HAS_PREFIX((char *)p, "CONNE")) {
RLAYERfatal(rl, SSL_AD_NO_ALERT,
SSL_R_HTTPS_PROXY_REQUEST);
return 0;
}
/* Doesn't look like TLS - don't send an alert */
RLAYERfatal(rl, SSL_AD_NO_ALERT,
SSL_R_WRONG_VERSION_NUMBER);
return 0;
} else {
RLAYERfatal(rl, SSL_AD_PROTOCOL_VERSION,
SSL_R_WRONG_VERSION_NUMBER);
return 0;
}
}
} else if (rl->version == TLS1_3_VERSION) {
/*
* In this case we know we are going to negotiate TLSv1.3, but we've
* had an HRR, so we haven't actually done so yet. Nonetheless we
* still expect the record version to be TLSv1.2 as per a normal
* TLSv1.3 record
*/
if (rec->rec_version != TLS1_2_VERSION) {
RLAYERfatal(rl, SSL_AD_PROTOCOL_VERSION,
SSL_R_WRONG_VERSION_NUMBER);
return 0;
}
} else if (rec->rec_version != rl->version) {
if ((rl->version & 0xFF00) == (rec->rec_version & 0xFF00)) {
if (rec->type == SSL3_RT_ALERT) {
/*
* The record is using an incorrect version number,
* but what we've got appears to be an alert. We
* haven't read the body yet to check whether its a
* fatal or not - but chances are it is. We probably
* shouldn't send a fatal alert back. We'll just
* end.
*/
RLAYERfatal(rl, SSL_AD_NO_ALERT,
SSL_R_WRONG_VERSION_NUMBER);
return 0;
}
/* Send back error using their minor version number */
rl->version = (unsigned short)rec->rec_version;
}
RLAYERfatal(rl, SSL_AD_PROTOCOL_VERSION,
SSL_R_WRONG_VERSION_NUMBER);
return 0;
}
}
if (rec->length > SSL3_RT_MAX_PLAIN_LENGTH) {
/*
* We use SSL_R_DATA_LENGTH_TOO_LONG instead of
* SSL_R_ENCRYPTED_LENGTH_TOO_LONG here because we are the "any" method
* and we know that we are dealing with plaintext data
*/
RLAYERfatal(rl, SSL_AD_RECORD_OVERFLOW, SSL_R_DATA_LENGTH_TOO_LONG);
return 0;
}
return 1;
}
static int tls_any_set_protocol_version(OSSL_RECORD_LAYER *rl, int vers)
{
if (rl->version != TLS_ANY_VERSION && rl->version != vers)
return 0;
rl->version = vers;
return 1;
}
struct record_functions_st tls_any_funcs = {
tls_any_set_crypto_state,
tls_default_read_n,
tls_any_cipher,
NULL
NULL,
tls_any_set_protocol_version,
tls_validate_record_header,
tls_default_post_process_record
};

View File

@ -1783,6 +1783,8 @@ static int ssl_post_record_layer_select(SSL_CONNECTION *s)
SSL_set_options(ssl, SSL_OP_NO_RENEGOTIATION);
}
#endif
if (SSL_IS_FIRST_HANDSHAKE(s) && s->rrlmethod->set_first_handshake != NULL)
s->rrlmethod->set_first_handshake(s->rrl, 1);
return 1;
}

View File

@ -284,6 +284,22 @@ struct ossl_record_method_st {
*/
int (*set1_bio)(OSSL_RECORD_LAYER *rl, BIO *bio);
/* Called when protocol negotiation selects a protocol version to use */
int (*set_protocol_version)(OSSL_RECORD_LAYER *rl, int version);
/*
* Whether we are allowed to receive unencrypted alerts, even if we might
* otherwise expect encrypted records. Ignored by protocol versions where
* this isn't relevant
*/
void (*set_plain_alerts)(OSSL_RECORD_LAYER *rl, int allow);
/*
* Called immediately after creation of the recory layer if we are in a
* first handshake. Also called at the end of the first handshake
*/
void (*set_first_handshake)(OSSL_RECORD_LAYER *rl, int first);
/*
* TODO(RECLAYER): Remove these. These function pointers are temporary hacks
* during the record layer refactoring. They need to be removed before the

View File

@ -80,13 +80,6 @@ typedef enum {
ENC_WRITE_STATE_WRITE_PLAIN_ALERTS
} ENC_WRITE_STATES;
typedef enum {
/* The enc_read_ctx can be used normally */
ENC_READ_STATE_VALID,
/* We may receive encrypted or plaintext alerts */
ENC_READ_STATE_ALLOW_PLAIN_ALERTS
} ENC_READ_STATES;
/*****************************************************************************
* *
* This structure should be considered "opaque" to anything outside of the *
@ -117,7 +110,6 @@ struct ossl_statem_st {
unsigned int no_cert_verify;
int use_timer;
ENC_WRITE_STATES enc_write_state;
ENC_READ_STATES enc_read_state;
};
typedef struct ossl_statem_st OSSL_STATEM;

View File

@ -794,16 +794,18 @@ MSG_PROCESS_RETURN tls_process_finished(SSL_CONNECTION *s, PACKET *pkt)
{
size_t md_len;
SSL *ssl = SSL_CONNECTION_GET_SSL(s);
int was_first = SSL_IS_FIRST_HANDSHAKE(s);
/* This is a real handshake so make sure we clean it up at the end */
if (s->server) {
/*
* To get this far we must have read encrypted data from the client. We
* no longer tolerate unencrypted alerts. This value is ignored if less
* than TLSv1.3
* no longer tolerate unencrypted alerts. This is ignored if less than
* TLSv1.3
*/
s->statem.enc_read_state = ENC_READ_STATE_VALID;
if (s->rrlmethod->set_plain_alerts != NULL)
s->rrlmethod->set_plain_alerts(s->rrl, 0);
if (s->post_handshake_auth != SSL_PHA_REQUESTED)
s->statem.cleanuphand = 1;
if (SSL_CONNECTION_IS_TLS13(s)
@ -893,6 +895,11 @@ MSG_PROCESS_RETURN tls_process_finished(SSL_CONNECTION *s, PACKET *pkt)
}
}
if (was_first
&& !SSL_IS_FIRST_HANDSHAKE(s)
&& s->rrlmethod->set_first_handshake != NULL)
s->rrlmethod->set_first_handshake(s->rrl, 0);
return MSG_PROCESS_FINISHED_READING;
}
@ -1873,6 +1880,9 @@ int ssl_choose_server_version(SSL_CONNECTION *s, CLIENTHELLO_MSG *hello,
check_for_downgrade(s, best_vers, dgrd);
s->version = best_vers;
ssl->method = best_method;
if (!s->rrlmethod->set_protocol_version(s->rrl, best_vers))
return ERR_R_INTERNAL_ERROR;
return 0;
}
return SSL_R_UNSUPPORTED_PROTOCOL;
@ -1900,6 +1910,9 @@ int ssl_choose_server_version(SSL_CONNECTION *s, CLIENTHELLO_MSG *hello,
check_for_downgrade(s, vent->version, dgrd);
s->version = vent->version;
ssl->method = method;
if (!s->rrlmethod->set_protocol_version(s->rrl, s->version))
return ERR_R_INTERNAL_ERROR;
return 0;
}
disabled = 1;
@ -1959,6 +1972,10 @@ int ssl_choose_client_version(SSL_CONNECTION *s, int version,
* versions they don't want. If not, then easy to fix, just return
* ssl_method_error(s, s->method)
*/
if (!s->rrlmethod->set_protocol_version(s->rrl, s->version)) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return 0;
}
return 1;
case TLS_ANY_VERSION:
table = tls_version_table;
@ -2019,6 +2036,10 @@ int ssl_choose_client_version(SSL_CONNECTION *s, int version,
continue;
ssl->method = vent->cmeth();
if (!s->rrlmethod->set_protocol_version(s->rrl, s->version)) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return 0;
}
return 1;
}

View File

@ -914,7 +914,8 @@ WORK_STATE ossl_statem_server_post_work(SSL_CONNECTION *s, WORK_STATE wst)
* is an unencrypted alert, an encrypted alert, or an encrypted
* handshake message. We temporarily tolerate unencrypted alerts.
*/
s->statem.enc_read_state = ENC_READ_STATE_ALLOW_PLAIN_ALERTS;
if (s->rrlmethod->set_plain_alerts != NULL)
s->rrlmethod->set_plain_alerts(s->rrl, 1);
break;
}
@ -3455,10 +3456,10 @@ MSG_PROCESS_RETURN tls_process_client_certificate(SSL_CONNECTION *s,
/*
* To get this far we must have read encrypted data from the client. We no
* longer tolerate unencrypted alerts. This value is ignored if less than
* TLSv1.3
* longer tolerate unencrypted alerts. This is ignored if less than TLSv1.3
*/
s->statem.enc_read_state = ENC_READ_STATE_VALID;
if (s->rrlmethod->set_plain_alerts != NULL)
s->rrlmethod->set_plain_alerts(s->rrl, 0);
if ((sk = sk_X509_new_null()) == NULL) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE);