early-access version 2698

This commit is contained in:
pineappleEA
2022-04-24 22:29:35 +02:00
parent c96f949832
commit caa0c2911b
486 changed files with 37806 additions and 14362 deletions

View File

@@ -1,15 +1,10 @@
set(
SSL_SRC
bio_ssl.c
bs_ber.c
bs_cbb.c
bs_cbs.c
d1_both.c
d1_clnt.c
d1_lib.c
d1_pkt.c
d1_srtp.c
d1_srvr.c
pqueue.c
s3_cbc.c
s3_lib.c
@@ -38,14 +33,17 @@ set(
ssl_versions.c
t1_enc.c
t1_lib.c
tls_buffer.c
tls_content.c
tls_key_share.c
tls12_key_schedule.c
tls12_lib.c
tls12_record_layer.c
tls13_buffer.c
tls13_client.c
tls13_error.c
tls13_handshake.c
tls13_handshake_msg.c
tls13_key_schedule.c
tls13_key_share.c
tls13_legacy.c
tls13_lib.c
tls13_record.c
@@ -53,14 +51,34 @@ set(
tls13_server.c
)
add_library(ssl ${SSL_SRC})
target_include_directories(ssl
set(
BS_SRC
bs_ber.c
bs_cbb.c
bs_cbs.c
)
add_library(ssl_obj OBJECT ${SSL_SRC})
target_include_directories(ssl_obj
PRIVATE
.
../crypto/bio
../include/compat
PUBLIC
../include)
add_library(bs_obj OBJECT ${BS_SRC})
target_include_directories(bs_obj
PRIVATE
.
../include/compat)
if(BUILD_SHARED_LIBS)
add_library(ssl $<TARGET_OBJECTS:ssl_obj> $<TARGET_OBJECTS:bs_obj>)
else()
add_library(ssl $<TARGET_OBJECTS:ssl_obj>)
endif()
export_symbol(ssl ${CMAKE_CURRENT_SOURCE_DIR}/ssl.sym)
target_link_libraries(ssl crypto ${PLATFORM_LIBS})
if (WIN32)
@@ -80,3 +98,10 @@ if(ENABLE_LIBRESSL_INSTALL)
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
endif(ENABLE_LIBRESSL_INSTALL)
# build static library for regression test
if(BUILD_SHARED_LIBS)
add_library(ssl-static STATIC $<TARGET_OBJECTS:ssl_obj>)
target_link_libraries(ssl-static crypto-static ${PLATFORM_LIBS})
endif()

View File

@@ -1 +1 @@
48:1:0
52:0:0

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: bio_ssl.c,v 1.29 2018/08/24 20:30:21 tb Exp $ */
/* $OpenBSD: bio_ssl.c,v 1.33 2022/01/14 09:12:53 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -66,6 +66,7 @@
#include <openssl/err.h>
#include <openssl/ssl.h>
#include "bio_local.h"
#include "ssl_locl.h"
static int ssl_write(BIO *h, const char *buf, int num);
@@ -74,7 +75,7 @@ static int ssl_puts(BIO *h, const char *str);
static long ssl_ctrl(BIO *h, int cmd, long arg1, void *arg2);
static int ssl_new(BIO *h);
static int ssl_free(BIO *data);
static long ssl_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
static long ssl_callback_ctrl(BIO *h, int cmd, BIO_info_cb *fp);
typedef struct bio_ssl_st {
SSL *ssl; /* The ssl handle :-) */
/* re-negotiate every time the total number of bytes is this size */
@@ -294,10 +295,10 @@ ssl_ctrl(BIO *b, int cmd, long num, void *ptr)
SSL_shutdown(ssl);
if (ssl->internal->handshake_func ==
ssl->method->internal->ssl_connect)
ssl->method->ssl_connect)
SSL_set_connect_state(ssl);
else if (ssl->internal->handshake_func ==
ssl->method->internal->ssl_accept)
ssl->method->ssl_accept)
SSL_set_accept_state(ssl);
SSL_clear(ssl);
@@ -462,7 +463,7 @@ ssl_ctrl(BIO *b, int cmd, long num, void *ptr)
}
static long
ssl_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
ssl_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp)
{
SSL *ssl;
BIO_SSL *bs;
@@ -509,7 +510,7 @@ BIO_new_buffer_ssl_connect(SSL_CTX *ctx)
goto err;
return (ret);
err:
err:
BIO_free(buf);
BIO_free(ssl);
return (NULL);
@@ -528,7 +529,7 @@ BIO_new_ssl_connect(SSL_CTX *ctx)
goto err;
return (ret);
err:
err:
BIO_free(con);
BIO_free(ssl);
return (NULL);
@@ -553,7 +554,7 @@ BIO_new_ssl(SSL_CTX *ctx, int client)
BIO_set_ssl(ret, ssl, BIO_CLOSE);
return (ret);
err:
err:
BIO_free(ret);
return (NULL);
}

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: bs_ber.c,v 1.9 2016/12/03 12:34:35 jsing Exp $ */
/* $OpenBSD: bs_ber.c,v 1.11 2021/05/16 10:58:27 jsing Exp $ */
/*
* Copyright (c) 2014, Google Inc.
*
@@ -12,12 +12,11 @@
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <string.h>
#include <openssl/opensslconf.h>
#include "bytestring.h"
/*

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: bs_cbb.c,v 1.23 2020/09/16 05:52:04 jsing Exp $ */
/* $OpenBSD: bs_cbb.c,v 1.27 2022/01/06 14:30:30 jsing Exp $ */
/*
* Copyright (c) 2014, Google Inc.
*
@@ -12,13 +12,12 @@
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <stdlib.h>
#include <string.h>
#include <openssl/opensslconf.h>
#include "bytestring.h"
#define CBB_INITIAL_SIZE 64
@@ -277,7 +276,7 @@ CBB_discard_child(CBB *cbb)
return;
cbb->base->len = cbb->offset;
cbb->child->base = NULL;
cbb->child = NULL;
cbb->pending_len_len = 0;
@@ -414,6 +413,19 @@ CBB_add_u32(CBB *cbb, size_t value)
return cbb_add_u(cbb, (uint32_t)value, 4);
}
int
CBB_add_u64(CBB *cbb, uint64_t value)
{
uint32_t a, b;
a = value >> 32;
b = value & 0xffffffff;
if (!CBB_add_u32(cbb, a))
return 0;
return CBB_add_u32(cbb, b);
}
int
CBB_add_asn1_uint64(CBB *cbb, uint64_t value)
{

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: bs_cbs.c,v 1.18 2019/01/23 22:20:40 beck Exp $ */
/* $OpenBSD: bs_cbs.c,v 1.24 2021/12/15 17:36:49 jsing Exp $ */
/*
* Copyright (c) 2014, Google Inc.
*
@@ -12,15 +12,12 @@
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <stdlib.h>
#include <string.h>
#include <openssl/opensslconf.h>
#include <openssl/buffer.h>
#include <openssl/crypto.h>
#include "bytestring.h"
void
@@ -50,6 +47,16 @@ cbs_get(CBS *cbs, const uint8_t **p, size_t n)
return 1;
}
static int
cbs_peek(CBS *cbs, const uint8_t **p, size_t n)
{
if (cbs->len < n)
return 0;
*p = cbs->data;
return 1;
}
size_t
CBS_offset(const CBS *cbs)
{
@@ -98,6 +105,11 @@ int
CBS_strdup(const CBS *cbs, char **out_ptr)
{
free(*out_ptr);
*out_ptr = NULL;
if (CBS_contains_zero_byte(cbs))
return 0;
*out_ptr = strndup((const char *)cbs->data, cbs->len);
return (*out_ptr != NULL);
}
@@ -188,6 +200,34 @@ CBS_get_u32(CBS *cbs, uint32_t *out)
return cbs_get_u(cbs, out, 4);
}
int
CBS_get_u64(CBS *cbs, uint64_t *out)
{
uint32_t a, b;
if (cbs->len < 8)
return 0;
if (!CBS_get_u32(cbs, &a))
return 0;
if (!CBS_get_u32(cbs, &b))
return 0;
*out = (uint64_t)a << 32 | b;
return 1;
}
int
CBS_get_last_u8(CBS *cbs, uint8_t *out)
{
if (cbs->len == 0)
return 0;
*out = cbs->data[cbs->len - 1];
cbs->len--;
return 1;
}
int
CBS_get_bytes(CBS *cbs, CBS *out, size_t len)
{
@@ -229,6 +269,73 @@ CBS_get_u24_length_prefixed(CBS *cbs, CBS *out)
return cbs_get_length_prefixed(cbs, out, 3);
}
static int
cbs_peek_u(CBS *cbs, uint32_t *out, size_t len)
{
uint32_t result = 0;
size_t i;
const uint8_t *data;
if (len < 1 || len > 4)
return 0;
if (!cbs_peek(cbs, &data, len))
return 0;
for (i = 0; i < len; i++) {
result <<= 8;
result |= data[i];
}
*out = result;
return 1;
}
int
CBS_peek_u8(CBS *cbs, uint8_t *out)
{
const uint8_t *v;
if (!cbs_peek(cbs, &v, 1))
return 0;
*out = *v;
return 1;
}
int
CBS_peek_u16(CBS *cbs, uint16_t *out)
{
uint32_t v;
if (!cbs_peek_u(cbs, &v, 2))
return 0;
*out = v;
return 1;
}
int
CBS_peek_u24(CBS *cbs, uint32_t *out)
{
return cbs_peek_u(cbs, out, 3);
}
int
CBS_peek_u32(CBS *cbs, uint32_t *out)
{
return cbs_peek_u(cbs, out, 4);
}
int
CBS_peek_last_u8(CBS *cbs, uint8_t *out)
{
if (cbs->len == 0)
return 0;
*out = cbs->data[cbs->len - 1];
return 1;
}
int
CBS_get_any_asn1_element(CBS *cbs, CBS *out, unsigned int *out_tag,
size_t *out_header_len)

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: bytestring.h,v 1.17 2018/08/16 18:39:37 jsing Exp $ */
/* $OpenBSD: bytestring.h,v 1.23 2022/01/06 14:30:30 jsing Exp $ */
/*
* Copyright (c) 2014, Google Inc.
*
@@ -12,7 +12,8 @@
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef OPENSSL_HEADER_BYTESTRING_H
#define OPENSSL_HEADER_BYTESTRING_H
@@ -20,8 +21,6 @@
#include <sys/types.h>
#include <stdint.h>
#include <openssl/opensslconf.h>
__BEGIN_HIDDEN_DECLS
/*
@@ -134,6 +133,18 @@ int CBS_get_u24(CBS *cbs, uint32_t *out);
*/
int CBS_get_u32(CBS *cbs, uint32_t *out);
/*
* CBS_get_u64 sets |*out| to the next, big-endian uint64_t value from |cbs|
* and advances |cbs|. It returns one on success and zero on error.
*/
int CBS_get_u64(CBS *cbs, uint64_t *out);
/*
* CBS_get_last_u8 sets |*out| to the last uint8_t from |cbs| and shortens
* |cbs|. It returns one on success and zero on error.
*/
int CBS_get_last_u8(CBS *cbs, uint8_t *out);
/*
* CBS_get_bytes sets |*out| to the next |len| bytes from |cbs| and advances
* |cbs|. It returns one on success and zero on error.
@@ -161,6 +172,36 @@ int CBS_get_u16_length_prefixed(CBS *cbs, CBS *out);
*/
int CBS_get_u24_length_prefixed(CBS *cbs, CBS *out);
/*
* CBS_peek_u8 sets |*out| to the next uint8_t from |cbs|, but does not advance
* |cbs|. It returns one on success and zero on error.
*/
int CBS_peek_u8(CBS *cbs, uint8_t *out);
/*
* CBS_peek_u16 sets |*out| to the next, big-endian uint16_t from |cbs|, but
* does not advance |cbs|. It returns one on success and zero on error.
*/
int CBS_peek_u16(CBS *cbs, uint16_t *out);
/*
* CBS_peek_u24 sets |*out| to the next, big-endian 24-bit value from |cbs|, but
* does not advance |cbs|. It returns one on success and zero on error.
*/
int CBS_peek_u24(CBS *cbs, uint32_t *out);
/*
* CBS_peek_u32 sets |*out| to the next, big-endian uint32_t value from |cbs|,
* but does not advance |cbs|. It returns one on success and zero on error.
*/
int CBS_peek_u32(CBS *cbs, uint32_t *out);
/*
* CBS_peek_last_u8 sets |*out| to the last uint8_t from |cbs|, but does not
* shorten |cbs|. It returns one on success and zero on error.
*/
int CBS_peek_last_u8(CBS *cbs, uint8_t *out);
/* Parsing ASN.1 */
@@ -467,6 +508,12 @@ int CBB_add_u24(CBB *cbb, size_t value);
*/
int CBB_add_u32(CBB *cbb, size_t value);
/*
* CBB_add_u64 appends a 64-bit, big-endian number from |value| to |cbb|. It
* returns one on success and zero otherwise.
*/
int CBB_add_u64(CBB *cbb, uint64_t value);
/*
* CBB_add_asn1_uint64 writes an ASN.1 INTEGER into |cbb| using |CBB_add_asn1|
* and writes |value| in its contents. It returns one on success and zero on

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: d1_both.c,v 1.60 2020/09/26 14:43:17 jsing Exp $ */
/* $OpenBSD: d1_both.c,v 1.81 2022/02/05 14:54:10 jsing Exp $ */
/*
* DTLS implementation written by Nagendra Modadugu
* (nagendra@cs.stanford.edu) for the OpenSSL project 2005.
@@ -117,15 +117,15 @@
#include <stdio.h>
#include <string.h>
#include "ssl_locl.h"
#include <openssl/buffer.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/x509.h>
#include "pqueue.h"
#include "bytestring.h"
#include "dtls_locl.h"
#include "pqueue.h"
#include "ssl_locl.h"
#define RSMBLY_BITMASK_SIZE(msg_len) (((msg_len) + 7) / 8)
@@ -148,15 +148,15 @@
if (is_complete) for (ii = (((msg_len) - 1) >> 3) - 1; ii >= 0 ; ii--) \
if (bitmask[ii] != 0xff) { is_complete = 0; break; } }
static unsigned char bitmask_start_values[] = {
static const unsigned char bitmask_start_values[] = {
0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80
};
static unsigned char bitmask_end_values[] = {
static const unsigned char bitmask_end_values[] = {
0xff, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f
};
/* XDTLS: figure out the right values */
static unsigned int g_probable_mtu[] = {1500 - 28, 512 - 28, 256 - 28};
static const unsigned int g_probable_mtu[] = {1500 - 28, 512 - 28, 256 - 28};
static unsigned int dtls1_guess_mtu(unsigned int curr_mtu);
static void dtls1_fix_message_header(SSL *s, unsigned long frag_off,
@@ -201,12 +201,6 @@ dtls1_hm_fragment_free(hm_fragment *frag)
if (frag == NULL)
return;
if (frag->msg_header.is_ccs) {
EVP_CIPHER_CTX_free(
frag->msg_header.saved_retransmit_state.enc_write_ctx);
EVP_MD_CTX_free(
frag->msg_header.saved_retransmit_state.write_hash);
}
free(frag->fragment);
free(frag->reassembly);
free(frag);
@@ -218,12 +212,13 @@ dtls1_do_write(SSL *s, int type)
{
int ret;
int curr_mtu;
unsigned int len, frag_off, mac_size, blocksize;
unsigned int len, frag_off;
size_t overhead;
/* AHA! Figure out the MTU, and stick to the right size */
if (D1I(s)->mtu < dtls1_min_mtu() &&
if (s->d1->mtu < dtls1_min_mtu() &&
!(SSL_get_options(s) & SSL_OP_NO_QUERY_MTU)) {
D1I(s)->mtu = BIO_ctrl(SSL_get_wbio(s),
s->d1->mtu = BIO_ctrl(SSL_get_wbio(s),
BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL);
/*
@@ -231,44 +226,36 @@ dtls1_do_write(SSL *s, int type)
* doesn't know the MTU (ie., the initial write), so just
* make sure we have a reasonable number
*/
if (D1I(s)->mtu < dtls1_min_mtu()) {
D1I(s)->mtu = 0;
D1I(s)->mtu = dtls1_guess_mtu(D1I(s)->mtu);
if (s->d1->mtu < dtls1_min_mtu()) {
s->d1->mtu = 0;
s->d1->mtu = dtls1_guess_mtu(s->d1->mtu);
BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SET_MTU,
D1I(s)->mtu, NULL);
s->d1->mtu, NULL);
}
}
OPENSSL_assert(D1I(s)->mtu >= dtls1_min_mtu());
OPENSSL_assert(s->d1->mtu >= dtls1_min_mtu());
/* should have something reasonable now */
if (s->internal->init_off == 0 && type == SSL3_RT_HANDSHAKE)
OPENSSL_assert(s->internal->init_num ==
(int)D1I(s)->w_msg_hdr.msg_len + DTLS1_HM_HEADER_LENGTH);
(int)s->d1->w_msg_hdr.msg_len + DTLS1_HM_HEADER_LENGTH);
if (s->internal->write_hash)
mac_size = EVP_MD_CTX_size(s->internal->write_hash);
else
mac_size = 0;
if (s->internal->enc_write_ctx &&
(EVP_CIPHER_mode( s->internal->enc_write_ctx->cipher) & EVP_CIPH_CBC_MODE))
blocksize = 2 * EVP_CIPHER_block_size(s->internal->enc_write_ctx->cipher);
else
blocksize = 0;
if (!tls12_record_layer_write_overhead(s->internal->rl, &overhead))
return -1;
frag_off = 0;
while (s->internal->init_num) {
curr_mtu = D1I(s)->mtu - BIO_wpending(SSL_get_wbio(s)) -
DTLS1_RT_HEADER_LENGTH - mac_size - blocksize;
curr_mtu = s->d1->mtu - BIO_wpending(SSL_get_wbio(s)) -
DTLS1_RT_HEADER_LENGTH - overhead;
if (curr_mtu <= DTLS1_HM_HEADER_LENGTH) {
/* grr.. we could get an error if MTU picked was wrong */
ret = BIO_flush(SSL_get_wbio(s));
if (ret <= 0)
return ret;
curr_mtu = D1I(s)->mtu - DTLS1_RT_HEADER_LENGTH -
mac_size - blocksize;
curr_mtu = s->d1->mtu - DTLS1_RT_HEADER_LENGTH -
overhead;
}
if (s->internal->init_num > curr_mtu)
@@ -276,7 +263,6 @@ dtls1_do_write(SSL *s, int type)
else
len = s->internal->init_num;
/* XDTLS: this function is too long. split out the CCS part */
if (type == SSL3_RT_HANDSHAKE) {
if (s->internal->init_off != 0) {
@@ -293,8 +279,8 @@ dtls1_do_write(SSL *s, int type)
dtls1_fix_message_header(s, frag_off,
len - DTLS1_HM_HEADER_LENGTH);
if (!dtls1_write_message_header(&D1I(s)->w_msg_hdr,
D1I(s)->w_msg_hdr.frag_off, D1I(s)->w_msg_hdr.frag_len,
if (!dtls1_write_message_header(&s->d1->w_msg_hdr,
s->d1->w_msg_hdr.frag_off, s->d1->w_msg_hdr.frag_len,
(unsigned char *)&s->internal->init_buf->data[s->internal->init_off]))
return -1;
@@ -313,7 +299,7 @@ dtls1_do_write(SSL *s, int type)
*/
if (BIO_ctrl(SSL_get_wbio(s),
BIO_CTRL_DGRAM_MTU_EXCEEDED, 0, NULL) > 0)
D1I(s)->mtu = BIO_ctrl(SSL_get_wbio(s),
s->d1->mtu = BIO_ctrl(SSL_get_wbio(s),
BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL);
else
return (-1);
@@ -327,14 +313,14 @@ dtls1_do_write(SSL *s, int type)
OPENSSL_assert(len == (unsigned int)ret);
if (type == SSL3_RT_HANDSHAKE &&
!D1I(s)->retransmitting) {
!s->d1->retransmitting) {
/*
* Should not be done for 'Hello Request's,
* but in that case we'll ignore the result
* anyway
*/
unsigned char *p = (unsigned char *)&s->internal->init_buf->data[s->internal->init_off];
const struct hm_header_st *msg_hdr = &D1I(s)->w_msg_hdr;
const struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr;
int xlen;
if (frag_off == 0) {
@@ -382,40 +368,39 @@ dtls1_do_write(SSL *s, int type)
* Read an entire handshake message. Handshake messages arrive in
* fragments.
*/
long
dtls1_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok)
int
dtls1_get_message(SSL *s, int st1, int stn, int mt, long max)
{
int i, al;
struct hm_header_st *msg_hdr;
unsigned char *p;
unsigned long msg_len;
int i, al, ok;
/*
* s3->internal->tmp is used to store messages that are unexpected, caused
* by the absence of an optional handshake message
*/
if (S3I(s)->tmp.reuse_message) {
S3I(s)->tmp.reuse_message = 0;
if ((mt >= 0) && (S3I(s)->tmp.message_type != mt)) {
if (s->s3->hs.tls12.reuse_message) {
s->s3->hs.tls12.reuse_message = 0;
if ((mt >= 0) && (s->s3->hs.tls12.message_type != mt)) {
al = SSL_AD_UNEXPECTED_MESSAGE;
SSLerror(s, SSL_R_UNEXPECTED_MESSAGE);
goto f_err;
goto fatal_err;
}
*ok = 1;
s->internal->init_msg = s->internal->init_buf->data + DTLS1_HM_HEADER_LENGTH;
s->internal->init_num = (int)S3I(s)->tmp.message_size;
return s->internal->init_num;
s->internal->init_num = (int)s->s3->hs.tls12.message_size;
return 1;
}
msg_hdr = &D1I(s)->r_msg_hdr;
msg_hdr = &s->d1->r_msg_hdr;
memset(msg_hdr, 0, sizeof(struct hm_header_st));
again:
i = dtls1_get_message_fragment(s, st1, stn, max, ok);
again:
i = dtls1_get_message_fragment(s, st1, stn, max, &ok);
if (i == DTLS1_HM_BAD_FRAGMENT ||
i == DTLS1_HM_FRAGMENT_RETRY) /* bad fragment received */
goto again;
else if (i <= 0 && !*ok)
else if (i <= 0 && !ok)
return i;
p = (unsigned char *)s->internal->init_buf->data;
@@ -435,19 +420,17 @@ again:
memset(msg_hdr, 0, sizeof(struct hm_header_st));
/* Don't change sequence numbers while listening */
if (!D1I(s)->listen)
D1I(s)->handshake_read_seq++;
if (!s->d1->listen)
s->d1->handshake_read_seq++;
s->internal->init_msg = s->internal->init_buf->data + DTLS1_HM_HEADER_LENGTH;
return s->internal->init_num;
return 1;
f_err:
fatal_err:
ssl3_send_alert(s, SSL3_AL_FATAL, al);
*ok = 0;
return -1;
}
static int
dtls1_preprocess_fragment(SSL *s, struct hm_header_st *msg_hdr, int max)
{
@@ -468,7 +451,7 @@ dtls1_preprocess_fragment(SSL *s, struct hm_header_st *msg_hdr, int max)
return SSL_AD_ILLEGAL_PARAMETER;
}
if ( D1I(s)->r_msg_hdr.frag_off == 0) /* first fragment */
if ( s->d1->r_msg_hdr.frag_off == 0) /* first fragment */
{
/*
* msg_len is limited to 2^24, but is effectively checked
@@ -480,12 +463,12 @@ dtls1_preprocess_fragment(SSL *s, struct hm_header_st *msg_hdr, int max)
return SSL_AD_INTERNAL_ERROR;
}
S3I(s)->tmp.message_size = msg_len;
D1I(s)->r_msg_hdr.msg_len = msg_len;
S3I(s)->tmp.message_type = msg_hdr->type;
D1I(s)->r_msg_hdr.type = msg_hdr->type;
D1I(s)->r_msg_hdr.seq = msg_hdr->seq;
} else if (msg_len != D1I(s)->r_msg_hdr.msg_len) {
s->s3->hs.tls12.message_size = msg_len;
s->d1->r_msg_hdr.msg_len = msg_len;
s->s3->hs.tls12.message_type = msg_hdr->type;
s->d1->r_msg_hdr.type = msg_hdr->type;
s->d1->r_msg_hdr.seq = msg_hdr->seq;
} else if (msg_len != s->d1->r_msg_hdr.msg_len) {
/*
* They must be playing with us! BTW, failure to enforce
* upper limit would open possibility for buffer overrun.
@@ -511,7 +494,7 @@ dtls1_retrieve_buffered_fragment(SSL *s, long max, int *ok)
int al;
*ok = 0;
item = pqueue_peek(D1I(s)->buffered_messages);
item = pqueue_peek(s->d1->buffered_messages);
if (item == NULL)
return 0;
@@ -521,9 +504,9 @@ dtls1_retrieve_buffered_fragment(SSL *s, long max, int *ok)
if (frag->reassembly != NULL)
return 0;
if (D1I(s)->handshake_read_seq == frag->msg_header.seq) {
if (s->d1->handshake_read_seq == frag->msg_header.seq) {
unsigned long frag_len = frag->msg_header.frag_len;
pqueue_pop(D1I(s)->buffered_messages);
pqueue_pop(s->d1->buffered_messages);
al = dtls1_preprocess_fragment(s, &frag->msg_header, max);
@@ -588,7 +571,7 @@ dtls1_reassemble_fragment(SSL *s, struct hm_header_st* msg_hdr, int *ok)
memset(seq64be, 0, sizeof(seq64be));
seq64be[6] = (unsigned char)(msg_hdr->seq >> 8);
seq64be[7] = (unsigned char)msg_hdr->seq;
item = pqueue_find(D1I(s)->buffered_messages, seq64be);
item = pqueue_find(s->d1->buffered_messages, seq64be);
if (item == NULL) {
frag = dtls1_hm_fragment_new(msg_hdr->msg_len, 1);
@@ -614,7 +597,7 @@ dtls1_reassemble_fragment(SSL *s, struct hm_header_st* msg_hdr, int *ok)
unsigned char devnull [256];
while (frag_len) {
i = s->method->internal->ssl_read_bytes(s, SSL3_RT_HANDSHAKE,
i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE,
devnull, frag_len > sizeof(devnull) ?
sizeof(devnull) : frag_len, 0);
if (i <= 0)
@@ -626,7 +609,7 @@ dtls1_reassemble_fragment(SSL *s, struct hm_header_st* msg_hdr, int *ok)
}
/* read the body of the fragment (header has already been read */
i = s->method->internal->ssl_read_bytes(s, SSL3_RT_HANDSHAKE,
i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE,
frag->fragment + msg_hdr->frag_off, frag_len, 0);
if (i <= 0 || (unsigned long)i != frag_len)
goto err;
@@ -653,12 +636,12 @@ dtls1_reassemble_fragment(SSL *s, struct hm_header_st* msg_hdr, int *ok)
goto err;
}
pqueue_insert(D1I(s)->buffered_messages, item);
pqueue_insert(s->d1->buffered_messages, item);
}
return DTLS1_HM_FRAGMENT_RETRY;
err:
err:
if (item == NULL && frag != NULL)
dtls1_hm_fragment_free(frag);
*ok = 0;
@@ -682,7 +665,7 @@ dtls1_process_out_of_seq_message(SSL *s, struct hm_header_st* msg_hdr, int *ok)
memset(seq64be, 0, sizeof(seq64be));
seq64be[6] = (unsigned char) (msg_hdr->seq >> 8);
seq64be[7] = (unsigned char) msg_hdr->seq;
item = pqueue_find(D1I(s)->buffered_messages, seq64be);
item = pqueue_find(s->d1->buffered_messages, seq64be);
/*
* If we already have an entry and this one is a fragment,
@@ -697,14 +680,14 @@ dtls1_process_out_of_seq_message(SSL *s, struct hm_header_st* msg_hdr, int *ok)
* a FINISHED before the SERVER_HELLO, which then must be a stale
* retransmit.
*/
if (msg_hdr->seq <= D1I(s)->handshake_read_seq ||
msg_hdr->seq > D1I(s)->handshake_read_seq + 10 || item != NULL ||
(D1I(s)->handshake_read_seq == 0 &&
if (msg_hdr->seq <= s->d1->handshake_read_seq ||
msg_hdr->seq > s->d1->handshake_read_seq + 10 || item != NULL ||
(s->d1->handshake_read_seq == 0 &&
msg_hdr->type == SSL3_MT_FINISHED)) {
unsigned char devnull [256];
while (frag_len) {
i = s->method->internal->ssl_read_bytes(s, SSL3_RT_HANDSHAKE,
i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE,
devnull, frag_len > sizeof(devnull) ?
sizeof(devnull) : frag_len, 0);
if (i <= 0)
@@ -726,7 +709,7 @@ dtls1_process_out_of_seq_message(SSL *s, struct hm_header_st* msg_hdr, int *ok)
if (frag_len) {
/* read the body of the fragment (header has already been read */
i = s->method->internal->ssl_read_bytes(s, SSL3_RT_HANDSHAKE,
i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE,
frag->fragment, frag_len, 0);
if (i <= 0 || (unsigned long)i != frag_len)
goto err;
@@ -740,12 +723,12 @@ dtls1_process_out_of_seq_message(SSL *s, struct hm_header_st* msg_hdr, int *ok)
if (item == NULL)
goto err;
pqueue_insert(D1I(s)->buffered_messages, item);
pqueue_insert(s->d1->buffered_messages, item);
}
return DTLS1_HM_FRAGMENT_RETRY;
err:
err:
if (item == NULL && frag != NULL)
dtls1_hm_fragment_free(frag);
*ok = 0;
@@ -758,10 +741,11 @@ dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, int *ok)
{
unsigned char wire[DTLS1_HM_HEADER_LENGTH];
unsigned long len, frag_off, frag_len;
int i, al;
struct hm_header_st msg_hdr;
int i, al;
CBS cbs;
again:
again:
/* see if we have the required fragment already */
if ((frag_len = dtls1_retrieve_buffered_fragment(s, max, ok)) || *ok) {
if (*ok)
@@ -770,21 +754,21 @@ again:
}
/* read handshake message header */
i = s->method->internal->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, wire,
i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, wire,
DTLS1_HM_HEADER_LENGTH, 0);
if (i <= 0) /* nbio, or an error */
{
if (i <= 0) {
/* nbio, or an error */
s->internal->rwstate = SSL_READING;
*ok = 0;
return i;
}
/* Handshake fails if message header is incomplete */
if (i != DTLS1_HM_HEADER_LENGTH ||
/* parse the message fragment header */
dtls1_get_message_header(wire, &msg_hdr) == 0) {
CBS_init(&cbs, wire, i);
if (!dtls1_get_message_header(&cbs, &msg_hdr)) {
/* Handshake fails if message header is incomplete. */
al = SSL_AD_UNEXPECTED_MESSAGE;
SSLerror(s, SSL_R_UNEXPECTED_MESSAGE);
goto f_err;
goto fatal_err;
}
/*
@@ -793,8 +777,8 @@ again:
* While listening, we accept seq 1 (ClientHello with cookie)
* although we're still expecting seq 0 (ClientHello)
*/
if (msg_hdr.seq != D1I(s)->handshake_read_seq &&
!(D1I(s)->listen && msg_hdr.seq == 1))
if (msg_hdr.seq != s->d1->handshake_read_seq &&
!(s->d1->listen && msg_hdr.seq == 1))
return dtls1_process_out_of_seq_message(s, &msg_hdr, ok);
len = msg_hdr.msg_len;
@@ -804,7 +788,7 @@ again:
if (frag_len && frag_len < len)
return dtls1_reassemble_fragment(s, &msg_hdr, ok);
if (!s->server && D1I(s)->r_msg_hdr.frag_off == 0 &&
if (!s->server && s->d1->r_msg_hdr.frag_off == 0 &&
wire[0] == SSL3_MT_HELLO_REQUEST) {
/*
* The server may always send 'Hello Request' messages --
@@ -826,20 +810,20 @@ again:
{
al = SSL_AD_UNEXPECTED_MESSAGE;
SSLerror(s, SSL_R_UNEXPECTED_MESSAGE);
goto f_err;
goto fatal_err;
}
}
if ((al = dtls1_preprocess_fragment(s, &msg_hdr, max)))
goto f_err;
goto fatal_err;
/* XDTLS: ressurect this when restart is in place */
S3I(s)->hs.state = stn;
s->s3->hs.state = stn;
if (frag_len > 0) {
unsigned char *p = (unsigned char *)s->internal->init_buf->data + DTLS1_HM_HEADER_LENGTH;
i = s->method->internal->ssl_read_bytes(s, SSL3_RT_HANDSHAKE,
i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE,
&p[frag_off], frag_len, 0);
/* XDTLS: fix this--message fragments cannot span multiple packets */
if (i <= 0) {
@@ -855,13 +839,11 @@ again:
* handshake to fail
*/
if (i != (int)frag_len) {
al = SSL3_AD_ILLEGAL_PARAMETER;
SSLerror(s, SSL3_AD_ILLEGAL_PARAMETER);
goto f_err;
al = SSL_AD_ILLEGAL_PARAMETER;
SSLerror(s, SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER);
goto fatal_err;
}
*ok = 1;
/*
* Note that s->internal->init_num is *not* used as current offset in
* s->internal->init_buf->data, but as a counter summing up fragments'
@@ -869,9 +851,10 @@ again:
* length, we assume we have got all the fragments.
*/
s->internal->init_num = frag_len;
*ok = 1;
return frag_len;
f_err:
fatal_err:
ssl3_send_alert(s, SSL3_AL_FATAL, al);
s->internal->init_num = 0;
@@ -973,27 +956,21 @@ dtls1_buffer_message(SSL *s, int is_ccs)
memcpy(frag->fragment, s->internal->init_buf->data, s->internal->init_num);
if (is_ccs) {
OPENSSL_assert(D1I(s)->w_msg_hdr.msg_len +
((s->version == DTLS1_VERSION) ?
DTLS1_CCS_HEADER_LENGTH : 3) == (unsigned int)s->internal->init_num);
} else {
OPENSSL_assert(D1I(s)->w_msg_hdr.msg_len +
DTLS1_HM_HEADER_LENGTH == (unsigned int)s->internal->init_num);
}
OPENSSL_assert(s->d1->w_msg_hdr.msg_len +
(is_ccs ? DTLS1_CCS_HEADER_LENGTH : DTLS1_HM_HEADER_LENGTH) ==
(unsigned int)s->internal->init_num);
frag->msg_header.msg_len = D1I(s)->w_msg_hdr.msg_len;
frag->msg_header.seq = D1I(s)->w_msg_hdr.seq;
frag->msg_header.type = D1I(s)->w_msg_hdr.type;
frag->msg_header.msg_len = s->d1->w_msg_hdr.msg_len;
frag->msg_header.seq = s->d1->w_msg_hdr.seq;
frag->msg_header.type = s->d1->w_msg_hdr.type;
frag->msg_header.frag_off = 0;
frag->msg_header.frag_len = D1I(s)->w_msg_hdr.msg_len;
frag->msg_header.frag_len = s->d1->w_msg_hdr.msg_len;
frag->msg_header.is_ccs = is_ccs;
/* save current state*/
frag->msg_header.saved_retransmit_state.enc_write_ctx = s->internal->enc_write_ctx;
frag->msg_header.saved_retransmit_state.write_hash = s->internal->write_hash;
frag->msg_header.saved_retransmit_state.session = s->session;
frag->msg_header.saved_retransmit_state.epoch = D1I(s)->w_epoch;
frag->msg_header.saved_retransmit_state.epoch =
tls12_record_layer_write_epoch(s->internal->rl);
memset(seq64be, 0, sizeof(seq64be));
seq64be[6] = (unsigned char)(dtls1_get_queue_priority(
@@ -1022,7 +999,6 @@ dtls1_retransmit_message(SSL *s, unsigned short seq, unsigned long frag_off,
unsigned long header_length;
unsigned char seq64be[8];
struct dtls1_retransmit_state saved_state;
unsigned char save_write_sequence[8];
/*
OPENSSL_assert(s->internal->init_num == 0);
@@ -1060,45 +1036,27 @@ dtls1_retransmit_message(SSL *s, unsigned short seq, unsigned long frag_off,
frag->msg_header.frag_len);
/* save current state */
saved_state.enc_write_ctx = s->internal->enc_write_ctx;
saved_state.write_hash = s->internal->write_hash;
saved_state.session = s->session;
saved_state.epoch = D1I(s)->w_epoch;
saved_state.epoch = tls12_record_layer_write_epoch(s->internal->rl);
D1I(s)->retransmitting = 1;
s->d1->retransmitting = 1;
/* restore state in which the message was originally sent */
s->internal->enc_write_ctx = frag->msg_header.saved_retransmit_state.enc_write_ctx;
s->internal->write_hash = frag->msg_header.saved_retransmit_state.write_hash;
s->session = frag->msg_header.saved_retransmit_state.session;
D1I(s)->w_epoch = frag->msg_header.saved_retransmit_state.epoch;
if (frag->msg_header.saved_retransmit_state.epoch ==
saved_state.epoch - 1) {
memcpy(save_write_sequence, S3I(s)->write_sequence,
sizeof(S3I(s)->write_sequence));
memcpy(S3I(s)->write_sequence, D1I(s)->last_write_sequence,
sizeof(S3I(s)->write_sequence));
}
if (!tls12_record_layer_use_write_epoch(s->internal->rl,
frag->msg_header.saved_retransmit_state.epoch))
return 0;
ret = dtls1_do_write(s, frag->msg_header.is_ccs ?
SSL3_RT_CHANGE_CIPHER_SPEC : SSL3_RT_HANDSHAKE);
/* restore current state */
s->internal->enc_write_ctx = saved_state.enc_write_ctx;
s->internal->write_hash = saved_state.write_hash;
s->session = saved_state.session;
D1I(s)->w_epoch = saved_state.epoch;
if (!tls12_record_layer_use_write_epoch(s->internal->rl,
saved_state.epoch))
return 0;
if (frag->msg_header.saved_retransmit_state.epoch ==
saved_state.epoch - 1) {
memcpy(D1I(s)->last_write_sequence, S3I(s)->write_sequence,
sizeof(S3I(s)->write_sequence));
memcpy(S3I(s)->write_sequence, save_write_sequence,
sizeof(S3I(s)->write_sequence));
}
D1I(s)->retransmitting = 0;
s->d1->retransmitting = 0;
(void)BIO_flush(SSL_get_wbio(s));
return ret;
@@ -1108,11 +1066,16 @@ dtls1_retransmit_message(SSL *s, unsigned short seq, unsigned long frag_off,
void
dtls1_clear_record_buffer(SSL *s)
{
hm_fragment *frag;
pitem *item;
for(item = pqueue_pop(s->d1->sent_messages); item != NULL;
item = pqueue_pop(s->d1->sent_messages)) {
dtls1_hm_fragment_free((hm_fragment *)item->data);
frag = item->data;
if (frag->msg_header.is_ccs)
tls12_record_layer_write_epoch_done(s->internal->rl,
frag->msg_header.saved_retransmit_state.epoch);
dtls1_hm_fragment_free(frag);
pitem_free(item);
}
}
@@ -1122,12 +1085,12 @@ dtls1_set_message_header(SSL *s, unsigned char mt, unsigned long len,
unsigned long frag_off, unsigned long frag_len)
{
/* Don't change sequence numbers while listening */
if (frag_off == 0 && !D1I(s)->listen) {
D1I(s)->handshake_write_seq = D1I(s)->next_handshake_write_seq;
D1I(s)->next_handshake_write_seq++;
if (frag_off == 0 && !s->d1->listen) {
s->d1->handshake_write_seq = s->d1->next_handshake_write_seq;
s->d1->next_handshake_write_seq++;
}
dtls1_set_message_header_int(s, mt, len, D1I(s)->handshake_write_seq,
dtls1_set_message_header_int(s, mt, len, s->d1->handshake_write_seq,
frag_off, frag_len);
}
@@ -1136,7 +1099,7 @@ void
dtls1_set_message_header_int(SSL *s, unsigned char mt, unsigned long len,
unsigned short seq_num, unsigned long frag_off, unsigned long frag_len)
{
struct hm_header_st *msg_hdr = &D1I(s)->w_msg_hdr;
struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr;
msg_hdr->type = mt;
msg_hdr->msg_len = len;
@@ -1148,7 +1111,7 @@ dtls1_set_message_header_int(SSL *s, unsigned char mt, unsigned long len,
static void
dtls1_fix_message_header(SSL *s, unsigned long frag_off, unsigned long frag_len)
{
struct hm_header_st *msg_hdr = &D1I(s)->w_msg_hdr;
struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr;
msg_hdr->frag_off = frag_off;
msg_hdr->frag_len = frag_len;
@@ -1206,26 +1169,23 @@ dtls1_guess_mtu(unsigned int curr_mtu)
}
int
dtls1_get_message_header(unsigned char *data, struct hm_header_st *msg_hdr)
dtls1_get_message_header(CBS *header, struct hm_header_st *msg_hdr)
{
CBS header;
uint32_t msg_len, frag_off, frag_len;
uint16_t seq;
uint8_t type;
CBS_init(&header, data, sizeof(*msg_hdr));
memset(msg_hdr, 0, sizeof(*msg_hdr));
if (!CBS_get_u8(&header, &type))
if (!CBS_get_u8(header, &type))
return 0;
if (!CBS_get_u24(&header, &msg_len))
if (!CBS_get_u24(header, &msg_len))
return 0;
if (!CBS_get_u16(&header, &seq))
if (!CBS_get_u16(header, &seq))
return 0;
if (!CBS_get_u24(&header, &frag_off))
if (!CBS_get_u24(header, &frag_off))
return 0;
if (!CBS_get_u24(&header, &frag_len))
if (!CBS_get_u24(header, &frag_len))
return 0;
msg_hdr->type = type;
@@ -1236,11 +1196,3 @@ dtls1_get_message_header(unsigned char *data, struct hm_header_st *msg_hdr)
return 1;
}
void
dtls1_get_ccs_header(unsigned char *data, struct ccs_header_st *ccs_hdr)
{
memset(ccs_hdr, 0, sizeof(struct ccs_header_st));
ccs_hdr->type = *(data++);
}

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: d1_lib.c,v 1.50 2020/09/26 14:43:17 jsing Exp $ */
/* $OpenBSD: d1_lib.c,v 1.61 2021/10/23 13:36:03 jsing Exp $ */
/*
* DTLS implementation written by Nagendra Modadugu
* (nagendra@cs.stanford.edu) for the OpenSSL project 2005.
@@ -67,6 +67,7 @@
#include <openssl/objects.h>
#include "dtls_locl.h"
#include "pqueue.h"
#include "ssl_locl.h"
@@ -74,10 +75,6 @@ void dtls1_hm_fragment_free(hm_fragment *frag);
static int dtls1_listen(SSL *s, struct sockaddr *client);
SSL3_ENC_METHOD DTLSv1_enc_data = {
.enc_flags = SSL_ENC_FLAG_EXPLICIT_IV,
};
int
dtls1_new(SSL *s)
{
@@ -86,24 +83,20 @@ dtls1_new(SSL *s)
if ((s->d1 = calloc(1, sizeof(*s->d1))) == NULL)
goto err;
if ((s->d1->internal = calloc(1, sizeof(*s->d1->internal))) == NULL)
goto err;
if ((s->d1->internal->unprocessed_rcds.q = pqueue_new()) == NULL)
if ((s->d1->unprocessed_rcds.q = pqueue_new()) == NULL)
goto err;
if ((s->d1->internal->processed_rcds.q = pqueue_new()) == NULL)
goto err;
if ((s->d1->internal->buffered_messages = pqueue_new()) == NULL)
if ((s->d1->buffered_messages = pqueue_new()) == NULL)
goto err;
if ((s->d1->sent_messages = pqueue_new()) == NULL)
goto err;
if ((s->d1->internal->buffered_app_data.q = pqueue_new()) == NULL)
if ((s->d1->buffered_app_data.q = pqueue_new()) == NULL)
goto err;
if (s->server)
s->d1->internal->cookie_len = sizeof(D1I(s)->cookie);
s->d1->cookie_len = sizeof(s->d1->cookie);
s->method->internal->ssl_clear(s);
s->method->ssl_clear(s);
return (1);
err:
@@ -145,11 +138,10 @@ dtls1_drain_fragments(pqueue queue)
static void
dtls1_clear_queues(SSL *s)
{
dtls1_drain_records(D1I(s)->unprocessed_rcds.q);
dtls1_drain_records(D1I(s)->processed_rcds.q);
dtls1_drain_fragments(D1I(s)->buffered_messages);
dtls1_drain_records(s->d1->unprocessed_rcds.q);
dtls1_drain_fragments(s->d1->buffered_messages);
dtls1_drain_fragments(s->d1->sent_messages);
dtls1_drain_records(D1I(s)->buffered_app_data.q);
dtls1_drain_records(s->d1->buffered_app_data.q);
}
void
@@ -160,59 +152,55 @@ dtls1_free(SSL *s)
ssl3_free(s);
if (s->d1 == NULL)
return;
dtls1_clear_queues(s);
pqueue_free(D1I(s)->unprocessed_rcds.q);
pqueue_free(D1I(s)->processed_rcds.q);
pqueue_free(D1I(s)->buffered_messages);
pqueue_free(s->d1->unprocessed_rcds.q);
pqueue_free(s->d1->buffered_messages);
pqueue_free(s->d1->sent_messages);
pqueue_free(D1I(s)->buffered_app_data.q);
pqueue_free(s->d1->buffered_app_data.q);
freezero(s->d1->internal, sizeof(*s->d1->internal));
freezero(s->d1, sizeof(*s->d1));
s->d1 = NULL;
}
void
dtls1_clear(SSL *s)
{
struct dtls1_state_internal_st *internal;
pqueue unprocessed_rcds;
pqueue processed_rcds;
pqueue buffered_messages;
pqueue sent_messages;
pqueue buffered_app_data;
unsigned int mtu;
if (s->d1) {
unprocessed_rcds = D1I(s)->unprocessed_rcds.q;
processed_rcds = D1I(s)->processed_rcds.q;
buffered_messages = D1I(s)->buffered_messages;
unprocessed_rcds = s->d1->unprocessed_rcds.q;
buffered_messages = s->d1->buffered_messages;
sent_messages = s->d1->sent_messages;
buffered_app_data = D1I(s)->buffered_app_data.q;
mtu = D1I(s)->mtu;
buffered_app_data = s->d1->buffered_app_data.q;
mtu = s->d1->mtu;
dtls1_clear_queues(s);
memset(s->d1->internal, 0, sizeof(*s->d1->internal));
internal = s->d1->internal;
memset(s->d1, 0, sizeof(*s->d1));
s->d1->internal = internal;
s->d1->unprocessed_rcds.epoch =
tls12_record_layer_read_epoch(s->internal->rl) + 1;
if (s->server) {
D1I(s)->cookie_len = sizeof(D1I(s)->cookie);
s->d1->cookie_len = sizeof(s->d1->cookie);
}
if (SSL_get_options(s) & SSL_OP_NO_QUERY_MTU) {
D1I(s)->mtu = mtu;
s->d1->mtu = mtu;
}
D1I(s)->unprocessed_rcds.q = unprocessed_rcds;
D1I(s)->processed_rcds.q = processed_rcds;
D1I(s)->buffered_messages = buffered_messages;
s->d1->unprocessed_rcds.q = unprocessed_rcds;
s->d1->buffered_messages = buffered_messages;
s->d1->sent_messages = sent_messages;
D1I(s)->buffered_app_data.q = buffered_app_data;
s->d1->buffered_app_data.q = buffered_app_data;
}
ssl3_clear(s);
@@ -255,14 +243,15 @@ dtls1_ctrl(SSL *s, int cmd, long larg, void *parg)
const SSL_CIPHER *
dtls1_get_cipher(unsigned int u)
{
const SSL_CIPHER *ciph = ssl3_get_cipher(u);
const SSL_CIPHER *cipher;
if (ciph != NULL) {
if (ciph->algorithm_enc == SSL_RC4)
return NULL;
}
if ((cipher = ssl3_get_cipher(u)) == NULL)
return NULL;
return ciph;
if (cipher->algorithm_enc == SSL_RC4)
return NULL;
return cipher;
}
void
@@ -357,7 +346,7 @@ void
dtls1_stop_timer(SSL *s)
{
/* Reset everything */
memset(&(D1I(s)->timeout), 0, sizeof(struct dtls1_timeout_st));
memset(&(s->d1->timeout), 0, sizeof(struct dtls1_timeout_st));
memset(&(s->d1->next_timeout), 0, sizeof(struct timeval));
s->d1->timeout_duration = 1;
BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0,
@@ -369,16 +358,16 @@ dtls1_stop_timer(SSL *s)
int
dtls1_check_timeout_num(SSL *s)
{
D1I(s)->timeout.num_alerts++;
s->d1->timeout.num_alerts++;
/* Reduce MTU after 2 unsuccessful retransmissions */
if (D1I(s)->timeout.num_alerts > 2) {
D1I(s)->mtu = BIO_ctrl(SSL_get_wbio(s),
if (s->d1->timeout.num_alerts > 2) {
s->d1->mtu = BIO_ctrl(SSL_get_wbio(s),
BIO_CTRL_DGRAM_GET_FALLBACK_MTU, 0, NULL);
}
if (D1I(s)->timeout.num_alerts > DTLS1_TMO_ALERT_COUNT) {
if (s->d1->timeout.num_alerts > DTLS1_TMO_ALERT_COUNT) {
/* fail the connection, enough alerts have been sent */
SSLerror(s, SSL_R_READ_TIMEOUT_EXPIRED);
return -1;
@@ -400,9 +389,9 @@ dtls1_handle_timeout(SSL *s)
if (dtls1_check_timeout_num(s) < 0)
return -1;
D1I(s)->timeout.read_timeouts++;
if (D1I(s)->timeout.read_timeouts > DTLS1_TMO_READ_COUNT) {
D1I(s)->timeout.read_timeouts = 1;
s->d1->timeout.read_timeouts++;
if (s->d1->timeout.read_timeouts > DTLS1_TMO_READ_COUNT) {
s->d1->timeout.read_timeouts = 1;
}
dtls1_start_timer(s);
@@ -418,7 +407,7 @@ dtls1_listen(SSL *s, struct sockaddr *client)
SSL_clear(s);
SSL_set_options(s, SSL_OP_COOKIE_EXCHANGE);
D1I(s)->listen = 1;
s->d1->listen = 1;
ret = SSL_accept(s);
if (ret <= 0)
@@ -427,24 +416,3 @@ dtls1_listen(SSL *s, struct sockaddr *client)
(void)BIO_dgram_get_peer(SSL_get_rbio(s), client);
return 1;
}
void
dtls1_build_sequence_number(unsigned char *dst, unsigned char *seq,
unsigned short epoch)
{
CBB cbb;
if (!CBB_init_fixed(&cbb, dst, SSL3_SEQUENCE_SIZE))
goto err;
if (!CBB_add_u16(&cbb, epoch))
goto err;
if (!CBB_add_bytes(&cbb, &seq[2], SSL3_SEQUENCE_SIZE - 2))
goto err;
if (!CBB_finish(&cbb, NULL, NULL))
goto err;
return;
err:
CBB_cleanup(&cbb);
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: d1_srtp.c,v 1.24 2020/03/16 15:25:13 tb Exp $ */
/* $OpenBSD: d1_srtp.c,v 1.30 2022/01/28 13:11:56 inoguchi Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -118,15 +118,16 @@
#include <stdio.h>
#include <openssl/objects.h>
#include "ssl_locl.h"
#include <openssl/opensslconf.h>
#ifndef OPENSSL_NO_SRTP
#include "bytestring.h"
#include "dtls_locl.h"
#include "ssl_locl.h"
#include "srtp.h"
static SRTP_PROTECTION_PROFILE srtp_known_profiles[] = {
static const SRTP_PROTECTION_PROFILE srtp_known_profiles[] = {
{
"SRTP_AES128_CM_SHA1_80",
SRTP_AES128_CM_SHA1_80,
@@ -135,14 +136,22 @@ static SRTP_PROTECTION_PROFILE srtp_known_profiles[] = {
"SRTP_AES128_CM_SHA1_32",
SRTP_AES128_CM_SHA1_32,
},
{
"SRTP_AEAD_AES_128_GCM",
SRTP_AEAD_AES_128_GCM,
},
{
"SRTP_AEAD_AES_256_GCM",
SRTP_AEAD_AES_256_GCM,
},
{0}
};
int
srtp_find_profile_by_name(char *profile_name, SRTP_PROTECTION_PROFILE **pptr,
unsigned int len)
srtp_find_profile_by_name(const char *profile_name,
const SRTP_PROTECTION_PROFILE **pptr, unsigned int len)
{
SRTP_PROTECTION_PROFILE *p;
const SRTP_PROTECTION_PROFILE *p;
p = srtp_known_profiles;
while (p->name) {
@@ -160,9 +169,9 @@ srtp_find_profile_by_name(char *profile_name, SRTP_PROTECTION_PROFILE **pptr,
int
srtp_find_profile_by_num(unsigned int profile_num,
SRTP_PROTECTION_PROFILE **pptr)
const SRTP_PROTECTION_PROFILE **pptr)
{
SRTP_PROTECTION_PROFILE *p;
const SRTP_PROTECTION_PROFILE *p;
p = srtp_known_profiles;
while (p->name) {
@@ -181,11 +190,9 @@ ssl_ctx_make_profiles(const char *profiles_string,
STACK_OF(SRTP_PROTECTION_PROFILE) **out)
{
STACK_OF(SRTP_PROTECTION_PROFILE) *profiles;
char *col;
char *ptr = (char *)profiles_string;
SRTP_PROTECTION_PROFILE *p;
const char *ptr = profiles_string;
const SRTP_PROTECTION_PROFILE *p;
if (!(profiles = sk_SRTP_PROTECTION_PROFILE_new_null())) {
SSLerrorx(SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES);
@@ -197,7 +204,10 @@ ssl_ctx_make_profiles(const char *profiles_string,
if (!srtp_find_profile_by_name(ptr, &p,
col ? col - ptr : (int)strlen(ptr))) {
sk_SRTP_PROTECTION_PROFILE_push(profiles, p);
if (!sk_SRTP_PROTECTION_PROFILE_push(profiles, p)) {
sk_SRTP_PROTECTION_PROFILE_free(profiles);
return 1;
}
} else {
SSLerrorx(SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE);
sk_SRTP_PROTECTION_PROFILE_free(profiles);
@@ -245,7 +255,8 @@ SSL_get_srtp_profiles(SSL *s)
SRTP_PROTECTION_PROFILE *
SSL_get_selected_srtp_profile(SSL *s)
{
return s->internal->srtp_profile;
/* XXX cast away the const */
return (SRTP_PROTECTION_PROFILE *)s->internal->srtp_profile;
}
#endif

222
externals/libressl/ssl/dtls_locl.h vendored Executable file
View File

@@ -0,0 +1,222 @@
/* $OpenBSD: dtls_locl.h,v 1.10 2021/10/23 13:45:44 jsing Exp $ */
/*
* DTLS implementation written by Nagendra Modadugu
* (nagendra@cs.stanford.edu) for the OpenSSL project 2005.
*/
/* ====================================================================
* Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#ifndef HEADER_DTLS_LOCL_H
#define HEADER_DTLS_LOCL_H
#include <sys/time.h>
#include <openssl/dtls1.h>
#include "ssl_locl.h"
__BEGIN_HIDDEN_DECLS
typedef struct dtls1_bitmap_st {
unsigned long map; /* track 32 packets on 32-bit systems
and 64 - on 64-bit systems */
unsigned char max_seq_num[8]; /* max record number seen so far,
64-bit value in big-endian
encoding */
} DTLS1_BITMAP;
struct dtls1_retransmit_state {
SSL_SESSION *session;
unsigned short epoch;
};
struct hm_header_st {
unsigned char type;
unsigned long msg_len;
unsigned short seq;
unsigned long frag_off;
unsigned long frag_len;
unsigned int is_ccs;
struct dtls1_retransmit_state saved_retransmit_state;
};
struct dtls1_timeout_st {
/* Number of read timeouts so far */
unsigned int read_timeouts;
/* Number of write timeouts so far */
unsigned int write_timeouts;
/* Number of alerts received so far */
unsigned int num_alerts;
};
struct _pqueue;
typedef struct record_pqueue_st {
unsigned short epoch;
struct _pqueue *q;
} record_pqueue;
typedef struct hm_fragment_st {
struct hm_header_st msg_header;
unsigned char *fragment;
unsigned char *reassembly;
} hm_fragment;
typedef struct dtls1_record_data_internal_st {
unsigned char *packet;
unsigned int packet_length;
SSL3_BUFFER_INTERNAL rbuf;
SSL3_RECORD_INTERNAL rrec;
} DTLS1_RECORD_DATA_INTERNAL;
struct dtls1_state_st {
/* Buffered (sent) handshake records */
struct _pqueue *sent_messages;
/* Indicates when the last handshake msg or heartbeat sent will timeout */
struct timeval next_timeout;
/* Timeout duration */
unsigned short timeout_duration;
unsigned int send_cookie;
unsigned char cookie[DTLS1_COOKIE_LENGTH];
unsigned char rcvd_cookie[DTLS1_COOKIE_LENGTH];
unsigned int cookie_len;
/* records being received in the current epoch */
DTLS1_BITMAP bitmap;
/* renegotiation starts a new set of sequence numbers */
DTLS1_BITMAP next_bitmap;
/* handshake message numbers */
unsigned short handshake_write_seq;
unsigned short next_handshake_write_seq;
unsigned short handshake_read_seq;
/* Received handshake records (unprocessed) */
record_pqueue unprocessed_rcds;
/* Buffered handshake messages */
struct _pqueue *buffered_messages;
/* Buffered application records.
* Only for records between CCS and Finished
* to prevent either protocol violation or
* unnecessary message loss.
*/
record_pqueue buffered_app_data;
/* Is set when listening for new connections with dtls1_listen() */
unsigned int listen;
unsigned int mtu; /* max DTLS packet size */
struct hm_header_st w_msg_hdr;
struct hm_header_st r_msg_hdr;
struct dtls1_timeout_st timeout;
unsigned int retransmitting;
unsigned int change_cipher_spec_ok;
};
int dtls1_do_write(SSL *s, int type);
int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek);
void dtls1_set_message_header(SSL *s, unsigned char mt, unsigned long len,
unsigned long frag_off, unsigned long frag_len);
void dtls1_set_message_header_int(SSL *s, unsigned char mt,
unsigned long len, unsigned short seq_num, unsigned long frag_off,
unsigned long frag_len);
int do_dtls1_write(SSL *s, int type, const unsigned char *buf,
unsigned int len);
int dtls1_write_app_data_bytes(SSL *s, int type, const void *buf, int len);
int dtls1_write_bytes(SSL *s, int type, const void *buf, int len);
int dtls1_read_failed(SSL *s, int code);
int dtls1_buffer_message(SSL *s, int ccs);
int dtls1_retransmit_message(SSL *s, unsigned short seq,
unsigned long frag_off, int *found);
int dtls1_get_queue_priority(unsigned short seq, int is_ccs);
int dtls1_retransmit_buffered_messages(SSL *s);
void dtls1_clear_record_buffer(SSL *s);
int dtls1_get_message_header(CBS *header, struct hm_header_st *msg_hdr);
void dtls1_reset_read_seq_numbers(SSL *s);
struct timeval* dtls1_get_timeout(SSL *s, struct timeval* timeleft);
int dtls1_check_timeout_num(SSL *s);
int dtls1_handle_timeout(SSL *s);
const SSL_CIPHER *dtls1_get_cipher(unsigned int u);
void dtls1_start_timer(SSL *s);
void dtls1_stop_timer(SSL *s);
int dtls1_is_timer_expired(SSL *s);
void dtls1_double_timeout(SSL *s);
unsigned int dtls1_min_mtu(void);
int dtls1_new(SSL *s);
void dtls1_free(SSL *s);
void dtls1_clear(SSL *s);
long dtls1_ctrl(SSL *s, int cmd, long larg, void *parg);
int dtls1_get_message(SSL *s, int st1, int stn, int mt, long max);
int dtls1_get_record(SSL *s);
__END_HIDDEN_DECLS
#endif

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: s3_cbc.c,v 1.22 2020/06/19 21:26:40 tb Exp $ */
/* $OpenBSD: s3_cbc.c,v 1.25 2021/12/09 17:45:49 tb Exp $ */
/* ====================================================================
* Copyright (c) 2012 The OpenSSL Project. All rights reserved.
*
@@ -53,11 +53,11 @@
*
*/
#include "ssl_locl.h"
#include <openssl/md5.h>
#include <openssl/sha.h>
#include "ssl_locl.h"
/* MAX_HASH_BIT_COUNT_BYTES is the maximum number of bytes in the hash's length
* field. (SHA-384/512 have 128-bit length.) */
#define MAX_HASH_BIT_COUNT_BYTES 16
@@ -101,7 +101,7 @@ constant_time_eq_8(unsigned int a, unsigned int b)
return DUPLICATE_MSB_TO_ALL_8(c);
}
/* tls1_cbc_remove_padding removes the CBC padding from the decrypted, TLS, CBC
/* ssl3_cbc_remove_padding removes the CBC padding from the decrypted, TLS, CBC
* record in |rec| in constant time and returns 1 if the padding is valid and
* -1 otherwise. It also removes any explicit IV from the start of the record
* without leaking any timing about whether there was enough space after the
@@ -113,26 +113,24 @@ constant_time_eq_8(unsigned int a, unsigned int b)
* 1: if the padding was valid
* -1: otherwise. */
int
tls1_cbc_remove_padding(const SSL* s, SSL3_RECORD_INTERNAL *rec,
unsigned int block_size, unsigned int mac_size)
ssl3_cbc_remove_padding(SSL3_RECORD_INTERNAL *rec, unsigned int eiv_len,
unsigned int mac_size)
{
unsigned int padding_length, good, to_check, i;
const unsigned int overhead = 1 /* padding length byte */ + mac_size;
/* Check if version requires explicit IV */
if (SSL_USE_EXPLICIT_IV(s)) {
/* These lengths are all public so we can test them in
* non-constant time.
*/
if (overhead + block_size > rec->length)
return 0;
/* We can now safely skip explicit IV */
rec->data += block_size;
rec->input += block_size;
rec->length -= block_size;
} else if (overhead > rec->length)
/*
* These lengths are all public so we can test them in
* non-constant time.
*/
if (overhead + eiv_len > rec->length)
return 0;
/* We can now safely skip explicit IV, if any. */
rec->data += eiv_len;
rec->input += eiv_len;
rec->length -= eiv_len;
padding_length = rec->data[rec->length - 1];
good = constant_time_ge(rec->length, overhead + padding_length);
@@ -406,7 +404,7 @@ ssl3_cbc_digest_record(const EVP_MD_CTX *ctx, unsigned char* md_out,
unsigned char first_block[MAX_HASH_BLOCK_SIZE];
unsigned char mac_out[EVP_MAX_MD_SIZE];
unsigned int i, j, md_out_size_u;
EVP_MD_CTX md_ctx;
EVP_MD_CTX *md_ctx;
/* mdLengthSize is the number of bytes in the length field that terminates
* the hash. */
unsigned int md_length_size = 8;
@@ -607,9 +605,10 @@ ssl3_cbc_digest_record(const EVP_MD_CTX *ctx, unsigned char* md_out,
mac_out[j] |= block[j]&is_block_b;
}
EVP_MD_CTX_init(&md_ctx);
if (!EVP_DigestInit_ex(&md_ctx, ctx->digest, NULL /* engine */)) {
EVP_MD_CTX_cleanup(&md_ctx);
if ((md_ctx = EVP_MD_CTX_new()) == NULL)
return 0;
if (!EVP_DigestInit_ex(md_ctx, EVP_MD_CTX_md(ctx), NULL /* engine */)) {
EVP_MD_CTX_free(md_ctx);
return 0;
}
@@ -617,13 +616,13 @@ ssl3_cbc_digest_record(const EVP_MD_CTX *ctx, unsigned char* md_out,
for (i = 0; i < md_block_size; i++)
hmac_pad[i] ^= 0x6a;
EVP_DigestUpdate(&md_ctx, hmac_pad, md_block_size);
EVP_DigestUpdate(&md_ctx, mac_out, md_size);
EVP_DigestUpdate(md_ctx, hmac_pad, md_block_size);
EVP_DigestUpdate(md_ctx, mac_out, md_size);
EVP_DigestFinal(&md_ctx, md_out, &md_out_size_u);
EVP_DigestFinal(md_ctx, md_out, &md_out_size_u);
if (md_out_size)
*md_out_size = md_out_size_u;
EVP_MD_CTX_cleanup(&md_ctx);
EVP_MD_CTX_free(md_ctx);
return 1;
}

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: s3_lib.c,v 1.198 2020/09/17 15:42:14 jsing Exp $ */
/* $OpenBSD: s3_lib.c,v 1.228 2022/03/17 17:24:37 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -156,9 +156,13 @@
#include <openssl/dh.h>
#include <openssl/md5.h>
#include <openssl/objects.h>
#include <openssl/opensslconf.h>
#include "ssl_locl.h"
#include "bytestring.h"
#include "dtls_locl.h"
#include "ssl_locl.h"
#include "ssl_sigalgs.h"
#include "ssl_tlsext.h"
#define SSL3_NUM_CIPHERS (sizeof(ssl3_ciphers) / sizeof(SSL_CIPHER))
@@ -170,7 +174,7 @@
#define FIXED_NONCE_LEN(x) (((x / 2) & 0xf) << 24)
/* list of available SSLv3 ciphers (sorted by id) */
SSL_CIPHER ssl3_ciphers[] = {
const SSL_CIPHER ssl3_ciphers[] = {
/* The RSA ciphers */
/* Cipher 01 */
@@ -417,7 +421,7 @@ SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_SHA256,
.algorithm_ssl = SSL_TLSV1_2,
.algo_strength = SSL_STRONG_NONE,
.algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
.algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
.strength_bits = 0,
.alg_bits = 0,
},
@@ -433,7 +437,7 @@ SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_SHA256,
.algorithm_ssl = SSL_TLSV1_2,
.algo_strength = SSL_HIGH,
.algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
.algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
.strength_bits = 128,
.alg_bits = 128,
},
@@ -449,7 +453,7 @@ SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_SHA256,
.algorithm_ssl = SSL_TLSV1_2,
.algo_strength = SSL_HIGH,
.algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
.algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
.strength_bits = 256,
.alg_bits = 256,
},
@@ -518,7 +522,7 @@ SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_SHA256,
.algorithm_ssl = SSL_TLSV1_2,
.algo_strength = SSL_HIGH,
.algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
.algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
.strength_bits = 128,
.alg_bits = 128,
},
@@ -534,7 +538,7 @@ SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_SHA256,
.algorithm_ssl = SSL_TLSV1_2,
.algo_strength = SSL_HIGH,
.algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
.algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
.strength_bits = 256,
.alg_bits = 256,
},
@@ -550,7 +554,7 @@ SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_SHA256,
.algorithm_ssl = SSL_TLSV1_2,
.algo_strength = SSL_HIGH,
.algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
.algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
.strength_bits = 128,
.alg_bits = 128,
},
@@ -566,7 +570,7 @@ SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_SHA256,
.algorithm_ssl = SSL_TLSV1_2,
.algo_strength = SSL_HIGH,
.algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
.algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
.strength_bits = 256,
.alg_bits = 256,
},
@@ -878,7 +882,7 @@ SSL_CIPHER ssl3_ciphers[] = {
/* Cipher 1301 */
{
.valid = 1,
.name = TLS1_3_TXT_AES_128_GCM_SHA256,
.name = TLS1_3_RFC_AES_128_GCM_SHA256,
.id = TLS1_3_CK_AES_128_GCM_SHA256,
.algorithm_mkey = SSL_kTLS1_3,
.algorithm_auth = SSL_aTLS1_3,
@@ -894,7 +898,7 @@ SSL_CIPHER ssl3_ciphers[] = {
/* Cipher 1302 */
{
.valid = 1,
.name = TLS1_3_TXT_AES_256_GCM_SHA384,
.name = TLS1_3_RFC_AES_256_GCM_SHA384,
.id = TLS1_3_CK_AES_256_GCM_SHA384,
.algorithm_mkey = SSL_kTLS1_3,
.algorithm_auth = SSL_aTLS1_3,
@@ -910,7 +914,7 @@ SSL_CIPHER ssl3_ciphers[] = {
/* Cipher 1303 */
{
.valid = 1,
.name = TLS1_3_TXT_CHACHA20_POLY1305_SHA256,
.name = TLS1_3_RFC_CHACHA20_POLY1305_SHA256,
.id = TLS1_3_CK_CHACHA20_POLY1305_SHA256,
.algorithm_mkey = SSL_kTLS1_3,
.algorithm_auth = SSL_aTLS1_3,
@@ -1440,14 +1444,14 @@ ssl3_pending(const SSL *s)
if (s->internal->rstate == SSL_ST_READ_BODY)
return 0;
return (S3I(s)->rrec.type == SSL3_RT_APPLICATION_DATA) ?
S3I(s)->rrec.length : 0;
return (s->s3->rrec.type == SSL3_RT_APPLICATION_DATA) ?
s->s3->rrec.length : 0;
}
int
ssl3_handshake_msg_hdr_len(SSL *s)
{
return (SSL_IS_DTLS(s) ? DTLS1_HM_HEADER_LENGTH :
return (SSL_is_dtls(s) ? DTLS1_HM_HEADER_LENGTH :
SSL3_HM_HEADER_LENGTH);
}
@@ -1460,7 +1464,7 @@ ssl3_handshake_msg_start(SSL *s, CBB *handshake, CBB *body, uint8_t msg_type)
goto err;
if (!CBB_add_u8(handshake, msg_type))
goto err;
if (SSL_IS_DTLS(s)) {
if (SSL_is_dtls(s)) {
unsigned char *data;
if (!CBB_add_space(handshake, &data, DTLS1_HM_HEADER_LENGTH -
@@ -1497,7 +1501,7 @@ ssl3_handshake_msg_finish(SSL *s, CBB *handshake)
s->internal->init_num = (int)outlen;
s->internal->init_off = 0;
if (SSL_IS_DTLS(s)) {
if (SSL_is_dtls(s)) {
unsigned long len;
uint8_t msg_type;
CBS cbs;
@@ -1529,7 +1533,7 @@ ssl3_handshake_write(SSL *s)
int
ssl3_record_write(SSL *s, int type)
{
if (SSL_IS_DTLS(s))
if (SSL_is_dtls(s))
return dtls1_do_write(s, type);
return ssl3_do_write(s, type);
@@ -1540,12 +1544,8 @@ ssl3_new(SSL *s)
{
if ((s->s3 = calloc(1, sizeof(*s->s3))) == NULL)
return (0);
if ((S3I(s) = calloc(1, sizeof(*S3I(s)))) == NULL) {
free(s->s3);
return (0);
}
s->method->internal->ssl_clear(s);
s->method->ssl_clear(s);
return (1);
}
@@ -1559,25 +1559,22 @@ ssl3_free(SSL *s)
tls1_cleanup_key_block(s);
ssl3_release_read_buffer(s);
ssl3_release_write_buffer(s);
freezero(S3I(s)->hs.sigalgs, S3I(s)->hs.sigalgs_len);
freezero(s->s3->hs.sigalgs, s->s3->hs.sigalgs_len);
DH_free(S3I(s)->tmp.dh);
EC_KEY_free(S3I(s)->tmp.ecdh);
freezero(S3I(s)->tmp.x25519, X25519_KEY_LENGTH);
tls_key_share_free(s->s3->hs.key_share);
tls13_key_share_free(S3I(s)->hs_tls13.key_share);
tls13_secrets_destroy(S3I(s)->hs_tls13.secrets);
freezero(S3I(s)->hs_tls13.cookie, S3I(s)->hs_tls13.cookie_len);
tls13_clienthello_hash_clear(&S3I(s)->hs_tls13);
tls13_secrets_destroy(s->s3->hs.tls13.secrets);
freezero(s->s3->hs.tls13.cookie, s->s3->hs.tls13.cookie_len);
tls13_clienthello_hash_clear(&s->s3->hs.tls13);
sk_X509_NAME_pop_free(S3I(s)->tmp.ca_names, X509_NAME_free);
sk_X509_NAME_pop_free(s->s3->hs.tls12.ca_names, X509_NAME_free);
sk_X509_pop_free(s->internal->verified_chain, X509_free);
tls1_transcript_free(s);
tls1_transcript_hash_free(s);
free(S3I(s)->alpn_selected);
free(s->s3->alpn_selected);
freezero(S3I(s), sizeof(*S3I(s)));
freezero(s->s3, sizeof(*s->s3));
s->s3 = NULL;
@@ -1586,105 +1583,78 @@ ssl3_free(SSL *s)
void
ssl3_clear(SSL *s)
{
struct ssl3_state_internal_st *internal;
unsigned char *rp, *wp;
size_t rlen, wlen;
tls1_cleanup_key_block(s);
sk_X509_NAME_pop_free(S3I(s)->tmp.ca_names, X509_NAME_free);
sk_X509_NAME_pop_free(s->s3->hs.tls12.ca_names, X509_NAME_free);
sk_X509_pop_free(s->internal->verified_chain, X509_free);
s->internal->verified_chain = NULL;
DH_free(S3I(s)->tmp.dh);
S3I(s)->tmp.dh = NULL;
EC_KEY_free(S3I(s)->tmp.ecdh);
S3I(s)->tmp.ecdh = NULL;
S3I(s)->tmp.ecdh_nid = NID_undef;
freezero(S3I(s)->tmp.x25519, X25519_KEY_LENGTH);
S3I(s)->tmp.x25519 = NULL;
freezero(s->s3->hs.sigalgs, s->s3->hs.sigalgs_len);
s->s3->hs.sigalgs = NULL;
s->s3->hs.sigalgs_len = 0;
freezero(S3I(s)->hs.sigalgs, S3I(s)->hs.sigalgs_len);
S3I(s)->hs.sigalgs = NULL;
S3I(s)->hs.sigalgs_len = 0;
tls_key_share_free(s->s3->hs.key_share);
s->s3->hs.key_share = NULL;
tls13_key_share_free(S3I(s)->hs_tls13.key_share);
S3I(s)->hs_tls13.key_share = NULL;
tls13_secrets_destroy(s->s3->hs.tls13.secrets);
s->s3->hs.tls13.secrets = NULL;
freezero(s->s3->hs.tls13.cookie, s->s3->hs.tls13.cookie_len);
s->s3->hs.tls13.cookie = NULL;
s->s3->hs.tls13.cookie_len = 0;
tls13_clienthello_hash_clear(&s->s3->hs.tls13);
tls13_secrets_destroy(S3I(s)->hs_tls13.secrets);
S3I(s)->hs_tls13.secrets = NULL;
freezero(S3I(s)->hs_tls13.cookie, S3I(s)->hs_tls13.cookie_len);
S3I(s)->hs_tls13.cookie = NULL;
S3I(s)->hs_tls13.cookie_len = 0;
tls13_clienthello_hash_clear(&S3I(s)->hs_tls13);
s->s3->hs.extensions_seen = 0;
S3I(s)->hs.extensions_seen = 0;
rp = S3I(s)->rbuf.buf;
wp = S3I(s)->wbuf.buf;
rlen = S3I(s)->rbuf.len;
wlen = S3I(s)->wbuf.len;
rp = s->s3->rbuf.buf;
wp = s->s3->wbuf.buf;
rlen = s->s3->rbuf.len;
wlen = s->s3->wbuf.len;
tls1_transcript_free(s);
tls1_transcript_hash_free(s);
free(S3I(s)->alpn_selected);
S3I(s)->alpn_selected = NULL;
free(s->s3->alpn_selected);
s->s3->alpn_selected = NULL;
s->s3->alpn_selected_len = 0;
memset(S3I(s), 0, sizeof(*S3I(s)));
internal = S3I(s);
memset(s->s3, 0, sizeof(*s->s3));
S3I(s) = internal;
S3I(s)->rbuf.buf = rp;
S3I(s)->wbuf.buf = wp;
S3I(s)->rbuf.len = rlen;
S3I(s)->wbuf.len = wlen;
s->s3->rbuf.buf = rp;
s->s3->wbuf.buf = wp;
s->s3->rbuf.len = rlen;
s->s3->wbuf.len = wlen;
ssl_free_wbio_buffer(s);
/* Not needed... */
S3I(s)->renegotiate = 0;
S3I(s)->total_renegotiations = 0;
S3I(s)->num_renegotiations = 0;
S3I(s)->in_read_app_data = 0;
s->s3->renegotiate = 0;
s->s3->total_renegotiations = 0;
s->s3->num_renegotiations = 0;
s->s3->in_read_app_data = 0;
s->internal->packet_length = 0;
s->version = TLS1_VERSION;
S3I(s)->hs.state = SSL_ST_BEFORE|((s->server) ? SSL_ST_ACCEPT : SSL_ST_CONNECT);
s->s3->hs.state = SSL_ST_BEFORE|((s->server) ? SSL_ST_ACCEPT : SSL_ST_CONNECT);
}
long
_SSL_get_peer_tmp_key(SSL *s, EVP_PKEY **key)
{
EVP_PKEY *pkey = NULL;
SESS_CERT *sc;
int ret = 0;
*key = NULL;
if (s->session == NULL || SSI(s)->sess_cert == NULL)
return 0;
sc = SSI(s)->sess_cert;
if (s->s3->hs.key_share == NULL)
goto err;
if ((pkey = EVP_PKEY_new()) == NULL)
return 0;
if (sc->peer_dh_tmp != NULL) {
if (!EVP_PKEY_set1_DH(pkey, sc->peer_dh_tmp))
goto err;
} else if (sc->peer_ecdh_tmp) {
if (!EVP_PKEY_set1_EC_KEY(pkey, sc->peer_ecdh_tmp))
goto err;
} else if (sc->peer_x25519_tmp != NULL) {
if (!ssl_kex_dummy_ecdhe_x25519(pkey))
goto err;
} else if (S3I(s)->hs_tls13.key_share != NULL) {
if (!tls13_key_share_peer_pkey(S3I(s)->hs_tls13.key_share,
pkey))
goto err;
} else {
goto err;
}
if (!tls_key_share_peer_pkey(s->s3->hs.key_share, pkey))
goto err;
*key = pkey;
pkey = NULL;
@@ -1706,7 +1676,7 @@ _SSL_session_reused(SSL *s)
static int
_SSL_num_renegotiations(SSL *s)
{
return S3I(s)->num_renegotiations;
return s->s3->num_renegotiations;
}
static int
@@ -1714,8 +1684,8 @@ _SSL_clear_num_renegotiations(SSL *s)
{
int renegs;
renegs = S3I(s)->num_renegotiations;
S3I(s)->num_renegotiations = 0;
renegs = s->s3->num_renegotiations;
s->s3->num_renegotiations = 0;
return renegs;
}
@@ -1723,26 +1693,26 @@ _SSL_clear_num_renegotiations(SSL *s)
static int
_SSL_total_renegotiations(SSL *s)
{
return S3I(s)->total_renegotiations;
return s->s3->total_renegotiations;
}
static int
_SSL_set_tmp_dh(SSL *s, DH *dh)
{
DH *dh_tmp;
DH *dhe_params;
if (dh == NULL) {
SSLerror(s, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
if ((dh_tmp = DHparams_dup(dh)) == NULL) {
if ((dhe_params = DHparams_dup(dh)) == NULL) {
SSLerror(s, ERR_R_DH_LIB);
return 0;
}
DH_free(s->cert->dh_tmp);
s->cert->dh_tmp = dh_tmp;
DH_free(s->cert->dhe_params);
s->cert->dhe_params = dhe_params;
return 1;
}
@@ -1750,7 +1720,7 @@ _SSL_set_tmp_dh(SSL *s, DH *dh)
static int
_SSL_set_dh_auto(SSL *s, int state)
{
s->cert->dh_tmp_auto = state;
s->cert->dhe_params_auto = state;
return 1;
}
@@ -1778,17 +1748,21 @@ _SSL_set_ecdh_auto(SSL *s, int state)
static int
_SSL_set_tlsext_host_name(SSL *s, const char *name)
{
int is_ip;
CBS cbs;
free(s->tlsext_hostname);
s->tlsext_hostname = NULL;
if (name == NULL)
return 1;
if (strlen(name) > TLSEXT_MAXLEN_host_name) {
CBS_init(&cbs, name, strlen(name));
if (!tlsext_sni_is_valid_hostname(&cbs, &is_ip)) {
SSLerror(s, SSL_R_SSL3_EXT_INVALID_SERVERNAME);
return 0;
}
if ((s->tlsext_hostname = strdup(name)) == NULL) {
SSLerror(s, ERR_R_INTERNAL_ERROR);
return 0;
@@ -1804,6 +1778,12 @@ _SSL_set_tlsext_debug_arg(SSL *s, void *arg)
return 1;
}
static int
_SSL_get_tlsext_status_type(SSL *s)
{
return s->tlsext_status_type;
}
static int
_SSL_set_tlsext_status_type(SSL *s, int type)
{
@@ -1926,6 +1906,64 @@ SSL_set1_groups_list(SSL *s, const char *groups)
&s->internal->tlsext_supportedgroups_length, groups);
}
static int
_SSL_get_signature_nid(SSL *s, int *nid)
{
const struct ssl_sigalg *sigalg;
if ((sigalg = s->s3->hs.our_sigalg) == NULL)
return 0;
*nid = EVP_MD_type(sigalg->md());
return 1;
}
static int
_SSL_get_peer_signature_nid(SSL *s, int *nid)
{
const struct ssl_sigalg *sigalg;
if ((sigalg = s->s3->hs.peer_sigalg) == NULL)
return 0;
*nid = EVP_MD_type(sigalg->md());
return 1;
}
int
SSL_get_signature_type_nid(const SSL *s, int *nid)
{
const struct ssl_sigalg *sigalg;
if ((sigalg = s->s3->hs.our_sigalg) == NULL)
return 0;
*nid = sigalg->key_type;
if (sigalg->key_type == EVP_PKEY_RSA &&
(sigalg->flags & SIGALG_FLAG_RSA_PSS))
*nid = EVP_PKEY_RSA_PSS;
return 1;
}
int
SSL_get_peer_signature_type_nid(const SSL *s, int *nid)
{
const struct ssl_sigalg *sigalg;
if ((sigalg = s->s3->hs.peer_sigalg) == NULL)
return 0;
*nid = sigalg->key_type;
if (sigalg->key_type == EVP_PKEY_RSA &&
(sigalg->flags & SIGALG_FLAG_RSA_PSS))
*nid = EVP_PKEY_RSA_PSS;
return 1;
}
long
ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
{
@@ -1972,6 +2010,9 @@ ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
case SSL_CTRL_SET_TLSEXT_DEBUG_ARG:
return _SSL_set_tlsext_debug_arg(s, parg);
case SSL_CTRL_GET_TLSEXT_STATUS_REQ_TYPE:
return _SSL_get_tlsext_status_type(s);
case SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE:
return _SSL_set_tlsext_status_type(s, larg);
@@ -2036,6 +2077,12 @@ ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
return 0;
return SSL_set_max_proto_version(s, larg);
case SSL_CTRL_GET_SIGNATURE_NID:
return _SSL_get_signature_nid(s, parg);
case SSL_CTRL_GET_PEER_SIGNATURE_NID:
return _SSL_get_peer_signature_nid(s, parg);
/*
* Legacy controls that should eventually be removed.
*/
@@ -2066,7 +2113,7 @@ ssl3_callback_ctrl(SSL *s, int cmd, void (*fp)(void))
return 0;
case SSL_CTRL_SET_TMP_DH_CB:
s->cert->dh_tmp_cb = (DH *(*)(SSL *, int, int))fp;
s->cert->dhe_params_cb = (DH *(*)(SSL *, int, int))fp;
return 1;
case SSL_CTRL_SET_TMP_ECDH_CB:
@@ -2084,15 +2131,20 @@ ssl3_callback_ctrl(SSL *s, int cmd, void (*fp)(void))
static int
_SSL_CTX_set_tmp_dh(SSL_CTX *ctx, DH *dh)
{
DH *dh_tmp;
DH *dhe_params;
if ((dh_tmp = DHparams_dup(dh)) == NULL) {
if (dh == NULL) {
SSLerrorx(ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
if ((dhe_params = DHparams_dup(dh)) == NULL) {
SSLerrorx(ERR_R_DH_LIB);
return 0;
}
DH_free(ctx->internal->cert->dh_tmp);
ctx->internal->cert->dh_tmp = dh_tmp;
DH_free(ctx->internal->cert->dhe_params);
ctx->internal->cert->dhe_params = dhe_params;
return 1;
}
@@ -2100,7 +2152,7 @@ _SSL_CTX_set_tmp_dh(SSL_CTX *ctx, DH *dh)
static int
_SSL_CTX_set_dh_auto(SSL_CTX *ctx, int state)
{
ctx->internal->cert->dh_tmp_auto = state;
ctx->internal->cert->dhe_params_auto = state;
return 1;
}
@@ -2387,7 +2439,7 @@ ssl3_ctx_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp)(void))
return 0;
case SSL_CTRL_SET_TMP_DH_CB:
ctx->internal->cert->dh_tmp_cb =
ctx->internal->cert->dhe_params_cb =
(DH *(*)(SSL *, int, int))fp;
return 1;
@@ -2416,51 +2468,6 @@ ssl3_ctx_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp)(void))
return 0;
}
/*
* This function needs to check if the ciphers required are actually available.
*/
const SSL_CIPHER *
ssl3_get_cipher_by_char(const unsigned char *p)
{
uint16_t cipher_value;
CBS cbs;
/* We have to assume it is at least 2 bytes due to existing API. */
CBS_init(&cbs, p, 2);
if (!CBS_get_u16(&cbs, &cipher_value))
return NULL;
return ssl3_get_cipher_by_value(cipher_value);
}
int
ssl3_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p)
{
CBB cbb;
if (p == NULL)
return (2);
if ((c->id & ~SSL3_CK_VALUE_MASK) != SSL3_CK_ID)
return (0);
memset(&cbb, 0, sizeof(cbb));
/* We have to assume it is at least 2 bytes due to existing API. */
if (!CBB_init_fixed(&cbb, p, 2))
goto err;
if (!CBB_add_u16(&cbb, ssl3_cipher_get_value(c)))
goto err;
if (!CBB_finish(&cbb, NULL, NULL))
goto err;
return (2);
err:
CBB_cleanup(&cbb);
return (0);
}
SSL_CIPHER *
ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt,
STACK_OF(SSL_CIPHER) *srvr)
@@ -2470,7 +2477,7 @@ ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt,
SSL_CIPHER *c, *ret = NULL;
int can_use_ecc;
int i, ii, ok;
CERT *cert;
SSL_CERT *cert;
/* Let's see which ciphers we can support */
cert = s->cert;
@@ -2548,7 +2555,7 @@ ssl3_get_req_cert_types(SSL *s, CBB *cbb)
{
unsigned long alg_k;
alg_k = S3I(s)->hs.new_cipher->algorithm_mkey;
alg_k = s->s3->hs.cipher->algorithm_mkey;
#ifndef OPENSSL_NO_GOST
if ((alg_k & SSL_kGOST) != 0) {
@@ -2592,7 +2599,7 @@ ssl3_shutdown(SSL *s)
* Don't do anything much if we have not done the handshake or
* we don't want to send messages :-)
*/
if ((s->internal->quiet_shutdown) || (S3I(s)->hs.state == SSL_ST_BEFORE)) {
if ((s->internal->quiet_shutdown) || (s->s3->hs.state == SSL_ST_BEFORE)) {
s->internal->shutdown = (SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
return (1);
}
@@ -2602,13 +2609,13 @@ ssl3_shutdown(SSL *s)
ssl3_send_alert(s, SSL3_AL_WARNING, SSL_AD_CLOSE_NOTIFY);
/*
* Our shutdown alert has been sent now, and if it still needs
* to be written, S3I(s)->alert_dispatch will be true
* to be written, s->s3->alert_dispatch will be true
*/
if (S3I(s)->alert_dispatch)
return(-1); /* return WANT_WRITE */
} else if (S3I(s)->alert_dispatch) {
if (s->s3->alert_dispatch)
return (-1); /* return WANT_WRITE */
} else if (s->s3->alert_dispatch) {
/* resend it if not sent */
ret = s->method->ssl_dispatch_alert(s);
ret = ssl3_dispatch_alert(s);
if (ret == -1) {
/*
* We only get to return -1 here the 2nd/Nth
@@ -2620,14 +2627,14 @@ ssl3_shutdown(SSL *s)
}
} else if (!(s->internal->shutdown & SSL_RECEIVED_SHUTDOWN)) {
/* If we are waiting for a close from our peer, we are closed */
s->method->internal->ssl_read_bytes(s, 0, NULL, 0, 0);
s->method->ssl_read_bytes(s, 0, NULL, 0, 0);
if (!(s->internal->shutdown & SSL_RECEIVED_SHUTDOWN)) {
return(-1); /* return WANT_READ */
return (-1); /* return WANT_READ */
}
}
if ((s->internal->shutdown == (SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN)) &&
!S3I(s)->alert_dispatch)
!s->s3->alert_dispatch)
return (1);
else
return (0);
@@ -2638,11 +2645,11 @@ ssl3_write(SSL *s, const void *buf, int len)
{
errno = 0;
if (S3I(s)->renegotiate)
if (s->s3->renegotiate)
ssl3_renegotiate_check(s);
return s->method->internal->ssl_write_bytes(s,
SSL3_RT_APPLICATION_DATA, buf, len);
return s->method->ssl_write_bytes(s, SSL3_RT_APPLICATION_DATA,
buf, len);
}
static int
@@ -2651,25 +2658,26 @@ ssl3_read_internal(SSL *s, void *buf, int len, int peek)
int ret;
errno = 0;
if (S3I(s)->renegotiate)
if (s->s3->renegotiate)
ssl3_renegotiate_check(s);
S3I(s)->in_read_app_data = 1;
ret = s->method->internal->ssl_read_bytes(s,
SSL3_RT_APPLICATION_DATA, buf, len, peek);
if ((ret == -1) && (S3I(s)->in_read_app_data == 2)) {
s->s3->in_read_app_data = 1;
ret = s->method->ssl_read_bytes(s, SSL3_RT_APPLICATION_DATA, buf, len,
peek);
if ((ret == -1) && (s->s3->in_read_app_data == 2)) {
/*
* ssl3_read_bytes decided to call s->internal->handshake_func, which
* called ssl3_read_bytes to read handshake data.
* ssl3_read_bytes decided to call s->internal->handshake_func,
* which called ssl3_read_bytes to read handshake data.
* However, ssl3_read_bytes actually found application data
* and thinks that application data makes sense here; so disable
* handshake processing and try to read application data again.
*/
s->internal->in_handshake++;
ret = s->method->internal->ssl_read_bytes(s,
SSL3_RT_APPLICATION_DATA, buf, len, peek);
ret = s->method->ssl_read_bytes(s, SSL3_RT_APPLICATION_DATA,
buf, len, peek);
s->internal->in_handshake--;
} else
S3I(s)->in_read_app_data = 0;
s->s3->in_read_app_data = 0;
return (ret);
}
@@ -2690,49 +2698,28 @@ int
ssl3_renegotiate(SSL *s)
{
if (s->internal->handshake_func == NULL)
return (1);
return 1;
if (s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS)
return (0);
return 0;
S3I(s)->renegotiate = 1;
return (1);
s->s3->renegotiate = 1;
return 1;
}
int
ssl3_renegotiate_check(SSL *s)
{
int ret = 0;
if (!s->s3->renegotiate)
return 0;
if (SSL_in_init(s) || s->s3->rbuf.left != 0 || s->s3->wbuf.left != 0)
return 0;
if (S3I(s)->renegotiate) {
if ((S3I(s)->rbuf.left == 0) && (S3I(s)->wbuf.left == 0) &&
!SSL_in_init(s)) {
/*
* If we are the server, and we have sent
* a 'RENEGOTIATE' message, we need to go
* to SSL_ST_ACCEPT.
*/
/* SSL_ST_ACCEPT */
S3I(s)->hs.state = SSL_ST_RENEGOTIATE;
S3I(s)->renegotiate = 0;
S3I(s)->num_renegotiations++;
S3I(s)->total_renegotiations++;
ret = 1;
}
}
return (ret);
}
/*
* If we are using default SHA1+MD5 algorithms switch to new SHA256 PRF
* and handshake macs if required.
*/
long
ssl_get_algorithm2(SSL *s)
{
long alg2 = S3I(s)->hs.new_cipher->algorithm2;
s->s3->hs.state = SSL_ST_RENEGOTIATE;
s->s3->renegotiate = 0;
s->s3->num_renegotiations++;
s->s3->total_renegotiations++;
if (s->method->internal->ssl3_enc->enc_flags & SSL_ENC_FLAG_SHA256_PRF &&
alg2 == (SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF))
return SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256;
return alg2;
return 1;
}

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: srtp.h,v 1.6 2015/09/01 15:18:23 jsing Exp $ */
/* $OpenBSD: srtp.h,v 1.7 2021/06/11 15:28:13 landry Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -129,6 +129,10 @@ extern "C" {
#define SRTP_NULL_SHA1_80 0x0005
#define SRTP_NULL_SHA1_32 0x0006
/* AEAD SRTP protection profiles from RFC 7714 */
#define SRTP_AEAD_AES_128_GCM 0x0007
#define SRTP_AEAD_AES_256_GCM 0x0008
int SSL_CTX_set_tlsext_use_srtp(SSL_CTX *ctx, const char *profiles);
int SSL_set_tlsext_use_srtp(SSL *ctx, const char *profiles);

View File

@@ -10,6 +10,9 @@ DTLS_server_method
DTLSv1_client_method
DTLSv1_method
DTLSv1_server_method
DTLSv1_2_client_method
DTLSv1_2_method
DTLSv1_2_server_method
SSLv23_client_method
SSLv23_method
SSLv23_server_method
@@ -33,6 +36,7 @@ d2i_SSL_SESSION
i2d_SSL_SESSION
ERR_load_SSL_strings
SSL_CIPHER_description
SSL_CIPHER_find
SSL_CIPHER_get_auth_nid
SSL_CIPHER_get_bits
SSL_CIPHER_get_by_id
@@ -61,6 +65,7 @@ SSL_CTX_free
SSL_CTX_get0_certificate
SSL_CTX_get0_chain_certs
SSL_CTX_get0_param
SSL_CTX_get0_privatekey
SSL_CTX_get_cert_store
SSL_CTX_get_ciphers
SSL_CTX_get_client_CA_list
@@ -70,9 +75,13 @@ SSL_CTX_get_default_passwd_cb_userdata
SSL_CTX_get_ex_data
SSL_CTX_get_ex_new_index
SSL_CTX_get_info_callback
SSL_CTX_get_keylog_callback
SSL_CTX_get_max_early_data
SSL_CTX_get_max_proto_version
SSL_CTX_get_min_proto_version
SSL_CTX_get_num_tickets
SSL_CTX_get_quiet_shutdown
SSL_CTX_get_ssl_method
SSL_CTX_get_timeout
SSL_CTX_get_verify_callback
SSL_CTX_get_verify_depth
@@ -98,6 +107,7 @@ SSL_CTX_set_alpn_select_cb
SSL_CTX_set_cert_store
SSL_CTX_set_cert_verify_callback
SSL_CTX_set_cipher_list
SSL_CTX_set_ciphersuites
SSL_CTX_set_client_CA_list
SSL_CTX_set_client_cert_cb
SSL_CTX_set_client_cert_engine
@@ -109,11 +119,15 @@ SSL_CTX_set_default_verify_paths
SSL_CTX_set_ex_data
SSL_CTX_set_generate_session_id
SSL_CTX_set_info_callback
SSL_CTX_set_keylog_callback
SSL_CTX_set_max_early_data
SSL_CTX_set_max_proto_version
SSL_CTX_set_min_proto_version
SSL_CTX_set_msg_callback
SSL_CTX_set_next_proto_select_cb
SSL_CTX_set_next_protos_advertised_cb
SSL_CTX_set_num_tickets
SSL_CTX_set_post_handshake_auth
SSL_CTX_set_purpose
SSL_CTX_set_quiet_shutdown
SSL_CTX_set_session_id_context
@@ -139,6 +153,7 @@ SSL_CTX_use_certificate_chain_file
SSL_CTX_use_certificate_chain_mem
SSL_CTX_use_certificate_file
SSL_SESSION_free
SSL_SESSION_get0_cipher
SSL_SESSION_get0_id_context
SSL_SESSION_get0_peer
SSL_SESSION_get_compress_id
@@ -146,17 +161,20 @@ SSL_SESSION_get_ex_data
SSL_SESSION_get_ex_new_index
SSL_SESSION_get_id
SSL_SESSION_get_master_key
SSL_SESSION_get_max_early_data
SSL_SESSION_get_protocol_version
SSL_SESSION_get_ticket_lifetime_hint
SSL_SESSION_get_time
SSL_SESSION_get_timeout
SSL_SESSION_has_ticket
SSL_SESSION_is_resumable
SSL_SESSION_new
SSL_SESSION_print
SSL_SESSION_print_fp
SSL_SESSION_set1_id
SSL_SESSION_set1_id_context
SSL_SESSION_set_ex_data
SSL_SESSION_set_max_early_data
SSL_SESSION_set_time
SSL_SESSION_set_timeout
SSL_SESSION_up_ref
@@ -187,6 +205,8 @@ SSL_get0_alpn_selected
SSL_get0_chain_certs
SSL_get0_next_proto_negotiated
SSL_get0_param
SSL_get0_peername
SSL_get0_verified_chain
SSL_get1_session
SSL_get1_supported_ciphers
SSL_get_SSL_CTX
@@ -200,6 +220,7 @@ SSL_get_current_cipher
SSL_get_current_compression
SSL_get_current_expansion
SSL_get_default_timeout
SSL_get_early_data_status
SSL_get_error
SSL_get_ex_data
SSL_get_ex_data_X509_STORE_CTX_idx
@@ -207,8 +228,10 @@ SSL_get_ex_new_index
SSL_get_fd
SSL_get_finished
SSL_get_info_callback
SSL_get_max_early_data
SSL_get_max_proto_version
SSL_get_min_proto_version
SSL_get_num_tickets
SSL_get_peer_cert_chain
SSL_get_peer_certificate
SSL_get_peer_finished
@@ -234,14 +257,18 @@ SSL_get_version
SSL_get_wbio
SSL_get_wfd
SSL_has_matching_session_id
SSL_is_dtls
SSL_is_server
SSL_library_init
SSL_load_client_CA_file
SSL_load_error_strings
SSL_new
SSL_peek
SSL_peek_ex
SSL_pending
SSL_read
SSL_read_early_data
SSL_read_ex
SSL_renegotiate
SSL_renegotiate_abbreviated
SSL_renegotiate_pending
@@ -249,6 +276,7 @@ SSL_rstate_string
SSL_rstate_string_long
SSL_select_next_proto
SSL_set0_chain
SSL_set0_rbio
SSL_set1_chain
SSL_set1_groups
SSL_set1_groups_list
@@ -259,16 +287,22 @@ SSL_set_accept_state
SSL_set_alpn_protos
SSL_set_bio
SSL_set_cipher_list
SSL_set_ciphersuites
SSL_set_client_CA_list
SSL_set_connect_state
SSL_set_debug
SSL_set_ex_data
SSL_set_fd
SSL_set_generate_session_id
SSL_set_hostflags
SSL_set_info_callback
SSL_set_max_early_data
SSL_set_max_proto_version
SSL_set_min_proto_version
SSL_set_msg_callback
SSL_set_num_tickets
SSL_set_post_handshake_auth
SSL_set_psk_use_session_callback
SSL_set_purpose
SSL_set_quiet_shutdown
SSL_set_read_ahead
@@ -303,9 +337,13 @@ SSL_use_RSAPrivateKey_ASN1
SSL_use_RSAPrivateKey_file
SSL_use_certificate
SSL_use_certificate_ASN1
SSL_use_certificate_chain_file
SSL_use_certificate_file
SSL_verify_client_post_handshake
SSL_version
SSL_version_str
SSL_want
SSL_write
SSL_write_early_data
SSL_write_ex
OPENSSL_init_ssl

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: ssl_algs.c,v 1.28 2019/04/04 16:44:24 jsing Exp $ */
/* $OpenBSD: ssl_algs.c,v 1.30 2022/01/14 08:38:48 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -60,6 +60,7 @@
#include <openssl/lhash.h>
#include <openssl/objects.h>
#include <openssl/opensslconf.h>
#include "ssl_locl.h"
@@ -112,7 +113,6 @@ SSL_library_init(void)
EVP_add_digest(EVP_sha256());
EVP_add_digest(EVP_sha384());
EVP_add_digest(EVP_sha512());
EVP_add_digest(EVP_ecdsa());
#ifndef OPENSSL_NO_GOST
EVP_add_digest(EVP_gostr341194());
EVP_add_digest(EVP_gost2814789imit());

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: ssl_asn1.c,v 1.57 2018/08/27 16:42:48 jsing Exp $ */
/* $OpenBSD: ssl_asn1.c,v 1.61 2022/01/11 18:39:28 jsing Exp $ */
/*
* Copyright (c) 2016 Joel Sing <jsing@openbsd.org>
*
@@ -20,9 +20,8 @@
#include <openssl/ssl.h>
#include <openssl/x509.h>
#include "ssl_locl.h"
#include "bytestring.h"
#include "ssl_locl.h"
#define SSLASN1_TAG (CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC)
#define SSLASN1_TIME_TAG (SSLASN1_TAG | 1)
@@ -114,8 +113,8 @@ SSL_SESSION_encode(SSL_SESSION *s, unsigned char **out, size_t *out_len,
}
/* Peer certificate [3]. */
if (s->peer != NULL) {
if ((len = i2d_X509(s->peer, &peer_cert_bytes)) <= 0)
if (s->peer_cert != NULL) {
if ((len = i2d_X509(s->peer_cert, &peer_cert_bytes)) <= 0)
goto err;
if (!CBB_add_asn1(&session, &peer_cert, SSLASN1_PEER_CERT_TAG))
goto err;
@@ -331,10 +330,10 @@ d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, long length)
goto err;
if (timeout != 0)
s->timeout = (long)timeout;
/* Peer certificate [3]. */
X509_free(s->peer);
s->peer = NULL;
X509_free(s->peer_cert);
s->peer_cert = NULL;
if (!CBS_get_optional_asn1(&session, &peer_cert, &present,
SSLASN1_PEER_CERT_TAG))
goto err;
@@ -343,7 +342,7 @@ d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, long length)
if (data_len > LONG_MAX)
goto err;
peer_cert_bytes = CBS_data(&peer_cert);
if (d2i_X509(&s->peer, &peer_cert_bytes,
if (d2i_X509(&s->peer_cert, &peer_cert_bytes,
(long)data_len) == NULL)
goto err;
}
@@ -383,22 +382,19 @@ d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, long length)
if (!CBS_strdup(&hostname, &s->tlsext_hostname))
goto err;
}
/* PSK identity hint [7]. */
/* PSK identity [8]. */
/* Ticket lifetime [9]. */
s->tlsext_tick_lifetime_hint = 0;
/* XXX - tlsext_ticklen is not yet set... */
if (s->tlsext_ticklen > 0 && s->session_id_length > 0)
s->tlsext_tick_lifetime_hint = -1;
if (!CBS_get_optional_asn1_uint64(&session, &lifetime,
SSLASN1_LIFETIME_TAG, 0))
goto err;
if (lifetime > LONG_MAX)
if (lifetime > UINT32_MAX)
goto err;
if (lifetime > 0)
s->tlsext_tick_lifetime_hint = (long)lifetime;
s->tlsext_tick_lifetime_hint = (uint32_t)lifetime;
/* Ticket [10]. */
free(s->tlsext_tick);
@@ -421,7 +417,7 @@ d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, long length)
return (s);
err:
err:
ERR_asprintf_error_data("offset=%d", (int)(CBS_data(&cbs) - *pp));
if (s != NULL && (a == NULL || *a != s))

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: ssl_both.c,v 1.20 2020/09/24 18:12:00 jsing Exp $ */
/* $OpenBSD: ssl_both.c,v 1.42 2022/02/05 14:54:10 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -118,14 +118,14 @@
#include <stdio.h>
#include <string.h>
#include "ssl_locl.h"
#include <openssl/buffer.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/x509.h>
#include "bytestring.h"
#include "dtls_locl.h"
#include "ssl_locl.h"
/*
* Send s->internal->init_buf in records of type 'type' (SSL3_RT_HANDSHAKE or
@@ -150,10 +150,8 @@ ssl3_do_write(SSL *s, int type)
(unsigned char *)&s->internal->init_buf->data[s->internal->init_off], ret);
if (ret == s->internal->init_num) {
if (s->internal->msg_callback)
s->internal->msg_callback(1, s->version, type, s->internal->init_buf->data,
(size_t)(s->internal->init_off + s->internal->init_num), s,
s->internal->msg_callback_arg);
ssl_msg_callback(s, 1, type, s->internal->init_buf->data,
(size_t)(s->internal->init_off + s->internal->init_num));
return (1);
}
@@ -164,42 +162,39 @@ ssl3_do_write(SSL *s, int type)
}
int
ssl3_send_finished(SSL *s, int a, int b, const char *sender, int slen)
ssl3_send_finished(SSL *s, int state_a, int state_b)
{
CBB cbb, finished;
int md_len;
memset(&cbb, 0, sizeof(cbb));
if (S3I(s)->hs.state == a) {
md_len = TLS1_FINISH_MAC_LENGTH;
OPENSSL_assert(md_len <= EVP_MAX_MD_SIZE);
if (tls1_final_finish_mac(s, sender, slen,
S3I(s)->tmp.finish_md) != md_len)
return (0);
S3I(s)->tmp.finish_md_len = md_len;
if (s->s3->hs.state == state_a) {
if (!tls12_derive_finished(s))
goto err;
/* Copy finished so we can use it for renegotiation checks. */
if (s->internal->type == SSL_ST_CONNECT) {
memcpy(S3I(s)->previous_client_finished,
S3I(s)->tmp.finish_md, md_len);
S3I(s)->previous_client_finished_len = md_len;
if (!s->server) {
memcpy(s->s3->previous_client_finished,
s->s3->hs.finished, s->s3->hs.finished_len);
s->s3->previous_client_finished_len =
s->s3->hs.finished_len;
} else {
memcpy(S3I(s)->previous_server_finished,
S3I(s)->tmp.finish_md, md_len);
S3I(s)->previous_server_finished_len = md_len;
memcpy(s->s3->previous_server_finished,
s->s3->hs.finished, s->s3->hs.finished_len);
s->s3->previous_server_finished_len =
s->s3->hs.finished_len;
}
if (!ssl3_handshake_msg_start(s, &cbb, &finished,
SSL3_MT_FINISHED))
goto err;
if (!CBB_add_bytes(&finished, S3I(s)->tmp.finish_md, md_len))
if (!CBB_add_bytes(&finished, s->s3->hs.finished,
s->s3->hs.finished_len))
goto err;
if (!ssl3_handshake_msg_finish(s, &cbb))
goto err;
S3I(s)->hs.state = b;
s->s3->hs.state = state_b;
}
return (ssl3_handshake_write(s));
@@ -210,104 +205,65 @@ ssl3_send_finished(SSL *s, int a, int b, const char *sender, int slen)
return (-1);
}
/*
* ssl3_take_mac calculates the Finished MAC for the handshakes messages seen
* so far.
*/
static void
ssl3_take_mac(SSL *s)
{
const char *sender;
int slen;
/*
* If no new cipher setup return immediately: other functions will
* set the appropriate error.
*/
if (S3I(s)->hs.new_cipher == NULL)
return;
if (S3I(s)->hs.state & SSL_ST_CONNECT) {
sender = TLS_MD_SERVER_FINISH_CONST;
slen = TLS_MD_SERVER_FINISH_CONST_SIZE;
} else {
sender = TLS_MD_CLIENT_FINISH_CONST;
slen = TLS_MD_CLIENT_FINISH_CONST_SIZE;
}
S3I(s)->tmp.peer_finish_md_len =
tls1_final_finish_mac(s, sender, slen,
S3I(s)->tmp.peer_finish_md);
}
int
ssl3_get_finished(SSL *s, int a, int b)
{
int al, ok, md_len;
long n;
int al, md_len, ret;
CBS cbs;
/* should actually be 36+4 :-) */
n = ssl3_get_message(s, a, b, SSL3_MT_FINISHED, 64, &ok);
if (!ok)
return ((int)n);
if ((ret = ssl3_get_message(s, a, b, SSL3_MT_FINISHED, 64)) <= 0)
return ret;
/* If this occurs, we have missed a message */
if (!S3I(s)->change_cipher_spec) {
if (!s->s3->change_cipher_spec) {
al = SSL_AD_UNEXPECTED_MESSAGE;
SSLerror(s, SSL_R_GOT_A_FIN_BEFORE_A_CCS);
goto f_err;
goto fatal_err;
}
S3I(s)->change_cipher_spec = 0;
s->s3->change_cipher_spec = 0;
md_len = TLS1_FINISH_MAC_LENGTH;
if (n < 0) {
if (s->internal->init_num < 0) {
al = SSL_AD_DECODE_ERROR;
SSLerror(s, SSL_R_BAD_DIGEST_LENGTH);
goto f_err;
goto fatal_err;
}
CBS_init(&cbs, s->internal->init_msg, n);
CBS_init(&cbs, s->internal->init_msg, s->internal->init_num);
if (S3I(s)->tmp.peer_finish_md_len != md_len ||
if (s->s3->hs.peer_finished_len != md_len ||
CBS_len(&cbs) != md_len) {
al = SSL_AD_DECODE_ERROR;
SSLerror(s, SSL_R_BAD_DIGEST_LENGTH);
goto f_err;
goto fatal_err;
}
if (!CBS_mem_equal(&cbs, S3I(s)->tmp.peer_finish_md, CBS_len(&cbs))) {
if (!CBS_mem_equal(&cbs, s->s3->hs.peer_finished, CBS_len(&cbs))) {
al = SSL_AD_DECRYPT_ERROR;
SSLerror(s, SSL_R_DIGEST_CHECK_FAILED);
goto f_err;
goto fatal_err;
}
/* Copy finished so we can use it for renegotiation checks. */
OPENSSL_assert(md_len <= EVP_MAX_MD_SIZE);
if (s->internal->type == SSL_ST_ACCEPT) {
memcpy(S3I(s)->previous_client_finished,
S3I(s)->tmp.peer_finish_md, md_len);
S3I(s)->previous_client_finished_len = md_len;
if (s->server) {
memcpy(s->s3->previous_client_finished,
s->s3->hs.peer_finished, md_len);
s->s3->previous_client_finished_len = md_len;
} else {
memcpy(S3I(s)->previous_server_finished,
S3I(s)->tmp.peer_finish_md, md_len);
S3I(s)->previous_server_finished_len = md_len;
memcpy(s->s3->previous_server_finished,
s->s3->hs.peer_finished, md_len);
s->s3->previous_server_finished_len = md_len;
}
return (1);
f_err:
fatal_err:
ssl3_send_alert(s, SSL3_AL_FATAL, al);
return (0);
}
/* for these 2 messages, we need to
* ssl->enc_read_ctx re-init
* ssl->s3->internal->read_sequence zero
* ssl->s3->internal->read_mac_secret re-init
* ssl->session->read_sym_enc assign
* ssl->session->read_hash assign
*/
int
ssl3_send_change_cipher_spec(SSL *s, int a, int b)
{
@@ -316,7 +272,7 @@ ssl3_send_change_cipher_spec(SSL *s, int a, int b)
memset(&cbb, 0, sizeof(cbb));
if (S3I(s)->hs.state == a) {
if (s->s3->hs.state == a) {
if (!CBB_init_fixed(&cbb, s->internal->init_buf->data,
s->internal->init_buf->length))
goto err;
@@ -331,15 +287,15 @@ ssl3_send_change_cipher_spec(SSL *s, int a, int b)
s->internal->init_num = (int)outlen;
s->internal->init_off = 0;
if (SSL_IS_DTLS(s)) {
D1I(s)->handshake_write_seq =
D1I(s)->next_handshake_write_seq;
if (SSL_is_dtls(s)) {
s->d1->handshake_write_seq =
s->d1->next_handshake_write_seq;
dtls1_set_message_header_int(s, SSL3_MT_CCS, 0,
D1I(s)->handshake_write_seq, 0, 0);
s->d1->handshake_write_seq, 0, 0);
dtls1_buffer_message(s, 1);
}
S3I(s)->hs.state = b;
s->s3->hs.state = b;
}
/* SSL3_ST_CW_CHANGE_B */
@@ -378,7 +334,7 @@ ssl3_add_cert(CBB *cbb, X509 *x)
}
int
ssl3_output_cert_chain(SSL *s, CBB *cbb, CERT_PKEY *cpk)
ssl3_output_cert_chain(SSL *s, CBB *cbb, SSL_CERT_PKEY *cpk)
{
X509_STORE_CTX *xs_ctx = NULL;
STACK_OF(X509) *chain;
@@ -408,9 +364,11 @@ ssl3_output_cert_chain(SSL *s, CBB *cbb, CERT_PKEY *cpk)
SSLerror(s, ERR_R_X509_LIB);
goto err;
}
X509_VERIFY_PARAM_set_flags(X509_STORE_CTX_get0_param(xs_ctx),
X509_V_FLAG_LEGACY_VERIFY);
X509_verify_cert(xs_ctx);
ERR_clear_error();
chain = xs_ctx->chain;
chain = X509_STORE_CTX_get0_chain(xs_ctx);
}
for (i = 0; i < sk_X509_num(chain); i++) {
@@ -437,8 +395,8 @@ ssl3_output_cert_chain(SSL *s, CBB *cbb, CERT_PKEY *cpk)
* The first four bytes (msg_type and length) are read in state 'st1',
* the body is read in state 'stn'.
*/
long
ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok)
int
ssl3_get_message(SSL *s, int st1, int stn, int mt, long max)
{
unsigned char *p;
uint32_t l;
@@ -447,36 +405,34 @@ ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok)
CBS cbs;
uint8_t u8;
if (SSL_IS_DTLS(s))
return (dtls1_get_message(s, st1, stn, mt, max, ok));
if (SSL_is_dtls(s))
return dtls1_get_message(s, st1, stn, mt, max);
if (S3I(s)->tmp.reuse_message) {
S3I(s)->tmp.reuse_message = 0;
if ((mt >= 0) && (S3I(s)->tmp.message_type != mt)) {
if (s->s3->hs.tls12.reuse_message) {
s->s3->hs.tls12.reuse_message = 0;
if ((mt >= 0) && (s->s3->hs.tls12.message_type != mt)) {
al = SSL_AD_UNEXPECTED_MESSAGE;
SSLerror(s, SSL_R_UNEXPECTED_MESSAGE);
goto f_err;
goto fatal_err;
}
*ok = 1;
s->internal->init_msg = s->internal->init_buf->data + 4;
s->internal->init_num = (int)S3I(s)->tmp.message_size;
return s->internal->init_num;
s->internal->init_msg = s->internal->init_buf->data +
SSL3_HM_HEADER_LENGTH;
s->internal->init_num = (int)s->s3->hs.tls12.message_size;
return 1;
}
p = (unsigned char *)s->internal->init_buf->data;
/* s->internal->init_num < 4 */
if (S3I(s)->hs.state == st1) {
if (s->s3->hs.state == st1) {
int skip_message;
do {
while (s->internal->init_num < 4) {
i = s->method->internal->ssl_read_bytes(s,
while (s->internal->init_num < SSL3_HM_HEADER_LENGTH) {
i = s->method->ssl_read_bytes(s,
SSL3_RT_HANDSHAKE, &p[s->internal->init_num],
4 - s->internal->init_num, 0);
SSL3_HM_HEADER_LENGTH - s->internal->init_num, 0);
if (i <= 0) {
s->internal->rwstate = SSL_READING;
*ok = 0;
return i;
}
s->internal->init_num += i;
@@ -494,115 +450,94 @@ ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok)
s->internal->init_num = 0;
skip_message = 1;
if (s->internal->msg_callback)
s->internal->msg_callback(0, s->version,
SSL3_RT_HANDSHAKE, p, 4, s,
s->internal->msg_callback_arg);
ssl_msg_callback(s, 0,
SSL3_RT_HANDSHAKE, p,
SSL3_HM_HEADER_LENGTH);
}
}
} while (skip_message);
/* s->internal->init_num == 4 */
if ((mt >= 0) && (*p != mt)) {
al = SSL_AD_UNEXPECTED_MESSAGE;
SSLerror(s, SSL_R_UNEXPECTED_MESSAGE);
goto f_err;
goto fatal_err;
}
CBS_init(&cbs, p, 4);
CBS_init(&cbs, p, SSL3_HM_HEADER_LENGTH);
if (!CBS_get_u8(&cbs, &u8) ||
!CBS_get_u24(&cbs, &l)) {
SSLerror(s, ERR_R_BUF_LIB);
goto err;
}
S3I(s)->tmp.message_type = u8;
s->s3->hs.tls12.message_type = u8;
if (l > (unsigned long)max) {
al = SSL_AD_ILLEGAL_PARAMETER;
SSLerror(s, SSL_R_EXCESSIVE_MESSAGE_SIZE);
goto f_err;
goto fatal_err;
}
if (l && !BUF_MEM_grow_clean(s->internal->init_buf, l + 4)) {
if (l && !BUF_MEM_grow_clean(s->internal->init_buf,
l + SSL3_HM_HEADER_LENGTH)) {
SSLerror(s, ERR_R_BUF_LIB);
goto err;
}
S3I(s)->tmp.message_size = l;
S3I(s)->hs.state = stn;
s->s3->hs.tls12.message_size = l;
s->s3->hs.state = stn;
s->internal->init_msg = s->internal->init_buf->data + 4;
s->internal->init_msg = s->internal->init_buf->data +
SSL3_HM_HEADER_LENGTH;
s->internal->init_num = 0;
}
/* next state (stn) */
p = s->internal->init_msg;
n = S3I(s)->tmp.message_size - s->internal->init_num;
n = s->s3->hs.tls12.message_size - s->internal->init_num;
while (n > 0) {
i = s->method->internal->ssl_read_bytes(s, SSL3_RT_HANDSHAKE,
i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE,
&p[s->internal->init_num], n, 0);
if (i <= 0) {
s->internal->rwstate = SSL_READING;
*ok = 0;
return i;
}
s->internal->init_num += i;
n -= i;
}
/* If receiving Finished, record MAC of prior handshake messages for
* Finished verification. */
if (*s->internal->init_buf->data == SSL3_MT_FINISHED)
ssl3_take_mac(s);
/* Feed this message into MAC computation. */
if (s->internal->mac_packet) {
tls1_transcript_record(s, (unsigned char *)s->internal->init_buf->data,
s->internal->init_num + 4);
s->internal->init_num + SSL3_HM_HEADER_LENGTH);
if (s->internal->msg_callback)
s->internal->msg_callback(0, s->version,
SSL3_RT_HANDSHAKE, s->internal->init_buf->data,
(size_t)s->internal->init_num + 4, s,
s->internal->msg_callback_arg);
ssl_msg_callback(s, 0, SSL3_RT_HANDSHAKE,
s->internal->init_buf->data,
(size_t)s->internal->init_num + SSL3_HM_HEADER_LENGTH);
}
*ok = 1;
return (s->internal->init_num);
return 1;
f_err:
fatal_err:
ssl3_send_alert(s, SSL3_AL_FATAL, al);
err:
*ok = 0;
return (-1);
err:
return -1;
}
int
ssl_cert_type(X509 *x, EVP_PKEY *pkey)
ssl_cert_type(EVP_PKEY *pkey)
{
EVP_PKEY *pk;
int ret = -1, i;
if (pkey == NULL)
pk = X509_get_pubkey(x);
else
pk = pkey;
if (pk == NULL)
goto err;
return -1;
i = pk->type;
if (i == EVP_PKEY_RSA) {
ret = SSL_PKEY_RSA;
} else if (i == EVP_PKEY_EC) {
ret = SSL_PKEY_ECC;
} else if (i == NID_id_GostR3410_2001 ||
i == NID_id_GostR3410_2001_cc) {
ret = SSL_PKEY_GOST01;
switch (EVP_PKEY_id(pkey)) {
case EVP_PKEY_EC:
return SSL_PKEY_ECC;
case NID_id_GostR3410_2001:
case NID_id_GostR3410_2001_cc:
return SSL_PKEY_GOST01;
case EVP_PKEY_RSA:
return SSL_PKEY_RSA;
}
err:
if (!pkey)
EVP_PKEY_free(pk);
return (ret);
return -1;
}
int
@@ -681,7 +616,7 @@ ssl3_setup_init_buffer(SSL *s)
s->internal->init_buf = buf;
return (1);
err:
err:
BUF_MEM_free(buf);
return (0);
}
@@ -702,26 +637,26 @@ ssl3_setup_read_buffer(SSL *s)
unsigned char *p;
size_t len, align, headerlen;
if (SSL_IS_DTLS(s))
if (SSL_is_dtls(s))
headerlen = DTLS1_RT_HEADER_LENGTH;
else
headerlen = SSL3_RT_HEADER_LENGTH;
align = (-SSL3_RT_HEADER_LENGTH) & (SSL3_ALIGN_PAYLOAD - 1);
if (S3I(s)->rbuf.buf == NULL) {
if (s->s3->rbuf.buf == NULL) {
len = SSL3_RT_MAX_PLAIN_LENGTH +
SSL3_RT_MAX_ENCRYPTED_OVERHEAD + headerlen + align;
if ((p = calloc(1, len)) == NULL)
goto err;
S3I(s)->rbuf.buf = p;
S3I(s)->rbuf.len = len;
s->s3->rbuf.buf = p;
s->s3->rbuf.len = len;
}
s->internal->packet = S3I(s)->rbuf.buf;
s->internal->packet = s->s3->rbuf.buf;
return 1;
err:
err:
SSLerror(s, ERR_R_MALLOC_FAILURE);
return 0;
}
@@ -732,14 +667,14 @@ ssl3_setup_write_buffer(SSL *s)
unsigned char *p;
size_t len, align, headerlen;
if (SSL_IS_DTLS(s))
if (SSL_is_dtls(s))
headerlen = DTLS1_RT_HEADER_LENGTH + 1;
else
headerlen = SSL3_RT_HEADER_LENGTH;
align = (-SSL3_RT_HEADER_LENGTH) & (SSL3_ALIGN_PAYLOAD - 1);
if (S3I(s)->wbuf.buf == NULL) {
if (s->s3->wbuf.buf == NULL) {
len = s->max_send_fragment +
SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD + headerlen + align;
if (!(s->internal->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS))
@@ -748,13 +683,13 @@ ssl3_setup_write_buffer(SSL *s)
if ((p = calloc(1, len)) == NULL)
goto err;
S3I(s)->wbuf.buf = p;
S3I(s)->wbuf.len = len;
s->s3->wbuf.buf = p;
s->s3->wbuf.len = len;
}
return 1;
err:
err:
SSLerror(s, ERR_R_MALLOC_FAILURE);
return 0;
}
@@ -780,11 +715,11 @@ ssl3_release_buffer(SSL3_BUFFER_INTERNAL *b)
void
ssl3_release_read_buffer(SSL *s)
{
ssl3_release_buffer(&S3I(s)->rbuf);
ssl3_release_buffer(&s->s3->rbuf);
}
void
ssl3_release_write_buffer(SSL *s)
{
ssl3_release_buffer(&S3I(s)->wbuf);
ssl3_release_buffer(&s->s3->wbuf);
}

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: ssl_cert.c,v 1.78 2020/06/05 17:55:24 jsing Exp $ */
/* $OpenBSD: ssl_cert.c,v 1.95 2022/02/05 14:54:10 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -158,12 +158,12 @@ SSL_get_ex_data_X509_STORE_CTX_idx(void)
return ssl_x509_store_ctx_idx;
}
CERT *
SSL_CERT *
ssl_cert_new(void)
{
CERT *ret;
SSL_CERT *ret;
ret = calloc(1, sizeof(CERT));
ret = calloc(1, sizeof(SSL_CERT));
if (ret == NULL) {
SSLerrorx(ERR_R_MALLOC_FAILURE);
return (NULL);
@@ -173,13 +173,13 @@ ssl_cert_new(void)
return (ret);
}
CERT *
ssl_cert_dup(CERT *cert)
SSL_CERT *
ssl_cert_dup(SSL_CERT *cert)
{
CERT *ret;
SSL_CERT *ret;
int i;
ret = calloc(1, sizeof(CERT));
ret = calloc(1, sizeof(SSL_CERT));
if (ret == NULL) {
SSLerrorx(ERR_R_MALLOC_FAILURE);
return (NULL);
@@ -195,44 +195,25 @@ ssl_cert_dup(CERT *cert)
ret->mask_k = cert->mask_k;
ret->mask_a = cert->mask_a;
if (cert->dh_tmp != NULL) {
ret->dh_tmp = DHparams_dup(cert->dh_tmp);
if (ret->dh_tmp == NULL) {
if (cert->dhe_params != NULL) {
ret->dhe_params = DHparams_dup(cert->dhe_params);
if (ret->dhe_params == NULL) {
SSLerrorx(ERR_R_DH_LIB);
goto err;
}
if (cert->dh_tmp->priv_key) {
BIGNUM *b = BN_dup(cert->dh_tmp->priv_key);
if (!b) {
SSLerrorx(ERR_R_BN_LIB);
goto err;
}
ret->dh_tmp->priv_key = b;
}
if (cert->dh_tmp->pub_key) {
BIGNUM *b = BN_dup(cert->dh_tmp->pub_key);
if (!b) {
SSLerrorx(ERR_R_BN_LIB);
goto err;
}
ret->dh_tmp->pub_key = b;
}
}
ret->dh_tmp_cb = cert->dh_tmp_cb;
ret->dh_tmp_auto = cert->dh_tmp_auto;
ret->dhe_params_cb = cert->dhe_params_cb;
ret->dhe_params_auto = cert->dhe_params_auto;
for (i = 0; i < SSL_PKEY_NUM; i++) {
if (cert->pkeys[i].x509 != NULL) {
ret->pkeys[i].x509 = cert->pkeys[i].x509;
CRYPTO_add(&ret->pkeys[i].x509->references, 1,
CRYPTO_LOCK_X509);
X509_up_ref(ret->pkeys[i].x509);
}
if (cert->pkeys[i].privatekey != NULL) {
ret->pkeys[i].privatekey = cert->pkeys[i].privatekey;
CRYPTO_add(&ret->pkeys[i].privatekey->references, 1,
CRYPTO_LOCK_EVP_PKEY);
EVP_PKEY_up_ref(ret->pkeys[i].privatekey);
switch (i) {
/*
* If there was anything special to do for
@@ -275,7 +256,7 @@ ssl_cert_dup(CERT *cert)
return (ret);
err:
DH_free(ret->dh_tmp);
DH_free(ret->dhe_params);
for (i = 0; i < SSL_PKEY_NUM; i++) {
X509_free(ret->pkeys[i].x509);
@@ -288,7 +269,7 @@ ssl_cert_dup(CERT *cert)
void
ssl_cert_free(CERT *c)
ssl_cert_free(SSL_CERT *c)
{
int i;
@@ -299,7 +280,7 @@ ssl_cert_free(CERT *c)
if (i > 0)
return;
DH_free(c->dh_tmp);
DH_free(c->dhe_params);
for (i = 0; i < SSL_PKEY_NUM; i++) {
X509_free(c->pkeys[i].x509);
@@ -311,7 +292,7 @@ ssl_cert_free(CERT *c)
}
int
ssl_cert_set0_chain(CERT *c, STACK_OF(X509) *chain)
ssl_cert_set0_chain(SSL_CERT *c, STACK_OF(X509) *chain)
{
if (c->key == NULL)
return 0;
@@ -323,7 +304,7 @@ ssl_cert_set0_chain(CERT *c, STACK_OF(X509) *chain)
}
int
ssl_cert_set1_chain(CERT *c, STACK_OF(X509) *chain)
ssl_cert_set1_chain(SSL_CERT *c, STACK_OF(X509) *chain)
{
STACK_OF(X509) *new_chain = NULL;
@@ -340,7 +321,7 @@ ssl_cert_set1_chain(CERT *c, STACK_OF(X509) *chain)
}
int
ssl_cert_add0_chain_cert(CERT *c, X509 *cert)
ssl_cert_add0_chain_cert(SSL_CERT *c, X509 *cert)
{
if (c->key == NULL)
return 0;
@@ -356,7 +337,7 @@ ssl_cert_add0_chain_cert(CERT *c, X509 *cert)
}
int
ssl_cert_add1_chain_cert(CERT *c, X509 *cert)
ssl_cert_add1_chain_cert(SSL_CERT *c, X509 *cert)
{
if (!ssl_cert_add0_chain_cert(c, cert))
return 0;
@@ -366,88 +347,61 @@ ssl_cert_add1_chain_cert(CERT *c, X509 *cert)
return 1;
}
SESS_CERT *
ssl_sess_cert_new(void)
{
SESS_CERT *ret;
ret = calloc(1, sizeof *ret);
if (ret == NULL) {
SSLerrorx(ERR_R_MALLOC_FAILURE);
return NULL;
}
ret->peer_key = &(ret->peer_pkeys[SSL_PKEY_RSA]);
ret->references = 1;
return ret;
}
void
ssl_sess_cert_free(SESS_CERT *sc)
{
int i;
if (sc == NULL)
return;
i = CRYPTO_add(&sc->references, -1, CRYPTO_LOCK_SSL_SESS_CERT);
if (i > 0)
return;
sk_X509_pop_free(sc->cert_chain, X509_free);
for (i = 0; i < SSL_PKEY_NUM; i++)
X509_free(sc->peer_pkeys[i].x509);
DH_free(sc->peer_dh_tmp);
EC_KEY_free(sc->peer_ecdh_tmp);
free(sc->peer_x25519_tmp);
free(sc);
}
int
ssl_verify_cert_chain(SSL *s, STACK_OF(X509) *sk)
{
X509_STORE_CTX ctx;
X509_STORE_CTX *ctx = NULL;
X509 *x;
int ret;
int ret = 0;
if ((sk == NULL) || (sk_X509_num(sk) == 0))
return (0);
goto err;
if ((ctx = X509_STORE_CTX_new()) == NULL)
goto err;
x = sk_X509_value(sk, 0);
if (!X509_STORE_CTX_init(&ctx, s->ctx->cert_store, x, sk)) {
if (!X509_STORE_CTX_init(ctx, s->ctx->cert_store, x, sk)) {
SSLerror(s, ERR_R_X509_LIB);
return (0);
goto err;
}
X509_STORE_CTX_set_ex_data(&ctx,
SSL_get_ex_data_X509_STORE_CTX_idx(), s);
X509_STORE_CTX_set_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx(), s);
/*
* We need to inherit the verify parameters. These can be
* determined by the context: if its a server it will verify
* SSL client certificates or vice versa.
*/
X509_STORE_CTX_set_default(&ctx,
s->server ? "ssl_client" : "ssl_server");
X509_STORE_CTX_set_default(ctx, s->server ? "ssl_client" : "ssl_server");
/*
* Anything non-default in "param" should overwrite anything
* in the ctx.
*/
X509_VERIFY_PARAM_set1(X509_STORE_CTX_get0_param(&ctx), s->param);
X509_VERIFY_PARAM_set1(X509_STORE_CTX_get0_param(ctx), s->param);
if (s->internal->verify_callback)
X509_STORE_CTX_set_verify_cb(&ctx, s->internal->verify_callback);
X509_STORE_CTX_set_verify_cb(ctx, s->internal->verify_callback);
if (s->ctx->internal->app_verify_callback != NULL)
ret = s->ctx->internal->app_verify_callback(&ctx,
ret = s->ctx->internal->app_verify_callback(ctx,
s->ctx->internal->app_verify_arg);
else
ret = X509_verify_cert(&ctx);
ret = X509_verify_cert(ctx);
s->verify_result = ctx.error;
X509_STORE_CTX_cleanup(&ctx);
s->verify_result = X509_STORE_CTX_get_error(ctx);
sk_X509_pop_free(s->internal->verified_chain, X509_free);
s->internal->verified_chain = NULL;
if (X509_STORE_CTX_get0_chain(ctx) != NULL) {
s->internal->verified_chain = X509_STORE_CTX_get1_chain(ctx);
if (s->internal->verified_chain == NULL) {
SSLerrorx(ERR_R_MALLOC_FAILURE);
ret = 0;
}
}
err:
X509_STORE_CTX_free(ctx);
return (ret);
}
@@ -505,10 +459,10 @@ SSL_CTX_get_client_CA_list(const SSL_CTX *ctx)
STACK_OF(X509_NAME) *
SSL_get_client_CA_list(const SSL *s)
{
if (s->internal->type == SSL_ST_CONNECT) {
if (!s->server) {
/* We are in the client. */
if ((s->version >> 8) == SSL3_VERSION_MAJOR)
return (S3I(s)->tmp.ca_names);
return (s->s3->hs.tls12.ca_names);
else
return (NULL);
} else {
@@ -575,7 +529,7 @@ SSL_load_client_CA_file(const char *file)
sk = sk_X509_NAME_new(xname_cmp);
in = BIO_new(BIO_s_file_internal());
in = BIO_new(BIO_s_file());
if ((sk == NULL) || (in == NULL)) {
SSLerrorx(ERR_R_MALLOC_FAILURE);
@@ -595,21 +549,24 @@ SSL_load_client_CA_file(const char *file)
goto err;
}
}
if ((xn = X509_get_subject_name(x)) == NULL) goto err;
/* check for duplicates */
if ((xn = X509_get_subject_name(x)) == NULL)
goto err;
/* check for duplicates */
xn = X509_NAME_dup(xn);
if (xn == NULL)
goto err;
if (sk_X509_NAME_find(sk, xn) >= 0)
X509_NAME_free(xn);
else {
sk_X509_NAME_push(sk, xn);
sk_X509_NAME_push(ret, xn);
if (!sk_X509_NAME_push(sk, xn))
goto err;
if (!sk_X509_NAME_push(ret, xn))
goto err;
}
}
if (0) {
err:
err:
sk_X509_NAME_pop_free(ret, X509_NAME_free);
ret = NULL;
}
@@ -643,7 +600,7 @@ SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack,
oldcmp = sk_X509_NAME_set_cmp_func(stack, xname_cmp);
in = BIO_new(BIO_s_file_internal());
in = BIO_new(BIO_s_file());
if (in == NULL) {
SSLerrorx(ERR_R_MALLOC_FAILURE);
@@ -656,20 +613,22 @@ SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack,
for (;;) {
if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL)
break;
if ((xn = X509_get_subject_name(x)) == NULL) goto err;
xn = X509_NAME_dup(xn);
if ((xn = X509_get_subject_name(x)) == NULL)
goto err;
xn = X509_NAME_dup(xn);
if (xn == NULL)
goto err;
if (sk_X509_NAME_find(stack, xn) >= 0)
X509_NAME_free(xn);
else
sk_X509_NAME_push(stack, xn);
if (!sk_X509_NAME_push(stack, xn))
goto err;
}
ERR_clear_error();
if (0) {
err:
err:
ret = 0;
}
BIO_free(in);

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: ssl_ciph.c,v 1.119 2020/09/13 16:49:05 jsing Exp $ */
/* $OpenBSD: ssl_ciph.c,v 1.127 2022/03/05 07:13:48 bket Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -143,6 +143,7 @@
#include <stdio.h>
#include <openssl/objects.h>
#include <openssl/opensslconf.h>
#ifndef OPENSSL_NO_ENGINE
#include <openssl/engine.h>
@@ -447,7 +448,7 @@ ssl_cipher_get_evp(const SSL_SESSION *ss, const EVP_CIPHER **enc,
/*
* This function does not handle EVP_AEAD.
* See ssl_cipher_get_aead_evp instead.
* See ssl_cipher_get_evp_aead instead.
*/
if (ss->cipher->algorithm_mac & SSL_AEAD)
return 0;
@@ -559,9 +560,21 @@ ssl_cipher_get_evp_aead(const SSL_SESSION *ss, const EVP_AEAD **aead)
int
ssl_get_handshake_evp_md(SSL *s, const EVP_MD **md)
{
unsigned long handshake_mac;
*md = NULL;
switch (ssl_get_algorithm2(s) & SSL_HANDSHAKE_MAC_MASK) {
if (s->s3->hs.cipher == NULL)
return 0;
handshake_mac = s->s3->hs.cipher->algorithm2 &
SSL_HANDSHAKE_MAC_MASK;
/* For TLSv1.2 we upgrade the default MD5+SHA1 MAC to SHA256. */
if (SSL_USE_SHA256_PRF(s) && handshake_mac == SSL_HANDSHAKE_MAC_DEFAULT)
handshake_mac = SSL_HANDSHAKE_MAC_SHA256;
switch (handshake_mac) {
case SSL_HANDSHAKE_MAC_DEFAULT:
*md = EVP_md5_sha1();
return 1;
@@ -668,7 +681,10 @@ ssl_cipher_collect_ciphers(const SSL_METHOD *ssl_method, int num_of_ciphers,
co_list_num = 0; /* actual count of ciphers */
for (i = 0; i < num_of_ciphers; i++) {
c = ssl_method->get_cipher(i);
/* drop those that use any of that is not available */
/*
* Drop any invalid ciphers and any which use unavailable
* algorithms.
*/
if ((c != NULL) && c->valid &&
!(c->algorithm_mkey & disabled_mkey) &&
!(c->algorithm_auth & disabled_auth) &&
@@ -1215,7 +1231,7 @@ ssl_create_cipher_list(const SSL_METHOD *ssl_method,
* in ciphers. We cannot get more than the number compiled in, so
* it is used for allocation.
*/
num_of_ciphers = ssl_method->num_ciphers();
num_of_ciphers = ssl3_num_ciphers();
co_list = reallocarray(NULL, num_of_ciphers, sizeof(CIPHER_ORDER));
if (co_list == NULL) {
SSLerrorx(ERR_R_MALLOC_FAILURE);
@@ -1587,6 +1603,20 @@ SSL_CIPHER_get_value(const SSL_CIPHER *c)
return ssl3_cipher_get_value(c);
}
const SSL_CIPHER *
SSL_CIPHER_find(SSL *ssl, const unsigned char *ptr)
{
uint16_t cipher_value;
CBS cbs;
/* This API is documented with ptr being an array of length two. */
CBS_init(&cbs, ptr, 2);
if (!CBS_get_u16(&cbs, &cipher_value))
return NULL;
return ssl3_get_cipher_by_value(cipher_value);
}
int
SSL_CIPHER_get_cipher_nid(const SSL_CIPHER *c)
{

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: ssl_ciphers.c,v 1.9 2020/09/15 15:28:38 schwarze Exp $ */
/* $OpenBSD: ssl_ciphers.c,v 1.13 2022/02/05 18:18:18 tb Exp $ */
/*
* Copyright (c) 2015-2017 Doug Hogan <doug@openbsd.org>
* Copyright (c) 2015-2018, 2020 Joel Sing <jsing@openbsd.org>
@@ -36,28 +36,17 @@ ssl_cipher_in_list(STACK_OF(SSL_CIPHER) *ciphers, const SSL_CIPHER *cipher)
}
int
ssl_cipher_allowed_in_version_range(const SSL_CIPHER *cipher, uint16_t min_ver,
ssl_cipher_allowed_in_tls_version_range(const SSL_CIPHER *cipher, uint16_t min_ver,
uint16_t max_ver)
{
/* XXX: We only support DTLSv1 which is effectively TLSv1.1 */
if (min_ver == DTLS1_VERSION || max_ver == DTLS1_VERSION)
min_ver = max_ver = TLS1_1_VERSION;
switch(cipher->algorithm_ssl) {
case SSL_SSLV3:
if (min_ver <= TLS1_2_VERSION)
return 1;
break;
return (min_ver <= TLS1_2_VERSION);
case SSL_TLSV1_2:
if (min_ver <= TLS1_2_VERSION && TLS1_2_VERSION <= max_ver)
return 1;
break;
return (min_ver <= TLS1_2_VERSION && TLS1_2_VERSION <= max_ver);
case SSL_TLSV1_3:
if (min_ver <= TLS1_3_VERSION && TLS1_3_VERSION <= max_ver)
return 1;
break;
return (min_ver <= TLS1_3_VERSION && TLS1_3_VERSION <= max_ver);
}
return 0;
}
@@ -72,13 +61,13 @@ ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *ciphers, CBB *cbb)
if (ciphers == NULL)
return 0;
if (!ssl_supported_version_range(s, &min_vers, &max_vers))
if (!ssl_supported_tls_version_range(s, &min_vers, &max_vers))
return 0;
for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) {
if ((cipher = sk_SSL_CIPHER_value(ciphers, i)) == NULL)
return 0;
if (!ssl_cipher_allowed_in_version_range(cipher, min_vers,
if (!ssl_cipher_allowed_in_tls_version_range(cipher, min_vers,
max_vers))
continue;
if (!CBB_add_u16(cbb, ssl3_cipher_get_value(cipher)))
@@ -104,10 +93,10 @@ ssl_bytes_to_cipher_list(SSL *s, CBS *cbs)
{
STACK_OF(SSL_CIPHER) *ciphers = NULL;
const SSL_CIPHER *cipher;
uint16_t cipher_value, max_version;
uint16_t cipher_value;
unsigned long cipher_id;
S3I(s)->send_connection_binding = 0;
s->s3->send_connection_binding = 0;
if ((ciphers = sk_SSL_CIPHER_new_null()) == NULL) {
SSLerror(s, ERR_R_MALLOC_FAILURE);
@@ -134,7 +123,7 @@ ssl_bytes_to_cipher_list(SSL *s, CBS *cbs)
goto err;
}
S3I(s)->send_connection_binding = 1;
s->s3->send_connection_binding = 1;
continue;
}
@@ -145,9 +134,8 @@ ssl_bytes_to_cipher_list(SSL *s, CBS *cbs)
* Fail if the current version is an unexpected
* downgrade.
*/
if (!ssl_downgrade_max_version(s, &max_version))
goto err;
if (s->version < max_version) {
if (s->s3->hs.negotiated_tls_version <
s->s3->hs.our_max_tls_version) {
SSLerror(s, SSL_R_INAPPROPRIATE_FALLBACK);
ssl3_send_alert(s, SSL3_AL_FATAL,
SSL_AD_INAPPROPRIATE_FALLBACK);
@@ -180,28 +168,28 @@ struct ssl_tls13_ciphersuite {
static const struct ssl_tls13_ciphersuite ssl_tls13_ciphersuites[] = {
{
.name = TLS1_3_TXT_AES_128_GCM_SHA256,
.alias = "TLS_AES_128_GCM_SHA256",
.name = TLS1_3_RFC_AES_128_GCM_SHA256,
.alias = TLS1_3_TXT_AES_128_GCM_SHA256,
.cid = TLS1_3_CK_AES_128_GCM_SHA256,
},
{
.name = TLS1_3_TXT_AES_256_GCM_SHA384,
.alias = "TLS_AES_256_GCM_SHA384",
.name = TLS1_3_RFC_AES_256_GCM_SHA384,
.alias = TLS1_3_TXT_AES_256_GCM_SHA384,
.cid = TLS1_3_CK_AES_256_GCM_SHA384,
},
{
.name = TLS1_3_TXT_CHACHA20_POLY1305_SHA256,
.alias = "TLS_CHACHA20_POLY1305_SHA256",
.name = TLS1_3_RFC_CHACHA20_POLY1305_SHA256,
.alias = TLS1_3_TXT_CHACHA20_POLY1305_SHA256,
.cid = TLS1_3_CK_CHACHA20_POLY1305_SHA256,
},
{
.name = TLS1_3_TXT_AES_128_CCM_SHA256,
.alias = "TLS_AES_128_CCM_SHA256",
.name = TLS1_3_RFC_AES_128_CCM_SHA256,
.alias = TLS1_3_TXT_AES_128_CCM_SHA256,
.cid = TLS1_3_CK_AES_128_CCM_SHA256,
},
{
.name = TLS1_3_TXT_AES_128_CCM_8_SHA256,
.alias = "TLS_AES_128_CCM_8_SHA256",
.name = TLS1_3_RFC_AES_128_CCM_8_SHA256,
.alias = TLS1_3_TXT_AES_128_CCM_8_SHA256,
.cid = TLS1_3_CK_AES_128_CCM_8_SHA256,
},
{

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: ssl_err.c,v 1.37 2020/01/21 05:19:02 jsing Exp $ */
/* $OpenBSD: ssl_err.c,v 1.40 2022/02/05 14:54:10 jsing Exp $ */
/* ====================================================================
* Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved.
*
@@ -61,6 +61,7 @@
#include <stdio.h>
#include <openssl/err.h>
#include <openssl/opensslconf.h>
#include <openssl/ssl.h>
#include "ssl_locl.h"
@@ -293,6 +294,7 @@ static ERR_STRING_DATA SSL_str_reasons[]= {
{ERR_REASON(SSL_R_MISSING_VERIFY_MESSAGE), "missing verify message"},
{ERR_REASON(SSL_R_MULTIPLE_SGC_RESTARTS) , "multiple sgc restarts"},
{ERR_REASON(SSL_R_NON_SSLV2_INITIAL_PACKET), "non sslv2 initial packet"},
{ERR_REASON(SSL_R_NO_APPLICATION_PROTOCOL), "no application protocol"},
{ERR_REASON(SSL_R_NO_CERTIFICATES_RETURNED), "no certificates returned"},
{ERR_REASON(SSL_R_NO_CERTIFICATE_ASSIGNED), "no certificate assigned"},
{ERR_REASON(SSL_R_NO_CERTIFICATE_RETURNED), "no certificate returned"},
@@ -664,5 +666,5 @@ void
SSL_error_internal(const SSL *s, int r, char *f, int l)
{
ERR_PUT_error(ERR_LIB_SSL,
(SSL_state_func_code(S3I(s)->hs.state)), r, f, l);
(SSL_state_func_code(s->s3->hs.state)), r, f, l);
}

View File

@@ -1,6 +1,6 @@
/* $OpenBSD: ssl_kex.c,v 1.2 2020/04/18 14:07:56 jsing Exp $ */
/* $OpenBSD: ssl_kex.c,v 1.10 2022/01/14 09:11:22 tb Exp $ */
/*
* Copyright (c) 2020 Joel Sing <jsing@openbsd.org>
* Copyright (c) 2020, 2021 Joel Sing <jsing@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -17,6 +17,8 @@
#include <stdlib.h>
#include <openssl/bn.h>
#include <openssl/dh.h>
#include <openssl/ec.h>
#include <openssl/ecdh.h>
#include <openssl/evp.h>
@@ -24,6 +26,245 @@
#include "bytestring.h"
#define DHE_MINIMUM_BITS 1024
int
ssl_kex_generate_dhe(DH *dh, DH *dh_params)
{
BIGNUM *p = NULL, *g = NULL;
int ret = 0;
if ((p = BN_dup(DH_get0_p(dh_params))) == NULL)
goto err;
if ((g = BN_dup(DH_get0_g(dh_params))) == NULL)
goto err;
if (!DH_set0_pqg(dh, p, NULL, g))
goto err;
p = NULL;
g = NULL;
if (!DH_generate_key(dh))
goto err;
ret = 1;
err:
BN_free(p);
BN_free(g);
return ret;
}
int
ssl_kex_generate_dhe_params_auto(DH *dh, size_t key_bits)
{
BIGNUM *p = NULL, *g = NULL;
int ret = 0;
if (key_bits >= 8192)
p = get_rfc3526_prime_8192(NULL);
else if (key_bits >= 4096)
p = get_rfc3526_prime_4096(NULL);
else if (key_bits >= 3072)
p = get_rfc3526_prime_3072(NULL);
else if (key_bits >= 2048)
p = get_rfc3526_prime_2048(NULL);
else if (key_bits >= 1536)
p = get_rfc3526_prime_1536(NULL);
else
p = get_rfc2409_prime_1024(NULL);
if (p == NULL)
goto err;
if ((g = BN_new()) == NULL)
goto err;
if (!BN_set_word(g, 2))
goto err;
if (!DH_set0_pqg(dh, p, NULL, g))
goto err;
p = NULL;
g = NULL;
if (!DH_generate_key(dh))
goto err;
ret = 1;
err:
BN_free(p);
BN_free(g);
return ret;
}
int
ssl_kex_params_dhe(DH *dh, CBB *cbb)
{
int dh_p_len, dh_g_len;
CBB dh_p, dh_g;
uint8_t *data;
if ((dh_p_len = BN_num_bytes(DH_get0_p(dh))) <= 0)
return 0;
if ((dh_g_len = BN_num_bytes(DH_get0_g(dh))) <= 0)
return 0;
if (!CBB_add_u16_length_prefixed(cbb, &dh_p))
return 0;
if (!CBB_add_space(&dh_p, &data, dh_p_len))
return 0;
if (BN_bn2bin(DH_get0_p(dh), data) != dh_p_len)
return 0;
if (!CBB_add_u16_length_prefixed(cbb, &dh_g))
return 0;
if (!CBB_add_space(&dh_g, &data, dh_g_len))
return 0;
if (BN_bn2bin(DH_get0_g(dh), data) != dh_g_len)
return 0;
if (!CBB_flush(cbb))
return 0;
return 1;
}
int
ssl_kex_public_dhe(DH *dh, CBB *cbb)
{
uint8_t *data;
int dh_y_len;
CBB dh_y;
if ((dh_y_len = BN_num_bytes(DH_get0_pub_key(dh))) <= 0)
return 0;
if (!CBB_add_u16_length_prefixed(cbb, &dh_y))
return 0;
if (!CBB_add_space(&dh_y, &data, dh_y_len))
return 0;
if (BN_bn2bin(DH_get0_pub_key(dh), data) != dh_y_len)
return 0;
if (!CBB_flush(cbb))
return 0;
return 1;
}
int
ssl_kex_peer_params_dhe(DH *dh, CBS *cbs, int *decode_error,
int *invalid_params)
{
BIGNUM *p = NULL, *g = NULL;
CBS dh_p, dh_g;
int ret = 0;
*decode_error = 0;
*invalid_params = 0;
if (!CBS_get_u16_length_prefixed(cbs, &dh_p)) {
*decode_error = 1;
goto err;
}
if (!CBS_get_u16_length_prefixed(cbs, &dh_g)) {
*decode_error = 1;
goto err;
}
if ((p = BN_bin2bn(CBS_data(&dh_p), CBS_len(&dh_p), NULL)) == NULL)
goto err;
if ((g = BN_bin2bn(CBS_data(&dh_g), CBS_len(&dh_g), NULL)) == NULL)
goto err;
if (!DH_set0_pqg(dh, p, NULL, g))
goto err;
p = NULL;
g = NULL;
/* XXX - consider calling DH_check(). */
if (DH_bits(dh) < DHE_MINIMUM_BITS)
*invalid_params = 1;
ret = 1;
err:
BN_free(p);
BN_free(g);
return ret;
}
int
ssl_kex_peer_public_dhe(DH *dh, CBS *cbs, int *decode_error,
int *invalid_key)
{
BIGNUM *pub_key = NULL;
int check_flags;
CBS dh_y;
int ret = 0;
*decode_error = 0;
*invalid_key = 0;
if (!CBS_get_u16_length_prefixed(cbs, &dh_y)) {
*decode_error = 1;
goto err;
}
if ((pub_key = BN_bin2bn(CBS_data(&dh_y), CBS_len(&dh_y),
NULL)) == NULL)
goto err;
if (!DH_set0_key(dh, pub_key, NULL))
goto err;
pub_key = NULL;
if (!DH_check_pub_key(dh, DH_get0_pub_key(dh), &check_flags))
goto err;
if (check_flags != 0)
*invalid_key = 1;
ret = 1;
err:
BN_free(pub_key);
return ret;
}
int
ssl_kex_derive_dhe(DH *dh, DH *dh_peer,
uint8_t **shared_key, size_t *shared_key_len)
{
uint8_t *key = NULL;
int key_len = 0;
int ret = 0;
if ((key_len = DH_size(dh)) <= 0)
goto err;
if ((key = calloc(1, key_len)) == NULL)
goto err;
if ((key_len = DH_compute_key(key, DH_get0_pub_key(dh_peer), dh)) <= 0)
goto err;
*shared_key = key;
*shared_key_len = key_len;
key = NULL;
ret = 1;
err:
freezero(key, key_len);
return ret;
}
int
ssl_kex_dummy_ecdhe_x25519(EVP_PKEY *pkey)
{
@@ -149,8 +390,8 @@ ssl_kex_derive_ecdhe_ecp(EC_KEY *ecdh, EC_KEY *ecdh_peer,
uint8_t **shared_key, size_t *shared_key_len)
{
const EC_POINT *point;
uint8_t *sk = NULL;
int sk_len = 0;
uint8_t *key = NULL;
int key_len = 0;
int ret = 0;
if (!EC_GROUP_check(EC_KEY_get0_group(ecdh), NULL))
@@ -161,22 +402,22 @@ ssl_kex_derive_ecdhe_ecp(EC_KEY *ecdh, EC_KEY *ecdh_peer,
if ((point = EC_KEY_get0_public_key(ecdh_peer)) == NULL)
goto err;
if ((sk_len = ECDH_size(ecdh)) <= 0)
if ((key_len = ECDH_size(ecdh)) <= 0)
goto err;
if ((sk = calloc(1, sk_len)) == NULL)
if ((key = calloc(1, key_len)) == NULL)
goto err;
if (ECDH_compute_key(sk, sk_len, point, ecdh, NULL) <= 0)
if (ECDH_compute_key(key, key_len, point, ecdh, NULL) <= 0)
goto err;
*shared_key = sk;
*shared_key_len = sk_len;
sk = NULL;
*shared_key = key;
*shared_key_len = key_len;
key = NULL;
ret = 1;
err:
freezero(sk, sk_len);
freezero(key, key_len);
return ret;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: ssl_packet.c,v 1.8 2018/11/08 22:28:52 jsing Exp $ */
/* $OpenBSD: ssl_packet.c,v 1.13 2022/02/05 14:54:10 jsing Exp $ */
/*
* Copyright (c) 2016, 2017 Joel Sing <jsing@openbsd.org>
*
@@ -15,9 +15,8 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "ssl_locl.h"
#include "bytestring.h"
#include "ssl_locl.h"
static int
ssl_is_sslv2_client_hello(CBS *header)
@@ -210,10 +209,10 @@ ssl_convert_sslv2_client_hello(SSL *s)
if (!CBB_finish(&cbb, &data, &data_len))
goto err;
if (data_len > S3I(s)->rbuf.len)
if (data_len > s->s3->rbuf.len)
goto err;
s->internal->packet = S3I(s)->rbuf.buf;
s->internal->packet = s->s3->rbuf.buf;
s->internal->packet_length = data_len;
memcpy(s->internal->packet, data, data_len);
ret = 1;
@@ -238,7 +237,7 @@ ssl_server_legacy_first_packet(SSL *s)
const char *data;
CBS header;
if (SSL_IS_DTLS(s))
if (SSL_is_dtls(s))
return 1;
CBS_init(&header, s->internal->packet, SSL3_RT_HEADER_LENGTH);
@@ -247,12 +246,12 @@ ssl_server_legacy_first_packet(SSL *s)
return 1;
/* Only continue if this is not a version locked method. */
if (s->method->internal->min_version == s->method->internal->max_version)
if (s->method->min_tls_version == s->method->max_tls_version)
return 1;
if (ssl_is_sslv2_client_hello(&header) == 1) {
/* Only permit SSLv2 client hellos if TLSv1.0 is enabled. */
if (ssl_enabled_version_range(s, &min_version, NULL) != 1) {
if (ssl_enabled_tls_version_range(s, &min_version, NULL) != 1) {
SSLerror(s, SSL_R_NO_PROTOCOLS_AVAILABLE);
return -1;
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: ssl_rsa.c,v 1.31 2019/03/25 16:46:48 jsing Exp $ */
/* $OpenBSD: ssl_rsa.c,v 1.39 2022/02/03 16:33:12 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -58,17 +58,20 @@
#include <stdio.h>
#include "ssl_locl.h"
#include <openssl/bio.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/pem.h>
#include <openssl/x509.h>
static int ssl_set_cert(CERT *c, X509 *x509);
static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey);
static int ssl_ctx_use_certificate_chain_bio(SSL_CTX *, BIO *);
#include "ssl_locl.h"
static int ssl_set_cert(SSL_CERT *c, X509 *x509);
static int ssl_set_pkey(SSL_CERT *c, EVP_PKEY *pkey);
static int use_certificate_chain_bio(BIO *in, SSL_CERT *cert,
pem_password_cb *passwd_cb, void *passwd_arg);
static int use_certificate_chain_file(const char *file, SSL_CERT *cert,
pem_password_cb *passwd_cb, void *passwd_arg);
int
SSL_use_certificate(SSL *ssl, X509 *x)
@@ -88,7 +91,7 @@ SSL_use_certificate_file(SSL *ssl, const char *file, int type)
int ret = 0;
X509 *x = NULL;
in = BIO_new(BIO_s_file_internal());
in = BIO_new(BIO_s_file());
if (in == NULL) {
SSLerror(ssl, ERR_R_BUF_LIB);
goto end;
@@ -117,7 +120,7 @@ SSL_use_certificate_file(SSL *ssl, const char *file, int type)
}
ret = SSL_use_certificate(ssl, x);
end:
end:
X509_free(x);
BIO_free(in);
return (ret);
@@ -164,11 +167,11 @@ SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa)
}
static int
ssl_set_pkey(CERT *c, EVP_PKEY *pkey)
ssl_set_pkey(SSL_CERT *c, EVP_PKEY *pkey)
{
int i;
i = ssl_cert_type(NULL, pkey);
i = ssl_cert_type(pkey);
if (i < 0) {
SSLerrorx(SSL_R_UNKNOWN_CERTIFICATE_TYPE);
return (0);
@@ -185,19 +188,18 @@ ssl_set_pkey(CERT *c, EVP_PKEY *pkey)
* Don't check the public/private key, this is mostly
* for smart cards.
*/
if ((pkey->type == EVP_PKEY_RSA) &&
(RSA_flags(pkey->pkey.rsa) & RSA_METHOD_FLAG_NO_CHECK))
;
else
if (!X509_check_private_key(c->pkeys[i].x509, pkey)) {
X509_free(c->pkeys[i].x509);
c->pkeys[i].x509 = NULL;
return 0;
if (EVP_PKEY_id(pkey) != EVP_PKEY_RSA ||
!(RSA_flags(EVP_PKEY_get0_RSA(pkey)) & RSA_METHOD_FLAG_NO_CHECK)) {
if (!X509_check_private_key(c->pkeys[i].x509, pkey)) {
X509_free(c->pkeys[i].x509);
c->pkeys[i].x509 = NULL;
return 0;
}
}
}
EVP_PKEY_free(c->pkeys[i].privatekey);
CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
EVP_PKEY_up_ref(pkey);
c->pkeys[i].privatekey = pkey;
c->key = &(c->pkeys[i]);
@@ -212,7 +214,7 @@ SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type)
BIO *in;
RSA *rsa = NULL;
in = BIO_new(BIO_s_file_internal());
in = BIO_new(BIO_s_file());
if (in == NULL) {
SSLerror(ssl, ERR_R_BUF_LIB);
goto end;
@@ -240,7 +242,7 @@ SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type)
}
ret = SSL_use_RSAPrivateKey(ssl, rsa);
RSA_free(rsa);
end:
end:
BIO_free(in);
return (ret);
}
@@ -281,7 +283,7 @@ SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type)
BIO *in;
EVP_PKEY *pkey = NULL;
in = BIO_new(BIO_s_file_internal());
in = BIO_new(BIO_s_file());
if (in == NULL) {
SSLerror(ssl, ERR_R_BUF_LIB);
goto end;
@@ -309,7 +311,7 @@ SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type)
}
ret = SSL_use_PrivateKey(ssl, pkey);
EVP_PKEY_free(pkey);
end:
end:
BIO_free(in);
return (ret);
}
@@ -341,7 +343,7 @@ SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x)
}
static int
ssl_set_cert(CERT *c, X509 *x)
ssl_set_cert(SSL_CERT *c, X509 *x)
{
EVP_PKEY *pkey;
int i;
@@ -352,7 +354,7 @@ ssl_set_cert(CERT *c, X509 *x)
return (0);
}
i = ssl_cert_type(x, pkey);
i = ssl_cert_type(pkey);
if (i < 0) {
SSLerrorx(SSL_R_UNKNOWN_CERTIFICATE_TYPE);
EVP_PKEY_free(pkey);
@@ -360,36 +362,35 @@ ssl_set_cert(CERT *c, X509 *x)
}
if (c->pkeys[i].privatekey != NULL) {
EVP_PKEY_copy_parameters(pkey, c->pkeys[i].privatekey);
EVP_PKEY *priv_key = c->pkeys[i].privatekey;
EVP_PKEY_copy_parameters(pkey, priv_key);
ERR_clear_error();
/*
* Don't check the public/private key, this is mostly
* for smart cards.
*/
if ((c->pkeys[i].privatekey->type == EVP_PKEY_RSA) &&
(RSA_flags(c->pkeys[i].privatekey->pkey.rsa) &
RSA_METHOD_FLAG_NO_CHECK))
;
else
if (!X509_check_private_key(x, c->pkeys[i].privatekey)) {
/*
* don't fail for a cert/key mismatch, just free
* current private key (when switching to a different
* cert & key, first this function should be used,
* then ssl_set_pkey
*/
EVP_PKEY_free(c->pkeys[i].privatekey);
c->pkeys[i].privatekey = NULL;
/* clear error queue */
ERR_clear_error();
if (EVP_PKEY_id(priv_key) != EVP_PKEY_RSA ||
!(RSA_flags(EVP_PKEY_get0_RSA(priv_key)) & RSA_METHOD_FLAG_NO_CHECK)) {
if (!X509_check_private_key(x, priv_key)) {
/*
* don't fail for a cert/key mismatch, just free
* current private key (when switching to a
* different cert & key, first this function
* should be used, then ssl_set_pkey.
*/
EVP_PKEY_free(c->pkeys[i].privatekey);
c->pkeys[i].privatekey = NULL;
ERR_clear_error();
}
}
}
EVP_PKEY_free(pkey);
X509_free(c->pkeys[i].x509);
CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
X509_up_ref(x);
c->pkeys[i].x509 = x;
c->key = &(c->pkeys[i]);
@@ -405,7 +406,7 @@ SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type)
int ret = 0;
X509 *x = NULL;
in = BIO_new(BIO_s_file_internal());
in = BIO_new(BIO_s_file());
if (in == NULL) {
SSLerrorx(ERR_R_BUF_LIB);
goto end;
@@ -433,7 +434,7 @@ SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type)
}
ret = SSL_CTX_use_certificate(ctx, x);
end:
end:
X509_free(x);
BIO_free(in);
return (ret);
@@ -486,7 +487,7 @@ SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type)
BIO *in;
RSA *rsa = NULL;
in = BIO_new(BIO_s_file_internal());
in = BIO_new(BIO_s_file());
if (in == NULL) {
SSLerrorx(ERR_R_BUF_LIB);
goto end;
@@ -514,7 +515,7 @@ SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type)
}
ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa);
RSA_free(rsa);
end:
end:
BIO_free(in);
return (ret);
}
@@ -552,7 +553,7 @@ SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type)
BIO *in;
EVP_PKEY *pkey = NULL;
in = BIO_new(BIO_s_file_internal());
in = BIO_new(BIO_s_file());
if (in == NULL) {
SSLerrorx(ERR_R_BUF_LIB);
goto end;
@@ -580,7 +581,7 @@ SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type)
}
ret = SSL_CTX_use_PrivateKey(ctx, pkey);
EVP_PKEY_free(pkey);
end:
end:
BIO_free(in);
return (ret);
}
@@ -609,29 +610,29 @@ SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, const unsigned char *d,
* sent to the peer in the Certificate message.
*/
static int
ssl_ctx_use_certificate_chain_bio(SSL_CTX *ctx, BIO *in)
use_certificate_chain_bio(BIO *in, SSL_CERT *cert, pem_password_cb *passwd_cb,
void *passwd_arg)
{
X509 *ca, *x = NULL;
unsigned long err;
int ret = 0;
if ((x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback,
ctx->default_passwd_callback_userdata)) == NULL) {
if ((x = PEM_read_bio_X509_AUX(in, NULL, passwd_cb, passwd_arg)) ==
NULL) {
SSLerrorx(ERR_R_PEM_LIB);
goto err;
}
if (!SSL_CTX_use_certificate(ctx, x))
if (!ssl_set_cert(cert, x))
goto err;
if (!ssl_cert_set0_chain(ctx->internal->cert, NULL))
if (!ssl_cert_set0_chain(cert, NULL))
goto err;
/* Process any additional CA certificates. */
while ((ca = PEM_read_bio_X509(in, NULL,
ctx->default_passwd_callback,
ctx->default_passwd_callback_userdata)) != NULL) {
if (!ssl_cert_add0_chain_cert(ctx->internal->cert, ca)) {
while ((ca = PEM_read_bio_X509(in, NULL, passwd_cb, passwd_arg)) !=
NULL) {
if (!ssl_cert_add0_chain_cert(cert, ca)) {
X509_free(ca);
goto err;
}
@@ -652,12 +653,13 @@ ssl_ctx_use_certificate_chain_bio(SSL_CTX *ctx, BIO *in)
}
int
SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file)
use_certificate_chain_file(const char *file, SSL_CERT *cert,
pem_password_cb *passwd_cb, void *passwd_arg)
{
BIO *in;
int ret = 0;
in = BIO_new(BIO_s_file_internal());
in = BIO_new(BIO_s_file());
if (in == NULL) {
SSLerrorx(ERR_R_BUF_LIB);
goto end;
@@ -668,13 +670,29 @@ SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file)
goto end;
}
ret = ssl_ctx_use_certificate_chain_bio(ctx, in);
ret = use_certificate_chain_bio(in, cert, passwd_cb, passwd_arg);
end:
end:
BIO_free(in);
return (ret);
}
int
SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file)
{
return use_certificate_chain_file(file, ctx->internal->cert,
ctx->default_passwd_callback,
ctx->default_passwd_callback_userdata);
}
int
SSL_use_certificate_chain_file(SSL *ssl, const char *file)
{
return use_certificate_chain_file(file, ssl->cert,
ssl->ctx->default_passwd_callback,
ssl->ctx->default_passwd_callback_userdata);
}
int
SSL_CTX_use_certificate_chain_mem(SSL_CTX *ctx, void *buf, int len)
{
@@ -687,9 +705,11 @@ SSL_CTX_use_certificate_chain_mem(SSL_CTX *ctx, void *buf, int len)
goto end;
}
ret = ssl_ctx_use_certificate_chain_bio(ctx, in);
ret = use_certificate_chain_bio(in, ctx->internal->cert,
ctx->default_passwd_callback,
ctx->default_passwd_callback_userdata);
end:
end:
BIO_free(in);
return (ret);
}

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: ssl_sess.c,v 1.100 2020/09/19 09:56:35 tb Exp $ */
/* $OpenBSD: ssl_sess.c,v 1.109 2022/01/11 19:03:15 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -136,6 +136,7 @@
*/
#include <openssl/lhash.h>
#include <openssl/opensslconf.h>
#ifndef OPENSSL_NO_ENGINE
#include <openssl/engine.h>
@@ -185,13 +186,13 @@ SSL_SESSION_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
int
SSL_SESSION_set_ex_data(SSL_SESSION *s, int idx, void *arg)
{
return (CRYPTO_set_ex_data(&s->internal->ex_data, idx, arg));
return (CRYPTO_set_ex_data(&s->ex_data, idx, arg));
}
void *
SSL_SESSION_get_ex_data(const SSL_SESSION *s, int idx)
{
return (CRYPTO_get_ex_data(&s->internal->ex_data, idx));
return (CRYPTO_get_ex_data(&s->ex_data, idx));
}
uint32_t
@@ -220,26 +221,21 @@ SSL_SESSION_new(void)
SSLerrorx(ERR_R_MALLOC_FAILURE);
return (NULL);
}
if ((ss->internal = calloc(1, sizeof(*ss->internal))) == NULL) {
free(ss);
SSLerrorx(ERR_R_MALLOC_FAILURE);
return (NULL);
}
ss->verify_result = 1; /* avoid 0 (= X509_V_OK) just in case */
ss->references = 1;
ss->timeout=60*5+4; /* 5 minute timeout by default */
ss->time = time(NULL);
ss->internal->prev = NULL;
ss->internal->next = NULL;
ss->prev = NULL;
ss->next = NULL;
ss->tlsext_hostname = NULL;
ss->internal->tlsext_ecpointformatlist_length = 0;
ss->internal->tlsext_ecpointformatlist = NULL;
ss->internal->tlsext_supportedgroups_length = 0;
ss->internal->tlsext_supportedgroups = NULL;
ss->tlsext_ecpointformatlist_length = 0;
ss->tlsext_ecpointformatlist = NULL;
ss->tlsext_supportedgroups_length = 0;
ss->tlsext_supportedgroups = NULL;
CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, ss, &ss->internal->ex_data);
CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, ss, &ss->ex_data);
return (ss);
}
@@ -345,6 +341,7 @@ ssl_get_new_session(SSL *s, int session)
case TLS1_1_VERSION:
case TLS1_2_VERSION:
case DTLS1_VERSION:
case DTLS1_2_VERSION:
ss->ssl_version = s->version;
ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH;
break;
@@ -736,7 +733,7 @@ remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck)
CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
if (ret) {
r->internal->not_resumable = 1;
r->not_resumable = 1;
if (ctx->internal->remove_session_cb != NULL)
ctx->internal->remove_session_cb(ctx, r);
SSL_SESSION_free(r);
@@ -758,23 +755,22 @@ SSL_SESSION_free(SSL_SESSION *ss)
if (i > 0)
return;
CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, ss, &ss->internal->ex_data);
CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, ss, &ss->ex_data);
explicit_bzero(ss->master_key, sizeof ss->master_key);
explicit_bzero(ss->session_id, sizeof ss->session_id);
ssl_sess_cert_free(ss->internal->sess_cert);
sk_X509_pop_free(ss->cert_chain, X509_free);
X509_free(ss->peer);
X509_free(ss->peer_cert);
sk_SSL_CIPHER_free(ss->ciphers);
free(ss->tlsext_hostname);
free(ss->tlsext_tick);
free(ss->internal->tlsext_ecpointformatlist);
free(ss->internal->tlsext_supportedgroups);
free(ss->tlsext_ecpointformatlist);
free(ss->tlsext_supportedgroups);
freezero(ss->internal, sizeof(*ss->internal));
freezero(ss, sizeof(*ss));
}
@@ -797,7 +793,7 @@ SSL_set_session(SSL *s, SSL_SESSION *session)
return SSL_set_ssl_method(s, s->ctx->method);
}
if ((method = ssl_get_client_method(session->ssl_version)) == NULL) {
if ((method = ssl_get_method(session->ssl_version)) == NULL) {
SSLerror(s, SSL_R_UNABLE_TO_FIND_SSL_METHOD);
return (0);
}
@@ -872,10 +868,16 @@ SSL_SESSION_get_protocol_version(const SSL_SESSION *s)
return s->ssl_version;
}
const SSL_CIPHER *
SSL_SESSION_get0_cipher(const SSL_SESSION *s)
{
return s->cipher;
}
X509 *
SSL_SESSION_get0_peer(SSL_SESSION *s)
{
return s->peer;
return s->peer_cert;
}
int
@@ -905,6 +907,12 @@ SSL_SESSION_set1_id_context(SSL_SESSION *s, const unsigned char *sid_ctx,
return 1;
}
int
SSL_SESSION_is_resumable(const SSL_SESSION *s)
{
return 0;
}
long
SSL_CTX_set_timeout(SSL_CTX *s, long t)
{
@@ -993,7 +1001,7 @@ timeout_doall_arg(SSL_SESSION *s, TIMEOUT_PARAM *p)
* save on locking overhead */
(void)lh_SSL_SESSION_delete(p->cache, s);
SSL_SESSION_list_remove(p->ctx, s);
s->internal->not_resumable = 1;
s->not_resumable = 1;
if (p->ctx->internal->remove_session_cb != NULL)
p->ctx->internal->remove_session_cb(p->ctx, s);
SSL_SESSION_free(s);
@@ -1045,50 +1053,50 @@ ssl_clear_bad_session(SSL *s)
static void
SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *s)
{
if ((s->internal->next == NULL) || (s->internal->prev == NULL))
if (s->next == NULL || s->prev == NULL)
return;
if (s->internal->next == (SSL_SESSION *)&(ctx->internal->session_cache_tail)) {
if (s->next == (SSL_SESSION *)&(ctx->internal->session_cache_tail)) {
/* last element in list */
if (s->internal->prev == (SSL_SESSION *)&(ctx->internal->session_cache_head)) {
if (s->prev == (SSL_SESSION *)&(ctx->internal->session_cache_head)) {
/* only one element in list */
ctx->internal->session_cache_head = NULL;
ctx->internal->session_cache_tail = NULL;
} else {
ctx->internal->session_cache_tail = s->internal->prev;
s->internal->prev->internal->next =
ctx->internal->session_cache_tail = s->prev;
s->prev->next =
(SSL_SESSION *)&(ctx->internal->session_cache_tail);
}
} else {
if (s->internal->prev == (SSL_SESSION *)&(ctx->internal->session_cache_head)) {
if (s->prev == (SSL_SESSION *)&(ctx->internal->session_cache_head)) {
/* first element in list */
ctx->internal->session_cache_head = s->internal->next;
s->internal->next->internal->prev =
ctx->internal->session_cache_head = s->next;
s->next->prev =
(SSL_SESSION *)&(ctx->internal->session_cache_head);
} else {
/* middle of list */
s->internal->next->internal->prev = s->internal->prev;
s->internal->prev->internal->next = s->internal->next;
s->next->prev = s->prev;
s->prev->next = s->next;
}
}
s->internal->prev = s->internal->next = NULL;
s->prev = s->next = NULL;
}
static void
SSL_SESSION_list_add(SSL_CTX *ctx, SSL_SESSION *s)
{
if ((s->internal->next != NULL) && (s->internal->prev != NULL))
if (s->next != NULL && s->prev != NULL)
SSL_SESSION_list_remove(ctx, s);
if (ctx->internal->session_cache_head == NULL) {
ctx->internal->session_cache_head = s;
ctx->internal->session_cache_tail = s;
s->internal->prev = (SSL_SESSION *)&(ctx->internal->session_cache_head);
s->internal->next = (SSL_SESSION *)&(ctx->internal->session_cache_tail);
s->prev = (SSL_SESSION *)&(ctx->internal->session_cache_head);
s->next = (SSL_SESSION *)&(ctx->internal->session_cache_tail);
} else {
s->internal->next = ctx->internal->session_cache_head;
s->internal->next->internal->prev = s;
s->internal->prev = (SSL_SESSION *)&(ctx->internal->session_cache_head);
s->next = ctx->internal->session_cache_head;
s->next->prev = s;
s->prev = (SSL_SESSION *)&(ctx->internal->session_cache_head);
ctx->internal->session_cache_head = s;
}
}

View File

@@ -1,6 +1,7 @@
/* $OpenBSD: ssl_sigalgs.c,v 1.21 2020/05/09 16:52:15 beck Exp $ */
/* $OpenBSD: ssl_sigalgs.c,v 1.41 2022/02/05 14:54:10 jsing Exp $ */
/*
* Copyright (c) 2018-2020 Bob Beck <beck@openbsd.org>
* Copyright (c) 2021 Joel Sing <jsing@openbsd.org>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -14,10 +15,12 @@
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <string.h>
#include <stdlib.h>
#include <openssl/evp.h>
#include <openssl/opensslconf.h>
#include "bytestring.h"
#include "ssl_locl.h"
@@ -27,101 +30,101 @@
const struct ssl_sigalg sigalgs[] = {
{
.value = SIGALG_RSA_PKCS1_SHA512,
.md = EVP_sha512,
.key_type = EVP_PKEY_RSA,
.md = EVP_sha512,
},
{
.value = SIGALG_ECDSA_SECP521R1_SHA512,
.md = EVP_sha512,
.key_type = EVP_PKEY_EC,
.md = EVP_sha512,
.curve_nid = NID_secp521r1,
},
#ifndef OPENSSL_NO_GOST
{
.value = SIGALG_GOSTR12_512_STREEBOG_512,
.md = EVP_streebog512,
.key_type = EVP_PKEY_GOSTR12_512,
.md = EVP_streebog512,
},
#endif
{
.value = SIGALG_RSA_PKCS1_SHA384,
.md = EVP_sha384,
.key_type = EVP_PKEY_RSA,
.md = EVP_sha384,
},
{
.value = SIGALG_ECDSA_SECP384R1_SHA384,
.md = EVP_sha384,
.key_type = EVP_PKEY_EC,
.md = EVP_sha384,
.curve_nid = NID_secp384r1,
},
{
.value = SIGALG_RSA_PKCS1_SHA256,
.md = EVP_sha256,
.key_type = EVP_PKEY_RSA,
.md = EVP_sha256,
},
{
.value = SIGALG_ECDSA_SECP256R1_SHA256,
.md = EVP_sha256,
.key_type = EVP_PKEY_EC,
.md = EVP_sha256,
.curve_nid = NID_X9_62_prime256v1,
},
#ifndef OPENSSL_NO_GOST
{
.value = SIGALG_GOSTR12_256_STREEBOG_256,
.md = EVP_streebog256,
.key_type = EVP_PKEY_GOSTR12_256,
.md = EVP_streebog256,
},
{
.value = SIGALG_GOSTR01_GOST94,
.md = EVP_gostr341194,
.key_type = EVP_PKEY_GOSTR01,
.md = EVP_gostr341194,
},
#endif
{
.value = SIGALG_RSA_PSS_RSAE_SHA256,
.md = EVP_sha256,
.key_type = EVP_PKEY_RSA,
.md = EVP_sha256,
.flags = SIGALG_FLAG_RSA_PSS,
},
{
.value = SIGALG_RSA_PSS_RSAE_SHA384,
.md = EVP_sha384,
.key_type = EVP_PKEY_RSA,
.md = EVP_sha384,
.flags = SIGALG_FLAG_RSA_PSS,
},
{
.value = SIGALG_RSA_PSS_RSAE_SHA512,
.md = EVP_sha512,
.key_type = EVP_PKEY_RSA,
.md = EVP_sha512,
.flags = SIGALG_FLAG_RSA_PSS,
},
{
.value = SIGALG_RSA_PSS_PSS_SHA256,
.md = EVP_sha256,
.key_type = EVP_PKEY_RSA,
.md = EVP_sha256,
.flags = SIGALG_FLAG_RSA_PSS,
},
{
.value = SIGALG_RSA_PSS_PSS_SHA384,
.md = EVP_sha384,
.key_type = EVP_PKEY_RSA,
.md = EVP_sha384,
.flags = SIGALG_FLAG_RSA_PSS,
},
{
.value = SIGALG_RSA_PSS_PSS_SHA512,
.md = EVP_sha512,
.key_type = EVP_PKEY_RSA,
.md = EVP_sha512,
.flags = SIGALG_FLAG_RSA_PSS,
},
{
.value = SIGALG_RSA_PKCS1_SHA224,
.md = EVP_sha224,
.key_type = EVP_PKEY_RSA,
.md = EVP_sha224,
},
{
.value = SIGALG_ECDSA_SECP224R1_SHA224,
.md = EVP_sha224,
.key_type = EVP_PKEY_EC,
.md = EVP_sha224,
},
{
.value = SIGALG_RSA_PKCS1_SHA1,
@@ -143,8 +146,8 @@ const struct ssl_sigalg sigalgs[] = {
},
};
/* Sigalgs for tls 1.3, in preference order, */
uint16_t tls13_sigalgs[] = {
/* Sigalgs for TLSv1.3, in preference order. */
const uint16_t tls13_sigalgs[] = {
SIGALG_RSA_PSS_RSAE_SHA512,
SIGALG_RSA_PKCS1_SHA512,
SIGALG_ECDSA_SECP521R1_SHA512,
@@ -155,10 +158,10 @@ uint16_t tls13_sigalgs[] = {
SIGALG_RSA_PKCS1_SHA256,
SIGALG_ECDSA_SECP256R1_SHA256,
};
size_t tls13_sigalgs_len = (sizeof(tls13_sigalgs) / sizeof(tls13_sigalgs[0]));
const size_t tls13_sigalgs_len = (sizeof(tls13_sigalgs) / sizeof(tls13_sigalgs[0]));
/* Sigalgs for tls 1.2, in preference order, */
uint16_t tls12_sigalgs[] = {
/* Sigalgs for TLSv1.2, in preference order. */
const uint16_t tls12_sigalgs[] = {
SIGALG_RSA_PSS_RSAE_SHA512,
SIGALG_RSA_PKCS1_SHA512,
SIGALG_ECDSA_SECP521R1_SHA512,
@@ -171,87 +174,124 @@ uint16_t tls12_sigalgs[] = {
SIGALG_RSA_PKCS1_SHA1, /* XXX */
SIGALG_ECDSA_SHA1, /* XXX */
};
size_t tls12_sigalgs_len = (sizeof(tls12_sigalgs) / sizeof(tls12_sigalgs[0]));
const size_t tls12_sigalgs_len = (sizeof(tls12_sigalgs) / sizeof(tls12_sigalgs[0]));
const struct ssl_sigalg *
ssl_sigalg_lookup(uint16_t sigalg)
static void
ssl_sigalgs_for_version(uint16_t tls_version, const uint16_t **out_values,
size_t *out_len)
{
if (tls_version >= TLS1_3_VERSION) {
*out_values = tls13_sigalgs;
*out_len = tls13_sigalgs_len;
} else {
*out_values = tls12_sigalgs;
*out_len = tls12_sigalgs_len;
}
}
static const struct ssl_sigalg *
ssl_sigalg_lookup(uint16_t value)
{
int i;
for (i = 0; sigalgs[i].value != SIGALG_NONE; i++) {
if (sigalgs[i].value == sigalg)
if (sigalgs[i].value == value)
return &sigalgs[i];
}
return NULL;
}
const struct ssl_sigalg *
ssl_sigalg(uint16_t sigalg, uint16_t *values, size_t len)
static const struct ssl_sigalg *
ssl_sigalg_from_value(SSL *s, uint16_t value)
{
const uint16_t *values;
size_t len;
int i;
ssl_sigalgs_for_version(s->s3->hs.negotiated_tls_version,
&values, &len);
for (i = 0; i < len; i++) {
if (values[i] == sigalg)
return ssl_sigalg_lookup(sigalg);
if (values[i] == value)
return ssl_sigalg_lookup(value);
}
return NULL;
}
int
ssl_sigalgs_build(CBB *cbb, uint16_t *values, size_t len)
ssl_sigalgs_build(uint16_t tls_version, CBB *cbb)
{
const uint16_t *values;
size_t len;
size_t i;
for (i = 0; sigalgs[i].value != SIGALG_NONE; i++);
if (len > i)
return 0;
/* XXX check for duplicates and other sanity BS? */
ssl_sigalgs_for_version(tls_version, &values, &len);
/* Add values in order as long as they are supported. */
for (i = 0; i < len; i++) {
/* Do not allow the legacy value for < 1.2 to be used */
/* Do not allow the legacy value for < 1.2 to be used. */
if (values[i] == SIGALG_RSA_PKCS1_MD5_SHA1)
return 0;
if (ssl_sigalg_lookup(values[i]) != NULL) {
if (!CBB_add_u16(cbb, values[i]))
return 0;
} else
if (ssl_sigalg_lookup(values[i]) == NULL)
return 0;
if (!CBB_add_u16(cbb, values[i]))
return 0;
}
return 1;
}
int
ssl_sigalg_pkey_ok(const struct ssl_sigalg *sigalg, EVP_PKEY *pkey,
int check_curve)
static const struct ssl_sigalg *
ssl_sigalg_for_legacy(SSL *s, EVP_PKEY *pkey)
{
/* Default signature algorithms used for TLSv1.2 and earlier. */
switch (EVP_PKEY_id(pkey)) {
case EVP_PKEY_RSA:
if (s->s3->hs.negotiated_tls_version < TLS1_2_VERSION)
return ssl_sigalg_lookup(SIGALG_RSA_PKCS1_MD5_SHA1);
return ssl_sigalg_lookup(SIGALG_RSA_PKCS1_SHA1);
case EVP_PKEY_EC:
return ssl_sigalg_lookup(SIGALG_ECDSA_SHA1);
#ifndef OPENSSL_NO_GOST
case EVP_PKEY_GOSTR01:
return ssl_sigalg_lookup(SIGALG_GOSTR01_GOST94);
#endif
}
SSLerror(s, SSL_R_UNKNOWN_PKEY_TYPE);
return NULL;
}
static int
ssl_sigalg_pkey_ok(SSL *s, const struct ssl_sigalg *sigalg, EVP_PKEY *pkey)
{
if (sigalg == NULL || pkey == NULL)
return 0;
if (sigalg->key_type != pkey->type)
if (sigalg->key_type != EVP_PKEY_id(pkey))
return 0;
/* RSA PSS must have a sufficiently large RSA key. */
if ((sigalg->flags & SIGALG_FLAG_RSA_PSS)) {
/*
* RSA PSS Must have an RSA key that needs to be at
* least as big as twice the size of the hash + 2
*/
if (pkey->type != EVP_PKEY_RSA ||
if (EVP_PKEY_id(pkey) != EVP_PKEY_RSA ||
EVP_PKEY_size(pkey) < (2 * EVP_MD_size(sigalg->md()) + 2))
return 0;
}
if (pkey->type == EVP_PKEY_EC && check_curve) {
/* Curve must match for EC keys. */
if (s->s3->hs.negotiated_tls_version < TLS1_3_VERSION)
return 1;
/* RSA cannot be used without PSS in TLSv1.3. */
if (sigalg->key_type == EVP_PKEY_RSA &&
(sigalg->flags & SIGALG_FLAG_RSA_PSS) == 0)
return 0;
/* Ensure that curve matches for EC keys. */
if (EVP_PKEY_id(pkey) == EVP_PKEY_EC) {
if (sigalg->curve_nid == 0)
return 0;
if (EC_GROUP_get_curve_name(EC_KEY_get0_group
(EVP_PKEY_get0_EC_KEY(pkey))) != sigalg->curve_nid) {
if (EC_GROUP_get_curve_name(EC_KEY_get0_group(
EVP_PKEY_get0_EC_KEY(pkey))) != sigalg->curve_nid)
return 0;
}
}
return 1;
@@ -260,78 +300,56 @@ ssl_sigalg_pkey_ok(const struct ssl_sigalg *sigalg, EVP_PKEY *pkey,
const struct ssl_sigalg *
ssl_sigalg_select(SSL *s, EVP_PKEY *pkey)
{
uint16_t *tls_sigalgs = tls12_sigalgs;
size_t tls_sigalgs_len = tls12_sigalgs_len;
int check_curve = 0;
CBS cbs;
if (TLS1_get_version(s) >= TLS1_3_VERSION) {
tls_sigalgs = tls13_sigalgs;
tls_sigalgs_len = tls13_sigalgs_len;
check_curve = 1;
}
/* Pre TLS 1.2 defaults */
if (!SSL_USE_SIGALGS(s)) {
switch (pkey->type) {
case EVP_PKEY_RSA:
return ssl_sigalg_lookup(SIGALG_RSA_PKCS1_MD5_SHA1);
case EVP_PKEY_EC:
return ssl_sigalg_lookup(SIGALG_ECDSA_SHA1);
#ifndef OPENSSL_NO_GOST
case EVP_PKEY_GOSTR01:
return ssl_sigalg_lookup(SIGALG_GOSTR01_GOST94);
#endif
}
SSLerror(s, SSL_R_UNKNOWN_PKEY_TYPE);
return (NULL);
}
if (!SSL_USE_SIGALGS(s))
return ssl_sigalg_for_legacy(s, pkey);
/*
* RFC 5246 allows a TLS 1.2 client to send no sigalgs, in
* which case the server must use the the default.
* RFC 5246 allows a TLS 1.2 client to send no sigalgs extension,
* in which case the server must use the default.
*/
if (TLS1_get_version(s) < TLS1_3_VERSION &&
S3I(s)->hs.sigalgs == NULL) {
switch (pkey->type) {
case EVP_PKEY_RSA:
return ssl_sigalg_lookup(SIGALG_RSA_PKCS1_SHA1);
case EVP_PKEY_EC:
return ssl_sigalg_lookup(SIGALG_ECDSA_SHA1);
#ifndef OPENSSL_NO_GOST
case EVP_PKEY_GOSTR01:
return ssl_sigalg_lookup(SIGALG_GOSTR01_GOST94);
#endif
}
SSLerror(s, SSL_R_UNKNOWN_PKEY_TYPE);
return (NULL);
}
if (s->s3->hs.negotiated_tls_version < TLS1_3_VERSION &&
s->s3->hs.sigalgs == NULL)
return ssl_sigalg_for_legacy(s, pkey);
/*
* If we get here, we have client or server sent sigalgs, use one.
*/
CBS_init(&cbs, S3I(s)->hs.sigalgs, S3I(s)->hs.sigalgs_len);
CBS_init(&cbs, s->s3->hs.sigalgs, s->s3->hs.sigalgs_len);
while (CBS_len(&cbs) > 0) {
uint16_t sig_alg;
const struct ssl_sigalg *sigalg;
uint16_t sigalg_value;
if (!CBS_get_u16(&cbs, &sig_alg))
return 0;
if (!CBS_get_u16(&cbs, &sigalg_value))
return NULL;
if ((sigalg = ssl_sigalg(sig_alg, tls_sigalgs,
tls_sigalgs_len)) == NULL)
if ((sigalg = ssl_sigalg_from_value(s, sigalg_value)) == NULL)
continue;
/* RSA cannot be used without PSS in TLSv1.3. */
if (TLS1_get_version(s) >= TLS1_3_VERSION &&
sigalg->key_type == EVP_PKEY_RSA &&
(sigalg->flags & SIGALG_FLAG_RSA_PSS) == 0)
continue;
if (ssl_sigalg_pkey_ok(sigalg, pkey, check_curve))
if (ssl_sigalg_pkey_ok(s, sigalg, pkey))
return sigalg;
}
SSLerror(s, SSL_R_UNKNOWN_PKEY_TYPE);
return NULL;
}
const struct ssl_sigalg *
ssl_sigalg_for_peer(SSL *s, EVP_PKEY *pkey, uint16_t sigalg_value)
{
const struct ssl_sigalg *sigalg;
if (!SSL_USE_SIGALGS(s))
return ssl_sigalg_for_legacy(s, pkey);
if ((sigalg = ssl_sigalg_from_value(s, sigalg_value)) == NULL) {
SSLerror(s, SSL_R_UNKNOWN_DIGEST);
return NULL;
}
if (!ssl_sigalg_pkey_ok(s, sigalg, pkey)) {
SSLerror(s, SSL_R_WRONG_SIGNATURE_TYPE);
return NULL;
}
return sigalg;
}

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: ssl_sigalgs.h,v 1.14 2019/03/25 17:33:26 jsing Exp $ */
/* $OpenBSD: ssl_sigalgs.h,v 1.23 2021/06/29 19:25:59 jsing Exp $ */
/*
* Copyright (c) 2018-2019 Bob Beck <beck@openbsd.org>
*
@@ -55,31 +55,23 @@ __BEGIN_HIDDEN_DECLS
#define SIGALG_GOSTR12_256_STREEBOG_256 0xEEEE
#define SIGALG_GOSTR01_GOST94 0xEDED
/* Legacy sigalg for < 1.2 same value as boring uses*/
/* Legacy sigalg for < TLSv1.2 same value as BoringSSL uses. */
#define SIGALG_RSA_PKCS1_MD5_SHA1 0xFF01
#define SIGALG_FLAG_RSA_PSS 0x00000001
struct ssl_sigalg{
struct ssl_sigalg {
uint16_t value;
const EVP_MD *(*md)(void);
int key_type;
const EVP_MD *(*md)(void);
int curve_nid;
int flags;
};
extern uint16_t tls12_sigalgs[];
extern size_t tls12_sigalgs_len;
extern uint16_t tls13_sigalgs[];
extern size_t tls13_sigalgs_len;
const struct ssl_sigalg *ssl_sigalg_lookup(uint16_t sigalg);
const struct ssl_sigalg *ssl_sigalg(uint16_t sigalg, uint16_t *values, size_t len);
int ssl_sigalgs_build(CBB *cbb, uint16_t *values, size_t len);
int ssl_sigalg_pkey_check(uint16_t sigalg, EVP_PKEY *pk);
int ssl_sigalg_pkey_ok(const struct ssl_sigalg *sigalg, EVP_PKEY *pkey,
int check_curve);
int ssl_sigalgs_build(uint16_t tls_version, CBB *cbb);
const struct ssl_sigalg *ssl_sigalg_select(SSL *s, EVP_PKEY *pkey);
const struct ssl_sigalg *ssl_sigalg_for_peer(SSL *s, EVP_PKEY *pkey,
uint16_t sigalg_value);
__END_HIDDEN_DECLS

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: ssl_stat.c,v 1.14 2017/05/07 04:22:24 beck Exp $ */
/* $OpenBSD: ssl_stat.c,v 1.18 2022/02/05 14:54:10 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -91,7 +91,7 @@ SSL_state_string_long(const SSL *s)
{
const char *str;
switch (S3I(s)->hs.state) {
switch (s->s3->hs.state) {
case SSL_ST_BEFORE:
str = "before SSL initialization";
break;
@@ -347,7 +347,7 @@ SSL_state_string(const SSL *s)
{
const char *str;
switch (S3I(s)->hs.state) {
switch (s->s3->hs.state) {
case SSL_ST_BEFORE:
str = "PINIT ";
break;
@@ -578,94 +578,88 @@ SSL_alert_desc_string(int value)
const char *str;
switch (value & 0xff) {
case SSL3_AD_CLOSE_NOTIFY:
case SSL_AD_CLOSE_NOTIFY:
str = "CN";
break;
case SSL3_AD_UNEXPECTED_MESSAGE:
case SSL_AD_UNEXPECTED_MESSAGE:
str = "UM";
break;
case SSL3_AD_BAD_RECORD_MAC:
case SSL_AD_BAD_RECORD_MAC:
str = "BM";
break;
case SSL3_AD_DECOMPRESSION_FAILURE:
case SSL_AD_DECOMPRESSION_FAILURE:
str = "DF";
break;
case SSL3_AD_HANDSHAKE_FAILURE:
case SSL_AD_HANDSHAKE_FAILURE:
str = "HF";
break;
case SSL3_AD_NO_CERTIFICATE:
str = "NC";
break;
case SSL3_AD_BAD_CERTIFICATE:
case SSL_AD_BAD_CERTIFICATE:
str = "BC";
break;
case SSL3_AD_UNSUPPORTED_CERTIFICATE:
case SSL_AD_UNSUPPORTED_CERTIFICATE:
str = "UC";
break;
case SSL3_AD_CERTIFICATE_REVOKED:
case SSL_AD_CERTIFICATE_REVOKED:
str = "CR";
break;
case SSL3_AD_CERTIFICATE_EXPIRED:
case SSL_AD_CERTIFICATE_EXPIRED:
str = "CE";
break;
case SSL3_AD_CERTIFICATE_UNKNOWN:
case SSL_AD_CERTIFICATE_UNKNOWN:
str = "CU";
break;
case SSL3_AD_ILLEGAL_PARAMETER:
case SSL_AD_ILLEGAL_PARAMETER:
str = "IP";
break;
case TLS1_AD_DECRYPTION_FAILED:
str = "DC";
break;
case TLS1_AD_RECORD_OVERFLOW:
case SSL_AD_RECORD_OVERFLOW:
str = "RO";
break;
case TLS1_AD_UNKNOWN_CA:
case SSL_AD_UNKNOWN_CA:
str = "CA";
break;
case TLS1_AD_ACCESS_DENIED:
case SSL_AD_ACCESS_DENIED:
str = "AD";
break;
case TLS1_AD_DECODE_ERROR:
case SSL_AD_DECODE_ERROR:
str = "DE";
break;
case TLS1_AD_DECRYPT_ERROR:
case SSL_AD_DECRYPT_ERROR:
str = "CY";
break;
case TLS1_AD_EXPORT_RESTRICTION:
str = "ER";
break;
case TLS1_AD_PROTOCOL_VERSION:
case SSL_AD_PROTOCOL_VERSION:
str = "PV";
break;
case TLS1_AD_INSUFFICIENT_SECURITY:
case SSL_AD_INSUFFICIENT_SECURITY:
str = "IS";
break;
case TLS1_AD_INTERNAL_ERROR:
case SSL_AD_INTERNAL_ERROR:
str = "IE";
break;
case TLS1_AD_USER_CANCELLED:
case SSL_AD_USER_CANCELLED:
str = "US";
break;
case TLS1_AD_NO_RENEGOTIATION:
case SSL_AD_NO_RENEGOTIATION:
str = "NR";
break;
case TLS1_AD_UNSUPPORTED_EXTENSION:
case SSL_AD_MISSING_EXTENSION:
str = "ME";
break;
case SSL_AD_UNSUPPORTED_EXTENSION:
str = "UE";
break;
case TLS1_AD_CERTIFICATE_UNOBTAINABLE:
case SSL_AD_CERTIFICATE_UNOBTAINABLE:
str = "CO";
break;
case TLS1_AD_UNRECOGNIZED_NAME:
case SSL_AD_UNRECOGNIZED_NAME:
str = "UN";
break;
case TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE:
case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE:
str = "BR";
break;
case TLS1_AD_BAD_CERTIFICATE_HASH_VALUE:
case SSL_AD_BAD_CERTIFICATE_HASH_VALUE:
str = "BH";
break;
case TLS1_AD_UNKNOWN_PSK_IDENTITY:
case SSL_AD_UNKNOWN_PSK_IDENTITY:
str = "UP";
break;
default:
@@ -681,94 +675,88 @@ SSL_alert_desc_string_long(int value)
const char *str;
switch (value & 0xff) {
case SSL3_AD_CLOSE_NOTIFY:
case SSL_AD_CLOSE_NOTIFY:
str = "close notify";
break;
case SSL3_AD_UNEXPECTED_MESSAGE:
case SSL_AD_UNEXPECTED_MESSAGE:
str = "unexpected_message";
break;
case SSL3_AD_BAD_RECORD_MAC:
case SSL_AD_BAD_RECORD_MAC:
str = "bad record mac";
break;
case SSL3_AD_DECOMPRESSION_FAILURE:
case SSL_AD_DECOMPRESSION_FAILURE:
str = "decompression failure";
break;
case SSL3_AD_HANDSHAKE_FAILURE:
case SSL_AD_HANDSHAKE_FAILURE:
str = "handshake failure";
break;
case SSL3_AD_NO_CERTIFICATE:
str = "no certificate";
break;
case SSL3_AD_BAD_CERTIFICATE:
case SSL_AD_BAD_CERTIFICATE:
str = "bad certificate";
break;
case SSL3_AD_UNSUPPORTED_CERTIFICATE:
case SSL_AD_UNSUPPORTED_CERTIFICATE:
str = "unsupported certificate";
break;
case SSL3_AD_CERTIFICATE_REVOKED:
case SSL_AD_CERTIFICATE_REVOKED:
str = "certificate revoked";
break;
case SSL3_AD_CERTIFICATE_EXPIRED:
case SSL_AD_CERTIFICATE_EXPIRED:
str = "certificate expired";
break;
case SSL3_AD_CERTIFICATE_UNKNOWN:
case SSL_AD_CERTIFICATE_UNKNOWN:
str = "certificate unknown";
break;
case SSL3_AD_ILLEGAL_PARAMETER:
case SSL_AD_ILLEGAL_PARAMETER:
str = "illegal parameter";
break;
case TLS1_AD_DECRYPTION_FAILED:
str = "decryption failed";
break;
case TLS1_AD_RECORD_OVERFLOW:
case SSL_AD_RECORD_OVERFLOW:
str = "record overflow";
break;
case TLS1_AD_UNKNOWN_CA:
case SSL_AD_UNKNOWN_CA:
str = "unknown CA";
break;
case TLS1_AD_ACCESS_DENIED:
case SSL_AD_ACCESS_DENIED:
str = "access denied";
break;
case TLS1_AD_DECODE_ERROR:
case SSL_AD_DECODE_ERROR:
str = "decode error";
break;
case TLS1_AD_DECRYPT_ERROR:
case SSL_AD_DECRYPT_ERROR:
str = "decrypt error";
break;
case TLS1_AD_EXPORT_RESTRICTION:
str = "export restriction";
break;
case TLS1_AD_PROTOCOL_VERSION:
case SSL_AD_PROTOCOL_VERSION:
str = "protocol version";
break;
case TLS1_AD_INSUFFICIENT_SECURITY:
case SSL_AD_INSUFFICIENT_SECURITY:
str = "insufficient security";
break;
case TLS1_AD_INTERNAL_ERROR:
case SSL_AD_INTERNAL_ERROR:
str = "internal error";
break;
case TLS1_AD_USER_CANCELLED:
case SSL_AD_USER_CANCELLED:
str = "user canceled";
break;
case TLS1_AD_NO_RENEGOTIATION:
case SSL_AD_NO_RENEGOTIATION:
str = "no renegotiation";
break;
case TLS1_AD_UNSUPPORTED_EXTENSION:
case SSL_AD_MISSING_EXTENSION:
str = "missing extension";
break;
case SSL_AD_UNSUPPORTED_EXTENSION:
str = "unsupported extension";
break;
case TLS1_AD_CERTIFICATE_UNOBTAINABLE:
case SSL_AD_CERTIFICATE_UNOBTAINABLE:
str = "certificate unobtainable";
break;
case TLS1_AD_UNRECOGNIZED_NAME:
case SSL_AD_UNRECOGNIZED_NAME:
str = "unrecognized name";
break;
case TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE:
case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE:
str = "bad certificate status response";
break;
case TLS1_AD_BAD_CERTIFICATE_HASH_VALUE:
case SSL_AD_BAD_CERTIFICATE_HASH_VALUE:
str = "bad certificate hash value";
break;
case TLS1_AD_UNKNOWN_PSK_IDENTITY:
case SSL_AD_UNKNOWN_PSK_IDENTITY:
str = "unknown PSK identity";
break;
default:

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: ssl_tlsext.h,v 1.25 2020/07/03 04:51:59 tb Exp $ */
/* $OpenBSD: ssl_tlsext.h,v 1.27 2021/11/01 16:37:17 jsing Exp $ */
/*
* Copyright (c) 2016, 2017 Joel Sing <jsing@openbsd.org>
* Copyright (c) 2017 Doug Hogan <doug@openbsd.org>
@@ -60,7 +60,7 @@ int tlsext_sni_client_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert);
int tlsext_sni_server_needs(SSL *s, uint16_t msg_type);
int tlsext_sni_server_build(SSL *s, uint16_t msg_type, CBB *cbb);
int tlsext_sni_server_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert);
int tlsext_sni_is_valid_hostname(CBS *cbs);
int tlsext_sni_is_valid_hostname(CBS *cbs, int *is_ip);
int tlsext_supportedgroups_client_needs(SSL *s, uint16_t msg_type);
int tlsext_supportedgroups_client_build(SSL *s, uint16_t msg_type, CBB *cbb);
@@ -134,7 +134,7 @@ int tlsext_client_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert);
int tlsext_server_build(SSL *s, uint16_t msg_type, CBB *cbb);
int tlsext_server_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert);
struct tls_extension *tls_extension_find(uint16_t, size_t *);
const struct tls_extension *tls_extension_find(uint16_t, size_t *);
int tlsext_extension_seen(SSL *s, uint16_t);
__END_HIDDEN_DECLS

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: ssl_transcript.c,v 1.2 2020/02/05 16:47:34 jsing Exp $ */
/* $OpenBSD: ssl_transcript.c,v 1.7 2022/03/17 17:22:16 jsing Exp $ */
/*
* Copyright (c) 2017 Joel Sing <jsing@openbsd.org>
*
@@ -15,10 +15,10 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "ssl_locl.h"
#include <openssl/ssl.h>
#include "ssl_locl.h"
int
tls1_transcript_hash_init(SSL *s)
{
@@ -33,11 +33,11 @@ tls1_transcript_hash_init(SSL *s)
goto err;
}
if ((S3I(s)->handshake_hash = EVP_MD_CTX_new()) == NULL) {
if ((s->s3->handshake_hash = EVP_MD_CTX_new()) == NULL) {
SSLerror(s, ERR_R_MALLOC_FAILURE);
goto err;
}
if (!EVP_DigestInit_ex(S3I(s)->handshake_hash, md, NULL)) {
if (!EVP_DigestInit_ex(s->s3->handshake_hash, md, NULL)) {
SSLerror(s, ERR_R_EVP_LIB);
goto err;
}
@@ -50,7 +50,7 @@ tls1_transcript_hash_init(SSL *s)
SSLerror(s, ERR_R_EVP_LIB);
goto err;
}
return 1;
err:
@@ -62,32 +62,35 @@ tls1_transcript_hash_init(SSL *s)
int
tls1_transcript_hash_update(SSL *s, const unsigned char *buf, size_t len)
{
if (S3I(s)->handshake_hash == NULL)
if (s->s3->handshake_hash == NULL)
return 1;
return EVP_DigestUpdate(S3I(s)->handshake_hash, buf, len);
return EVP_DigestUpdate(s->s3->handshake_hash, buf, len);
}
int
tls1_transcript_hash_value(SSL *s, const unsigned char *out, size_t len,
tls1_transcript_hash_value(SSL *s, unsigned char *out, size_t len,
size_t *outlen)
{
EVP_MD_CTX *mdctx = NULL;
unsigned int mdlen;
int ret = 0;
if (EVP_MD_CTX_size(S3I(s)->handshake_hash) > len)
if (s->s3->handshake_hash == NULL)
goto err;
if (EVP_MD_CTX_size(s->s3->handshake_hash) > len)
goto err;
if ((mdctx = EVP_MD_CTX_new()) == NULL) {
SSLerror(s, ERR_R_MALLOC_FAILURE);
goto err;
}
if (!EVP_MD_CTX_copy_ex(mdctx, S3I(s)->handshake_hash)) {
if (!EVP_MD_CTX_copy_ex(mdctx, s->s3->handshake_hash)) {
SSLerror(s, ERR_R_EVP_LIB);
goto err;
}
if (!EVP_DigestFinal_ex(mdctx, (unsigned char *)out, &mdlen)) {
if (!EVP_DigestFinal_ex(mdctx, out, &mdlen)) {
SSLerror(s, ERR_R_EVP_LIB);
goto err;
}
@@ -105,17 +108,17 @@ tls1_transcript_hash_value(SSL *s, const unsigned char *out, size_t len,
void
tls1_transcript_hash_free(SSL *s)
{
EVP_MD_CTX_free(S3I(s)->handshake_hash);
S3I(s)->handshake_hash = NULL;
EVP_MD_CTX_free(s->s3->handshake_hash);
s->s3->handshake_hash = NULL;
}
int
tls1_transcript_init(SSL *s)
{
if (S3I(s)->handshake_transcript != NULL)
if (s->s3->handshake_transcript != NULL)
return 0;
if ((S3I(s)->handshake_transcript = BUF_MEM_new()) == NULL)
if ((s->s3->handshake_transcript = BUF_MEM_new()) == NULL)
return 0;
tls1_transcript_reset(s);
@@ -126,8 +129,8 @@ tls1_transcript_init(SSL *s)
void
tls1_transcript_free(SSL *s)
{
BUF_MEM_free(S3I(s)->handshake_transcript);
S3I(s)->handshake_transcript = NULL;
BUF_MEM_free(s->s3->handshake_transcript);
s->s3->handshake_transcript = NULL;
}
void
@@ -139,8 +142,8 @@ tls1_transcript_reset(SSL *s)
* it is impossible to tell if it succeeded (returning a length of zero)
* or if it failed (and returned zero)... our implementation never
* fails with a length of zero, so we trust all is okay...
*/
(void)BUF_MEM_grow_clean(S3I(s)->handshake_transcript, 0);
*/
(void)BUF_MEM_grow_clean(s->s3->handshake_transcript, 0);
tls1_transcript_unfreeze(s);
}
@@ -150,22 +153,22 @@ tls1_transcript_append(SSL *s, const unsigned char *buf, size_t len)
{
size_t olen, nlen;
if (S3I(s)->handshake_transcript == NULL)
if (s->s3->handshake_transcript == NULL)
return 1;
if (s->s3->flags & TLS1_FLAGS_FREEZE_TRANSCRIPT)
return 1;
olen = S3I(s)->handshake_transcript->length;
olen = s->s3->handshake_transcript->length;
nlen = olen + len;
if (nlen < olen)
return 0;
if (BUF_MEM_grow(S3I(s)->handshake_transcript, nlen) == 0)
if (BUF_MEM_grow(s->s3->handshake_transcript, nlen) == 0)
return 0;
memcpy(S3I(s)->handshake_transcript->data + olen, buf, len);
memcpy(s->s3->handshake_transcript->data + olen, buf, len);
return 1;
}
@@ -173,11 +176,11 @@ tls1_transcript_append(SSL *s, const unsigned char *buf, size_t len)
int
tls1_transcript_data(SSL *s, const unsigned char **data, size_t *len)
{
if (S3I(s)->handshake_transcript == NULL)
if (s->s3->handshake_transcript == NULL)
return 0;
*data = S3I(s)->handshake_transcript->data;
*len = S3I(s)->handshake_transcript->length;
*data = s->s3->handshake_transcript->data;
*len = s->s3->handshake_transcript->length;
return 1;
}

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: ssl_txt.c,v 1.28 2017/02/07 02:08:38 beck Exp $ */
/* $OpenBSD: ssl_txt.c,v 1.31 2021/11/29 18:36:27 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -95,7 +95,7 @@ SSL_SESSION_print_fp(FILE *fp, const SSL_SESSION *x)
BIO *b;
int ret;
if ((b = BIO_new(BIO_s_file_internal())) == NULL) {
if ((b = BIO_new(BIO_s_file())) == NULL) {
SSLerrorx(ERR_R_BUF_LIB);
return (0);
}
@@ -152,7 +152,7 @@ SSL_SESSION_print(BIO *bp, const SSL_SESSION *x)
}
if (x->tlsext_tick_lifetime_hint) {
if (BIO_printf(bp,
"\n TLS session ticket lifetime hint: %ld (seconds)",
"\n TLS session ticket lifetime hint: %u (seconds)",
x->tlsext_tick_lifetime_hint) <= 0)
goto err;
}
@@ -182,7 +182,7 @@ SSL_SESSION_print(BIO *bp, const SSL_SESSION *x)
goto err;
return (1);
err:
err:
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: ssl_versions.c,v 1.6 2020/05/31 18:03:32 jsing Exp $ */
/* $OpenBSD: ssl_versions.c,v 1.22 2022/02/05 14:54:10 jsing Exp $ */
/*
* Copyright (c) 2016, 2017 Joel Sing <jsing@openbsd.org>
*
@@ -17,8 +17,28 @@
#include "ssl_locl.h"
static uint16_t
ssl_dtls_to_tls_version(uint16_t dtls_ver)
{
if (dtls_ver == DTLS1_VERSION)
return TLS1_1_VERSION;
if (dtls_ver == DTLS1_2_VERSION)
return TLS1_2_VERSION;
return 0;
}
static uint16_t
ssl_tls_to_dtls_version(uint16_t tls_ver)
{
if (tls_ver == TLS1_1_VERSION)
return DTLS1_VERSION;
if (tls_ver == TLS1_2_VERSION)
return DTLS1_2_VERSION;
return 0;
}
static int
ssl_clamp_version_range(uint16_t *min_ver, uint16_t *max_ver,
ssl_clamp_tls_version_range(uint16_t *min_ver, uint16_t *max_ver,
uint16_t clamp_min, uint16_t clamp_max)
{
if (clamp_min > clamp_max || *min_ver > *max_ver)
@@ -35,55 +55,80 @@ ssl_clamp_version_range(uint16_t *min_ver, uint16_t *max_ver,
}
int
ssl_version_set_min(const SSL_METHOD *meth, uint16_t ver, uint16_t max_ver,
uint16_t *out_ver)
ssl_version_set_min(const SSL_METHOD *meth, uint16_t proto_ver,
uint16_t max_tls_ver, uint16_t *out_tls_ver, uint16_t *out_proto_ver)
{
uint16_t min_version, max_version;
uint16_t min_proto, min_version, max_version;
if (ver == 0) {
*out_ver = meth->internal->min_version;
if (proto_ver == 0) {
*out_tls_ver = meth->min_tls_version;
*out_proto_ver = 0;
return 1;
}
min_version = ver;
max_version = max_ver;
min_version = proto_ver;
max_version = max_tls_ver;
if (!ssl_clamp_version_range(&min_version, &max_version,
meth->internal->min_version, meth->internal->max_version))
if (meth->dtls) {
if ((min_version = ssl_dtls_to_tls_version(proto_ver)) == 0)
return 0;
}
if (!ssl_clamp_tls_version_range(&min_version, &max_version,
meth->min_tls_version, meth->max_tls_version))
return 0;
*out_ver = min_version;
min_proto = min_version;
if (meth->dtls) {
if ((min_proto = ssl_tls_to_dtls_version(min_version)) == 0)
return 0;
}
*out_tls_ver = min_version;
*out_proto_ver = min_proto;
return 1;
}
int
ssl_version_set_max(const SSL_METHOD *meth, uint16_t ver, uint16_t min_ver,
uint16_t *out_ver)
ssl_version_set_max(const SSL_METHOD *meth, uint16_t proto_ver,
uint16_t min_tls_ver, uint16_t *out_tls_ver, uint16_t *out_proto_ver)
{
uint16_t min_version, max_version;
uint16_t max_proto, min_version, max_version;
if (ver == 0) {
*out_ver = meth->internal->max_version;
if (proto_ver == 0) {
*out_tls_ver = meth->max_tls_version;
*out_proto_ver = 0;
return 1;
}
min_version = min_ver;
max_version = ver;
min_version = min_tls_ver;
max_version = proto_ver;
if (!ssl_clamp_version_range(&min_version, &max_version,
meth->internal->min_version, meth->internal->max_version))
if (meth->dtls) {
if ((max_version = ssl_dtls_to_tls_version(proto_ver)) == 0)
return 0;
}
if (!ssl_clamp_tls_version_range(&min_version, &max_version,
meth->min_tls_version, meth->max_tls_version))
return 0;
*out_ver = max_version;
max_proto = max_version;
if (meth->dtls) {
if ((max_proto = ssl_tls_to_dtls_version(max_version)) == 0)
return 0;
}
*out_tls_ver = max_version;
*out_proto_ver = max_proto;
return 1;
}
int
ssl_enabled_version_range(SSL *s, uint16_t *min_ver, uint16_t *max_ver)
ssl_enabled_tls_version_range(SSL *s, uint16_t *min_ver, uint16_t *max_ver)
{
uint16_t min_version, max_version;
unsigned long options;
/*
* The enabled versions have to be a contiguous range, which means we
@@ -95,23 +140,32 @@ ssl_enabled_version_range(SSL *s, uint16_t *min_ver, uint16_t *max_ver)
min_version = 0;
max_version = TLS1_3_VERSION;
options = s->internal->options;
if ((s->internal->options & SSL_OP_NO_TLSv1) == 0)
if (SSL_is_dtls(s)) {
options = 0;
if (s->internal->options & SSL_OP_NO_DTLSv1)
options |= SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1;
if (s->internal->options & SSL_OP_NO_DTLSv1_2)
options |= SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_2;
}
if ((options & SSL_OP_NO_TLSv1) == 0)
min_version = TLS1_VERSION;
else if ((s->internal->options & SSL_OP_NO_TLSv1_1) == 0)
else if ((options & SSL_OP_NO_TLSv1_1) == 0)
min_version = TLS1_1_VERSION;
else if ((s->internal->options & SSL_OP_NO_TLSv1_2) == 0)
else if ((options & SSL_OP_NO_TLSv1_2) == 0)
min_version = TLS1_2_VERSION;
else if ((s->internal->options & SSL_OP_NO_TLSv1_3) == 0)
else if ((options & SSL_OP_NO_TLSv1_3) == 0)
min_version = TLS1_3_VERSION;
if ((s->internal->options & SSL_OP_NO_TLSv1_3) && min_version < TLS1_3_VERSION)
if ((options & SSL_OP_NO_TLSv1_3) && min_version < TLS1_3_VERSION)
max_version = TLS1_2_VERSION;
if ((s->internal->options & SSL_OP_NO_TLSv1_2) && min_version < TLS1_2_VERSION)
if ((options & SSL_OP_NO_TLSv1_2) && min_version < TLS1_2_VERSION)
max_version = TLS1_1_VERSION;
if ((s->internal->options & SSL_OP_NO_TLSv1_1) && min_version < TLS1_1_VERSION)
if ((options & SSL_OP_NO_TLSv1_1) && min_version < TLS1_1_VERSION)
max_version = TLS1_VERSION;
if ((s->internal->options & SSL_OP_NO_TLSv1) && min_version < TLS1_VERSION)
if ((options & SSL_OP_NO_TLSv1) && min_version < TLS1_VERSION)
max_version = 0;
/* Everything has been disabled... */
@@ -119,8 +173,8 @@ ssl_enabled_version_range(SSL *s, uint16_t *min_ver, uint16_t *max_ver)
return 0;
/* Limit to configured version range. */
if (!ssl_clamp_version_range(&min_version, &max_version,
s->internal->min_version, s->internal->max_version))
if (!ssl_clamp_tls_version_range(&min_version, &max_version,
s->internal->min_tls_version, s->internal->max_tls_version))
return 0;
if (min_ver != NULL)
@@ -132,26 +186,18 @@ ssl_enabled_version_range(SSL *s, uint16_t *min_ver, uint16_t *max_ver)
}
int
ssl_supported_version_range(SSL *s, uint16_t *min_ver, uint16_t *max_ver)
ssl_supported_tls_version_range(SSL *s, uint16_t *min_ver, uint16_t *max_ver)
{
uint16_t min_version, max_version;
/* DTLS cannot currently be disabled... */
if (SSL_IS_DTLS(s)) {
min_version = max_version = DTLS1_VERSION;
goto done;
}
if (!ssl_enabled_version_range(s, &min_version, &max_version))
if (!ssl_enabled_tls_version_range(s, &min_version, &max_version))
return 0;
/* Limit to the versions supported by this method. */
if (!ssl_clamp_version_range(&min_version, &max_version,
s->method->internal->min_version,
s->method->internal->max_version))
if (!ssl_clamp_tls_version_range(&min_version, &max_version,
s->method->min_tls_version, s->method->max_tls_version))
return 0;
done:
if (min_ver != NULL)
*min_ver = min_version;
if (max_ver != NULL)
@@ -160,33 +206,111 @@ ssl_supported_version_range(SSL *s, uint16_t *min_ver, uint16_t *max_ver)
return 1;
}
uint16_t
ssl_tls_version(uint16_t version)
{
if (version == TLS1_VERSION || version == TLS1_1_VERSION ||
version == TLS1_2_VERSION || version == TLS1_3_VERSION)
return version;
if (version == DTLS1_VERSION)
return TLS1_1_VERSION;
if (version == DTLS1_2_VERSION)
return TLS1_2_VERSION;
return 0;
}
uint16_t
ssl_effective_tls_version(SSL *s)
{
if (s->s3->hs.negotiated_tls_version > 0)
return s->s3->hs.negotiated_tls_version;
return s->s3->hs.our_max_tls_version;
}
int
ssl_max_supported_version(SSL *s, uint16_t *max_ver)
{
uint16_t max_version;
*max_ver = 0;
if (!ssl_supported_tls_version_range(s, NULL, &max_version))
return 0;
if (SSL_is_dtls(s)) {
if ((max_version = ssl_tls_to_dtls_version(max_version)) == 0)
return 0;
}
*max_ver = max_version;
return 1;
}
int
ssl_max_legacy_version(SSL *s, uint16_t *max_ver)
{
uint16_t max_version;
if ((max_version = s->s3->hs.our_max_tls_version) > TLS1_2_VERSION)
max_version = TLS1_2_VERSION;
if (SSL_is_dtls(s)) {
if ((max_version = ssl_tls_to_dtls_version(max_version)) == 0)
return 0;
}
*max_ver = max_version;
return 1;
}
int
ssl_max_shared_version(SSL *s, uint16_t peer_ver, uint16_t *max_ver)
{
uint16_t min_version, max_version, shared_version;
uint16_t min_version, max_version, peer_tls_version, shared_version;
*max_ver = 0;
peer_tls_version = peer_ver;
if (SSL_IS_DTLS(s)) {
if (peer_ver >= DTLS1_VERSION) {
*max_ver = DTLS1_VERSION;
return 1;
if (SSL_is_dtls(s)) {
if ((peer_ver >> 8) != DTLS1_VERSION_MAJOR)
return 0;
/*
* Convert the peer version to a TLS version - DTLS versions are
* the 1's complement of TLS version numbers (but not the actual
* protocol version numbers, that would be too sensible). Not to
* mention that DTLSv1.0 is really equivalent to DTLSv1.1.
*/
peer_tls_version = ssl_dtls_to_tls_version(peer_ver);
/*
* This may be a version that we do not know about, if it is
* newer than DTLS1_2_VERSION (yes, less than is correct due
* to the "clever" versioning scheme), use TLS1_2_VERSION.
*/
if (peer_tls_version == 0) {
if (peer_ver < DTLS1_2_VERSION)
peer_tls_version = TLS1_2_VERSION;
}
return 0;
}
if (peer_ver >= TLS1_3_VERSION)
if (peer_tls_version >= TLS1_3_VERSION)
shared_version = TLS1_3_VERSION;
else if (peer_ver >= TLS1_2_VERSION)
else if (peer_tls_version >= TLS1_2_VERSION)
shared_version = TLS1_2_VERSION;
else if (peer_ver >= TLS1_1_VERSION)
else if (peer_tls_version >= TLS1_1_VERSION)
shared_version = TLS1_1_VERSION;
else if (peer_ver >= TLS1_VERSION)
else if (peer_tls_version >= TLS1_VERSION)
shared_version = TLS1_VERSION;
else
return 0;
if (!ssl_supported_version_range(s, &min_version, &max_version))
if (!ssl_supported_tls_version_range(s, &min_version, &max_version))
return 0;
if (shared_version < min_version)
@@ -195,39 +319,49 @@ ssl_max_shared_version(SSL *s, uint16_t peer_ver, uint16_t *max_ver)
if (shared_version > max_version)
shared_version = max_version;
if (SSL_is_dtls(s)) {
/*
* The resulting shared version will by definition be something
* that we know about. Switch back from TLS to DTLS.
*/
shared_version = ssl_tls_to_dtls_version(shared_version);
if (shared_version == 0)
return 0;
}
*max_ver = shared_version;
return 1;
}
int
ssl_downgrade_max_version(SSL *s, uint16_t *max_ver)
ssl_check_version_from_server(SSL *s, uint16_t server_version)
{
uint16_t min_version, max_version;
uint16_t min_tls_version, max_tls_version, server_tls_version;
/*
* The downgrade maximum version is based on the versions that are
* enabled, however we also have to then limit to the versions
* supported by the method. The SSL method will be changed during
* version negotiation and when switching from the new stack to
* the legacy context, as such we want to use the method from the
* context.
*/
/* Ensure that the version selected by the server is valid. */
if (SSL_IS_DTLS(s)) {
*max_ver = DTLS1_VERSION;
return 1;
server_tls_version = server_version;
if (SSL_is_dtls(s)) {
server_tls_version = ssl_dtls_to_tls_version(server_version);
if (server_tls_version == 0)
return 0;
}
if (!ssl_enabled_version_range(s, &min_version, &max_version))
if (!ssl_supported_tls_version_range(s, &min_tls_version,
&max_tls_version))
return 0;
if (!ssl_clamp_version_range(&min_version, &max_version,
s->ctx->method->internal->min_version,
s->ctx->method->internal->max_version))
return 0;
*max_ver = max_version;
return 1;
return (server_tls_version >= min_tls_version &&
server_tls_version <= max_tls_version);
}
int
ssl_legacy_stack_version(SSL *s, uint16_t version)
{
if (SSL_is_dtls(s))
return version == DTLS1_VERSION || version == DTLS1_2_VERSION;
return version == TLS1_VERSION || version == TLS1_1_VERSION ||
version == TLS1_2_VERSION;
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: t1_lib.c,v 1.176 2020/09/12 17:25:11 tb Exp $ */
/* $OpenBSD: t1_lib.c,v 1.186 2022/01/24 13:47:53 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -116,34 +116,20 @@
#include <openssl/objects.h>
#include <openssl/ocsp.h>
#include "ssl_locl.h"
#include "bytestring.h"
#include "ssl_locl.h"
#include "ssl_sigalgs.h"
#include "ssl_tlsext.h"
static int tls_decrypt_ticket(SSL *s, CBS *ticket, int *alert,
SSL_SESSION **psess);
SSL3_ENC_METHOD TLSv1_enc_data = {
.enc_flags = 0,
};
SSL3_ENC_METHOD TLSv1_1_enc_data = {
.enc_flags = SSL_ENC_FLAG_EXPLICIT_IV,
};
SSL3_ENC_METHOD TLSv1_2_enc_data = {
.enc_flags = SSL_ENC_FLAG_EXPLICIT_IV|SSL_ENC_FLAG_SIGALGS|
SSL_ENC_FLAG_SHA256_PRF|SSL_ENC_FLAG_TLS1_2_CIPHERS,
};
int
tls1_new(SSL *s)
{
if (!ssl3_new(s))
return (0);
s->method->internal->ssl_clear(s);
s->method->ssl_clear(s);
return (1);
}
@@ -161,10 +147,10 @@ void
tls1_clear(SSL *s)
{
ssl3_clear(s);
s->version = s->method->internal->version;
s->version = s->method->version;
}
static int nid_list[] = {
static const int nid_list[] = {
NID_sect163k1, /* sect163k1 (1) */
NID_sect163r1, /* sect163r1 (2) */
NID_sect163r2, /* sect163r2 (3) */
@@ -343,8 +329,8 @@ tls1_get_formatlist(SSL *s, int client_formats, const uint8_t **pformats,
size_t *pformatslen)
{
if (client_formats != 0) {
*pformats = SSI(s)->tlsext_ecpointformatlist;
*pformatslen = SSI(s)->tlsext_ecpointformatlist_length;
*pformats = s->session->tlsext_ecpointformatlist;
*pformatslen = s->session->tlsext_ecpointformatlist_length;
return;
}
@@ -366,8 +352,8 @@ tls1_get_group_list(SSL *s, int client_groups, const uint16_t **pgroups,
size_t *pgroupslen)
{
if (client_groups != 0) {
*pgroups = SSI(s)->tlsext_supportedgroups;
*pgroupslen = SSI(s)->tlsext_supportedgroups_length;
*pgroups = s->session->tlsext_supportedgroups;
*pgroupslen = s->session->tlsext_supportedgroups_length;
return;
}
@@ -583,19 +569,19 @@ tls1_check_ec_key(SSL *s, const uint16_t *curve_id, const uint8_t *comp_id)
int
tls1_check_ec_server_key(SSL *s)
{
CERT_PKEY *cpk = s->cert->pkeys + SSL_PKEY_ECC;
SSL_CERT_PKEY *cpk = s->cert->pkeys + SSL_PKEY_ECC;
uint16_t curve_id;
uint8_t comp_id;
EC_KEY *eckey;
EVP_PKEY *pkey;
int rv;
if (cpk->x509 == NULL || cpk->privatekey == NULL)
return (0);
if ((pkey = X509_get_pubkey(cpk->x509)) == NULL)
if ((pkey = X509_get0_pubkey(cpk->x509)) == NULL)
return (0);
rv = tls1_set_ec_id(&curve_id, &comp_id, pkey->pkey.ec);
EVP_PKEY_free(pkey);
if (rv != 1)
if ((eckey = EVP_PKEY_get0_EC_KEY(pkey)) == NULL)
return (0);
if (!tls1_set_ec_id(&curve_id, &comp_id, eckey))
return (0);
return tls1_check_ec_key(s, &curve_id, &comp_id);
@@ -648,7 +634,7 @@ ssl_check_clienthello_tlsext_late(SSL *s)
if ((s->tlsext_status_type != -1) &&
s->ctx && s->ctx->internal->tlsext_status_cb) {
int r;
CERT_PKEY *certpkey;
SSL_CERT_PKEY *certpkey;
certpkey = ssl_get_server_send_pkey(s);
/* If no certificate can't return certificate status */
if (certpkey == NULL) {
@@ -682,7 +668,7 @@ ssl_check_clienthello_tlsext_late(SSL *s)
} else
s->internal->tlsext_status_expected = 0;
err:
err:
switch (ret) {
case SSL_TLSEXT_ERR_ALERT_FATAL:
ssl3_send_alert(s, SSL3_AL_FATAL, al);

175
externals/libressl/ssl/tls12_key_schedule.c vendored Executable file
View File

@@ -0,0 +1,175 @@
/* $OpenBSD: tls12_key_schedule.c,v 1.1 2021/05/05 10:05:27 jsing Exp $ */
/*
* Copyright (c) 2021 Joel Sing <jsing@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <stdlib.h>
#include <openssl/evp.h>
#include "bytestring.h"
#include "ssl_locl.h"
struct tls12_key_block {
CBS client_write_mac_key;
CBS server_write_mac_key;
CBS client_write_key;
CBS server_write_key;
CBS client_write_iv;
CBS server_write_iv;
uint8_t *key_block;
size_t key_block_len;
};
struct tls12_key_block *
tls12_key_block_new(void)
{
return calloc(1, sizeof(struct tls12_key_block));
}
static void
tls12_key_block_clear(struct tls12_key_block *kb)
{
CBS_init(&kb->client_write_mac_key, NULL, 0);
CBS_init(&kb->server_write_mac_key, NULL, 0);
CBS_init(&kb->client_write_key, NULL, 0);
CBS_init(&kb->server_write_key, NULL, 0);
CBS_init(&kb->client_write_iv, NULL, 0);
CBS_init(&kb->server_write_iv, NULL, 0);
freezero(kb->key_block, kb->key_block_len);
kb->key_block = NULL;
kb->key_block_len = 0;
}
void
tls12_key_block_free(struct tls12_key_block *kb)
{
if (kb == NULL)
return;
tls12_key_block_clear(kb);
freezero(kb, sizeof(struct tls12_key_block));
}
void
tls12_key_block_client_write(struct tls12_key_block *kb, CBS *mac_key,
CBS *key, CBS *iv)
{
CBS_dup(&kb->client_write_mac_key, mac_key);
CBS_dup(&kb->client_write_key, key);
CBS_dup(&kb->client_write_iv, iv);
}
void
tls12_key_block_server_write(struct tls12_key_block *kb, CBS *mac_key,
CBS *key, CBS *iv)
{
CBS_dup(&kb->server_write_mac_key, mac_key);
CBS_dup(&kb->server_write_key, key);
CBS_dup(&kb->server_write_iv, iv);
}
int
tls12_key_block_generate(struct tls12_key_block *kb, SSL *s,
const EVP_AEAD *aead, const EVP_CIPHER *cipher, const EVP_MD *mac_hash)
{
size_t mac_key_len = 0, key_len = 0, iv_len = 0;
uint8_t *key_block = NULL;
size_t key_block_len = 0;
CBS cbs;
/*
* Generate a TLSv1.2 key block and partition into individual secrets,
* as per RFC 5246 section 6.3.
*/
tls12_key_block_clear(kb);
/* Must have AEAD or cipher/MAC pair. */
if (aead == NULL && (cipher == NULL || mac_hash == NULL))
goto err;
if (aead != NULL) {
key_len = EVP_AEAD_key_length(aead);
/* AEAD fixed nonce length. */
if (aead == EVP_aead_aes_128_gcm() ||
aead == EVP_aead_aes_256_gcm())
iv_len = 4;
else if (aead == EVP_aead_chacha20_poly1305())
iv_len = 12;
else
goto err;
} else if (cipher != NULL && mac_hash != NULL) {
/*
* A negative integer return value will be detected via the
* EVP_MAX_* checks against the size_t variables below.
*/
mac_key_len = EVP_MD_size(mac_hash);
key_len = EVP_CIPHER_key_length(cipher);
iv_len = EVP_CIPHER_iv_length(cipher);
/* Special handling for GOST... */
if (EVP_MD_type(mac_hash) == NID_id_Gost28147_89_MAC)
mac_key_len = 32;
}
if (mac_key_len > EVP_MAX_MD_SIZE)
goto err;
if (key_len > EVP_MAX_KEY_LENGTH)
goto err;
if (iv_len > EVP_MAX_IV_LENGTH)
goto err;
key_block_len = 2 * mac_key_len + 2 * key_len + 2 * iv_len;
if ((key_block = calloc(1, key_block_len)) == NULL)
goto err;
if (!tls1_generate_key_block(s, key_block, key_block_len))
goto err;
kb->key_block = key_block;
kb->key_block_len = key_block_len;
key_block = NULL;
key_block_len = 0;
/* Partition key block into individual secrets. */
CBS_init(&cbs, kb->key_block, kb->key_block_len);
if (!CBS_get_bytes(&cbs, &kb->client_write_mac_key, mac_key_len))
goto err;
if (!CBS_get_bytes(&cbs, &kb->server_write_mac_key, mac_key_len))
goto err;
if (!CBS_get_bytes(&cbs, &kb->client_write_key, key_len))
goto err;
if (!CBS_get_bytes(&cbs, &kb->server_write_key, key_len))
goto err;
if (!CBS_get_bytes(&cbs, &kb->client_write_iv, iv_len))
goto err;
if (!CBS_get_bytes(&cbs, &kb->server_write_iv, iv_len))
goto err;
if (CBS_len(&cbs) != 0)
goto err;
return 1;
err:
tls12_key_block_clear(kb);
freezero(key_block, key_block_len);
return 0;
}

118
externals/libressl/ssl/tls12_lib.c vendored Executable file
View File

@@ -0,0 +1,118 @@
/* $OpenBSD: tls12_lib.c,v 1.4 2022/02/05 14:54:10 jsing Exp $ */
/*
* Copyright (c) 2021 Joel Sing <jsing@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "ssl_locl.h"
static int
tls12_finished_verify_data(SSL *s, const char *finished_label,
size_t finished_label_len, uint8_t *verify_data, size_t verify_data_len,
size_t *out_len)
{
uint8_t transcript_hash[EVP_MAX_MD_SIZE];
size_t transcript_hash_len;
*out_len = 0;
if (s->session->master_key_length <= 0)
return 0;
if (verify_data_len < TLS1_FINISH_MAC_LENGTH)
return 0;
if (!tls1_transcript_hash_value(s, transcript_hash,
sizeof(transcript_hash), &transcript_hash_len))
return 0;
if (!tls1_PRF(s, s->session->master_key, s->session->master_key_length,
finished_label, finished_label_len, transcript_hash,
transcript_hash_len, NULL, 0, NULL, 0, NULL, 0, verify_data,
TLS1_FINISH_MAC_LENGTH))
return 0;
*out_len = TLS1_FINISH_MAC_LENGTH;
return 1;
}
static int
tls12_client_finished_verify_data(SSL *s, uint8_t *verify_data,
size_t verify_data_len, size_t *out_len)
{
return tls12_finished_verify_data(s, TLS_MD_CLIENT_FINISH_CONST,
TLS_MD_CLIENT_FINISH_CONST_SIZE, verify_data, verify_data_len,
out_len);
}
static int
tls12_server_finished_verify_data(SSL *s, uint8_t *verify_data,
size_t verify_data_len, size_t *out_len)
{
return tls12_finished_verify_data(s, TLS_MD_SERVER_FINISH_CONST,
TLS_MD_SERVER_FINISH_CONST_SIZE, verify_data, verify_data_len,
out_len);
}
int
tls12_derive_finished(SSL *s)
{
if (!s->server) {
return tls12_client_finished_verify_data(s,
s->s3->hs.finished, sizeof(s->s3->hs.finished),
&s->s3->hs.finished_len);
} else {
return tls12_server_finished_verify_data(s,
s->s3->hs.finished, sizeof(s->s3->hs.finished),
&s->s3->hs.finished_len);
}
}
int
tls12_derive_peer_finished(SSL *s)
{
if (s->server) {
return tls12_client_finished_verify_data(s,
s->s3->hs.peer_finished, sizeof(s->s3->hs.peer_finished),
&s->s3->hs.peer_finished_len);
} else {
return tls12_server_finished_verify_data(s,
s->s3->hs.peer_finished, sizeof(s->s3->hs.peer_finished),
&s->s3->hs.peer_finished_len);
}
}
int
tls12_derive_master_secret(SSL *s, uint8_t *premaster_secret,
size_t premaster_secret_len)
{
s->session->master_key_length = 0;
if (premaster_secret_len == 0)
return 0;
CTASSERT(sizeof(s->session->master_key) == SSL_MAX_MASTER_KEY_LENGTH);
if (!tls1_PRF(s, premaster_secret, premaster_secret_len,
TLS_MD_MASTER_SECRET_CONST, TLS_MD_MASTER_SECRET_CONST_SIZE,
s->s3->client_random, SSL3_RANDOM_SIZE, NULL, 0,
s->s3->server_random, SSL3_RANDOM_SIZE, NULL, 0,
s->session->master_key, sizeof(s->session->master_key)))
return 0;
s->session->master_key_length = SSL_MAX_MASTER_KEY_LENGTH;
return 1;
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: tls13_client.c,v 1.67 2020/09/11 17:36:27 jsing Exp $ */
/* $OpenBSD: tls13_client.c,v 1.94 2022/02/03 16:33:12 jsing Exp $ */
/*
* Copyright (c) 2018, 2019 Joel Sing <jsing@openbsd.org>
*
@@ -15,11 +15,11 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "ssl_locl.h"
#include <openssl/ssl3.h>
#include "bytestring.h"
#include "ssl_locl.h"
#include "ssl_sigalgs.h"
#include "ssl_tlsext.h"
#include "tls13_handshake.h"
#include "tls13_internal.h"
@@ -31,12 +31,12 @@ tls13_client_init(struct tls13_ctx *ctx)
size_t groups_len;
SSL *s = ctx->ssl;
if (!ssl_supported_version_range(s, &ctx->hs->min_version,
&ctx->hs->max_version)) {
if (!ssl_supported_tls_version_range(s, &ctx->hs->our_min_tls_version,
&ctx->hs->our_max_tls_version)) {
SSLerror(s, SSL_R_NO_PROTOCOLS_AVAILABLE);
return 0;
}
s->client_version = s->version = ctx->hs->max_version;
s->version = ctx->hs->our_max_tls_version;
tls13_record_layer_set_retry_after_phh(ctx->rl,
(s->internal->mode & SSL_MODE_AUTO_RETRY) != 0);
@@ -51,9 +51,9 @@ tls13_client_init(struct tls13_ctx *ctx)
tls1_get_group_list(s, 0, &groups, &groups_len);
if (groups_len < 1)
return 0;
if ((ctx->hs->key_share = tls13_key_share_new(groups[0])) == NULL)
if ((ctx->hs->key_share = tls_key_share_new(groups[0])) == NULL)
return 0;
if (!tls13_key_share_generate(ctx->hs->key_share))
if (!tls_key_share_generate(ctx->hs->key_share))
return 0;
arc4random_buf(s->s3->client_random, SSL3_RANDOM_SIZE);
@@ -64,11 +64,12 @@ tls13_client_init(struct tls13_ctx *ctx)
* legacy session identifier triggers compatibility mode (see RFC 8446
* Appendix D.4). In the pre-TLSv1.3 case a zero length value is used.
*/
if (ctx->middlebox_compat && ctx->hs->max_version >= TLS1_3_VERSION) {
arc4random_buf(ctx->hs->legacy_session_id,
sizeof(ctx->hs->legacy_session_id));
ctx->hs->legacy_session_id_len =
sizeof(ctx->hs->legacy_session_id);
if (ctx->middlebox_compat &&
ctx->hs->our_max_tls_version >= TLS1_3_VERSION) {
arc4random_buf(ctx->hs->tls13.legacy_session_id,
sizeof(ctx->hs->tls13.legacy_session_id));
ctx->hs->tls13.legacy_session_id_len =
sizeof(ctx->hs->tls13.legacy_session_id);
}
return 1;
@@ -91,9 +92,8 @@ tls13_client_hello_build(struct tls13_ctx *ctx, CBB *cbb)
SSL *s = ctx->ssl;
/* Legacy client version is capped at TLS 1.2. */
client_version = ctx->hs->max_version;
if (client_version > TLS1_2_VERSION)
client_version = TLS1_2_VERSION;
if (!ssl_max_legacy_version(s, &client_version))
goto err;
if (!CBB_add_u16(cbb, client_version))
goto err;
@@ -102,8 +102,8 @@ tls13_client_hello_build(struct tls13_ctx *ctx, CBB *cbb)
if (!CBB_add_u8_length_prefixed(cbb, &session_id))
goto err;
if (!CBB_add_bytes(&session_id, ctx->hs->legacy_session_id,
ctx->hs->legacy_session_id_len))
if (!CBB_add_bytes(&session_id, ctx->hs->tls13.legacy_session_id,
ctx->hs->tls13.legacy_session_id_len))
goto err;
if (!CBB_add_u16_length_prefixed(cbb, &cipher_suites))
@@ -133,7 +133,7 @@ tls13_client_hello_build(struct tls13_ctx *ctx, CBB *cbb)
int
tls13_client_hello_send(struct tls13_ctx *ctx, CBB *cbb)
{
if (ctx->hs->min_version < TLS1_2_VERSION)
if (ctx->hs->our_min_tls_version < TLS1_2_VERSION)
tls13_record_layer_set_legacy_version(ctx->rl, TLS1_VERSION);
/* We may receive a pre-TLSv1.3 alert in response to the client hello. */
@@ -228,9 +228,9 @@ tls13_server_hello_process(struct tls13_ctx *ctx, CBS *cbs)
goto err;
if (tls13_server_hello_is_legacy(cbs)) {
if (ctx->hs->max_version >= TLS1_3_VERSION) {
if (ctx->hs->our_max_tls_version >= TLS1_3_VERSION) {
/*
* RFC 8446 section 4.1.3, We must not downgrade if
* RFC 8446 section 4.1.3: we must not downgrade if
* the server random value contains the TLS 1.2 or 1.1
* magical value.
*/
@@ -249,7 +249,7 @@ tls13_server_hello_process(struct tls13_ctx *ctx, CBS *cbs)
if (!CBS_skip(cbs, CBS_len(cbs)))
goto err;
ctx->hs->use_legacy = 1;
ctx->hs->tls13.use_legacy = 1;
return 1;
}
@@ -262,7 +262,7 @@ tls13_server_hello_process(struct tls13_ctx *ctx, CBS *cbs)
if (CBS_mem_equal(&server_random, tls13_hello_retry_request_hash,
sizeof(tls13_hello_retry_request_hash))) {
tlsext_msg_type = SSL_TLSEXT_MSG_HRR;
ctx->hs->hrr = 1;
ctx->hs->tls13.hrr = 1;
}
if (!tlsext_client_parse(s, tlsext_msg_type, cbs, &alert_desc)) {
@@ -271,50 +271,49 @@ tls13_server_hello_process(struct tls13_ctx *ctx, CBS *cbs)
}
/*
* See if a supported versions extension was returned. If it was then
* the legacy version must be set to 0x0303 (RFC 8446 section 4.1.3).
* Otherwise, fallback to the legacy version, ensuring that it is both
* within range and not TLS 1.3 or greater (which must use the
* supported version extension.
* The supported versions extension indicated 0x0304 or greater.
* Ensure that it was 0x0304 and that legacy version is set to 0x0303
* (RFC 8446 section 4.2.1).
*/
if (ctx->hs->server_version != 0) {
if (legacy_version != TLS1_2_VERSION) {
ctx->alert = TLS13_ALERT_PROTOCOL_VERSION;
goto err;
}
} else {
if (legacy_version < ctx->hs->min_version ||
legacy_version > ctx->hs->max_version ||
legacy_version > TLS1_2_VERSION) {
ctx->alert = TLS13_ALERT_PROTOCOL_VERSION;
goto err;
}
ctx->hs->server_version = legacy_version;
if (ctx->hs->tls13.server_version != TLS1_3_VERSION ||
legacy_version != TLS1_2_VERSION) {
ctx->alert = TLS13_ALERT_PROTOCOL_VERSION;
goto err;
}
ctx->hs->negotiated_tls_version = ctx->hs->tls13.server_version;
ctx->hs->peer_legacy_version = legacy_version;
/* The session_id must match. */
if (!CBS_mem_equal(&session_id, ctx->hs->legacy_session_id,
ctx->hs->legacy_session_id_len)) {
if (!CBS_mem_equal(&session_id, ctx->hs->tls13.legacy_session_id,
ctx->hs->tls13.legacy_session_id_len)) {
ctx->alert = TLS13_ALERT_ILLEGAL_PARAMETER;
goto err;
}
/*
* Ensure that the cipher suite is one that we offered in the client
* hello and that it matches the TLS version selected.
* hello and that it is a TLSv1.3 cipher suite.
*/
cipher = ssl3_get_cipher_by_value(cipher_suite);
if (cipher == NULL || !ssl_cipher_in_list(SSL_get_ciphers(s), cipher)) {
ctx->alert = TLS13_ALERT_ILLEGAL_PARAMETER;
goto err;
}
if (ctx->hs->server_version == TLS1_3_VERSION &&
cipher->algorithm_ssl != SSL_TLSV1_3) {
if (cipher->algorithm_ssl != SSL_TLSV1_3) {
ctx->alert = TLS13_ALERT_ILLEGAL_PARAMETER;
goto err;
}
/* XXX - move this to hs_tls13? */
S3I(s)->hs.new_cipher = cipher;
if (!(ctx->handshake_stage.hs_type & WITHOUT_HRR) && !ctx->hs->tls13.hrr) {
/*
* A ServerHello following a HelloRetryRequest MUST use the same
* cipher suite (RFC 8446 section 4.1.4).
*/
if (ctx->hs->cipher != cipher) {
ctx->alert = TLS13_ALERT_ILLEGAL_PARAMETER;
goto err;
}
}
ctx->hs->cipher = cipher;
if (compression_method != 0) {
ctx->alert = TLS13_ALERT_ILLEGAL_PARAMETER;
@@ -344,21 +343,21 @@ tls13_client_engage_record_protection(struct tls13_ctx *ctx)
/* Derive the shared key and engage record protection. */
if (!tls13_key_share_derive(ctx->hs->key_share, &shared_key,
if (!tls_key_share_derive(ctx->hs->key_share, &shared_key,
&shared_key_len))
goto err;
s->session->cipher = S3I(s)->hs.new_cipher;
s->session->ssl_version = ctx->hs->server_version;
s->session->cipher = ctx->hs->cipher;
s->session->ssl_version = ctx->hs->tls13.server_version;
if ((ctx->aead = tls13_cipher_aead(S3I(s)->hs.new_cipher)) == NULL)
if ((ctx->aead = tls13_cipher_aead(ctx->hs->cipher)) == NULL)
goto err;
if ((ctx->hash = tls13_cipher_hash(S3I(s)->hs.new_cipher)) == NULL)
if ((ctx->hash = tls13_cipher_hash(ctx->hs->cipher)) == NULL)
goto err;
if ((secrets = tls13_secrets_create(ctx->hash, 0)) == NULL)
goto err;
ctx->hs->secrets = secrets;
ctx->hs->tls13.secrets = secrets;
/* XXX - pass in hash. */
if (!tls1_transcript_hash_init(s))
@@ -375,7 +374,7 @@ tls13_client_engage_record_protection(struct tls13_ctx *ctx)
goto err;
/* Handshake secrets. */
if (!tls13_derive_handshake_secrets(ctx->hs->secrets, shared_key,
if (!tls13_derive_handshake_secrets(ctx->hs->tls13.secrets, shared_key,
shared_key_len, &context))
goto err;
@@ -414,13 +413,13 @@ tls13_server_hello_retry_request_recv(struct tls13_ctx *ctx, CBS *cbs)
return 0;
/*
* This may have been a TLSv1.2 or earlier ServerHello that just happened
* to have matching server random...
* This may have been a TLSv1.2 or earlier ServerHello that just
* happened to have matching server random...
*/
if (ctx->hs->use_legacy)
if (ctx->hs->tls13.use_legacy)
return tls13_use_legacy_client(ctx);
if (!ctx->hs->hrr)
if (!ctx->hs->tls13.hrr)
return 0;
if (!tls13_synthetic_handshake_message(ctx))
@@ -428,7 +427,7 @@ tls13_server_hello_retry_request_recv(struct tls13_ctx *ctx, CBS *cbs)
if (!tls13_handshake_msg_record(ctx))
return 0;
ctx->hs->hrr = 0;
ctx->hs->tls13.hrr = 0;
return 1;
}
@@ -441,17 +440,17 @@ tls13_client_hello_retry_send(struct tls13_ctx *ctx, CBB *cbb)
* supported groups and is not the same as the key share we previously
* offered.
*/
if (!tls1_check_curve(ctx->ssl, ctx->hs->server_group))
if (!tls1_check_curve(ctx->ssl, ctx->hs->tls13.server_group))
return 0; /* XXX alert */
if (ctx->hs->server_group == tls13_key_share_group(ctx->hs->key_share))
if (ctx->hs->tls13.server_group == tls_key_share_group(ctx->hs->key_share))
return 0; /* XXX alert */
/* Switch to new key share. */
tls13_key_share_free(ctx->hs->key_share);
tls_key_share_free(ctx->hs->key_share);
if ((ctx->hs->key_share =
tls13_key_share_new(ctx->hs->server_group)) == NULL)
tls_key_share_new(ctx->hs->tls13.server_group)) == NULL)
return 0;
if (!tls13_key_share_generate(ctx->hs->key_share))
if (!tls_key_share_generate(ctx->hs->key_share))
return 0;
if (!tls13_client_hello_build(ctx, cbb))
@@ -478,13 +477,13 @@ tls13_server_hello_recv(struct tls13_ctx *ctx, CBS *cbs)
return 0;
}
if (ctx->hs->use_legacy) {
if (ctx->hs->tls13.use_legacy) {
if (!(ctx->handshake_stage.hs_type & WITHOUT_HRR))
return 0;
return tls13_use_legacy_client(ctx);
}
if (ctx->hs->hrr) {
if (ctx->hs->tls13.hrr) {
/* The server has sent two HelloRetryRequests. */
ctx->alert = TLS13_ALERT_ILLEGAL_PARAMETER;
return 0;
@@ -562,7 +561,7 @@ tls13_server_certificate_recv(struct tls13_ctx *ctx, CBS *cbs)
X509 *cert = NULL;
EVP_PKEY *pkey;
const uint8_t *p;
int cert_idx, alert_desc;
int alert_desc, cert_type;
int ret = 0;
if ((certs = sk_X509_new_null()) == NULL)
@@ -626,26 +625,20 @@ tls13_server_certificate_recv(struct tls13_ctx *ctx, CBS *cbs)
goto err;
if (EVP_PKEY_missing_parameters(pkey))
goto err;
if ((cert_idx = ssl_cert_type(cert, pkey)) < 0)
if ((cert_type = ssl_cert_type(pkey)) < 0)
goto err;
ssl_sess_cert_free(SSI(s)->sess_cert);
if ((SSI(s)->sess_cert = ssl_sess_cert_new()) == NULL)
goto err;
SSI(s)->sess_cert->cert_chain = certs;
certs = NULL;
X509_up_ref(cert);
SSI(s)->sess_cert->peer_pkeys[cert_idx].x509 = cert;
SSI(s)->sess_cert->peer_key = &(SSI(s)->sess_cert->peer_pkeys[cert_idx]);
X509_free(s->session->peer_cert);
s->session->peer_cert = cert;
s->session->peer_cert_type = cert_type;
X509_free(s->session->peer);
X509_up_ref(cert);
s->session->peer = cert;
s->session->verify_result = s->verify_result;
sk_X509_pop_free(s->session->cert_chain, X509_free);
s->session->cert_chain = certs;
certs = NULL;
if (ctx->ocsp_status_recv_cb != NULL &&
!ctx->ocsp_status_recv_cb(ctx))
goto err;
@@ -681,10 +674,6 @@ tls13_server_certificate_verify_recv(struct tls13_ctx *ctx, CBS *cbs)
if (!CBS_get_u16_length_prefixed(cbs, &signature))
goto err;
if ((sigalg = ssl_sigalg(signature_scheme, tls13_sigalgs,
tls13_sigalgs_len)) == NULL)
goto err;
if (!CBB_init(&cbb, 0))
goto err;
if (!CBB_add_bytes(&cbb, tls13_cert_verify_pad,
@@ -695,18 +684,20 @@ tls13_server_certificate_verify_recv(struct tls13_ctx *ctx, CBS *cbs)
goto err;
if (!CBB_add_u8(&cbb, 0))
goto err;
if (!CBB_add_bytes(&cbb, ctx->hs->transcript_hash,
ctx->hs->transcript_hash_len))
if (!CBB_add_bytes(&cbb, ctx->hs->tls13.transcript_hash,
ctx->hs->tls13.transcript_hash_len))
goto err;
if (!CBB_finish(&cbb, &sig_content, &sig_content_len))
goto err;
if ((cert = ctx->ssl->session->peer) == NULL)
if ((cert = ctx->ssl->session->peer_cert) == NULL)
goto err;
if ((pkey = X509_get0_pubkey(cert)) == NULL)
goto err;
if (!ssl_sigalg_pkey_ok(sigalg, pkey, 1))
if ((sigalg = ssl_sigalg_for_peer(ctx->ssl, pkey,
signature_scheme)) == NULL)
goto err;
ctx->hs->peer_sigalg = sigalg;
if (CBS_len(&signature) > EVP_PKEY_size(pkey))
goto err;
@@ -746,7 +737,7 @@ tls13_server_certificate_verify_recv(struct tls13_ctx *ctx, CBS *cbs)
int
tls13_server_finished_recv(struct tls13_ctx *ctx, CBS *cbs)
{
struct tls13_secrets *secrets = ctx->hs->secrets;
struct tls13_secrets *secrets = ctx->hs->tls13.secrets;
struct tls13_secret context = { .data = "", .len = 0 };
struct tls13_secret finished_key;
uint8_t transcript_hash[EVP_MAX_MD_SIZE];
@@ -774,8 +765,8 @@ tls13_server_finished_recv(struct tls13_ctx *ctx, CBS *cbs)
if (!HMAC_Init_ex(hmac_ctx, finished_key.data, finished_key.len,
ctx->hash, NULL))
goto err;
if (!HMAC_Update(hmac_ctx, ctx->hs->transcript_hash,
ctx->hs->transcript_hash_len))
if (!HMAC_Update(hmac_ctx, ctx->hs->tls13.transcript_hash,
ctx->hs->tls13.transcript_hash_len))
goto err;
verify_data_len = HMAC_size(hmac_ctx);
if ((verify_data = calloc(1, verify_data_len)) == NULL)
@@ -790,6 +781,11 @@ tls13_server_finished_recv(struct tls13_ctx *ctx, CBS *cbs)
goto err;
}
if (!CBS_write_bytes(cbs, ctx->hs->peer_finished,
sizeof(ctx->hs->peer_finished),
&ctx->hs->peer_finished_len))
goto err;
if (!CBS_skip(cbs, verify_data_len))
goto err;
@@ -826,7 +822,7 @@ tls13_server_finished_recv(struct tls13_ctx *ctx, CBS *cbs)
}
static int
tls13_client_check_certificate(struct tls13_ctx *ctx, CERT_PKEY *cpk,
tls13_client_check_certificate(struct tls13_ctx *ctx, SSL_CERT_PKEY *cpk,
int *ok, const struct ssl_sigalg **out_sigalg)
{
const struct ssl_sigalg *sigalg;
@@ -849,12 +845,12 @@ tls13_client_check_certificate(struct tls13_ctx *ctx, CERT_PKEY *cpk,
}
static int
tls13_client_select_certificate(struct tls13_ctx *ctx, CERT_PKEY **out_cpk,
tls13_client_select_certificate(struct tls13_ctx *ctx, SSL_CERT_PKEY **out_cpk,
const struct ssl_sigalg **out_sigalg)
{
SSL *s = ctx->ssl;
const struct ssl_sigalg *sigalg;
CERT_PKEY *cpk;
SSL_CERT_PKEY *cpk;
int cert_ok;
*out_cpk = NULL;
@@ -895,15 +891,15 @@ tls13_client_certificate_send(struct tls13_ctx *ctx, CBB *cbb)
CBB cert_request_context, cert_list;
const struct ssl_sigalg *sigalg;
STACK_OF(X509) *chain;
CERT_PKEY *cpk;
SSL_CERT_PKEY *cpk;
X509 *cert;
int i, ret = 0;
if (!tls13_client_select_certificate(ctx, &cpk, &sigalg))
goto err;
ctx->hs->cpk = cpk;
ctx->hs->sigalg = sigalg;
ctx->hs->tls13.cpk = cpk;
ctx->hs->our_sigalg = sigalg;
if (!CBB_add_u8_length_prefixed(cbb, &cert_request_context))
goto err;
@@ -946,15 +942,15 @@ tls13_client_certificate_verify_send(struct tls13_ctx *ctx, CBB *cbb)
EVP_MD_CTX *mdctx = NULL;
EVP_PKEY_CTX *pctx;
EVP_PKEY *pkey;
const CERT_PKEY *cpk;
const SSL_CERT_PKEY *cpk;
CBB sig_cbb;
int ret = 0;
memset(&sig_cbb, 0, sizeof(sig_cbb));
if ((cpk = ctx->hs->cpk) == NULL)
if ((cpk = ctx->hs->tls13.cpk) == NULL)
goto err;
if ((sigalg = ctx->hs->sigalg) == NULL)
if ((sigalg = ctx->hs->our_sigalg) == NULL)
goto err;
pkey = cpk->privatekey;
@@ -968,8 +964,8 @@ tls13_client_certificate_verify_send(struct tls13_ctx *ctx, CBB *cbb)
goto err;
if (!CBB_add_u8(&sig_cbb, 0))
goto err;
if (!CBB_add_bytes(&sig_cbb, ctx->hs->transcript_hash,
ctx->hs->transcript_hash_len))
if (!CBB_add_bytes(&sig_cbb, ctx->hs->tls13.transcript_hash,
ctx->hs->tls13.transcript_hash_len))
goto err;
if (!CBB_finish(&sig_cbb, &sig_content, &sig_content_len))
goto err;
@@ -1026,20 +1022,20 @@ tls13_client_end_of_early_data_send(struct tls13_ctx *ctx, CBB *cbb)
int
tls13_client_finished_send(struct tls13_ctx *ctx, CBB *cbb)
{
struct tls13_secrets *secrets = ctx->hs->secrets;
struct tls13_secrets *secrets = ctx->hs->tls13.secrets;
struct tls13_secret context = { .data = "", .len = 0 };
struct tls13_secret finished_key;
struct tls13_secret finished_key = { .data = NULL, .len = 0 };
uint8_t transcript_hash[EVP_MAX_MD_SIZE];
size_t transcript_hash_len;
uint8_t key[EVP_MAX_MD_SIZE];
uint8_t *verify_data;
size_t hmac_len;
size_t verify_data_len;
unsigned int hlen;
HMAC_CTX *hmac_ctx = NULL;
CBS cbs;
int ret = 0;
finished_key.data = key;
finished_key.len = EVP_MD_size(ctx->hash);
if (!tls13_secret_init(&finished_key, EVP_MD_size(ctx->hash)))
goto err;
if (!tls13_hkdf_expand_label(&finished_key, ctx->hash,
&secrets->client_handshake_traffic, "finished",
@@ -1058,17 +1054,23 @@ tls13_client_finished_send(struct tls13_ctx *ctx, CBB *cbb)
if (!HMAC_Update(hmac_ctx, transcript_hash, transcript_hash_len))
goto err;
hmac_len = HMAC_size(hmac_ctx);
if (!CBB_add_space(cbb, &verify_data, hmac_len))
verify_data_len = HMAC_size(hmac_ctx);
if (!CBB_add_space(cbb, &verify_data, verify_data_len))
goto err;
if (!HMAC_Final(hmac_ctx, verify_data, &hlen))
goto err;
if (hlen != hmac_len)
if (hlen != verify_data_len)
goto err;
CBS_init(&cbs, verify_data, verify_data_len);
if (!CBS_write_bytes(&cbs, ctx->hs->finished,
sizeof(ctx->hs->finished), &ctx->hs->finished_len))
goto err;
ret = 1;
err:
tls13_secret_cleanup(&finished_key);
HMAC_CTX_free(hmac_ctx);
return ret;
@@ -1077,7 +1079,7 @@ tls13_client_finished_send(struct tls13_ctx *ctx, CBB *cbb)
int
tls13_client_finished_sent(struct tls13_ctx *ctx)
{
struct tls13_secrets *secrets = ctx->hs->secrets;
struct tls13_secrets *secrets = ctx->hs->tls13.secrets;
/*
* Any records following the client finished message must be encrypted

View File

@@ -1,6 +1,6 @@
/* $OpenBSD: tls13_handshake.c,v 1.64 2020/07/30 16:23:17 tb Exp $ */
/* $OpenBSD: tls13_handshake.c,v 1.70 2021/09/16 19:25:30 jsing Exp $ */
/*
* Copyright (c) 2018-2019 Theo Buehler <tb@openbsd.org>
* Copyright (c) 2018-2021 Theo Buehler <tb@openbsd.org>
* Copyright (c) 2019 Joel Sing <jsing@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
@@ -48,6 +48,9 @@ static int tls13_handshake_send_action(struct tls13_ctx *ctx,
static int tls13_handshake_recv_action(struct tls13_ctx *ctx,
const struct tls13_handshake_action *action);
static int tls13_handshake_set_legacy_state(struct tls13_ctx *ctx);
static int tls13_handshake_legacy_info_callback(struct tls13_ctx *ctx);
static const struct tls13_handshake_action state_machine[] = {
[CLIENT_HELLO] = {
.handshake_type = TLS13_MT_CLIENT_HELLO,
@@ -328,6 +331,18 @@ tls13_handshake_advance_state_machine(struct tls13_ctx *ctx)
return 1;
}
static int
tls13_handshake_end_of_flight(struct tls13_ctx *ctx,
const struct tls13_handshake_action *previous)
{
const struct tls13_handshake_action *current;
if ((current = tls13_handshake_active_action(ctx)) == NULL)
return 1;
return current->sender != previous->sender;
}
int
tls13_handshake_msg_record(struct tls13_ctx *ctx)
{
@@ -341,40 +356,64 @@ int
tls13_handshake_perform(struct tls13_ctx *ctx)
{
const struct tls13_handshake_action *action;
int sending;
int ret;
if (!ctx->handshake_started) {
/*
* Set legacy state to connect/accept and call info callback
* to signal that the handshake started.
*/
if (!tls13_handshake_set_legacy_state(ctx))
return TLS13_IO_FAILURE;
if (!tls13_handshake_legacy_info_callback(ctx))
return TLS13_IO_FAILURE;
ctx->handshake_started = 1;
if (ctx->info_cb != NULL)
ctx->info_cb(ctx, TLS13_INFO_HANDSHAKE_STARTED, 1);
/* Set legacy state for initial ClientHello read or write. */
if (!tls13_handshake_set_legacy_state(ctx))
return TLS13_IO_FAILURE;
}
for (;;) {
if ((action = tls13_handshake_active_action(ctx)) == NULL)
return TLS13_IO_FAILURE;
if (ctx->need_flush) {
if ((ret = tls13_record_layer_flush(ctx->rl)) !=
TLS13_IO_SUCCESS)
return ret;
ctx->need_flush = 0;
}
if (action->handshake_complete) {
ctx->handshake_completed = 1;
tls13_record_layer_handshake_completed(ctx->rl);
if (ctx->info_cb != NULL)
ctx->info_cb(ctx,
TLS13_INFO_HANDSHAKE_COMPLETED, 1);
if (!tls13_handshake_set_legacy_state(ctx))
return TLS13_IO_FAILURE;
if (!tls13_handshake_legacy_info_callback(ctx))
return TLS13_IO_FAILURE;
return TLS13_IO_SUCCESS;
}
sending = action->sender == ctx->mode;
DEBUGF("%s %s %s\n", tls13_handshake_mode_name(ctx->mode),
(action->sender == ctx->mode) ? "sending" : "receiving",
sending ? "sending" : "receiving",
tls13_handshake_message_name(action->handshake_type));
if (ctx->alert)
if (ctx->alert != 0)
return tls13_send_alert(ctx->rl, ctx->alert);
if (action->sender == ctx->mode)
if (sending)
ret = tls13_handshake_send_action(ctx, action);
else
ret = tls13_handshake_recv_action(ctx, action);
if (ctx->alert)
if (ctx->alert != 0)
return tls13_send_alert(ctx->rl, ctx->alert);
if (ret <= 0) {
@@ -385,8 +424,18 @@ tls13_handshake_perform(struct tls13_ctx *ctx)
return ret;
}
if (!tls13_handshake_legacy_info_callback(ctx))
return TLS13_IO_FAILURE;
if (!tls13_handshake_advance_state_machine(ctx))
return TLS13_IO_FAILURE;
if (sending)
ctx->need_flush = tls13_handshake_end_of_flight(ctx,
action);
if (!tls13_handshake_set_legacy_state(ctx))
return TLS13_IO_FAILURE;
}
}
@@ -428,8 +477,9 @@ tls13_handshake_send_action(struct tls13_ctx *ctx,
if (action->send_preserve_transcript_hash) {
if (!tls1_transcript_hash_value(ctx->ssl,
ctx->hs->transcript_hash, sizeof(ctx->hs->transcript_hash),
&ctx->hs->transcript_hash_len))
ctx->hs->tls13.transcript_hash,
sizeof(ctx->hs->tls13.transcript_hash),
&ctx->hs->tls13.transcript_hash_len))
return TLS13_IO_FAILURE;
}
@@ -471,8 +521,9 @@ tls13_handshake_recv_action(struct tls13_ctx *ctx,
if (action->recv_preserve_transcript_hash) {
if (!tls1_transcript_hash_value(ctx->ssl,
ctx->hs->transcript_hash, sizeof(ctx->hs->transcript_hash),
&ctx->hs->transcript_hash_len))
ctx->hs->tls13.transcript_hash,
sizeof(ctx->hs->tls13.transcript_hash),
&ctx->hs->tls13.transcript_hash_len))
return TLS13_IO_FAILURE;
}
@@ -510,8 +561,163 @@ tls13_handshake_recv_action(struct tls13_ctx *ctx,
tls13_handshake_msg_free(ctx->hs_msg);
ctx->hs_msg = NULL;
if (ctx->ssl->method->internal->version < TLS1_3_VERSION)
if (ctx->ssl->method->version < TLS1_3_VERSION)
return TLS13_IO_USE_LEGACY;
return ret;
}
struct tls13_handshake_legacy_state {
int recv;
int send;
};
static const struct tls13_handshake_legacy_state legacy_states[] = {
[CLIENT_HELLO] = {
.recv = SSL3_ST_SR_CLNT_HELLO_A,
.send = SSL3_ST_CW_CLNT_HELLO_A,
},
[SERVER_HELLO_RETRY_REQUEST] = {
.recv = SSL3_ST_CR_SRVR_HELLO_A,
.send = SSL3_ST_SW_SRVR_HELLO_A,
},
[CLIENT_HELLO_RETRY] = {
.recv = SSL3_ST_SR_CLNT_HELLO_A,
.send = SSL3_ST_CW_CLNT_HELLO_A,
},
[SERVER_HELLO] = {
.recv = SSL3_ST_CR_SRVR_HELLO_A,
.send = SSL3_ST_SW_SRVR_HELLO_A,
},
[SERVER_ENCRYPTED_EXTENSIONS] = {
.send = 0,
.recv = 0,
},
[SERVER_CERTIFICATE_REQUEST] = {
.recv = SSL3_ST_CR_CERT_REQ_A,
.send = SSL3_ST_SW_CERT_REQ_A,
},
[SERVER_CERTIFICATE] = {
.recv = SSL3_ST_CR_CERT_A,
.send = SSL3_ST_SW_CERT_A,
},
[SERVER_CERTIFICATE_VERIFY] = {
.send = 0,
.recv = 0,
},
[SERVER_FINISHED] = {
.recv = SSL3_ST_CR_FINISHED_A,
.send = SSL3_ST_SW_FINISHED_A,
},
[CLIENT_END_OF_EARLY_DATA] = {
.send = 0,
.recv = 0,
},
[CLIENT_CERTIFICATE] = {
.recv = SSL3_ST_SR_CERT_VRFY_A,
.send = SSL3_ST_CW_CERT_VRFY_B,
},
[CLIENT_CERTIFICATE_VERIFY] = {
.send = 0,
.recv = 0,
},
[CLIENT_FINISHED] = {
.recv = SSL3_ST_SR_FINISHED_A,
.send = SSL3_ST_CW_FINISHED_A,
},
[APPLICATION_DATA] = {
.recv = 0,
.send = 0,
},
};
CTASSERT(sizeof(state_machine) / sizeof(state_machine[0]) ==
sizeof(legacy_states) / sizeof(legacy_states[0]));
static int
tls13_handshake_legacy_state(struct tls13_ctx *ctx, int *out_state)
{
const struct tls13_handshake_action *action;
enum tls13_message_type mt;
*out_state = 0;
if (!ctx->handshake_started) {
if (ctx->mode == TLS13_HS_CLIENT)
*out_state = SSL_ST_CONNECT;
else
*out_state = SSL_ST_ACCEPT;
return 1;
}
if (ctx->handshake_completed) {
*out_state = SSL_ST_OK;
return 1;
}
if ((mt = tls13_handshake_active_state(ctx)) == INVALID)
return 0;
if ((action = tls13_handshake_active_action(ctx)) == NULL)
return 0;
if (action->sender == ctx->mode)
*out_state = legacy_states[mt].send;
else
*out_state = legacy_states[mt].recv;
return 1;
}
static int
tls13_handshake_info_position(struct tls13_ctx *ctx)
{
if (!ctx->handshake_started)
return TLS13_INFO_HANDSHAKE_STARTED;
if (ctx->handshake_completed)
return TLS13_INFO_HANDSHAKE_COMPLETED;
if (ctx->mode == TLS13_HS_CLIENT)
return TLS13_INFO_CONNECT_LOOP;
else
return TLS13_INFO_ACCEPT_LOOP;
}
static int
tls13_handshake_legacy_info_callback(struct tls13_ctx *ctx)
{
int state, where;
if (!tls13_handshake_legacy_state(ctx, &state))
return 0;
/* Do nothing if there's no corresponding legacy state. */
if (state == 0)
return 1;
if (ctx->info_cb != NULL) {
where = tls13_handshake_info_position(ctx);
ctx->info_cb(ctx, where, 1);
}
return 1;
}
static int
tls13_handshake_set_legacy_state(struct tls13_ctx *ctx)
{
int state;
if (!tls13_handshake_legacy_state(ctx, &state))
return 0;
/* Do nothing if there's no corresponding legacy state. */
if (state == 0)
return 1;
ctx->hs->state = state;
return 1;
}

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: tls13_handshake_msg.c,v 1.2 2019/11/20 16:21:20 beck Exp $ */
/* $OpenBSD: tls13_handshake_msg.c,v 1.4 2021/10/23 13:12:14 jsing Exp $ */
/*
* Copyright (c) 2018, 2019 Joel Sing <jsing@openbsd.org>
*
@@ -16,7 +16,6 @@
*/
#include "bytestring.h"
#include "ssl_locl.h"
#include "tls13_internal.h"
#define TLS13_HANDSHAKE_MSG_HEADER_LEN 4
@@ -29,7 +28,7 @@ struct tls13_handshake_msg {
uint8_t *data;
size_t data_len;
struct tls13_buffer *buf;
struct tls_buffer *buf;
CBS cbs;
CBB cbb;
};
@@ -41,7 +40,7 @@ tls13_handshake_msg_new()
if ((msg = calloc(1, sizeof(struct tls13_handshake_msg))) == NULL)
goto err;
if ((msg->buf = tls13_buffer_new(0)) == NULL)
if ((msg->buf = tls_buffer_new(0)) == NULL)
goto err;
return msg;
@@ -58,7 +57,7 @@ tls13_handshake_msg_free(struct tls13_handshake_msg *msg)
if (msg == NULL)
return;
tls13_buffer_free(msg->buf);
tls_buffer_free(msg->buf);
CBB_cleanup(&msg->cbb);
@@ -75,7 +74,7 @@ tls13_handshake_msg_data(struct tls13_handshake_msg *msg, CBS *cbs)
int
tls13_handshake_msg_set_buffer(struct tls13_handshake_msg *msg, CBS *cbs)
{
return tls13_buffer_set_data(msg->buf, cbs);
return tls_buffer_set_data(msg->buf, cbs);
}
uint8_t
@@ -138,12 +137,12 @@ tls13_handshake_msg_recv(struct tls13_handshake_msg *msg,
return TLS13_IO_FAILURE;
if (msg->msg_type == 0) {
if ((ret = tls13_buffer_extend(msg->buf,
if ((ret = tls_buffer_extend(msg->buf,
TLS13_HANDSHAKE_MSG_HEADER_LEN,
tls13_handshake_msg_read_cb, rl)) <= 0)
return ret;
tls13_buffer_cbs(msg->buf, &cbs);
tls_buffer_cbs(msg->buf, &cbs);
if (!CBS_get_u8(&cbs, &msg_type))
return TLS13_IO_FAILURE;
@@ -158,12 +157,12 @@ tls13_handshake_msg_recv(struct tls13_handshake_msg *msg,
msg->msg_len = msg_len;
}
if ((ret = tls13_buffer_extend(msg->buf,
if ((ret = tls_buffer_extend(msg->buf,
TLS13_HANDSHAKE_MSG_HEADER_LEN + msg->msg_len,
tls13_handshake_msg_read_cb, rl)) <= 0)
return ret;
if (!tls13_buffer_finish(msg->buf, &msg->data, &msg->data_len))
if (!tls_buffer_finish(msg->buf, &msg->data, &msg->data_len))
return TLS13_IO_FAILURE;
return TLS13_IO_SUCCESS;

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: tls13_internal.h,v 1.86 2020/07/30 16:23:17 tb Exp $ */
/* $OpenBSD: tls13_internal.h,v 1.96 2022/01/05 17:10:02 jsing Exp $ */
/*
* Copyright (c) 2018 Bob Beck <beck@openbsd.org>
* Copyright (c) 2018 Theo Buehler <tb@openbsd.org>
@@ -24,6 +24,7 @@
#include <openssl/ssl.h>
#include "bytestring.h"
#include "tls_internal.h"
__BEGIN_HIDDEN_DECLS
@@ -81,31 +82,18 @@ __BEGIN_HIDDEN_DECLS
#define TLS13_INFO_HANDSHAKE_STARTED SSL_CB_HANDSHAKE_START
#define TLS13_INFO_HANDSHAKE_COMPLETED SSL_CB_HANDSHAKE_DONE
#define TLS13_INFO_ACCEPT_LOOP SSL_CB_ACCEPT_LOOP
#define TLS13_INFO_CONNECT_LOOP SSL_CB_CONNECT_LOOP
#define TLS13_INFO_ACCEPT_EXIT SSL_CB_ACCEPT_EXIT
#define TLS13_INFO_CONNECT_EXIT SSL_CB_CONNECT_EXIT
typedef void (*tls13_alert_cb)(uint8_t _alert_desc, void *_cb_arg);
typedef ssize_t (*tls13_phh_recv_cb)(void *_cb_arg, CBS *_cbs);
typedef void (*tls13_phh_sent_cb)(void *_cb_arg);
typedef ssize_t (*tls13_read_cb)(void *_buf, size_t _buflen, void *_cb_arg);
typedef ssize_t (*tls13_write_cb)(const void *_buf, size_t _buflen,
void *_cb_arg);
typedef void (*tls13_handshake_message_cb)(void *_cb_arg);
typedef void (*tls13_info_cb)(void *_cb_arg, int _state, int _ret);
typedef int (*tls13_ocsp_status_cb)(void *_cb_arg);
/*
* Buffers.
*/
struct tls13_buffer;
struct tls13_buffer *tls13_buffer_new(size_t init_size);
int tls13_buffer_set_data(struct tls13_buffer *buf, CBS *data);
void tls13_buffer_free(struct tls13_buffer *buf);
ssize_t tls13_buffer_extend(struct tls13_buffer *buf, size_t len,
tls13_read_cb read_cb, void *cb_arg);
void tls13_buffer_cbs(struct tls13_buffer *buf, CBS *cbs);
int tls13_buffer_finish(struct tls13_buffer *buf, uint8_t **out,
size_t *out_len);
/*
* Secrets.
*/
@@ -141,6 +129,8 @@ struct tls13_secrets {
struct tls13_secret resumption_master;
};
int tls13_secret_init(struct tls13_secret *secret, size_t len);
void tls13_secret_cleanup(struct tls13_secret *secret);
struct tls13_secrets *tls13_secrets_create(const EVP_MD *digest,
int resumption);
void tls13_secrets_destroy(struct tls13_secrets *secrets);
@@ -148,6 +138,16 @@ void tls13_secrets_destroy(struct tls13_secrets *secrets);
int tls13_hkdf_expand_label(struct tls13_secret *out, const EVP_MD *digest,
const struct tls13_secret *secret, const char *label,
const struct tls13_secret *context);
int tls13_hkdf_expand_label_with_length(struct tls13_secret *out,
const EVP_MD *digest, const struct tls13_secret *secret,
const uint8_t *label, size_t label_len, const struct tls13_secret *context);
int tls13_derive_secret(struct tls13_secret *out, const EVP_MD *digest,
const struct tls13_secret *secret, const char *label,
const struct tls13_secret *context);
int tls13_derive_secret_with_label_length(struct tls13_secret *out,
const EVP_MD *digest, const struct tls13_secret *secret,
const uint8_t *label, size_t label_len, const struct tls13_secret *context);
int tls13_derive_early_secrets(struct tls13_secrets *secrets, uint8_t *psk,
size_t psk_len, const struct tls13_secret *context);
@@ -158,32 +158,15 @@ int tls13_derive_application_secrets(struct tls13_secrets *secrets,
int tls13_update_client_traffic_secret(struct tls13_secrets *secrets);
int tls13_update_server_traffic_secret(struct tls13_secrets *secrets);
/*
* Key shares.
*/
struct tls13_key_share;
struct tls13_key_share *tls13_key_share_new(uint16_t group_id);
struct tls13_key_share *tls13_key_share_new_nid(int nid);
void tls13_key_share_free(struct tls13_key_share *ks);
uint16_t tls13_key_share_group(struct tls13_key_share *ks);
int tls13_key_share_peer_pkey(struct tls13_key_share *ks, EVP_PKEY *pkey);
int tls13_key_share_generate(struct tls13_key_share *ks);
int tls13_key_share_public(struct tls13_key_share *ks, CBB *cbb);
int tls13_key_share_peer_public(struct tls13_key_share *ks, uint16_t group,
CBS *cbs);
int tls13_key_share_derive(struct tls13_key_share *ks, uint8_t **shared_key,
size_t *shared_key_len);
/*
* Record Layer.
*/
struct tls13_record_layer;
struct tls13_record_layer_callbacks {
tls13_read_cb wire_read;
tls13_write_cb wire_write;
tls_read_cb wire_read;
tls_write_cb wire_write;
tls_flush_cb wire_flush;
tls13_alert_cb alert_recv;
tls13_alert_cb alert_sent;
tls13_phh_recv_cb phh_recv;
@@ -195,7 +178,7 @@ struct tls13_record_layer *tls13_record_layer_new(
void tls13_record_layer_free(struct tls13_record_layer *rl);
void tls13_record_layer_allow_ccs(struct tls13_record_layer *rl, int allow);
void tls13_record_layer_allow_legacy_alerts(struct tls13_record_layer *rl, int allow);
void tls13_record_layer_rbuf(struct tls13_record_layer *rl, CBS *cbs);
void tls13_record_layer_rcontent(struct tls13_record_layer *rl, CBS *cbs);
void tls13_record_layer_set_aead(struct tls13_record_layer *rl,
const EVP_AEAD *aead);
void tls13_record_layer_set_hash(struct tls13_record_layer *rl,
@@ -210,6 +193,7 @@ int tls13_record_layer_set_write_traffic_key(struct tls13_record_layer *rl,
struct tls13_secret *write_key);
ssize_t tls13_record_layer_send_pending(struct tls13_record_layer *rl);
ssize_t tls13_record_layer_phh(struct tls13_record_layer *rl, CBS *cbs);
ssize_t tls13_record_layer_flush(struct tls13_record_layer *rl);
ssize_t tls13_read_handshake_data(struct tls13_record_layer *rl, uint8_t *buf, size_t n);
ssize_t tls13_write_handshake_data(struct tls13_record_layer *rl, const uint8_t *buf,
@@ -262,11 +246,12 @@ struct tls13_ctx {
struct tls13_error error;
SSL *ssl;
struct ssl_handshake_tls13_st *hs;
struct ssl_handshake_st *hs;
uint8_t mode;
struct tls13_handshake_stage handshake_stage;
int handshake_started;
int handshake_completed;
int need_flush;
int middlebox_compat;
int send_dummy_ccs;
int send_dummy_ccs_after;
@@ -312,6 +297,7 @@ int tls13_legacy_connect(SSL *ssl);
int tls13_legacy_return_code(SSL *ssl, ssize_t ret);
ssize_t tls13_legacy_wire_read_cb(void *buf, size_t n, void *arg);
ssize_t tls13_legacy_wire_write_cb(const void *buf, size_t n, void *arg);
ssize_t tls13_legacy_wire_flush_cb(void *arg);
int tls13_legacy_pending(const SSL *ssl);
int tls13_legacy_read_bytes(SSL *ssl, int type, unsigned char *buf, int len,
int peek);
@@ -412,6 +398,10 @@ int tls13_error_setx(struct tls13_error *error, int code, int subcode,
tls13_error_setx(&(ctx)->error, (code), (subcode), __FILE__, __LINE__, \
(fmt), __VA_ARGS__)
int tls13_exporter(struct tls13_ctx *ctx, const uint8_t *label, size_t label_len,
const uint8_t *context_value, size_t context_value_len, uint8_t *out,
size_t out_len);
extern const uint8_t tls13_downgrade_12[8];
extern const uint8_t tls13_downgrade_11[8];
extern const uint8_t tls13_hello_retry_request_hash[32];

View File

@@ -1,5 +1,6 @@
/* $OpenBSD: tls13_key_schedule.c,v 1.8 2019/11/17 21:01:08 beck Exp $ */
/* Copyright (c) 2018, Bob Beck <beck@openbsd.org>
/* $OpenBSD: tls13_key_schedule.c,v 1.14 2021/01/05 18:36:22 tb Exp $ */
/*
* Copyright (c) 2018, Bob Beck <beck@openbsd.org>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -22,46 +23,25 @@
#include "bytestring.h"
#include "tls13_internal.h"
void
tls13_secrets_destroy(struct tls13_secrets *secrets)
int
tls13_secret_init(struct tls13_secret *secret, size_t len)
{
if (secrets == NULL)
return;
if (secret->data != NULL)
return 0;
/* you can never be too sure :) */
freezero(secrets->zeros.data, secrets->zeros.len);
freezero(secrets->empty_hash.data, secrets->empty_hash.len);
if ((secret->data = calloc(1, len)) == NULL)
return 0;
secret->len = len;
freezero(secrets->extracted_early.data,
secrets->extracted_early.len);
freezero(secrets->binder_key.data,
secrets->binder_key.len);
freezero(secrets->client_early_traffic.data,
secrets->client_early_traffic.len);
freezero(secrets->early_exporter_master.data,
secrets->early_exporter_master.len);
freezero(secrets->derived_early.data,
secrets->derived_early.len);
freezero(secrets->extracted_handshake.data,
secrets->extracted_handshake.len);
freezero(secrets->client_handshake_traffic.data,
secrets->client_handshake_traffic.len);
freezero(secrets->server_handshake_traffic.data,
secrets->server_handshake_traffic.len);
freezero(secrets->derived_handshake.data,
secrets->derived_handshake.len);
freezero(secrets->extracted_master.data,
secrets->extracted_master.len);
freezero(secrets->client_application_traffic.data,
secrets->client_application_traffic.len);
freezero(secrets->server_application_traffic.data,
secrets->server_application_traffic.len);
freezero(secrets->exporter_master.data,
secrets->exporter_master.len);
freezero(secrets->resumption_master.data,
secrets->resumption_master.len);
return 1;
}
freezero(secrets, sizeof(struct tls13_secrets));
void
tls13_secret_cleanup(struct tls13_secret *secret)
{
freezero(secret->data, secret->len);
secret->data = NULL;
secret->len = 0;
}
/*
@@ -81,62 +61,39 @@ tls13_secrets_create(const EVP_MD *digest, int resumption)
if ((secrets = calloc(1, sizeof(struct tls13_secrets))) == NULL)
goto err;
if ((secrets->zeros.data = calloc(hash_length, sizeof(uint8_t))) ==
NULL)
if (!tls13_secret_init(&secrets->zeros, hash_length))
goto err;
if (!tls13_secret_init(&secrets->empty_hash, hash_length))
goto err;
secrets->zeros.len = hash_length;
if ((secrets->empty_hash.data = malloc(hash_length)) == NULL)
if (!tls13_secret_init(&secrets->extracted_early, hash_length))
goto err;
secrets->empty_hash.len = hash_length;
if ((secrets->extracted_early.data = malloc(hash_length)) == NULL)
if (!tls13_secret_init(&secrets->binder_key, hash_length))
goto err;
secrets->extracted_early.len = hash_length;
if ((secrets->binder_key.data = malloc(hash_length)) == NULL)
if (!tls13_secret_init(&secrets->client_early_traffic, hash_length))
goto err;
secrets->binder_key.len = hash_length;
if ((secrets->client_early_traffic.data = malloc(hash_length)) == NULL)
if (!tls13_secret_init(&secrets->early_exporter_master, hash_length))
goto err;
secrets->client_early_traffic.len = hash_length;
if ((secrets->early_exporter_master.data = malloc(hash_length)) ==
NULL)
if (!tls13_secret_init(&secrets->derived_early, hash_length))
goto err;
secrets->early_exporter_master.len = hash_length;
if ((secrets->derived_early.data = malloc(hash_length)) == NULL)
if (!tls13_secret_init(&secrets->extracted_handshake, hash_length))
goto err;
secrets->derived_early.len = hash_length;
if ((secrets->extracted_handshake.data = malloc(hash_length)) == NULL)
if (!tls13_secret_init(&secrets->client_handshake_traffic, hash_length))
goto err;
secrets->extracted_handshake.len = hash_length;
if ((secrets->client_handshake_traffic.data = malloc(hash_length))
== NULL)
if (!tls13_secret_init(&secrets->server_handshake_traffic, hash_length))
goto err;
secrets->client_handshake_traffic.len = hash_length;
if ((secrets->server_handshake_traffic.data = malloc(hash_length))
== NULL)
if (!tls13_secret_init(&secrets->derived_handshake, hash_length))
goto err;
secrets->server_handshake_traffic.len = hash_length;
if ((secrets->derived_handshake.data = malloc(hash_length)) == NULL)
if (!tls13_secret_init(&secrets->extracted_master, hash_length))
goto err;
secrets->derived_handshake.len = hash_length;
if ((secrets->extracted_master.data = malloc(hash_length)) == NULL)
if (!tls13_secret_init(&secrets->client_application_traffic, hash_length))
goto err;
secrets->extracted_master.len = hash_length;
if ((secrets->client_application_traffic.data = malloc(hash_length)) ==
NULL)
if (!tls13_secret_init(&secrets->server_application_traffic, hash_length))
goto err;
secrets->client_application_traffic.len = hash_length;
if ((secrets->server_application_traffic.data = malloc(hash_length)) ==
NULL)
if (!tls13_secret_init(&secrets->exporter_master, hash_length))
goto err;
secrets->server_application_traffic.len = hash_length;
if ((secrets->exporter_master.data = malloc(hash_length)) == NULL)
if (!tls13_secret_init(&secrets->resumption_master, hash_length))
goto err;
secrets->exporter_master.len = hash_length;
if ((secrets->resumption_master.data = malloc(hash_length)) == NULL)
goto err;
secrets->resumption_master.len = hash_length;
/*
* Calculate the hash of a zero-length string - this is needed during
@@ -169,10 +126,47 @@ tls13_secrets_create(const EVP_MD *digest, int resumption)
return NULL;
}
void
tls13_secrets_destroy(struct tls13_secrets *secrets)
{
if (secrets == NULL)
return;
/* you can never be too sure :) */
tls13_secret_cleanup(&secrets->zeros);
tls13_secret_cleanup(&secrets->empty_hash);
tls13_secret_cleanup(&secrets->extracted_early);
tls13_secret_cleanup(&secrets->binder_key);
tls13_secret_cleanup(&secrets->client_early_traffic);
tls13_secret_cleanup(&secrets->early_exporter_master);
tls13_secret_cleanup(&secrets->derived_early);
tls13_secret_cleanup(&secrets->extracted_handshake);
tls13_secret_cleanup(&secrets->client_handshake_traffic);
tls13_secret_cleanup(&secrets->server_handshake_traffic);
tls13_secret_cleanup(&secrets->derived_handshake);
tls13_secret_cleanup(&secrets->extracted_master);
tls13_secret_cleanup(&secrets->client_application_traffic);
tls13_secret_cleanup(&secrets->server_application_traffic);
tls13_secret_cleanup(&secrets->exporter_master);
tls13_secret_cleanup(&secrets->resumption_master);
freezero(secrets, sizeof(struct tls13_secrets));
}
int
tls13_hkdf_expand_label(struct tls13_secret *out, const EVP_MD *digest,
const struct tls13_secret *secret, const char *label,
const struct tls13_secret *context)
{
return tls13_hkdf_expand_label_with_length(out, digest, secret, label,
strlen(label), context);
}
int
tls13_hkdf_expand_label_with_length(struct tls13_secret *out,
const EVP_MD *digest, const struct tls13_secret *secret,
const uint8_t *label, size_t label_len, const struct tls13_secret *context)
{
const char tls13_plabel[] = "tls13 ";
uint8_t *hkdf_label;
@@ -188,7 +182,7 @@ tls13_hkdf_expand_label(struct tls13_secret *out, const EVP_MD *digest,
goto err;
if (!CBB_add_bytes(&child, tls13_plabel, strlen(tls13_plabel)))
goto err;
if (!CBB_add_bytes(&child, label, strlen(label)))
if (!CBB_add_bytes(&child, label, label_len))
goto err;
if (!CBB_add_u8_length_prefixed(&cbb, &child))
goto err;
@@ -207,7 +201,7 @@ tls13_hkdf_expand_label(struct tls13_secret *out, const EVP_MD *digest,
return(0);
}
static int
int
tls13_derive_secret(struct tls13_secret *out, const EVP_MD *digest,
const struct tls13_secret *secret, const char *label,
const struct tls13_secret *context)
@@ -215,6 +209,15 @@ tls13_derive_secret(struct tls13_secret *out, const EVP_MD *digest,
return tls13_hkdf_expand_label(out, digest, secret, label, context);
}
int
tls13_derive_secret_with_label_length(struct tls13_secret *out,
const EVP_MD *digest, const struct tls13_secret *secret, const uint8_t *label,
size_t label_len, const struct tls13_secret *context)
{
return tls13_hkdf_expand_label_with_length(out, digest, secret, label,
label_len, context);
}
int
tls13_derive_early_secrets(struct tls13_secrets *secrets,
uint8_t *psk, size_t psk_len, const struct tls13_secret *context)

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: tls13_legacy.c,v 1.13 2020/09/13 15:04:35 jsing Exp $ */
/* $OpenBSD: tls13_legacy.c,v 1.37 2022/02/06 16:08:14 jsing Exp $ */
/*
* Copyright (c) 2018, 2019 Joel Sing <jsing@openbsd.org>
*
@@ -20,10 +20,6 @@
#include "ssl_locl.h"
#include "tls13_internal.h"
SSL3_ENC_METHOD TLSv1_3_enc_data = {
.enc_flags = SSL_ENC_FLAG_SIGALGS|SSL_ENC_FLAG_TLS1_3_CIPHERS,
};
static ssize_t
tls13_legacy_wire_read(SSL *ssl, uint8_t *buf, size_t len)
{
@@ -40,8 +36,6 @@ tls13_legacy_wire_read(SSL *ssl, uint8_t *buf, size_t len)
if ((n = BIO_read(ssl->rbio, buf, len)) <= 0) {
if (BIO_should_read(ssl->rbio))
return TLS13_IO_WANT_POLLIN;
if (BIO_should_write(ssl->rbio))
return TLS13_IO_WANT_POLLOUT;
if (n == 0)
return TLS13_IO_EOF;
@@ -79,8 +73,6 @@ tls13_legacy_wire_write(SSL *ssl, const uint8_t *buf, size_t len)
errno = 0;
if ((n = BIO_write(ssl->wbio, buf, len)) <= 0) {
if (BIO_should_read(ssl->wbio))
return TLS13_IO_WANT_POLLIN;
if (BIO_should_write(ssl->wbio))
return TLS13_IO_WANT_POLLOUT;
@@ -104,6 +96,30 @@ tls13_legacy_wire_write_cb(const void *buf, size_t n, void *arg)
return tls13_legacy_wire_write(ctx->ssl, buf, n);
}
static ssize_t
tls13_legacy_wire_flush(SSL *ssl)
{
if (BIO_flush(ssl->wbio) <= 0) {
if (BIO_should_write(ssl->wbio))
return TLS13_IO_WANT_POLLOUT;
if (ERR_peek_error() == 0 && errno != 0)
SYSerror(errno);
return TLS13_IO_FAILURE;
}
return TLS13_IO_SUCCESS;
}
ssize_t
tls13_legacy_wire_flush_cb(void *arg)
{
struct tls13_ctx *ctx = arg;
return tls13_legacy_wire_flush(ctx->ssl);
}
static void
tls13_legacy_error(SSL *ssl)
{
@@ -111,7 +127,7 @@ tls13_legacy_error(SSL *ssl)
int reason = SSL_R_UNKNOWN;
/* If we received a fatal alert we already put an error on the stack. */
if (S3I(ssl)->fatal_alert != 0)
if (ssl->s3->fatal_alert != 0)
return;
switch (ctx->error.code) {
@@ -213,6 +229,8 @@ tls13_legacy_read_bytes(SSL *ssl, int type, unsigned char *buf, int len, int pee
if (ctx == NULL || !ctx->handshake_completed) {
if ((ret = ssl->internal->handshake_func(ssl)) <= 0)
return ret;
if (len == 0)
return 0;
return tls13_legacy_return_code(ssl, TLS13_IO_WANT_POLLIN);
}
@@ -224,7 +242,7 @@ tls13_legacy_read_bytes(SSL *ssl, int type, unsigned char *buf, int len, int pee
return -1;
}
if (len < 0) {
SSLerror(ssl, SSL_R_BAD_LENGTH);
SSLerror(ssl, SSL_R_BAD_LENGTH);
return -1;
}
@@ -247,6 +265,8 @@ tls13_legacy_write_bytes(SSL *ssl, int type, const void *vbuf, int len)
if (ctx == NULL || !ctx->handshake_completed) {
if ((ret = ssl->internal->handshake_func(ssl)) <= 0)
return ret;
if (len == 0)
return 0;
return tls13_legacy_return_code(ssl, TLS13_IO_WANT_POLLOUT);
}
@@ -255,7 +275,7 @@ tls13_legacy_write_bytes(SSL *ssl, int type, const void *vbuf, int len)
return -1;
}
if (len < 0) {
SSLerror(ssl, SSL_R_BAD_LENGTH);
SSLerror(ssl, SSL_R_BAD_LENGTH);
return -1;
}
@@ -269,23 +289,23 @@ tls13_legacy_write_bytes(SSL *ssl, int type, const void *vbuf, int len)
}
/*
* In the non-SSL_MODE_ENABLE_PARTIAL_WRITE case we have to loop until
* In the non-SSL_MODE_ENABLE_PARTIAL_WRITE case we have to loop until
* we have written out all of the requested data.
*/
sent = S3I(ssl)->wnum;
sent = ssl->s3->wnum;
if (len < sent) {
SSLerror(ssl, SSL_R_BAD_LENGTH);
SSLerror(ssl, SSL_R_BAD_LENGTH);
return -1;
}
n = len - sent;
for (;;) {
if (n == 0) {
S3I(ssl)->wnum = 0;
ssl->s3->wnum = 0;
return sent;
}
if ((ret = tls13_write_application_data(ctx->rl,
&buf[sent], n)) <= 0) {
S3I(ssl)->wnum = sent;
ssl->s3->wnum = sent;
return tls13_legacy_return_code(ssl, ret);
}
sent += ret;
@@ -297,44 +317,65 @@ static int
tls13_use_legacy_stack(struct tls13_ctx *ctx)
{
SSL *s = ctx->ssl;
CBB cbb, fragment;
CBS cbs;
memset(&cbb, 0, sizeof(cbb));
s->method = tls_legacy_method();
if (!ssl3_setup_init_buffer(s))
return 0;
goto err;
if (!ssl3_setup_buffers(s))
return 0;
goto err;
if (!ssl_init_wbio_buffer(s, 1))
return 0;
goto err;
/* Stash any unprocessed data from the last record. */
tls13_record_layer_rbuf(ctx->rl, &cbs);
tls13_record_layer_rcontent(ctx->rl, &cbs);
if (CBS_len(&cbs) > 0) {
if (!CBS_write_bytes(&cbs,
S3I(s)->rbuf.buf + SSL3_RT_HEADER_LENGTH,
S3I(s)->rbuf.len - SSL3_RT_HEADER_LENGTH, NULL))
return 0;
if (!CBB_init_fixed(&cbb, s->s3->rbuf.buf,
s->s3->rbuf.len))
goto err;
if (!CBB_add_u8(&cbb, SSL3_RT_HANDSHAKE))
goto err;
if (!CBB_add_u16(&cbb, TLS1_2_VERSION))
goto err;
if (!CBB_add_u16_length_prefixed(&cbb, &fragment))
goto err;
if (!CBB_add_bytes(&fragment, CBS_data(&cbs), CBS_len(&cbs)))
goto err;
if (!CBB_finish(&cbb, NULL, NULL))
goto err;
S3I(s)->rbuf.offset = SSL3_RT_HEADER_LENGTH;
S3I(s)->rbuf.left = CBS_len(&cbs);
S3I(s)->rrec.type = SSL3_RT_HANDSHAKE;
S3I(s)->rrec.length = CBS_len(&cbs);
s->s3->rbuf.offset = SSL3_RT_HEADER_LENGTH;
s->s3->rbuf.left = CBS_len(&cbs);
s->s3->rrec.type = SSL3_RT_HANDSHAKE;
s->s3->rrec.length = CBS_len(&cbs);
s->internal->rstate = SSL_ST_READ_BODY;
s->internal->packet = S3I(s)->rbuf.buf;
s->internal->packet = s->s3->rbuf.buf;
s->internal->packet_length = SSL3_RT_HEADER_LENGTH;
s->internal->mac_packet = 1;
}
/* Stash the current handshake message. */
tls13_handshake_msg_data(ctx->hs_msg, &cbs);
if (!BUF_MEM_grow_clean(s->internal->init_buf, CBS_len(&cbs)))
goto err;
if (!CBS_write_bytes(&cbs, s->internal->init_buf->data,
s->internal->init_buf->length, NULL))
return 0;
goto err;
S3I(s)->tmp.reuse_message = 1;
S3I(s)->tmp.message_type = tls13_handshake_msg_type(ctx->hs_msg);
S3I(s)->tmp.message_size = CBS_len(&cbs);
s->s3->hs.tls12.reuse_message = 1;
s->s3->hs.tls12.message_type = tls13_handshake_msg_type(ctx->hs_msg);
s->s3->hs.tls12.message_size = CBS_len(&cbs) - SSL3_HM_HEADER_LENGTH;
return 1;
err:
CBB_cleanup(&cbb);
return 0;
}
int
@@ -342,14 +383,11 @@ tls13_use_legacy_client(struct tls13_ctx *ctx)
{
SSL *s = ctx->ssl;
s->method = tls_legacy_client_method();
s->internal->handshake_func = s->method->internal->ssl_connect;
s->client_version = s->version = s->method->internal->max_version;
if (!tls13_use_legacy_stack(ctx))
return 0;
S3I(s)->hs.state = SSL3_ST_CR_SRVR_HELLO_A;
s->internal->handshake_func = s->method->ssl_connect;
s->version = s->method->max_tls_version;
return 1;
}
@@ -359,15 +397,12 @@ tls13_use_legacy_server(struct tls13_ctx *ctx)
{
SSL *s = ctx->ssl;
s->method = tls_legacy_server_method();
s->internal->handshake_func = s->method->internal->ssl_accept;
s->client_version = s->version = s->method->internal->max_version;
s->server = 1;
if (!tls13_use_legacy_stack(ctx))
return 0;
S3I(s)->hs.state = SSL3_ST_SR_CLNT_HELLO_A;
s->internal->handshake_func = s->method->ssl_accept;
s->version = s->method->max_tls_version;
s->server = 1;
return 1;
}
@@ -385,7 +420,7 @@ tls13_legacy_accept(SSL *ssl)
}
ssl->internal->tls13 = ctx;
ctx->ssl = ssl;
ctx->hs = &S3I(ssl)->hs_tls13;
ctx->hs = &ssl->s3->hs;
if (!tls13_server_init(ctx)) {
if (ERR_peek_error() == 0)
@@ -395,15 +430,17 @@ tls13_legacy_accept(SSL *ssl)
}
ERR_clear_error();
S3I(ssl)->hs.state = SSL_ST_ACCEPT;
ret = tls13_server_accept(ctx);
if (ret == TLS13_IO_USE_LEGACY)
return ssl->method->internal->ssl_accept(ssl);
if (ret == TLS13_IO_SUCCESS)
S3I(ssl)->hs.state = SSL_ST_OK;
return ssl->method->ssl_accept(ssl);
return tls13_legacy_return_code(ssl, ret);
ret = tls13_legacy_return_code(ssl, ret);
if (ctx->info_cb != NULL)
ctx->info_cb(ctx, TLS13_INFO_ACCEPT_EXIT, ret);
return ret;
}
int
@@ -412,14 +449,6 @@ tls13_legacy_connect(SSL *ssl)
struct tls13_ctx *ctx = ssl->internal->tls13;
int ret;
#ifdef TLS13_USE_LEGACY_CLIENT_AUTH
/* XXX drop back to legacy for client auth for now */
if (ssl->cert->key->privatekey != NULL) {
ssl->method = tls_legacy_client_method();
return ssl->method->internal->ssl_connect(ssl);
}
#endif
if (ctx == NULL) {
if ((ctx = tls13_ctx_new(TLS13_HS_CLIENT)) == NULL) {
SSLerror(ssl, ERR_R_INTERNAL_ERROR); /* XXX */
@@ -427,7 +456,7 @@ tls13_legacy_connect(SSL *ssl)
}
ssl->internal->tls13 = ctx;
ctx->ssl = ssl;
ctx->hs = &S3I(ssl)->hs_tls13;
ctx->hs = &ssl->s3->hs;
if (!tls13_client_init(ctx)) {
if (ERR_peek_error() == 0)
@@ -437,15 +466,17 @@ tls13_legacy_connect(SSL *ssl)
}
ERR_clear_error();
S3I(ssl)->hs.state = SSL_ST_CONNECT;
ret = tls13_client_connect(ctx);
if (ret == TLS13_IO_USE_LEGACY)
return ssl->method->internal->ssl_connect(ssl);
if (ret == TLS13_IO_SUCCESS)
S3I(ssl)->hs.state = SSL_ST_OK;
return ssl->method->ssl_connect(ssl);
return tls13_legacy_return_code(ssl, ret);
ret = tls13_legacy_return_code(ssl, ret);
if (ctx->info_cb != NULL)
ctx->info_cb(ctx, TLS13_INFO_CONNECT_EXIT, ret);
return ret;
}
int
@@ -456,9 +487,9 @@ tls13_legacy_shutdown(SSL *ssl)
ssize_t ret;
/*
* We need to return 0 when we have sent a close-notify but have not
* yet received one. We return 1 only once we have sent and received
* close-notify alerts. All other cases return -1 and set internal
* We need to return 0 at the point that we have completed sending a
* close-notify. We return 1 when we have sent and received close-notify
* alerts. All other cases, including EOF, return -1 and set internal
* state appropriately.
*/
if (ctx == NULL || ssl->internal->quiet_shutdown) {
@@ -474,13 +505,15 @@ tls13_legacy_shutdown(SSL *ssl)
TLS13_ALERT_CLOSE_NOTIFY)) < 0)
return tls13_legacy_return_code(ssl, ret);
}
if ((ret = tls13_record_layer_send_pending(ctx->rl)) !=
TLS13_IO_SUCCESS)
ret = tls13_record_layer_send_pending(ctx->rl);
if (ret == TLS13_IO_EOF)
return -1;
if (ret != TLS13_IO_SUCCESS)
return tls13_legacy_return_code(ssl, ret);
} else if (!ctx->close_notify_recv) {
/*
* If there is no application data pending, attempt to read more
* data in order to receive a close notify. This should trigger
* data in order to receive a close-notify. This should trigger
* a record to be read from the wire, which may be application
* handshake or alert data. Only one attempt is made to match
* previous semantics.
@@ -489,6 +522,8 @@ tls13_legacy_shutdown(SSL *ssl)
if ((ret = tls13_read_application_data(ctx->rl, buf,
sizeof(buf))) < 0)
return tls13_legacy_return_code(ssl, ret);
if (!ctx->close_notify_recv)
return -1;
}
}
@@ -504,18 +539,22 @@ tls13_legacy_servername_process(struct tls13_ctx *ctx, uint8_t *alert)
int legacy_alert = SSL_AD_UNRECOGNIZED_NAME;
int ret = SSL_TLSEXT_ERR_NOACK;
SSL_CTX *ssl_ctx = ctx->ssl->ctx;
SSL *ssl = ctx->ssl;
SSL *s = ctx->ssl;
if (ssl_ctx->internal->tlsext_servername_callback == NULL)
ssl_ctx = ssl->initial_ctx;
ssl_ctx = s->initial_ctx;
if (ssl_ctx->internal->tlsext_servername_callback == NULL)
return 1;
ret = ssl_ctx->internal->tlsext_servername_callback(ssl, &legacy_alert,
ret = ssl_ctx->internal->tlsext_servername_callback(s, &legacy_alert,
ssl_ctx->internal->tlsext_servername_arg);
if (ret == SSL_TLSEXT_ERR_ALERT_FATAL ||
ret == SSL_TLSEXT_ERR_ALERT_WARNING) {
/*
* Ignore SSL_TLSEXT_ERR_ALERT_WARNING returns to match OpenSSL's
* behavior: the only warning alerts in TLSv1.3 are close_notify and
* user_canceled, neither of which should be returned by the callback.
*/
if (ret == SSL_TLSEXT_ERR_ALERT_FATAL) {
if (legacy_alert >= 0 && legacy_alert <= 255)
*alert = legacy_alert;
return 0;

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: tls13_lib.c,v 1.54 2020/09/11 15:03:36 jsing Exp $ */
/* $OpenBSD: tls13_lib.c,v 1.63 2022/02/05 14:54:10 jsing Exp $ */
/*
* Copyright (c) 2018, 2019 Joel Sing <jsing@openbsd.org>
* Copyright (c) 2019 Bob Beck <beck@openbsd.org>
@@ -111,7 +111,7 @@ tls13_alert_received_cb(uint8_t alert_desc, void *arg)
if (alert_desc == TLS13_ALERT_CLOSE_NOTIFY) {
ctx->close_notify_recv = 1;
ctx->ssl->internal->shutdown |= SSL_RECEIVED_SHUTDOWN;
S3I(ctx->ssl)->warn_alert = alert_desc;
ctx->ssl->s3->warn_alert = alert_desc;
return;
}
@@ -124,7 +124,7 @@ tls13_alert_received_cb(uint8_t alert_desc, void *arg)
}
/* All other alerts are treated as fatal in TLSv1.3. */
S3I(ctx->ssl)->fatal_alert = alert_desc;
ctx->ssl->s3->fatal_alert = alert_desc;
SSLerror(ctx->ssl, SSL_AD_REASON_OFFSET + alert_desc);
ERR_asprintf_error_data("SSL alert number %d", alert_desc);
@@ -147,7 +147,8 @@ tls13_alert_sent_cb(uint8_t alert_desc, void *arg)
}
/* All other alerts are treated as fatal in TLSv1.3. */
SSLerror(ctx->ssl, SSL_AD_REASON_OFFSET + alert_desc);
if (ctx->error.code == 0)
SSLerror(ctx->ssl, SSL_AD_REASON_OFFSET + alert_desc);
}
static void
@@ -161,8 +162,7 @@ tls13_legacy_handshake_message_recv_cb(void *arg)
return;
tls13_handshake_msg_data(ctx->hs_msg, &cbs);
s->internal->msg_callback(0, TLS1_3_VERSION, SSL3_RT_HANDSHAKE,
CBS_data(&cbs), CBS_len(&cbs), s, s->internal->msg_callback_arg);
ssl_msg_callback(s, 0, SSL3_RT_HANDSHAKE, CBS_data(&cbs), CBS_len(&cbs));
}
static void
@@ -176,8 +176,7 @@ tls13_legacy_handshake_message_sent_cb(void *arg)
return;
tls13_handshake_msg_data(ctx->hs_msg, &cbs);
s->internal->msg_callback(1, TLS1_3_VERSION, SSL3_RT_HANDSHAKE,
CBS_data(&cbs), CBS_len(&cbs), s, s->internal->msg_callback_arg);
ssl_msg_callback(s, 1, SSL3_RT_HANDSHAKE, CBS_data(&cbs), CBS_len(&cbs));
}
static void
@@ -185,12 +184,8 @@ tls13_legacy_info_cb(void *arg, int state, int ret)
{
struct tls13_ctx *ctx = arg;
SSL *s = ctx->ssl;
void (*cb)(const SSL *, int, int);
if ((cb = s->internal->info_callback) == NULL)
cb = s->ctx->internal->info_callback;
if (cb != NULL)
cb(s, state, ret);
ssl_info_callback(s, state, ret);
}
static int
@@ -200,8 +195,7 @@ tls13_legacy_ocsp_status_recv_cb(void *arg)
SSL *s = ctx->ssl;
int ret;
if (s->ctx->internal->tlsext_status_cb == NULL ||
s->internal->tlsext_ocsp_resp == NULL)
if (s->ctx->internal->tlsext_status_cb == NULL)
return 1;
ret = s->ctx->internal->tlsext_status_cb(s,
@@ -223,7 +217,7 @@ tls13_legacy_ocsp_status_recv_cb(void *arg)
static int
tls13_phh_update_local_traffic_secret(struct tls13_ctx *ctx)
{
struct tls13_secrets *secrets = ctx->hs->secrets;
struct tls13_secrets *secrets = ctx->hs->tls13.secrets;
if (ctx->mode == TLS13_HS_CLIENT)
return (tls13_update_client_traffic_secret(secrets) &&
@@ -237,7 +231,7 @@ tls13_phh_update_local_traffic_secret(struct tls13_ctx *ctx)
static int
tls13_phh_update_peer_traffic_secret(struct tls13_ctx *ctx)
{
struct tls13_secrets *secrets = ctx->hs->secrets;
struct tls13_secrets *secrets = ctx->hs->tls13.secrets;
if (ctx->mode == TLS13_HS_CLIENT)
return (tls13_update_server_traffic_secret(secrets) &&
@@ -380,6 +374,7 @@ tls13_phh_received_cb(void *cb_arg, CBS *cbs)
static const struct tls13_record_layer_callbacks rl_callbacks = {
.wire_read = tls13_legacy_wire_read_cb,
.wire_write = tls13_legacy_wire_write_cb,
.wire_flush = tls13_legacy_wire_flush_cb,
.alert_recv = tls13_alert_received_cb,
.alert_sent = tls13_alert_sent_cb,
.phh_recv = tls13_phh_received_cb,
@@ -429,9 +424,9 @@ tls13_ctx_free(struct tls13_ctx *ctx)
int
tls13_cert_add(struct tls13_ctx *ctx, CBB *cbb, X509 *cert,
int(*build_extensions)(SSL *s, uint16_t msg_type, CBB *cbb))
int (*build_extensions)(SSL *s, uint16_t msg_type, CBB *cbb))
{
CBB cert_data;
CBB cert_data, cert_exts;
uint8_t *data;
int cert_len;
@@ -448,7 +443,6 @@ tls13_cert_add(struct tls13_ctx *ctx, CBB *cbb, X509 *cert,
if (!build_extensions(ctx->ssl, SSL_TLSEXT_MSG_CT, cbb))
return 0;
} else {
CBB cert_exts;
if (!CBB_add_u16_length_prefixed(cbb, &cert_exts))
return 0;
}
@@ -504,16 +498,16 @@ tls13_synthetic_handshake_message(struct tls13_ctx *ctx)
int
tls13_clienthello_hash_init(struct tls13_ctx *ctx)
{
if (ctx->hs->clienthello_md_ctx != NULL)
if (ctx->hs->tls13.clienthello_md_ctx != NULL)
return 0;
if ((ctx->hs->clienthello_md_ctx = EVP_MD_CTX_new()) == NULL)
if ((ctx->hs->tls13.clienthello_md_ctx = EVP_MD_CTX_new()) == NULL)
return 0;
if (!EVP_DigestInit_ex(ctx->hs->clienthello_md_ctx,
if (!EVP_DigestInit_ex(ctx->hs->tls13.clienthello_md_ctx,
EVP_sha256(), NULL))
return 0;
if ((ctx->hs->clienthello_hash == NULL) &&
(ctx->hs->clienthello_hash = calloc(1, EVP_MAX_MD_SIZE)) ==
if ((ctx->hs->tls13.clienthello_hash == NULL) &&
(ctx->hs->tls13.clienthello_hash = calloc(1, EVP_MAX_MD_SIZE)) ==
NULL)
return 0;
@@ -521,7 +515,7 @@ tls13_clienthello_hash_init(struct tls13_ctx *ctx)
}
void
tls13_clienthello_hash_clear(struct ssl_handshake_tls13_st *hs)
tls13_clienthello_hash_clear(struct ssl_handshake_tls13_st *hs) /* XXX */
{
EVP_MD_CTX_free(hs->clienthello_md_ctx);
hs->clienthello_md_ctx = NULL;
@@ -533,7 +527,7 @@ int
tls13_clienthello_hash_update_bytes(struct tls13_ctx *ctx, void *data,
size_t len)
{
return EVP_DigestUpdate(ctx->hs->clienthello_md_ctx, data, len);
return EVP_DigestUpdate(ctx->hs->tls13.clienthello_md_ctx, data, len);
}
int
@@ -546,12 +540,12 @@ tls13_clienthello_hash_update(struct tls13_ctx *ctx, CBS *cbs)
int
tls13_clienthello_hash_finalize(struct tls13_ctx *ctx)
{
if (!EVP_DigestFinal_ex(ctx->hs->clienthello_md_ctx,
ctx->hs->clienthello_hash,
&ctx->hs->clienthello_hash_len))
if (!EVP_DigestFinal_ex(ctx->hs->tls13.clienthello_md_ctx,
ctx->hs->tls13.clienthello_hash,
&ctx->hs->tls13.clienthello_hash_len))
return 0;
EVP_MD_CTX_free(ctx->hs->clienthello_md_ctx);
ctx->hs->clienthello_md_ctx = NULL;
EVP_MD_CTX_free(ctx->hs->tls13.clienthello_md_ctx);
ctx->hs->tls13.clienthello_md_ctx = NULL;
return 1;
}
@@ -561,21 +555,90 @@ tls13_clienthello_hash_validate(struct tls13_ctx *ctx)
unsigned char new_ch_hash[EVP_MAX_MD_SIZE];
unsigned int new_ch_hash_len;
if (ctx->hs->clienthello_hash == NULL)
if (ctx->hs->tls13.clienthello_hash == NULL)
return 0;
if (!EVP_DigestFinal_ex(ctx->hs->clienthello_md_ctx,
if (!EVP_DigestFinal_ex(ctx->hs->tls13.clienthello_md_ctx,
new_ch_hash, &new_ch_hash_len))
return 0;
EVP_MD_CTX_free(ctx->hs->clienthello_md_ctx);
ctx->hs->clienthello_md_ctx = NULL;
EVP_MD_CTX_free(ctx->hs->tls13.clienthello_md_ctx);
ctx->hs->tls13.clienthello_md_ctx = NULL;
if (ctx->hs->clienthello_hash_len != new_ch_hash_len)
if (ctx->hs->tls13.clienthello_hash_len != new_ch_hash_len)
return 0;
if (memcmp(ctx->hs->clienthello_hash, new_ch_hash,
if (memcmp(ctx->hs->tls13.clienthello_hash, new_ch_hash,
new_ch_hash_len) != 0)
return 0;
return 1;
}
int
tls13_exporter(struct tls13_ctx *ctx, const uint8_t *label, size_t label_len,
const uint8_t *context_value, size_t context_value_len, uint8_t *out,
size_t out_len)
{
struct tls13_secret context, export_out, export_secret;
struct tls13_secrets *secrets = ctx->hs->tls13.secrets;
EVP_MD_CTX *md_ctx = NULL;
unsigned int md_out_len;
int md_len;
int ret = 0;
/*
* RFC 8446 Section 7.5.
*/
memset(&context, 0, sizeof(context));
memset(&export_secret, 0, sizeof(export_secret));
export_out.data = out;
export_out.len = out_len;
if (!ctx->handshake_completed)
return 0;
md_len = EVP_MD_size(secrets->digest);
if (md_len <= 0 || md_len > EVP_MAX_MD_SIZE)
goto err;
if (!tls13_secret_init(&export_secret, md_len))
goto err;
if (!tls13_secret_init(&context, md_len))
goto err;
/* In TLSv1.3 no context is equivalent to an empty context. */
if (context_value == NULL) {
context_value = "";
context_value_len = 0;
}
if ((md_ctx = EVP_MD_CTX_new()) == NULL)
goto err;
if (!EVP_DigestInit_ex(md_ctx, secrets->digest, NULL))
goto err;
if (!EVP_DigestUpdate(md_ctx, context_value, context_value_len))
goto err;
if (!EVP_DigestFinal_ex(md_ctx, context.data, &md_out_len))
goto err;
if (md_len != md_out_len)
goto err;
if (!tls13_derive_secret_with_label_length(&export_secret,
secrets->digest, &secrets->exporter_master, label, label_len,
&secrets->empty_hash))
goto err;
if (!tls13_hkdf_expand_label(&export_out, secrets->digest,
&export_secret, "exporter", &context))
goto err;
ret = 1;
err:
EVP_MD_CTX_free(md_ctx);
tls13_secret_cleanup(&context);
tls13_secret_cleanup(&export_secret);
return ret;
}

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: tls13_record.c,v 1.6 2020/05/11 18:08:11 jsing Exp $ */
/* $OpenBSD: tls13_record.c,v 1.9 2021/10/23 13:12:14 jsing Exp $ */
/*
* Copyright (c) 2018, 2019 Joel Sing <jsing@openbsd.org>
*
@@ -15,8 +15,6 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "ssl_locl.h"
#include "tls13_internal.h"
#include "tls13_record.h"
@@ -28,7 +26,7 @@ struct tls13_record {
size_t data_len;
CBS cbs;
struct tls13_buffer *buf;
struct tls_buffer *buf;
};
struct tls13_record *
@@ -38,7 +36,7 @@ tls13_record_new(void)
if ((rec = calloc(1, sizeof(struct tls13_record))) == NULL)
goto err;
if ((rec->buf = tls13_buffer_new(TLS13_RECORD_MAX_LEN)) == NULL)
if ((rec->buf = tls_buffer_new(TLS13_RECORD_MAX_LEN)) == NULL)
goto err;
return rec;
@@ -55,7 +53,7 @@ tls13_record_free(struct tls13_record *rec)
if (rec == NULL)
return;
tls13_buffer_free(rec->buf);
tls_buffer_free(rec->buf);
freezero(rec->data, rec->data_len);
freezero(rec, sizeof(struct tls13_record));
@@ -120,7 +118,7 @@ tls13_record_set_data(struct tls13_record *rec, uint8_t *data, size_t data_len)
}
ssize_t
tls13_record_recv(struct tls13_record *rec, tls13_read_cb wire_read,
tls13_record_recv(struct tls13_record *rec, tls_read_cb wire_read,
void *wire_arg)
{
uint16_t rec_len, rec_version;
@@ -132,11 +130,11 @@ tls13_record_recv(struct tls13_record *rec, tls13_read_cb wire_read,
return TLS13_IO_FAILURE;
if (rec->content_type == 0) {
if ((ret = tls13_buffer_extend(rec->buf,
if ((ret = tls_buffer_extend(rec->buf,
TLS13_RECORD_HEADER_LEN, wire_read, wire_arg)) <= 0)
return ret;
tls13_buffer_cbs(rec->buf, &cbs);
tls_buffer_cbs(rec->buf, &cbs);
if (!CBS_get_u8(&cbs, &content_type))
return TLS13_IO_FAILURE;
@@ -155,18 +153,18 @@ tls13_record_recv(struct tls13_record *rec, tls13_read_cb wire_read,
rec->rec_len = rec_len;
}
if ((ret = tls13_buffer_extend(rec->buf,
if ((ret = tls_buffer_extend(rec->buf,
TLS13_RECORD_HEADER_LEN + rec->rec_len, wire_read, wire_arg)) <= 0)
return ret;
if (!tls13_buffer_finish(rec->buf, &rec->data, &rec->data_len))
if (!tls_buffer_finish(rec->buf, &rec->data, &rec->data_len))
return TLS13_IO_FAILURE;
return rec->data_len;
}
ssize_t
tls13_record_send(struct tls13_record *rec, tls13_write_cb wire_write,
tls13_record_send(struct tls13_record *rec, tls_write_cb wire_write,
void *wire_arg)
{
ssize_t ret;

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: tls13_record.h,v 1.3 2019/01/21 00:24:19 jsing Exp $ */
/* $OpenBSD: tls13_record.h,v 1.5 2021/10/23 13:12:14 jsing Exp $ */
/*
* Copyright (c) 2019 Joel Sing <jsing@openbsd.org>
*
@@ -19,7 +19,6 @@
#define HEADER_TLS13_RECORD_H
#include "bytestring.h"
#include "tls13_internal.h"
__BEGIN_HIDDEN_DECLS
@@ -57,9 +56,9 @@ int tls13_record_content(struct tls13_record *_rec, CBS *_cbs);
void tls13_record_data(struct tls13_record *_rec, CBS *_cbs);
int tls13_record_set_data(struct tls13_record *_rec, uint8_t *_data,
size_t _data_len);
ssize_t tls13_record_recv(struct tls13_record *_rec, tls13_read_cb _wire_read,
ssize_t tls13_record_recv(struct tls13_record *_rec, tls_read_cb _wire_read,
void *_wire_arg);
ssize_t tls13_record_send(struct tls13_record *_rec, tls13_write_cb _wire_write,
ssize_t tls13_record_send(struct tls13_record *_rec, tls_write_cb _wire_write,
void *_wire_arg);
__END_HIDDEN_DECLS

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: tls13_record_layer.c,v 1.53 2020/09/11 15:03:36 jsing Exp $ */
/* $OpenBSD: tls13_record_layer.c,v 1.67 2022/01/14 09:12:15 tb Exp $ */
/*
* Copyright (c) 2018, 2019 Joel Sing <jsing@openbsd.org>
*
@@ -15,16 +15,50 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "ssl_locl.h"
#include "tls13_internal.h"
#include "tls13_record.h"
#include "tls_content.h"
static ssize_t tls13_record_layer_write_chunk(struct tls13_record_layer *rl,
uint8_t content_type, const uint8_t *buf, size_t n);
static ssize_t tls13_record_layer_write_record(struct tls13_record_layer *rl,
uint8_t content_type, const uint8_t *content, size_t content_len);
struct tls13_record_protection {
EVP_AEAD_CTX *aead_ctx;
struct tls13_secret iv;
struct tls13_secret nonce;
uint8_t seq_num[TLS13_RECORD_SEQ_NUM_LEN];
};
struct tls13_record_protection *
tls13_record_protection_new(void)
{
return calloc(1, sizeof(struct tls13_record_protection));
}
void
tls13_record_protection_clear(struct tls13_record_protection *rp)
{
EVP_AEAD_CTX_free(rp->aead_ctx);
tls13_secret_cleanup(&rp->iv);
tls13_secret_cleanup(&rp->nonce);
memset(rp, 0, sizeof(*rp));
}
void
tls13_record_protection_free(struct tls13_record_protection *rp)
{
if (rp == NULL)
return;
tls13_record_protection_clear(rp);
freezero(rp, sizeof(struct tls13_record_protection));
}
struct tls13_record_layer {
uint16_t legacy_version;
@@ -66,39 +100,20 @@ struct tls13_record_layer {
uint8_t *phh_data;
size_t phh_len;
/* Buffer containing plaintext from opened records. */
uint8_t rbuf_content_type;
uint8_t *rbuf;
size_t rbuf_len;
CBS rbuf_cbs;
/* Content from opened records. */
struct tls_content *rcontent;
/* Record protection. */
const EVP_MD *hash;
const EVP_AEAD *aead;
EVP_AEAD_CTX read_aead_ctx;
EVP_AEAD_CTX write_aead_ctx;
struct tls13_secret read_iv;
struct tls13_secret write_iv;
struct tls13_secret read_nonce;
struct tls13_secret write_nonce;
uint8_t read_seq_num[TLS13_RECORD_SEQ_NUM_LEN];
uint8_t write_seq_num[TLS13_RECORD_SEQ_NUM_LEN];
struct tls13_record_protection *read;
struct tls13_record_protection *write;
/* Callbacks. */
struct tls13_record_layer_callbacks cb;
void *cb_arg;
};
static void
tls13_record_layer_rbuf_free(struct tls13_record_layer *rl)
{
CBS_init(&rl->rbuf_cbs, NULL, 0);
freezero(rl->rbuf, rl->rbuf_len);
rl->rbuf = NULL;
rl->rbuf_len = 0;
rl->rbuf_content_type = 0;
}
static void
tls13_record_layer_rrec_free(struct tls13_record_layer *rl)
{
@@ -120,13 +135,26 @@ tls13_record_layer_new(const struct tls13_record_layer_callbacks *callbacks,
struct tls13_record_layer *rl;
if ((rl = calloc(1, sizeof(struct tls13_record_layer))) == NULL)
return NULL;
goto err;
if ((rl->rcontent = tls_content_new()) == NULL)
goto err;
if ((rl->read = tls13_record_protection_new()) == NULL)
goto err;
if ((rl->write = tls13_record_protection_new()) == NULL)
goto err;
rl->legacy_version = TLS1_2_VERSION;
rl->cb = *callbacks;
rl->cb_arg = cb_arg;
return rl;
err:
tls13_record_layer_free(rl);
return NULL;
}
void
@@ -135,26 +163,24 @@ tls13_record_layer_free(struct tls13_record_layer *rl)
if (rl == NULL)
return;
tls13_record_layer_rbuf_free(rl);
tls13_record_layer_rrec_free(rl);
tls13_record_layer_wrec_free(rl);
EVP_AEAD_CTX_cleanup(&rl->read_aead_ctx);
EVP_AEAD_CTX_cleanup(&rl->write_aead_ctx);
freezero(rl->alert_data, rl->alert_len);
freezero(rl->phh_data, rl->phh_len);
freezero(rl->read_iv.data, rl->read_iv.len);
freezero(rl->write_iv.data, rl->write_iv.len);
freezero(rl->read_nonce.data, rl->read_nonce.len);
freezero(rl->write_nonce.data, rl->write_nonce.len);
tls_content_free(rl->rcontent);
tls13_record_protection_free(rl->read);
tls13_record_protection_free(rl->write);
freezero(rl, sizeof(struct tls13_record_layer));
}
void
tls13_record_layer_rbuf(struct tls13_record_layer *rl, CBS *cbs)
tls13_record_layer_rcontent(struct tls13_record_layer *rl, CBS *cbs)
{
CBS_dup(&rl->rbuf_cbs, cbs);
CBS_dup(tls_content_cbs(rl->rcontent), cbs);
}
static const uint8_t tls13_max_seq_num[TLS13_RECORD_SEQ_NUM_LEN] = {
@@ -257,22 +283,18 @@ tls13_record_layer_process_alert(struct tls13_record_layer *rl)
* will result in one of three things - continuation (user_cancelled),
* read channel closure (close_notify) or termination (all others).
*/
if (rl->rbuf == NULL)
if (tls_content_type(rl->rcontent) != SSL3_RT_ALERT)
return TLS13_IO_FAILURE;
if (rl->rbuf_content_type != SSL3_RT_ALERT)
return TLS13_IO_FAILURE;
if (!CBS_get_u8(&rl->rbuf_cbs, &alert_level))
if (!CBS_get_u8(tls_content_cbs(rl->rcontent), &alert_level))
return tls13_send_alert(rl, TLS13_ALERT_DECODE_ERROR);
if (!CBS_get_u8(tls_content_cbs(rl->rcontent), &alert_desc))
return tls13_send_alert(rl, TLS13_ALERT_DECODE_ERROR);
if (!CBS_get_u8(&rl->rbuf_cbs, &alert_desc))
if (tls_content_remaining(rl->rcontent) != 0)
return tls13_send_alert(rl, TLS13_ALERT_DECODE_ERROR);
if (CBS_len(&rl->rbuf_cbs) != 0)
return tls13_send_alert(rl, TLS13_ALERT_DECODE_ERROR);
tls13_record_layer_rbuf_free(rl);
tls_content_clear(rl->rcontent);
/*
* Alert level is ignored for closure alerts (RFC 8446 section 6.1),
@@ -383,7 +405,7 @@ tls13_record_layer_send_pending(struct tls13_record_layer *rl)
}
static ssize_t
tls13_record_layer_alert(struct tls13_record_layer *rl,
tls13_record_layer_enqueue_alert(struct tls13_record_layer *rl,
uint8_t alert_level, uint8_t alert_desc)
{
CBB cbb;
@@ -427,49 +449,38 @@ tls13_record_layer_phh(struct tls13_record_layer *rl, CBS *cbs)
}
static int
tls13_record_layer_set_traffic_key(const EVP_AEAD *aead, EVP_AEAD_CTX *aead_ctx,
const EVP_MD *hash, struct tls13_secret *iv, struct tls13_secret *nonce,
struct tls13_secret *traffic_key)
tls13_record_layer_set_traffic_key(const EVP_AEAD *aead, const EVP_MD *hash,
struct tls13_record_protection *rp, struct tls13_secret *traffic_key)
{
struct tls13_secret context = { .data = "", .len = 0 };
struct tls13_secret key = { .data = NULL, .len = 0 };
int ret = 0;
EVP_AEAD_CTX_cleanup(aead_ctx);
tls13_record_protection_clear(rp);
freezero(iv->data, iv->len);
iv->data = NULL;
iv->len = 0;
if ((rp->aead_ctx = EVP_AEAD_CTX_new()) == NULL)
return 0;
freezero(nonce->data, nonce->len);
nonce->data = NULL;
nonce->len = 0;
if ((iv->data = calloc(1, EVP_AEAD_nonce_length(aead))) == NULL)
if (!tls13_secret_init(&rp->iv, EVP_AEAD_nonce_length(aead)))
goto err;
iv->len = EVP_AEAD_nonce_length(aead);
if ((nonce->data = calloc(1, EVP_AEAD_nonce_length(aead))) == NULL)
if (!tls13_secret_init(&rp->nonce, EVP_AEAD_nonce_length(aead)))
goto err;
nonce->len = EVP_AEAD_nonce_length(aead);
if ((key.data = calloc(1, EVP_AEAD_key_length(aead))) == NULL)
if (!tls13_secret_init(&key, EVP_AEAD_key_length(aead)))
goto err;
key.len = EVP_AEAD_key_length(aead);
if (!tls13_hkdf_expand_label(iv, hash, traffic_key, "iv", &context))
if (!tls13_hkdf_expand_label(&rp->iv, hash, traffic_key, "iv", &context))
goto err;
if (!tls13_hkdf_expand_label(&key, hash, traffic_key, "key", &context))
goto err;
if (!EVP_AEAD_CTX_init(aead_ctx, aead, key.data, key.len,
if (!EVP_AEAD_CTX_init(rp->aead_ctx, aead, key.data, key.len,
EVP_AEAD_DEFAULT_TAG_LENGTH, NULL))
goto err;
ret = 1;
err:
freezero(key.data, key.len);
tls13_secret_cleanup(&key);
return ret;
}
@@ -478,20 +489,16 @@ int
tls13_record_layer_set_read_traffic_key(struct tls13_record_layer *rl,
struct tls13_secret *read_key)
{
memset(rl->read_seq_num, 0, TLS13_RECORD_SEQ_NUM_LEN);
return tls13_record_layer_set_traffic_key(rl->aead, &rl->read_aead_ctx,
rl->hash, &rl->read_iv, &rl->read_nonce, read_key);
return tls13_record_layer_set_traffic_key(rl->aead, rl->hash,
rl->read, read_key);
}
int
tls13_record_layer_set_write_traffic_key(struct tls13_record_layer *rl,
struct tls13_secret *write_key)
{
memset(rl->write_seq_num, 0, TLS13_RECORD_SEQ_NUM_LEN);
return tls13_record_layer_set_traffic_key(rl->aead, &rl->write_aead_ctx,
rl->hash, &rl->write_iv, &rl->write_nonce, write_key);
return tls13_record_layer_set_traffic_key(rl->aead, rl->hash,
rl->write, write_key);
}
static int
@@ -514,23 +521,17 @@ tls13_record_layer_open_record_plaintext(struct tls13_record_layer *rl)
return 0;
}
tls13_record_layer_rbuf_free(rl);
if (!CBS_stow(&cbs, &rl->rbuf, &rl->rbuf_len))
if (!tls_content_dup_data(rl->rcontent,
tls13_record_content_type(rl->rrec), CBS_data(&cbs), CBS_len(&cbs)))
return 0;
rl->rbuf_content_type = tls13_record_content_type(rl->rrec);
CBS_init(&rl->rbuf_cbs, rl->rbuf, rl->rbuf_len);
return 1;
}
static int
tls13_record_layer_open_record_protected(struct tls13_record_layer *rl)
{
CBS header, enc_record;
ssize_t inner_len;
CBS header, enc_record, inner;
uint8_t *content = NULL;
size_t content_len = 0;
uint8_t content_type;
@@ -548,13 +549,13 @@ tls13_record_layer_open_record_protected(struct tls13_record_layer *rl)
goto err;
content_len = CBS_len(&enc_record);
if (!tls13_record_layer_update_nonce(&rl->read_nonce, &rl->read_iv,
rl->read_seq_num))
if (!tls13_record_layer_update_nonce(&rl->read->nonce, &rl->read->iv,
rl->read->seq_num))
goto err;
if (!EVP_AEAD_CTX_open(&rl->read_aead_ctx,
if (!EVP_AEAD_CTX_open(rl->read->aead_ctx,
content, &out_len, content_len,
rl->read_nonce.data, rl->read_nonce.len,
rl->read->nonce.data, rl->read->nonce.len,
CBS_data(&enc_record), CBS_len(&enc_record),
CBS_data(&header), CBS_len(&header)))
goto err;
@@ -564,7 +565,7 @@ tls13_record_layer_open_record_protected(struct tls13_record_layer *rl)
goto err;
}
if (!tls13_record_layer_inc_seq_num(rl->read_seq_num))
if (!tls13_record_layer_inc_seq_num(rl->read->seq_num))
goto err;
/*
@@ -572,28 +573,24 @@ tls13_record_layer_open_record_protected(struct tls13_record_layer *rl)
* it may be followed by padding that consists of one or more zeroes.
* Time to hunt for that elusive content type!
*/
/* XXX - CBS from end? CBS_get_end_u8()? */
inner_len = out_len - 1;
while (inner_len >= 0 && content[inner_len] == 0)
inner_len--;
if (inner_len < 0) {
CBS_init(&inner, content, out_len);
content_type = 0;
while (CBS_get_last_u8(&inner, &content_type)) {
if (content_type != 0)
break;
}
if (content_type == 0) {
/* Unexpected message per RFC 8446 section 5.4. */
rl->alert = TLS13_ALERT_UNEXPECTED_MESSAGE;
goto err;
}
if (inner_len > TLS13_RECORD_MAX_PLAINTEXT_LEN) {
if (CBS_len(&inner) > TLS13_RECORD_MAX_PLAINTEXT_LEN) {
rl->alert = TLS13_ALERT_RECORD_OVERFLOW;
goto err;
}
content_type = content[inner_len];
tls13_record_layer_rbuf_free(rl);
rl->rbuf_content_type = content_type;
rl->rbuf = content;
rl->rbuf_len = inner_len;
CBS_init(&rl->rbuf_cbs, rl->rbuf, rl->rbuf_len);
tls_content_set_data(rl->rcontent, content_type, CBS_data(&inner),
CBS_len(&inner));
return 1;
@@ -725,8 +722,8 @@ tls13_record_layer_seal_record_protected(struct tls13_record_layer *rl,
if (!CBB_finish(&cbb, &data, &data_len))
goto err;
if (!tls13_record_layer_update_nonce(&rl->write_nonce,
&rl->write_iv, rl->write_seq_num))
if (!tls13_record_layer_update_nonce(&rl->write->nonce,
&rl->write->iv, rl->write->seq_num))
goto err;
/*
@@ -734,16 +731,16 @@ tls13_record_layer_seal_record_protected(struct tls13_record_layer *rl,
* this would avoid a copy since the inner would be passed as two
* separate pieces.
*/
if (!EVP_AEAD_CTX_seal(&rl->write_aead_ctx,
if (!EVP_AEAD_CTX_seal(rl->write->aead_ctx,
enc_record, &out_len, enc_record_len,
rl->write_nonce.data, rl->write_nonce.len,
rl->write->nonce.data, rl->write->nonce.len,
inner, inner_len, header, header_len))
goto err;
if (out_len != enc_record_len)
goto err;
if (!tls13_record_layer_inc_seq_num(rl->write_seq_num))
if (!tls13_record_layer_inc_seq_num(rl->write->seq_num))
goto err;
if (!tls13_record_set_data(rl->wrec, data, data_len))
@@ -798,7 +795,7 @@ tls13_record_layer_read_record(struct tls13_record_layer *rl)
if ((rl->rrec = tls13_record_new()) == NULL)
goto err;
}
if ((ret = tls13_record_recv(rl->rrec, rl->cb.wire_read, rl->cb_arg)) <= 0) {
switch (ret) {
case TLS13_IO_RECORD_VERSION:
@@ -808,13 +805,19 @@ tls13_record_layer_read_record(struct tls13_record_layer *rl)
}
return ret;
}
if (rl->legacy_version == TLS1_2_VERSION &&
tls13_record_version(rl->rrec) != TLS1_2_VERSION)
return tls13_send_alert(rl, TLS13_ALERT_PROTOCOL_VERSION);
content_type = tls13_record_content_type(rl->rrec);
/*
* In response to a client hello we may receive an alert in a
* record with a legacy version. Otherwise enforce that the
* legacy record version is 0x0303 per RFC 8446, section 5.1.
*/
if (rl->legacy_version == TLS1_2_VERSION &&
tls13_record_version(rl->rrec) != TLS1_2_VERSION &&
(content_type != SSL3_RT_ALERT || !rl->legacy_alerts_allowed))
return tls13_send_alert(rl, TLS13_ALERT_PROTOCOL_VERSION);
/*
* Bag of hacks ahead... after the first ClientHello message has been
* sent or received and before the peer's Finished message has been
@@ -854,12 +857,12 @@ tls13_record_layer_read_record(struct tls13_record_layer *rl)
* we must terminate the connection with an unexpected_message alert.
* See RFC 8446 section 5.4.
*/
if (CBS_len(&rl->rbuf_cbs) == 0 &&
(rl->rbuf_content_type == SSL3_RT_ALERT ||
rl->rbuf_content_type == SSL3_RT_HANDSHAKE))
if (tls_content_remaining(rl->rcontent) == 0 &&
(tls_content_type(rl->rcontent) == SSL3_RT_ALERT ||
tls_content_type(rl->rcontent) == SSL3_RT_HANDSHAKE))
return tls13_send_alert(rl, TLS13_ALERT_UNEXPECTED_MESSAGE);
switch (rl->rbuf_content_type) {
switch (tls_content_type(rl->rcontent)) {
case SSL3_RT_ALERT:
return tls13_record_layer_process_alert(rl);
@@ -884,10 +887,10 @@ tls13_record_layer_read_record(struct tls13_record_layer *rl)
static ssize_t
tls13_record_layer_pending(struct tls13_record_layer *rl, uint8_t content_type)
{
if (rl->rbuf_content_type != content_type)
if (tls_content_type(rl->rcontent) != content_type)
return 0;
return CBS_len(&rl->rbuf_cbs);
return tls_content_remaining(rl->rcontent);
}
static ssize_t
@@ -906,9 +909,9 @@ tls13_record_layer_recv_phh(struct tls13_record_layer *rl)
* TLS13_IO_FAILURE something broke.
*/
if (rl->cb.phh_recv != NULL)
ret = rl->cb.phh_recv(rl->cb_arg, &rl->rbuf_cbs);
ret = rl->cb.phh_recv(rl->cb_arg, tls_content_cbs(rl->rcontent));
tls13_record_layer_rbuf_free(rl);
tls_content_clear(rl->rcontent);
/* Leave post handshake handshake mode unless we need more data. */
if (ret != TLS13_IO_WANT_POLLIN)
@@ -937,7 +940,7 @@ tls13_record_layer_read_internal(struct tls13_record_layer *rl,
return TLS13_IO_EOF;
/* If necessary, pull up the next record. */
if (CBS_len(&rl->rbuf_cbs) == 0) {
if (tls_content_remaining(rl->rcontent) == 0) {
if ((ret = tls13_record_layer_read_record(rl)) <= 0)
return ret;
@@ -945,17 +948,15 @@ tls13_record_layer_read_internal(struct tls13_record_layer *rl,
* We may have read a valid 0-byte application data record,
* in which case we need to read the next record.
*/
if (CBS_len(&rl->rbuf_cbs) == 0) {
tls13_record_layer_rbuf_free(rl);
if (tls_content_remaining(rl->rcontent) == 0)
return TLS13_IO_WANT_POLLIN;
}
}
/*
* If we are in post handshake handshake mode, we must not see
* any record type that isn't a handshake until we are done.
*/
if (rl->phh && rl->rbuf_content_type != SSL3_RT_HANDSHAKE)
if (rl->phh && tls_content_type(rl->rcontent) != SSL3_RT_HANDSHAKE)
return tls13_send_alert(rl, TLS13_ALERT_UNEXPECTED_MESSAGE);
/*
@@ -964,32 +965,18 @@ tls13_record_layer_read_internal(struct tls13_record_layer *rl,
* be trying to read application data and need to handle a
* post-handshake handshake message instead...
*/
if (rl->rbuf_content_type != content_type) {
if (rl->rbuf_content_type == SSL3_RT_HANDSHAKE) {
if (tls_content_type(rl->rcontent) != content_type) {
if (tls_content_type(rl->rcontent) == SSL3_RT_HANDSHAKE) {
if (rl->handshake_completed)
return tls13_record_layer_recv_phh(rl);
}
return tls13_send_alert(rl, TLS13_ALERT_UNEXPECTED_MESSAGE);
}
if (n > CBS_len(&rl->rbuf_cbs))
n = CBS_len(&rl->rbuf_cbs);
if (peek)
return tls_content_peek(rl->rcontent, buf, n);
/* XXX - CBS_memcpy? CBS_copy_bytes? */
memcpy(buf, CBS_data(&rl->rbuf_cbs), n);
if (!peek) {
if (!CBS_skip(&rl->rbuf_cbs, n))
goto err;
}
if (CBS_len(&rl->rbuf_cbs) == 0)
tls13_record_layer_rbuf_free(rl);
return n;
err:
return TLS13_IO_FAILURE;
return tls_content_read(rl->rcontent, buf, n);
}
static ssize_t
@@ -1113,6 +1100,12 @@ tls13_record_layer_write(struct tls13_record_layer *rl, uint8_t content_type,
return ret;
}
ssize_t
tls13_record_layer_flush(struct tls13_record_layer *rl)
{
return rl->cb.wire_flush(rl->cb_arg);
}
static const uint8_t tls13_dummy_ccs[] = { 0x01 };
ssize_t
@@ -1193,7 +1186,8 @@ tls13_send_alert(struct tls13_record_layer *rl, uint8_t alert_desc)
alert_level = TLS13_ALERT_LEVEL_WARNING;
do {
ret = tls13_record_layer_alert(rl, alert_level, alert_desc);
ret = tls13_record_layer_enqueue_alert(rl, alert_level,
alert_desc);
} while (ret == TLS13_IO_WANT_RETRY);
return ret;

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: tls13_server.c,v 1.61 2020/07/03 04:12:51 tb Exp $ */
/* $OpenBSD: tls13_server.c,v 1.96 2022/02/03 16:33:12 jsing Exp $ */
/*
* Copyright (c) 2019, 2020 Joel Sing <jsing@openbsd.org>
* Copyright (c) 2020 Bob Beck <beck@openbsd.org>
@@ -19,8 +19,8 @@
#include <openssl/x509v3.h>
#include "ssl_locl.h"
#include "ssl_sigalgs.h"
#include "ssl_tlsext.h"
#include "tls13_handshake.h"
#include "tls13_internal.h"
@@ -29,12 +29,12 @@ tls13_server_init(struct tls13_ctx *ctx)
{
SSL *s = ctx->ssl;
if (!ssl_supported_version_range(s, &ctx->hs->min_version,
&ctx->hs->max_version)) {
if (!ssl_supported_tls_version_range(s, &ctx->hs->our_min_tls_version,
&ctx->hs->our_max_tls_version)) {
SSLerror(s, SSL_R_NO_PROTOCOLS_AVAILABLE);
return 0;
}
s->version = ctx->hs->max_version;
s->version = ctx->hs->our_max_tls_version;
tls13_record_layer_set_retry_after_phh(ctx->rl,
(s->internal->mode & SSL_MODE_AUTO_RETRY) != 0);
@@ -99,7 +99,7 @@ tls13_client_hello_is_legacy(CBS *cbs)
int
tls13_client_hello_required_extensions(struct tls13_ctx *ctx)
{
SSL *ssl = ctx->ssl;
SSL *s = ctx->ssl;
/*
* RFC 8446, section 9.2. If the ClientHello has supported_versions
@@ -111,10 +111,10 @@ tls13_client_hello_required_extensions(struct tls13_ctx *ctx)
* If we got no pre_shared_key, then signature_algorithms and
* supported_groups must both be present.
*/
if (!tlsext_extension_seen(ssl, TLSEXT_TYPE_pre_shared_key)) {
if (!tlsext_extension_seen(ssl, TLSEXT_TYPE_signature_algorithms))
if (!tlsext_extension_seen(s, TLSEXT_TYPE_pre_shared_key)) {
if (!tlsext_extension_seen(s, TLSEXT_TYPE_signature_algorithms))
return 0;
if (!tlsext_extension_seen(ssl, TLSEXT_TYPE_supported_groups))
if (!tlsext_extension_seen(s, TLSEXT_TYPE_supported_groups))
return 0;
}
@@ -122,8 +122,8 @@ tls13_client_hello_required_extensions(struct tls13_ctx *ctx)
* supported_groups and key_share must either both be present or
* both be absent.
*/
if (tlsext_extension_seen(ssl, TLSEXT_TYPE_supported_groups) !=
tlsext_extension_seen(ssl, TLSEXT_TYPE_key_share))
if (tlsext_extension_seen(s, TLSEXT_TYPE_supported_groups) !=
tlsext_extension_seen(s, TLSEXT_TYPE_key_share))
return 0;
/*
@@ -163,6 +163,11 @@ tls13_client_hello_process(struct tls13_ctx *ctx, CBS *cbs)
goto err;
return tls13_use_legacy_server(ctx);
}
ctx->hs->negotiated_tls_version = TLS1_3_VERSION;
ctx->hs->peer_legacy_version = legacy_version;
/* Ensure we send subsequent alerts with the correct record version. */
tls13_record_layer_set_legacy_version(ctx->rl, TLS1_2_VERSION);
/* Add decoded values to the current ClientHello hash */
if (!tls13_clienthello_hash_init(ctx)) {
@@ -197,7 +202,7 @@ tls13_client_hello_process(struct tls13_ctx *ctx, CBS *cbs)
}
/* Finalize first ClientHello hash, or validate against it */
if (!ctx->hs->hrr) {
if (!ctx->hs->tls13.hrr) {
if (!tls13_clienthello_hash_finalize(ctx)) {
ctx->alert = TLS13_ALERT_INTERNAL_ERROR;
goto err;
@@ -207,7 +212,7 @@ tls13_client_hello_process(struct tls13_ctx *ctx, CBS *cbs)
ctx->alert = TLS13_ALERT_ILLEGAL_PARAMETER;
goto err;
}
tls13_clienthello_hash_clear(ctx->hs);
tls13_clienthello_hash_clear(&ctx->hs->tls13);
}
if (!tls13_client_hello_required_extensions(ctx)) {
@@ -225,13 +230,13 @@ tls13_client_hello_process(struct tls13_ctx *ctx, CBS *cbs)
}
/* Store legacy session identifier so we can echo it. */
if (CBS_len(&session_id) > sizeof(ctx->hs->legacy_session_id)) {
if (CBS_len(&session_id) > sizeof(ctx->hs->tls13.legacy_session_id)) {
ctx->alert = TLS13_ALERT_ILLEGAL_PARAMETER;
goto err;
}
if (!CBS_write_bytes(&session_id, ctx->hs->legacy_session_id,
sizeof(ctx->hs->legacy_session_id),
&ctx->hs->legacy_session_id_len)) {
if (!CBS_write_bytes(&session_id, ctx->hs->tls13.legacy_session_id,
sizeof(ctx->hs->tls13.legacy_session_id),
&ctx->hs->tls13.legacy_session_id_len)) {
ctx->alert = TLS13_ALERT_INTERNAL_ERROR;
goto err;
}
@@ -248,7 +253,11 @@ tls13_client_hello_process(struct tls13_ctx *ctx, CBS *cbs)
ctx->alert = TLS13_ALERT_HANDSHAKE_FAILURE;
goto err;
}
S3I(s)->hs.new_cipher = cipher;
ctx->hs->cipher = cipher;
sk_SSL_CIPHER_free(s->session->ciphers);
s->session->ciphers = ciphers;
ciphers = NULL;
/* Ensure only the NULL compression method is advertised. */
if (!CBS_mem_equal(&compression_methods, tls13_compression_null_only,
@@ -274,11 +283,9 @@ tls13_client_hello_recv(struct tls13_ctx *ctx, CBS *cbs)
goto err;
/* See if we switched back to the legacy client method. */
if (s->method->internal->version < TLS1_3_VERSION)
if (s->method->version < TLS1_3_VERSION)
return 1;
tls13_record_layer_set_legacy_version(ctx->rl, TLS1_2_VERSION);
/*
* If a matching key share was provided, we do not need to send a
* HelloRetryRequest.
@@ -309,7 +316,7 @@ tls13_server_hello_build(struct tls13_ctx *ctx, CBB *cbb, int hrr)
SSL *s = ctx->ssl;
uint16_t cipher;
cipher = SSL_CIPHER_get_value(S3I(s)->hs.new_cipher);
cipher = SSL_CIPHER_get_value(ctx->hs->cipher);
server_random = s->s3->server_random;
if (hrr) {
@@ -323,8 +330,8 @@ tls13_server_hello_build(struct tls13_ctx *ctx, CBB *cbb, int hrr)
goto err;
if (!CBB_add_u8_length_prefixed(cbb, &session_id))
goto err;
if (!CBB_add_bytes(&session_id, ctx->hs->legacy_session_id,
ctx->hs->legacy_session_id_len))
if (!CBB_add_bytes(&session_id, ctx->hs->tls13.legacy_session_id,
ctx->hs->tls13.legacy_session_id_len))
goto err;
if (!CBB_add_u16(cbb, cipher))
goto err;
@@ -337,7 +344,7 @@ tls13_server_hello_build(struct tls13_ctx *ctx, CBB *cbb, int hrr)
goto err;
return 1;
err:
err:
return 0;
}
@@ -353,20 +360,20 @@ tls13_server_engage_record_protection(struct tls13_ctx *ctx)
SSL *s = ctx->ssl;
int ret = 0;
if (!tls13_key_share_derive(ctx->hs->key_share,
&shared_key, &shared_key_len))
if (!tls_key_share_derive(ctx->hs->key_share, &shared_key,
&shared_key_len))
goto err;
s->session->cipher = S3I(s)->hs.new_cipher;
s->session->cipher = ctx->hs->cipher;
if ((ctx->aead = tls13_cipher_aead(S3I(s)->hs.new_cipher)) == NULL)
if ((ctx->aead = tls13_cipher_aead(ctx->hs->cipher)) == NULL)
goto err;
if ((ctx->hash = tls13_cipher_hash(S3I(s)->hs.new_cipher)) == NULL)
if ((ctx->hash = tls13_cipher_hash(ctx->hs->cipher)) == NULL)
goto err;
if ((secrets = tls13_secrets_create(ctx->hash, 0)) == NULL)
goto err;
ctx->hs->secrets = secrets;
ctx->hs->tls13.secrets = secrets;
/* XXX - pass in hash. */
if (!tls1_transcript_hash_init(s))
@@ -383,7 +390,7 @@ tls13_server_engage_record_protection(struct tls13_ctx *ctx)
goto err;
/* Handshake secrets. */
if (!tls13_derive_handshake_secrets(ctx->hs->secrets, shared_key,
if (!tls13_derive_handshake_secrets(ctx->hs->tls13.secrets, shared_key,
shared_key_len, &context))
goto err;
@@ -413,7 +420,7 @@ tls13_server_hello_retry_request_send(struct tls13_ctx *ctx, CBB *cbb)
{
int nid;
ctx->hs->hrr = 1;
ctx->hs->tls13.hrr = 1;
if (!tls13_synthetic_handshake_message(ctx))
return 0;
@@ -422,7 +429,7 @@ tls13_server_hello_retry_request_send(struct tls13_ctx *ctx, CBB *cbb)
return 0;
if ((nid = tls1_get_shared_curve(ctx->ssl)) == NID_undef)
return 0;
if ((ctx->hs->server_group = tls1_ec_nid2curve_id(nid)) == 0)
if ((ctx->hs->tls13.server_group = tls1_ec_nid2curve_id(nid)) == 0)
return 0;
if (!tls13_server_hello_build(ctx, cbb, 1))
@@ -439,7 +446,7 @@ tls13_server_hello_retry_request_sent(struct tls13_ctx *ctx)
* we MUST send a dummy CCS following our first handshake message.
* See RFC 8446 Appendix D.4.
*/
if (ctx->hs->legacy_session_id_len > 0)
if (ctx->hs->tls13.legacy_session_id_len > 0)
ctx->send_dummy_ccs_after = 1;
return 1;
@@ -454,10 +461,10 @@ tls13_client_hello_retry_recv(struct tls13_ctx *ctx, CBS *cbs)
return 0;
/* XXX - need further checks. */
if (s->method->internal->version < TLS1_3_VERSION)
if (s->method->version < TLS1_3_VERSION)
return 0;
ctx->hs->hrr = 0;
ctx->hs->tls13.hrr = 0;
return 1;
}
@@ -480,12 +487,12 @@ tls13_server_hello_send(struct tls13_ctx *ctx, CBB *cbb)
{
if (ctx->hs->key_share == NULL)
return 0;
if (!tls13_key_share_generate(ctx->hs->key_share))
if (!tls_key_share_generate(ctx->hs->key_share))
return 0;
if (!tls13_servername_process(ctx))
return 0;
ctx->hs->server_group = 0;
ctx->hs->tls13.server_group = 0;
if (!tls13_server_hello_build(ctx, cbb, 0))
return 0;
@@ -502,7 +509,7 @@ tls13_server_hello_sent(struct tls13_ctx *ctx)
* See RFC 8446 Appendix D.4.
*/
if ((ctx->handshake_stage.hs_type & WITHOUT_HRR) &&
ctx->hs->legacy_session_id_len > 0)
ctx->hs->tls13.legacy_session_id_len > 0)
ctx->send_dummy_ccs_after = 1;
return tls13_server_engage_record_protection(ctx);
@@ -538,7 +545,7 @@ tls13_server_certificate_request_send(struct tls13_ctx *ctx, CBB *cbb)
}
static int
tls13_server_check_certificate(struct tls13_ctx *ctx, CERT_PKEY *cpk,
tls13_server_check_certificate(struct tls13_ctx *ctx, SSL_CERT_PKEY *cpk,
int *ok, const struct ssl_sigalg **out_sigalg)
{
const struct ssl_sigalg *sigalg;
@@ -550,15 +557,11 @@ tls13_server_check_certificate(struct tls13_ctx *ctx, CERT_PKEY *cpk,
if (cpk->x509 == NULL || cpk->privatekey == NULL)
goto done;
if (!X509_check_purpose(cpk->x509, -1, 0))
return 0;
/*
* The digitalSignature bit MUST be set if the Key Usage extension is
* present as per RFC 8446 section 4.4.2.2.
*/
if ((cpk->x509->ex_flags & EXFLAG_KUSAGE) &&
!(cpk->x509->ex_kusage & X509v3_KU_DIGITAL_SIGNATURE))
if (!(X509_get_key_usage(cpk->x509) & X509v3_KU_DIGITAL_SIGNATURE))
goto done;
if ((sigalg = ssl_sigalg_select(s, cpk->privatekey)) == NULL)
@@ -572,12 +575,12 @@ tls13_server_check_certificate(struct tls13_ctx *ctx, CERT_PKEY *cpk,
}
static int
tls13_server_select_certificate(struct tls13_ctx *ctx, CERT_PKEY **out_cpk,
tls13_server_select_certificate(struct tls13_ctx *ctx, SSL_CERT_PKEY **out_cpk,
const struct ssl_sigalg **out_sigalg)
{
SSL *s = ctx->ssl;
const struct ssl_sigalg *sigalg;
CERT_PKEY *cpk;
SSL_CERT_PKEY *cpk;
int cert_ok;
*out_cpk = NULL;
@@ -611,8 +614,9 @@ tls13_server_certificate_send(struct tls13_ctx *ctx, CBB *cbb)
SSL *s = ctx->ssl;
CBB cert_request_context, cert_list;
const struct ssl_sigalg *sigalg;
X509_STORE_CTX *xsc = NULL;
STACK_OF(X509) *chain;
CERT_PKEY *cpk;
SSL_CERT_PKEY *cpk;
X509 *cert;
int i, ret = 0;
@@ -627,12 +631,24 @@ tls13_server_certificate_send(struct tls13_ctx *ctx, CBB *cbb)
goto err;
}
ctx->hs->cpk = cpk;
ctx->hs->sigalg = sigalg;
ctx->hs->tls13.cpk = cpk;
ctx->hs->our_sigalg = sigalg;
if ((chain = cpk->chain) == NULL)
chain = s->ctx->extra_certs;
if (chain == NULL && !(s->internal->mode & SSL_MODE_NO_AUTO_CHAIN)) {
if ((xsc = X509_STORE_CTX_new()) == NULL)
goto err;
if (!X509_STORE_CTX_init(xsc, s->ctx->cert_store, cpk->x509, NULL))
goto err;
X509_VERIFY_PARAM_set_flags(X509_STORE_CTX_get0_param(xsc),
X509_V_FLAG_LEGACY_VERIFY);
X509_verify_cert(xsc);
ERR_clear_error();
chain = X509_STORE_CTX_get0_chain(xsc);
}
if (!CBB_add_u8_length_prefixed(cbb, &cert_request_context))
goto err;
if (!CBB_add_u24_length_prefixed(cbb, &cert_list))
@@ -643,10 +659,19 @@ tls13_server_certificate_send(struct tls13_ctx *ctx, CBB *cbb)
for (i = 0; i < sk_X509_num(chain); i++) {
cert = sk_X509_value(chain, i);
/*
* In the case of auto chain, the leaf certificate will be at
* the top of the chain - skip over it as we've already added
* it earlier.
*/
if (i == 0 && cert == cpk->x509)
continue;
/*
* XXX we don't send extensions with chain certs to avoid sending
* a leaf ocsp stape with the chain certs. This needs to get
* fixed
* a leaf ocsp staple with the chain certs. This needs to get
* fixed.
*/
if (!tls13_cert_add(ctx, &cert_list, cert, NULL))
goto err;
@@ -658,6 +683,8 @@ tls13_server_certificate_send(struct tls13_ctx *ctx, CBB *cbb)
ret = 1;
err:
X509_STORE_CTX_free(xsc);
return ret;
}
@@ -670,15 +697,15 @@ tls13_server_certificate_verify_send(struct tls13_ctx *ctx, CBB *cbb)
EVP_MD_CTX *mdctx = NULL;
EVP_PKEY_CTX *pctx;
EVP_PKEY *pkey;
const CERT_PKEY *cpk;
const SSL_CERT_PKEY *cpk;
CBB sig_cbb;
int ret = 0;
memset(&sig_cbb, 0, sizeof(sig_cbb));
if ((cpk = ctx->hs->cpk) == NULL)
if ((cpk = ctx->hs->tls13.cpk) == NULL)
goto err;
if ((sigalg = ctx->hs->sigalg) == NULL)
if ((sigalg = ctx->hs->our_sigalg) == NULL)
goto err;
pkey = cpk->privatekey;
@@ -692,8 +719,8 @@ tls13_server_certificate_verify_send(struct tls13_ctx *ctx, CBB *cbb)
goto err;
if (!CBB_add_u8(&sig_cbb, 0))
goto err;
if (!CBB_add_bytes(&sig_cbb, ctx->hs->transcript_hash,
ctx->hs->transcript_hash_len))
if (!CBB_add_bytes(&sig_cbb, ctx->hs->tls13.transcript_hash,
ctx->hs->tls13.transcript_hash_len))
goto err;
if (!CBB_finish(&sig_cbb, &sig_content, &sig_content_len))
goto err;
@@ -744,20 +771,20 @@ tls13_server_certificate_verify_send(struct tls13_ctx *ctx, CBB *cbb)
int
tls13_server_finished_send(struct tls13_ctx *ctx, CBB *cbb)
{
struct tls13_secrets *secrets = ctx->hs->secrets;
struct tls13_secrets *secrets = ctx->hs->tls13.secrets;
struct tls13_secret context = { .data = "", .len = 0 };
struct tls13_secret finished_key;
struct tls13_secret finished_key = { .data = NULL, .len = 0 } ;
uint8_t transcript_hash[EVP_MAX_MD_SIZE];
size_t transcript_hash_len;
uint8_t key[EVP_MAX_MD_SIZE];
uint8_t *verify_data;
size_t hmac_len;
size_t verify_data_len;
unsigned int hlen;
HMAC_CTX *hmac_ctx = NULL;
CBS cbs;
int ret = 0;
finished_key.data = key;
finished_key.len = EVP_MD_size(ctx->hash);
if (!tls13_secret_init(&finished_key, EVP_MD_size(ctx->hash)))
goto err;
if (!tls13_hkdf_expand_label(&finished_key, ctx->hash,
&secrets->server_handshake_traffic, "finished",
@@ -776,17 +803,23 @@ tls13_server_finished_send(struct tls13_ctx *ctx, CBB *cbb)
if (!HMAC_Update(hmac_ctx, transcript_hash, transcript_hash_len))
goto err;
hmac_len = HMAC_size(hmac_ctx);
if (!CBB_add_space(cbb, &verify_data, hmac_len))
verify_data_len = HMAC_size(hmac_ctx);
if (!CBB_add_space(cbb, &verify_data, verify_data_len))
goto err;
if (!HMAC_Final(hmac_ctx, verify_data, &hlen))
goto err;
if (hlen != hmac_len)
if (hlen != verify_data_len)
goto err;
CBS_init(&cbs, verify_data, verify_data_len);
if (!CBS_write_bytes(&cbs, ctx->hs->finished,
sizeof(ctx->hs->finished), &ctx->hs->finished_len))
goto err;
ret = 1;
err:
tls13_secret_cleanup(&finished_key);
HMAC_CTX_free(hmac_ctx);
return ret;
@@ -795,14 +828,14 @@ tls13_server_finished_send(struct tls13_ctx *ctx, CBB *cbb)
int
tls13_server_finished_sent(struct tls13_ctx *ctx)
{
struct tls13_secrets *secrets = ctx->hs->secrets;
struct tls13_secrets *secrets = ctx->hs->tls13.secrets;
struct tls13_secret context = { .data = "", .len = 0 };
/*
* Derive application traffic keys.
*/
context.data = ctx->hs->transcript_hash;
context.len = ctx->hs->transcript_hash_len;
context.data = ctx->hs->tls13.transcript_hash;
context.len = ctx->hs->tls13.transcript_hash_len;
if (!tls13_derive_application_secrets(secrets, &context))
return 0;
@@ -824,7 +857,7 @@ tls13_client_certificate_recv(struct tls13_ctx *ctx, CBS *cbs)
X509 *cert = NULL;
EVP_PKEY *pkey;
const uint8_t *p;
int cert_idx;
int cert_type;
int ret = 0;
if (!CBS_get_u8_length_prefixed(cbs, &cert_request_context))
@@ -875,33 +908,30 @@ tls13_client_certificate_recv(struct tls13_ctx *ctx, CBS *cbs)
}
ERR_clear_error();
cert = sk_X509_value(certs, 0);
X509_up_ref(cert);
/*
* Achtung! Due to API inconsistency, a client includes the peer's leaf
* certificate in the stored certificate chain, while a server does not.
*/
cert = sk_X509_shift(certs);
if ((pkey = X509_get0_pubkey(cert)) == NULL)
goto err;
if (EVP_PKEY_missing_parameters(pkey))
goto err;
if ((cert_idx = ssl_cert_type(cert, pkey)) < 0)
if ((cert_type = ssl_cert_type(pkey)) < 0)
goto err;
ssl_sess_cert_free(SSI(s)->sess_cert);
if ((SSI(s)->sess_cert = ssl_sess_cert_new()) == NULL)
goto err;
SSI(s)->sess_cert->cert_chain = certs;
certs = NULL;
X509_up_ref(cert);
SSI(s)->sess_cert->peer_pkeys[cert_idx].x509 = cert;
SSI(s)->sess_cert->peer_key = &(SSI(s)->sess_cert->peer_pkeys[cert_idx]);
X509_free(s->session->peer_cert);
s->session->peer_cert = cert;
s->session->peer_cert_type = cert_type;
X509_free(s->session->peer);
X509_up_ref(cert);
s->session->peer = cert;
s->session->verify_result = s->verify_result;
sk_X509_pop_free(s->session->cert_chain, X509_free);
s->session->cert_chain = certs;
certs = NULL;
ctx->handshake_stage.hs_type |= WITH_CCV;
ret = 1;
@@ -934,10 +964,6 @@ tls13_client_certificate_verify_recv(struct tls13_ctx *ctx, CBS *cbs)
if (!CBS_get_u16_length_prefixed(cbs, &signature))
goto err;
if ((sigalg = ssl_sigalg(signature_scheme, tls13_sigalgs,
tls13_sigalgs_len)) == NULL)
goto err;
if (!CBB_init(&cbb, 0))
goto err;
if (!CBB_add_bytes(&cbb, tls13_cert_verify_pad,
@@ -948,18 +974,20 @@ tls13_client_certificate_verify_recv(struct tls13_ctx *ctx, CBS *cbs)
goto err;
if (!CBB_add_u8(&cbb, 0))
goto err;
if (!CBB_add_bytes(&cbb, ctx->hs->transcript_hash,
ctx->hs->transcript_hash_len))
if (!CBB_add_bytes(&cbb, ctx->hs->tls13.transcript_hash,
ctx->hs->tls13.transcript_hash_len))
goto err;
if (!CBB_finish(&cbb, &sig_content, &sig_content_len))
goto err;
if ((cert = ctx->ssl->session->peer) == NULL)
if ((cert = ctx->ssl->session->peer_cert) == NULL)
goto err;
if ((pkey = X509_get0_pubkey(cert)) == NULL)
goto err;
if (!ssl_sigalg_pkey_ok(sigalg, pkey, 1))
if ((sigalg = ssl_sigalg_for_peer(ctx->ssl, pkey,
signature_scheme)) == NULL)
goto err;
ctx->hs->peer_sigalg = sigalg;
if (CBS_len(&signature) > EVP_PKEY_size(pkey))
goto err;
@@ -1006,7 +1034,7 @@ tls13_client_end_of_early_data_recv(struct tls13_ctx *ctx, CBS *cbs)
int
tls13_client_finished_recv(struct tls13_ctx *ctx, CBS *cbs)
{
struct tls13_secrets *secrets = ctx->hs->secrets;
struct tls13_secrets *secrets = ctx->hs->tls13.secrets;
struct tls13_secret context = { .data = "", .len = 0 };
struct tls13_secret finished_key;
uint8_t *verify_data = NULL;
@@ -1032,8 +1060,8 @@ tls13_client_finished_recv(struct tls13_ctx *ctx, CBS *cbs)
if (!HMAC_Init_ex(hmac_ctx, finished_key.data, finished_key.len,
ctx->hash, NULL))
goto err;
if (!HMAC_Update(hmac_ctx, ctx->hs->transcript_hash,
ctx->hs->transcript_hash_len))
if (!HMAC_Update(hmac_ctx, ctx->hs->tls13.transcript_hash,
ctx->hs->tls13.transcript_hash_len))
goto err;
verify_data_len = HMAC_size(hmac_ctx);
if ((verify_data = calloc(1, verify_data_len)) == NULL)
@@ -1048,6 +1076,11 @@ tls13_client_finished_recv(struct tls13_ctx *ctx, CBS *cbs)
goto err;
}
if (!CBS_write_bytes(cbs, ctx->hs->peer_finished,
sizeof(ctx->hs->peer_finished),
&ctx->hs->peer_finished_len))
goto err;
if (!CBS_skip(cbs, verify_data_len))
goto err;

138
externals/libressl/ssl/tls_buffer.c vendored Executable file
View File

@@ -0,0 +1,138 @@
/* $OpenBSD: tls_buffer.c,v 1.1 2021/10/23 13:12:14 jsing Exp $ */
/*
* Copyright (c) 2018, 2019 Joel Sing <jsing@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <stdlib.h>
#include <string.h>
#include "bytestring.h"
#include "tls_internal.h"
struct tls_buffer {
size_t capacity;
uint8_t *data;
size_t len;
size_t offset;
};
static int tls_buffer_resize(struct tls_buffer *buf, size_t capacity);
struct tls_buffer *
tls_buffer_new(size_t init_size)
{
struct tls_buffer *buf = NULL;
if ((buf = calloc(1, sizeof(struct tls_buffer))) == NULL)
goto err;
if (!tls_buffer_resize(buf, init_size))
goto err;
return buf;
err:
tls_buffer_free(buf);
return NULL;
}
void
tls_buffer_free(struct tls_buffer *buf)
{
if (buf == NULL)
return;
freezero(buf->data, buf->capacity);
freezero(buf, sizeof(struct tls_buffer));
}
static int
tls_buffer_resize(struct tls_buffer *buf, size_t capacity)
{
uint8_t *data;
if (buf->capacity == capacity)
return 1;
if ((data = recallocarray(buf->data, buf->capacity, capacity, 1)) == NULL)
return 0;
buf->data = data;
buf->capacity = capacity;
return 1;
}
int
tls_buffer_set_data(struct tls_buffer *buf, CBS *data)
{
if (!tls_buffer_resize(buf, CBS_len(data)))
return 0;
memcpy(buf->data, CBS_data(data), CBS_len(data));
return 1;
}
ssize_t
tls_buffer_extend(struct tls_buffer *buf, size_t len,
tls_read_cb read_cb, void *cb_arg)
{
ssize_t ret;
if (len == buf->len)
return buf->len;
if (len < buf->len)
return TLS_IO_FAILURE;
if (!tls_buffer_resize(buf, len))
return TLS_IO_FAILURE;
for (;;) {
if ((ret = read_cb(&buf->data[buf->len],
buf->capacity - buf->len, cb_arg)) <= 0)
return ret;
if (ret > buf->capacity - buf->len)
return TLS_IO_FAILURE;
buf->len += ret;
if (buf->len == buf->capacity)
return buf->len;
}
}
void
tls_buffer_cbs(struct tls_buffer *buf, CBS *cbs)
{
CBS_init(cbs, buf->data, buf->len);
}
int
tls_buffer_finish(struct tls_buffer *buf, uint8_t **out, size_t *out_len)
{
if (out == NULL || out_len == NULL)
return 0;
*out = buf->data;
*out_len = buf->len;
buf->capacity = 0;
buf->data = NULL;
buf->len = 0;
return 1;
}

149
externals/libressl/ssl/tls_content.c vendored Executable file
View File

@@ -0,0 +1,149 @@
/* $OpenBSD: tls_content.c,v 1.1 2021/09/04 16:26:12 jsing Exp $ */
/*
* Copyright (c) 2020 Joel Sing <jsing@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <stdlib.h>
#include <string.h>
#include "tls_content.h"
/* Content from a TLS record. */
struct tls_content {
uint8_t type;
uint16_t epoch;
const uint8_t *data;
size_t len;
CBS cbs;
};
struct tls_content *
tls_content_new(void)
{
return calloc(1, sizeof(struct tls_content));
}
void
tls_content_clear(struct tls_content *content)
{
freezero((void *)content->data, content->len);
memset(content, 0, sizeof(*content));
}
void
tls_content_free(struct tls_content *content)
{
if (content == NULL)
return;
tls_content_clear(content);
freezero(content, sizeof(struct tls_content));
}
CBS *
tls_content_cbs(struct tls_content *content)
{
return &content->cbs;
}
int
tls_content_equal(struct tls_content *content, const uint8_t *buf, size_t n)
{
return CBS_mem_equal(&content->cbs, buf, n);
}
size_t
tls_content_remaining(struct tls_content *content)
{
return CBS_len(&content->cbs);
}
uint8_t
tls_content_type(struct tls_content *content)
{
return content->type;
}
int
tls_content_dup_data(struct tls_content *content, uint8_t type,
const uint8_t *data, size_t data_len)
{
uint8_t *dup;
if ((dup = calloc(1, data_len)) == NULL)
return 0;
memcpy(dup, data, data_len);
tls_content_set_data(content, type, dup, data_len);
return 1;
}
uint16_t
tls_content_epoch(struct tls_content *content)
{
return content->epoch;
}
void
tls_content_set_epoch(struct tls_content *content, uint16_t epoch)
{
content->epoch = epoch;
}
void
tls_content_set_data(struct tls_content *content, uint8_t type,
const uint8_t *data, size_t data_len)
{
tls_content_clear(content);
content->type = type;
content->data = data;
content->len = data_len;
CBS_init(&content->cbs, content->data, content->len);
}
static ssize_t
tls_content_read_internal(struct tls_content *content, uint8_t *buf, size_t n,
int peek)
{
if (n > CBS_len(&content->cbs))
n = CBS_len(&content->cbs);
/* XXX - CBS_memcpy? CBS_copy_bytes? */
memcpy(buf, CBS_data(&content->cbs), n);
if (!peek) {
if (!CBS_skip(&content->cbs, n))
return -1;
}
return n;
}
ssize_t
tls_content_peek(struct tls_content *content, uint8_t *buf, size_t n)
{
return tls_content_read_internal(content, buf, n, 1);
}
ssize_t
tls_content_read(struct tls_content *content, uint8_t *buf, size_t n)
{
return tls_content_read_internal(content, buf, n, 0);
}

48
externals/libressl/ssl/tls_content.h vendored Executable file
View File

@@ -0,0 +1,48 @@
/* $OpenBSD: tls_content.h,v 1.1 2021/09/04 16:26:12 jsing Exp $ */
/*
* Copyright (c) 2020 Joel Sing <jsing@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef HEADER_TLS_CONTENT_H
#define HEADER_TLS_CONTENT_H
#include "bytestring.h"
__BEGIN_HIDDEN_DECLS
struct tls_content;
struct tls_content *tls_content_new(void);
void tls_content_clear(struct tls_content *content);
void tls_content_free(struct tls_content *content);
CBS *tls_content_cbs(struct tls_content *content);
int tls_content_equal(struct tls_content *content, const uint8_t *buf, size_t n);
size_t tls_content_remaining(struct tls_content *content);
uint8_t tls_content_type(struct tls_content *content);
uint16_t tls_content_epoch(struct tls_content *content);
int tls_content_dup_data(struct tls_content *content, uint8_t type,
const uint8_t *data, size_t data_len);
void tls_content_set_data(struct tls_content *content, uint8_t type,
const uint8_t *data, size_t data_len);
void tls_content_set_epoch(struct tls_content *content, uint16_t epoch);
ssize_t tls_content_peek(struct tls_content *content, uint8_t *buf, size_t n);
ssize_t tls_content_read(struct tls_content *content, uint8_t *buf, size_t n);
__END_HIDDEN_DECLS
#endif

83
externals/libressl/ssl/tls_internal.h vendored Executable file
View File

@@ -0,0 +1,83 @@
/* $OpenBSD: tls_internal.h,v 1.5 2022/01/11 18:28:41 jsing Exp $ */
/*
* Copyright (c) 2018, 2019, 2021 Joel Sing <jsing@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef HEADER_TLS_INTERNAL_H
#define HEADER_TLS_INTERNAL_H
#include <openssl/dh.h>
#include <openssl/evp.h>
#include "bytestring.h"
__BEGIN_HIDDEN_DECLS
#define TLS_IO_SUCCESS 1
#define TLS_IO_EOF 0
#define TLS_IO_FAILURE -1
#define TLS_IO_ALERT -2
#define TLS_IO_WANT_POLLIN -3
#define TLS_IO_WANT_POLLOUT -4
#define TLS_IO_WANT_RETRY -5 /* Retry the previous call immediately. */
/*
* Callbacks.
*/
typedef ssize_t (*tls_read_cb)(void *_buf, size_t _buflen, void *_cb_arg);
typedef ssize_t (*tls_write_cb)(const void *_buf, size_t _buflen,
void *_cb_arg);
typedef ssize_t (*tls_flush_cb)(void *_cb_arg);
/*
* Buffers.
*/
struct tls_buffer;
struct tls_buffer *tls_buffer_new(size_t init_size);
int tls_buffer_set_data(struct tls_buffer *buf, CBS *data);
void tls_buffer_free(struct tls_buffer *buf);
ssize_t tls_buffer_extend(struct tls_buffer *buf, size_t len,
tls_read_cb read_cb, void *cb_arg);
void tls_buffer_cbs(struct tls_buffer *buf, CBS *cbs);
int tls_buffer_finish(struct tls_buffer *buf, uint8_t **out, size_t *out_len);
/*
* Key shares.
*/
struct tls_key_share;
struct tls_key_share *tls_key_share_new(uint16_t group_id);
struct tls_key_share *tls_key_share_new_nid(int nid);
void tls_key_share_free(struct tls_key_share *ks);
uint16_t tls_key_share_group(struct tls_key_share *ks);
int tls_key_share_nid(struct tls_key_share *ks);
void tls_key_share_set_key_bits(struct tls_key_share *ks, size_t key_bits);
int tls_key_share_set_dh_params(struct tls_key_share *ks, DH *dh_params);
int tls_key_share_peer_pkey(struct tls_key_share *ks, EVP_PKEY *pkey);
int tls_key_share_generate(struct tls_key_share *ks);
int tls_key_share_params(struct tls_key_share *ks, CBB *cbb);
int tls_key_share_public(struct tls_key_share *ks, CBB *cbb);
int tls_key_share_peer_params(struct tls_key_share *ks, CBS *cbs,
int *decode_error, int *invalid_params);
int tls_key_share_peer_public(struct tls_key_share *ks, CBS *cbs,
int *decode_error, int *invalid_key);
int tls_key_share_derive(struct tls_key_share *ks, uint8_t **shared_key,
size_t *shared_key_len);
__END_HIDDEN_DECLS
#endif

473
externals/libressl/ssl/tls_key_share.c vendored Executable file
View File

@@ -0,0 +1,473 @@
/* $OpenBSD: tls_key_share.c,v 1.4 2022/01/11 18:28:41 jsing Exp $ */
/*
* Copyright (c) 2020, 2021 Joel Sing <jsing@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <stdlib.h>
#include <openssl/curve25519.h>
#include <openssl/dh.h>
#include <openssl/ec.h>
#include <openssl/evp.h>
#include "bytestring.h"
#include "ssl_locl.h"
#include "tls_internal.h"
struct tls_key_share {
int nid;
uint16_t group_id;
size_t key_bits;
DH *dhe;
DH *dhe_peer;
EC_KEY *ecdhe;
EC_KEY *ecdhe_peer;
uint8_t *x25519_public;
uint8_t *x25519_private;
uint8_t *x25519_peer_public;
};
static struct tls_key_share *
tls_key_share_new_internal(int nid, uint16_t group_id)
{
struct tls_key_share *ks;
if ((ks = calloc(1, sizeof(struct tls_key_share))) == NULL)
return NULL;
ks->group_id = group_id;
ks->nid = nid;
return ks;
}
struct tls_key_share *
tls_key_share_new(uint16_t group_id)
{
int nid;
if ((nid = tls1_ec_curve_id2nid(group_id)) == 0)
return NULL;
return tls_key_share_new_internal(nid, group_id);
}
struct tls_key_share *
tls_key_share_new_nid(int nid)
{
uint16_t group_id = 0;
if (nid != NID_dhKeyAgreement) {
if ((group_id = tls1_ec_nid2curve_id(nid)) == 0)
return NULL;
}
return tls_key_share_new_internal(nid, group_id);
}
void
tls_key_share_free(struct tls_key_share *ks)
{
if (ks == NULL)
return;
DH_free(ks->dhe);
DH_free(ks->dhe_peer);
EC_KEY_free(ks->ecdhe);
EC_KEY_free(ks->ecdhe_peer);
freezero(ks->x25519_public, X25519_KEY_LENGTH);
freezero(ks->x25519_private, X25519_KEY_LENGTH);
freezero(ks->x25519_peer_public, X25519_KEY_LENGTH);
freezero(ks, sizeof(*ks));
}
uint16_t
tls_key_share_group(struct tls_key_share *ks)
{
return ks->group_id;
}
int
tls_key_share_nid(struct tls_key_share *ks)
{
return ks->nid;
}
void
tls_key_share_set_key_bits(struct tls_key_share *ks, size_t key_bits)
{
ks->key_bits = key_bits;
}
int
tls_key_share_set_dh_params(struct tls_key_share *ks, DH *dh_params)
{
if (ks->nid != NID_dhKeyAgreement)
return 0;
if (ks->dhe != NULL || ks->dhe_peer != NULL)
return 0;
if ((ks->dhe = DHparams_dup(dh_params)) == NULL)
return 0;
if ((ks->dhe_peer = DHparams_dup(dh_params)) == NULL)
return 0;
return 1;
}
int
tls_key_share_peer_pkey(struct tls_key_share *ks, EVP_PKEY *pkey)
{
if (ks->nid == NID_dhKeyAgreement && ks->dhe_peer != NULL)
return EVP_PKEY_set1_DH(pkey, ks->dhe_peer);
if (ks->nid == NID_X25519 && ks->x25519_peer_public != NULL)
return ssl_kex_dummy_ecdhe_x25519(pkey);
if (ks->ecdhe_peer != NULL)
return EVP_PKEY_set1_EC_KEY(pkey, ks->ecdhe_peer);
return 0;
}
static int
tls_key_share_generate_dhe(struct tls_key_share *ks)
{
/*
* If auto params are not being used then we must already have DH
* parameters set.
*/
if (ks->key_bits == 0) {
if (ks->dhe == NULL)
return 0;
return ssl_kex_generate_dhe(ks->dhe, ks->dhe);
}
if (ks->dhe != NULL || ks->dhe_peer != NULL)
return 0;
if ((ks->dhe = DH_new()) == NULL)
return 0;
if (!ssl_kex_generate_dhe_params_auto(ks->dhe, ks->key_bits))
return 0;
if ((ks->dhe_peer = DHparams_dup(ks->dhe)) == NULL)
return 0;
return 1;
}
static int
tls_key_share_generate_ecdhe_ecp(struct tls_key_share *ks)
{
EC_KEY *ecdhe = NULL;
int ret = 0;
if (ks->ecdhe != NULL)
goto err;
if ((ecdhe = EC_KEY_new()) == NULL)
goto err;
if (!ssl_kex_generate_ecdhe_ecp(ecdhe, ks->nid))
goto err;
ks->ecdhe = ecdhe;
ecdhe = NULL;
ret = 1;
err:
EC_KEY_free(ecdhe);
return ret;
}
static int
tls_key_share_generate_x25519(struct tls_key_share *ks)
{
uint8_t *public = NULL, *private = NULL;
int ret = 0;
if (ks->x25519_public != NULL || ks->x25519_private != NULL)
goto err;
if ((public = calloc(1, X25519_KEY_LENGTH)) == NULL)
goto err;
if ((private = calloc(1, X25519_KEY_LENGTH)) == NULL)
goto err;
X25519_keypair(public, private);
ks->x25519_public = public;
ks->x25519_private = private;
public = NULL;
private = NULL;
ret = 1;
err:
freezero(public, X25519_KEY_LENGTH);
freezero(private, X25519_KEY_LENGTH);
return ret;
}
int
tls_key_share_generate(struct tls_key_share *ks)
{
if (ks->nid == NID_dhKeyAgreement)
return tls_key_share_generate_dhe(ks);
if (ks->nid == NID_X25519)
return tls_key_share_generate_x25519(ks);
return tls_key_share_generate_ecdhe_ecp(ks);
}
static int
tls_key_share_params_dhe(struct tls_key_share *ks, CBB *cbb)
{
if (ks->dhe == NULL)
return 0;
return ssl_kex_params_dhe(ks->dhe, cbb);
}
int
tls_key_share_params(struct tls_key_share *ks, CBB *cbb)
{
if (ks->nid == NID_dhKeyAgreement)
return tls_key_share_params_dhe(ks, cbb);
return 0;
}
static int
tls_key_share_public_dhe(struct tls_key_share *ks, CBB *cbb)
{
if (ks->dhe == NULL)
return 0;
return ssl_kex_public_dhe(ks->dhe, cbb);
}
static int
tls_key_share_public_ecdhe_ecp(struct tls_key_share *ks, CBB *cbb)
{
if (ks->ecdhe == NULL)
return 0;
return ssl_kex_public_ecdhe_ecp(ks->ecdhe, cbb);
}
static int
tls_key_share_public_x25519(struct tls_key_share *ks, CBB *cbb)
{
if (ks->x25519_public == NULL)
return 0;
return CBB_add_bytes(cbb, ks->x25519_public, X25519_KEY_LENGTH);
}
int
tls_key_share_public(struct tls_key_share *ks, CBB *cbb)
{
if (ks->nid == NID_dhKeyAgreement)
return tls_key_share_public_dhe(ks, cbb);
if (ks->nid == NID_X25519)
return tls_key_share_public_x25519(ks, cbb);
return tls_key_share_public_ecdhe_ecp(ks, cbb);
}
static int
tls_key_share_peer_params_dhe(struct tls_key_share *ks, CBS *cbs,
int *decode_error, int *invalid_params)
{
if (ks->dhe != NULL || ks->dhe_peer != NULL)
return 0;
if ((ks->dhe_peer = DH_new()) == NULL)
return 0;
if (!ssl_kex_peer_params_dhe(ks->dhe_peer, cbs, decode_error,
invalid_params))
return 0;
if ((ks->dhe = DHparams_dup(ks->dhe_peer)) == NULL)
return 0;
return 1;
}
int
tls_key_share_peer_params(struct tls_key_share *ks, CBS *cbs,
int *decode_error, int *invalid_params)
{
if (ks->nid != NID_dhKeyAgreement)
return 0;
return tls_key_share_peer_params_dhe(ks, cbs, decode_error,
invalid_params);
}
static int
tls_key_share_peer_public_dhe(struct tls_key_share *ks, CBS *cbs,
int *decode_error, int *invalid_key)
{
if (ks->dhe_peer == NULL)
return 0;
return ssl_kex_peer_public_dhe(ks->dhe_peer, cbs, decode_error,
invalid_key);
}
static int
tls_key_share_peer_public_ecdhe_ecp(struct tls_key_share *ks, CBS *cbs)
{
EC_KEY *ecdhe = NULL;
int ret = 0;
if (ks->ecdhe_peer != NULL)
goto err;
if ((ecdhe = EC_KEY_new()) == NULL)
goto err;
if (!ssl_kex_peer_public_ecdhe_ecp(ecdhe, ks->nid, cbs))
goto err;
ks->ecdhe_peer = ecdhe;
ecdhe = NULL;
ret = 1;
err:
EC_KEY_free(ecdhe);
return ret;
}
static int
tls_key_share_peer_public_x25519(struct tls_key_share *ks, CBS *cbs,
int *decode_error)
{
size_t out_len;
*decode_error = 0;
if (ks->x25519_peer_public != NULL)
return 0;
if (CBS_len(cbs) != X25519_KEY_LENGTH) {
*decode_error = 1;
return 0;
}
return CBS_stow(cbs, &ks->x25519_peer_public, &out_len);
}
int
tls_key_share_peer_public(struct tls_key_share *ks, CBS *cbs, int *decode_error,
int *invalid_key)
{
*decode_error = 0;
if (invalid_key != NULL)
*invalid_key = 0;
if (ks->nid == NID_dhKeyAgreement)
return tls_key_share_peer_public_dhe(ks, cbs, decode_error,
invalid_key);
if (ks->nid == NID_X25519)
return tls_key_share_peer_public_x25519(ks, cbs, decode_error);
return tls_key_share_peer_public_ecdhe_ecp(ks, cbs);
}
static int
tls_key_share_derive_dhe(struct tls_key_share *ks,
uint8_t **shared_key, size_t *shared_key_len)
{
if (ks->dhe == NULL || ks->dhe_peer == NULL)
return 0;
return ssl_kex_derive_dhe(ks->dhe, ks->dhe_peer, shared_key,
shared_key_len);
}
static int
tls_key_share_derive_ecdhe_ecp(struct tls_key_share *ks,
uint8_t **shared_key, size_t *shared_key_len)
{
if (ks->ecdhe == NULL || ks->ecdhe_peer == NULL)
return 0;
return ssl_kex_derive_ecdhe_ecp(ks->ecdhe, ks->ecdhe_peer,
shared_key, shared_key_len);
}
static int
tls_key_share_derive_x25519(struct tls_key_share *ks,
uint8_t **shared_key, size_t *shared_key_len)
{
uint8_t *sk = NULL;
int ret = 0;
if (ks->x25519_private == NULL || ks->x25519_peer_public == NULL)
goto err;
if ((sk = calloc(1, X25519_KEY_LENGTH)) == NULL)
goto err;
if (!X25519(sk, ks->x25519_private, ks->x25519_peer_public))
goto err;
*shared_key = sk;
*shared_key_len = X25519_KEY_LENGTH;
sk = NULL;
ret = 1;
err:
freezero(sk, X25519_KEY_LENGTH);
return ret;
}
int
tls_key_share_derive(struct tls_key_share *ks, uint8_t **shared_key,
size_t *shared_key_len)
{
if (*shared_key != NULL)
return 0;
*shared_key_len = 0;
if (ks->nid == NID_dhKeyAgreement)
return tls_key_share_derive_dhe(ks, shared_key,
shared_key_len);
if (ks->nid == NID_X25519)
return tls_key_share_derive_x25519(ks, shared_key,
shared_key_len);
return tls_key_share_derive_ecdhe_ecp(ks, shared_key,
shared_key_len);
}