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
+34 -9
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()
+1 -1
View File
@@ -1 +1 @@
48:1:0
52:0:0
+9 -8
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);
}
+3 -4
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"
/*
+17 -5
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)
{
+113 -6
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)
+51 -4
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
+127 -175
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++);
}
+44 -76
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);
}
+394 -695
View File
File diff suppressed because it is too large Load Diff
+26 -15
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
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
+25 -26
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;
}
+206 -219
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;
}
+5 -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);
+38
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
+2 -2
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());
+12 -16
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))
+116 -181
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);
}
+67 -108
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);
+35 -5
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)
{
+22 -34
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,
},
{
+690 -925
View File
File diff suppressed because it is too large Load Diff
+4 -2
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);
}
+252 -11
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;
}
+484 -264
View File
File diff suppressed because it is too large Load Diff
+490 -399
View File
File diff suppressed because it is too large Load Diff
+353 -515
View File
File diff suppressed because it is too large Load Diff
+7 -8
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;
}
+545 -603
View File
File diff suppressed because it is too large Load Diff
+84 -64
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);
}
+50 -42
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;
}
}
+130 -112
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;
}
+7 -15
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
+632 -813
View File
File diff suppressed because it is too large Load Diff
+63 -75
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:
+285 -261
View File
File diff suppressed because it is too large Load Diff
+3 -3
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
+30 -27
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;
}
+4 -4
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);
}
+214 -80
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;
}
+93 -787
View File
File diff suppressed because it is too large Load Diff
+17 -31
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
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
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
+116 -114
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
+222 -16
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;
}
+9 -10
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;
+30 -40
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];
+83 -80
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)
+115 -76
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;
+101 -38
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;
}
+10 -12
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;
+3 -4
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
+144 -150
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;
+131 -98
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
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
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
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
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
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);
}