early-access version 2698

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

View File

@@ -1,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;
}