mirror of https://github.com/openssl/openssl.git
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:
parent
5b24990ba4
commit
1853d20a00
|
@ -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
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue