Update - OpenSSL 1.1.1-pre7-dev
This commit is contained in:
@@ -307,9 +307,8 @@ static const EXTENSION_DEFINITION ext_defs[] = {
|
||||
},
|
||||
{
|
||||
TLSEXT_TYPE_supported_versions,
|
||||
SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS1_2_SERVER_HELLO
|
||||
| SSL_EXT_TLS1_3_SERVER_HELLO | SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST
|
||||
| SSL_EXT_TLS_IMPLEMENTATION_ONLY,
|
||||
SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS1_3_SERVER_HELLO
|
||||
| SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST | SSL_EXT_TLS_IMPLEMENTATION_ONLY,
|
||||
NULL,
|
||||
/* Processed inline as part of version selection */
|
||||
NULL, tls_parse_stoc_supported_versions,
|
||||
@@ -1560,7 +1559,8 @@ int tls_psk_do_binder(SSL *s, const EVP_MD *md, const unsigned char *msgstart,
|
||||
goto err;
|
||||
}
|
||||
|
||||
mackey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, finishedkey, hashsize);
|
||||
mackey = EVP_PKEY_new_raw_private_key(EVP_PKEY_HMAC, NULL, finishedkey,
|
||||
hashsize);
|
||||
if (mackey == NULL) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PSK_DO_BINDER,
|
||||
ERR_R_INTERNAL_ERROR);
|
||||
|
||||
@@ -538,7 +538,9 @@ EXT_RETURN tls_construct_ctos_supported_versions(SSL *s, WPACKET *pkt,
|
||||
for (currv = max_version; currv >= min_version; currv--) {
|
||||
/* TODO(TLS1.3): Remove this first if clause prior to release!! */
|
||||
if (currv == TLS1_3_VERSION) {
|
||||
if (!WPACKET_put_bytes_u16(pkt, TLS1_3_VERSION_DRAFT)) {
|
||||
if (!WPACKET_put_bytes_u16(pkt, TLS1_3_VERSION_DRAFT)
|
||||
|| !WPACKET_put_bytes_u16(pkt, TLS1_3_VERSION_DRAFT_27)
|
||||
|| !WPACKET_put_bytes_u16(pkt, TLS1_3_VERSION_DRAFT_26)) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR,
|
||||
SSL_F_TLS_CONSTRUCT_CTOS_SUPPORTED_VERSIONS,
|
||||
ERR_R_INTERNAL_ERROR);
|
||||
@@ -744,7 +746,9 @@ EXT_RETURN tls_construct_ctos_early_data(SSL *s, WPACKET *pkt,
|
||||
unsigned int context, X509 *x,
|
||||
size_t chainidx)
|
||||
{
|
||||
#ifndef OPENSSL_NO_PSK
|
||||
char identity[PSK_MAX_IDENTITY_LEN + 1];
|
||||
#endif /* OPENSSL_NO_PSK */
|
||||
const unsigned char *id = NULL;
|
||||
size_t idlen = 0;
|
||||
SSL_SESSION *psksess = NULL;
|
||||
@@ -764,6 +768,7 @@ EXT_RETURN tls_construct_ctos_early_data(SSL *s, WPACKET *pkt,
|
||||
return EXT_RETURN_FAIL;
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_PSK
|
||||
if (psksess == NULL && s->psk_client_callback != NULL) {
|
||||
unsigned char psk[PSK_MAX_PSK_LEN];
|
||||
size_t psklen = 0;
|
||||
@@ -815,6 +820,7 @@ EXT_RETURN tls_construct_ctos_early_data(SSL *s, WPACKET *pkt,
|
||||
OPENSSL_cleanse(psk, psklen);
|
||||
}
|
||||
}
|
||||
#endif /* OPENSSL_NO_PSK */
|
||||
|
||||
SSL_SESSION_free(s->psksession);
|
||||
s->psksession = psksess;
|
||||
@@ -1675,7 +1681,15 @@ int tls_parse_stoc_alpn(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
|
||||
s->ext.early_data_ok = 0;
|
||||
}
|
||||
if (!s->hit) {
|
||||
/* If a new session then update it with the selected ALPN */
|
||||
/*
|
||||
* This is a new session and so alpn_selected should have been
|
||||
* initialised to NULL. We should update it with the selected ALPN.
|
||||
*/
|
||||
if (!ossl_assert(s->session->ext.alpn_selected == NULL)) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_STOC_ALPN,
|
||||
ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
s->session->ext.alpn_selected =
|
||||
OPENSSL_memdup(s->s3->alpn_selected, s->s3->alpn_selected_len);
|
||||
if (s->session->ext.alpn_selected == NULL) {
|
||||
@@ -1777,24 +1791,26 @@ int tls_parse_stoc_supported_versions(SSL *s, PACKET *pkt, unsigned int context,
|
||||
}
|
||||
|
||||
/* TODO(TLS1.3): Remove this before release */
|
||||
if (version == TLS1_3_VERSION_DRAFT)
|
||||
if (version == TLS1_3_VERSION_DRAFT
|
||||
|| version == TLS1_3_VERSION_DRAFT_27
|
||||
|| version == TLS1_3_VERSION_DRAFT_26)
|
||||
version = TLS1_3_VERSION;
|
||||
|
||||
/* We ignore this extension for HRRs except to sanity check it */
|
||||
if (context == SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST) {
|
||||
/*
|
||||
* The only protocol version we support which has an HRR message is
|
||||
* TLSv1.3, therefore we shouldn't be getting an HRR for anything else.
|
||||
*/
|
||||
if (version != TLS1_3_VERSION) {
|
||||
SSLfatal(s, SSL_AD_PROTOCOL_VERSION,
|
||||
SSL_F_TLS_PARSE_STOC_SUPPORTED_VERSIONS,
|
||||
SSL_R_BAD_HRR_VERSION);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
/*
|
||||
* The only protocol version we support which is valid in this extension in
|
||||
* a ServerHello is TLSv1.3 therefore we shouldn't be getting anything else.
|
||||
*/
|
||||
if (version != TLS1_3_VERSION) {
|
||||
SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER,
|
||||
SSL_F_TLS_PARSE_STOC_SUPPORTED_VERSIONS,
|
||||
SSL_R_BAD_PROTOCOL_VERSION_NUMBER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* We ignore this extension for HRRs except to sanity check it */
|
||||
if (context == SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST)
|
||||
return 1;
|
||||
|
||||
/* We just set it here. We validate it in ssl_choose_client_version */
|
||||
s->version = version;
|
||||
|
||||
|
||||
@@ -324,6 +324,10 @@ int tls_parse_ctos_status_request(SSL *s, PACKET *pkt, unsigned int context,
|
||||
{
|
||||
PACKET responder_id_list, exts;
|
||||
|
||||
/* We ignore this in a resumption handshake */
|
||||
if (s->hit)
|
||||
return 1;
|
||||
|
||||
/* Not defined if we get one of these in a client Certificate */
|
||||
if (x != NULL)
|
||||
return 1;
|
||||
@@ -717,6 +721,7 @@ int tls_parse_ctos_key_share(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
|
||||
int tls_parse_ctos_cookie(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
|
||||
size_t chainidx)
|
||||
{
|
||||
#ifndef OPENSSL_NO_TLS1_3
|
||||
unsigned int format, version, key_share, group_id;
|
||||
EVP_MD_CTX *hctx;
|
||||
EVP_PKEY *pkey;
|
||||
@@ -752,9 +757,10 @@ int tls_parse_ctos_cookie(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
|
||||
|
||||
/* Verify the HMAC of the cookie */
|
||||
hctx = EVP_MD_CTX_create();
|
||||
pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL,
|
||||
s->session_ctx->ext.cookie_hmac_key,
|
||||
sizeof(s->session_ctx->ext.cookie_hmac_key));
|
||||
pkey = EVP_PKEY_new_raw_private_key(EVP_PKEY_HMAC, NULL,
|
||||
s->session_ctx->ext.cookie_hmac_key,
|
||||
sizeof(s->session_ctx->ext
|
||||
.cookie_hmac_key));
|
||||
if (hctx == NULL || pkey == NULL) {
|
||||
EVP_MD_CTX_free(hctx);
|
||||
EVP_PKEY_free(pkey);
|
||||
@@ -887,7 +893,7 @@ int tls_parse_ctos_cookie(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
|
||||
if (!WPACKET_put_bytes_u16(&hrrpkt, TLSEXT_TYPE_supported_versions)
|
||||
|| !WPACKET_start_sub_packet_u16(&hrrpkt)
|
||||
/* TODO(TLS1.3): Fix this before release */
|
||||
|| !WPACKET_put_bytes_u16(&hrrpkt, TLS1_3_VERSION_DRAFT)
|
||||
|| !WPACKET_put_bytes_u16(&hrrpkt, s->version_draft)
|
||||
|| !WPACKET_close(&hrrpkt)) {
|
||||
WPACKET_cleanup(&hrrpkt);
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE,
|
||||
@@ -931,6 +937,7 @@ int tls_parse_ctos_cookie(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
|
||||
s->hello_retry_request = 1;
|
||||
|
||||
s->ext.cookieok = 1;
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -1025,6 +1032,7 @@ int tls_parse_ctos_psk(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
|
||||
return 0;
|
||||
}
|
||||
|
||||
s->ext.ticket_expected = 0;
|
||||
for (id = 0; PACKET_remaining(&identities) != 0; id++) {
|
||||
PACKET identity;
|
||||
unsigned long ticket_agel;
|
||||
@@ -1046,6 +1054,7 @@ int tls_parse_ctos_psk(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_PSK
|
||||
if(sess == NULL
|
||||
&& s->psk_server_callback != NULL
|
||||
&& idlen <= PSK_MAX_IDENTITY_LEN) {
|
||||
@@ -1096,6 +1105,7 @@ int tls_parse_ctos_psk(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
|
||||
OPENSSL_cleanse(pskdata, pskdatalen);
|
||||
}
|
||||
}
|
||||
#endif /* OPENSSL_NO_PSK */
|
||||
|
||||
if (sess != NULL) {
|
||||
/* We found a PSK */
|
||||
@@ -1120,9 +1130,17 @@ int tls_parse_ctos_psk(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
|
||||
s->ext.early_data_ok = 1;
|
||||
} else {
|
||||
uint32_t ticket_age = 0, now, agesec, agems;
|
||||
int ret = tls_decrypt_ticket(s, PACKET_data(&identity),
|
||||
PACKET_remaining(&identity), NULL, 0,
|
||||
&sess);
|
||||
int ret;
|
||||
|
||||
ret = tls_decrypt_ticket(s, PACKET_data(&identity),
|
||||
PACKET_remaining(&identity), NULL, 0,
|
||||
&sess);
|
||||
|
||||
if (ret == SSL_TICKET_EMPTY) {
|
||||
SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_CTOS_PSK,
|
||||
SSL_R_BAD_EXTENSION);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ret == SSL_TICKET_FATAL_ERR_MALLOC
|
||||
|| ret == SSL_TICKET_FATAL_ERR_OTHER) {
|
||||
@@ -1130,9 +1148,17 @@ int tls_parse_ctos_psk(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
|
||||
SSL_F_TLS_PARSE_CTOS_PSK, ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
if (ret == SSL_TICKET_NO_DECRYPT)
|
||||
if (ret == SSL_TICKET_NONE || ret == SSL_TICKET_NO_DECRYPT)
|
||||
continue;
|
||||
|
||||
/* Check for replay */
|
||||
if (s->max_early_data > 0
|
||||
&& !SSL_CTX_remove_session(s->session_ctx, sess)) {
|
||||
SSL_SESSION_free(sess);
|
||||
sess = NULL;
|
||||
continue;
|
||||
}
|
||||
|
||||
ticket_age = (uint32_t)ticket_agel;
|
||||
now = (uint32_t)time(NULL);
|
||||
agesec = now - (uint32_t)sess->time;
|
||||
@@ -1572,13 +1598,17 @@ EXT_RETURN tls_construct_stoc_supported_versions(SSL *s, WPACKET *pkt,
|
||||
unsigned int context, X509 *x,
|
||||
size_t chainidx)
|
||||
{
|
||||
if (!SSL_IS_TLS13(s))
|
||||
return EXT_RETURN_NOT_SENT;
|
||||
if (!ossl_assert(SSL_IS_TLS13(s))) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR,
|
||||
SSL_F_TLS_CONSTRUCT_STOC_SUPPORTED_VERSIONS,
|
||||
ERR_R_INTERNAL_ERROR);
|
||||
return EXT_RETURN_FAIL;
|
||||
}
|
||||
|
||||
if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_supported_versions)
|
||||
|| !WPACKET_start_sub_packet_u16(pkt)
|
||||
/* TODO(TLS1.3): Update to remove the TLSv1.3 draft indicator */
|
||||
|| !WPACKET_put_bytes_u16(pkt, TLS1_3_VERSION_DRAFT)
|
||||
|| !WPACKET_put_bytes_u16(pkt, s->version_draft)
|
||||
|| !WPACKET_close(pkt)) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR,
|
||||
SSL_F_TLS_CONSTRUCT_STOC_SUPPORTED_VERSIONS,
|
||||
@@ -1666,14 +1696,16 @@ EXT_RETURN tls_construct_stoc_key_share(SSL *s, WPACKET *pkt,
|
||||
/* SSLfatal() already called */
|
||||
return EXT_RETURN_FAIL;
|
||||
}
|
||||
#endif
|
||||
|
||||
return EXT_RETURN_SENT;
|
||||
#else
|
||||
return EXT_RETURN_FAIL;
|
||||
#endif
|
||||
}
|
||||
|
||||
EXT_RETURN tls_construct_stoc_cookie(SSL *s, WPACKET *pkt, unsigned int context,
|
||||
X509 *x, size_t chainidx)
|
||||
{
|
||||
#ifndef OPENSSL_NO_TLS1_3
|
||||
unsigned char *hashval1, *hashval2, *appcookie1, *appcookie2, *cookie;
|
||||
unsigned char *hmac, *hmac2;
|
||||
size_t startlen, ciphlen, totcookielen, hashlen, hmaclen, appcookielen;
|
||||
@@ -1758,9 +1790,10 @@ EXT_RETURN tls_construct_stoc_cookie(SSL *s, WPACKET *pkt, unsigned int context,
|
||||
|
||||
/* HMAC the cookie */
|
||||
hctx = EVP_MD_CTX_create();
|
||||
pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL,
|
||||
s->session_ctx->ext.cookie_hmac_key,
|
||||
sizeof(s->session_ctx->ext.cookie_hmac_key));
|
||||
pkey = EVP_PKEY_new_raw_private_key(EVP_PKEY_HMAC, NULL,
|
||||
s->session_ctx->ext.cookie_hmac_key,
|
||||
sizeof(s->session_ctx->ext
|
||||
.cookie_hmac_key));
|
||||
if (hctx == NULL || pkey == NULL) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_STOC_COOKIE,
|
||||
ERR_R_MALLOC_FAILURE);
|
||||
@@ -1797,6 +1830,9 @@ EXT_RETURN tls_construct_stoc_cookie(SSL *s, WPACKET *pkt, unsigned int context,
|
||||
EVP_MD_CTX_free(hctx);
|
||||
EVP_PKEY_free(pkey);
|
||||
return ret;
|
||||
#else
|
||||
return EXT_RETURN_FAIL;
|
||||
#endif
|
||||
}
|
||||
|
||||
EXT_RETURN tls_construct_stoc_cryptopro_bug(SSL *s, WPACKET *pkt,
|
||||
|
||||
+2
-4
@@ -123,7 +123,7 @@ void ossl_statem_fatal(SSL *s, int al, int func, int reason, const char *file,
|
||||
s->statem.in_init = 1;
|
||||
s->statem.state = MSG_FLOW_ERROR;
|
||||
ERR_put_error(ERR_LIB_SSL, func, reason, file, line);
|
||||
if (al != SSL_AD_NO_ALERT)
|
||||
if (al != SSL_AD_NO_ALERT && !s->statem.invalid_enc_write_ctx)
|
||||
ssl3_send_alert(s, SSL3_AL_FATAL, al);
|
||||
}
|
||||
|
||||
@@ -589,10 +589,8 @@ static SUB_STATE_RETURN read_state_machine(SSL *s)
|
||||
* Validate that we are allowed to move to the new state and move
|
||||
* to that state if so
|
||||
*/
|
||||
if (!transition(s, mt)) {
|
||||
check_fatal(s, SSL_F_READ_STATE_MACHINE);
|
||||
if (!transition(s, mt))
|
||||
return SUB_STATE_ERROR;
|
||||
}
|
||||
|
||||
if (s->s3->tmp.message_size > max_message_size(s)) {
|
||||
SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_READ_STATE_MACHINE,
|
||||
|
||||
@@ -100,6 +100,7 @@ struct ossl_statem_st {
|
||||
/* Should we skip the CertificateVerify message? */
|
||||
unsigned int no_cert_verify;
|
||||
int use_timer;
|
||||
int invalid_enc_write_ctx;
|
||||
};
|
||||
typedef struct ossl_statem_st OSSL_STATEM;
|
||||
|
||||
|
||||
+23
-16
@@ -11,6 +11,7 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <assert.h>
|
||||
#include "../ssl_locl.h"
|
||||
#include "statem_locl.h"
|
||||
#include <openssl/buffer.h>
|
||||
@@ -374,6 +375,20 @@ int ossl_statem_client_read_transition(SSL *s, int mt)
|
||||
|
||||
err:
|
||||
/* No valid transition found */
|
||||
if (SSL_IS_DTLS(s) && mt == SSL3_MT_CHANGE_CIPHER_SPEC) {
|
||||
BIO *rbio;
|
||||
|
||||
/*
|
||||
* CCS messages don't have a message sequence number so this is probably
|
||||
* because of an out-of-order CCS. We'll just drop it.
|
||||
*/
|
||||
s->init_num = 0;
|
||||
s->rwstate = SSL_READING;
|
||||
rbio = SSL_get_rbio(s);
|
||||
BIO_clear_retry_flags(rbio);
|
||||
BIO_set_retry_read(rbio);
|
||||
return 0;
|
||||
}
|
||||
SSLfatal(s, SSL3_AD_UNEXPECTED_MESSAGE,
|
||||
SSL_F_OSSL_STATEM_CLIENT_READ_TRANSITION,
|
||||
SSL_R_UNEXPECTED_MESSAGE);
|
||||
@@ -1188,8 +1203,7 @@ int tls_construct_client_hello(SSL *s, WPACKET *pkt)
|
||||
s->tmp_session_id_len = sess_id_len;
|
||||
session_id = s->tmp_session_id;
|
||||
if (s->hello_retry_request == SSL_HRR_NONE
|
||||
&& ssl_randbytes(s, s->tmp_session_id,
|
||||
sess_id_len) <= 0) {
|
||||
&& RAND_bytes(s->tmp_session_id, sess_id_len) <= 0) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR,
|
||||
SSL_F_TLS_CONSTRUCT_CLIENT_HELLO,
|
||||
ERR_R_INTERNAL_ERROR);
|
||||
@@ -1199,14 +1213,14 @@ int tls_construct_client_hello(SSL *s, WPACKET *pkt)
|
||||
sess_id_len = 0;
|
||||
}
|
||||
} else {
|
||||
assert(s->session->session_id_length <= sizeof(s->session->session_id));
|
||||
sess_id_len = s->session->session_id_length;
|
||||
if (s->version == TLS1_3_VERSION) {
|
||||
s->tmp_session_id_len = sess_id_len;
|
||||
memcpy(s->tmp_session_id, s->session->session_id, sess_id_len);
|
||||
}
|
||||
}
|
||||
if (sess_id_len > sizeof(s->session->session_id)
|
||||
|| !WPACKET_start_sub_packet_u8(pkt)
|
||||
if (!WPACKET_start_sub_packet_u8(pkt)
|
||||
|| (sess_id_len != 0 && !WPACKET_memcpy(pkt, session_id,
|
||||
sess_id_len))
|
||||
|| !WPACKET_close(pkt)) {
|
||||
@@ -1898,7 +1912,7 @@ MSG_PROCESS_RETURN tls_process_server_certificate(SSL *s, PACKET *pkt)
|
||||
* set. The *documented* interface remains the same.
|
||||
*/
|
||||
if (s->verify_mode != SSL_VERIFY_NONE && i <= 0) {
|
||||
SSLfatal(s, ssl_verify_alarm_type(s->verify_result),
|
||||
SSLfatal(s, ssl_x509err2alert(s->verify_result),
|
||||
SSL_F_TLS_PROCESS_SERVER_CERTIFICATE,
|
||||
SSL_R_CERTIFICATE_VERIFY_FAILED);
|
||||
goto err;
|
||||
@@ -2192,7 +2206,8 @@ static int tls_process_ske_ecdhe(SSL *s, PACKET *pkt, EVP_PKEY **pkey)
|
||||
* Check curve is named curve type and one of our preferences, if not
|
||||
* server has sent an invalid curve.
|
||||
*/
|
||||
if (curve_type != NAMED_CURVE_TYPE || !tls1_check_group_id(s, curve_id)) {
|
||||
if (curve_type != NAMED_CURVE_TYPE
|
||||
|| !tls1_check_group_id(s, curve_id, 1)) {
|
||||
SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS_PROCESS_SKE_ECDHE,
|
||||
SSL_R_WRONG_CURVE);
|
||||
return 0;
|
||||
@@ -2575,7 +2590,6 @@ MSG_PROCESS_RETURN tls_process_new_session_ticket(SSL *s, PACKET *pkt)
|
||||
* cache.
|
||||
*/
|
||||
if (SSL_IS_TLS13(s) || s->session->session_id_length > 0) {
|
||||
int i = s->session_ctx->session_cache_mode;
|
||||
SSL_SESSION *new_sess;
|
||||
/*
|
||||
* We reused an existing session, so we need to replace it with a new
|
||||
@@ -2588,13 +2602,6 @@ MSG_PROCESS_RETURN tls_process_new_session_ticket(SSL *s, PACKET *pkt)
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (i & SSL_SESS_CACHE_CLIENT) {
|
||||
/*
|
||||
* Remove the old session from the cache. We carry on if this fails
|
||||
*/
|
||||
SSL_CTX_remove_session(s->session_ctx, s->session);
|
||||
}
|
||||
|
||||
SSL_SESSION_free(s->session);
|
||||
s->session = new_sess;
|
||||
}
|
||||
@@ -2925,7 +2932,7 @@ static int tls_construct_cke_rsa(SSL *s, WPACKET *pkt)
|
||||
pms[0] = s->client_version >> 8;
|
||||
pms[1] = s->client_version & 0xff;
|
||||
/* TODO(size_t): Convert this function */
|
||||
if (ssl_randbytes(s, pms + 2, (int)(pmslen - 2)) <= 0) {
|
||||
if (RAND_bytes(pms + 2, (int)(pmslen - 2)) <= 0) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_RSA,
|
||||
ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
@@ -3146,7 +3153,7 @@ static int tls_construct_cke_gost(SSL *s, WPACKET *pkt)
|
||||
/* Generate session key
|
||||
* TODO(size_t): Convert this function
|
||||
*/
|
||||
|| ssl_randbytes(s, pms, (int)pmslen) <= 0) {
|
||||
|| RAND_bytes(pms, (int)pmslen) <= 0) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_GOST,
|
||||
ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
|
||||
@@ -59,13 +59,14 @@ static hm_fragment *dtls1_hm_fragment_new(size_t frag_len, int reassembly)
|
||||
unsigned char *buf = NULL;
|
||||
unsigned char *bitmask = NULL;
|
||||
|
||||
frag = OPENSSL_malloc(sizeof(*frag));
|
||||
if (frag == NULL)
|
||||
if ((frag = OPENSSL_malloc(sizeof(*frag))) == NULL) {
|
||||
SSLerr(SSL_F_DTLS1_HM_FRAGMENT_NEW, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (frag_len) {
|
||||
buf = OPENSSL_malloc(frag_len);
|
||||
if (buf == NULL) {
|
||||
if ((buf = OPENSSL_malloc(frag_len)) == NULL) {
|
||||
SSLerr(SSL_F_DTLS1_HM_FRAGMENT_NEW, ERR_R_MALLOC_FAILURE);
|
||||
OPENSSL_free(frag);
|
||||
return NULL;
|
||||
}
|
||||
@@ -78,6 +79,7 @@ static hm_fragment *dtls1_hm_fragment_new(size_t frag_len, int reassembly)
|
||||
if (reassembly) {
|
||||
bitmask = OPENSSL_zalloc(RSMBLY_BITMASK_SIZE(frag_len));
|
||||
if (bitmask == NULL) {
|
||||
SSLerr(SSL_F_DTLS1_HM_FRAGMENT_NEW, ERR_R_MALLOC_FAILURE);
|
||||
OPENSSL_free(buf);
|
||||
OPENSSL_free(frag);
|
||||
return NULL;
|
||||
@@ -502,7 +504,7 @@ static int dtls1_retrieve_buffered_fragment(SSL *s, size_t *len)
|
||||
/* Calls SSLfatal() as required */
|
||||
ret = dtls1_preprocess_fragment(s, &frag->msg_header);
|
||||
|
||||
if (ret) {
|
||||
if (ret && frag->msg_header.frag_len > 0) {
|
||||
unsigned char *p =
|
||||
(unsigned char *)s->init_buf->data + DTLS1_HM_HEADER_LENGTH;
|
||||
memcpy(&p[frag->msg_header.frag_off], frag->fragment,
|
||||
@@ -922,9 +924,14 @@ int dtls_construct_change_cipher_spec(SSL *s, WPACKET *pkt)
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_SCTP
|
||||
/*
|
||||
* Wait for a dry event. Should only be called at a point in the handshake
|
||||
* where we are not expecting any data from the peer except an alert.
|
||||
*/
|
||||
WORK_STATE dtls_wait_for_dry(SSL *s)
|
||||
{
|
||||
int ret;
|
||||
int ret, errtype;
|
||||
size_t len;
|
||||
|
||||
/* read app data until dry event */
|
||||
ret = BIO_dgram_sctp_wait_for_dry(SSL_get_wbio(s));
|
||||
@@ -935,6 +942,19 @@ WORK_STATE dtls_wait_for_dry(SSL *s)
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/*
|
||||
* We're not expecting any more messages from the peer at this point -
|
||||
* but we could get an alert. If an alert is waiting then we will never
|
||||
* return successfully. Therefore we attempt to read a message. This
|
||||
* should never succeed but will process any waiting alerts.
|
||||
*/
|
||||
if (dtls_get_reassembled_message(s, &errtype, &len)) {
|
||||
/* The call succeeded! This should never happen */
|
||||
SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_F_DTLS_WAIT_FOR_DRY,
|
||||
SSL_R_UNEXPECTED_MESSAGE);
|
||||
return WORK_ERROR;
|
||||
}
|
||||
|
||||
s->s3->in_read_app_data = 2;
|
||||
s->rwstate = SSL_READING;
|
||||
BIO_clear_retry_flags(SSL_get_rbio(s));
|
||||
|
||||
+127
-87
@@ -19,6 +19,14 @@
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/x509.h>
|
||||
|
||||
/*
|
||||
* Map error codes to TLS/SSL alart types.
|
||||
*/
|
||||
typedef struct x509err2alert_st {
|
||||
int x509err;
|
||||
int alert;
|
||||
} X509ERR2ALERT;
|
||||
|
||||
/* Fixed value used in the ServerHello random field to identify an HRR */
|
||||
const unsigned char hrrrandom[] = {
|
||||
0xcf, 0x21, 0xad, 0x74, 0xe5, 0x9a, 0x61, 0x11, 0xbe, 0x1d, 0x8c, 0x02,
|
||||
@@ -1004,15 +1012,6 @@ WORK_STATE tls_finish_handshake(SSL *s, WORK_STATE wst, int clearbufs, int stop)
|
||||
int discard;
|
||||
void (*cb) (const SSL *ssl, int type, int val) = NULL;
|
||||
|
||||
#ifndef OPENSSL_NO_SCTP
|
||||
if (SSL_IS_DTLS(s) && BIO_dgram_is_sctp(SSL_get_wbio(s))) {
|
||||
WORK_STATE ret;
|
||||
ret = dtls_wait_for_dry(s);
|
||||
if (ret != WORK_FINISHED_CONTINUE)
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (clearbufs) {
|
||||
if (!SSL_IS_DTLS(s)) {
|
||||
/*
|
||||
@@ -1034,21 +1033,40 @@ WORK_STATE tls_finish_handshake(SSL *s, WORK_STATE wst, int clearbufs, int stop)
|
||||
&& s->post_handshake_auth == SSL_PHA_REQUESTED)
|
||||
s->post_handshake_auth = SSL_PHA_EXT_SENT;
|
||||
|
||||
/*
|
||||
* Only set if there was a Finished message and this isn't after a TLSv1.3
|
||||
* post handshake exchange
|
||||
*/
|
||||
if (s->statem.cleanuphand) {
|
||||
/* skipped if we just sent a HelloRequest */
|
||||
s->renegotiate = 0;
|
||||
s->new_session = 0;
|
||||
s->statem.cleanuphand = 0;
|
||||
s->ext.ticket_expected = 0;
|
||||
|
||||
ssl3_cleanup_key_block(s);
|
||||
|
||||
if (s->server) {
|
||||
ssl_update_cache(s, SSL_SESS_CACHE_SERVER);
|
||||
/*
|
||||
* In TLSv1.3 we update the cache as part of constructing the
|
||||
* NewSessionTicket
|
||||
*/
|
||||
if (!SSL_IS_TLS13(s))
|
||||
ssl_update_cache(s, SSL_SESS_CACHE_SERVER);
|
||||
|
||||
/* N.B. s->ctx may not equal s->session_ctx */
|
||||
CRYPTO_atomic_add(&s->ctx->stats.sess_accept_good, 1, &discard,
|
||||
s->ctx->lock);
|
||||
s->handshake_func = ossl_statem_accept;
|
||||
|
||||
if (SSL_IS_DTLS(s) && !s->hit) {
|
||||
/*
|
||||
* We are finishing after the client. We start the timer going
|
||||
* in case there are any retransmits of our final flight
|
||||
* required.
|
||||
*/
|
||||
dtls1_start_timer(s);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* In TLSv1.3 we update the cache as part of processing the
|
||||
@@ -1063,16 +1081,17 @@ WORK_STATE tls_finish_handshake(SSL *s, WORK_STATE wst, int clearbufs, int stop)
|
||||
s->handshake_func = ossl_statem_connect;
|
||||
CRYPTO_atomic_add(&s->session_ctx->stats.sess_connect_good, 1,
|
||||
&discard, s->session_ctx->lock);
|
||||
|
||||
if (SSL_IS_DTLS(s) && s->hit) {
|
||||
/*
|
||||
* We are finishing after the server. We start the timer going
|
||||
* in case there are any retransmits of our final flight
|
||||
* required.
|
||||
*/
|
||||
dtls1_start_timer(s);
|
||||
}
|
||||
}
|
||||
|
||||
if (s->info_callback != NULL)
|
||||
cb = s->info_callback;
|
||||
else if (s->ctx->info_callback != NULL)
|
||||
cb = s->ctx->info_callback;
|
||||
|
||||
if (cb != NULL)
|
||||
cb(s, SSL_CB_HANDSHAKE_DONE, 1);
|
||||
|
||||
if (SSL_IS_DTLS(s)) {
|
||||
/* done with handshaking */
|
||||
s->d1->handshake_read_seq = 0;
|
||||
@@ -1082,10 +1101,23 @@ WORK_STATE tls_finish_handshake(SSL *s, WORK_STATE wst, int clearbufs, int stop)
|
||||
}
|
||||
}
|
||||
|
||||
if (!stop)
|
||||
return WORK_FINISHED_CONTINUE;
|
||||
if (s->info_callback != NULL)
|
||||
cb = s->info_callback;
|
||||
else if (s->ctx->info_callback != NULL)
|
||||
cb = s->ctx->info_callback;
|
||||
|
||||
/* The callback may expect us to not be in init at handshake done */
|
||||
ossl_statem_set_in_init(s, 0);
|
||||
|
||||
if (cb != NULL)
|
||||
cb(s, SSL_CB_HANDSHAKE_DONE, 1);
|
||||
|
||||
if (!stop) {
|
||||
/* If we've got more work to do we go back into init */
|
||||
ossl_statem_set_in_init(s, 1);
|
||||
return WORK_FINISHED_CONTINUE;
|
||||
}
|
||||
|
||||
return WORK_FINISHED_STOP;
|
||||
}
|
||||
|
||||
@@ -1281,73 +1313,59 @@ int tls_get_message_body(SSL *s, size_t *len)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ssl_verify_alarm_type(long type)
|
||||
{
|
||||
int al;
|
||||
static const X509ERR2ALERT x509table[] = {
|
||||
{X509_V_ERR_APPLICATION_VERIFICATION, SSL_AD_HANDSHAKE_FAILURE},
|
||||
{X509_V_ERR_CA_KEY_TOO_SMALL, SSL_AD_BAD_CERTIFICATE},
|
||||
{X509_V_ERR_CA_MD_TOO_WEAK, SSL_AD_BAD_CERTIFICATE},
|
||||
{X509_V_ERR_CERT_CHAIN_TOO_LONG, SSL_AD_UNKNOWN_CA},
|
||||
{X509_V_ERR_CERT_HAS_EXPIRED, SSL_AD_CERTIFICATE_EXPIRED},
|
||||
{X509_V_ERR_CERT_NOT_YET_VALID, SSL_AD_BAD_CERTIFICATE},
|
||||
{X509_V_ERR_CERT_REJECTED, SSL_AD_BAD_CERTIFICATE},
|
||||
{X509_V_ERR_CERT_REVOKED, SSL_AD_CERTIFICATE_REVOKED},
|
||||
{X509_V_ERR_CERT_SIGNATURE_FAILURE, SSL_AD_DECRYPT_ERROR},
|
||||
{X509_V_ERR_CERT_UNTRUSTED, SSL_AD_BAD_CERTIFICATE},
|
||||
{X509_V_ERR_CRL_HAS_EXPIRED, SSL_AD_CERTIFICATE_EXPIRED},
|
||||
{X509_V_ERR_CRL_NOT_YET_VALID, SSL_AD_BAD_CERTIFICATE},
|
||||
{X509_V_ERR_CRL_SIGNATURE_FAILURE, SSL_AD_DECRYPT_ERROR},
|
||||
{X509_V_ERR_DANE_NO_MATCH, SSL_AD_BAD_CERTIFICATE},
|
||||
{X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT, SSL_AD_UNKNOWN_CA},
|
||||
{X509_V_ERR_EE_KEY_TOO_SMALL, SSL_AD_BAD_CERTIFICATE},
|
||||
{X509_V_ERR_EMAIL_MISMATCH, SSL_AD_BAD_CERTIFICATE},
|
||||
{X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD, SSL_AD_BAD_CERTIFICATE},
|
||||
{X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD, SSL_AD_BAD_CERTIFICATE},
|
||||
{X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD, SSL_AD_BAD_CERTIFICATE},
|
||||
{X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD, SSL_AD_BAD_CERTIFICATE},
|
||||
{X509_V_ERR_HOSTNAME_MISMATCH, SSL_AD_BAD_CERTIFICATE},
|
||||
{X509_V_ERR_INVALID_CA, SSL_AD_UNKNOWN_CA},
|
||||
{X509_V_ERR_INVALID_CALL, SSL_AD_INTERNAL_ERROR},
|
||||
{X509_V_ERR_INVALID_PURPOSE, SSL_AD_UNSUPPORTED_CERTIFICATE},
|
||||
{X509_V_ERR_IP_ADDRESS_MISMATCH, SSL_AD_BAD_CERTIFICATE},
|
||||
{X509_V_ERR_OUT_OF_MEM, SSL_AD_INTERNAL_ERROR},
|
||||
{X509_V_ERR_PATH_LENGTH_EXCEEDED, SSL_AD_UNKNOWN_CA},
|
||||
{X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN, SSL_AD_UNKNOWN_CA},
|
||||
{X509_V_ERR_STORE_LOOKUP, SSL_AD_INTERNAL_ERROR},
|
||||
{X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY, SSL_AD_BAD_CERTIFICATE},
|
||||
{X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE, SSL_AD_BAD_CERTIFICATE},
|
||||
{X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE, SSL_AD_BAD_CERTIFICATE},
|
||||
{X509_V_ERR_UNABLE_TO_GET_CRL, SSL_AD_UNKNOWN_CA},
|
||||
{X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER, SSL_AD_UNKNOWN_CA},
|
||||
{X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT, SSL_AD_UNKNOWN_CA},
|
||||
{X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY, SSL_AD_UNKNOWN_CA},
|
||||
{X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE, SSL_AD_UNKNOWN_CA},
|
||||
{X509_V_ERR_UNSPECIFIED, SSL_AD_INTERNAL_ERROR},
|
||||
|
||||
switch (type) {
|
||||
case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
|
||||
case X509_V_ERR_UNABLE_TO_GET_CRL:
|
||||
case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER:
|
||||
al = SSL_AD_UNKNOWN_CA;
|
||||
break;
|
||||
case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
|
||||
case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:
|
||||
case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
|
||||
case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
|
||||
case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
|
||||
case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
|
||||
case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
|
||||
case X509_V_ERR_CERT_NOT_YET_VALID:
|
||||
case X509_V_ERR_CRL_NOT_YET_VALID:
|
||||
case X509_V_ERR_CERT_UNTRUSTED:
|
||||
case X509_V_ERR_CERT_REJECTED:
|
||||
case X509_V_ERR_HOSTNAME_MISMATCH:
|
||||
case X509_V_ERR_EMAIL_MISMATCH:
|
||||
case X509_V_ERR_IP_ADDRESS_MISMATCH:
|
||||
case X509_V_ERR_DANE_NO_MATCH:
|
||||
case X509_V_ERR_EE_KEY_TOO_SMALL:
|
||||
case X509_V_ERR_CA_KEY_TOO_SMALL:
|
||||
case X509_V_ERR_CA_MD_TOO_WEAK:
|
||||
al = SSL_AD_BAD_CERTIFICATE;
|
||||
break;
|
||||
case X509_V_ERR_CERT_SIGNATURE_FAILURE:
|
||||
case X509_V_ERR_CRL_SIGNATURE_FAILURE:
|
||||
al = SSL_AD_DECRYPT_ERROR;
|
||||
break;
|
||||
case X509_V_ERR_CERT_HAS_EXPIRED:
|
||||
case X509_V_ERR_CRL_HAS_EXPIRED:
|
||||
al = SSL_AD_CERTIFICATE_EXPIRED;
|
||||
break;
|
||||
case X509_V_ERR_CERT_REVOKED:
|
||||
al = SSL_AD_CERTIFICATE_REVOKED;
|
||||
break;
|
||||
case X509_V_ERR_UNSPECIFIED:
|
||||
case X509_V_ERR_OUT_OF_MEM:
|
||||
case X509_V_ERR_INVALID_CALL:
|
||||
case X509_V_ERR_STORE_LOOKUP:
|
||||
al = SSL_AD_INTERNAL_ERROR;
|
||||
break;
|
||||
case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
|
||||
case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
|
||||
case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
|
||||
case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
|
||||
case X509_V_ERR_CERT_CHAIN_TOO_LONG:
|
||||
case X509_V_ERR_PATH_LENGTH_EXCEEDED:
|
||||
case X509_V_ERR_INVALID_CA:
|
||||
al = SSL_AD_UNKNOWN_CA;
|
||||
break;
|
||||
case X509_V_ERR_APPLICATION_VERIFICATION:
|
||||
al = SSL_AD_HANDSHAKE_FAILURE;
|
||||
break;
|
||||
case X509_V_ERR_INVALID_PURPOSE:
|
||||
al = SSL_AD_UNSUPPORTED_CERTIFICATE;
|
||||
break;
|
||||
default:
|
||||
al = SSL_AD_CERTIFICATE_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
return al;
|
||||
/* Last entry; return this if we don't find the value above. */
|
||||
{X509_V_OK, SSL_AD_CERTIFICATE_UNKNOWN}
|
||||
};
|
||||
|
||||
int ssl_x509err2alert(int x509err)
|
||||
{
|
||||
const X509ERR2ALERT *tp;
|
||||
|
||||
for (tp = x509table; tp->x509err != X509_V_OK; ++tp)
|
||||
if (tp->x509err == x509err)
|
||||
break;
|
||||
return tp->alert;
|
||||
}
|
||||
|
||||
int ssl_allow_compression(SSL *s)
|
||||
@@ -1677,6 +1695,8 @@ int ssl_choose_server_version(SSL *s, CLIENTHELLO_MSG *hello, DOWNGRADE *dgrd)
|
||||
unsigned int best_vers = 0;
|
||||
const SSL_METHOD *best_method = NULL;
|
||||
PACKET versionslist;
|
||||
/* TODO(TLS1.3): Remove this before release */
|
||||
unsigned int orig_candidate = 0;
|
||||
|
||||
suppversions->parsed = 1;
|
||||
|
||||
@@ -1687,8 +1707,18 @@ int ssl_choose_server_version(SSL *s, CLIENTHELLO_MSG *hello, DOWNGRADE *dgrd)
|
||||
|
||||
while (PACKET_get_net_2(&versionslist, &candidate_vers)) {
|
||||
/* TODO(TLS1.3): Remove this before release */
|
||||
if (candidate_vers == TLS1_3_VERSION_DRAFT)
|
||||
if (candidate_vers == TLS1_3_VERSION_DRAFT
|
||||
|| candidate_vers == TLS1_3_VERSION_DRAFT_27
|
||||
|| candidate_vers == TLS1_3_VERSION_DRAFT_26) {
|
||||
if (best_vers == TLS1_3_VERSION
|
||||
&& orig_candidate > candidate_vers)
|
||||
continue;
|
||||
orig_candidate = candidate_vers;
|
||||
candidate_vers = TLS1_3_VERSION;
|
||||
} else if (candidate_vers == TLS1_3_VERSION) {
|
||||
/* Don't actually accept real TLSv1.3 */
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
* TODO(TLS1.3): There is some discussion on the TLS list about
|
||||
* whether to ignore versions <TLS1.2 in supported_versions. At the
|
||||
@@ -1727,6 +1757,9 @@ int ssl_choose_server_version(SSL *s, CLIENTHELLO_MSG *hello, DOWNGRADE *dgrd)
|
||||
}
|
||||
check_for_downgrade(s, best_vers, dgrd);
|
||||
s->version = best_vers;
|
||||
/* TODO(TLS1.3): Remove this before release */
|
||||
if (best_vers == TLS1_3_VERSION)
|
||||
s->version_draft = orig_candidate;
|
||||
s->method = best_method;
|
||||
return 0;
|
||||
}
|
||||
@@ -2005,6 +2038,13 @@ int ssl_set_client_hello_version(SSL *s)
|
||||
{
|
||||
int ver_min, ver_max, ret;
|
||||
|
||||
/*
|
||||
* In a renegotiation we always send the same client_version that we sent
|
||||
* last time, regardless of which version we eventually negotiated.
|
||||
*/
|
||||
if (!SSL_IS_FIRST_HANDSHAKE(s))
|
||||
return 0;
|
||||
|
||||
ret = ssl_get_min_max_version(s, &ver_min, &ver_max);
|
||||
|
||||
if (ret != 0)
|
||||
|
||||
+164
-56
@@ -277,6 +277,20 @@ int ossl_statem_server_read_transition(SSL *s, int mt)
|
||||
|
||||
err:
|
||||
/* No valid transition found */
|
||||
if (SSL_IS_DTLS(s) && mt == SSL3_MT_CHANGE_CIPHER_SPEC) {
|
||||
BIO *rbio;
|
||||
|
||||
/*
|
||||
* CCS messages don't have a message sequence number so this is probably
|
||||
* because of an out-of-order CCS. We'll just drop it.
|
||||
*/
|
||||
s->init_num = 0;
|
||||
s->rwstate = SSL_READING;
|
||||
rbio = SSL_get_rbio(s);
|
||||
BIO_clear_retry_flags(rbio);
|
||||
BIO_set_retry_read(rbio);
|
||||
return 0;
|
||||
}
|
||||
SSLfatal(s, SSL3_AD_UNEXPECTED_MESSAGE,
|
||||
SSL_F_OSSL_STATEM_SERVER_READ_TRANSITION,
|
||||
SSL_R_UNEXPECTED_MESSAGE);
|
||||
@@ -466,15 +480,23 @@ static WRITE_TRAN ossl_statem_server13_write_transition(SSL *s)
|
||||
case TLS_ST_SR_FINISHED:
|
||||
/*
|
||||
* Technically we have finished the handshake at this point, but we're
|
||||
* going to remain "in_init" for now and write out the session ticket
|
||||
* going to remain "in_init" for now and write out any session tickets
|
||||
* immediately.
|
||||
* TODO(TLS1.3): Perhaps we need to be able to control this behaviour
|
||||
* and give the application the opportunity to delay sending the
|
||||
* session ticket?
|
||||
*/
|
||||
if (s->post_handshake_auth == SSL_PHA_REQUESTED)
|
||||
if (s->post_handshake_auth == SSL_PHA_REQUESTED) {
|
||||
s->post_handshake_auth = SSL_PHA_EXT_RECEIVED;
|
||||
st->hand_state = TLS_ST_SW_SESSION_TICKET;
|
||||
} else if (!s->ext.ticket_expected) {
|
||||
/*
|
||||
* If we're not going to renew the ticket then we just finish the
|
||||
* handshake at this point.
|
||||
*/
|
||||
st->hand_state = TLS_ST_OK;
|
||||
return WRITE_TRAN_CONTINUE;
|
||||
}
|
||||
if (s->num_tickets > s->sent_tickets)
|
||||
st->hand_state = TLS_ST_SW_SESSION_TICKET;
|
||||
else
|
||||
st->hand_state = TLS_ST_OK;
|
||||
return WRITE_TRAN_CONTINUE;
|
||||
|
||||
case TLS_ST_SR_KEY_UPDATE:
|
||||
@@ -485,9 +507,19 @@ static WRITE_TRAN ossl_statem_server13_write_transition(SSL *s)
|
||||
/* Fall through */
|
||||
|
||||
case TLS_ST_SW_KEY_UPDATE:
|
||||
case TLS_ST_SW_SESSION_TICKET:
|
||||
st->hand_state = TLS_ST_OK;
|
||||
return WRITE_TRAN_CONTINUE;
|
||||
|
||||
case TLS_ST_SW_SESSION_TICKET:
|
||||
/* In a resumption we only ever send a maximum of one new ticket.
|
||||
* Following an initial handshake we send the number of tickets we have
|
||||
* been configured for.
|
||||
*/
|
||||
if (s->hit || s->num_tickets <= s->sent_tickets) {
|
||||
/* We've written enough tickets out. */
|
||||
st->hand_state = TLS_ST_OK;
|
||||
}
|
||||
return WRITE_TRAN_CONTINUE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -679,7 +711,7 @@ WORK_STATE ossl_statem_server_pre_work(SSL *s, WORK_STATE wst)
|
||||
return WORK_FINISHED_CONTINUE;
|
||||
|
||||
case TLS_ST_SW_SESSION_TICKET:
|
||||
if (SSL_IS_TLS13(s)) {
|
||||
if (SSL_IS_TLS13(s) && s->sent_tickets == 0) {
|
||||
/*
|
||||
* Actually this is the end of the handshake, but we're going
|
||||
* straight into writing the session ticket out. So we finish off
|
||||
@@ -1676,7 +1708,7 @@ static int tls_early_post_process_client_hello(SSL *s)
|
||||
/* For TLSv1.3 we must select the ciphersuite *before* session resumption */
|
||||
if (SSL_IS_TLS13(s)) {
|
||||
const SSL_CIPHER *cipher =
|
||||
ssl3_choose_cipher(s, ciphers, ssl_get_cipher_preferences(s));
|
||||
ssl3_choose_cipher(s, ciphers, SSL_get_ciphers(s));
|
||||
|
||||
if (cipher == NULL) {
|
||||
SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE,
|
||||
@@ -1857,7 +1889,7 @@ static int tls_early_post_process_client_hello(SSL *s)
|
||||
/* check if some cipher was preferred by call back */
|
||||
if (pref_cipher == NULL)
|
||||
pref_cipher = ssl3_choose_cipher(s, s->session->ciphers,
|
||||
ssl_get_cipher_preferences(s));
|
||||
SSL_get_ciphers(s));
|
||||
if (pref_cipher == NULL) {
|
||||
SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE,
|
||||
SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO,
|
||||
@@ -1866,9 +1898,8 @@ static int tls_early_post_process_client_hello(SSL *s)
|
||||
}
|
||||
|
||||
s->session->cipher = pref_cipher;
|
||||
ssl_cipher_preference_list_free(s->cipher_list);
|
||||
s->cipher_list = ssl_cipher_preference_list_from_ciphers(
|
||||
s->session->ciphers);
|
||||
sk_SSL_CIPHER_free(s->cipher_list);
|
||||
s->cipher_list = sk_SSL_CIPHER_dup(s->session->ciphers);
|
||||
sk_SSL_CIPHER_free(s->cipher_list_by_id);
|
||||
s->cipher_list_by_id = sk_SSL_CIPHER_dup(s->session->ciphers);
|
||||
}
|
||||
@@ -2101,7 +2132,17 @@ int tls_handle_alpn(SSL *s)
|
||||
s->ext.early_data_ok = 0;
|
||||
|
||||
if (!s->hit) {
|
||||
/* If a new session update it with the new ALPN value */
|
||||
/*
|
||||
* This is a new session and so alpn_selected should have
|
||||
* been initialised to NULL. We should update it with the
|
||||
* selected ALPN.
|
||||
*/
|
||||
if (!ossl_assert(s->session->ext.alpn_selected == NULL)) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR,
|
||||
SSL_F_TLS_HANDLE_ALPN,
|
||||
ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
s->session->ext.alpn_selected = OPENSSL_memdup(selected,
|
||||
selected_len);
|
||||
if (s->session->ext.alpn_selected == NULL) {
|
||||
@@ -2170,7 +2211,7 @@ WORK_STATE tls_post_process_client_hello(SSL *s, WORK_STATE wst)
|
||||
/* In TLSv1.3 we selected the ciphersuite before resumption */
|
||||
if (!SSL_IS_TLS13(s)) {
|
||||
cipher =
|
||||
ssl3_choose_cipher(s, s->session->ciphers, ssl_get_cipher_preferences(s));
|
||||
ssl3_choose_cipher(s, s->session->ciphers, SSL_get_ciphers(s));
|
||||
|
||||
if (cipher == NULL) {
|
||||
SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE,
|
||||
@@ -2472,6 +2513,12 @@ int tls_construct_server_key_exchange(SSL *s, WPACKET *pkt)
|
||||
}
|
||||
|
||||
dh = EVP_PKEY_get0_DH(s->s3->tmp.pkey);
|
||||
if (dh == NULL) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR,
|
||||
SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE,
|
||||
ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
|
||||
EVP_PKEY_free(pkdh);
|
||||
pkdh = NULL;
|
||||
@@ -2738,7 +2785,7 @@ int tls_construct_certificate_request(SSL *s, WPACKET *pkt)
|
||||
OPENSSL_free(s->pha_context);
|
||||
s->pha_context_len = 32;
|
||||
if ((s->pha_context = OPENSSL_malloc(s->pha_context_len)) == NULL
|
||||
|| ssl_randbytes(s, s->pha_context, s->pha_context_len) <= 0
|
||||
|| RAND_bytes(s->pha_context, s->pha_context_len) <= 0
|
||||
|| !WPACKET_sub_memcpy_u8(pkt, s->pha_context, s->pha_context_len)) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR,
|
||||
SSL_F_TLS_CONSTRUCT_CERTIFICATE_REQUEST,
|
||||
@@ -2927,7 +2974,7 @@ static int tls_process_cke_rsa(SSL *s, PACKET *pkt)
|
||||
* fails. See https://tools.ietf.org/html/rfc5246#section-7.4.7.1
|
||||
*/
|
||||
|
||||
if (ssl_randbytes(s, rand_premaster_secret,
|
||||
if (RAND_priv_bytes(rand_premaster_secret,
|
||||
sizeof(rand_premaster_secret)) <= 0) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CKE_RSA,
|
||||
ERR_R_INTERNAL_ERROR);
|
||||
@@ -3224,11 +3271,9 @@ static int tls_process_cke_gost(SSL *s, PACKET *pkt)
|
||||
const unsigned char *start;
|
||||
size_t outlen = 32, inlen;
|
||||
unsigned long alg_a;
|
||||
int Ttag, Tclass;
|
||||
long Tlen;
|
||||
size_t sess_key_len;
|
||||
const unsigned char *data;
|
||||
unsigned int asn1id, asn1len;
|
||||
int ret = 0;
|
||||
PACKET encdata;
|
||||
|
||||
/* Get our certificate private key */
|
||||
alg_a = s->s3->tmp.new_cipher->algorithm_auth;
|
||||
@@ -3270,22 +3315,42 @@ static int tls_process_cke_gost(SSL *s, PACKET *pkt)
|
||||
ERR_clear_error();
|
||||
}
|
||||
/* Decrypt session key */
|
||||
sess_key_len = PACKET_remaining(pkt);
|
||||
if (!PACKET_get_bytes(pkt, &data, sess_key_len)) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CKE_GOST,
|
||||
ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
/* TODO(size_t): Convert this function */
|
||||
if (ASN1_get_object((const unsigned char **)&data, &Tlen, &Ttag,
|
||||
&Tclass, (long)sess_key_len) != V_ASN1_CONSTRUCTED
|
||||
|| Ttag != V_ASN1_SEQUENCE || Tclass != V_ASN1_UNIVERSAL) {
|
||||
if (!PACKET_get_1(pkt, &asn1id)
|
||||
|| asn1id != (V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED)
|
||||
|| !PACKET_peek_1(pkt, &asn1len)) {
|
||||
SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_CKE_GOST,
|
||||
SSL_R_DECRYPTION_FAILED);
|
||||
goto err;
|
||||
}
|
||||
start = data;
|
||||
inlen = Tlen;
|
||||
if (asn1len == 0x81) {
|
||||
/*
|
||||
* Long form length. Should only be one byte of length. Anything else
|
||||
* isn't supported.
|
||||
* We did a successful peek before so this shouldn't fail
|
||||
*/
|
||||
if (!PACKET_forward(pkt, 1)) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CKE_GOST,
|
||||
SSL_R_DECRYPTION_FAILED);
|
||||
goto err;
|
||||
}
|
||||
} else if (asn1len >= 0x80) {
|
||||
/*
|
||||
* Indefinite length, or more than one long form length bytes. We don't
|
||||
* support it
|
||||
*/
|
||||
SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_CKE_GOST,
|
||||
SSL_R_DECRYPTION_FAILED);
|
||||
goto err;
|
||||
} /* else short form length */
|
||||
|
||||
if (!PACKET_as_length_prefixed_1(pkt, &encdata)) {
|
||||
SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_CKE_GOST,
|
||||
SSL_R_DECRYPTION_FAILED);
|
||||
goto err;
|
||||
}
|
||||
inlen = PACKET_remaining(&encdata);
|
||||
start = PACKET_data(&encdata);
|
||||
|
||||
if (EVP_PKEY_decrypt(pkey_ctx, premaster_secret, &outlen, start,
|
||||
inlen) <= 0) {
|
||||
SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_CKE_GOST,
|
||||
@@ -3554,7 +3619,7 @@ MSG_PROCESS_RETURN tls_process_client_certificate(SSL *s, PACKET *pkt)
|
||||
EVP_PKEY *pkey;
|
||||
i = ssl_verify_cert_chain(s, sk);
|
||||
if (i <= 0) {
|
||||
SSLfatal(s, ssl_verify_alarm_type(s->verify_result),
|
||||
SSLfatal(s, ssl_x509err2alert(s->verify_result),
|
||||
SSL_F_TLS_PROCESS_CLIENT_CERTIFICATE,
|
||||
SSL_R_CERTIFICATE_VERIFY_FAILED);
|
||||
goto err;
|
||||
@@ -3609,9 +3674,6 @@ MSG_PROCESS_RETURN tls_process_client_certificate(SSL *s, PACKET *pkt)
|
||||
sk_X509_pop_free(s->session->peer_chain, X509_free);
|
||||
s->session->peer_chain = sk;
|
||||
|
||||
if (new_sess != NULL)
|
||||
ssl_update_cache(s, SSL_SESS_CACHE_SERVER);
|
||||
|
||||
/*
|
||||
* Freeze the handshake buffer. For <TLS1.3 we do this after the CKE
|
||||
* message
|
||||
@@ -3628,12 +3690,16 @@ MSG_PROCESS_RETURN tls_process_client_certificate(SSL *s, PACKET *pkt)
|
||||
sk = NULL;
|
||||
|
||||
/* Save the current hash state for when we receive the CertificateVerify */
|
||||
if (SSL_IS_TLS13(s)
|
||||
&& !ssl_handshake_hash(s, s->cert_verify_hash,
|
||||
sizeof(s->cert_verify_hash),
|
||||
&s->cert_verify_hash_len)) {
|
||||
/* SSLfatal() already called */
|
||||
goto err;
|
||||
if (SSL_IS_TLS13(s)) {
|
||||
if (!ssl_handshake_hash(s, s->cert_verify_hash,
|
||||
sizeof(s->cert_verify_hash),
|
||||
&s->cert_verify_hash_len)) {
|
||||
/* SSLfatal() already called */
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Resend session tickets */
|
||||
s->sent_tickets = 0;
|
||||
}
|
||||
|
||||
ret = MSG_PROCESS_CONTINUE_READING;
|
||||
@@ -3692,7 +3758,48 @@ int tls_construct_new_session_ticket(SSL *s, WPACKET *pkt)
|
||||
} age_add_u;
|
||||
|
||||
if (SSL_IS_TLS13(s)) {
|
||||
if (ssl_randbytes(s, age_add_u.age_add_c, sizeof(age_add_u)) <= 0) {
|
||||
void (*cb) (const SSL *ssl, int type, int val) = NULL;
|
||||
|
||||
if (s->info_callback != NULL)
|
||||
cb = s->info_callback;
|
||||
else if (s->ctx->info_callback != NULL)
|
||||
cb = s->ctx->info_callback;
|
||||
|
||||
|
||||
if (cb != NULL) {
|
||||
/*
|
||||
* We don't start and stop the handshake in between each ticket when
|
||||
* sending more than one - but it should appear that way to the info
|
||||
* callback.
|
||||
*/
|
||||
if (s->sent_tickets != 0) {
|
||||
ossl_statem_set_in_init(s, 0);
|
||||
cb(s, SSL_CB_HANDSHAKE_DONE, 1);
|
||||
ossl_statem_set_in_init(s, 1);
|
||||
}
|
||||
cb(s, SSL_CB_HANDSHAKE_START, 1);
|
||||
}
|
||||
/*
|
||||
* If we already sent one NewSessionTicket then we need to take a copy
|
||||
* of it and create a new session from it.
|
||||
*/
|
||||
if (s->sent_tickets != 0) {
|
||||
SSL_SESSION *new_sess = ssl_session_dup(s->session, 0);
|
||||
|
||||
if (new_sess == NULL) {
|
||||
/* SSLfatal already called */
|
||||
goto err;
|
||||
}
|
||||
|
||||
SSL_SESSION_free(s->session);
|
||||
s->session = new_sess;
|
||||
}
|
||||
|
||||
if (!ssl_generate_session_id(s, s->session)) {
|
||||
/* SSLfatal() already called */
|
||||
goto err;
|
||||
}
|
||||
if (RAND_bytes(age_add_u.age_add_c, sizeof(age_add_u)) <= 0) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR,
|
||||
SSL_F_TLS_CONSTRUCT_NEW_SESSION_TICKET,
|
||||
ERR_R_INTERNAL_ERROR);
|
||||
@@ -3758,7 +3865,6 @@ int tls_construct_new_session_ticket(SSL *s, WPACKET *pkt)
|
||||
SSL_F_TLS_CONSTRUCT_NEW_SESSION_TICKET, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_SET_DRBG, 0, s->drbg);
|
||||
|
||||
p = senc;
|
||||
if (!i2d_SSL_SESSION(s->session, &p)) {
|
||||
@@ -3777,7 +3883,6 @@ int tls_construct_new_session_ticket(SSL *s, WPACKET *pkt)
|
||||
SSL_F_TLS_CONSTRUCT_NEW_SESSION_TICKET, ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
sess->session_id_length = 0; /* ID is irrelevant for the ticket */
|
||||
|
||||
slen = i2d_SSL_SESSION(sess, NULL);
|
||||
if (slen == 0 || slen > slen_full) {
|
||||
@@ -3831,11 +3936,11 @@ int tls_construct_new_session_ticket(SSL *s, WPACKET *pkt)
|
||||
const EVP_CIPHER *cipher = EVP_aes_256_cbc();
|
||||
|
||||
iv_len = EVP_CIPHER_iv_length(cipher);
|
||||
if (ssl_randbytes(s, iv, iv_len) <= 0
|
||||
if (RAND_bytes(iv, iv_len) <= 0
|
||||
|| !EVP_EncryptInit_ex(ctx, cipher, NULL,
|
||||
tctx->ext.tick_aes_key, iv)
|
||||
|| !HMAC_Init_ex(hctx, tctx->ext.tick_hmac_key,
|
||||
sizeof(tctx->ext.tick_hmac_key),
|
||||
tctx->ext.secure->tick_aes_key, iv)
|
||||
|| !HMAC_Init_ex(hctx, tctx->ext.secure->tick_hmac_key,
|
||||
sizeof(tctx->ext.secure->tick_hmac_key),
|
||||
EVP_sha256(), NULL)) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR,
|
||||
SSL_F_TLS_CONSTRUCT_NEW_SESSION_TICKET,
|
||||
@@ -3890,12 +3995,15 @@ int tls_construct_new_session_ticket(SSL *s, WPACKET *pkt)
|
||||
SSL_F_TLS_CONSTRUCT_NEW_SESSION_TICKET, ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
if (SSL_IS_TLS13(s)
|
||||
&& !tls_construct_extensions(s, pkt,
|
||||
SSL_EXT_TLS1_3_NEW_SESSION_TICKET,
|
||||
NULL, 0)) {
|
||||
/* SSLfatal() already called */
|
||||
goto err;
|
||||
if (SSL_IS_TLS13(s)) {
|
||||
if (!tls_construct_extensions(s, pkt,
|
||||
SSL_EXT_TLS1_3_NEW_SESSION_TICKET,
|
||||
NULL, 0)) {
|
||||
/* SSLfatal() already called */
|
||||
goto err;
|
||||
}
|
||||
s->sent_tickets++;
|
||||
ssl_update_cache(s, SSL_SESS_CACHE_SERVER);
|
||||
}
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
HMAC_CTX_free(hctx);
|
||||
|
||||
Reference in New Issue
Block a user