Update - OpenSSL 1.1.1-pre7-dev
This commit is contained in:
+8
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#include "internal/cryptlib.h"
|
||||
#include "packet_locl.h"
|
||||
#include <openssl/sslerr.h>
|
||||
|
||||
#define DEFAULT_BUF_SIZE 256
|
||||
|
||||
@@ -93,9 +94,10 @@ static int wpacket_intern_init_len(WPACKET *pkt, size_t lenbytes)
|
||||
pkt->curr = 0;
|
||||
pkt->written = 0;
|
||||
|
||||
pkt->subs = OPENSSL_zalloc(sizeof(*pkt->subs));
|
||||
if (pkt->subs == NULL)
|
||||
if ((pkt->subs = OPENSSL_zalloc(sizeof(*pkt->subs))) == NULL) {
|
||||
SSLerr(SSL_F_WPACKET_INTERN_INIT_LEN, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lenbytes == 0)
|
||||
return 1;
|
||||
@@ -276,9 +278,10 @@ int WPACKET_start_sub_packet_len__(WPACKET *pkt, size_t lenbytes)
|
||||
if (!ossl_assert(pkt->subs != NULL))
|
||||
return 0;
|
||||
|
||||
sub = OPENSSL_zalloc(sizeof(*sub));
|
||||
if (sub == NULL)
|
||||
if ((sub = OPENSSL_zalloc(sizeof(*sub))) == NULL) {
|
||||
SSLerr(SSL_F_WPACKET_START_SUB_PACKET_LEN__, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
sub->parent = pkt->subs;
|
||||
pkt->subs = sub;
|
||||
|
||||
+9
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2005-2017 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2005-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -18,14 +18,15 @@ struct pqueue_st {
|
||||
pitem *pitem_new(unsigned char *prio64be, void *data)
|
||||
{
|
||||
pitem *item = OPENSSL_malloc(sizeof(*item));
|
||||
if (item == NULL)
|
||||
|
||||
if (item == NULL) {
|
||||
SSLerr(SSL_F_PITEM_NEW, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy(item->priority, prio64be, sizeof(item->priority));
|
||||
|
||||
item->data = data;
|
||||
item->next = NULL;
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
@@ -34,10 +35,13 @@ void pitem_free(pitem *item)
|
||||
OPENSSL_free(item);
|
||||
}
|
||||
|
||||
pqueue *pqueue_new()
|
||||
pqueue *pqueue_new(void)
|
||||
{
|
||||
pqueue *pq = OPENSSL_zalloc(sizeof(*pq));
|
||||
|
||||
if (pq == NULL)
|
||||
SSLerr(SSL_F_PQUEUE_NEW, ERR_R_MALLOC_FAILURE);
|
||||
|
||||
return pq;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2005-2017 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2005-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -20,8 +20,10 @@ int DTLS_RECORD_LAYER_new(RECORD_LAYER *rl)
|
||||
{
|
||||
DTLS_RECORD_LAYER *d;
|
||||
|
||||
if ((d = OPENSSL_malloc(sizeof(*d))) == NULL)
|
||||
if ((d = OPENSSL_malloc(sizeof(*d))) == NULL) {
|
||||
SSLerr(SSL_F_DTLS_RECORD_LAYER_NEW, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
rl->d = d;
|
||||
|
||||
@@ -361,8 +363,7 @@ int dtls1_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf,
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!ossl_statem_get_in_handshake(s) && SSL_in_init(s))
|
||||
{
|
||||
if (!ossl_statem_get_in_handshake(s) && SSL_in_init(s)) {
|
||||
/* type == SSL3_RT_APPLICATION_DATA */
|
||||
i = s->handshake_func(s);
|
||||
/* SSLfatal() already called if appropriate */
|
||||
@@ -418,6 +419,7 @@ int dtls1_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf,
|
||||
/* get new packet if necessary */
|
||||
if ((SSL3_RECORD_get_length(rr) == 0)
|
||||
|| (s->rlayer.rstate == SSL_ST_READ_BODY)) {
|
||||
RECORD_LAYER_set_numrpipes(&s->rlayer, 0);
|
||||
iret = dtls1_get_record(s);
|
||||
if (iret <= 0) {
|
||||
iret = dtls1_read_failed(s, iret);
|
||||
@@ -430,6 +432,7 @@ int dtls1_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf,
|
||||
else
|
||||
goto start;
|
||||
}
|
||||
RECORD_LAYER_set_numrpipes(&s->rlayer, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -440,6 +443,19 @@ int dtls1_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf,
|
||||
&& SSL3_RECORD_get_length(rr) != 0)
|
||||
s->rlayer.alert_count = 0;
|
||||
|
||||
if (SSL3_RECORD_get_type(rr) != SSL3_RT_HANDSHAKE
|
||||
&& SSL3_RECORD_get_type(rr) != SSL3_RT_CHANGE_CIPHER_SPEC
|
||||
&& !SSL_in_init(s)
|
||||
&& (s->d1->next_timeout.tv_sec != 0
|
||||
|| s->d1->next_timeout.tv_usec != 0)) {
|
||||
/*
|
||||
* The timer is still running but we've received something that isn't
|
||||
* handshake data - so the peer must have finished processing our
|
||||
* last handshake flight. Stop the timer.
|
||||
*/
|
||||
dtls1_stop_timer(s);
|
||||
}
|
||||
|
||||
/* we now have a packet which can be read and processed */
|
||||
|
||||
if (s->s3->change_cipher_spec /* set when we receive ChangeCipherSpec,
|
||||
@@ -456,6 +472,7 @@ int dtls1_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf,
|
||||
return -1;
|
||||
}
|
||||
SSL3_RECORD_set_length(rr, 0);
|
||||
SSL3_RECORD_set_read(rr);
|
||||
goto start;
|
||||
}
|
||||
|
||||
@@ -465,6 +482,7 @@ int dtls1_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf,
|
||||
*/
|
||||
if (s->shutdown & SSL_RECEIVED_SHUTDOWN) {
|
||||
SSL3_RECORD_set_length(rr, 0);
|
||||
SSL3_RECORD_set_read(rr);
|
||||
s->rwstate = SSL_NOTHING;
|
||||
return 0;
|
||||
}
|
||||
@@ -491,8 +509,16 @@ int dtls1_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf,
|
||||
if (recvd_type != NULL)
|
||||
*recvd_type = SSL3_RECORD_get_type(rr);
|
||||
|
||||
if (len == 0)
|
||||
if (len == 0) {
|
||||
/*
|
||||
* Mark a zero length record as read. This ensures multiple calls to
|
||||
* SSL_read() with a zero length buffer will eventually cause
|
||||
* SSL_pending() to report data as being available.
|
||||
*/
|
||||
if (SSL3_RECORD_get_length(rr) == 0)
|
||||
SSL3_RECORD_set_read(rr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (len > SSL3_RECORD_get_length(rr))
|
||||
n = SSL3_RECORD_get_length(rr);
|
||||
@@ -500,12 +526,16 @@ int dtls1_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf,
|
||||
n = len;
|
||||
|
||||
memcpy(buf, &(SSL3_RECORD_get_data(rr)[SSL3_RECORD_get_off(rr)]), n);
|
||||
if (!peek) {
|
||||
if (peek) {
|
||||
if (SSL3_RECORD_get_length(rr) == 0)
|
||||
SSL3_RECORD_set_read(rr);
|
||||
} else {
|
||||
SSL3_RECORD_sub_length(rr, n);
|
||||
SSL3_RECORD_add_off(rr, n);
|
||||
if (SSL3_RECORD_get_length(rr) == 0) {
|
||||
s->rlayer.rstate = SSL_ST_READ_HEADER;
|
||||
SSL3_RECORD_set_off(rr, 0);
|
||||
SSL3_RECORD_set_read(rr);
|
||||
}
|
||||
}
|
||||
#ifndef OPENSSL_NO_SCTP
|
||||
@@ -561,6 +591,7 @@ int dtls1_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf,
|
||||
|
||||
if (alert_level == SSL3_AL_WARNING) {
|
||||
s->s3->warn_alert = alert_descr;
|
||||
SSL3_RECORD_set_read(rr);
|
||||
|
||||
s->rlayer.alert_count++;
|
||||
if (s->rlayer.alert_count == MAX_WARN_ALERT_COUNT) {
|
||||
@@ -598,6 +629,7 @@ int dtls1_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf,
|
||||
BIO_snprintf(tmp, sizeof tmp, "%d", alert_descr);
|
||||
ERR_add_error_data(2, "SSL alert number ", tmp);
|
||||
s->shutdown |= SSL_RECEIVED_SHUTDOWN;
|
||||
SSL3_RECORD_set_read(rr);
|
||||
SSL_CTX_remove_session(s->session_ctx, s->session);
|
||||
return 0;
|
||||
} else {
|
||||
@@ -613,6 +645,7 @@ int dtls1_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf,
|
||||
* shutdown */
|
||||
s->rwstate = SSL_NOTHING;
|
||||
SSL3_RECORD_set_length(rr, 0);
|
||||
SSL3_RECORD_set_read(rr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -622,6 +655,7 @@ int dtls1_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf,
|
||||
* are still missing, so just drop it.
|
||||
*/
|
||||
SSL3_RECORD_set_length(rr, 0);
|
||||
SSL3_RECORD_set_read(rr);
|
||||
goto start;
|
||||
}
|
||||
|
||||
@@ -639,6 +673,7 @@ int dtls1_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf,
|
||||
if (SSL3_RECORD_get_epoch(rr) != s->rlayer.d->r_epoch
|
||||
|| SSL3_RECORD_get_length(rr) < DTLS1_HM_HEADER_LENGTH) {
|
||||
SSL3_RECORD_set_length(rr, 0);
|
||||
SSL3_RECORD_set_read(rr);
|
||||
goto start;
|
||||
}
|
||||
|
||||
@@ -660,6 +695,19 @@ int dtls1_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf,
|
||||
return -1;
|
||||
}
|
||||
SSL3_RECORD_set_length(rr, 0);
|
||||
SSL3_RECORD_set_read(rr);
|
||||
if (!(s->mode & SSL_MODE_AUTO_RETRY)) {
|
||||
if (SSL3_BUFFER_get_left(&s->rlayer.rbuf) == 0) {
|
||||
/* no read-ahead left? */
|
||||
BIO *bio;
|
||||
|
||||
s->rwstate = SSL_READING;
|
||||
bio = SSL_get_rbio(s);
|
||||
BIO_clear_retry_flags(bio);
|
||||
BIO_set_retry_read(bio);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
goto start;
|
||||
}
|
||||
|
||||
|
||||
@@ -825,7 +825,6 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
|
||||
thispkt = &pkt[j];
|
||||
thiswr = &wr[j];
|
||||
|
||||
SSL3_RECORD_set_type(thiswr, type);
|
||||
/*
|
||||
* In TLSv1.3, once encrypting, we always use application data for the
|
||||
* record type
|
||||
@@ -834,6 +833,8 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
|
||||
rectype = SSL3_RT_APPLICATION_DATA;
|
||||
else
|
||||
rectype = type;
|
||||
SSL3_RECORD_set_type(thiswr, rectype);
|
||||
|
||||
/*
|
||||
* Some servers hang if initial client hello is larger than 256 bytes
|
||||
* and record version number > TLS 1.0
|
||||
@@ -843,6 +844,7 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
|
||||
&& TLS1_get_version(s) > TLS1_VERSION
|
||||
&& s->hello_retry_request == SSL_HRR_NONE)
|
||||
version = TLS1_VERSION;
|
||||
SSL3_RECORD_set_rec_version(thiswr, version);
|
||||
|
||||
maxcomplen = pipelens[j];
|
||||
if (s->compress != NULL)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -80,6 +80,7 @@ int ssl3_release_write_buffer(SSL *s);
|
||||
|
||||
#define SSL3_RECORD_get_type(r) ((r)->type)
|
||||
#define SSL3_RECORD_set_type(r, t) ((r)->type = (t))
|
||||
#define SSL3_RECORD_set_rec_version(r, v) ((r)->rec_version = (v))
|
||||
#define SSL3_RECORD_get_length(r) ((r)->length)
|
||||
#define SSL3_RECORD_set_length(r, l) ((r)->length = (l))
|
||||
#define SSL3_RECORD_add_length(r, l) ((r)->length += (l))
|
||||
|
||||
+32
-13
@@ -270,7 +270,8 @@ int ssl3_get_record(SSL *s)
|
||||
thisrr->rec_version = version;
|
||||
|
||||
/*
|
||||
* Lets check version. In TLSv1.3 we ignore this field. For the
|
||||
* 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
|
||||
@@ -333,14 +334,19 @@ int ssl3_get_record(SSL *s)
|
||||
}
|
||||
}
|
||||
|
||||
if (SSL_IS_TLS13(s)
|
||||
&& s->enc_read_ctx != NULL
|
||||
&& thisrr->type != SSL3_RT_APPLICATION_DATA
|
||||
&& (thisrr->type != SSL3_RT_CHANGE_CIPHER_SPEC
|
||||
|| !SSL_IS_FIRST_HANDSHAKE(s))) {
|
||||
SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE,
|
||||
SSL_F_SSL3_GET_RECORD, SSL_R_BAD_RECORD_TYPE);
|
||||
return -1;
|
||||
if (SSL_IS_TLS13(s) && s->enc_read_ctx != NULL) {
|
||||
if (thisrr->type != SSL3_RT_APPLICATION_DATA
|
||||
&& (thisrr->type != SSL3_RT_CHANGE_CIPHER_SPEC
|
||||
|| !SSL_IS_FIRST_HANDSHAKE(s))) {
|
||||
SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE,
|
||||
SSL_F_SSL3_GET_RECORD, SSL_R_BAD_RECORD_TYPE);
|
||||
return -1;
|
||||
}
|
||||
if (thisrr->rec_version != TLS1_2_VERSION) {
|
||||
SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_SSL3_GET_RECORD,
|
||||
SSL_R_WRONG_VERSION_NUMBER);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (thisrr->length >
|
||||
@@ -966,7 +972,7 @@ int tls1_enc(SSL *s, SSL3_RECORD *recs, size_t n_recs, int sending)
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS1_ENC,
|
||||
ERR_R_INTERNAL_ERROR);
|
||||
return -1;
|
||||
} else if (ssl_randbytes(s, recs[ctr].input, ivlen) <= 0) {
|
||||
} else if (RAND_bytes(recs[ctr].input, ivlen) <= 0) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS1_ENC,
|
||||
ERR_R_INTERNAL_ERROR);
|
||||
return -1;
|
||||
@@ -1250,7 +1256,7 @@ int n_ssl3_mac(SSL *ssl, SSL3_RECORD *rec, unsigned char *md, int sending)
|
||||
|| EVP_DigestUpdate(md_ctx, ssl3_pad_2, npad) <= 0
|
||||
|| EVP_DigestUpdate(md_ctx, md, md_size) <= 0
|
||||
|| EVP_DigestFinal_ex(md_ctx, md, &md_size_u) <= 0) {
|
||||
EVP_MD_CTX_reset(md_ctx);
|
||||
EVP_MD_CTX_free(md_ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1291,8 +1297,10 @@ int tls1_mac(SSL *ssl, SSL3_RECORD *rec, unsigned char *md, int sending)
|
||||
mac_ctx = hash;
|
||||
} else {
|
||||
hmac = EVP_MD_CTX_new();
|
||||
if (hmac == NULL || !EVP_MD_CTX_copy(hmac, hash))
|
||||
if (hmac == NULL || !EVP_MD_CTX_copy(hmac, hash)) {
|
||||
EVP_MD_CTX_free(hmac);
|
||||
return 0;
|
||||
}
|
||||
mac_ctx = hmac;
|
||||
}
|
||||
|
||||
@@ -1874,6 +1882,7 @@ int dtls1_get_record(SSL *s)
|
||||
p += 6;
|
||||
|
||||
n2s(p, rr->length);
|
||||
rr->read = 0;
|
||||
|
||||
/*
|
||||
* Lets check the version. We tolerate alerts that don't have the exact
|
||||
@@ -1883,6 +1892,7 @@ int dtls1_get_record(SSL *s)
|
||||
if (version != s->version) {
|
||||
/* unexpected version, silently discard */
|
||||
rr->length = 0;
|
||||
rr->read = 1;
|
||||
RECORD_LAYER_reset_packet_length(&s->rlayer);
|
||||
goto again;
|
||||
}
|
||||
@@ -1891,6 +1901,7 @@ int dtls1_get_record(SSL *s)
|
||||
if ((version & 0xff00) != (s->version & 0xff00)) {
|
||||
/* wrong version, silently discard record */
|
||||
rr->length = 0;
|
||||
rr->read = 1;
|
||||
RECORD_LAYER_reset_packet_length(&s->rlayer);
|
||||
goto again;
|
||||
}
|
||||
@@ -1898,6 +1909,7 @@ int dtls1_get_record(SSL *s)
|
||||
if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH) {
|
||||
/* record too long, silently discard it */
|
||||
rr->length = 0;
|
||||
rr->read = 1;
|
||||
RECORD_LAYER_reset_packet_length(&s->rlayer);
|
||||
goto again;
|
||||
}
|
||||
@@ -1907,6 +1919,7 @@ int dtls1_get_record(SSL *s)
|
||||
&& rr->length > GET_MAX_FRAGMENT_LENGTH(s->session)) {
|
||||
/* record too long, silently discard it */
|
||||
rr->length = 0;
|
||||
rr->read = 1;
|
||||
RECORD_LAYER_reset_packet_length(&s->rlayer);
|
||||
goto again;
|
||||
}
|
||||
@@ -1928,6 +1941,7 @@ int dtls1_get_record(SSL *s)
|
||||
return -1;
|
||||
}
|
||||
rr->length = 0;
|
||||
rr->read = 1;
|
||||
RECORD_LAYER_reset_packet_length(&s->rlayer);
|
||||
goto again;
|
||||
}
|
||||
@@ -1958,6 +1972,7 @@ int dtls1_get_record(SSL *s)
|
||||
*/
|
||||
if (!dtls1_record_replay_check(s, bitmap)) {
|
||||
rr->length = 0;
|
||||
rr->read = 1;
|
||||
RECORD_LAYER_reset_packet_length(&s->rlayer); /* dump this record */
|
||||
goto again; /* get another record */
|
||||
}
|
||||
@@ -1966,8 +1981,10 @@ int dtls1_get_record(SSL *s)
|
||||
#endif
|
||||
|
||||
/* just read a 0 length packet */
|
||||
if (rr->length == 0)
|
||||
if (rr->length == 0) {
|
||||
rr->read = 1;
|
||||
goto again;
|
||||
}
|
||||
|
||||
/*
|
||||
* If this record is from the next epoch (either HM or ALERT), and a
|
||||
@@ -1984,6 +2001,7 @@ int dtls1_get_record(SSL *s)
|
||||
}
|
||||
}
|
||||
rr->length = 0;
|
||||
rr->read = 1;
|
||||
RECORD_LAYER_reset_packet_length(&s->rlayer);
|
||||
goto again;
|
||||
}
|
||||
@@ -1994,6 +2012,7 @@ int dtls1_get_record(SSL *s)
|
||||
return -1;
|
||||
}
|
||||
rr->length = 0;
|
||||
rr->read = 1;
|
||||
RECORD_LAYER_reset_packet_length(&s->rlayer); /* dump this record */
|
||||
goto again; /* get another record */
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -25,13 +25,14 @@
|
||||
int tls13_enc(SSL *s, SSL3_RECORD *recs, size_t n_recs, int sending)
|
||||
{
|
||||
EVP_CIPHER_CTX *ctx;
|
||||
unsigned char iv[EVP_MAX_IV_LENGTH];
|
||||
size_t ivlen, taglen, offset, loop;
|
||||
unsigned char iv[EVP_MAX_IV_LENGTH], recheader[SSL3_RT_HEADER_LENGTH];
|
||||
size_t ivlen, taglen, offset, loop, hdrlen;
|
||||
unsigned char *staticiv;
|
||||
unsigned char *seq;
|
||||
int lenu, lenf;
|
||||
SSL3_RECORD *rec = &recs[0];
|
||||
uint32_t alg_enc;
|
||||
WPACKET wpkt;
|
||||
|
||||
if (n_recs != 1) {
|
||||
/* Should not happen */
|
||||
@@ -143,7 +144,31 @@ int tls13_enc(SSL *s, SSL3_RECORD *recs, size_t n_recs, int sending)
|
||||
if (EVP_CipherInit_ex(ctx, NULL, NULL, NULL, iv, sending) <= 0
|
||||
|| (!sending && EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG,
|
||||
taglen,
|
||||
rec->data + rec->length) <= 0)
|
||||
rec->data + rec->length) <= 0)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Set up the AAD */
|
||||
if (!WPACKET_init_static_len(&wpkt, recheader, sizeof(recheader), 0)
|
||||
|| !WPACKET_put_bytes_u8(&wpkt, rec->type)
|
||||
|| !WPACKET_put_bytes_u16(&wpkt, rec->rec_version)
|
||||
|| !WPACKET_put_bytes_u16(&wpkt, rec->length + taglen)
|
||||
|| !WPACKET_get_total_written(&wpkt, &hdrlen)
|
||||
|| hdrlen != SSL3_RT_HEADER_LENGTH
|
||||
|| !WPACKET_finish(&wpkt)) {
|
||||
WPACKET_cleanup(&wpkt);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* For CCM we must explicitly set the total plaintext length before we add
|
||||
* any AAD.
|
||||
*/
|
||||
if (((alg_enc & SSL_AESCCM) != 0
|
||||
&& EVP_CipherUpdate(ctx, NULL, &lenu, NULL,
|
||||
(unsigned int)rec->length) <= 0)
|
||||
|| EVP_CipherUpdate(ctx, NULL, &lenu, recheader,
|
||||
sizeof(recheader)) <= 0
|
||||
|| EVP_CipherUpdate(ctx, rec->data, &lenu, rec->input,
|
||||
(unsigned int)rec->length) <= 0
|
||||
|| EVP_CipherFinal_ex(ctx, rec->data + lenu, &lenf) <= 0
|
||||
|
||||
+3
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2005 Nokia. All rights reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
@@ -155,6 +155,7 @@ int ssl3_change_cipher_state(SSL *s, int which)
|
||||
RECORD_LAYER_reset_read_sequence(&s->rlayer);
|
||||
mac_secret = &(s->s3->read_mac_secret[0]);
|
||||
} else {
|
||||
s->statem.invalid_enc_write_ctx = 1;
|
||||
if (s->enc_write_ctx != NULL) {
|
||||
reuse_dd = 1;
|
||||
} else if ((s->enc_write_ctx = EVP_CIPHER_CTX_new()) == NULL) {
|
||||
@@ -167,7 +168,6 @@ int ssl3_change_cipher_state(SSL *s, int which)
|
||||
*/
|
||||
EVP_CIPHER_CTX_reset(s->enc_write_ctx);
|
||||
}
|
||||
EVP_CIPHER_CTX_ctrl(s->enc_write_ctx, EVP_CTRL_SET_DRBG, 0, s->drbg);
|
||||
dd = s->enc_write_ctx;
|
||||
if (ssl_replace_hash(&s->write_hash, m) == NULL) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_CHANGE_CIPHER_STATE,
|
||||
@@ -238,6 +238,7 @@ int ssl3_change_cipher_state(SSL *s, int which)
|
||||
goto err;
|
||||
}
|
||||
|
||||
s->statem.invalid_enc_write_ctx = 0;
|
||||
OPENSSL_cleanse(exp_key, sizeof(exp_key));
|
||||
OPENSSL_cleanse(exp_iv, sizeof(exp_iv));
|
||||
return 1;
|
||||
|
||||
+211
-175
@@ -18,6 +18,7 @@
|
||||
#include <openssl/rand.h>
|
||||
#include "internal/cryptlib.h"
|
||||
|
||||
#define TLS13_NUM_CIPHERS OSSL_NELEM(tls13_ciphers)
|
||||
#define SSL3_NUM_CIPHERS OSSL_NELEM(ssl3_ciphers)
|
||||
#define SSL3_NUM_SCSVS OSSL_NELEM(ssl3_scsvs)
|
||||
|
||||
@@ -29,6 +30,90 @@ const unsigned char tls12downgrade[] = {
|
||||
0x44, 0x4f, 0x57, 0x4e, 0x47, 0x52, 0x44, 0x01
|
||||
};
|
||||
|
||||
/* The list of available TLSv1.3 ciphers */
|
||||
static SSL_CIPHER tls13_ciphers[] = {
|
||||
{
|
||||
1,
|
||||
TLS1_3_RFC_AES_128_GCM_SHA256,
|
||||
TLS1_3_RFC_AES_128_GCM_SHA256,
|
||||
TLS1_3_CK_AES_128_GCM_SHA256,
|
||||
SSL_kANY,
|
||||
SSL_aANY,
|
||||
SSL_AES128GCM,
|
||||
SSL_AEAD,
|
||||
TLS1_3_VERSION, TLS1_3_VERSION,
|
||||
0, 0,
|
||||
SSL_HIGH,
|
||||
SSL_HANDSHAKE_MAC_SHA256,
|
||||
128,
|
||||
128,
|
||||
}, {
|
||||
1,
|
||||
TLS1_3_RFC_AES_256_GCM_SHA384,
|
||||
TLS1_3_RFC_AES_256_GCM_SHA384,
|
||||
TLS1_3_CK_AES_256_GCM_SHA384,
|
||||
SSL_kANY,
|
||||
SSL_aANY,
|
||||
SSL_AES256GCM,
|
||||
SSL_AEAD,
|
||||
TLS1_3_VERSION, TLS1_3_VERSION,
|
||||
0, 0,
|
||||
SSL_HIGH,
|
||||
SSL_HANDSHAKE_MAC_SHA384,
|
||||
256,
|
||||
256,
|
||||
},
|
||||
#if !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305)
|
||||
{
|
||||
1,
|
||||
TLS1_3_RFC_CHACHA20_POLY1305_SHA256,
|
||||
TLS1_3_RFC_CHACHA20_POLY1305_SHA256,
|
||||
TLS1_3_CK_CHACHA20_POLY1305_SHA256,
|
||||
SSL_kANY,
|
||||
SSL_aANY,
|
||||
SSL_CHACHA20POLY1305,
|
||||
SSL_AEAD,
|
||||
TLS1_3_VERSION, TLS1_3_VERSION,
|
||||
0, 0,
|
||||
SSL_HIGH,
|
||||
SSL_HANDSHAKE_MAC_SHA256,
|
||||
256,
|
||||
256,
|
||||
},
|
||||
#endif
|
||||
{
|
||||
1,
|
||||
TLS1_3_RFC_AES_128_CCM_SHA256,
|
||||
TLS1_3_RFC_AES_128_CCM_SHA256,
|
||||
TLS1_3_CK_AES_128_CCM_SHA256,
|
||||
SSL_kANY,
|
||||
SSL_aANY,
|
||||
SSL_AES128CCM,
|
||||
SSL_AEAD,
|
||||
TLS1_3_VERSION, TLS1_3_VERSION,
|
||||
0, 0,
|
||||
SSL_NOT_DEFAULT | SSL_HIGH,
|
||||
SSL_HANDSHAKE_MAC_SHA256,
|
||||
128,
|
||||
128,
|
||||
}, {
|
||||
1,
|
||||
TLS1_3_RFC_AES_128_CCM_8_SHA256,
|
||||
TLS1_3_RFC_AES_128_CCM_8_SHA256,
|
||||
TLS1_3_CK_AES_128_CCM_8_SHA256,
|
||||
SSL_kANY,
|
||||
SSL_aANY,
|
||||
SSL_AES128CCM8,
|
||||
SSL_AEAD,
|
||||
TLS1_3_VERSION, TLS1_3_VERSION,
|
||||
0, 0,
|
||||
SSL_NOT_DEFAULT | SSL_HIGH,
|
||||
SSL_HANDSHAKE_MAC_SHA256,
|
||||
128,
|
||||
128,
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* The list of available ciphers, mostly organized into the following
|
||||
* groups:
|
||||
@@ -858,88 +943,6 @@ static SSL_CIPHER ssl3_ciphers[] = {
|
||||
256,
|
||||
256,
|
||||
},
|
||||
{
|
||||
1,
|
||||
TLS1_3_TXT_AES_128_GCM_SHA256,
|
||||
TLS1_3_RFC_AES_128_GCM_SHA256,
|
||||
TLS1_3_CK_AES_128_GCM_SHA256,
|
||||
0, 0,
|
||||
SSL_AES128GCM,
|
||||
SSL_AEAD,
|
||||
TLS1_3_VERSION, TLS1_3_VERSION,
|
||||
SSL_kANY,
|
||||
SSL_aANY,
|
||||
SSL_HIGH,
|
||||
SSL_HANDSHAKE_MAC_SHA256,
|
||||
128,
|
||||
128,
|
||||
},
|
||||
{
|
||||
1,
|
||||
TLS1_3_TXT_AES_256_GCM_SHA384,
|
||||
TLS1_3_RFC_AES_256_GCM_SHA384,
|
||||
TLS1_3_CK_AES_256_GCM_SHA384,
|
||||
SSL_kANY,
|
||||
SSL_aANY,
|
||||
SSL_AES256GCM,
|
||||
SSL_AEAD,
|
||||
TLS1_3_VERSION, TLS1_3_VERSION,
|
||||
0, 0,
|
||||
SSL_HIGH,
|
||||
SSL_HANDSHAKE_MAC_SHA384,
|
||||
256,
|
||||
256,
|
||||
},
|
||||
#if !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305)
|
||||
{
|
||||
1,
|
||||
TLS1_3_TXT_CHACHA20_POLY1305_SHA256,
|
||||
TLS1_3_RFC_CHACHA20_POLY1305_SHA256,
|
||||
TLS1_3_CK_CHACHA20_POLY1305_SHA256,
|
||||
SSL_kANY,
|
||||
SSL_aANY,
|
||||
SSL_CHACHA20POLY1305,
|
||||
SSL_AEAD,
|
||||
TLS1_3_VERSION, TLS1_3_VERSION,
|
||||
0, 0,
|
||||
SSL_HIGH,
|
||||
SSL_HANDSHAKE_MAC_SHA256,
|
||||
256,
|
||||
256,
|
||||
},
|
||||
#endif
|
||||
{
|
||||
1,
|
||||
TLS1_3_TXT_AES_128_CCM_SHA256,
|
||||
TLS1_3_RFC_AES_128_CCM_SHA256,
|
||||
TLS1_3_CK_AES_128_CCM_SHA256,
|
||||
SSL_kANY,
|
||||
SSL_aANY,
|
||||
SSL_AES128CCM,
|
||||
SSL_AEAD,
|
||||
TLS1_3_VERSION, TLS1_3_VERSION,
|
||||
0, 0,
|
||||
SSL_NOT_DEFAULT | SSL_HIGH,
|
||||
SSL_HANDSHAKE_MAC_SHA256,
|
||||
128,
|
||||
128,
|
||||
},
|
||||
{
|
||||
1,
|
||||
TLS1_3_TXT_AES_128_CCM_8_SHA256,
|
||||
TLS1_3_RFC_AES_128_CCM_8_SHA256,
|
||||
TLS1_3_CK_AES_128_CCM_8_SHA256,
|
||||
SSL_kANY,
|
||||
SSL_aANY,
|
||||
SSL_AES128CCM8,
|
||||
SSL_AEAD,
|
||||
TLS1_3_VERSION, TLS1_3_VERSION,
|
||||
0, 0,
|
||||
SSL_NOT_DEFAULT | SSL_HIGH,
|
||||
SSL_HANDSHAKE_MAC_SHA256,
|
||||
128,
|
||||
128,
|
||||
},
|
||||
{
|
||||
1,
|
||||
TLS1_TXT_ECDHE_ECDSA_WITH_NULL_SHA,
|
||||
@@ -3207,6 +3210,8 @@ static int cipher_compare(const void *a, const void *b)
|
||||
|
||||
void ssl_sort_cipher_list(void)
|
||||
{
|
||||
qsort(tls13_ciphers, TLS13_NUM_CIPHERS, sizeof(tls13_ciphers[0]),
|
||||
cipher_compare);
|
||||
qsort(ssl3_ciphers, SSL3_NUM_CIPHERS, sizeof(ssl3_ciphers[0]),
|
||||
cipher_compare);
|
||||
qsort(ssl3_scsvs, SSL3_NUM_SCSVS, sizeof(ssl3_scsvs[0]), cipher_compare);
|
||||
@@ -3793,8 +3798,8 @@ long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
|
||||
{
|
||||
unsigned char *keys = parg;
|
||||
long tick_keylen = (sizeof(ctx->ext.tick_key_name) +
|
||||
sizeof(ctx->ext.tick_hmac_key) +
|
||||
sizeof(ctx->ext.tick_aes_key));
|
||||
sizeof(ctx->ext.secure->tick_hmac_key) +
|
||||
sizeof(ctx->ext.secure->tick_aes_key));
|
||||
if (keys == NULL)
|
||||
return tick_keylen;
|
||||
if (larg != tick_keylen) {
|
||||
@@ -3804,23 +3809,23 @@ long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
|
||||
if (cmd == SSL_CTRL_SET_TLSEXT_TICKET_KEYS) {
|
||||
memcpy(ctx->ext.tick_key_name, keys,
|
||||
sizeof(ctx->ext.tick_key_name));
|
||||
memcpy(ctx->ext.tick_hmac_key,
|
||||
memcpy(ctx->ext.secure->tick_hmac_key,
|
||||
keys + sizeof(ctx->ext.tick_key_name),
|
||||
sizeof(ctx->ext.tick_hmac_key));
|
||||
memcpy(ctx->ext.tick_aes_key,
|
||||
sizeof(ctx->ext.secure->tick_hmac_key));
|
||||
memcpy(ctx->ext.secure->tick_aes_key,
|
||||
keys + sizeof(ctx->ext.tick_key_name) +
|
||||
sizeof(ctx->ext.tick_hmac_key),
|
||||
sizeof(ctx->ext.tick_aes_key));
|
||||
sizeof(ctx->ext.secure->tick_hmac_key),
|
||||
sizeof(ctx->ext.secure->tick_aes_key));
|
||||
} else {
|
||||
memcpy(keys, ctx->ext.tick_key_name,
|
||||
sizeof(ctx->ext.tick_key_name));
|
||||
memcpy(keys + sizeof(ctx->ext.tick_key_name),
|
||||
ctx->ext.tick_hmac_key,
|
||||
sizeof(ctx->ext.tick_hmac_key));
|
||||
ctx->ext.secure->tick_hmac_key,
|
||||
sizeof(ctx->ext.secure->tick_hmac_key));
|
||||
memcpy(keys + sizeof(ctx->ext.tick_key_name) +
|
||||
sizeof(ctx->ext.tick_hmac_key),
|
||||
ctx->ext.tick_aes_key,
|
||||
sizeof(ctx->ext.tick_aes_key));
|
||||
sizeof(ctx->ext.secure->tick_hmac_key),
|
||||
ctx->ext.secure->tick_aes_key,
|
||||
sizeof(ctx->ext.secure->tick_aes_key));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -4027,6 +4032,9 @@ const SSL_CIPHER *ssl3_get_cipher_by_id(uint32_t id)
|
||||
const SSL_CIPHER *cp;
|
||||
|
||||
c.id = id;
|
||||
cp = OBJ_bsearch_ssl_cipher_id(&c, tls13_ciphers, TLS13_NUM_CIPHERS);
|
||||
if (cp != NULL)
|
||||
return cp;
|
||||
cp = OBJ_bsearch_ssl_cipher_id(&c, ssl3_ciphers, SSL3_NUM_CIPHERS);
|
||||
if (cp != NULL)
|
||||
return cp;
|
||||
@@ -4035,17 +4043,19 @@ const SSL_CIPHER *ssl3_get_cipher_by_id(uint32_t id)
|
||||
|
||||
const SSL_CIPHER *ssl3_get_cipher_by_std_name(const char *stdname)
|
||||
{
|
||||
SSL_CIPHER *c = NULL;
|
||||
SSL_CIPHER *tbl = ssl3_ciphers;
|
||||
size_t i;
|
||||
SSL_CIPHER *c = NULL, *tbl;
|
||||
SSL_CIPHER *alltabs[] = {tls13_ciphers, ssl3_ciphers};
|
||||
size_t i, j, tblsize[] = {TLS13_NUM_CIPHERS, SSL3_NUM_CIPHERS};
|
||||
|
||||
/* this is not efficient, necessary to optimize this? */
|
||||
for (i = 0; i < SSL3_NUM_CIPHERS; i++, tbl++) {
|
||||
if (tbl->stdname == NULL)
|
||||
continue;
|
||||
if (strcmp(stdname, tbl->stdname) == 0) {
|
||||
c = tbl;
|
||||
break;
|
||||
for (j = 0; j < OSSL_NELEM(alltabs); j++) {
|
||||
for (i = 0, tbl = alltabs[j]; i < tblsize[j]; i++, tbl++) {
|
||||
if (tbl->stdname == NULL)
|
||||
continue;
|
||||
if (strcmp(stdname, tbl->stdname) == 0) {
|
||||
c = tbl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (c == NULL) {
|
||||
@@ -4085,17 +4095,6 @@ int ssl3_put_cipher_by_char(const SSL_CIPHER *c, WPACKET *pkt, size_t *len)
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct ssl_cipher_preference_list_st* ssl_get_cipher_preferences(SSL *s)
|
||||
{
|
||||
if (s->cipher_list != NULL)
|
||||
return (s->cipher_list);
|
||||
|
||||
if ((s->ctx != NULL) && (s->ctx->cipher_list != NULL))
|
||||
return (s->ctx->cipher_list);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* ssl3_choose_cipher - choose a cipher from those offered by the client
|
||||
* @s: SSL connection
|
||||
@@ -4105,23 +4104,16 @@ struct ssl_cipher_preference_list_st* ssl_get_cipher_preferences(SSL *s)
|
||||
* Returns the selected cipher or NULL when no common ciphers.
|
||||
*/
|
||||
const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt,
|
||||
struct ssl_cipher_preference_list_st
|
||||
*server_pref)
|
||||
STACK_OF(SSL_CIPHER) *srvr)
|
||||
{
|
||||
const SSL_CIPHER *c, *ret = NULL;
|
||||
STACK_OF(SSL_CIPHER) *srvr = server_pref->ciphers, *prio, *allow;
|
||||
int i, ii, ok, safari_ec = 0;
|
||||
STACK_OF(SSL_CIPHER) *prio, *allow;
|
||||
int i, ii, ok, prefer_sha256 = 0;
|
||||
unsigned long alg_k = 0, alg_a = 0, mask_k = 0, mask_a = 0;
|
||||
|
||||
/* in_group_flags will either be NULL, or will point to an array of
|
||||
* bytes which indicate equal-preference groups in the |prio| stack.
|
||||
* See the comment about |in_group_flags| in the
|
||||
* |ssl_cipher_preference_list_st| struct. */
|
||||
const uint8_t *in_group_flags;
|
||||
|
||||
/* group_min contains the minimal index so far found in a group, or -1
|
||||
* if no such value exists yet. */
|
||||
int group_min = -1;
|
||||
const EVP_MD *mdsha256 = EVP_sha256();
|
||||
#ifndef OPENSSL_NO_CHACHA
|
||||
STACK_OF(SSL_CIPHER) *prio_chacha = NULL;
|
||||
#endif
|
||||
|
||||
/* Let's see which ciphers we can support */
|
||||
|
||||
@@ -4148,17 +4140,77 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt,
|
||||
#endif
|
||||
|
||||
/* SUITE-B takes precedence over server preference and ChaCha priortiy */
|
||||
if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE || tls1_suiteb(s)) {
|
||||
if (tls1_suiteb(s)) {
|
||||
prio = srvr;
|
||||
in_group_flags = server_pref->in_group_flags;
|
||||
allow = clnt;
|
||||
} else if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE) {
|
||||
prio = srvr;
|
||||
allow = clnt;
|
||||
#ifndef OPENSSL_NO_CHACHA
|
||||
/* If ChaCha20 is at the top of the client preference list,
|
||||
and there are ChaCha20 ciphers in the server list, then
|
||||
temporarily prioritize all ChaCha20 ciphers in the servers list. */
|
||||
if (s->options & SSL_OP_PRIORITIZE_CHACHA && sk_SSL_CIPHER_num(clnt) > 0) {
|
||||
c = sk_SSL_CIPHER_value(clnt, 0);
|
||||
if (c->algorithm_enc == SSL_CHACHA20POLY1305) {
|
||||
/* ChaCha20 is client preferred, check server... */
|
||||
int num = sk_SSL_CIPHER_num(srvr);
|
||||
int found = 0;
|
||||
for (i = 0; i < num; i++) {
|
||||
c = sk_SSL_CIPHER_value(srvr, i);
|
||||
if (c->algorithm_enc == SSL_CHACHA20POLY1305) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
prio_chacha = sk_SSL_CIPHER_new_reserve(NULL, num);
|
||||
/* if reserve fails, then there's likely a memory issue */
|
||||
if (prio_chacha != NULL) {
|
||||
/* Put all ChaCha20 at the top, starting with the one we just found */
|
||||
sk_SSL_CIPHER_push(prio_chacha, c);
|
||||
for (i++; i < num; i++) {
|
||||
c = sk_SSL_CIPHER_value(srvr, i);
|
||||
if (c->algorithm_enc == SSL_CHACHA20POLY1305)
|
||||
sk_SSL_CIPHER_push(prio_chacha, c);
|
||||
}
|
||||
/* Pull in the rest */
|
||||
for (i = 0; i < num; i++) {
|
||||
c = sk_SSL_CIPHER_value(srvr, i);
|
||||
if (c->algorithm_enc != SSL_CHACHA20POLY1305)
|
||||
sk_SSL_CIPHER_push(prio_chacha, c);
|
||||
}
|
||||
prio = prio_chacha;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
# endif
|
||||
} else {
|
||||
prio = clnt;
|
||||
in_group_flags = NULL;
|
||||
allow = srvr;
|
||||
}
|
||||
|
||||
if (!SSL_IS_TLS13(s)) {
|
||||
if (SSL_IS_TLS13(s)) {
|
||||
#ifndef OPENSSL_NO_PSK
|
||||
int j;
|
||||
|
||||
/*
|
||||
* If we allow "old" style PSK callbacks, and we have no certificate (so
|
||||
* we're not going to succeed without a PSK anyway), and we're in
|
||||
* TLSv1.3 then the default hash for a PSK is SHA-256 (as per the
|
||||
* TLSv1.3 spec). Therefore we should prioritise ciphersuites using
|
||||
* that.
|
||||
*/
|
||||
if (s->psk_server_callback != NULL) {
|
||||
for (j = 0; j < SSL_PKEY_NUM && !ssl_has_cert(s, j); j++);
|
||||
if (j == SSL_PKEY_NUM) {
|
||||
/* There are no certificates */
|
||||
prefer_sha256 = 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
tls1_set_cert_validity(s);
|
||||
ssl_set_masks(s);
|
||||
}
|
||||
@@ -4166,16 +4218,14 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt,
|
||||
for (i = 0; i < sk_SSL_CIPHER_num(prio); i++) {
|
||||
c = sk_SSL_CIPHER_value(prio, i);
|
||||
|
||||
ok = 1;
|
||||
|
||||
/* Skip ciphers not supported by the protocol version */
|
||||
if (!SSL_IS_DTLS(s) &&
|
||||
((s->version < c->min_tls) || (s->version > c->max_tls)))
|
||||
ok = 0;
|
||||
continue;
|
||||
if (SSL_IS_DTLS(s) &&
|
||||
(DTLS_VERSION_LT(s->version, c->min_dtls) ||
|
||||
DTLS_VERSION_GT(s->version, c->max_dtls)))
|
||||
ok = 0;
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Since TLS 1.3 ciphersuites can be used with any auth or
|
||||
@@ -4197,10 +4247,10 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt,
|
||||
#ifndef OPENSSL_NO_PSK
|
||||
/* with PSK there must be server callback set */
|
||||
if ((alg_k & SSL_PSK) && s->psk_server_callback == NULL)
|
||||
ok = 0;
|
||||
continue;
|
||||
#endif /* OPENSSL_NO_PSK */
|
||||
|
||||
ok = ok && (alg_k & mask_k) && (alg_a & mask_a);
|
||||
ok = (alg_k & mask_k) && (alg_a & mask_a);
|
||||
#ifdef CIPHER_DEBUG
|
||||
fprintf(stderr, "%d:[%08lX:%08lX:%08lX:%08lX]%p:%s\n", ok, alg_k,
|
||||
alg_a, mask_k, mask_a, (void *)c, c->name);
|
||||
@@ -4217,14 +4267,6 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt,
|
||||
|
||||
if (!ok)
|
||||
continue;
|
||||
|
||||
safari_ec = 0;
|
||||
#if !defined(OPENSSL_NO_EC)
|
||||
if ((alg_k & SSL_kECDHE) && (alg_a & SSL_aECDSA)) {
|
||||
if (s->s3->is_probably_safari)
|
||||
safari_ec = 1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
ii = sk_SSL_CIPHER_find(allow, c);
|
||||
if (ii >= 0) {
|
||||
@@ -4232,38 +4274,32 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt,
|
||||
if (!ssl_security(s, SSL_SECOP_CIPHER_SHARED,
|
||||
c->strength_bits, 0, (void *)c))
|
||||
continue;
|
||||
|
||||
if (in_group_flags != NULL && in_group_flags[i] == 1) {
|
||||
/* This element of |prio| is in a group. Update
|
||||
* the minimum index found so far and continue
|
||||
* looking. */
|
||||
if (group_min == -1 || group_min > ii)
|
||||
group_min = ii;
|
||||
} else {
|
||||
if (group_min != -1 && group_min < ii)
|
||||
ii = group_min;
|
||||
if (safari_ec) {
|
||||
if (!ret)
|
||||
ret = sk_SSL_CIPHER_value(allow, ii);
|
||||
continue;
|
||||
}
|
||||
ret = sk_SSL_CIPHER_value(allow, ii);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (in_group_flags != NULL && !in_group_flags[i] && group_min != -1) {
|
||||
/* We are about to leave a group, but we found a match
|
||||
* in it, so that's our answer. */
|
||||
if (safari_ec) {
|
||||
#if !defined(OPENSSL_NO_EC)
|
||||
if ((alg_k & SSL_kECDHE) && (alg_a & SSL_aECDSA)
|
||||
&& s->s3->is_probably_safari) {
|
||||
if (!ret)
|
||||
ret = sk_SSL_CIPHER_value(allow, group_min);
|
||||
ret = sk_SSL_CIPHER_value(allow, ii);
|
||||
continue;
|
||||
}
|
||||
ret = sk_SSL_CIPHER_value(allow, group_min);
|
||||
#endif
|
||||
if (prefer_sha256) {
|
||||
const SSL_CIPHER *tmp = sk_SSL_CIPHER_value(allow, ii);
|
||||
|
||||
if (ssl_md(tmp->algorithm2) == mdsha256) {
|
||||
ret = tmp;
|
||||
break;
|
||||
}
|
||||
if (ret == NULL)
|
||||
ret = tmp;
|
||||
continue;
|
||||
}
|
||||
ret = sk_SSL_CIPHER_value(allow, ii);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#ifndef OPENSSL_NO_CHACHA
|
||||
sk_SSL_CIPHER_free(prio_chacha);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -4519,12 +4555,12 @@ int ssl_fill_hello_random(SSL *s, int server, unsigned char *result, size_t len,
|
||||
unsigned char *p = result;
|
||||
|
||||
l2n(Time, p);
|
||||
ret = ssl_randbytes(s, p, len - 4);
|
||||
ret = RAND_bytes(p, len - 4);
|
||||
} else {
|
||||
ret = ssl_randbytes(s, result, len);
|
||||
ret = RAND_bytes(result, len);
|
||||
}
|
||||
#ifndef OPENSSL_NO_TLS13DOWNGRADE
|
||||
if (ret) {
|
||||
if (ret > 0) {
|
||||
if (!ossl_assert(sizeof(tls11downgrade) < len)
|
||||
|| !ossl_assert(sizeof(tls12downgrade) < len))
|
||||
return 0;
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2005 Nokia. All rights reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
|
||||
@@ -227,7 +227,6 @@ void ssl_cert_free(CERT *c)
|
||||
|
||||
if (c == NULL)
|
||||
return;
|
||||
|
||||
CRYPTO_DOWN_REF(&c->references, &i, c->lock);
|
||||
REF_PRINT_COUNT("CERT", c);
|
||||
if (i > 0)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2017 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
|
||||
+195
-155
@@ -15,6 +15,7 @@
|
||||
#include <openssl/comp.h>
|
||||
#include <openssl/engine.h>
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/conf.h>
|
||||
#include "internal/nelem.h"
|
||||
#include "ssl_locl.h"
|
||||
#include "internal/thread_once.h"
|
||||
@@ -189,7 +190,6 @@ typedef struct cipher_order_st {
|
||||
const SSL_CIPHER *cipher;
|
||||
int active;
|
||||
int dead;
|
||||
int in_group;
|
||||
struct cipher_order_st *next, *prev;
|
||||
} CIPHER_ORDER;
|
||||
|
||||
@@ -682,7 +682,6 @@ static void ssl_cipher_collect_ciphers(const SSL_METHOD *ssl_method,
|
||||
co_list[co_list_num].next = NULL;
|
||||
co_list[co_list_num].prev = NULL;
|
||||
co_list[co_list_num].active = 0;
|
||||
co_list[co_list_num].in_group = 0;
|
||||
co_list_num++;
|
||||
}
|
||||
|
||||
@@ -776,8 +775,8 @@ static void ssl_cipher_apply_rule(uint32_t cipher_id, uint32_t alg_mkey,
|
||||
uint32_t alg_auth, uint32_t alg_enc,
|
||||
uint32_t alg_mac, int min_tls,
|
||||
uint32_t algo_strength, int rule,
|
||||
int32_t strength_bits, int in_group,
|
||||
CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p)
|
||||
int32_t strength_bits, CIPHER_ORDER **head_p,
|
||||
CIPHER_ORDER **tail_p)
|
||||
{
|
||||
CIPHER_ORDER *head, *tail, *curr, *next, *last;
|
||||
const SSL_CIPHER *cp;
|
||||
@@ -785,9 +784,9 @@ static void ssl_cipher_apply_rule(uint32_t cipher_id, uint32_t alg_mkey,
|
||||
|
||||
#ifdef CIPHER_DEBUG
|
||||
fprintf(stderr,
|
||||
"Applying rule %d with %08x/%08x/%08x/%08x/%08x %08x (%d) g:%d\n",
|
||||
"Applying rule %d with %08x/%08x/%08x/%08x/%08x %08x (%d)\n",
|
||||
rule, alg_mkey, alg_auth, alg_enc, alg_mac, min_tls,
|
||||
algo_strength, strength_bits, in_group);
|
||||
algo_strength, strength_bits);
|
||||
#endif
|
||||
|
||||
if (rule == CIPHER_DEL || rule == CIPHER_BUMP)
|
||||
@@ -864,7 +863,6 @@ static void ssl_cipher_apply_rule(uint32_t cipher_id, uint32_t alg_mkey,
|
||||
if (!curr->active) {
|
||||
ll_append_tail(&head, curr, &tail);
|
||||
curr->active = 1;
|
||||
curr->in_group = in_group;
|
||||
}
|
||||
}
|
||||
/* Move the added cipher to this location */
|
||||
@@ -872,7 +870,6 @@ static void ssl_cipher_apply_rule(uint32_t cipher_id, uint32_t alg_mkey,
|
||||
/* reverse == 0 */
|
||||
if (curr->active) {
|
||||
ll_append_tail(&head, curr, &tail);
|
||||
curr->in_group = 0;
|
||||
}
|
||||
} else if (rule == CIPHER_DEL) {
|
||||
/* reverse == 1 */
|
||||
@@ -884,7 +881,6 @@ static void ssl_cipher_apply_rule(uint32_t cipher_id, uint32_t alg_mkey,
|
||||
*/
|
||||
ll_append_head(&head, curr, &tail);
|
||||
curr->active = 0;
|
||||
curr->in_group = 0;
|
||||
}
|
||||
} else if (rule == CIPHER_BUMP) {
|
||||
if (curr->active)
|
||||
@@ -952,8 +948,8 @@ static int ssl_cipher_strength_sort(CIPHER_ORDER **head_p,
|
||||
*/
|
||||
for (i = max_strength_bits; i >= 0; i--)
|
||||
if (number_uses[i] > 0)
|
||||
ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_ORD, i, 0,
|
||||
head_p, tail_p);
|
||||
ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_ORD, i, head_p,
|
||||
tail_p);
|
||||
|
||||
OPENSSL_free(number_uses);
|
||||
return 1;
|
||||
@@ -967,7 +963,7 @@ static int ssl_cipher_process_rulestr(const char *rule_str,
|
||||
uint32_t alg_mkey, alg_auth, alg_enc, alg_mac, algo_strength;
|
||||
int min_tls;
|
||||
const char *l, *buf;
|
||||
int j, multi, found, rule, retval, ok, buflen, in_group = 0, has_group = 0;
|
||||
int j, multi, found, rule, retval, ok, buflen;
|
||||
uint32_t cipher_id = 0;
|
||||
char ch;
|
||||
|
||||
@@ -978,66 +974,18 @@ static int ssl_cipher_process_rulestr(const char *rule_str,
|
||||
|
||||
if (ch == '\0')
|
||||
break; /* done */
|
||||
if (in_group) {
|
||||
if (ch == ']') {
|
||||
if (!in_group) {
|
||||
SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR,
|
||||
SSL_R_UNEXPECTED_GROUP_CLOSE);
|
||||
retval = found = in_group = 0;
|
||||
break;
|
||||
}
|
||||
if (*tail_p)
|
||||
(*tail_p)->in_group = 0;
|
||||
in_group = 0;
|
||||
l++;
|
||||
continue;
|
||||
}
|
||||
if (ch == '|') {
|
||||
rule = CIPHER_ADD;
|
||||
l++;
|
||||
continue;
|
||||
} else if (!(ch >= 'a' && ch <= 'z')
|
||||
&& !(ch >= 'A' && ch <= 'Z')
|
||||
&& !(ch >= '0' && ch <= '9')) {
|
||||
SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR,
|
||||
SSL_R_UNEXPECTED_OPERATOR_IN_GROUP);
|
||||
retval = found = in_group = 0;
|
||||
break;
|
||||
} else {
|
||||
rule = CIPHER_ADD;
|
||||
}
|
||||
} else if (ch == '-') {
|
||||
if (ch == '-') {
|
||||
rule = CIPHER_DEL;
|
||||
l++;
|
||||
} else if (ch == '+') {
|
||||
rule = CIPHER_ORD;
|
||||
l++;
|
||||
} else if (ch == '!' && has_group) {
|
||||
SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR,
|
||||
SSL_R_MIXED_SPECIAL_OPERATOR_WITH_GROUPS);
|
||||
retval = found = in_group = 0;
|
||||
break;
|
||||
} else if (ch == '!') {
|
||||
rule = CIPHER_KILL;
|
||||
l++;
|
||||
} else if (ch == '@' && has_group) {
|
||||
SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR,
|
||||
SSL_R_MIXED_SPECIAL_OPERATOR_WITH_GROUPS);
|
||||
retval = found = in_group = 0;
|
||||
break;
|
||||
} else if (ch == '@') {
|
||||
rule = CIPHER_SPECIAL;
|
||||
l++;
|
||||
} else if (ch == '[') {
|
||||
if (in_group) {
|
||||
SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR, SSL_R_NESTED_GROUP);
|
||||
retval = found = in_group = 0;
|
||||
break;
|
||||
}
|
||||
in_group = 1;
|
||||
has_group = 1;
|
||||
l++;
|
||||
continue;
|
||||
} else {
|
||||
rule = CIPHER_ADD;
|
||||
}
|
||||
@@ -1079,7 +1027,7 @@ static int ssl_cipher_process_rulestr(const char *rule_str,
|
||||
* alphanumeric, so we call this an error.
|
||||
*/
|
||||
SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR, SSL_R_INVALID_COMMAND);
|
||||
retval = found = in_group = 0;
|
||||
retval = found = 0;
|
||||
l++;
|
||||
break;
|
||||
}
|
||||
@@ -1258,8 +1206,8 @@ static int ssl_cipher_process_rulestr(const char *rule_str,
|
||||
} else if (found) {
|
||||
ssl_cipher_apply_rule(cipher_id,
|
||||
alg_mkey, alg_auth, alg_enc, alg_mac,
|
||||
min_tls, algo_strength, rule, -1, in_group,
|
||||
head_p, tail_p);
|
||||
min_tls, algo_strength, rule, -1, head_p,
|
||||
tail_p);
|
||||
} else {
|
||||
while ((*l != '\0') && !ITEM_SEP(*l))
|
||||
l++;
|
||||
@@ -1268,11 +1216,6 @@ static int ssl_cipher_process_rulestr(const char *rule_str,
|
||||
break; /* done */
|
||||
}
|
||||
|
||||
if (in_group) {
|
||||
SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR, SSL_R_INVALID_COMMAND);
|
||||
retval = 0;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
@@ -1332,19 +1275,144 @@ static int check_suiteb_cipher_list(const SSL_METHOD *meth, CERT *c,
|
||||
}
|
||||
#endif
|
||||
|
||||
STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method,
|
||||
struct ssl_cipher_preference_list_st **cipher_list,
|
||||
STACK_OF(SSL_CIPHER) **cipher_list_by_id, const char *rule_str, CERT *c)
|
||||
static int ciphersuite_cb(const char *elem, int len, void *arg)
|
||||
{
|
||||
int ok, num_of_ciphers, num_of_alias_max, num_of_group_aliases;
|
||||
STACK_OF(SSL_CIPHER) *ciphersuites = (STACK_OF(SSL_CIPHER) *)arg;
|
||||
const SSL_CIPHER *cipher;
|
||||
/* Arbitrary sized temp buffer for the cipher name. Should be big enough */
|
||||
char name[80];
|
||||
|
||||
if (len > (int)(sizeof(name) - 1)) {
|
||||
SSLerr(SSL_F_CIPHERSUITE_CB, SSL_R_NO_CIPHER_MATCH);
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(name, elem, len);
|
||||
name[len] = '\0';
|
||||
|
||||
cipher = ssl3_get_cipher_by_std_name(name);
|
||||
if (cipher == NULL) {
|
||||
SSLerr(SSL_F_CIPHERSUITE_CB, SSL_R_NO_CIPHER_MATCH);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!sk_SSL_CIPHER_push(ciphersuites, cipher)) {
|
||||
SSLerr(SSL_F_CIPHERSUITE_CB, ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int set_ciphersuites(STACK_OF(SSL_CIPHER) **currciphers, const char *str)
|
||||
{
|
||||
STACK_OF(SSL_CIPHER) *newciphers = sk_SSL_CIPHER_new_null();
|
||||
|
||||
if (newciphers == NULL)
|
||||
return 0;
|
||||
|
||||
/* Parse the list. We explicitly allow an empty list */
|
||||
if (*str != '\0'
|
||||
&& !CONF_parse_list(str, ':', 1, ciphersuite_cb, newciphers)) {
|
||||
sk_SSL_CIPHER_free(newciphers);
|
||||
return 0;
|
||||
}
|
||||
sk_SSL_CIPHER_free(*currciphers);
|
||||
*currciphers = newciphers;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int update_cipher_list_by_id(STACK_OF(SSL_CIPHER) **cipher_list_by_id,
|
||||
STACK_OF(SSL_CIPHER) *cipherstack)
|
||||
{
|
||||
STACK_OF(SSL_CIPHER) *tmp_cipher_list = sk_SSL_CIPHER_dup(cipherstack);
|
||||
|
||||
if (tmp_cipher_list == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
sk_SSL_CIPHER_free(*cipher_list_by_id);
|
||||
*cipher_list_by_id = tmp_cipher_list;
|
||||
|
||||
(void)sk_SSL_CIPHER_set_cmp_func(*cipher_list_by_id, ssl_cipher_ptr_id_cmp);
|
||||
sk_SSL_CIPHER_sort(*cipher_list_by_id);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int update_cipher_list(STACK_OF(SSL_CIPHER) **cipher_list,
|
||||
STACK_OF(SSL_CIPHER) **cipher_list_by_id,
|
||||
STACK_OF(SSL_CIPHER) *tls13_ciphersuites)
|
||||
{
|
||||
int i;
|
||||
STACK_OF(SSL_CIPHER) *tmp_cipher_list = sk_SSL_CIPHER_dup(*cipher_list);
|
||||
|
||||
if (tmp_cipher_list == NULL)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Delete any existing TLSv1.3 ciphersuites. These are always first in the
|
||||
* list.
|
||||
*/
|
||||
while (sk_SSL_CIPHER_num(tmp_cipher_list) > 0
|
||||
&& sk_SSL_CIPHER_value(tmp_cipher_list, 0)->min_tls
|
||||
== TLS1_3_VERSION)
|
||||
sk_SSL_CIPHER_delete(tmp_cipher_list, 0);
|
||||
|
||||
/* Insert the new TLSv1.3 ciphersuites */
|
||||
for (i = 0; i < sk_SSL_CIPHER_num(tls13_ciphersuites); i++)
|
||||
sk_SSL_CIPHER_insert(tmp_cipher_list,
|
||||
sk_SSL_CIPHER_value(tls13_ciphersuites, i), i);
|
||||
|
||||
if (!update_cipher_list_by_id(cipher_list_by_id, tmp_cipher_list))
|
||||
return 0;
|
||||
|
||||
sk_SSL_CIPHER_free(*cipher_list);
|
||||
*cipher_list = tmp_cipher_list;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int SSL_CTX_set_ciphersuites(SSL_CTX *ctx, const char *str)
|
||||
{
|
||||
int ret = set_ciphersuites(&(ctx->tls13_ciphersuites), str);
|
||||
|
||||
if (ret && ctx->cipher_list != NULL) {
|
||||
/* We already have a cipher_list, so we need to update it */
|
||||
return update_cipher_list(&ctx->cipher_list, &ctx->cipher_list_by_id,
|
||||
ctx->tls13_ciphersuites);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SSL_set_ciphersuites(SSL *s, const char *str)
|
||||
{
|
||||
int ret = set_ciphersuites(&(s->tls13_ciphersuites), str);
|
||||
|
||||
if (ret && s->cipher_list != NULL) {
|
||||
/* We already have a cipher_list, so we need to update it */
|
||||
return update_cipher_list(&s->cipher_list, &s->cipher_list_by_id,
|
||||
s->tls13_ciphersuites);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method,
|
||||
STACK_OF(SSL_CIPHER) *tls13_ciphersuites,
|
||||
STACK_OF(SSL_CIPHER) **cipher_list,
|
||||
STACK_OF(SSL_CIPHER) **cipher_list_by_id,
|
||||
const char *rule_str,
|
||||
CERT *c)
|
||||
{
|
||||
int ok, num_of_ciphers, num_of_alias_max, num_of_group_aliases, i;
|
||||
uint32_t disabled_mkey, disabled_auth, disabled_enc, disabled_mac;
|
||||
STACK_OF(SSL_CIPHER) *cipherstack = NULL, *tmp_cipher_list = NULL;
|
||||
STACK_OF(SSL_CIPHER) *cipherstack;
|
||||
const char *rule_p;
|
||||
CIPHER_ORDER *co_list = NULL, *head = NULL, *tail = NULL, *curr;
|
||||
const SSL_CIPHER **ca_list = NULL;
|
||||
uint8_t *in_group_flags = NULL;
|
||||
unsigned int num_in_group_flags = 0;
|
||||
struct ssl_cipher_preference_list_st *pref_list = NULL;
|
||||
|
||||
/*
|
||||
* Return with error if nothing to do.
|
||||
@@ -1393,16 +1461,16 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method,
|
||||
* preference).
|
||||
*/
|
||||
ssl_cipher_apply_rule(0, SSL_kECDHE, SSL_aECDSA, 0, 0, 0, 0, CIPHER_ADD,
|
||||
-1, 0,&head, &tail);
|
||||
ssl_cipher_apply_rule(0, SSL_kECDHE, 0, 0, 0, 0, 0, CIPHER_ADD, -1, 0,
|
||||
&head, &tail);
|
||||
ssl_cipher_apply_rule(0, SSL_kECDHE, 0, 0, 0, 0, 0, CIPHER_DEL, -1, 0,
|
||||
&head, &tail);
|
||||
-1, &head, &tail);
|
||||
ssl_cipher_apply_rule(0, SSL_kECDHE, 0, 0, 0, 0, 0, CIPHER_ADD, -1, &head,
|
||||
&tail);
|
||||
ssl_cipher_apply_rule(0, SSL_kECDHE, 0, 0, 0, 0, 0, CIPHER_DEL, -1, &head,
|
||||
&tail);
|
||||
|
||||
/* Within each strength group, we prefer GCM over CHACHA... */
|
||||
ssl_cipher_apply_rule(0, 0, 0, SSL_AESGCM, 0, 0, 0, CIPHER_ADD, -1, 0,
|
||||
ssl_cipher_apply_rule(0, 0, 0, SSL_AESGCM, 0, 0, 0, CIPHER_ADD, -1,
|
||||
&head, &tail);
|
||||
ssl_cipher_apply_rule(0, 0, 0, SSL_CHACHA20, 0, 0, 0, CIPHER_ADD, -1, 0,
|
||||
ssl_cipher_apply_rule(0, 0, 0, SSL_CHACHA20, 0, 0, 0, CIPHER_ADD, -1,
|
||||
&head, &tail);
|
||||
|
||||
/*
|
||||
@@ -1411,13 +1479,13 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method,
|
||||
* strength.
|
||||
*/
|
||||
ssl_cipher_apply_rule(0, 0, 0, SSL_AES ^ SSL_AESGCM, 0, 0, 0, CIPHER_ADD,
|
||||
-1, 0, &head, &tail);
|
||||
-1, &head, &tail);
|
||||
|
||||
/* Temporarily enable everything else for sorting */
|
||||
ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_ADD, -1, 0, &head, &tail);
|
||||
ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_ADD, -1, &head, &tail);
|
||||
|
||||
/* Low priority for MD5 */
|
||||
ssl_cipher_apply_rule(0, 0, 0, 0, SSL_MD5, 0, 0, CIPHER_ORD, -1, 0, &head,
|
||||
ssl_cipher_apply_rule(0, 0, 0, 0, SSL_MD5, 0, 0, CIPHER_ORD, -1, &head,
|
||||
&tail);
|
||||
|
||||
/*
|
||||
@@ -1425,16 +1493,16 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method,
|
||||
* disabled. (For applications that allow them, they aren't too bad, but
|
||||
* we prefer authenticated ciphers.)
|
||||
*/
|
||||
ssl_cipher_apply_rule(0, 0, SSL_aNULL, 0, 0, 0, 0, CIPHER_ORD, -1, 0, &head,
|
||||
ssl_cipher_apply_rule(0, 0, SSL_aNULL, 0, 0, 0, 0, CIPHER_ORD, -1, &head,
|
||||
&tail);
|
||||
|
||||
ssl_cipher_apply_rule(0, SSL_kRSA, 0, 0, 0, 0, 0, CIPHER_ORD, -1, 0, &head,
|
||||
ssl_cipher_apply_rule(0, SSL_kRSA, 0, 0, 0, 0, 0, CIPHER_ORD, -1, &head,
|
||||
&tail);
|
||||
ssl_cipher_apply_rule(0, SSL_kPSK, 0, 0, 0, 0, 0, CIPHER_ORD, -1, 0, &head,
|
||||
ssl_cipher_apply_rule(0, SSL_kPSK, 0, 0, 0, 0, 0, CIPHER_ORD, -1, &head,
|
||||
&tail);
|
||||
|
||||
/* RC4 is sort-of broken -- move to the end */
|
||||
ssl_cipher_apply_rule(0, 0, 0, SSL_RC4, 0, 0, 0, CIPHER_ORD, -1, 0, &head,
|
||||
ssl_cipher_apply_rule(0, 0, 0, SSL_RC4, 0, 0, 0, CIPHER_ORD, -1, &head,
|
||||
&tail);
|
||||
|
||||
/*
|
||||
@@ -1450,7 +1518,7 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method,
|
||||
* Partially overrule strength sort to prefer TLS 1.2 ciphers/PRFs.
|
||||
* TODO(openssl-team): is there an easier way to accomplish all this?
|
||||
*/
|
||||
ssl_cipher_apply_rule(0, 0, 0, 0, 0, TLS1_2_VERSION, 0, CIPHER_BUMP, -1, 0,
|
||||
ssl_cipher_apply_rule(0, 0, 0, 0, 0, TLS1_2_VERSION, 0, CIPHER_BUMP, -1,
|
||||
&head, &tail);
|
||||
|
||||
/*
|
||||
@@ -1466,15 +1534,15 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method,
|
||||
* Because we now bump ciphers to the top of the list, we proceed in
|
||||
* reverse order of preference.
|
||||
*/
|
||||
ssl_cipher_apply_rule(0, 0, 0, 0, SSL_AEAD, 0, 0, CIPHER_BUMP, -1, 0,
|
||||
ssl_cipher_apply_rule(0, 0, 0, 0, SSL_AEAD, 0, 0, CIPHER_BUMP, -1,
|
||||
&head, &tail);
|
||||
ssl_cipher_apply_rule(0, SSL_kDHE | SSL_kECDHE, 0, 0, 0, 0, 0,
|
||||
CIPHER_BUMP, -1, 0, &head, &tail);
|
||||
CIPHER_BUMP, -1, &head, &tail);
|
||||
ssl_cipher_apply_rule(0, SSL_kDHE | SSL_kECDHE, 0, 0, SSL_AEAD, 0, 0,
|
||||
CIPHER_BUMP, -1, 0, &head, &tail);
|
||||
CIPHER_BUMP, -1, &head, &tail);
|
||||
|
||||
/* Now disable everything (maintaining the ordering!) */
|
||||
ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_DEL, -1, 0, &head, &tail);
|
||||
ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_DEL, -1, &head, &tail);
|
||||
|
||||
/*
|
||||
* We also need cipher aliases for selecting based on the rule_str.
|
||||
@@ -1488,8 +1556,9 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method,
|
||||
num_of_alias_max = num_of_ciphers + num_of_group_aliases + 1;
|
||||
ca_list = OPENSSL_malloc(sizeof(*ca_list) * num_of_alias_max);
|
||||
if (ca_list == NULL) {
|
||||
OPENSSL_free(co_list);
|
||||
SSLerr(SSL_F_SSL_CREATE_CIPHER_LIST, ERR_R_MALLOC_FAILURE);
|
||||
goto err; /* Failure */
|
||||
return NULL; /* Failure */
|
||||
}
|
||||
ssl_cipher_collect_aliases(ca_list, num_of_group_aliases,
|
||||
disabled_mkey, disabled_auth, disabled_enc,
|
||||
@@ -1514,19 +1583,28 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method,
|
||||
|
||||
OPENSSL_free(ca_list); /* Not needed anymore */
|
||||
|
||||
if (!ok)
|
||||
goto err; /* Rule processing failure */
|
||||
if (!ok) { /* Rule processing failure */
|
||||
OPENSSL_free(co_list);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate new "cipherstack" for the result, return with error
|
||||
* if we cannot get one.
|
||||
*/
|
||||
if ((cipherstack = sk_SSL_CIPHER_new_null()) == NULL)
|
||||
goto err;
|
||||
if ((cipherstack = sk_SSL_CIPHER_new_null()) == NULL) {
|
||||
OPENSSL_free(co_list);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
in_group_flags = OPENSSL_malloc(num_of_ciphers);
|
||||
if (!in_group_flags)
|
||||
goto err;
|
||||
/* Add TLSv1.3 ciphers first - we always prefer those if possible */
|
||||
for (i = 0; i < sk_SSL_CIPHER_num(tls13_ciphersuites); i++) {
|
||||
if (!sk_SSL_CIPHER_push(cipherstack,
|
||||
sk_SSL_CIPHER_value(tls13_ciphersuites, i))) {
|
||||
sk_SSL_CIPHER_free(cipherstack);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The cipher selection for the list is done. The ciphers are added
|
||||
@@ -1534,65 +1612,26 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method,
|
||||
*/
|
||||
for (curr = head; curr != NULL; curr = curr->next) {
|
||||
if (curr->active) {
|
||||
if (!sk_SSL_CIPHER_push(cipherstack, curr->cipher))
|
||||
goto err;
|
||||
in_group_flags[num_in_group_flags++] = curr->in_group;
|
||||
if (!sk_SSL_CIPHER_push(cipherstack, curr->cipher)) {
|
||||
OPENSSL_free(co_list);
|
||||
sk_SSL_CIPHER_free(cipherstack);
|
||||
return NULL;
|
||||
}
|
||||
#ifdef CIPHER_DEBUG
|
||||
fprintf(stderr, "<%s>\n", curr->cipher->name);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
OPENSSL_free(co_list); /* Not needed any longer */
|
||||
co_list = NULL;
|
||||
|
||||
tmp_cipher_list = sk_SSL_CIPHER_dup(cipherstack);
|
||||
if (tmp_cipher_list == NULL)
|
||||
goto err;
|
||||
|
||||
pref_list = OPENSSL_malloc(sizeof(struct ssl_cipher_preference_list_st));
|
||||
if (!pref_list)
|
||||
goto err;
|
||||
pref_list->ciphers = cipherstack;
|
||||
pref_list->in_group_flags = OPENSSL_malloc(num_in_group_flags);
|
||||
if (!pref_list->in_group_flags)
|
||||
goto err;
|
||||
memcpy(pref_list->in_group_flags, in_group_flags, num_in_group_flags);
|
||||
OPENSSL_free(in_group_flags);
|
||||
in_group_flags = NULL;
|
||||
if (*cipher_list != NULL)
|
||||
ssl_cipher_preference_list_free(*cipher_list);
|
||||
*cipher_list = pref_list;
|
||||
pref_list = NULL;
|
||||
|
||||
if (cipher_list_by_id != NULL) {
|
||||
if (*cipher_list_by_id != NULL)
|
||||
sk_SSL_CIPHER_free(*cipher_list_by_id);
|
||||
*cipher_list_by_id = tmp_cipher_list;
|
||||
tmp_cipher_list = NULL;
|
||||
(void)sk_SSL_CIPHER_set_cmp_func(*cipher_list_by_id,
|
||||
ssl_cipher_ptr_id_cmp);
|
||||
sk_SSL_CIPHER_sort(*cipher_list_by_id);
|
||||
} else {
|
||||
sk_SSL_CIPHER_free(tmp_cipher_list);
|
||||
tmp_cipher_list = NULL;
|
||||
if (!update_cipher_list_by_id(cipher_list_by_id, cipherstack)) {
|
||||
sk_SSL_CIPHER_free(cipherstack);
|
||||
return NULL;
|
||||
}
|
||||
sk_SSL_CIPHER_free(*cipher_list);
|
||||
*cipher_list = cipherstack;
|
||||
|
||||
return cipherstack;
|
||||
|
||||
err:
|
||||
if (co_list)
|
||||
OPENSSL_free(co_list);
|
||||
if (in_group_flags)
|
||||
OPENSSL_free(in_group_flags);
|
||||
if (cipherstack)
|
||||
sk_SSL_CIPHER_free(cipherstack);
|
||||
if (tmp_cipher_list)
|
||||
sk_SSL_CIPHER_free(tmp_cipher_list);
|
||||
if (pref_list && pref_list->in_group_flags)
|
||||
OPENSSL_free(pref_list->in_group_flags);
|
||||
if (pref_list)
|
||||
OPENSSL_free(pref_list);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len)
|
||||
@@ -1604,9 +1643,10 @@ char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len)
|
||||
|
||||
if (buf == NULL) {
|
||||
len = 128;
|
||||
buf = OPENSSL_malloc(len);
|
||||
if (buf == NULL)
|
||||
if ((buf = OPENSSL_malloc(len)) == NULL) {
|
||||
SSLerr(SSL_F_SSL_CIPHER_DESCRIPTION, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
} else if (len < 128) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+33
-3
@@ -229,8 +229,9 @@ static int cmd_ECDHParameters(SSL_CONF_CTX *cctx, const char *value)
|
||||
int nid;
|
||||
|
||||
/* Ignore values supported by 1.0.2 for the automatic selection */
|
||||
if ((cctx->flags & SSL_CONF_FLAG_FILE) &&
|
||||
strcasecmp(value, "+automatic") == 0)
|
||||
if ((cctx->flags & SSL_CONF_FLAG_FILE)
|
||||
&& (strcasecmp(value, "+automatic") == 0
|
||||
|| strcasecmp(value, "automatic") == 0))
|
||||
return 1;
|
||||
if ((cctx->flags & SSL_CONF_FLAG_CMDLINE) &&
|
||||
strcmp(value, "auto") == 0)
|
||||
@@ -256,6 +257,7 @@ static int cmd_ECDHParameters(SSL_CONF_CTX *cctx, const char *value)
|
||||
static int cmd_CipherString(SSL_CONF_CTX *cctx, const char *value)
|
||||
{
|
||||
int rv = 1;
|
||||
|
||||
if (cctx->ctx)
|
||||
rv = SSL_CTX_set_cipher_list(cctx->ctx, value);
|
||||
if (cctx->ssl)
|
||||
@@ -263,6 +265,17 @@ static int cmd_CipherString(SSL_CONF_CTX *cctx, const char *value)
|
||||
return rv > 0;
|
||||
}
|
||||
|
||||
static int cmd_Ciphersuites(SSL_CONF_CTX *cctx, const char *value)
|
||||
{
|
||||
int rv = 1;
|
||||
|
||||
if (cctx->ctx)
|
||||
rv = SSL_CTX_set_ciphersuites(cctx->ctx, value);
|
||||
if (cctx->ssl)
|
||||
rv = SSL_set_ciphersuites(cctx->ssl, value);
|
||||
return rv > 0;
|
||||
}
|
||||
|
||||
static int cmd_Protocol(SSL_CONF_CTX *cctx, const char *value)
|
||||
{
|
||||
static const ssl_flag_tbl ssl_protocol_list[] = {
|
||||
@@ -557,6 +570,21 @@ static int cmd_RecordPadding(SSL_CONF_CTX *cctx, const char *value)
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
static int cmd_NumTickets(SSL_CONF_CTX *cctx, const char *value)
|
||||
{
|
||||
int rv = 0;
|
||||
int num_tickets = atoi(value);
|
||||
|
||||
if (num_tickets >= 0) {
|
||||
if (cctx->ctx)
|
||||
rv = SSL_CTX_set_num_tickets(cctx->ctx, num_tickets);
|
||||
if (cctx->ssl)
|
||||
rv = SSL_set_num_tickets(cctx->ssl, num_tickets);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
int (*cmd) (SSL_CONF_CTX *cctx, const char *value);
|
||||
const char *str_file;
|
||||
@@ -606,6 +634,7 @@ static const ssl_conf_cmd_tbl ssl_conf_cmds[] = {
|
||||
SSL_CONF_CMD_STRING(ECDHParameters, "named_curve", SSL_CONF_FLAG_SERVER),
|
||||
#endif
|
||||
SSL_CONF_CMD_STRING(CipherString, "cipher", 0),
|
||||
SSL_CONF_CMD_STRING(Ciphersuites, "ciphersuites", 0),
|
||||
SSL_CONF_CMD_STRING(Protocol, NULL, 0),
|
||||
SSL_CONF_CMD_STRING(MinProtocol, "min_protocol", 0),
|
||||
SSL_CONF_CMD_STRING(MaxProtocol, "max_protocol", 0),
|
||||
@@ -641,7 +670,8 @@ static const ssl_conf_cmd_tbl ssl_conf_cmds[] = {
|
||||
SSL_CONF_FLAG_SERVER | SSL_CONF_FLAG_CERTIFICATE,
|
||||
SSL_CONF_TYPE_FILE),
|
||||
#endif
|
||||
SSL_CONF_CMD_STRING(RecordPadding, "record_padding", 0)
|
||||
SSL_CONF_CMD_STRING(RecordPadding, "record_padding", 0),
|
||||
SSL_CONF_CMD_STRING(NumTickets, "num_tickets", SSL_CONF_FLAG_SERVER)
|
||||
};
|
||||
|
||||
/* Supported switches: must match order of switches in ssl_conf_cmds */
|
||||
|
||||
+22
-6
@@ -20,6 +20,7 @@ static const ERR_STRING_DATA SSL_str_functs[] = {
|
||||
"bytes_to_cipher_list"},
|
||||
{ERR_PACK(ERR_LIB_SSL, SSL_F_CHECK_SUITEB_CIPHER_LIST, 0),
|
||||
"check_suiteb_cipher_list"},
|
||||
{ERR_PACK(ERR_LIB_SSL, SSL_F_CIPHERSUITE_CB, 0), "ciphersuite_cb"},
|
||||
{ERR_PACK(ERR_LIB_SSL, SSL_F_CONSTRUCT_CA_NAMES, 0), "construct_ca_names"},
|
||||
{ERR_PACK(ERR_LIB_SSL, SSL_F_CONSTRUCT_KEY_EXCHANGE_TBS, 0),
|
||||
"construct_key_exchange_tbs"},
|
||||
@@ -42,6 +43,8 @@ static const ERR_STRING_DATA SSL_str_functs[] = {
|
||||
{ERR_PACK(ERR_LIB_SSL, SSL_F_DTLS1_CHECK_TIMEOUT_NUM, 0),
|
||||
"dtls1_check_timeout_num"},
|
||||
{ERR_PACK(ERR_LIB_SSL, SSL_F_DTLS1_HEARTBEAT, 0), ""},
|
||||
{ERR_PACK(ERR_LIB_SSL, SSL_F_DTLS1_HM_FRAGMENT_NEW, 0),
|
||||
"dtls1_hm_fragment_new"},
|
||||
{ERR_PACK(ERR_LIB_SSL, SSL_F_DTLS1_PREPROCESS_FRAGMENT, 0),
|
||||
"dtls1_preprocess_fragment"},
|
||||
{ERR_PACK(ERR_LIB_SSL, SSL_F_DTLS1_PROCESS_BUFFERED_RECORDS, 0),
|
||||
@@ -64,6 +67,8 @@ static const ERR_STRING_DATA SSL_str_functs[] = {
|
||||
"dtls_get_reassembled_message"},
|
||||
{ERR_PACK(ERR_LIB_SSL, SSL_F_DTLS_PROCESS_HELLO_VERIFY, 0),
|
||||
"dtls_process_hello_verify"},
|
||||
{ERR_PACK(ERR_LIB_SSL, SSL_F_DTLS_RECORD_LAYER_NEW, 0),
|
||||
"DTLS_RECORD_LAYER_new"},
|
||||
{ERR_PACK(ERR_LIB_SSL, SSL_F_DTLS_WAIT_FOR_DRY, 0), "dtls_wait_for_dry"},
|
||||
{ERR_PACK(ERR_LIB_SSL, SSL_F_EARLY_DATA_COUNT_OK, 0),
|
||||
"early_data_count_ok"},
|
||||
@@ -108,6 +113,8 @@ static const ERR_STRING_DATA SSL_str_functs[] = {
|
||||
{ERR_PACK(ERR_LIB_SSL, SSL_F_OSSL_STATEM_SERVER_WRITE_TRANSITION, 0),
|
||||
"ossl_statem_server_write_transition"},
|
||||
{ERR_PACK(ERR_LIB_SSL, SSL_F_PARSE_CA_NAMES, 0), "parse_ca_names"},
|
||||
{ERR_PACK(ERR_LIB_SSL, SSL_F_PITEM_NEW, 0), "pitem_new"},
|
||||
{ERR_PACK(ERR_LIB_SSL, SSL_F_PQUEUE_NEW, 0), "pqueue_new"},
|
||||
{ERR_PACK(ERR_LIB_SSL, SSL_F_PROCESS_KEY_SHARE_EXT, 0), ""},
|
||||
{ERR_PACK(ERR_LIB_SSL, SSL_F_READ_STATE_MACHINE, 0), "read_state_machine"},
|
||||
{ERR_PACK(ERR_LIB_SSL, SSL_F_SET_CLIENT_CIPHERSUITE, 0),
|
||||
@@ -187,6 +194,8 @@ static const ERR_STRING_DATA SSL_str_functs[] = {
|
||||
"ssl_check_srvr_ecc_cert_and_alg"},
|
||||
{ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_CHOOSE_CLIENT_VERSION, 0),
|
||||
"ssl_choose_client_version"},
|
||||
{ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_CIPHER_DESCRIPTION, 0),
|
||||
"SSL_CIPHER_description"},
|
||||
{ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_CIPHER_LIST_TO_BYTES, 0),
|
||||
"ssl_cipher_list_to_bytes"},
|
||||
{ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_CIPHER_PROCESS_RULESTR, 0),
|
||||
@@ -194,6 +203,8 @@ static const ERR_STRING_DATA SSL_str_functs[] = {
|
||||
{ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_CIPHER_STRENGTH_SORT, 0),
|
||||
"ssl_cipher_strength_sort"},
|
||||
{ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_CLEAR, 0), "SSL_clear"},
|
||||
{ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_CLIENT_HELLO_GET1_EXTENSIONS_PRESENT, 0),
|
||||
"SSL_client_hello_get1_extensions_present"},
|
||||
{ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD, 0),
|
||||
"SSL_COMP_add_compression_method"},
|
||||
{ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_CONF_CMD, 0), "SSL_CONF_cmd"},
|
||||
@@ -387,10 +398,17 @@ static const ERR_STRING_DATA SSL_str_functs[] = {
|
||||
"tls1_export_keying_material"},
|
||||
{ERR_PACK(ERR_LIB_SSL, SSL_F_TLS1_GET_CURVELIST, 0), "tls1_get_curvelist"},
|
||||
{ERR_PACK(ERR_LIB_SSL, SSL_F_TLS1_PRF, 0), "tls1_PRF"},
|
||||
{ERR_PACK(ERR_LIB_SSL, SSL_F_TLS1_SAVE_U16, 0), "tls1_save_u16"},
|
||||
{ERR_PACK(ERR_LIB_SSL, SSL_F_TLS1_SETUP_KEY_BLOCK, 0),
|
||||
"tls1_setup_key_block"},
|
||||
{ERR_PACK(ERR_LIB_SSL, SSL_F_TLS1_SET_GROUPS, 0), "tls1_set_groups"},
|
||||
{ERR_PACK(ERR_LIB_SSL, SSL_F_TLS1_SET_RAW_SIGALGS, 0),
|
||||
"tls1_set_raw_sigalgs"},
|
||||
{ERR_PACK(ERR_LIB_SSL, SSL_F_TLS1_SET_SERVER_SIGALGS, 0),
|
||||
"tls1_set_server_sigalgs"},
|
||||
{ERR_PACK(ERR_LIB_SSL, SSL_F_TLS1_SET_SHARED_SIGALGS, 0),
|
||||
"tls1_set_shared_sigalgs"},
|
||||
{ERR_PACK(ERR_LIB_SSL, SSL_F_TLS1_SET_SIGALGS, 0), "tls1_set_sigalgs"},
|
||||
{ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CHOOSE_SIGALG, 0), "tls_choose_sigalg"},
|
||||
{ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CLIENT_KEY_EXCHANGE_POST_WORK, 0),
|
||||
"tls_client_key_exchange_post_work"},
|
||||
@@ -692,6 +710,10 @@ static const ERR_STRING_DATA SSL_str_functs[] = {
|
||||
"tls_setup_handshake"},
|
||||
{ERR_PACK(ERR_LIB_SSL, SSL_F_USE_CERTIFICATE_CHAIN_FILE, 0),
|
||||
"use_certificate_chain_file"},
|
||||
{ERR_PACK(ERR_LIB_SSL, SSL_F_WPACKET_INTERN_INIT_LEN, 0),
|
||||
"wpacket_intern_init_len"},
|
||||
{ERR_PACK(ERR_LIB_SSL, SSL_F_WPACKET_START_SUB_PACKET_LEN__, 0),
|
||||
"WPACKET_start_sub_packet_len__"},
|
||||
{ERR_PACK(ERR_LIB_SSL, SSL_F_WRITE_STATE_MACHINE, 0),
|
||||
"write_state_machine"},
|
||||
{0, NULL}
|
||||
@@ -934,9 +956,6 @@ static const ERR_STRING_DATA SSL_str_reasons[] = {
|
||||
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_MISSING_TMP_DH_KEY), "missing tmp dh key"},
|
||||
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_MISSING_TMP_ECDH_KEY),
|
||||
"missing tmp ecdh key"},
|
||||
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_MIXED_SPECIAL_OPERATOR_WITH_GROUPS),
|
||||
"mixed special operator with groups"},
|
||||
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NESTED_GROUP), "nested group"},
|
||||
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NOT_ON_RECORD_BOUNDARY),
|
||||
"not on record boundary"},
|
||||
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NOT_REPLACING_CERTIFICATE),
|
||||
@@ -1167,14 +1186,11 @@ static const ERR_STRING_DATA SSL_str_reasons[] = {
|
||||
"unable to load ssl3 md5 routines"},
|
||||
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES),
|
||||
"unable to load ssl3 sha1 routines"},
|
||||
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNEXPECTED_GROUP_CLOSE), "unexpected group close"},
|
||||
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNEXPECTED_CCS_MESSAGE),
|
||||
"unexpected ccs message"},
|
||||
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNEXPECTED_END_OF_EARLY_DATA),
|
||||
"unexpected end of early data"},
|
||||
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNEXPECTED_MESSAGE), "unexpected message"},
|
||||
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNEXPECTED_OPERATOR_IN_GROUP),
|
||||
"unexpected operator in group"},
|
||||
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNEXPECTED_RECORD), "unexpected record"},
|
||||
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNINITIALIZED), "uninitialized"},
|
||||
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNKNOWN_ALERT_TYPE), "unknown alert type"},
|
||||
|
||||
+9
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -106,7 +106,6 @@ DEFINE_RUN_ONCE_STATIC(ossl_init_ssl_base)
|
||||
fprintf(stderr, "OPENSSL_INIT: ossl_init_ssl_base: "
|
||||
"SSL_add_ssl_module()\n");
|
||||
#endif
|
||||
SSL_add_ssl_module();
|
||||
/*
|
||||
* We ignore an error return here. Not much we can do - but not that bad
|
||||
* either. We can still safely continue.
|
||||
@@ -195,11 +194,16 @@ int OPENSSL_init_ssl(uint64_t opts, const OPENSSL_INIT_SETTINGS * settings)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!RUN_ONCE(&ssl_base, ossl_init_ssl_base))
|
||||
if (!OPENSSL_init_crypto(opts
|
||||
#ifndef OPENSSL_NO_AUTOLOAD_CONFIG
|
||||
| OPENSSL_INIT_LOAD_CONFIG
|
||||
#endif
|
||||
| OPENSSL_INIT_ADD_ALL_CIPHERS
|
||||
| OPENSSL_INIT_ADD_ALL_DIGESTS,
|
||||
settings))
|
||||
return 0;
|
||||
|
||||
if (!OPENSSL_init_crypto(opts | OPENSSL_INIT_ADD_ALL_CIPHERS
|
||||
| OPENSSL_INIT_ADD_ALL_DIGESTS, settings))
|
||||
if (!RUN_ONCE(&ssl_base, ossl_init_ssl_base))
|
||||
return 0;
|
||||
|
||||
if ((opts & OPENSSL_INIT_NO_LOAD_SSL_STRINGS)
|
||||
|
||||
+140
-149
@@ -14,13 +14,13 @@
|
||||
#include <openssl/objects.h>
|
||||
#include <openssl/x509v3.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/rand_drbg.h>
|
||||
#include <openssl/ocsp.h>
|
||||
#include <openssl/dh.h>
|
||||
#include <openssl/engine.h>
|
||||
#include <openssl/async.h>
|
||||
#include <openssl/ct.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include "internal/rand.h"
|
||||
#include "internal/refcount.h"
|
||||
|
||||
const char SSL_version_str[] = OPENSSL_VERSION_TEXT;
|
||||
@@ -591,6 +591,7 @@ int SSL_clear(SSL *s)
|
||||
s->psksession_id = NULL;
|
||||
s->psksession_id_len = 0;
|
||||
s->hello_retry_request = 0;
|
||||
s->sent_tickets = 0;
|
||||
|
||||
s->error = 0;
|
||||
s->hit = 0;
|
||||
@@ -653,7 +654,9 @@ int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth)
|
||||
|
||||
ctx->method = meth;
|
||||
|
||||
sk = ssl_create_cipher_list(ctx->method, &(ctx->cipher_list),
|
||||
sk = ssl_create_cipher_list(ctx->method,
|
||||
ctx->tls13_ciphersuites,
|
||||
&(ctx->cipher_list),
|
||||
&(ctx->cipher_list_by_id),
|
||||
SSL_DEFAULT_CIPHER_LIST, ctx->cert);
|
||||
if ((sk == NULL) || (sk_SSL_CIPHER_num(sk) <= 0)) {
|
||||
@@ -688,20 +691,6 @@ SSL *SSL_new(SSL_CTX *ctx)
|
||||
goto err;
|
||||
}
|
||||
|
||||
/*
|
||||
* If not using the standard RAND (say for fuzzing), then don't use a
|
||||
* chained DRBG.
|
||||
*/
|
||||
if (RAND_get_rand_method() == RAND_OpenSSL()) {
|
||||
s->drbg =
|
||||
RAND_DRBG_new(RAND_DRBG_NID, 0, RAND_DRBG_get0_public());
|
||||
if (s->drbg == NULL
|
||||
|| RAND_DRBG_instantiate(s->drbg,
|
||||
(const unsigned char *) SSL_version_str,
|
||||
sizeof(SSL_version_str) - 1) == 0)
|
||||
goto err;
|
||||
}
|
||||
|
||||
RECORD_LAYER_init(&s->rlayer, s);
|
||||
|
||||
s->options = ctx->options;
|
||||
@@ -711,6 +700,12 @@ SSL *SSL_new(SSL_CTX *ctx)
|
||||
s->mode = ctx->mode;
|
||||
s->max_cert_list = ctx->max_cert_list;
|
||||
s->max_early_data = ctx->max_early_data;
|
||||
s->num_tickets = ctx->num_tickets;
|
||||
|
||||
/* Shallow copy of the ciphersuites stack */
|
||||
s->tls13_ciphersuites = sk_SSL_CIPHER_dup(ctx->tls13_ciphersuites);
|
||||
if (s->tls13_ciphersuites == NULL)
|
||||
goto err;
|
||||
|
||||
/*
|
||||
* Earlier library versions used to copy the pointer to the CERT, not
|
||||
@@ -1113,71 +1108,6 @@ int SSL_set1_param(SSL *ssl, X509_VERIFY_PARAM *vpm)
|
||||
return X509_VERIFY_PARAM_set1(ssl->param, vpm);
|
||||
}
|
||||
|
||||
void ssl_cipher_preference_list_free(struct ssl_cipher_preference_list_st
|
||||
*cipher_list)
|
||||
{
|
||||
sk_SSL_CIPHER_free(cipher_list->ciphers);
|
||||
OPENSSL_free(cipher_list->in_group_flags);
|
||||
OPENSSL_free(cipher_list);
|
||||
}
|
||||
|
||||
struct ssl_cipher_preference_list_st*
|
||||
ssl_cipher_preference_list_dup(struct ssl_cipher_preference_list_st
|
||||
*cipher_list)
|
||||
{
|
||||
struct ssl_cipher_preference_list_st* ret = NULL;
|
||||
size_t n = sk_SSL_CIPHER_num(cipher_list->ciphers);
|
||||
|
||||
ret = OPENSSL_malloc(sizeof(struct ssl_cipher_preference_list_st));
|
||||
if (!ret)
|
||||
goto err;
|
||||
ret->ciphers = NULL;
|
||||
ret->in_group_flags = NULL;
|
||||
ret->ciphers = sk_SSL_CIPHER_dup(cipher_list->ciphers);
|
||||
if (!ret->ciphers)
|
||||
goto err;
|
||||
ret->in_group_flags = OPENSSL_malloc(n);
|
||||
if (!ret->in_group_flags)
|
||||
goto err;
|
||||
memcpy(ret->in_group_flags, cipher_list->in_group_flags, n);
|
||||
return ret;
|
||||
|
||||
err:
|
||||
if (ret->ciphers)
|
||||
sk_SSL_CIPHER_free(ret->ciphers);
|
||||
if (ret)
|
||||
OPENSSL_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct ssl_cipher_preference_list_st*
|
||||
ssl_cipher_preference_list_from_ciphers(STACK_OF(SSL_CIPHER) *ciphers)
|
||||
{
|
||||
struct ssl_cipher_preference_list_st* ret = NULL;
|
||||
size_t n = sk_SSL_CIPHER_num(ciphers);
|
||||
|
||||
ret = OPENSSL_malloc(sizeof(struct ssl_cipher_preference_list_st));
|
||||
if (!ret)
|
||||
goto err;
|
||||
ret->ciphers = NULL;
|
||||
ret->in_group_flags = NULL;
|
||||
ret->ciphers = sk_SSL_CIPHER_dup(ciphers);
|
||||
if (!ret->ciphers)
|
||||
goto err;
|
||||
ret->in_group_flags = OPENSSL_malloc(n);
|
||||
if (!ret->in_group_flags)
|
||||
goto err;
|
||||
memset(ret->in_group_flags, 0, n);
|
||||
return ret;
|
||||
|
||||
err:
|
||||
if (ret->ciphers)
|
||||
sk_SSL_CIPHER_free(ret->ciphers);
|
||||
if (ret)
|
||||
OPENSSL_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
X509_VERIFY_PARAM *SSL_CTX_get0_param(SSL_CTX *ctx)
|
||||
{
|
||||
return ctx->param;
|
||||
@@ -1199,7 +1129,6 @@ void SSL_free(SSL *s)
|
||||
|
||||
if (s == NULL)
|
||||
return;
|
||||
|
||||
CRYPTO_DOWN_REF(&s->references, &i, s->lock);
|
||||
REF_PRINT_COUNT("SSL", s);
|
||||
if (i > 0)
|
||||
@@ -1219,9 +1148,9 @@ void SSL_free(SSL *s)
|
||||
BUF_MEM_free(s->init_buf);
|
||||
|
||||
/* add extra stuff */
|
||||
if (s->cipher_list != NULL)
|
||||
ssl_cipher_preference_list_free(s->cipher_list);
|
||||
sk_SSL_CIPHER_free(s->cipher_list);
|
||||
sk_SSL_CIPHER_free(s->cipher_list_by_id);
|
||||
sk_SSL_CIPHER_free(s->tls13_ciphersuites);
|
||||
|
||||
/* Make the next call work :-) */
|
||||
if (s->session != NULL) {
|
||||
@@ -1278,7 +1207,6 @@ void SSL_free(SSL *s)
|
||||
sk_SRTP_PROTECTION_PROFILE_free(s->srtp_profiles);
|
||||
#endif
|
||||
|
||||
RAND_DRBG_free(s->drbg);
|
||||
CRYPTO_THREAD_lock_free(s->lock);
|
||||
|
||||
OPENSSL_free(s);
|
||||
@@ -2097,6 +2025,9 @@ int SSL_write_early_data(SSL *s, const void *buf, size_t num, size_t *written)
|
||||
/* We are a server writing to an unauthenticated client */
|
||||
s->early_data_state = SSL_EARLY_DATA_UNAUTH_WRITING;
|
||||
ret = SSL_write_ex(s, buf, num, written);
|
||||
/* The buffering BIO is still in place */
|
||||
if (ret)
|
||||
(void)BIO_flush(s->wbio);
|
||||
s->early_data_state = early_data_state;
|
||||
return ret;
|
||||
|
||||
@@ -2500,9 +2431,9 @@ STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *s)
|
||||
{
|
||||
if (s != NULL) {
|
||||
if (s->cipher_list != NULL) {
|
||||
return (s->cipher_list->ciphers);
|
||||
return s->cipher_list;
|
||||
} else if ((s->ctx != NULL) && (s->ctx->cipher_list != NULL)) {
|
||||
return (s->ctx->cipher_list->ciphers);
|
||||
return s->ctx->cipher_list;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
@@ -2576,8 +2507,8 @@ const char *SSL_get_cipher_list(const SSL *s, int n)
|
||||
* preference */
|
||||
STACK_OF(SSL_CIPHER) *SSL_CTX_get_ciphers(const SSL_CTX *ctx)
|
||||
{
|
||||
if (ctx != NULL && ctx->cipher_list != NULL)
|
||||
return ctx->cipher_list->ciphers;
|
||||
if (ctx != NULL)
|
||||
return ctx->cipher_list;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -2586,8 +2517,9 @@ int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str)
|
||||
{
|
||||
STACK_OF(SSL_CIPHER) *sk;
|
||||
|
||||
sk = ssl_create_cipher_list(ctx->method, &ctx->cipher_list,
|
||||
&ctx->cipher_list_by_id, str, ctx->cert);
|
||||
sk = ssl_create_cipher_list(ctx->method, ctx->tls13_ciphersuites,
|
||||
&ctx->cipher_list, &ctx->cipher_list_by_id, str,
|
||||
ctx->cert);
|
||||
/*
|
||||
* ssl_create_cipher_list may return an empty stack if it was unable to
|
||||
* find a cipher matching the given rule string (for example if the rule
|
||||
@@ -2609,8 +2541,9 @@ int SSL_set_cipher_list(SSL *s, const char *str)
|
||||
{
|
||||
STACK_OF(SSL_CIPHER) *sk;
|
||||
|
||||
sk = ssl_create_cipher_list(s->ctx->method, &s->cipher_list,
|
||||
&s->cipher_list_by_id, str, s->cert);
|
||||
sk = ssl_create_cipher_list(s->ctx->method, s->tls13_ciphersuites,
|
||||
&s->cipher_list, &s->cipher_list_by_id, str,
|
||||
s->cert);
|
||||
/* see comment in SSL_CTX_set_cipher_list */
|
||||
if (sk == NULL)
|
||||
return 0;
|
||||
@@ -2621,28 +2554,37 @@ int SSL_set_cipher_list(SSL *s, const char *str)
|
||||
return 1;
|
||||
}
|
||||
|
||||
char *SSL_get_shared_ciphers(const SSL *s, char *buf, int len)
|
||||
char *SSL_get_shared_ciphers(const SSL *s, char *buf, int size)
|
||||
{
|
||||
char *p;
|
||||
STACK_OF(SSL_CIPHER) *sk;
|
||||
STACK_OF(SSL_CIPHER) *clntsk, *srvrsk;
|
||||
const SSL_CIPHER *c;
|
||||
int i;
|
||||
|
||||
if ((s->session == NULL) || (s->session->ciphers == NULL) || (len < 2))
|
||||
if (!s->server
|
||||
|| s->session == NULL
|
||||
|| s->session->ciphers == NULL
|
||||
|| size < 2)
|
||||
return NULL;
|
||||
|
||||
p = buf;
|
||||
sk = s->session->ciphers;
|
||||
|
||||
if (sk_SSL_CIPHER_num(sk) == 0)
|
||||
clntsk = s->session->ciphers;
|
||||
srvrsk = SSL_get_ciphers(s);
|
||||
if (clntsk == NULL || srvrsk == NULL)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) {
|
||||
if (sk_SSL_CIPHER_num(clntsk) == 0 || sk_SSL_CIPHER_num(srvrsk) == 0)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < sk_SSL_CIPHER_num(clntsk); i++) {
|
||||
int n;
|
||||
|
||||
c = sk_SSL_CIPHER_value(sk, i);
|
||||
c = sk_SSL_CIPHER_value(clntsk, i);
|
||||
if (sk_SSL_CIPHER_find(srvrsk, c) < 0)
|
||||
continue;
|
||||
|
||||
n = strlen(c->name);
|
||||
if (n + 1 > len) {
|
||||
if (n + 1 > size) {
|
||||
if (p != buf)
|
||||
--p;
|
||||
*p = '\0';
|
||||
@@ -2651,7 +2593,7 @@ char *SSL_get_shared_ciphers(const SSL *s, char *buf, int len)
|
||||
strcpy(p, c->name);
|
||||
p += n;
|
||||
*(p++) = ':';
|
||||
len -= n + 1;
|
||||
size -= n + 1;
|
||||
}
|
||||
p[-1] = '\0';
|
||||
return buf;
|
||||
@@ -2954,6 +2896,7 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth)
|
||||
ret->method = meth;
|
||||
ret->min_proto_version = 0;
|
||||
ret->max_proto_version = 0;
|
||||
ret->mode = SSL_MODE_AUTO_RETRY;
|
||||
ret->session_cache_mode = SSL_SESS_CACHE_SERVER;
|
||||
ret->session_cache_size = SSL_SESSION_CACHE_MAX_SIZE_DEFAULT;
|
||||
/* We take the system default. */
|
||||
@@ -2981,10 +2924,15 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth)
|
||||
if (ret->ctlog_store == NULL)
|
||||
goto err;
|
||||
#endif
|
||||
|
||||
if (!SSL_CTX_set_ciphersuites(ret, TLS_DEFAULT_CIPHERSUITES))
|
||||
goto err;
|
||||
|
||||
if (!ssl_create_cipher_list(ret->method,
|
||||
ret->tls13_ciphersuites,
|
||||
&ret->cipher_list, &ret->cipher_list_by_id,
|
||||
SSL_DEFAULT_CIPHER_LIST, ret->cert)
|
||||
|| sk_SSL_CIPHER_num(ret->cipher_list->ciphers) <= 0) {
|
||||
|| sk_SSL_CIPHER_num(ret->cipher_list) <= 0) {
|
||||
SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_LIBRARY_HAS_NO_CIPHERS);
|
||||
goto err2;
|
||||
}
|
||||
@@ -3008,6 +2956,9 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth)
|
||||
if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_CTX, ret, &ret->ex_data))
|
||||
goto err;
|
||||
|
||||
if ((ret->ext.secure = OPENSSL_secure_zalloc(sizeof(*ret->ext.secure))) == NULL)
|
||||
goto err;
|
||||
|
||||
/* No compression for DTLS */
|
||||
if (!(meth->ssl3_enc->enc_flags & SSL_ENC_FLAG_DTLS))
|
||||
ret->comp_methods = SSL_COMP_get_compression_methods();
|
||||
@@ -3018,13 +2969,13 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth)
|
||||
/* Setup RFC5077 ticket keys */
|
||||
if ((RAND_bytes(ret->ext.tick_key_name,
|
||||
sizeof(ret->ext.tick_key_name)) <= 0)
|
||||
|| (RAND_bytes(ret->ext.tick_hmac_key,
|
||||
sizeof(ret->ext.tick_hmac_key)) <= 0)
|
||||
|| (RAND_bytes(ret->ext.tick_aes_key,
|
||||
sizeof(ret->ext.tick_aes_key)) <= 0))
|
||||
|| (RAND_priv_bytes(ret->ext.secure->tick_hmac_key,
|
||||
sizeof(ret->ext.secure->tick_hmac_key)) <= 0)
|
||||
|| (RAND_priv_bytes(ret->ext.secure->tick_aes_key,
|
||||
sizeof(ret->ext.secure->tick_aes_key)) <= 0))
|
||||
ret->options |= SSL_OP_NO_TICKET;
|
||||
|
||||
if (RAND_bytes(ret->ext.cookie_hmac_key,
|
||||
if (RAND_priv_bytes(ret->ext.cookie_hmac_key,
|
||||
sizeof(ret->ext.cookie_hmac_key)) <= 0)
|
||||
goto err;
|
||||
|
||||
@@ -3085,6 +3036,11 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth)
|
||||
*/
|
||||
ret->max_early_data = 0;
|
||||
|
||||
/* By default we send two session tickets automatically in TLSv1.3 */
|
||||
ret->num_tickets = 2;
|
||||
|
||||
ssl_ctx_system_config(ret);
|
||||
|
||||
return ret;
|
||||
err:
|
||||
SSLerr(SSL_F_SSL_CTX_NEW, ERR_R_MALLOC_FAILURE);
|
||||
@@ -3139,8 +3095,9 @@ void SSL_CTX_free(SSL_CTX *a)
|
||||
#ifndef OPENSSL_NO_CT
|
||||
CTLOG_STORE_free(a->ctlog_store);
|
||||
#endif
|
||||
ssl_cipher_preference_list_free(a->cipher_list);
|
||||
sk_SSL_CIPHER_free(a->cipher_list);
|
||||
sk_SSL_CIPHER_free(a->cipher_list_by_id);
|
||||
sk_SSL_CIPHER_free(a->tls13_ciphersuites);
|
||||
ssl_cert_free(a->cert);
|
||||
sk_X509_NAME_pop_free(a->ca_names, X509_NAME_free);
|
||||
sk_X509_pop_free(a->extra_certs, X509_free);
|
||||
@@ -3160,6 +3117,7 @@ void SSL_CTX_free(SSL_CTX *a)
|
||||
OPENSSL_free(a->ext.supportedgroups);
|
||||
#endif
|
||||
OPENSSL_free(a->ext.alpn);
|
||||
OPENSSL_secure_free(a->ext.secure);
|
||||
|
||||
CRYPTO_THREAD_lock_free(a->lock);
|
||||
|
||||
@@ -3393,15 +3351,48 @@ void ssl_update_cache(SSL *s, int mode)
|
||||
if (s->session->session_id_length == 0)
|
||||
return;
|
||||
|
||||
/*
|
||||
* If sid_ctx_length is 0 there is no specific application context
|
||||
* associated with this session, so when we try to resume it and
|
||||
* SSL_VERIFY_PEER is requested to verify the client identity, we have no
|
||||
* indication that this is actually a session for the proper application
|
||||
* context, and the *handshake* will fail, not just the resumption attempt.
|
||||
* Do not cache (on the server) these sessions that are not resumable
|
||||
* (clients can set SSL_VERIFY_PEER without needing a sid_ctx set).
|
||||
*/
|
||||
if (s->server && s->session->sid_ctx_length == 0
|
||||
&& (s->verify_mode & SSL_VERIFY_PEER) != 0)
|
||||
return;
|
||||
|
||||
i = s->session_ctx->session_cache_mode;
|
||||
if ((i & mode) != 0
|
||||
&& (!s->hit || SSL_IS_TLS13(s))
|
||||
&& ((i & SSL_SESS_CACHE_NO_INTERNAL_STORE) != 0
|
||||
|| SSL_CTX_add_session(s->session_ctx, s->session))
|
||||
&& s->session_ctx->new_session_cb != NULL) {
|
||||
SSL_SESSION_up_ref(s->session);
|
||||
if (!s->session_ctx->new_session_cb(s, s->session))
|
||||
SSL_SESSION_free(s->session);
|
||||
&& (!s->hit || SSL_IS_TLS13(s))) {
|
||||
/*
|
||||
* Add the session to the internal cache. In server side TLSv1.3 we
|
||||
* normally don't do this because its a full stateless ticket with only
|
||||
* a dummy session id so there is no reason to cache it, unless:
|
||||
* - we are doing early_data, in which case we cache so that we can
|
||||
* detect replays
|
||||
* - the application has set a remove_session_cb so needs to know about
|
||||
* session timeout events
|
||||
*/
|
||||
if ((i & SSL_SESS_CACHE_NO_INTERNAL_STORE) == 0
|
||||
&& (!SSL_IS_TLS13(s)
|
||||
|| !s->server
|
||||
|| s->max_early_data > 0
|
||||
|| s->session_ctx->remove_session_cb != NULL))
|
||||
SSL_CTX_add_session(s->session_ctx, s->session);
|
||||
|
||||
/*
|
||||
* Add the session to the external cache. We do this even in server side
|
||||
* TLSv1.3 without early data because some applications just want to
|
||||
* know about the creation of a session and aren't doing a full cache.
|
||||
*/
|
||||
if (s->session_ctx->new_session_cb != NULL) {
|
||||
SSL_SESSION_up_ref(s->session);
|
||||
if (!s->session_ctx->new_session_cb(s, s->session))
|
||||
SSL_SESSION_free(s->session);
|
||||
}
|
||||
}
|
||||
|
||||
/* auto flush every 255 connections */
|
||||
@@ -3756,15 +3747,13 @@ SSL *SSL_dup(SSL *s)
|
||||
|
||||
/* dup the cipher_list and cipher_list_by_id stacks */
|
||||
if (s->cipher_list != NULL) {
|
||||
ret->cipher_list = ssl_cipher_preference_list_dup(s->cipher_list);
|
||||
if (ret->cipher_list == NULL)
|
||||
if ((ret->cipher_list = sk_SSL_CIPHER_dup(s->cipher_list)) == NULL)
|
||||
goto err;
|
||||
}
|
||||
if (s->cipher_list_by_id != NULL) {
|
||||
ret->cipher_list_by_id = sk_SSL_CIPHER_dup(s->cipher_list_by_id);
|
||||
if (ret->cipher_list_by_id == NULL)
|
||||
if (s->cipher_list_by_id != NULL)
|
||||
if ((ret->cipher_list_by_id = sk_SSL_CIPHER_dup(s->cipher_list_by_id))
|
||||
== NULL)
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Dup the client_CA list */
|
||||
if (s->ca_names != NULL) {
|
||||
@@ -3894,8 +3883,6 @@ int ssl_free_wbio_buffer(SSL *s)
|
||||
return 1;
|
||||
|
||||
s->wbio = BIO_pop(s->wbio);
|
||||
if (!ossl_assert(s->wbio != NULL))
|
||||
return 0;
|
||||
BIO_free(s->bbio);
|
||||
s->bbio = NULL;
|
||||
|
||||
@@ -4353,6 +4340,30 @@ int SSL_set_block_padding(SSL *ssl, size_t block_size)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int SSL_set_num_tickets(SSL *s, size_t num_tickets)
|
||||
{
|
||||
s->num_tickets = num_tickets;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
size_t SSL_get_num_tickets(SSL *s)
|
||||
{
|
||||
return s->num_tickets;
|
||||
}
|
||||
|
||||
int SSL_CTX_set_num_tickets(SSL_CTX *ctx, size_t num_tickets)
|
||||
{
|
||||
ctx->num_tickets = num_tickets;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
size_t SSL_CTX_get_num_tickets(SSL_CTX *ctx)
|
||||
{
|
||||
return ctx->num_tickets;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocates new EVP_MD_CTX and sets pointer to it into given pointer
|
||||
* variable, freeing EVP_MD_CTX previously stored in that variable, if any.
|
||||
@@ -5005,9 +5016,11 @@ int SSL_client_hello_get1_extensions_present(SSL *s, int **out, size_t *outlen)
|
||||
if (ext->present)
|
||||
num++;
|
||||
}
|
||||
present = OPENSSL_malloc(sizeof(*present) * num);
|
||||
if (present == NULL)
|
||||
if ((present = OPENSSL_malloc(sizeof(*present) * num)) == NULL) {
|
||||
SSLerr(SSL_F_SSL_CLIENT_HELLO_GET1_EXTENSIONS_PRESENT,
|
||||
ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
for (i = 0; i < s->clienthello->pre_proc_exts_len; i++) {
|
||||
ext = s->clienthello->pre_proc_exts + i;
|
||||
if (ext->present) {
|
||||
@@ -5356,28 +5369,6 @@ uint32_t SSL_get_max_early_data(const SSL *s)
|
||||
return s->max_early_data;
|
||||
}
|
||||
|
||||
int ssl_randbytes(SSL *s, unsigned char *rnd, size_t size)
|
||||
{
|
||||
if (s->drbg != NULL) {
|
||||
/*
|
||||
* Currently, it's the duty of the caller to serialize the generate
|
||||
* requests to the DRBG. So formally we have to check whether
|
||||
* s->drbg->lock != NULL and take the lock if this is the case.
|
||||
* However, this DRBG is unique to a given SSL object, and we already
|
||||
* require that SSL objects are only accessed by a single thread at
|
||||
* a given time. Also, SSL DRBGs have no child DRBG, so there is
|
||||
* no risk that this DRBG is accessed by a child DRBG in parallel
|
||||
* for reseeding. As such, we can rely on the application's
|
||||
* serialization of SSL accesses for the needed concurrency protection
|
||||
* here.
|
||||
*/
|
||||
return RAND_DRBG_bytes(s->drbg, rnd, size);
|
||||
}
|
||||
if (size > INT_MAX)
|
||||
return 0;
|
||||
return RAND_bytes(rnd, size);
|
||||
}
|
||||
|
||||
__owur unsigned int ssl_get_max_send_fragment(const SSL *ssl)
|
||||
{
|
||||
/* Return any active Max Fragment Len extension */
|
||||
|
||||
+45
-60
@@ -550,7 +550,7 @@ struct ssl_session_st {
|
||||
const SSL_CIPHER *cipher;
|
||||
unsigned long cipher_id; /* when ASN.1 loaded, this needs to be used to
|
||||
* load the 'cipher' structure */
|
||||
STACK_OF(SSL_CIPHER) *ciphers; /* shared ciphers? */
|
||||
STACK_OF(SSL_CIPHER) *ciphers; /* ciphers offered by the client */
|
||||
CRYPTO_EX_DATA ex_data; /* application specific data */
|
||||
/*
|
||||
* These are used to make removal of session-ids more efficient and to
|
||||
@@ -733,50 +733,21 @@ DEFINE_LHASH_OF(SSL_SESSION);
|
||||
/* Needed in ssl_cert.c */
|
||||
DEFINE_LHASH_OF(X509_NAME);
|
||||
|
||||
# define TLSEXT_KEYNAME_LENGTH 16
|
||||
|
||||
/* ssl_cipher_preference_list_st contains a list of SSL_CIPHERs with
|
||||
* equal-preference groups. For TLS clients, the groups are moot because the
|
||||
* server picks the cipher and groups cannot be expressed on the wire. However,
|
||||
* for servers, the equal-preference groups allow the client's preferences to
|
||||
* be partially respected. (This only has an effect with
|
||||
* SSL_OP_CIPHER_SERVER_PREFERENCE).
|
||||
*
|
||||
* The equal-preference groups are expressed by grouping SSL_CIPHERs together.
|
||||
* All elements of a group have the same priority: no ordering is expressed
|
||||
* within a group.
|
||||
*
|
||||
* The values in |ciphers| are in one-to-one correspondence with
|
||||
* |in_group_flags|. (That is, sk_SSL_CIPHER_num(ciphers) is the number of
|
||||
* bytes in |in_group_flags|.) The bytes in |in_group_flags| are either 1, to
|
||||
* indicate that the corresponding SSL_CIPHER is not the last element of a
|
||||
* group, or 0 to indicate that it is.
|
||||
*
|
||||
* For example, if |in_group_flags| contains all zeros then that indicates a
|
||||
* traditional, fully-ordered preference. Every SSL_CIPHER is the last element
|
||||
* of the group (i.e. they are all in a one-element group).
|
||||
*
|
||||
* For a more complex example, consider:
|
||||
* ciphers: A B C D E F
|
||||
* in_group_flags: 1 1 0 0 1 0
|
||||
*
|
||||
* That would express the following, order:
|
||||
*
|
||||
* A E
|
||||
* B -> D -> F
|
||||
* C
|
||||
*/
|
||||
struct ssl_cipher_preference_list_st {
|
||||
STACK_OF(SSL_CIPHER) *ciphers;
|
||||
uint8_t *in_group_flags;
|
||||
};
|
||||
# define TLSEXT_KEYNAME_LENGTH 16
|
||||
# define TLSEXT_TICK_KEY_LENGTH 32
|
||||
|
||||
typedef struct ssl_ctx_ext_secure_st {
|
||||
unsigned char tick_hmac_key[TLSEXT_TICK_KEY_LENGTH];
|
||||
unsigned char tick_aes_key[TLSEXT_TICK_KEY_LENGTH];
|
||||
} SSL_CTX_EXT_SECURE;
|
||||
|
||||
struct ssl_ctx_st {
|
||||
const SSL_METHOD *method;
|
||||
struct ssl_cipher_preference_list_st *cipher_list;
|
||||
STACK_OF(SSL_CIPHER) *cipher_list;
|
||||
/* same as above but sorted for lookup */
|
||||
STACK_OF(SSL_CIPHER) *cipher_list_by_id;
|
||||
/* TLSv1.3 specific ciphersuites */
|
||||
STACK_OF(SSL_CIPHER) *tls13_ciphersuites;
|
||||
struct x509_store_st /* X509_STORE */ *cert_store;
|
||||
LHASH_OF(SSL_SESSION) *sessions;
|
||||
/*
|
||||
@@ -962,8 +933,7 @@ struct ssl_ctx_st {
|
||||
void *servername_arg;
|
||||
/* RFC 4507 session ticket keys */
|
||||
unsigned char tick_key_name[TLSEXT_KEYNAME_LENGTH];
|
||||
unsigned char tick_hmac_key[32];
|
||||
unsigned char tick_aes_key[32];
|
||||
SSL_CTX_EXT_SECURE *secure;
|
||||
/* Callback to support customisation of ticket key setting */
|
||||
int (*ticket_key_cb) (SSL *ssl,
|
||||
unsigned char *name, unsigned char *iv,
|
||||
@@ -1049,8 +1019,10 @@ struct ssl_ctx_st {
|
||||
/* Shared DANE context */
|
||||
struct dane_ctx_st dane;
|
||||
|
||||
# ifndef OPENSSL_NO_SRTP
|
||||
/* SRTP profiles we are willing to do from RFC 5764 */
|
||||
STACK_OF(SRTP_PROTECTION_PROFILE) *srtp_profiles;
|
||||
# endif
|
||||
/*
|
||||
* Callback for disabling session caching and ticket support on a session
|
||||
* basis, depending on the chosen cipher.
|
||||
@@ -1077,6 +1049,9 @@ struct ssl_ctx_st {
|
||||
SSL_CTX_generate_session_ticket_fn generate_ticket_cb;
|
||||
SSL_CTX_decrypt_session_ticket_fn decrypt_ticket_cb;
|
||||
void *ticket_cb_data;
|
||||
|
||||
/* The number of TLS1.3 tickets to automatically send */
|
||||
size_t num_tickets;
|
||||
};
|
||||
|
||||
struct ssl_st {
|
||||
@@ -1085,6 +1060,8 @@ struct ssl_st {
|
||||
* DTLS1_VERSION)
|
||||
*/
|
||||
int version;
|
||||
/* TODO(TLS1.3): Remove this before release */
|
||||
int version_draft;
|
||||
/* SSLv3 */
|
||||
const SSL_METHOD *method;
|
||||
/*
|
||||
@@ -1143,8 +1120,10 @@ struct ssl_st {
|
||||
/* Per connection DANE state */
|
||||
SSL_DANE dane;
|
||||
/* crypto */
|
||||
struct ssl_cipher_preference_list_st *cipher_list;
|
||||
STACK_OF(SSL_CIPHER) *cipher_list;
|
||||
STACK_OF(SSL_CIPHER) *cipher_list_by_id;
|
||||
/* TLSv1.3 specific ciphersuites */
|
||||
STACK_OF(SSL_CIPHER) *tls13_ciphersuites;
|
||||
/*
|
||||
* These are the ones being used, the ones in SSL_SESSION are the ones to
|
||||
* be 'copied' into these ones
|
||||
@@ -1386,10 +1365,12 @@ struct ssl_st {
|
||||
int scts_parsed;
|
||||
# endif
|
||||
SSL_CTX *session_ctx; /* initial ctx, used to store sessions */
|
||||
# ifndef OPENSSL_NO_SRTP
|
||||
/* What we'll do */
|
||||
STACK_OF(SRTP_PROTECTION_PROFILE) *srtp_profiles;
|
||||
/* What's been chosen */
|
||||
SRTP_PROTECTION_PROFILE *srtp_profile;
|
||||
# endif
|
||||
/*-
|
||||
* 1 if we are renegotiating.
|
||||
* 2 if we are a server and are inside a handshake
|
||||
@@ -1441,6 +1422,11 @@ struct ssl_st {
|
||||
|
||||
CRYPTO_RWLOCK *lock;
|
||||
RAND_DRBG *drbg;
|
||||
|
||||
/* The number of TLS1.3 tickets to automatically send */
|
||||
size_t num_tickets;
|
||||
/* The number of TLS1.3 tickets actually sent so far */
|
||||
size_t sent_tickets;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -2235,24 +2221,19 @@ __owur int ssl_cipher_id_cmp(const SSL_CIPHER *a, const SSL_CIPHER *b);
|
||||
DECLARE_OBJ_BSEARCH_GLOBAL_CMP_FN(SSL_CIPHER, SSL_CIPHER, ssl_cipher_id);
|
||||
__owur int ssl_cipher_ptr_id_cmp(const SSL_CIPHER *const *ap,
|
||||
const SSL_CIPHER *const *bp);
|
||||
__owur STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *meth,
|
||||
struct ssl_cipher_preference_list_st **pref,
|
||||
STACK_OF(SSL_CIPHER) **sorted,
|
||||
__owur int set_ciphersuites(STACK_OF(SSL_CIPHER) **currciphers, const char *str);
|
||||
__owur STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method,
|
||||
STACK_OF(SSL_CIPHER) *tls13_ciphersuites,
|
||||
STACK_OF(SSL_CIPHER) **cipher_list,
|
||||
STACK_OF(SSL_CIPHER) **cipher_list_by_id,
|
||||
const char *rule_str,
|
||||
CERT *c);
|
||||
CERT *c);
|
||||
__owur int ssl_cache_cipherlist(SSL *s, PACKET *cipher_suites, int sslv2format);
|
||||
__owur int bytes_to_cipher_list(SSL *s, PACKET *cipher_suites,
|
||||
STACK_OF(SSL_CIPHER) **skp,
|
||||
STACK_OF(SSL_CIPHER) **scsvs, int sslv2format,
|
||||
int fatal);
|
||||
void ssl_update_cache(SSL *s, int mode);
|
||||
struct ssl_cipher_preference_list_st* ssl_cipher_preference_list_dup(
|
||||
struct ssl_cipher_preference_list_st *cipher_list);
|
||||
void ssl_cipher_preference_list_free(
|
||||
struct ssl_cipher_preference_list_st *cipher_list);
|
||||
struct ssl_cipher_preference_list_st* ssl_cipher_preference_list_from_ciphers(
|
||||
STACK_OF(SSL_CIPHER) *ciphers);
|
||||
struct ssl_cipher_preference_list_st* ssl_get_cipher_preferences(SSL *s);
|
||||
__owur int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc,
|
||||
const EVP_MD **md, int *mac_pkey_type,
|
||||
size_t *mac_secret_size, SSL_COMP **comp,
|
||||
@@ -2277,7 +2258,6 @@ __owur int ssl_build_cert_chain(SSL *s, SSL_CTX *ctx, int flags);
|
||||
__owur int ssl_cert_set_cert_store(CERT *c, X509_STORE *store, int chain,
|
||||
int ref);
|
||||
|
||||
__owur int ssl_randbytes(SSL *s, unsigned char *buf, size_t num);
|
||||
__owur int ssl_security(const SSL *s, int op, int bits, int nid, void *other);
|
||||
__owur int ssl_ctx_security(const SSL_CTX *ctx, int op, int bits, int nid,
|
||||
void *other);
|
||||
@@ -2294,7 +2274,7 @@ __owur int ssl_get_server_cert_serverinfo(SSL *s,
|
||||
size_t *serverinfo_length);
|
||||
void ssl_set_masks(SSL *s);
|
||||
__owur STACK_OF(SSL_CIPHER) *ssl_get_ciphers_by_id(SSL *s);
|
||||
__owur int ssl_verify_alarm_type(long type);
|
||||
__owur int ssl_x509err2alert(int type);
|
||||
void ssl_sort_cipher_list(void);
|
||||
int ssl_load_ciphers(void);
|
||||
__owur int ssl_fill_hello_random(SSL *s, int server, unsigned char *field,
|
||||
@@ -2335,8 +2315,8 @@ void ssl3_free_digest_list(SSL *s);
|
||||
__owur unsigned long ssl3_output_cert_chain(SSL *s, WPACKET *pkt,
|
||||
CERT_PKEY *cpk);
|
||||
__owur const SSL_CIPHER *ssl3_choose_cipher(SSL *ssl,
|
||||
STACK_OF(SSL_CIPHER) *clnt,
|
||||
struct ssl_cipher_preference_list_st *srvr);
|
||||
STACK_OF(SSL_CIPHER) *clnt,
|
||||
STACK_OF(SSL_CIPHER) *srvr);
|
||||
__owur int ssl3_digest_cached_records(SSL *s, int keep);
|
||||
__owur int ssl3_new(SSL *s);
|
||||
void ssl3_free(SSL *s);
|
||||
@@ -2485,7 +2465,7 @@ SSL_COMP *ssl3_comp_find(STACK_OF(SSL_COMP) *sk, int n);
|
||||
# ifndef OPENSSL_NO_EC
|
||||
|
||||
__owur const TLS_GROUP_INFO *tls1_group_id_lookup(uint16_t curve_id);
|
||||
__owur int tls1_check_group_id(SSL *s, uint16_t group_id);
|
||||
__owur int tls1_check_group_id(SSL *s, uint16_t group_id, int check_own_curves);
|
||||
__owur uint16_t tls1_shared_group(SSL *s, int nmatch);
|
||||
__owur int tls1_set_groups(uint16_t **pext, size_t *pextlen,
|
||||
int *curves, size_t ncurves);
|
||||
@@ -2504,9 +2484,9 @@ void tls1_get_supported_groups(SSL *s, const uint16_t **pgroups,
|
||||
|
||||
__owur int tls1_set_server_sigalgs(SSL *s);
|
||||
|
||||
__owur SSL_TICKET_RETURN tls_get_ticket_from_client(SSL *s, CLIENTHELLO_MSG *hello,
|
||||
__owur SSL_TICKET_STATUS tls_get_ticket_from_client(SSL *s, CLIENTHELLO_MSG *hello,
|
||||
SSL_SESSION **ret);
|
||||
__owur SSL_TICKET_RETURN tls_decrypt_ticket(SSL *s, const unsigned char *etick,
|
||||
__owur SSL_TICKET_STATUS tls_decrypt_ticket(SSL *s, const unsigned char *etick,
|
||||
size_t eticklen,
|
||||
const unsigned char *sess_id,
|
||||
size_t sesslen, SSL_SESSION **psess);
|
||||
@@ -2585,6 +2565,8 @@ __owur int ssl_log_secret(SSL *ssl, const char *label,
|
||||
#define SERVER_HANDSHAKE_LABEL "SERVER_HANDSHAKE_TRAFFIC_SECRET"
|
||||
#define CLIENT_APPLICATION_LABEL "CLIENT_TRAFFIC_SECRET_0"
|
||||
#define SERVER_APPLICATION_LABEL "SERVER_TRAFFIC_SECRET_0"
|
||||
#define EARLY_EXPORTER_SECRET_LABEL "EARLY_EXPORTER_SECRET"
|
||||
#define EXPORTER_SECRET_LABEL "EXPORTER_SECRET"
|
||||
|
||||
/* s3_cbc.c */
|
||||
__owur char ssl3_cbc_record_digest_supported(const EVP_MD_CTX *ctx);
|
||||
@@ -2628,6 +2610,9 @@ void custom_exts_free(custom_ext_methods *exts);
|
||||
|
||||
void ssl_comp_free_compression_methods_int(void);
|
||||
|
||||
/* ssl_mcnf.c */
|
||||
void ssl_ctx_system_config(SSL_CTX *ctx);
|
||||
|
||||
# else /* OPENSSL_UNIT_TEST */
|
||||
|
||||
# define ssl_init_wbio_buffer SSL_test_functions()->p_ssl_init_wbio_buffer
|
||||
|
||||
+32
-132
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -11,153 +11,45 @@
|
||||
#include <openssl/conf.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include "ssl_locl.h"
|
||||
#include "internal/sslconf.h"
|
||||
|
||||
/* SSL library configuration module. */
|
||||
|
||||
struct ssl_conf_name {
|
||||
/* Name of this set of commands */
|
||||
char *name;
|
||||
/* List of commands */
|
||||
struct ssl_conf_cmd *cmds;
|
||||
/* Number of commands */
|
||||
size_t cmd_count;
|
||||
};
|
||||
|
||||
struct ssl_conf_cmd {
|
||||
/* Command */
|
||||
char *cmd;
|
||||
/* Argument */
|
||||
char *arg;
|
||||
};
|
||||
|
||||
static struct ssl_conf_name *ssl_names;
|
||||
static size_t ssl_names_count;
|
||||
|
||||
static void ssl_module_free(CONF_IMODULE *md)
|
||||
{
|
||||
size_t i, j;
|
||||
if (ssl_names == NULL)
|
||||
return;
|
||||
for (i = 0; i < ssl_names_count; i++) {
|
||||
struct ssl_conf_name *tname = ssl_names + i;
|
||||
OPENSSL_free(tname->name);
|
||||
for (j = 0; j < tname->cmd_count; j++) {
|
||||
OPENSSL_free(tname->cmds[j].cmd);
|
||||
OPENSSL_free(tname->cmds[j].arg);
|
||||
}
|
||||
OPENSSL_free(tname->cmds);
|
||||
}
|
||||
OPENSSL_free(ssl_names);
|
||||
ssl_names = NULL;
|
||||
ssl_names_count = 0;
|
||||
}
|
||||
|
||||
static int ssl_module_init(CONF_IMODULE *md, const CONF *cnf)
|
||||
{
|
||||
size_t i, j, cnt;
|
||||
int rv = 0;
|
||||
const char *ssl_conf_section;
|
||||
STACK_OF(CONF_VALUE) *cmd_lists;
|
||||
ssl_conf_section = CONF_imodule_get_value(md);
|
||||
cmd_lists = NCONF_get_section(cnf, ssl_conf_section);
|
||||
if (sk_CONF_VALUE_num(cmd_lists) <= 0) {
|
||||
if (cmd_lists == NULL)
|
||||
SSLerr(SSL_F_SSL_MODULE_INIT, SSL_R_SSL_SECTION_NOT_FOUND);
|
||||
else
|
||||
SSLerr(SSL_F_SSL_MODULE_INIT, SSL_R_SSL_SECTION_EMPTY);
|
||||
ERR_add_error_data(2, "section=", ssl_conf_section);
|
||||
goto err;
|
||||
}
|
||||
cnt = sk_CONF_VALUE_num(cmd_lists);
|
||||
ssl_names = OPENSSL_zalloc(sizeof(*ssl_names) * cnt);
|
||||
ssl_names_count = cnt;
|
||||
for (i = 0; i < ssl_names_count; i++) {
|
||||
struct ssl_conf_name *ssl_name = ssl_names + i;
|
||||
CONF_VALUE *sect = sk_CONF_VALUE_value(cmd_lists, (int)i);
|
||||
STACK_OF(CONF_VALUE) *cmds = NCONF_get_section(cnf, sect->value);
|
||||
if (sk_CONF_VALUE_num(cmds) <= 0) {
|
||||
if (cmds == NULL)
|
||||
SSLerr(SSL_F_SSL_MODULE_INIT,
|
||||
SSL_R_SSL_COMMAND_SECTION_NOT_FOUND);
|
||||
else
|
||||
SSLerr(SSL_F_SSL_MODULE_INIT, SSL_R_SSL_COMMAND_SECTION_EMPTY);
|
||||
ERR_add_error_data(4, "name=", sect->name, ", value=", sect->value);
|
||||
goto err;
|
||||
}
|
||||
ssl_name->name = BUF_strdup(sect->name);
|
||||
if (ssl_name->name == NULL)
|
||||
goto err;
|
||||
cnt = sk_CONF_VALUE_num(cmds);
|
||||
ssl_name->cmds = OPENSSL_zalloc(cnt * sizeof(struct ssl_conf_cmd));
|
||||
if (ssl_name->cmds == NULL)
|
||||
goto err;
|
||||
ssl_name->cmd_count = cnt;
|
||||
for (j = 0; j < cnt; j++) {
|
||||
const char *name;
|
||||
CONF_VALUE *cmd_conf = sk_CONF_VALUE_value(cmds, (int)j);
|
||||
struct ssl_conf_cmd *cmd = ssl_name->cmds + j;
|
||||
/* Skip any initial dot in name */
|
||||
name = strchr(cmd_conf->name, '.');
|
||||
if (name != NULL)
|
||||
name++;
|
||||
else
|
||||
name = cmd_conf->name;
|
||||
cmd->cmd = BUF_strdup(name);
|
||||
cmd->arg = BUF_strdup(cmd_conf->value);
|
||||
if (cmd->cmd == NULL || cmd->arg == NULL)
|
||||
goto err;
|
||||
}
|
||||
|
||||
}
|
||||
rv = 1;
|
||||
err:
|
||||
if (rv == 0)
|
||||
ssl_module_free(md);
|
||||
return rv;
|
||||
}
|
||||
|
||||
void SSL_add_ssl_module(void)
|
||||
{
|
||||
CONF_module_add("ssl_conf", ssl_module_init, ssl_module_free);
|
||||
/* Do nothing. This will be added automatically by libcrypto */
|
||||
}
|
||||
|
||||
static const struct ssl_conf_name *ssl_name_find(const char *name)
|
||||
{
|
||||
size_t i;
|
||||
const struct ssl_conf_name *nm;
|
||||
if (name == NULL)
|
||||
return NULL;
|
||||
for (i = 0, nm = ssl_names; i < ssl_names_count; i++, nm++) {
|
||||
if (strcmp(nm->name, name) == 0)
|
||||
return nm;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int ssl_do_config(SSL *s, SSL_CTX *ctx, const char *name)
|
||||
static int ssl_do_config(SSL *s, SSL_CTX *ctx, const char *name, int system)
|
||||
{
|
||||
SSL_CONF_CTX *cctx = NULL;
|
||||
size_t i;
|
||||
size_t i, idx, cmd_count;
|
||||
int rv = 0;
|
||||
unsigned int flags;
|
||||
const SSL_METHOD *meth;
|
||||
const struct ssl_conf_name *nm;
|
||||
struct ssl_conf_cmd *cmd;
|
||||
const SSL_CONF_CMD *cmds;
|
||||
|
||||
if (s == NULL && ctx == NULL) {
|
||||
SSLerr(SSL_F_SSL_DO_CONFIG, ERR_R_PASSED_NULL_PARAMETER);
|
||||
goto err;
|
||||
}
|
||||
nm = ssl_name_find(name);
|
||||
if (nm == NULL) {
|
||||
SSLerr(SSL_F_SSL_DO_CONFIG, SSL_R_INVALID_CONFIGURATION_NAME);
|
||||
ERR_add_error_data(2, "name=", name);
|
||||
|
||||
if (name == NULL && system)
|
||||
name = "system_default";
|
||||
if (!conf_ssl_name_find(name, &idx)) {
|
||||
if (!system) {
|
||||
SSLerr(SSL_F_SSL_DO_CONFIG, SSL_R_INVALID_CONFIGURATION_NAME);
|
||||
ERR_add_error_data(2, "name=", name);
|
||||
}
|
||||
goto err;
|
||||
}
|
||||
cmds = conf_ssl_get(idx, &name, &cmd_count);
|
||||
cctx = SSL_CONF_CTX_new();
|
||||
if (cctx == NULL)
|
||||
goto err;
|
||||
flags = SSL_CONF_FLAG_FILE;
|
||||
flags |= SSL_CONF_FLAG_CERTIFICATE | SSL_CONF_FLAG_REQUIRE_PRIVATE;
|
||||
if (!system)
|
||||
flags |= SSL_CONF_FLAG_CERTIFICATE | SSL_CONF_FLAG_REQUIRE_PRIVATE;
|
||||
if (s != NULL) {
|
||||
meth = s->method;
|
||||
SSL_CONF_CTX_set_ssl(cctx, s);
|
||||
@@ -170,15 +62,18 @@ static int ssl_do_config(SSL *s, SSL_CTX *ctx, const char *name)
|
||||
if (meth->ssl_connect != ssl_undefined_function)
|
||||
flags |= SSL_CONF_FLAG_CLIENT;
|
||||
SSL_CONF_CTX_set_flags(cctx, flags);
|
||||
for (i = 0, cmd = nm->cmds; i < nm->cmd_count; i++, cmd++) {
|
||||
rv = SSL_CONF_cmd(cctx, cmd->cmd, cmd->arg);
|
||||
for (i = 0; i < cmd_count; i++) {
|
||||
char *cmdstr, *arg;
|
||||
|
||||
conf_ssl_get_cmd(cmds, i, &cmdstr, &arg);
|
||||
rv = SSL_CONF_cmd(cctx, cmdstr, arg);
|
||||
if (rv <= 0) {
|
||||
if (rv == -2)
|
||||
SSLerr(SSL_F_SSL_DO_CONFIG, SSL_R_UNKNOWN_COMMAND);
|
||||
else
|
||||
SSLerr(SSL_F_SSL_DO_CONFIG, SSL_R_BAD_VALUE);
|
||||
ERR_add_error_data(6, "section=", name, ", cmd=", cmd->cmd,
|
||||
", arg=", cmd->arg);
|
||||
ERR_add_error_data(6, "section=", name, ", cmd=", cmdstr,
|
||||
", arg=", arg);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
@@ -190,10 +85,15 @@ static int ssl_do_config(SSL *s, SSL_CTX *ctx, const char *name)
|
||||
|
||||
int SSL_config(SSL *s, const char *name)
|
||||
{
|
||||
return ssl_do_config(s, NULL, name);
|
||||
return ssl_do_config(s, NULL, name, 0);
|
||||
}
|
||||
|
||||
int SSL_CTX_config(SSL_CTX *ctx, const char *name)
|
||||
{
|
||||
return ssl_do_config(NULL, ctx, name);
|
||||
return ssl_do_config(NULL, ctx, name, 0);
|
||||
}
|
||||
|
||||
void ssl_ctx_system_config(SSL_CTX *ctx)
|
||||
{
|
||||
ssl_do_config(NULL, ctx, NULL, 1);
|
||||
}
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
|
||||
+18
-8
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2005 Nokia. All rights reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
@@ -295,7 +295,7 @@ static int def_generate_session_id(SSL *ssl, unsigned char *id,
|
||||
{
|
||||
unsigned int retry = 0;
|
||||
do
|
||||
if (ssl_randbytes(ssl, id, *id_len) <= 0)
|
||||
if (RAND_bytes(id, *id_len) <= 0)
|
||||
return 0;
|
||||
while (SSL_has_matching_session_id(ssl, id, *id_len) &&
|
||||
(++retry < MAX_SESS_ID_ATTEMPTS)) ;
|
||||
@@ -417,7 +417,13 @@ int ssl_get_new_session(SSL *s, int session)
|
||||
s->session = NULL;
|
||||
|
||||
if (session) {
|
||||
if (!ssl_generate_session_id(s, ss)) {
|
||||
if (SSL_IS_TLS13(s)) {
|
||||
/*
|
||||
* We generate the session id while constructing the
|
||||
* NewSessionTicket in TLSv1.3.
|
||||
*/
|
||||
ss->session_id_length = 0;
|
||||
} else if (!ssl_generate_session_id(s, ss)) {
|
||||
/* SSLfatal() already called */
|
||||
SSL_SESSION_free(ss);
|
||||
return 0;
|
||||
@@ -479,9 +485,14 @@ int ssl_get_prev_session(SSL *s, CLIENTHELLO_MSG *hello)
|
||||
SSL_SESSION *ret = NULL;
|
||||
int fatal = 0, discard;
|
||||
int try_session_cache = 0;
|
||||
SSL_TICKET_RETURN r;
|
||||
SSL_TICKET_STATUS r;
|
||||
|
||||
if (SSL_IS_TLS13(s)) {
|
||||
/*
|
||||
* By default we will send a new ticket. This can be overridden in the
|
||||
* ticket processing.
|
||||
*/
|
||||
s->ext.ticket_expected = 1;
|
||||
if (!tls_parse_extension(s, TLSEXT_IDX_psk_kex_modes,
|
||||
SSL_EXT_CLIENT_HELLO, hello->pre_proc_exts,
|
||||
NULL, 0)
|
||||
@@ -755,10 +766,10 @@ static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck)
|
||||
if ((c != NULL) && (c->session_id_length != 0)) {
|
||||
if (lck)
|
||||
CRYPTO_THREAD_write_lock(ctx->lock);
|
||||
if ((r = lh_SSL_SESSION_retrieve(ctx->sessions, c)) == c) {
|
||||
if ((r = lh_SSL_SESSION_retrieve(ctx->sessions, c)) != NULL) {
|
||||
ret = 1;
|
||||
r = lh_SSL_SESSION_delete(ctx->sessions, c);
|
||||
SSL_SESSION_list_remove(ctx, c);
|
||||
r = lh_SSL_SESSION_delete(ctx->sessions, r);
|
||||
SSL_SESSION_list_remove(ctx, r);
|
||||
}
|
||||
c->not_resumable = 1;
|
||||
|
||||
@@ -781,7 +792,6 @@ void SSL_SESSION_free(SSL_SESSION *ss)
|
||||
|
||||
if (ss == NULL)
|
||||
return;
|
||||
|
||||
CRYPTO_DOWN_REF(&ss->references, &i, ss->lock);
|
||||
REF_PRINT_COUNT("SSL_SESSION", ss);
|
||||
if (i > 0)
|
||||
|
||||
+7
-7
@@ -44,18 +44,18 @@ int SSL_SESSION_print(BIO *bp, const SSL_SESSION *x)
|
||||
|
||||
if (x->cipher == NULL) {
|
||||
if (((x->cipher_id) & 0xff000000) == 0x02000000) {
|
||||
if (BIO_printf
|
||||
(bp, " Cipher : %06lX\n", x->cipher_id & 0xffffff) <= 0)
|
||||
if (BIO_printf(bp, " Cipher : %06lX\n",
|
||||
x->cipher_id & 0xffffff) <= 0)
|
||||
goto err;
|
||||
} else {
|
||||
if (BIO_printf
|
||||
(bp, " Cipher : %04lX\n", x->cipher_id & 0xffff) <= 0)
|
||||
if (BIO_printf(bp, " Cipher : %04lX\n",
|
||||
x->cipher_id & 0xffff) <= 0)
|
||||
goto err;
|
||||
}
|
||||
} else {
|
||||
if (BIO_printf
|
||||
(bp, " Cipher : %s\n",
|
||||
((x->cipher == NULL) ? "unknown" : x->cipher->name)) <= 0)
|
||||
if (BIO_printf(bp, " Cipher : %s\n",
|
||||
((x->cipher->name == NULL) ? "unknown"
|
||||
: x->cipher->name)) <= 0)
|
||||
goto err;
|
||||
}
|
||||
if (BIO_puts(bp, " Session-ID: ") <= 0)
|
||||
|
||||
@@ -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);
|
||||
|
||||
+5
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2005 Nokia. All rights reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
@@ -154,6 +154,7 @@ int tls1_change_cipher_state(SSL *s, int which)
|
||||
mac_secret = &(s->s3->read_mac_secret[0]);
|
||||
mac_secret_size = &(s->s3->read_mac_secret_size);
|
||||
} else {
|
||||
s->statem.invalid_enc_write_ctx = 1;
|
||||
if (s->ext.use_etm)
|
||||
s->s3->flags |= TLS1_FLAGS_ENCRYPT_THEN_MAC_WRITE;
|
||||
else
|
||||
@@ -170,7 +171,6 @@ int tls1_change_cipher_state(SSL *s, int which)
|
||||
ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
EVP_CIPHER_CTX_ctrl(s->enc_write_ctx, EVP_CTRL_SET_DRBG, 0, s->drbg);
|
||||
dd = s->enc_write_ctx;
|
||||
if (SSL_IS_DTLS(s)) {
|
||||
mac_ctx = EVP_MD_CTX_new();
|
||||
@@ -257,8 +257,8 @@ int tls1_change_cipher_state(SSL *s, int which)
|
||||
|
||||
if (!(EVP_CIPHER_flags(c) & EVP_CIPH_FLAG_AEAD_CIPHER)) {
|
||||
/* TODO(size_t): Convert this function */
|
||||
mac_key = EVP_PKEY_new_mac_key(mac_type, NULL,
|
||||
mac_secret, (int)*mac_secret_size);
|
||||
mac_key = EVP_PKEY_new_mac_key(mac_type, NULL, mac_secret,
|
||||
(int)*mac_secret_size);
|
||||
if (mac_key == NULL
|
||||
|| EVP_DigestSignInit(mac_ctx, NULL, m, NULL, mac_key) <= 0) {
|
||||
EVP_PKEY_free(mac_key);
|
||||
@@ -316,6 +316,7 @@ int tls1_change_cipher_state(SSL *s, int which)
|
||||
ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
s->statem.invalid_enc_write_ctx = 0;
|
||||
|
||||
#ifdef SSL_DEBUG
|
||||
printf("which = %04X\nkey=", which);
|
||||
|
||||
+184
-143
@@ -342,9 +342,11 @@ int tls1_set_groups(uint16_t **pext, size_t *pextlen,
|
||||
* ids < 32
|
||||
*/
|
||||
unsigned long dup_list = 0;
|
||||
glist = OPENSSL_malloc(ngroups * sizeof(*glist));
|
||||
if (glist == NULL)
|
||||
|
||||
if ((glist = OPENSSL_malloc(ngroups * sizeof(*glist))) == NULL) {
|
||||
SSLerr(SSL_F_TLS1_SET_GROUPS, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
for (i = 0; i < ngroups; i++) {
|
||||
unsigned long idmask;
|
||||
uint16_t id;
|
||||
@@ -364,7 +366,7 @@ int tls1_set_groups(uint16_t **pext, size_t *pextlen,
|
||||
return 1;
|
||||
}
|
||||
|
||||
# define MAX_CURVELIST 28
|
||||
# define MAX_CURVELIST OSSL_NELEM(nid_list)
|
||||
|
||||
typedef struct {
|
||||
size_t nidcnt;
|
||||
@@ -440,8 +442,11 @@ static int tls1_check_pkey_comp(SSL *s, EVP_PKEY *pkey)
|
||||
if (EC_KEY_get_conv_form(ec) == POINT_CONVERSION_UNCOMPRESSED) {
|
||||
comp_id = TLSEXT_ECPOINTFORMAT_uncompressed;
|
||||
} else if (SSL_IS_TLS13(s)) {
|
||||
/* Compression not allowed in TLS 1.3 */
|
||||
return 0;
|
||||
/*
|
||||
* ec_point_formats extension is not used in TLSv1.3 so we ignore
|
||||
* this check.
|
||||
*/
|
||||
return 1;
|
||||
} else {
|
||||
int field_type = EC_METHOD_get_field_type(EC_GROUP_method_of(grp));
|
||||
|
||||
@@ -467,7 +472,7 @@ static int tls1_check_pkey_comp(SSL *s, EVP_PKEY *pkey)
|
||||
}
|
||||
|
||||
/* Check a group id matches preferences */
|
||||
int tls1_check_group_id(SSL *s, uint16_t group_id)
|
||||
int tls1_check_group_id(SSL *s, uint16_t group_id, int check_own_groups)
|
||||
{
|
||||
const uint16_t *groups;
|
||||
size_t groups_len;
|
||||
@@ -491,10 +496,12 @@ int tls1_check_group_id(SSL *s, uint16_t group_id)
|
||||
}
|
||||
}
|
||||
|
||||
/* Check group is one of our preferences */
|
||||
tls1_get_supported_groups(s, &groups, &groups_len);
|
||||
if (!tls1_in_list(group_id, groups, groups_len))
|
||||
return 0;
|
||||
if (check_own_groups) {
|
||||
/* Check group is one of our preferences */
|
||||
tls1_get_supported_groups(s, &groups, &groups_len);
|
||||
if (!tls1_in_list(group_id, groups, groups_len))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!tls_curve_allowed(s, group_id, SSL_SECOP_CURVE_CHECK))
|
||||
return 0;
|
||||
@@ -554,7 +561,11 @@ static int tls1_check_cert_param(SSL *s, X509 *x, int check_ee_md)
|
||||
if (!tls1_check_pkey_comp(s, pkey))
|
||||
return 0;
|
||||
group_id = tls1_get_group_id(pkey);
|
||||
if (!tls1_check_group_id(s, group_id))
|
||||
/*
|
||||
* For a server we allow the certificate to not be in our list of supported
|
||||
* groups.
|
||||
*/
|
||||
if (!tls1_check_group_id(s, group_id, !s->server))
|
||||
return 0;
|
||||
/*
|
||||
* Special case for suite B. We *MUST* sign using SHA256+P-256 or
|
||||
@@ -601,9 +612,9 @@ int tls1_check_ec_tmp_key(SSL *s, unsigned long cid)
|
||||
* curves permitted.
|
||||
*/
|
||||
if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256)
|
||||
return tls1_check_group_id(s, TLSEXT_curve_P_256);
|
||||
return tls1_check_group_id(s, TLSEXT_curve_P_256, 1);
|
||||
if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384)
|
||||
return tls1_check_group_id(s, TLSEXT_curve_P_384);
|
||||
return tls1_check_group_id(s, TLSEXT_curve_P_384, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -979,7 +990,7 @@ int tls12_check_peer_sigalg(SSL *s, uint16_t sig, EVP_PKEY *pkey)
|
||||
}
|
||||
if (!SSL_IS_TLS13(s)) {
|
||||
/* Check curve matches extensions */
|
||||
if (!tls1_check_group_id(s, tls1_get_group_id(pkey))) {
|
||||
if (!tls1_check_group_id(s, tls1_get_group_id(pkey), 1)) {
|
||||
SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER,
|
||||
SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_WRONG_CURVE);
|
||||
return 0;
|
||||
@@ -1183,32 +1194,10 @@ int tls1_set_server_sigalgs(SSL *s)
|
||||
* hello: The parsed ClientHello data
|
||||
* ret: (output) on return, if a ticket was decrypted, then this is set to
|
||||
* point to the resulting session.
|
||||
*
|
||||
* If s->tls_session_secret_cb is set then we are expecting a pre-shared key
|
||||
* ciphersuite, in which case we have no use for session tickets and one will
|
||||
* never be decrypted, nor will s->ext.ticket_expected be set to 1.
|
||||
*
|
||||
* Returns:
|
||||
* -1: fatal error, either from parsing or decrypting the ticket.
|
||||
* 0: no ticket was found (or was ignored, based on settings).
|
||||
* 1: a zero length extension was found, indicating that the client supports
|
||||
* session tickets but doesn't currently have one to offer.
|
||||
* 2: either s->tls_session_secret_cb was set, or a ticket was offered but
|
||||
* couldn't be decrypted because of a non-fatal error.
|
||||
* 3: a ticket was successfully decrypted and *ret was set.
|
||||
*
|
||||
* Side effects:
|
||||
* Sets s->ext.ticket_expected to 1 if the server will have to issue
|
||||
* a new session ticket to the client because the client indicated support
|
||||
* (and s->tls_session_secret_cb is NULL) but the client either doesn't have
|
||||
* a session ticket or we couldn't use the one it gave us, or if
|
||||
* s->ctx->ext.ticket_key_cb asked to renew the client's ticket.
|
||||
* Otherwise, s->ext.ticket_expected is set to 0.
|
||||
*/
|
||||
SSL_TICKET_RETURN tls_get_ticket_from_client(SSL *s, CLIENTHELLO_MSG *hello,
|
||||
SSL_TICKET_STATUS tls_get_ticket_from_client(SSL *s, CLIENTHELLO_MSG *hello,
|
||||
SSL_SESSION **ret)
|
||||
{
|
||||
int retv;
|
||||
size_t size;
|
||||
RAW_EXTENSION *ticketext;
|
||||
|
||||
@@ -1228,70 +1217,27 @@ SSL_TICKET_RETURN tls_get_ticket_from_client(SSL *s, CLIENTHELLO_MSG *hello,
|
||||
return SSL_TICKET_NONE;
|
||||
|
||||
size = PACKET_remaining(&ticketext->data);
|
||||
if (size == 0) {
|
||||
/*
|
||||
* The client will accept a ticket but doesn't currently have
|
||||
* one.
|
||||
*/
|
||||
s->ext.ticket_expected = 1;
|
||||
return SSL_TICKET_EMPTY;
|
||||
}
|
||||
if (s->ext.session_secret_cb) {
|
||||
/*
|
||||
* Indicate that the ticket couldn't be decrypted rather than
|
||||
* generating the session from ticket now, trigger
|
||||
* abbreviated handshake based on external mechanism to
|
||||
* calculate the master secret later.
|
||||
*/
|
||||
return SSL_TICKET_NO_DECRYPT;
|
||||
}
|
||||
|
||||
retv = tls_decrypt_ticket(s, PACKET_data(&ticketext->data), size,
|
||||
return tls_decrypt_ticket(s, PACKET_data(&ticketext->data), size,
|
||||
hello->session_id, hello->session_id_len, ret);
|
||||
|
||||
/*
|
||||
* If set, the decrypt_ticket_cb() is always called regardless of the
|
||||
* return from tls_decrypt_ticket(). The callback is responsible for
|
||||
* checking |retv| before it performs any action
|
||||
*/
|
||||
if (s->session_ctx->decrypt_ticket_cb != NULL) {
|
||||
size_t keyname_len = size;
|
||||
|
||||
if (keyname_len > TLSEXT_KEYNAME_LENGTH)
|
||||
keyname_len = TLSEXT_KEYNAME_LENGTH;
|
||||
retv = s->session_ctx->decrypt_ticket_cb(s, *ret,
|
||||
PACKET_data(&ticketext->data),
|
||||
keyname_len,
|
||||
retv, s->session_ctx->ticket_cb_data);
|
||||
}
|
||||
|
||||
switch (retv) {
|
||||
case SSL_TICKET_NO_DECRYPT:
|
||||
s->ext.ticket_expected = 1;
|
||||
return SSL_TICKET_NO_DECRYPT;
|
||||
|
||||
case SSL_TICKET_SUCCESS:
|
||||
return SSL_TICKET_SUCCESS;
|
||||
|
||||
case SSL_TICKET_SUCCESS_RENEW:
|
||||
s->ext.ticket_expected = 1;
|
||||
return SSL_TICKET_SUCCESS;
|
||||
|
||||
case SSL_TICKET_EMPTY:
|
||||
s->ext.ticket_expected = 1;
|
||||
return SSL_TICKET_EMPTY;
|
||||
|
||||
case SSL_TICKET_NONE:
|
||||
return SSL_TICKET_NONE;
|
||||
|
||||
default:
|
||||
return SSL_TICKET_FATAL_ERR_OTHER;
|
||||
}
|
||||
}
|
||||
|
||||
/*-
|
||||
* tls_decrypt_ticket attempts to decrypt a session ticket.
|
||||
*
|
||||
* If s->tls_session_secret_cb is set and we're not doing TLSv1.3 then we are
|
||||
* expecting a pre-shared key ciphersuite, in which case we have no use for
|
||||
* session tickets and one will never be decrypted, nor will
|
||||
* s->ext.ticket_expected be set to 1.
|
||||
*
|
||||
* Side effects:
|
||||
* Sets s->ext.ticket_expected to 1 if the server will have to issue
|
||||
* a new session ticket to the client because the client indicated support
|
||||
* (and s->tls_session_secret_cb is NULL) but the client either doesn't have
|
||||
* a session ticket or we couldn't use the one it gave us, or if
|
||||
* s->ctx->ext.ticket_key_cb asked to renew the client's ticket.
|
||||
* Otherwise, s->ext.ticket_expected is set to 0.
|
||||
*
|
||||
* etick: points to the body of the session ticket extension.
|
||||
* eticklen: the length of the session tickets extension.
|
||||
* sess_id: points at the session ID.
|
||||
@@ -1299,46 +1245,69 @@ SSL_TICKET_RETURN tls_get_ticket_from_client(SSL *s, CLIENTHELLO_MSG *hello,
|
||||
* psess: (output) on return, if a ticket was decrypted, then this is set to
|
||||
* point to the resulting session.
|
||||
*/
|
||||
SSL_TICKET_RETURN tls_decrypt_ticket(SSL *s, const unsigned char *etick,
|
||||
SSL_TICKET_STATUS tls_decrypt_ticket(SSL *s, const unsigned char *etick,
|
||||
size_t eticklen, const unsigned char *sess_id,
|
||||
size_t sesslen, SSL_SESSION **psess)
|
||||
{
|
||||
SSL_SESSION *sess;
|
||||
SSL_SESSION *sess = NULL;
|
||||
unsigned char *sdec;
|
||||
const unsigned char *p;
|
||||
int slen, renew_ticket = 0, declen;
|
||||
SSL_TICKET_RETURN ret = SSL_TICKET_FATAL_ERR_OTHER;
|
||||
SSL_TICKET_STATUS ret = SSL_TICKET_FATAL_ERR_OTHER;
|
||||
size_t mlen;
|
||||
unsigned char tick_hmac[EVP_MAX_MD_SIZE];
|
||||
HMAC_CTX *hctx = NULL;
|
||||
EVP_CIPHER_CTX *ctx = NULL;
|
||||
SSL_CTX *tctx = s->session_ctx;
|
||||
|
||||
if (eticklen == 0) {
|
||||
/*
|
||||
* The client will accept a ticket but doesn't currently have
|
||||
* one (TLSv1.2 and below), or treated as a fatal error in TLSv1.3
|
||||
*/
|
||||
ret = SSL_TICKET_EMPTY;
|
||||
goto end;
|
||||
}
|
||||
if (!SSL_IS_TLS13(s) && s->ext.session_secret_cb) {
|
||||
/*
|
||||
* Indicate that the ticket couldn't be decrypted rather than
|
||||
* generating the session from ticket now, trigger
|
||||
* abbreviated handshake based on external mechanism to
|
||||
* calculate the master secret later.
|
||||
*/
|
||||
ret = SSL_TICKET_NO_DECRYPT;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* Need at least keyname + iv */
|
||||
if (eticklen < TLSEXT_KEYNAME_LENGTH + EVP_MAX_IV_LENGTH) {
|
||||
ret = SSL_TICKET_NO_DECRYPT;
|
||||
goto err;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* Initialize session ticket encryption and HMAC contexts */
|
||||
hctx = HMAC_CTX_new();
|
||||
if (hctx == NULL)
|
||||
return SSL_TICKET_FATAL_ERR_MALLOC;
|
||||
if (hctx == NULL) {
|
||||
ret = SSL_TICKET_FATAL_ERR_MALLOC;
|
||||
goto end;
|
||||
}
|
||||
ctx = EVP_CIPHER_CTX_new();
|
||||
if (ctx == NULL) {
|
||||
ret = SSL_TICKET_FATAL_ERR_MALLOC;
|
||||
goto err;
|
||||
goto end;
|
||||
}
|
||||
if (tctx->ext.ticket_key_cb) {
|
||||
unsigned char *nctick = (unsigned char *)etick;
|
||||
int rv = tctx->ext.ticket_key_cb(s, nctick,
|
||||
nctick + TLSEXT_KEYNAME_LENGTH,
|
||||
ctx, hctx, 0);
|
||||
if (rv < 0)
|
||||
goto err;
|
||||
if (rv < 0) {
|
||||
ret = SSL_TICKET_FATAL_ERR_OTHER;
|
||||
goto end;
|
||||
}
|
||||
if (rv == 0) {
|
||||
ret = SSL_TICKET_NO_DECRYPT;
|
||||
goto err;
|
||||
goto end;
|
||||
}
|
||||
if (rv == 2)
|
||||
renew_ticket = 1;
|
||||
@@ -1347,16 +1316,19 @@ SSL_TICKET_RETURN tls_decrypt_ticket(SSL *s, const unsigned char *etick,
|
||||
if (memcmp(etick, tctx->ext.tick_key_name,
|
||||
TLSEXT_KEYNAME_LENGTH) != 0) {
|
||||
ret = SSL_TICKET_NO_DECRYPT;
|
||||
goto err;
|
||||
goto end;
|
||||
}
|
||||
if (HMAC_Init_ex(hctx, tctx->ext.tick_hmac_key,
|
||||
sizeof(tctx->ext.tick_hmac_key),
|
||||
if (HMAC_Init_ex(hctx, tctx->ext.secure->tick_hmac_key,
|
||||
sizeof(tctx->ext.secure->tick_hmac_key),
|
||||
EVP_sha256(), NULL) <= 0
|
||||
|| EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL,
|
||||
tctx->ext.tick_aes_key,
|
||||
tctx->ext.secure->tick_aes_key,
|
||||
etick + TLSEXT_KEYNAME_LENGTH) <= 0) {
|
||||
goto err;
|
||||
ret = SSL_TICKET_FATAL_ERR_OTHER;
|
||||
goto end;
|
||||
}
|
||||
if (SSL_IS_TLS13(s))
|
||||
renew_ticket = 1;
|
||||
}
|
||||
/*
|
||||
* Attempt to process session ticket, first conduct sanity and integrity
|
||||
@@ -1364,24 +1336,27 @@ SSL_TICKET_RETURN tls_decrypt_ticket(SSL *s, const unsigned char *etick,
|
||||
*/
|
||||
mlen = HMAC_size(hctx);
|
||||
if (mlen == 0) {
|
||||
goto err;
|
||||
ret = SSL_TICKET_FATAL_ERR_OTHER;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* Sanity check ticket length: must exceed keyname + IV + HMAC */
|
||||
if (eticklen <=
|
||||
TLSEXT_KEYNAME_LENGTH + EVP_CIPHER_CTX_iv_length(ctx) + mlen) {
|
||||
ret = SSL_TICKET_NO_DECRYPT;
|
||||
goto err;
|
||||
goto end;
|
||||
}
|
||||
eticklen -= mlen;
|
||||
/* Check HMAC of encrypted ticket */
|
||||
if (HMAC_Update(hctx, etick, eticklen) <= 0
|
||||
|| HMAC_Final(hctx, tick_hmac, NULL) <= 0) {
|
||||
goto err;
|
||||
ret = SSL_TICKET_FATAL_ERR_OTHER;
|
||||
goto end;
|
||||
}
|
||||
HMAC_CTX_free(hctx);
|
||||
|
||||
if (CRYPTO_memcmp(tick_hmac, etick + eticklen, mlen)) {
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
return SSL_TICKET_NO_DECRYPT;
|
||||
ret = SSL_TICKET_NO_DECRYPT;
|
||||
goto end;
|
||||
}
|
||||
/* Attempt to decrypt session data */
|
||||
/* Move p after IV to start of encrypted ticket, update length */
|
||||
@@ -1390,18 +1365,16 @@ SSL_TICKET_RETURN tls_decrypt_ticket(SSL *s, const unsigned char *etick,
|
||||
sdec = OPENSSL_malloc(eticklen);
|
||||
if (sdec == NULL || EVP_DecryptUpdate(ctx, sdec, &slen, p,
|
||||
(int)eticklen) <= 0) {
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
OPENSSL_free(sdec);
|
||||
return SSL_TICKET_FATAL_ERR_OTHER;
|
||||
ret = SSL_TICKET_FATAL_ERR_OTHER;
|
||||
goto end;
|
||||
}
|
||||
if (EVP_DecryptFinal(ctx, sdec + slen, &declen) <= 0) {
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
OPENSSL_free(sdec);
|
||||
return SSL_TICKET_NO_DECRYPT;
|
||||
ret = SSL_TICKET_NO_DECRYPT;
|
||||
goto end;
|
||||
}
|
||||
slen += declen;
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
ctx = NULL;
|
||||
p = sdec;
|
||||
|
||||
sess = d2i_SSL_SESSION(NULL, &p, slen);
|
||||
@@ -1409,9 +1382,11 @@ SSL_TICKET_RETURN tls_decrypt_ticket(SSL *s, const unsigned char *etick,
|
||||
OPENSSL_free(sdec);
|
||||
if (sess) {
|
||||
/* Some additional consistency checks */
|
||||
if (slen != 0 || sess->session_id_length != 0) {
|
||||
if (slen != 0) {
|
||||
SSL_SESSION_free(sess);
|
||||
return SSL_TICKET_NO_DECRYPT;
|
||||
sess = NULL;
|
||||
ret = SSL_TICKET_NO_DECRYPT;
|
||||
goto end;
|
||||
}
|
||||
/*
|
||||
* The session ID, if non-empty, is used by some clients to detect
|
||||
@@ -1419,23 +1394,88 @@ SSL_TICKET_RETURN tls_decrypt_ticket(SSL *s, const unsigned char *etick,
|
||||
* structure. If it is empty set length to zero as required by
|
||||
* standard.
|
||||
*/
|
||||
if (sesslen)
|
||||
if (sesslen) {
|
||||
memcpy(sess->session_id, sess_id, sesslen);
|
||||
sess->session_id_length = sesslen;
|
||||
*psess = sess;
|
||||
sess->session_id_length = sesslen;
|
||||
}
|
||||
if (renew_ticket)
|
||||
return SSL_TICKET_SUCCESS_RENEW;
|
||||
ret = SSL_TICKET_SUCCESS_RENEW;
|
||||
else
|
||||
return SSL_TICKET_SUCCESS;
|
||||
ret = SSL_TICKET_SUCCESS;
|
||||
goto end;
|
||||
}
|
||||
ERR_clear_error();
|
||||
/*
|
||||
* For session parse failure, indicate that we need to send a new ticket.
|
||||
*/
|
||||
return SSL_TICKET_NO_DECRYPT;
|
||||
err:
|
||||
ret = SSL_TICKET_NO_DECRYPT;
|
||||
|
||||
end:
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
HMAC_CTX_free(hctx);
|
||||
|
||||
/*
|
||||
* If set, the decrypt_ticket_cb() is called unless a fatal error was
|
||||
* detected above. The callback is responsible for checking |ret| before it
|
||||
* performs any action
|
||||
*/
|
||||
if (s->session_ctx->decrypt_ticket_cb != NULL
|
||||
&& (ret == SSL_TICKET_EMPTY
|
||||
|| ret == SSL_TICKET_NO_DECRYPT
|
||||
|| ret == SSL_TICKET_SUCCESS
|
||||
|| ret == SSL_TICKET_SUCCESS_RENEW)) {
|
||||
size_t keyname_len = eticklen;
|
||||
int retcb;
|
||||
|
||||
if (keyname_len > TLSEXT_KEYNAME_LENGTH)
|
||||
keyname_len = TLSEXT_KEYNAME_LENGTH;
|
||||
retcb = s->session_ctx->decrypt_ticket_cb(s, sess, etick, keyname_len,
|
||||
ret,
|
||||
s->session_ctx->ticket_cb_data);
|
||||
switch (retcb) {
|
||||
case SSL_TICKET_RETURN_ABORT:
|
||||
ret = SSL_TICKET_FATAL_ERR_OTHER;
|
||||
break;
|
||||
|
||||
case SSL_TICKET_RETURN_IGNORE:
|
||||
ret = SSL_TICKET_NONE;
|
||||
SSL_SESSION_free(sess);
|
||||
sess = NULL;
|
||||
break;
|
||||
|
||||
case SSL_TICKET_RETURN_IGNORE_RENEW:
|
||||
if (ret != SSL_TICKET_EMPTY && ret != SSL_TICKET_NO_DECRYPT)
|
||||
ret = SSL_TICKET_NO_DECRYPT;
|
||||
/* else the value of |ret| will already do the right thing */
|
||||
SSL_SESSION_free(sess);
|
||||
sess = NULL;
|
||||
break;
|
||||
|
||||
case SSL_TICKET_RETURN_USE:
|
||||
case SSL_TICKET_RETURN_USE_RENEW:
|
||||
if (ret != SSL_TICKET_SUCCESS
|
||||
&& ret != SSL_TICKET_SUCCESS_RENEW)
|
||||
ret = SSL_TICKET_FATAL_ERR_OTHER;
|
||||
else if (retcb == SSL_TICKET_RETURN_USE)
|
||||
ret = SSL_TICKET_SUCCESS;
|
||||
else
|
||||
ret = SSL_TICKET_SUCCESS_RENEW;
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = SSL_TICKET_FATAL_ERR_OTHER;
|
||||
}
|
||||
}
|
||||
|
||||
switch (ret) {
|
||||
case SSL_TICKET_NO_DECRYPT:
|
||||
case SSL_TICKET_SUCCESS_RENEW:
|
||||
case SSL_TICKET_EMPTY:
|
||||
s->ext.ticket_expected = 1;
|
||||
}
|
||||
|
||||
*psess = sess;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1593,9 +1633,10 @@ static int tls1_set_shared_sigalgs(SSL *s)
|
||||
}
|
||||
nmatch = tls12_shared_sigalgs(s, NULL, pref, preflen, allow, allowlen);
|
||||
if (nmatch) {
|
||||
salgs = OPENSSL_malloc(nmatch * sizeof(*salgs));
|
||||
if (salgs == NULL)
|
||||
if ((salgs = OPENSSL_malloc(nmatch * sizeof(*salgs))) == NULL) {
|
||||
SSLerr(SSL_F_TLS1_SET_SHARED_SIGALGS, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
nmatch = tls12_shared_sigalgs(s, salgs, pref, preflen, allow, allowlen);
|
||||
} else {
|
||||
salgs = NULL;
|
||||
@@ -1619,9 +1660,10 @@ int tls1_save_u16(PACKET *pkt, uint16_t **pdest, size_t *pdestlen)
|
||||
|
||||
size >>= 1;
|
||||
|
||||
buf = OPENSSL_malloc(size * sizeof(*buf));
|
||||
if (buf == NULL)
|
||||
if ((buf = OPENSSL_malloc(size * sizeof(*buf))) == NULL) {
|
||||
SSLerr(SSL_F_TLS1_SAVE_U16, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
for (i = 0; i < size && PACKET_get_net_2(pkt, &stmp); i++)
|
||||
buf[i] = stmp;
|
||||
|
||||
@@ -1849,9 +1891,10 @@ int tls1_set_raw_sigalgs(CERT *c, const uint16_t *psigs, size_t salglen,
|
||||
{
|
||||
uint16_t *sigalgs;
|
||||
|
||||
sigalgs = OPENSSL_malloc(salglen * sizeof(*sigalgs));
|
||||
if (sigalgs == NULL)
|
||||
if ((sigalgs = OPENSSL_malloc(salglen * sizeof(*sigalgs))) == NULL) {
|
||||
SSLerr(SSL_F_TLS1_SET_RAW_SIGALGS, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
memcpy(sigalgs, psigs, salglen * sizeof(*sigalgs));
|
||||
|
||||
if (client) {
|
||||
@@ -1874,9 +1917,10 @@ int tls1_set_sigalgs(CERT *c, const int *psig_nids, size_t salglen, int client)
|
||||
|
||||
if (salglen & 1)
|
||||
return 0;
|
||||
sigalgs = OPENSSL_malloc((salglen / 2) * sizeof(*sigalgs));
|
||||
if (sigalgs == NULL)
|
||||
if ((sigalgs = OPENSSL_malloc((salglen / 2) * sizeof(*sigalgs))) == NULL) {
|
||||
SSLerr(SSL_F_TLS1_SET_SIGALGS, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
for (i = 0, sptr = sigalgs; i < salglen; i += 2) {
|
||||
size_t j;
|
||||
const SIGALG_LOOKUP *curr;
|
||||
@@ -2422,7 +2466,7 @@ int tls_choose_sigalg(SSL *s, int fatalerrs)
|
||||
if (SSL_IS_TLS13(s)) {
|
||||
size_t i;
|
||||
#ifndef OPENSSL_NO_EC
|
||||
int curve = -1, skip_ec = 0;
|
||||
int curve = -1;
|
||||
#endif
|
||||
|
||||
/* Look for a certificate matching shared sigalgs */
|
||||
@@ -2445,11 +2489,8 @@ int tls_choose_sigalg(SSL *s, int fatalerrs)
|
||||
EC_KEY *ec = EVP_PKEY_get0_EC_KEY(s->cert->pkeys[SSL_PKEY_ECC].privatekey);
|
||||
|
||||
curve = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec));
|
||||
if (EC_KEY_get_conv_form(ec)
|
||||
!= POINT_CONVERSION_UNCOMPRESSED)
|
||||
skip_ec = 1;
|
||||
}
|
||||
if (skip_ec || (lu->curve != NID_undef && curve != lu->curve))
|
||||
if (lu->curve != NID_undef && curve != lu->curve)
|
||||
continue;
|
||||
#else
|
||||
continue;
|
||||
|
||||
+38
-11
@@ -19,11 +19,11 @@ typedef struct {
|
||||
} ssl_trace_tbl;
|
||||
|
||||
# define ssl_trace_str(val, tbl) \
|
||||
do_ssl_trace_str(val, tbl, OSSL_NELEM(tbl))
|
||||
do_ssl_trace_str(val, tbl, OSSL_NELEM(tbl))
|
||||
|
||||
# define ssl_trace_list(bio, indent, msg, msglen, value, table) \
|
||||
do_ssl_trace_list(bio, indent, msg, msglen, value, \
|
||||
table, OSSL_NELEM(table))
|
||||
do_ssl_trace_list(bio, indent, msg, msglen, value, \
|
||||
table, OSSL_NELEM(table))
|
||||
|
||||
static const char *do_ssl_trace_str(int val, const ssl_trace_tbl *tbl,
|
||||
size_t ntbl)
|
||||
@@ -65,7 +65,9 @@ static const ssl_trace_tbl ssl_version_tbl[] = {
|
||||
{TLS1_1_VERSION, "TLS 1.1"},
|
||||
{TLS1_2_VERSION, "TLS 1.2"},
|
||||
{TLS1_3_VERSION, "TLS 1.3"},
|
||||
/* TODO(TLS1.3): Remove this line before release */
|
||||
/* TODO(TLS1.3): Remove these lines before release */
|
||||
{TLS1_3_VERSION_DRAFT_26, TLS1_3_VERSION_DRAFT_TXT_26},
|
||||
{TLS1_3_VERSION_DRAFT_27, TLS1_3_VERSION_DRAFT_TXT_27},
|
||||
{TLS1_3_VERSION_DRAFT, TLS1_3_VERSION_DRAFT_TXT},
|
||||
{DTLS1_VERSION, "DTLS 1.0"},
|
||||
{DTLS1_2_VERSION, "DTLS 1.2"},
|
||||
@@ -184,6 +186,8 @@ static const ssl_trace_tbl ssl_ciphers_tbl[] = {
|
||||
{0x006B, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256"},
|
||||
{0x006C, "TLS_DH_anon_WITH_AES_128_CBC_SHA256"},
|
||||
{0x006D, "TLS_DH_anon_WITH_AES_256_CBC_SHA256"},
|
||||
{0x0081, "TLS_GOSTR341001_WITH_28147_CNT_IMIT"},
|
||||
{0x0083, "TLS_GOSTR341001_WITH_NULL_GOSTR3411"},
|
||||
{0x0084, "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA"},
|
||||
{0x0085, "TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA"},
|
||||
{0x0086, "TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA"},
|
||||
@@ -441,6 +445,8 @@ static const ssl_trace_tbl ssl_ciphers_tbl[] = {
|
||||
{0x1305, "TLS_AES_128_CCM_8_SHA256"},
|
||||
{0xFEFE, "SSL_RSA_FIPS_WITH_DES_CBC_SHA"},
|
||||
{0xFEFF, "SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA"},
|
||||
{0xFF85, "GOST2012-GOST8912-GOST8912"},
|
||||
{0xFF87, "GOST2012-NULL-GOST12"},
|
||||
};
|
||||
|
||||
/* Compression methods */
|
||||
@@ -638,7 +644,15 @@ static int ssl_print_version(BIO *bio, int indent, const char *name,
|
||||
vers = ((*pmsg)[0] << 8) | (*pmsg)[1];
|
||||
if (version != NULL) {
|
||||
/* TODO(TLS1.3): Remove the draft conditional here before release */
|
||||
*version = (vers == TLS1_3_VERSION_DRAFT) ? TLS1_3_VERSION : vers;
|
||||
switch(vers) {
|
||||
case TLS1_3_VERSION_DRAFT_26:
|
||||
case TLS1_3_VERSION_DRAFT_27:
|
||||
case TLS1_3_VERSION_DRAFT:
|
||||
*version = TLS1_3_VERSION;
|
||||
break;
|
||||
default:
|
||||
*version = vers;
|
||||
}
|
||||
}
|
||||
BIO_indent(bio, indent, 80);
|
||||
BIO_printf(bio, "%s=0x%x (%s)\n",
|
||||
@@ -729,7 +743,7 @@ static int ssl_print_extension(BIO *bio, int indent, int server,
|
||||
while (xlen > 0) {
|
||||
size_t plen = *ext++;
|
||||
|
||||
if (plen > xlen + 1)
|
||||
if (plen + 1 > xlen)
|
||||
return 0;
|
||||
BIO_indent(bio, indent + 2, 80);
|
||||
BIO_write(bio, ext, plen);
|
||||
@@ -888,6 +902,8 @@ static int ssl_print_extensions(BIO *bio, int indent, int server,
|
||||
BIO_puts(bio, "No Extensions\n");
|
||||
return 1;
|
||||
}
|
||||
if (msglen < 2)
|
||||
return 0;
|
||||
extslen = (msg[0] << 8) | msg[1];
|
||||
if (extslen != msglen - 2)
|
||||
return 0;
|
||||
@@ -1086,10 +1102,10 @@ static int ssl_print_client_keyex(BIO *bio, int indent, const SSL *ssl,
|
||||
case SSL_kRSAPSK:
|
||||
if (TLS1_get_version(ssl) == SSL3_VERSION) {
|
||||
ssl_print_hex(bio, indent + 2,
|
||||
"EncyptedPreMasterSecret", msg, msglen);
|
||||
"EncryptedPreMasterSecret", msg, msglen);
|
||||
} else {
|
||||
if (!ssl_print_hexbuf(bio, indent + 2,
|
||||
"EncyptedPreMasterSecret", 2, &msg, &msglen))
|
||||
"EncryptedPreMasterSecret", 2, &msg, &msglen))
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
@@ -1293,6 +1309,8 @@ static int ssl_print_cert_request(BIO *bio, int indent, const SSL *ssl,
|
||||
msg += xlen;
|
||||
}
|
||||
|
||||
if (msglen < 2)
|
||||
return 0;
|
||||
xlen = (msg[0] << 8) | msg[1];
|
||||
BIO_indent(bio, indent, 80);
|
||||
if (msglen < xlen + 2)
|
||||
@@ -1354,8 +1372,8 @@ static int ssl_print_ticket(BIO *bio, int indent, const SSL *ssl,
|
||||
|
||||
if (msglen < 4)
|
||||
return 0;
|
||||
ticket_age_add = (msg[0] << 24) | (msg[1] << 16) | (msg[2] << 8)
|
||||
| msg[3];
|
||||
ticket_age_add =
|
||||
(msg[0] << 24) | (msg[1] << 16) | (msg[2] << 8) | msg[3];
|
||||
msglen -= 4;
|
||||
msg += 4;
|
||||
BIO_indent(bio, indent + 2, 80);
|
||||
@@ -1493,7 +1511,16 @@ void SSL_trace(int write_p, int version, int content_type,
|
||||
switch (content_type) {
|
||||
case SSL3_RT_HEADER:
|
||||
{
|
||||
int hvers = msg[1] << 8 | msg[2];
|
||||
int hvers;
|
||||
|
||||
/* avoid overlapping with length at the end of buffer */
|
||||
if (msglen < (size_t)(SSL_IS_DTLS(ssl) ?
|
||||
DTLS1_RT_HEADER_LENGTH : SSL3_RT_HEADER_LENGTH)) {
|
||||
BIO_puts(bio, write_p ? "Sent" : "Received");
|
||||
ssl_print_hex(bio, 0, " too short message", msg, msglen);
|
||||
break;
|
||||
}
|
||||
hvers = msg[1] << 8 | msg[2];
|
||||
BIO_puts(bio, write_p ? "Sent" : "Received");
|
||||
BIO_printf(bio, " Record\nHeader:\n Version = %s (0x%x)\n",
|
||||
ssl_trace_str(hvers, ssl_version_tbl), hvers);
|
||||
|
||||
+33
-7
@@ -247,12 +247,23 @@ size_t tls13_final_finish_mac(SSL *s, const char *str, size_t slen,
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (str == s->method->ssl3_enc->server_finished_label)
|
||||
key = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL,
|
||||
s->server_finished_secret, hashlen);
|
||||
else
|
||||
key = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL,
|
||||
s->client_finished_secret, hashlen);
|
||||
if (str == s->method->ssl3_enc->server_finished_label) {
|
||||
key = EVP_PKEY_new_raw_private_key(EVP_PKEY_HMAC, NULL,
|
||||
s->server_finished_secret, hashlen);
|
||||
} else if (SSL_IS_FIRST_HANDSHAKE(s)) {
|
||||
key = EVP_PKEY_new_raw_private_key(EVP_PKEY_HMAC, NULL,
|
||||
s->client_finished_secret, hashlen);
|
||||
} else {
|
||||
unsigned char finsecret[EVP_MAX_MD_SIZE];
|
||||
|
||||
if (!tls13_derive_finishedkey(s, ssl_handshake_md(s),
|
||||
s->client_app_traffic_secret,
|
||||
finsecret, hashlen))
|
||||
goto err;
|
||||
|
||||
key = EVP_PKEY_new_raw_private_key(EVP_PKEY_HMAC, NULL, finsecret,
|
||||
hashlen);
|
||||
}
|
||||
|
||||
if (key == NULL
|
||||
|| ctx == NULL
|
||||
@@ -397,6 +408,7 @@ int tls13_change_cipher_state(SSL *s, int which)
|
||||
|
||||
RECORD_LAYER_reset_read_sequence(&s->rlayer);
|
||||
} else {
|
||||
s->statem.invalid_enc_write_ctx = 1;
|
||||
if (s->enc_write_ctx != NULL) {
|
||||
EVP_CIPHER_CTX_reset(s->enc_write_ctx);
|
||||
} else {
|
||||
@@ -406,7 +418,6 @@ int tls13_change_cipher_state(SSL *s, int which)
|
||||
SSL_F_TLS13_CHANGE_CIPHER_STATE, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
EVP_CIPHER_CTX_ctrl(s->enc_write_ctx, EVP_CTRL_SET_DRBG, 0, s->drbg);
|
||||
}
|
||||
ciph_ctx = s->enc_write_ctx;
|
||||
iv = s->write_iv;
|
||||
@@ -493,6 +504,12 @@ int tls13_change_cipher_state(SSL *s, int which)
|
||||
SSL_F_TLS13_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!ssl_log_secret(s, EARLY_EXPORTER_SECRET_LABEL,
|
||||
s->early_exporter_master_secret, hashlen)) {
|
||||
/* SSLfatal() already called */
|
||||
goto err;
|
||||
}
|
||||
} else if (which & SSL3_CC_HANDSHAKE) {
|
||||
insecret = s->handshake_secret;
|
||||
finsecret = s->client_finished_secret;
|
||||
@@ -594,6 +611,12 @@ int tls13_change_cipher_state(SSL *s, int which)
|
||||
/* SSLfatal() already called */
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!ssl_log_secret(s, EXPORTER_SECRET_LABEL, s->exporter_master_secret,
|
||||
hashlen)) {
|
||||
/* SSLfatal() already called */
|
||||
goto err;
|
||||
}
|
||||
} else if (label == client_application_traffic)
|
||||
memcpy(s->client_app_traffic_secret, secret, hashlen);
|
||||
|
||||
@@ -609,6 +632,7 @@ int tls13_change_cipher_state(SSL *s, int which)
|
||||
goto err;
|
||||
}
|
||||
|
||||
s->statem.invalid_enc_write_ctx = 0;
|
||||
ret = 1;
|
||||
err:
|
||||
OPENSSL_cleanse(secret, sizeof(secret));
|
||||
@@ -631,6 +655,7 @@ int tls13_update_key(SSL *s, int sending)
|
||||
insecret = s->client_app_traffic_secret;
|
||||
|
||||
if (sending) {
|
||||
s->statem.invalid_enc_write_ctx = 1;
|
||||
iv = s->write_iv;
|
||||
ciph_ctx = s->enc_write_ctx;
|
||||
RECORD_LAYER_reset_write_sequence(&s->rlayer);
|
||||
@@ -651,6 +676,7 @@ int tls13_update_key(SSL *s, int sending)
|
||||
|
||||
memcpy(insecret, secret, hashlen);
|
||||
|
||||
s->statem.invalid_enc_write_ctx = 0;
|
||||
ret = 1;
|
||||
err:
|
||||
OPENSSL_cleanse(secret, sizeof(secret));
|
||||
|
||||
+2
-2
@@ -157,7 +157,7 @@ int SSL_srp_server_param_with_username(SSL *s, int *ad)
|
||||
(s->srp_ctx.s == NULL) || (s->srp_ctx.v == NULL))
|
||||
return SSL3_AL_FATAL;
|
||||
|
||||
if (ssl_randbytes(s, b, sizeof(b)) <= 0)
|
||||
if (RAND_priv_bytes(b, sizeof(b)) <= 0)
|
||||
return SSL3_AL_FATAL;
|
||||
s->srp_ctx.b = BN_bin2bn(b, sizeof(b), NULL);
|
||||
OPENSSL_cleanse(b, sizeof(b));
|
||||
@@ -369,7 +369,7 @@ int SRP_Calc_A_param(SSL *s)
|
||||
{
|
||||
unsigned char rnd[SSL_MAX_MASTER_KEY_LENGTH];
|
||||
|
||||
if (ssl_randbytes(s, rnd, sizeof(rnd)) <= 0)
|
||||
if (RAND_priv_bytes(rnd, sizeof(rnd)) <= 0)
|
||||
return 0;
|
||||
s->srp_ctx.a = BN_bin2bn(rnd, sizeof(rnd), s->srp_ctx.a);
|
||||
OPENSSL_cleanse(rnd, sizeof(rnd));
|
||||
|
||||
Reference in New Issue
Block a user