diff options
Diffstat (limited to 'ssl')
-rw-r--r-- | ssl/d1_lib.c | 93 | ||||
-rw-r--r-- | ssl/record/rec_layer_d1.c | 5 | ||||
-rw-r--r-- | ssl/record/record.h | 6 | ||||
-rw-r--r-- | ssl/record/record_locl.h | 2 | ||||
-rw-r--r-- | ssl/record/ssl3_record.c | 25 | ||||
-rw-r--r-- | ssl/s3_cbc.c | 7 | ||||
-rw-r--r-- | ssl/s3_enc.c | 8 | ||||
-rw-r--r-- | ssl/s3_lib.c | 24 | ||||
-rw-r--r-- | ssl/ssl_cert.c | 17 | ||||
-rw-r--r-- | ssl/ssl_ciph.c | 2 | ||||
-rw-r--r-- | ssl/ssl_lib.c | 62 | ||||
-rw-r--r-- | ssl/ssl_locl.h | 22 | ||||
-rw-r--r-- | ssl/statem/extensions.c | 12 | ||||
-rw-r--r-- | ssl/statem/extensions_clnt.c | 13 | ||||
-rw-r--r-- | ssl/statem/statem.c | 5 | ||||
-rw-r--r-- | ssl/statem/statem_clnt.c | 12 | ||||
-rw-r--r-- | ssl/statem/statem_lib.c | 59 | ||||
-rw-r--r-- | ssl/statem/statem_locl.h | 3 | ||||
-rw-r--r-- | ssl/statem/statem_srvr.c | 44 | ||||
-rw-r--r-- | ssl/t1_lib.c | 45 | ||||
-rw-r--r-- | ssl/tls13_enc.c | 16 |
21 files changed, 342 insertions, 140 deletions
diff --git a/ssl/d1_lib.c b/ssl/d1_lib.c index f80851251fe2..fcda32754735 100644 --- a/ssl/d1_lib.c +++ b/ssl/d1_lib.c @@ -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 @@ -445,15 +445,14 @@ static void get_current_time(struct timeval *t) #ifndef OPENSSL_NO_SOCK int DTLSv1_listen(SSL *s, BIO_ADDR *client) { - int next, n, ret = 0, clearpkt = 0; + int next, n, ret = 0; unsigned char cookie[DTLS1_COOKIE_LENGTH]; unsigned char seq[SEQ_NUM_SIZE]; const unsigned char *data; - unsigned char *buf; - size_t fragoff, fraglen, msglen; + unsigned char *buf, *wbuf; + size_t fragoff, fraglen, msglen, reclen, align = 0; unsigned int rectype, versmajor, msgseq, msgtype, clientvers, cookielen; BIO *rbio, *wbio; - BUF_MEM *bufm; BIO_ADDR *tmpclient = NULL; PACKET pkt, msgpkt, msgpayload, session, cookiepkt; @@ -477,13 +476,6 @@ int DTLSv1_listen(SSL *s, BIO_ADDR *client) } /* - * We only peek at incoming ClientHello's until we're sure we are going to - * to respond with a HelloVerifyRequest. If its a ClientHello with a valid - * cookie then we leave it in the BIO for accept to handle. - */ - BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_PEEK_MODE, 1, NULL); - - /* * Note: This check deliberately excludes DTLS1_BAD_VER because that version * requires the MAC to be calculated *including* the first ClientHello * (without the cookie). Since DTLSv1_listen is stateless that cannot be @@ -495,35 +487,32 @@ int DTLSv1_listen(SSL *s, BIO_ADDR *client) return -1; } - if (s->init_buf == NULL) { - if ((bufm = BUF_MEM_new()) == NULL) { - SSLerr(SSL_F_DTLSV1_LISTEN, ERR_R_MALLOC_FAILURE); - return -1; - } - - if (!BUF_MEM_grow(bufm, SSL3_RT_MAX_PLAIN_LENGTH)) { - BUF_MEM_free(bufm); - SSLerr(SSL_F_DTLSV1_LISTEN, ERR_R_MALLOC_FAILURE); - return -1; - } - s->init_buf = bufm; + if (!ssl3_setup_buffers(s)) { + /* SSLerr already called */ + return -1; } - buf = (unsigned char *)s->init_buf->data; + buf = RECORD_LAYER_get_rbuf(&s->rlayer)->buf; + wbuf = RECORD_LAYER_get_wbuf(&s->rlayer)[0].buf; +#if defined(SSL3_ALIGN_PAYLOAD) +# if SSL3_ALIGN_PAYLOAD != 0 + /* + * Using SSL3_RT_HEADER_LENGTH here instead of DTLS1_RT_HEADER_LENGTH for + * consistency with ssl3_read_n. In practice it should make no difference + * for sensible values of SSL3_ALIGN_PAYLOAD because the difference between + * SSL3_RT_HEADER_LENGTH and DTLS1_RT_HEADER_LENGTH is exactly 8 + */ + align = (size_t)buf + SSL3_RT_HEADER_LENGTH; + align = SSL3_ALIGN_PAYLOAD - 1 - ((align - 1) % SSL3_ALIGN_PAYLOAD); +# endif +#endif + buf += align; do { /* Get a packet */ clear_sys_error(); - /* - * Technically a ClientHello could be SSL3_RT_MAX_PLAIN_LENGTH - * + DTLS1_RT_HEADER_LENGTH bytes long. Normally init_buf does not store - * the record header as well, but we do here. We've set up init_buf to - * be the standard size for simplicity. In practice we shouldn't ever - * receive a ClientHello as long as this. If we do it will get dropped - * in the record length check below. - */ - n = BIO_read(rbio, buf, SSL3_RT_MAX_PLAIN_LENGTH); - + n = BIO_read(rbio, buf, SSL3_RT_MAX_PLAIN_LENGTH + + DTLS1_RT_HEADER_LENGTH); if (n <= 0) { if (BIO_should_retry(rbio)) { /* Non-blocking IO */ @@ -532,9 +521,6 @@ int DTLSv1_listen(SSL *s, BIO_ADDR *client) return -1; } - /* If we hit any problems we need to clear this packet from the BIO */ - clearpkt = 1; - if (!PACKET_buf_init(&pkt, buf, n)) { SSLerr(SSL_F_DTLSV1_LISTEN, ERR_R_INTERNAL_ERROR); return -1; @@ -587,6 +573,7 @@ int DTLSv1_listen(SSL *s, BIO_ADDR *client) SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_LENGTH_MISMATCH); goto end; } + reclen = PACKET_remaining(&msgpkt); /* * We allow data remaining at the end of the packet because there could * be a second record (but we ignore it) @@ -706,14 +693,6 @@ int DTLSv1_listen(SSL *s, BIO_ADDR *client) * to resend, we just drop it. */ - /* - * Dump the read packet, we don't need it any more. Ignore return - * value - */ - BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_PEEK_MODE, 0, NULL); - BIO_read(rbio, buf, SSL3_RT_MAX_PLAIN_LENGTH); - BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_PEEK_MODE, 1, NULL); - /* Generate the cookie */ if (s->ctx->app_gen_cookie_cb == NULL || s->ctx->app_gen_cookie_cb(s, cookie, &cookielen) == 0 || @@ -732,7 +711,11 @@ int DTLSv1_listen(SSL *s, BIO_ADDR *client) : s->version; /* Construct the record and message headers */ - if (!WPACKET_init(&wpkt, s->init_buf) + if (!WPACKET_init_static_len(&wpkt, + wbuf, + ssl_get_max_send_fragment(s) + + DTLS1_RT_HEADER_LENGTH, + 0) || !WPACKET_put_bytes_u8(&wpkt, SSL3_RT_HANDSHAKE) || !WPACKET_put_bytes_u16(&wpkt, version) /* @@ -790,8 +773,8 @@ int DTLSv1_listen(SSL *s, BIO_ADDR *client) * plus one byte for the message content type. The source is the * last 3 bytes of the message header */ - memcpy(&buf[DTLS1_RT_HEADER_LENGTH + 1], - &buf[DTLS1_RT_HEADER_LENGTH + DTLS1_HM_HEADER_LENGTH - 3], + memcpy(&wbuf[DTLS1_RT_HEADER_LENGTH + 1], + &wbuf[DTLS1_RT_HEADER_LENGTH + DTLS1_HM_HEADER_LENGTH - 3], 3); if (s->msg_callback) @@ -815,7 +798,7 @@ int DTLSv1_listen(SSL *s, BIO_ADDR *client) tmpclient = NULL; /* TODO(size_t): convert this call */ - if (BIO_write(wbio, buf, wreclen) < (int)wreclen) { + if (BIO_write(wbio, wbuf, wreclen) < (int)wreclen) { if (BIO_should_retry(wbio)) { /* * Non-blocking IO...but we're stateless, so we're just @@ -865,15 +848,13 @@ int DTLSv1_listen(SSL *s, BIO_ADDR *client) if (BIO_dgram_get_peer(rbio, client) <= 0) BIO_ADDR_clear(client); + /* Buffer the record in the processed_rcds queue */ + if (!dtls_buffer_listen_record(s, reclen, seq, align)) + return -1; + ret = 1; - clearpkt = 0; end: BIO_ADDR_free(tmpclient); - BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_PEEK_MODE, 0, NULL); - if (clearpkt) { - /* Dump this packet. Ignore return value */ - BIO_read(rbio, buf, SSL3_RT_MAX_PLAIN_LENGTH); - } return ret; } #endif diff --git a/ssl/record/rec_layer_d1.c b/ssl/record/rec_layer_d1.c index 43e1f9895319..1f9b31969d82 100644 --- a/ssl/record/rec_layer_d1.c +++ b/ssl/record/rec_layer_d1.c @@ -185,14 +185,11 @@ int dtls1_buffer_record(SSL *s, record_pqueue *queue, unsigned char *priority) return -1; } - /* insert should not fail, since duplicates are dropped */ if (pqueue_insert(queue->q, item) == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DTLS1_BUFFER_RECORD, - ERR_R_INTERNAL_ERROR); + /* Must be a duplicate so ignore it */ OPENSSL_free(rdata->rbuf.buf); OPENSSL_free(rdata); pitem_free(item); - return -1; } return 1; diff --git a/ssl/record/record.h b/ssl/record/record.h index 32db8212aa14..af56206e07c9 100644 --- a/ssl/record/record.h +++ b/ssl/record/record.h @@ -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 @@ -188,6 +188,8 @@ typedef struct record_layer_st { ((rl)->d->processed_rcds) #define DTLS_RECORD_LAYER_get_unprocessed_rcds(rl) \ ((rl)->d->unprocessed_rcds) +#define RECORD_LAYER_get_rbuf(rl) (&(rl)->rbuf) +#define RECORD_LAYER_get_wbuf(rl) ((rl)->wbuf) void RECORD_LAYER_init(RECORD_LAYER *rl, SSL *s); void RECORD_LAYER_clear(RECORD_LAYER *rl); @@ -230,3 +232,5 @@ __owur int dtls1_write_bytes(SSL *s, int type, const void *buf, size_t len, int do_dtls1_write(SSL *s, int type, const unsigned char *buf, size_t len, int create_empty_fragment, size_t *written); void dtls1_reset_seq_numbers(SSL *s, int rw); +int dtls_buffer_listen_record(SSL *s, size_t len, unsigned char *seq, + size_t off); diff --git a/ssl/record/record_locl.h b/ssl/record/record_locl.h index 07fd7ab640ba..5e8dd7f70442 100644 --- a/ssl/record/record_locl.h +++ b/ssl/record/record_locl.h @@ -18,8 +18,6 @@ /* Functions/macros provided by the RECORD_LAYER component */ -#define RECORD_LAYER_get_rbuf(rl) (&(rl)->rbuf) -#define RECORD_LAYER_get_wbuf(rl) ((rl)->wbuf) #define RECORD_LAYER_get_rrec(rl) ((rl)->rrec) #define RECORD_LAYER_set_packet(rl, p) ((rl)->packet = (p)) #define RECORD_LAYER_reset_packet_length(rl) ((rl)->packet_length = 0) diff --git a/ssl/record/ssl3_record.c b/ssl/record/ssl3_record.c index a616bf040932..e59ac5a67676 100644 --- a/ssl/record/ssl3_record.c +++ b/ssl/record/ssl3_record.c @@ -2030,3 +2030,28 @@ int dtls1_get_record(SSL *s) return 1; } + +int dtls_buffer_listen_record(SSL *s, size_t len, unsigned char *seq, size_t off) +{ + SSL3_RECORD *rr; + + rr = RECORD_LAYER_get_rrec(&s->rlayer); + memset(rr, 0, sizeof(SSL3_RECORD)); + + rr->length = len; + rr->type = SSL3_RT_HANDSHAKE; + memcpy(rr->seq_num, seq, sizeof(rr->seq_num)); + rr->off = off; + + s->rlayer.packet = RECORD_LAYER_get_rbuf(&s->rlayer)->buf; + s->rlayer.packet_length = DTLS1_RT_HEADER_LENGTH + len; + rr->data = s->rlayer.packet + DTLS1_RT_HEADER_LENGTH; + + if (dtls1_buffer_record(s, &(s->rlayer.d->processed_rcds), + SSL3_RECORD_get_seq_num(s->rlayer.rrec)) <= 0) { + /* SSLfatal() already called */ + return 0; + } + + return 1; +} diff --git a/ssl/s3_cbc.c b/ssl/s3_cbc.c index 7d9c3776973d..8377d7fe13dc 100644 --- a/ssl/s3_cbc.c +++ b/ssl/s3_cbc.c @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2012-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 @@ -256,12 +256,13 @@ int ssl3_cbc_digest_record(const EVP_MD_CTX *ctx, * of hash termination (0x80 + 64-bit length) don't fit in the final * block, we say that the final two blocks can vary based on the padding. * TLSv1 has MACs up to 48 bytes long (SHA-384) and the padding is not - * required to be minimal. Therefore we say that the final six blocks can + * required to be minimal. Therefore we say that the final |variance_blocks| + * blocks can * vary based on the padding. Later in the function, if the message is * short and there obviously cannot be this many blocks then * variance_blocks can be reduced. */ - variance_blocks = is_sslv3 ? 2 : 6; + variance_blocks = is_sslv3 ? 2 : ( ((255 + 1 + md_size + md_block_size - 1) / md_block_size) + 1); /* * From now on we're dealing with the MAC, which conceptually has 13 * bytes of `header' before the start of the data (TLS) or 71/75 bytes diff --git a/ssl/s3_enc.c b/ssl/s3_enc.c index 5f403817b4d5..fca84ef99acf 100644 --- a/ssl/s3_enc.c +++ b/ssl/s3_enc.c @@ -442,15 +442,16 @@ size_t ssl3_final_finish_mac(SSL *s, const char *sender, size_t len, if (!EVP_MD_CTX_copy_ex(ctx, s->s3->handshake_dgst)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_FINAL_FINISH_MAC, ERR_R_INTERNAL_ERROR); - return 0; + ret = 0; + goto err; } ret = EVP_MD_CTX_size(ctx); if (ret < 0) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_FINAL_FINISH_MAC, ERR_R_INTERNAL_ERROR); - EVP_MD_CTX_reset(ctx); - return 0; + ret = 0; + goto err; } if ((sender != NULL && EVP_DigestUpdate(ctx, sender, len) <= 0) @@ -463,6 +464,7 @@ size_t ssl3_final_finish_mac(SSL *s, const char *sender, size_t len, ret = 0; } + err: EVP_MD_CTX_free(ctx); return ret; diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c index 7713f767b2d3..866ca4dfa9b0 100644 --- a/ssl/s3_lib.c +++ b/ssl/s3_lib.c @@ -3681,9 +3681,15 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg) *(int *)parg = s->s3->tmp.peer_sigalg->hash; return 1; - case SSL_CTRL_GET_SERVER_TMP_KEY: + case SSL_CTRL_GET_SIGNATURE_NID: + if (s->s3->tmp.sigalg == NULL) + return 0; + *(int *)parg = s->s3->tmp.sigalg->hash; + return 1; + + case SSL_CTRL_GET_PEER_TMP_KEY: #if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_EC) - if (s->server || s->session == NULL || s->s3->peer_tmp == NULL) { + if (s->session == NULL || s->s3->peer_tmp == NULL) { return 0; } else { EVP_PKEY_up_ref(s->s3->peer_tmp); @@ -3693,6 +3699,20 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg) #else return 0; #endif + + case SSL_CTRL_GET_TMP_KEY: +#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_EC) + if (s->session == NULL || s->s3->tmp.pkey == NULL) { + return 0; + } else { + EVP_PKEY_up_ref(s->s3->tmp.pkey); + *(EVP_PKEY **)parg = s->s3->tmp.pkey; + return 1; + } +#else + return 0; +#endif + #ifndef OPENSSL_NO_EC case SSL_CTRL_GET_EC_POINT_FORMATS: { diff --git a/ssl/ssl_cert.c b/ssl/ssl_cert.c index 52a4a7eaadd2..33145078963d 100644 --- a/ssl/ssl_cert.c +++ b/ssl/ssl_cert.c @@ -501,17 +501,17 @@ const STACK_OF(X509_NAME) *SSL_get0_CA_list(const SSL *s) void SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list) { - SSL_CTX_set0_CA_list(ctx, name_list); + set0_CA_list(&ctx->client_ca_names, name_list); } STACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *ctx) { - return ctx->ca_names; + return ctx->client_ca_names; } void SSL_set_client_CA_list(SSL *s, STACK_OF(X509_NAME) *name_list) { - SSL_set0_CA_list(s, name_list); + set0_CA_list(&s->client_ca_names, name_list); } const STACK_OF(X509_NAME) *SSL_get0_peer_CA_list(const SSL *s) @@ -523,7 +523,8 @@ STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *s) { if (!s->server) return s->s3 != NULL ? s->s3->tmp.peer_ca_names : NULL; - return s->ca_names != NULL ? s->ca_names : s->ctx->ca_names; + return s->client_ca_names != NULL ? s->client_ca_names + : s->ctx->client_ca_names; } static int add_ca_name(STACK_OF(X509_NAME) **sk, const X509 *x) @@ -561,12 +562,12 @@ int SSL_CTX_add1_to_CA_list(SSL_CTX *ctx, const X509 *x) */ int SSL_add_client_CA(SSL *ssl, X509 *x) { - return add_ca_name(&ssl->ca_names, x); + return add_ca_name(&ssl->client_ca_names, x); } int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x) { - return add_ca_name(&ctx->ca_names, x); + return add_ca_name(&ctx->client_ca_names, x); } static int xname_cmp(const X509_NAME *a, const X509_NAME *b) @@ -951,8 +952,8 @@ static int ssl_security_default_callback(const SSL *s, const SSL_CTX *ctx, if (level >= 2 && c->algorithm_enc == SSL_RC4) return 0; /* Level 3: forward secure ciphersuites only */ - if (level >= 3 && (c->min_tls != TLS1_3_VERSION || - !(c->algorithm_mkey & (SSL_kEDH | SSL_kEECDH)))) + if (level >= 3 && c->min_tls != TLS1_3_VERSION && + !(c->algorithm_mkey & (SSL_kEDH | SSL_kEECDH))) return 0; break; } diff --git a/ssl/ssl_ciph.c b/ssl/ssl_ciph.c index b60cc79a2f53..14066d0ea451 100644 --- a/ssl/ssl_ciph.c +++ b/ssl/ssl_ciph.c @@ -1301,7 +1301,7 @@ static int ciphersuite_cb(const char *elem, int len, void *arg) return 1; } -int set_ciphersuites(STACK_OF(SSL_CIPHER) **currciphers, const char *str) +static __owur int set_ciphersuites(STACK_OF(SSL_CIPHER) **currciphers, const char *str) { STACK_OF(SSL_CIPHER) *newciphers = sk_SSL_CIPHER_new_null(); diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index d75158e30c4f..61a0ea2cc974 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -654,6 +654,10 @@ int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth) ctx->method = meth; + if (!SSL_CTX_set_ciphersuites(ctx, TLS_DEFAULT_CIPHERSUITES)) { + SSLerr(SSL_F_SSL_CTX_SET_SSL_VERSION, SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS); + return 0; + } sk = ssl_create_cipher_list(ctx->method, ctx->tls13_ciphersuites, &(ctx->cipher_list), @@ -1192,6 +1196,7 @@ void SSL_free(SSL *s) EVP_MD_CTX_free(s->pha_dgst); sk_X509_NAME_pop_free(s->ca_names, X509_NAME_free); + sk_X509_NAME_pop_free(s->client_ca_names, X509_NAME_free); sk_X509_pop_free(s->verified_chain, X509_free); @@ -2951,6 +2956,9 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth) if ((ret->ca_names = sk_X509_NAME_new_null()) == NULL) goto err; + if ((ret->client_ca_names = sk_X509_NAME_new_null()) == NULL) + goto err; + if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_CTX, ret, &ret->ex_data)) goto err; @@ -3108,6 +3116,7 @@ void SSL_CTX_free(SSL_CTX *a) 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_NAME_pop_free(a->client_ca_names, X509_NAME_free); sk_X509_pop_free(a->extra_certs, X509_free); a->comp_methods = NULL; #ifndef OPENSSL_NO_SRTP @@ -3653,10 +3662,38 @@ const char *SSL_get_version(const SSL *s) return ssl_protocol_to_string(s->version); } -SSL *SSL_dup(SSL *s) +static int dup_ca_names(STACK_OF(X509_NAME) **dst, STACK_OF(X509_NAME) *src) { STACK_OF(X509_NAME) *sk; X509_NAME *xn; + int i; + + if (src == NULL) { + *dst = NULL; + return 1; + } + + if ((sk = sk_X509_NAME_new_null()) == NULL) + return 0; + for (i = 0; i < sk_X509_NAME_num(src); i++) { + xn = X509_NAME_dup(sk_X509_NAME_value(src, i)); + if (xn == NULL) { + sk_X509_NAME_pop_free(sk, X509_NAME_free); + return 0; + } + if (sk_X509_NAME_insert(sk, xn, i) == 0) { + X509_NAME_free(xn); + sk_X509_NAME_pop_free(sk, X509_NAME_free); + return 0; + } + } + *dst = sk; + + return 1; +} + +SSL *SSL_dup(SSL *s) +{ SSL *ret; int i; @@ -3761,18 +3798,10 @@ SSL *SSL_dup(SSL *s) goto err; /* Dup the client_CA list */ - if (s->ca_names != NULL) { - if ((sk = sk_X509_NAME_dup(s->ca_names)) == NULL) - goto err; - ret->ca_names = sk; - for (i = 0; i < sk_X509_NAME_num(sk); i++) { - xn = sk_X509_NAME_value(sk, i); - if (sk_X509_NAME_set(sk, i, X509_NAME_dup(xn)) == NULL) { - X509_NAME_free(xn); - goto err; - } - } - } + if (!dup_ca_names(&ret->ca_names, s->ca_names) + || !dup_ca_names(&ret->client_ca_names, s->client_ca_names)) + goto err; + return ret; err: @@ -5102,7 +5131,8 @@ static int nss_keylog_int(const char *prefix, size_t i; size_t prefix_len; - if (ssl->ctx->keylog_callback == NULL) return 1; + if (ssl->ctx->keylog_callback == NULL) + return 1; /* * Our output buffer will contain the following strings, rendered with @@ -5113,7 +5143,7 @@ static int nss_keylog_int(const char *prefix, * hexadecimal, so we need a buffer that is twice their lengths. */ prefix_len = strlen(prefix); - out_len = prefix_len + (2*parameter_1_len) + (2*parameter_2_len) + 3; + out_len = prefix_len + (2 * parameter_1_len) + (2 * parameter_2_len) + 3; if ((out = cursor = OPENSSL_malloc(out_len)) == NULL) { SSLfatal(ssl, SSL_AD_INTERNAL_ERROR, SSL_F_NSS_KEYLOG_INT, ERR_R_MALLOC_FAILURE); @@ -5137,7 +5167,7 @@ static int nss_keylog_int(const char *prefix, *cursor = '\0'; ssl->ctx->keylog_callback(ssl, (const char *)out); - OPENSSL_free(out); + OPENSSL_clear_free(out, out_len); return 1; } diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h index e8819e7a2838..70e5a1740f9c 100644 --- a/ssl/ssl_locl.h +++ b/ssl/ssl_locl.h @@ -471,7 +471,11 @@ struct ssl_method_st { long (*ssl_ctx_callback_ctrl) (SSL_CTX *s, int cb_id, void (*fp) (void)); }; -# define TLS13_MAX_RESUMPTION_PSK_LENGTH 64 +/* + * Matches the length of PSK_MAX_PSK_LEN. We keep it the same value for + * consistency, even in the event of OPENSSL_NO_PSK being defined. + */ +# define TLS13_MAX_RESUMPTION_PSK_LENGTH 256 /*- * Lets make this into an ASN.1 type structure as follows @@ -850,9 +854,11 @@ struct ssl_ctx_st { /* * What we put in certificate_authorities extension for TLS 1.3 * (ClientHello and CertificateRequest) or just client cert requests for - * earlier versions. + * earlier versions. If client_ca_names is populated then it is only used + * for client cert requests, and in preference to ca_names. */ STACK_OF(X509_NAME) *ca_names; + STACK_OF(X509_NAME) *client_ca_names; /* * Default values to use in SSL structures follow (these are copied by @@ -1229,8 +1235,14 @@ struct ssl_st { long verify_result; /* extra application data */ CRYPTO_EX_DATA ex_data; - /* for server side, keep the list of CA_dn we can use */ + /* + * What we put in certificate_authorities extension for TLS 1.3 + * (ClientHello and CertificateRequest) or just client cert requests for + * earlier versions. If client_ca_names is populated then it is only used + * for client cert requests, and in preference to ca_names. + */ STACK_OF(X509_NAME) *ca_names; + STACK_OF(X509_NAME) *client_ca_names; CRYPTO_REF_COUNT references; /* protocol behaviour */ uint32_t options; @@ -2251,7 +2263,6 @@ __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 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, @@ -2561,6 +2572,9 @@ __owur int tls1_process_sigalgs(SSL *s); __owur int tls1_set_peer_legacy_sigalg(SSL *s, const EVP_PKEY *pkey); __owur int tls1_lookup_md(const SIGALG_LOOKUP *lu, const EVP_MD **pmd); __owur size_t tls12_get_psigalgs(SSL *s, int sent, const uint16_t **psigs); +# ifndef OPENSSL_NO_EC +__owur int tls_check_sigalg_curve(const SSL *s, int curve); +# endif __owur int tls12_check_peer_sigalg(SSL *s, uint16_t, EVP_PKEY *pkey); __owur int ssl_set_client_disabled(SSL *s); __owur int ssl_cipher_disabled(SSL *s, const SSL_CIPHER *c, int op, int echde); diff --git a/ssl/statem/extensions.c b/ssl/statem/extensions.c index 8422161dc103..63e61c6184ac 100644 --- a/ssl/statem/extensions.c +++ b/ssl/statem/extensions.c @@ -962,7 +962,7 @@ static int final_server_name(SSL *s, unsigned int context, int sent) */ if (SSL_IS_FIRST_HANDSHAKE(s) && s->ctx != s->session_ctx) { tsan_counter(&s->ctx->stats.sess_accept); - tsan_counter(&s->session_ctx->stats.sess_accept); + tsan_decr(&s->session_ctx->stats.sess_accept); } /* @@ -1198,7 +1198,7 @@ static EXT_RETURN tls_construct_certificate_authorities(SSL *s, WPACKET *pkt, X509 *x, size_t chainidx) { - const STACK_OF(X509_NAME) *ca_sk = SSL_get0_CA_list(s); + const STACK_OF(X509_NAME) *ca_sk = get_ca_names(s); if (ca_sk == NULL || sk_X509_NAME_num(ca_sk) == 0) return EXT_RETURN_NOT_SENT; @@ -1211,7 +1211,7 @@ static EXT_RETURN tls_construct_certificate_authorities(SSL *s, WPACKET *pkt, return EXT_RETURN_FAIL; } - if (!construct_ca_names(s, pkt)) { + if (!construct_ca_names(s, ca_sk, pkt)) { /* SSLfatal() already called */ return EXT_RETURN_FAIL; } @@ -1530,10 +1530,12 @@ int tls_psk_do_binder(SSL *s, const EVP_MD *md, const unsigned char *msgstart, */ if (s->hello_retry_request == SSL_HRR_PENDING) { size_t hdatalen; + long hdatalen_l; void *hdata; - hdatalen = BIO_get_mem_data(s->s3->handshake_buffer, &hdata); - if (hdatalen <= 0) { + hdatalen = hdatalen_l = + BIO_get_mem_data(s->s3->handshake_buffer, &hdata); + if (hdatalen_l <= 0) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PSK_DO_BINDER, SSL_R_BAD_HANDSHAKE_LENGTH); goto err; diff --git a/ssl/statem/extensions_clnt.c b/ssl/statem/extensions_clnt.c index 4b5e6fe2b87f..ab4dbf67131e 100644 --- a/ssl/statem/extensions_clnt.c +++ b/ssl/statem/extensions_clnt.c @@ -115,7 +115,7 @@ EXT_RETURN tls_construct_ctos_srp(SSL *s, WPACKET *pkt, unsigned int context, #ifndef OPENSSL_NO_EC static int use_ecc(SSL *s) { - int i, end; + int i, end, ret = 0; unsigned long alg_k, alg_a; STACK_OF(SSL_CIPHER) *cipher_stack = NULL; @@ -123,7 +123,7 @@ static int use_ecc(SSL *s) if (s->version == SSL3_VERSION) return 0; - cipher_stack = SSL_get_ciphers(s); + cipher_stack = SSL_get1_supported_ciphers(s); end = sk_SSL_CIPHER_num(cipher_stack); for (i = 0; i < end; i++) { const SSL_CIPHER *c = sk_SSL_CIPHER_value(cipher_stack, i); @@ -132,11 +132,14 @@ static int use_ecc(SSL *s) alg_a = c->algorithm_auth; if ((alg_k & (SSL_kECDHE | SSL_kECDHEPSK)) || (alg_a & SSL_aECDSA) - || c->min_tls >= TLS1_3_VERSION) - return 1; + || c->min_tls >= TLS1_3_VERSION) { + ret = 1; + break; + } } - return 0; + sk_SSL_CIPHER_free(cipher_stack); + return ret; } EXT_RETURN tls_construct_ctos_ec_pt_formats(SSL *s, WPACKET *pkt, diff --git a/ssl/statem/statem.c b/ssl/statem/statem.c index d75f9ea03608..f76c0e48034b 100644 --- a/ssl/statem/statem.c +++ b/ssl/statem/statem.c @@ -118,11 +118,12 @@ void ossl_statem_set_renegotiate(SSL *s) void ossl_statem_fatal(SSL *s, int al, int func, int reason, const char *file, int line) { + ERR_put_error(ERR_LIB_SSL, func, reason, file, line); /* We shouldn't call SSLfatal() twice. Once is enough */ - assert(s->statem.state != MSG_FLOW_ERROR); + if (s->statem.in_init && s->statem.state == MSG_FLOW_ERROR) + return; 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 && s->statem.enc_write_state != ENC_WRITE_STATE_INVALID) ssl3_send_alert(s, SSL3_AL_FATAL, al); diff --git a/ssl/statem/statem_clnt.c b/ssl/statem/statem_clnt.c index 8c658da8990d..0a11b88183e3 100644 --- a/ssl/statem/statem_clnt.c +++ b/ssl/statem/statem_clnt.c @@ -1095,6 +1095,7 @@ WORK_STATE ossl_statem_client_post_process_message(SSL *s, WORK_STATE wst) ERR_R_INTERNAL_ERROR); return WORK_ERROR; + case TLS_ST_CR_CERT_VRFY: case TLS_ST_CR_CERT_REQ: return tls_prepare_client_certificate(s, wst); } @@ -2563,6 +2564,17 @@ MSG_PROCESS_RETURN tls_process_certificate_request(SSL *s, PACKET *pkt) /* we should setup a certificate to return.... */ s->s3->tmp.cert_req = 1; + /* + * In TLSv1.3 we don't prepare the client certificate yet. We wait until + * after the CertificateVerify message has been received. This is because + * in TLSv1.3 the CertificateRequest arrives before the Certificate message + * but in TLSv1.2 it is the other way around. We want to make sure that + * SSL_get_peer_certificate() returns something sensible in + * client_cert_cb. + */ + if (SSL_IS_TLS13(s) && s->post_handshake_auth != SSL_PHA_REQUESTED) + return MSG_PROCESS_CONTINUE_READING; + return MSG_PROCESS_CONTINUE_PROCESSING; } diff --git a/ssl/statem/statem_lib.c b/ssl/statem/statem_lib.c index 508bb88767a7..4324896f500a 100644 --- a/ssl/statem/statem_lib.c +++ b/ssl/statem/statem_lib.c @@ -203,9 +203,10 @@ static int get_cert_verify_tbs_data(SSL *s, unsigned char *tls13tbs, *hdatalen = TLS13_TBS_PREAMBLE_SIZE + hashlen; } else { size_t retlen; + long retlen_l; - retlen = BIO_get_mem_data(s->s3->handshake_buffer, hdata); - if (retlen <= 0) { + retlen = retlen_l = BIO_get_mem_data(s->s3->handshake_buffer, hdata); + if (retlen_l <= 0) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_GET_CERT_VERIFY_TBS_DATA, ERR_R_INTERNAL_ERROR); return 0; @@ -494,7 +495,18 @@ MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt) } } - ret = MSG_PROCESS_CONTINUE_READING; + /* + * In TLSv1.3 on the client side we make sure we prepare the client + * certificate after the CertVerify instead of when we get the + * CertificateRequest. This is because in TLSv1.3 the CertificateRequest + * comes *before* the Certificate message. In TLSv1.2 it comes after. We + * want to make sure that SSL_get_peer_certificate() will return the actual + * server certificate from the client_cert_cb callback. + */ + if (!s->server && SSL_IS_TLS13(s) && s->s3->tmp.cert_req == 1) + ret = MSG_PROCESS_CONTINUE_PROCESSING; + else + ret = MSG_PROCESS_CONTINUE_READING; err: BIO_free(s->s3->handshake_buffer); s->s3->handshake_buffer = NULL; @@ -1495,6 +1507,10 @@ static int ssl_method_error(const SSL *s, const SSL_METHOD *method) static int is_tls13_capable(const SSL *s) { int i; +#ifndef OPENSSL_NO_EC + int curve; + EC_KEY *eckey; +#endif #ifndef OPENSSL_NO_PSK if (s->psk_server_callback != NULL) @@ -1515,8 +1531,25 @@ static int is_tls13_capable(const SSL *s) default: break; } - if (ssl_has_cert(s, i)) + if (!ssl_has_cert(s, i)) + continue; +#ifndef OPENSSL_NO_EC + if (i != SSL_PKEY_ECC) + return 1; + /* + * Prior to TLSv1.3 sig algs allowed any curve to be used. TLSv1.3 is + * more restrictive so check that our sig algs are consistent with this + * EC cert. See section 4.2.3 of RFC8446. + */ + eckey = EVP_PKEY_get0_EC_KEY(s->cert->pkeys[SSL_PKEY_ECC].privatekey); + if (eckey == NULL) + continue; + curve = EC_GROUP_get_curve_name(EC_KEY_get0_group(eckey)); + if (tls_check_sigalg_curve(s, curve)) return 1; +#else + return 1; +#endif } return 0; @@ -2261,10 +2294,24 @@ int parse_ca_names(SSL *s, PACKET *pkt) return 0; } -int construct_ca_names(SSL *s, WPACKET *pkt) +const STACK_OF(X509_NAME) *get_ca_names(SSL *s) { - const STACK_OF(X509_NAME) *ca_sk = SSL_get0_CA_list(s); + const STACK_OF(X509_NAME) *ca_sk = NULL;; + + if (s->server) { + ca_sk = SSL_get_client_CA_list(s); + if (ca_sk != NULL && sk_X509_NAME_num(ca_sk) == 0) + ca_sk = NULL; + } + + if (ca_sk == NULL) + ca_sk = SSL_get0_CA_list(s); + return ca_sk; +} + +int construct_ca_names(SSL *s, const STACK_OF(X509_NAME) *ca_sk, WPACKET *pkt) +{ /* Start sub-packet for client CA list */ if (!WPACKET_start_sub_packet_u16(pkt)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_CONSTRUCT_CA_NAMES, diff --git a/ssl/statem/statem_locl.h b/ssl/statem/statem_locl.h index 25e56e4e8ddf..6b8cf37faa01 100644 --- a/ssl/statem/statem_locl.h +++ b/ssl/statem/statem_locl.h @@ -61,7 +61,8 @@ int create_synthetic_message_hash(SSL *s, const unsigned char *hashval, size_t hashlen, const unsigned char *hrr, size_t hrrlen); int parse_ca_names(SSL *s, PACKET *pkt); -int construct_ca_names(SSL *s, WPACKET *pkt); +const STACK_OF(X509_NAME) *get_ca_names(SSL *s); +int construct_ca_names(SSL *s, const STACK_OF(X509_NAME) *ca_sk, WPACKET *pkt); size_t construct_key_exchange_tbs(SSL *s, unsigned char **ptbs, const void *param, size_t paramlen); diff --git a/ssl/statem/statem_srvr.c b/ssl/statem/statem_srvr.c index 346b1e398916..e7c11c4bea4d 100644 --- a/ssl/statem/statem_srvr.c +++ b/ssl/statem/statem_srvr.c @@ -1519,8 +1519,10 @@ MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, PACKET *pkt) * So check cookie length... */ if (SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE) { - if (clienthello->dtls_cookie_len == 0) + if (clienthello->dtls_cookie_len == 0) { + OPENSSL_free(clienthello); return MSG_PROCESS_FINISHED_READING; + } } } @@ -2056,10 +2058,6 @@ static int tls_early_post_process_client_hello(SSL *s) #else s->session->compress_meth = (comp == NULL) ? 0 : comp->id; #endif - if (!tls1_set_server_sigalgs(s)) { - /* SSLfatal() already called */ - goto err; - } } sk_SSL_CIPHER_free(ciphers); @@ -2227,19 +2225,25 @@ WORK_STATE tls_post_process_client_hello(SSL *s, WORK_STATE wst) if (wst == WORK_MORE_B) { if (!s->hit || SSL_IS_TLS13(s)) { /* Let cert callback update server certificates if required */ - if (!s->hit && s->cert->cert_cb != NULL) { - int rv = s->cert->cert_cb(s, s->cert->cert_cb_arg); - if (rv == 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_POST_PROCESS_CLIENT_HELLO, - SSL_R_CERT_CB_ERROR); - goto err; + if (!s->hit) { + if (s->cert->cert_cb != NULL) { + int rv = s->cert->cert_cb(s, s->cert->cert_cb_arg); + if (rv == 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, + SSL_F_TLS_POST_PROCESS_CLIENT_HELLO, + SSL_R_CERT_CB_ERROR); + goto err; + } + if (rv < 0) { + s->rwstate = SSL_X509_LOOKUP; + return WORK_MORE_B; + } + s->rwstate = SSL_NOTHING; } - if (rv < 0) { - s->rwstate = SSL_X509_LOOKUP; - return WORK_MORE_B; + if (!tls1_set_server_sigalgs(s)) { + /* SSLfatal already called */ + goto err; } - s->rwstate = SSL_NOTHING; } /* In TLSv1.3 we selected the ciphersuite before resumption */ @@ -2876,7 +2880,7 @@ int tls_construct_certificate_request(SSL *s, WPACKET *pkt) } } - if (!construct_ca_names(s, pkt)) { + if (!construct_ca_names(s, get_ca_names(s), pkt)) { /* SSLfatal() already called */ return 0; } @@ -3222,6 +3226,12 @@ static int tls_process_cke_ecdhe(SSL *s, PACKET *pkt) SSL_R_LENGTH_MISMATCH); goto err; } + if (skey == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CKE_ECDHE, + SSL_R_MISSING_TMP_ECDH_KEY); + goto err; + } + ckey = EVP_PKEY_new(); if (ckey == NULL || EVP_PKEY_copy_parameters(ckey, skey) <= 0) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CKE_ECDHE, diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index 156497988a62..fc41ed90e710 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c @@ -343,6 +343,10 @@ int tls1_set_groups(uint16_t **pext, size_t *pextlen, */ unsigned long dup_list = 0; + if (ngroups == 0) { + SSLerr(SSL_F_TLS1_SET_GROUPS, SSL_R_BAD_LENGTH); + return 0; + } if ((glist = OPENSSL_malloc(ngroups * sizeof(*glist))) == NULL) { SSLerr(SSL_F_TLS1_SET_GROUPS, ERR_R_MALLOC_FAILURE); return 0; @@ -945,6 +949,39 @@ size_t tls12_get_psigalgs(SSL *s, int sent, const uint16_t **psigs) } } +#ifndef OPENSSL_NO_EC +/* + * Called by servers only. Checks that we have a sig alg that supports the + * specified EC curve. + */ +int tls_check_sigalg_curve(const SSL *s, int curve) +{ + const uint16_t *sigs; + size_t siglen, i; + + if (s->cert->conf_sigalgs) { + sigs = s->cert->conf_sigalgs; + siglen = s->cert->conf_sigalgslen; + } else { + sigs = tls12_sigalgs; + siglen = OSSL_NELEM(tls12_sigalgs); + } + + for (i = 0; i < siglen; i++) { + const SIGALG_LOOKUP *lu = tls1_lookup_sigalg(sigs[i]); + + if (lu == NULL) + continue; + if (lu->sig == EVP_PKEY_EC + && lu->curve != NID_undef + && curve == lu->curve) + return 1; + } + + return 0; +} +#endif + /* * Check signature algorithm is consistent with sent supported signature * algorithms and if so set relevant digest and signature scheme in @@ -1087,6 +1124,14 @@ int SSL_get_peer_signature_type_nid(const SSL *s, int *pnid) return 1; } +int SSL_get_signature_type_nid(const SSL *s, int *pnid) +{ + if (s->s3->tmp.sigalg == NULL) + return 0; + *pnid = s->s3->tmp.sigalg->sig; + return 1; +} + /* * Set a mask of disabled algorithms: an algorithm is disabled if it isn't * supported, doesn't appear in supported signature algorithms, isn't supported diff --git a/ssl/tls13_enc.c b/ssl/tls13_enc.c index f7ab0fa47040..b6825d20c2dc 100644 --- a/ssl/tls13_enc.c +++ b/ssl/tls13_enc.c @@ -13,7 +13,14 @@ #include <openssl/evp.h> #include <openssl/kdf.h> -#define TLS13_MAX_LABEL_LEN 246 +/* + * RFC 8446, 7.1 Key Schedule, says: + * Note: With common hash functions, any label longer than 12 characters + * requires an additional iteration of the hash function to compute. + * The labels in this specification have all been chosen to fit within + * this limit. + */ +#define TLS13_MAX_LABEL_LEN 12 /* Always filled with zeros */ static const unsigned char default_zeros[EVP_MAX_MD_SIZE]; @@ -29,14 +36,15 @@ int tls13_hkdf_expand(SSL *s, const EVP_MD *md, const unsigned char *secret, const unsigned char *data, size_t datalen, unsigned char *out, size_t outlen) { - const unsigned char label_prefix[] = "tls13 "; + static const unsigned char label_prefix[] = "tls13 "; EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL); int ret; size_t hkdflabellen; size_t hashlen; /* - * 2 bytes for length of whole HkdfLabel + 1 byte for length of combined - * prefix and label + bytes for the label itself + bytes for the hash + * 2 bytes for length of derived secret + 1 byte for length of combined + * prefix and label + bytes for the label itself + 1 byte length of hash + * + bytes for the hash itself */ unsigned char hkdflabel[sizeof(uint16_t) + sizeof(uint8_t) + + sizeof(label_prefix) + TLS13_MAX_LABEL_LEN |