summaryrefslogtreecommitdiffstats
path: root/lib/libssl/tls13_client.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libssl/tls13_client.c')
-rw-r--r--lib/libssl/tls13_client.c131
1 files changed, 130 insertions, 1 deletions
diff --git a/lib/libssl/tls13_client.c b/lib/libssl/tls13_client.c
index d15ab65105e..b3209c063cb 100644
--- a/lib/libssl/tls13_client.c
+++ b/lib/libssl/tls13_client.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tls13_client.c,v 1.6 2019/02/11 17:48:15 jsing Exp $ */
+/* $OpenBSD: tls13_client.c,v 1.7 2019/02/13 16:28:28 jsing Exp $ */
/*
* Copyright (c) 2018, 2019 Joel Sing <jsing@openbsd.org>
*
@@ -555,3 +555,132 @@ tls13_server_certificate_verify_recv(struct tls13_ctx *ctx)
return ret;
}
+
+int
+tls13_server_finished_recv(struct tls13_ctx *ctx)
+{
+ struct tls13_secrets *secrets = ctx->hs->secrets;
+ struct tls13_secret context = { .data = "", .len = 0 };
+ struct tls13_secret finished_key;
+ uint8_t transcript_hash[EVP_MAX_MD_SIZE];
+ size_t transcript_hash_len;
+ uint8_t *verify_data = NULL;
+ size_t verify_data_len;
+ uint8_t key[EVP_MAX_MD_SIZE];
+ HMAC_CTX *hmac_ctx = NULL;
+ unsigned int hlen;
+ int ret = 0;
+ CBS cbs;
+
+ if (!tls13_handshake_msg_content(ctx->hs_msg, &cbs))
+ goto err;
+
+ /*
+ * Verify server finished.
+ */
+ finished_key.data = key;
+ finished_key.len = EVP_MD_size(ctx->hash);
+
+ if (!tls13_hkdf_expand_label(&finished_key, ctx->hash,
+ &secrets->server_handshake_traffic, "finished",
+ &context))
+ goto err;
+
+ if ((hmac_ctx = HMAC_CTX_new()) == NULL)
+ goto err;
+ 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))
+ goto err;
+ verify_data_len = HMAC_size(hmac_ctx);
+ if ((verify_data = calloc(1, verify_data_len)) == NULL)
+ goto err;
+ if (!HMAC_Final(hmac_ctx, verify_data, &hlen))
+ goto err;
+ if (hlen != verify_data_len)
+ goto err;
+
+ if (!CBS_mem_equal(&cbs, verify_data, verify_data_len)) {
+ /* XXX - send alert. */
+ goto err;
+ }
+
+ /*
+ * Derive application traffic keys.
+ */
+ if (!tls1_transcript_hash_value(ctx->ssl, transcript_hash,
+ sizeof(transcript_hash), &transcript_hash_len))
+ goto err;
+
+ context.data = transcript_hash;
+ context.len = transcript_hash_len;
+
+ if (!tls13_derive_application_secrets(secrets, &context))
+ return TLS13_IO_FAILURE;
+
+ ret = 1;
+
+ err:
+ HMAC_CTX_free(hmac_ctx);
+ free(verify_data);
+
+ return ret;
+}
+
+int
+tls13_client_finished_send(struct tls13_ctx *ctx)
+{
+ struct tls13_secrets *secrets = ctx->hs->secrets;
+ struct tls13_secret context = { .data = "", .len = 0 };
+ struct tls13_secret finished_key;
+ 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;
+ unsigned int hlen;
+ HMAC_CTX *hmac_ctx = NULL;
+ int ret = 0;
+ CBB body;
+
+ finished_key.data = key;
+ finished_key.len = EVP_MD_size(ctx->hash);
+
+ if (!tls13_hkdf_expand_label(&finished_key, ctx->hash,
+ &secrets->client_handshake_traffic, "finished",
+ &context))
+ goto err;
+
+ if (!tls1_transcript_hash_value(ctx->ssl, transcript_hash,
+ sizeof(transcript_hash), &transcript_hash_len))
+ goto err;
+
+ if ((hmac_ctx = HMAC_CTX_new()) == NULL)
+ goto err;
+ if (!HMAC_Init_ex(hmac_ctx, finished_key.data, finished_key.len,
+ ctx->hash, NULL))
+ goto err;
+ if (!HMAC_Update(hmac_ctx, transcript_hash, transcript_hash_len))
+ goto err;
+
+ if (!tls13_handshake_msg_start(ctx->hs_msg, &body, TLS13_MT_FINISHED))
+ goto err;
+ hmac_len = HMAC_size(hmac_ctx);
+ if (!CBB_add_space(&body, &verify_data, hmac_len))
+ goto err;
+ if (!HMAC_Final(hmac_ctx, verify_data, &hlen))
+ goto err;
+ if (hlen != hmac_len)
+ goto err;
+ if (!tls13_handshake_msg_finish(ctx->hs_msg))
+ goto err;
+
+ ret = 1;
+
+ err:
+ HMAC_CTX_free(hmac_ctx);
+
+ return ret;
+}