summaryrefslogtreecommitdiff
path: root/lib/libssl/tls13_server.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libssl/tls13_server.c')
-rw-r--r--lib/libssl/tls13_server.c449
1 files changed, 221 insertions, 228 deletions
diff --git a/lib/libssl/tls13_server.c b/lib/libssl/tls13_server.c
index 16c2e32dbab..864e434fda0 100644
--- a/lib/libssl/tls13_server.c
+++ b/lib/libssl/tls13_server.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tls13_server.c,v 1.32 2020/04/25 18:06:28 jsing Exp $ */
+/* $OpenBSD: tls13_server.c,v 1.33 2020/04/27 20:15:17 jsing Exp $ */
/*
* Copyright (c) 2019, 2020 Joel Sing <jsing@openbsd.org>
* Copyright (c) 2020 Bob Beck <beck@openbsd.org>
@@ -23,15 +23,6 @@
#include "tls13_internal.h"
static int
-tls13_accept(struct tls13_ctx *ctx)
-{
- if (ctx->mode != TLS13_HS_SERVER)
- return TLS13_IO_FAILURE;
-
- return tls13_handshake_perform(ctx);
-}
-
-static int
tls13_server_init(struct tls13_ctx *ctx)
{
SSL *s = ctx->ssl;
@@ -54,6 +45,15 @@ tls13_server_init(struct tls13_ctx *ctx)
return 1;
}
+static int
+tls13_accept(struct tls13_ctx *ctx)
+{
+ if (ctx->mode != TLS13_HS_SERVER)
+ return TLS13_IO_FAILURE;
+
+ return tls13_handshake_perform(ctx);
+}
+
int
tls13_legacy_accept(SSL *ssl)
{
@@ -300,202 +300,6 @@ tls13_client_hello_recv(struct tls13_ctx *ctx, CBS *cbs)
return 0;
}
-int
-tls13_client_hello_retry_recv(struct tls13_ctx *ctx, CBS *cbs)
-{
- return 0;
-}
-
-int
-tls13_client_end_of_early_data_send(struct tls13_ctx *ctx, CBB *cbb)
-{
- return 0;
-}
-
-int
-tls13_client_end_of_early_data_recv(struct tls13_ctx *ctx, CBS *cbs)
-{
- return 0;
-}
-
-int
-tls13_client_certificate_recv(struct tls13_ctx *ctx, CBS *cbs)
-{
- CBS cert_request_context, cert_list, cert_data, cert_exts;
- struct stack_st_X509 *certs = NULL;
- SSL *s = ctx->ssl;
- X509 *cert = NULL;
- EVP_PKEY *pkey;
- const uint8_t *p;
- int cert_idx;
- int ret = 0;
-
- if (!CBS_get_u8_length_prefixed(cbs, &cert_request_context))
- goto err;
- if (CBS_len(&cert_request_context) != 0)
- goto err;
- if (!CBS_get_u24_length_prefixed(cbs, &cert_list))
- goto err;
-
- if (CBS_len(&cert_list) == 0)
- return 1;
-
- if ((certs = sk_X509_new_null()) == NULL)
- goto err;
- while (CBS_len(&cert_list) > 0) {
- if (!CBS_get_u24_length_prefixed(&cert_list, &cert_data))
- goto err;
- if (!CBS_get_u16_length_prefixed(&cert_list, &cert_exts))
- goto err;
-
- p = CBS_data(&cert_data);
- if ((cert = d2i_X509(NULL, &p, CBS_len(&cert_data))) == NULL)
- goto err;
- if (p != CBS_data(&cert_data) + CBS_len(&cert_data))
- goto err;
-
- if (!sk_X509_push(certs, cert))
- goto err;
-
- cert = NULL;
- }
-
- /*
- * At this stage we still have no proof of possession. As such, it would
- * be preferable to keep the chain and verify once we have successfully
- * processed the CertificateVerify message.
- */
- if (ssl_verify_cert_chain(s, certs) <= 0 &&
- s->verify_mode != SSL_VERIFY_NONE) {
- ctx->alert = ssl_verify_alarm_type(s->verify_result);
- tls13_set_errorx(ctx, TLS13_ERR_VERIFY_FAILED, 0,
- "failed to verify peer certificate", NULL);
- goto err;
- }
- ERR_clear_error();
-
- cert = sk_X509_value(certs, 0);
- X509_up_ref(cert);
-
- 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)
- 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);
-
- X509_up_ref(cert);
- s->session->peer = cert;
- s->session->verify_result = s->verify_result;
-
- ctx->handshake_stage.hs_type |= WITH_CCV;
- ret = 1;
-
- err:
- sk_X509_pop_free(certs, X509_free);
- X509_free(cert);
-
- return ret;
-}
-
-int
-tls13_client_certificate_verify_recv(struct tls13_ctx *ctx, CBS *cbs)
-{
- const struct ssl_sigalg *sigalg;
- uint16_t signature_scheme;
- uint8_t *sig_content = NULL;
- size_t sig_content_len;
- EVP_MD_CTX *mdctx = NULL;
- EVP_PKEY_CTX *pctx;
- EVP_PKEY *pkey;
- X509 *cert;
- CBS signature;
- CBB cbb;
- int ret = 0;
-
- memset(&cbb, 0, sizeof(cbb));
-
- if (!CBS_get_u16(cbs, &signature_scheme))
- goto err;
- 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,
- sizeof(tls13_cert_verify_pad)))
- goto err;
- if (!CBB_add_bytes(&cbb, tls13_cert_client_verify_context,
- strlen(tls13_cert_client_verify_context)))
- goto err;
- if (!CBB_add_u8(&cbb, 0))
- goto err;
- if (!CBB_add_bytes(&cbb, ctx->hs->transcript_hash,
- ctx->hs->transcript_hash_len))
- goto err;
- if (!CBB_finish(&cbb, &sig_content, &sig_content_len))
- goto err;
-
- if ((cert = ctx->ssl->session->peer) == NULL)
- goto err;
- if ((pkey = X509_get0_pubkey(cert)) == NULL)
- goto err;
- if (!ssl_sigalg_pkey_ok(sigalg, pkey, 1))
- goto err;
-
- if (CBS_len(&signature) > EVP_PKEY_size(pkey))
- goto err;
-
- if ((mdctx = EVP_MD_CTX_new()) == NULL)
- goto err;
- if (!EVP_DigestVerifyInit(mdctx, &pctx, sigalg->md(), NULL, pkey))
- goto err;
- if (sigalg->flags & SIGALG_FLAG_RSA_PSS) {
- if (!EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING))
- goto err;
- if (!EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, -1))
- goto err;
- }
- if (!EVP_DigestVerifyUpdate(mdctx, sig_content, sig_content_len)) {
- ctx->alert = TLS1_AD_DECRYPT_ERROR;
- goto err;
- }
- if (EVP_DigestVerifyFinal(mdctx, CBS_data(&signature),
- CBS_len(&signature)) <= 0) {
- ctx->alert = TLS1_AD_DECRYPT_ERROR;
- goto err;
- }
-
- ret = 1;
-
- err:
- if (!ret && ctx->alert == 0) {
- ctx->alert = TLS1_AD_DECODE_ERROR;
- }
- CBB_cleanup(&cbb);
- EVP_MD_CTX_free(mdctx);
- free(sig_content);
-
- return ret;
-}
-
static int
tls13_server_hello_build(struct tls13_ctx *ctx, CBB *cbb)
{
@@ -530,6 +334,18 @@ err:
}
int
+tls13_server_hello_retry_request_send(struct tls13_ctx *ctx, CBB *cbb)
+{
+ return 0;
+}
+
+int
+tls13_client_hello_retry_recv(struct tls13_ctx *ctx, CBS *cbs)
+{
+ return 0;
+}
+
+int
tls13_server_hello_send(struct tls13_ctx *ctx, CBB *cbb)
{
if (ctx->hs->key_share == NULL)
@@ -613,15 +429,27 @@ tls13_server_hello_sent(struct tls13_ctx *ctx)
}
int
-tls13_server_hello_retry_request_send(struct tls13_ctx *ctx, CBB *cbb)
+tls13_server_encrypted_extensions_send(struct tls13_ctx *ctx, CBB *cbb)
{
+ if (!tlsext_server_build(ctx->ssl, cbb, SSL_TLSEXT_MSG_EE))
+ goto err;
+
+ return 1;
+ err:
return 0;
}
int
-tls13_server_encrypted_extensions_send(struct tls13_ctx *ctx, CBB *cbb)
+tls13_server_certificate_request_send(struct tls13_ctx *ctx, CBB *cbb)
{
- if (!tlsext_server_build(ctx->ssl, cbb, SSL_TLSEXT_MSG_EE))
+ CBB certificate_request_context;
+
+ if (!CBB_add_u8_length_prefixed(cbb, &certificate_request_context))
+ goto err;
+ if (!tlsext_server_build(ctx->ssl, cbb, SSL_TLSEXT_MSG_CR))
+ goto err;
+
+ if (!CBB_flush(cbb))
goto err;
return 1;
@@ -672,25 +500,6 @@ tls13_server_certificate_send(struct tls13_ctx *ctx, CBB *cbb)
return ret;
}
-/* XXX - move up. */
-int
-tls13_server_certificate_request_send(struct tls13_ctx *ctx, CBB *cbb)
-{
- CBB certificate_request_context;
-
- if (!CBB_add_u8_length_prefixed(cbb, &certificate_request_context))
- goto err;
- if (!tlsext_server_build(ctx->ssl, cbb, SSL_TLSEXT_MSG_CR))
- goto err;
-
- if (!CBB_flush(cbb))
- goto err;
-
- return 1;
- err:
- return 0;
-}
-
int
tls13_server_certificate_verify_send(struct tls13_ctx *ctx, CBB *cbb)
{
@@ -850,6 +659,190 @@ tls13_server_finished_sent(struct tls13_ctx *ctx)
}
int
+tls13_client_certificate_recv(struct tls13_ctx *ctx, CBS *cbs)
+{
+ CBS cert_request_context, cert_list, cert_data, cert_exts;
+ struct stack_st_X509 *certs = NULL;
+ SSL *s = ctx->ssl;
+ X509 *cert = NULL;
+ EVP_PKEY *pkey;
+ const uint8_t *p;
+ int cert_idx;
+ int ret = 0;
+
+ if (!CBS_get_u8_length_prefixed(cbs, &cert_request_context))
+ goto err;
+ if (CBS_len(&cert_request_context) != 0)
+ goto err;
+ if (!CBS_get_u24_length_prefixed(cbs, &cert_list))
+ goto err;
+
+ if (CBS_len(&cert_list) == 0)
+ return 1;
+
+ if ((certs = sk_X509_new_null()) == NULL)
+ goto err;
+ while (CBS_len(&cert_list) > 0) {
+ if (!CBS_get_u24_length_prefixed(&cert_list, &cert_data))
+ goto err;
+ if (!CBS_get_u16_length_prefixed(&cert_list, &cert_exts))
+ goto err;
+
+ p = CBS_data(&cert_data);
+ if ((cert = d2i_X509(NULL, &p, CBS_len(&cert_data))) == NULL)
+ goto err;
+ if (p != CBS_data(&cert_data) + CBS_len(&cert_data))
+ goto err;
+
+ if (!sk_X509_push(certs, cert))
+ goto err;
+
+ cert = NULL;
+ }
+
+ /*
+ * At this stage we still have no proof of possession. As such, it would
+ * be preferable to keep the chain and verify once we have successfully
+ * processed the CertificateVerify message.
+ */
+ if (ssl_verify_cert_chain(s, certs) <= 0 &&
+ s->verify_mode != SSL_VERIFY_NONE) {
+ ctx->alert = ssl_verify_alarm_type(s->verify_result);
+ tls13_set_errorx(ctx, TLS13_ERR_VERIFY_FAILED, 0,
+ "failed to verify peer certificate", NULL);
+ goto err;
+ }
+ ERR_clear_error();
+
+ cert = sk_X509_value(certs, 0);
+ X509_up_ref(cert);
+
+ 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)
+ 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);
+
+ X509_up_ref(cert);
+ s->session->peer = cert;
+ s->session->verify_result = s->verify_result;
+
+ ctx->handshake_stage.hs_type |= WITH_CCV;
+ ret = 1;
+
+ err:
+ sk_X509_pop_free(certs, X509_free);
+ X509_free(cert);
+
+ return ret;
+}
+
+int
+tls13_client_certificate_verify_recv(struct tls13_ctx *ctx, CBS *cbs)
+{
+ const struct ssl_sigalg *sigalg;
+ uint16_t signature_scheme;
+ uint8_t *sig_content = NULL;
+ size_t sig_content_len;
+ EVP_MD_CTX *mdctx = NULL;
+ EVP_PKEY_CTX *pctx;
+ EVP_PKEY *pkey;
+ X509 *cert;
+ CBS signature;
+ CBB cbb;
+ int ret = 0;
+
+ memset(&cbb, 0, sizeof(cbb));
+
+ if (!CBS_get_u16(cbs, &signature_scheme))
+ goto err;
+ 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,
+ sizeof(tls13_cert_verify_pad)))
+ goto err;
+ if (!CBB_add_bytes(&cbb, tls13_cert_client_verify_context,
+ strlen(tls13_cert_client_verify_context)))
+ goto err;
+ if (!CBB_add_u8(&cbb, 0))
+ goto err;
+ if (!CBB_add_bytes(&cbb, ctx->hs->transcript_hash,
+ ctx->hs->transcript_hash_len))
+ goto err;
+ if (!CBB_finish(&cbb, &sig_content, &sig_content_len))
+ goto err;
+
+ if ((cert = ctx->ssl->session->peer) == NULL)
+ goto err;
+ if ((pkey = X509_get0_pubkey(cert)) == NULL)
+ goto err;
+ if (!ssl_sigalg_pkey_ok(sigalg, pkey, 1))
+ goto err;
+
+ if (CBS_len(&signature) > EVP_PKEY_size(pkey))
+ goto err;
+
+ if ((mdctx = EVP_MD_CTX_new()) == NULL)
+ goto err;
+ if (!EVP_DigestVerifyInit(mdctx, &pctx, sigalg->md(), NULL, pkey))
+ goto err;
+ if (sigalg->flags & SIGALG_FLAG_RSA_PSS) {
+ if (!EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING))
+ goto err;
+ if (!EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, -1))
+ goto err;
+ }
+ if (!EVP_DigestVerifyUpdate(mdctx, sig_content, sig_content_len)) {
+ ctx->alert = TLS1_AD_DECRYPT_ERROR;
+ goto err;
+ }
+ if (EVP_DigestVerifyFinal(mdctx, CBS_data(&signature),
+ CBS_len(&signature)) <= 0) {
+ ctx->alert = TLS1_AD_DECRYPT_ERROR;
+ goto err;
+ }
+
+ ret = 1;
+
+ err:
+ if (!ret && ctx->alert == 0) {
+ ctx->alert = TLS1_AD_DECODE_ERROR;
+ }
+ CBB_cleanup(&cbb);
+ EVP_MD_CTX_free(mdctx);
+ free(sig_content);
+
+ return ret;
+}
+
+int
+tls13_client_end_of_early_data_recv(struct tls13_ctx *ctx, CBS *cbs)
+{
+ return 0;
+}
+
+int
tls13_client_finished_recv(struct tls13_ctx *ctx, CBS *cbs)
{
struct tls13_secrets *secrets = ctx->hs->secrets;