From e08d5914dd7e1ea431a3e55853f9527ced7e5e8a Mon Sep 17 00:00:00 2001 From: Joel Sing Date: Sat, 9 May 2020 10:51:56 +0000 Subject: Add support for HelloRetryRequests in the TLSv1.3 server. ok inoguchi@ tb@ --- lib/libssl/ssl_tlsext.c | 34 ++++++++++++++++++++++++++++++-- lib/libssl/tls13_server.c | 49 +++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 73 insertions(+), 10 deletions(-) (limited to 'lib/libssl') diff --git a/lib/libssl/ssl_tlsext.c b/lib/libssl/ssl_tlsext.c index a0e2f7320bd..cb2b2cadc74 100644 --- a/lib/libssl/ssl_tlsext.c +++ b/lib/libssl/ssl_tlsext.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssl_tlsext.c,v 1.63 2020/04/21 17:06:16 jsing Exp $ */ +/* $OpenBSD: ssl_tlsext.c,v 1.64 2020/05/09 10:51:55 jsing Exp $ */ /* * Copyright (c) 2016, 2017, 2019 Joel Sing * Copyright (c) 2017 Doug Hogan @@ -222,6 +222,31 @@ tlsext_supportedgroups_server_parse(SSL *s, CBS *cbs, int *alert) uint16_t *groups; int i; + if (SSI(s)->tlsext_supportedgroups != NULL) { + /* + * We should only end up here in the case of a TLSv1.3 + * HelloRetryRequest... and the client cannot change + * supported groups. + */ + /* XXX - we should know this is a HRR. */ + if (groups_len != SSI(s)->tlsext_supportedgroups_length) { + *alert = SSL_AD_ILLEGAL_PARAMETER; + return 0; + } + for (i = 0; i < groups_len; i++) { + uint16_t group; + + if (!CBS_get_u16(&grouplist, &group)) + goto err; + if (SSI(s)->tlsext_supportedgroups[i] != group) { + *alert = SSL_AD_ILLEGAL_PARAMETER; + return 0; + } + } + + return 1; + } + if (SSI(s)->tlsext_supportedgroups != NULL) goto err; @@ -672,7 +697,7 @@ tlsext_sni_server_parse(SSL *s, CBS *cbs, int *alert) return 0; } - if (s->internal->hit) { + if (s->internal->hit || S3I(s)->hs_tls13.hrr) { if (s->session->tlsext_hostname == NULL) { *alert = TLS1_AD_UNRECOGNIZED_NAME; return 0; @@ -1333,6 +1358,11 @@ tlsext_keyshare_server_needs(SSL *s) int tlsext_keyshare_server_build(SSL *s, CBB *cbb) { + /* In the case of a HRR, we only send the server selected group. */ + /* XXX - we should know this is a HRR. */ + if (S3I(s)->hs_tls13.server_group != 0) + return CBB_add_u16(cbb, S3I(s)->hs_tls13.server_group); + if (S3I(s)->hs_tls13.key_share == NULL) return 0; diff --git a/lib/libssl/tls13_server.c b/lib/libssl/tls13_server.c index 029dd7211b4..313c5026d02 100644 --- a/lib/libssl/tls13_server.c +++ b/lib/libssl/tls13_server.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tls13_server.c,v 1.36 2020/05/09 10:17:58 tb Exp $ */ +/* $OpenBSD: tls13_server.c,v 1.37 2020/05/09 10:51:55 jsing Exp $ */ /* * Copyright (c) 2019, 2020 Joel Sing * Copyright (c) 2020 Bob Beck @@ -210,17 +210,25 @@ tls13_client_hello_recv(struct tls13_ctx *ctx, CBS *cbs) } static int -tls13_server_hello_build(struct tls13_ctx *ctx, CBB *cbb) +tls13_server_hello_build(struct tls13_ctx *ctx, CBB *cbb, int hrr) { + uint16_t tlsext_msg_type = SSL_TLSEXT_MSG_SH; + const uint8_t *server_random; CBB session_id; SSL *s = ctx->ssl; uint16_t cipher; cipher = SSL_CIPHER_get_value(S3I(s)->hs.new_cipher); + server_random = s->s3->server_random; + + if (hrr) { + server_random = tls13_hello_retry_request_hash; + tlsext_msg_type = SSL_TLSEXT_MSG_HRR; + } if (!CBB_add_u16(cbb, TLS1_2_VERSION)) goto err; - if (!CBB_add_bytes(cbb, s->s3->server_random, SSL3_RANDOM_SIZE)) + if (!CBB_add_bytes(cbb, server_random, SSL3_RANDOM_SIZE)) goto err; if (!CBB_add_u8_length_prefixed(cbb, &session_id)) goto err; @@ -231,7 +239,7 @@ tls13_server_hello_build(struct tls13_ctx *ctx, CBB *cbb) goto err; if (!CBB_add_u8(cbb, 0)) goto err; - if (!tlsext_server_build(s, cbb, SSL_TLSEXT_MSG_SH)) + if (!tlsext_server_build(s, cbb, tlsext_msg_type)) goto err; if (!CBB_flush(cbb)) @@ -313,13 +321,37 @@ tls13_server_engage_record_protection(struct tls13_ctx *ctx) int tls13_server_hello_retry_request_send(struct tls13_ctx *ctx, CBB *cbb) { - return 0; + int nid; + + if (!tls13_synthetic_handshake_message(ctx)) + return 0; + + if (ctx->hs->key_share != NULL) + 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) + return 0; + + if (!tls13_server_hello_build(ctx, cbb, 1)) + return 0; + + return 1; } int tls13_client_hello_retry_recv(struct tls13_ctx *ctx, CBS *cbs) { - return 0; + SSL *s = ctx->ssl; + + if (!tls13_client_hello_process(ctx, cbs)) + return 0; + + /* XXX - need further checks. */ + if (s->method->internal->version < TLS1_3_VERSION) + return 0; + + return 1; } int @@ -327,11 +359,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)) return 0; - if (!tls13_server_hello_build(ctx, cbb)) + ctx->hs->server_group = 0; + + if (!tls13_server_hello_build(ctx, cbb, 0)) return 0; return 1; -- cgit v1.2.3