summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/libssl/s3_lib.c6
-rw-r--r--lib/libssl/ssl_clnt.c30
-rw-r--r--lib/libssl/ssl_lib.c15
-rw-r--r--lib/libssl/ssl_locl.h6
-rw-r--r--lib/libssl/ssl_sigalgs.c84
-rw-r--r--lib/libssl/ssl_sigalgs.h8
-rw-r--r--lib/libssl/ssl_srvr.c4
-rw-r--r--lib/libssl/ssl_tlsext.c15
-rw-r--r--lib/libssl/tls13_client.c4
9 files changed, 124 insertions, 48 deletions
diff --git a/lib/libssl/s3_lib.c b/lib/libssl/s3_lib.c
index de928bd70e1..49f402d0658 100644
--- a/lib/libssl/s3_lib.c
+++ b/lib/libssl/s3_lib.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: s3_lib.c,v 1.184 2019/02/09 15:26:15 jsing Exp $ */
+/* $OpenBSD: s3_lib.c,v 1.185 2019/03/25 17:21:18 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -1559,6 +1559,7 @@ 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);
DH_free(S3I(s)->tmp.dh);
EC_KEY_free(S3I(s)->tmp.ecdh);
@@ -1598,6 +1599,9 @@ ssl3_clear(SSL *s)
S3I(s)->tmp.dh = NULL;
EC_KEY_free(S3I(s)->tmp.ecdh);
S3I(s)->tmp.ecdh = NULL;
+ freezero(S3I(s)->hs.sigalgs, S3I(s)->hs.sigalgs_len);
+ S3I(s)->hs.sigalgs = NULL;
+ S3I(s)->hs.sigalgs_len = 0;
freezero(S3I(s)->tmp.x25519, X25519_KEY_LENGTH);
S3I(s)->tmp.x25519 = NULL;
diff --git a/lib/libssl/ssl_clnt.c b/lib/libssl/ssl_clnt.c
index 262e09fe5eb..2174e3a83d1 100644
--- a/lib/libssl/ssl_clnt.c
+++ b/lib/libssl/ssl_clnt.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssl_clnt.c,v 1.59 2019/03/25 16:35:48 jsing Exp $ */
+/* $OpenBSD: ssl_clnt.c,v 1.60 2019/03/25 17:21:18 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -1512,7 +1512,7 @@ ssl3_get_server_key_exchange(SSL *s)
if (!CBS_get_u16(&cbs, &sigalg_value))
goto truncated;
if ((sigalg = ssl_sigalg(sigalg_value, tls12_sigalgs,
- tls12_sigalgs_len)) == NULL) {
+ tls12_sigalgs_len)) == NULL) {
SSLerror(s, SSL_R_UNKNOWN_DIGEST);
al = SSL_AD_DECODE_ERROR;
goto f_err;
@@ -1522,7 +1522,7 @@ ssl3_get_server_key_exchange(SSL *s)
al = SSL_AD_DECODE_ERROR;
goto f_err;
}
- if (!ssl_sigalg_pkey_ok(sigalg, pkey)) {
+ if (!ssl_sigalg_pkey_ok(sigalg, pkey, 0)) {
SSLerror(s, SSL_R_WRONG_SIGNATURE_TYPE);
al = SSL_AD_DECODE_ERROR;
goto f_err;
@@ -1671,21 +1671,19 @@ ssl3_get_certificate_request(SSL *s)
SSLerror(s, SSL_R_DATA_LENGTH_TOO_LONG);
goto err;
}
-
- /* Check we have enough room for signature algorithms and
- * following length value.
- */
if (!CBS_get_u16_length_prefixed(&cert_request, &sigalgs)) {
ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
SSLerror(s, SSL_R_DATA_LENGTH_TOO_LONG);
goto err;
}
- if (!tls1_process_sigalgs(s, &sigalgs, tls12_sigalgs,
- tls12_sigalgs_len)) {
+ if (CBS_len(&sigalgs) % 2 != 0 || CBS_len(&sigalgs) > 64) {
ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
SSLerror(s, SSL_R_SIGNATURE_ALGORITHMS_ERROR);
goto err;
}
+ if (!CBS_stow(&sigalgs, &S3I(s)->hs.sigalgs,
+ &S3I(s)->hs.sigalgs_len))
+ goto err;
}
/* get the CA RDNs */
@@ -2372,6 +2370,7 @@ err:
static int
ssl3_send_client_verify_sigalgs(SSL *s, CBB *cert_verify)
{
+ const struct ssl_sigalg *sigalg;
CBB cbb_signature;
EVP_PKEY_CTX *pctx = NULL;
EVP_PKEY *pkey;
@@ -2387,10 +2386,17 @@ ssl3_send_client_verify_sigalgs(SSL *s, CBB *cert_verify)
EVP_MD_CTX_init(&mctx);
pkey = s->cert->key->privatekey;
- md = s->cert->key->sigalg->md();
+ if ((sigalg = ssl_sigalg_select(s, pkey)) == NULL) {
+ SSLerror(s, SSL_R_SIGNATURE_ALGORITHMS_ERROR);
+ goto err;
+ }
+ if ((md = sigalg->md()) == NULL) {
+ SSLerror(s, SSL_R_UNKNOWN_DIGEST);
+ goto err;
+ }
if (!tls1_transcript_data(s, &hdata, &hdatalen) ||
- !CBB_add_u16(cert_verify, s->cert->key->sigalg->value)) {
+ !CBB_add_u16(cert_verify, sigalg->value)) {
SSLerror(s, ERR_R_INTERNAL_ERROR);
goto err;
}
@@ -2398,7 +2404,7 @@ ssl3_send_client_verify_sigalgs(SSL *s, CBB *cert_verify)
SSLerror(s, ERR_R_EVP_LIB);
goto err;
}
- if ((s->cert->key->sigalg->flags & SIGALG_FLAG_RSA_PSS) &&
+ if ((sigalg->flags & SIGALG_FLAG_RSA_PSS) &&
(!EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING) ||
!EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, -1))) {
SSLerror(s, ERR_R_EVP_LIB);
diff --git a/lib/libssl/ssl_lib.c b/lib/libssl/ssl_lib.c
index 52ede46f7e2..70a4c6d16ff 100644
--- a/lib/libssl/ssl_lib.c
+++ b/lib/libssl/ssl_lib.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssl_lib.c,v 1.202 2019/03/25 16:37:52 jsing Exp $ */
+/* $OpenBSD: ssl_lib.c,v 1.203 2019/03/25 17:21:18 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -2120,18 +2120,7 @@ ssl_get_sign_pkey(SSL *s, const SSL_CIPHER *cipher, const EVP_MD **pmd,
}
pkey = c->pkeys[idx].privatekey;
- sigalg = c->pkeys[idx].sigalg;
- if (!SSL_USE_SIGALGS(s)) {
- if (pkey->type == EVP_PKEY_RSA) {
- sigalg = ssl_sigalg_lookup(SIGALG_RSA_PKCS1_MD5_SHA1);
- } else if (pkey->type == EVP_PKEY_EC) {
- sigalg = ssl_sigalg_lookup(SIGALG_ECDSA_SHA1);
- } else {
- SSLerror(s, SSL_R_UNKNOWN_PKEY_TYPE);
- return (NULL);
- }
- }
- if (sigalg == NULL) {
+ if ((sigalg = ssl_sigalg_select(s, pkey)) == NULL) {
SSLerror(s, SSL_R_SIGNATURE_ALGORITHMS_ERROR);
return (NULL);
}
diff --git a/lib/libssl/ssl_locl.h b/lib/libssl/ssl_locl.h
index 9d06deeb7a3..44abb6d6dab 100644
--- a/lib/libssl/ssl_locl.h
+++ b/lib/libssl/ssl_locl.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssl_locl.h,v 1.241 2019/03/25 16:37:52 jsing Exp $ */
+/* $OpenBSD: ssl_locl.h,v 1.242 2019/03/25 17:21:18 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -432,6 +432,10 @@ typedef struct ssl_handshake_st {
/* Extensions seen in this handshake. */
uint32_t extensions_seen;
+
+ /* sigalgs offered in this handshake in wire form */
+ size_t sigalgs_len;
+ uint8_t *sigalgs;
} SSL_HANDSHAKE;
typedef struct ssl_handshake_tls13_st {
diff --git a/lib/libssl/ssl_sigalgs.c b/lib/libssl/ssl_sigalgs.c
index 3a7f6d66875..50f4802fdb7 100644
--- a/lib/libssl/ssl_sigalgs.c
+++ b/lib/libssl/ssl_sigalgs.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssl_sigalgs.c,v 1.17 2019/03/19 16:56:04 jsing Exp $ */
+/* $OpenBSD: ssl_sigalgs.c,v 1.18 2019/03/25 17:21:18 jsing Exp $ */
/*
* Copyright (c) 2018-2019 Bob Beck <beck@openbsd.org>
*
@@ -246,7 +246,8 @@ ssl_sigalgs_build(CBB *cbb, uint16_t *values, size_t len)
}
int
-ssl_sigalg_pkey_ok(const struct ssl_sigalg *sigalg, EVP_PKEY *pkey)
+ssl_sigalg_pkey_ok(const struct ssl_sigalg *sigalg, EVP_PKEY *pkey,
+ int check_curve)
{
if (sigalg == NULL || pkey == NULL)
return 0;
@@ -266,12 +267,85 @@ ssl_sigalg_pkey_ok(const struct ssl_sigalg *sigalg, EVP_PKEY *pkey)
if (pkey->type == EVP_PKEY_EC) {
if (sigalg->curve_nid == 0)
return 0;
- /* Curve must match for EC keys */
- if (EC_GROUP_get_curve_name(EC_KEY_get0_group
+ /* Curve must match for EC keys. */
+ if (check_curve && EC_GROUP_get_curve_name(EC_KEY_get0_group
(EVP_PKEY_get0_EC_KEY(pkey))) != sigalg->curve_nid) {
- return 1; /* XXX www.videolan.org curve mismatch */
+ return 0;
}
}
return 1;
}
+
+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);
+ }
+
+ /*
+ * RFC 5246 allows a TLS 1.2 client to send no sigalgs, in
+ * which case the server must use the 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 we get here, we have client or server sent sigalgs, use one.
+ */
+ CBS_init(&cbs, S3I(s)->hs.sigalgs, S3I(s)->hs.sigalgs_len);
+ while (CBS_len(&cbs) > 0) {
+ uint16_t sig_alg;
+ const struct ssl_sigalg *sigalg;
+
+ if (!CBS_get_u16(&cbs, &sig_alg))
+ return 0;
+
+ if ((sigalg = ssl_sigalg(sig_alg, tls_sigalgs,
+ tls_sigalgs_len)) == NULL)
+ continue;
+
+ if (ssl_sigalg_pkey_ok(sigalg, pkey, check_curve))
+ return sigalg;
+ }
+
+ SSLerror(s, SSL_R_UNKNOWN_PKEY_TYPE);
+ return NULL;
+}
diff --git a/lib/libssl/ssl_sigalgs.h b/lib/libssl/ssl_sigalgs.h
index d05f66f7ba4..d06731e10d8 100644
--- a/lib/libssl/ssl_sigalgs.h
+++ b/lib/libssl/ssl_sigalgs.h
@@ -1,6 +1,6 @@
-/* $OpenBSD: ssl_sigalgs.h,v 1.12 2019/01/23 23:47:13 beck Exp $ */
+/* $OpenBSD: ssl_sigalgs.h,v 1.13 2019/03/25 17:21:18 jsing Exp $ */
/*
- * Copyright (c) 2018, Bob Beck <beck@openbsd.org>
+ * Copyright (c) 2018-2019 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
@@ -78,7 +78,9 @@ 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 ssl_sigalg_pkey_ok(const struct ssl_sigalg *sigalg, EVP_PKEY *pkey,
+ int check_curve);
+const struct ssl_sigalg *ssl_sigalg_select(SSL *s, EVP_PKEY *pkey);
__END_HIDDEN_DECLS
diff --git a/lib/libssl/ssl_srvr.c b/lib/libssl/ssl_srvr.c
index f2aafc30326..745d0228f30 100644
--- a/lib/libssl/ssl_srvr.c
+++ b/lib/libssl/ssl_srvr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssl_srvr.c,v 1.65 2019/03/25 16:35:48 jsing Exp $ */
+/* $OpenBSD: ssl_srvr.c,v 1.66 2019/03/25 17:21:18 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -2177,7 +2177,7 @@ ssl3_get_cert_verify(SSL *s)
al = SSL_AD_DECODE_ERROR;
goto f_err;
}
- if (!ssl_sigalg_pkey_ok(sigalg, pkey)) {
+ if (!ssl_sigalg_pkey_ok(sigalg, pkey, 0)) {
SSLerror(s, SSL_R_WRONG_SIGNATURE_TYPE);
al = SSL_AD_DECODE_ERROR;
goto f_err;
diff --git a/lib/libssl/ssl_tlsext.c b/lib/libssl/ssl_tlsext.c
index de9fabd4c7b..0e37cc3cc00 100644
--- a/lib/libssl/ssl_tlsext.c
+++ b/lib/libssl/ssl_tlsext.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssl_tlsext.c,v 1.43 2019/03/19 16:53:03 jsing Exp $ */
+/* $OpenBSD: ssl_tlsext.c,v 1.44 2019/03/25 17:21:18 jsing Exp $ */
/*
* Copyright (c) 2016, 2017, 2019 Joel Sing <jsing@openbsd.org>
* Copyright (c) 2017 Doug Hogan <doug@openbsd.org>
@@ -556,19 +556,16 @@ tlsext_sigalgs_client_build(SSL *s, CBB *cbb)
int
tlsext_sigalgs_server_parse(SSL *s, CBS *cbs, int *alert)
{
- uint16_t *tls_sigalgs = tls12_sigalgs;
- size_t tls_sigalgs_len = tls12_sigalgs_len;
CBS sigalgs;
- if (s->version >= TLS1_3_VERSION) {
- tls_sigalgs = tls13_sigalgs;
- tls_sigalgs_len = tls13_sigalgs_len;
- }
-
if (!CBS_get_u16_length_prefixed(cbs, &sigalgs))
return 0;
+ if (CBS_len(&sigalgs) % 2 != 0 || CBS_len(&sigalgs) > 64)
+ return 0;
+ if (!CBS_stow(&sigalgs, &S3I(s)->hs.sigalgs, &S3I(s)->hs.sigalgs_len))
+ return 0;
- return tls1_process_sigalgs(s, &sigalgs, tls_sigalgs, tls_sigalgs_len);
+ return 1;
}
int
diff --git a/lib/libssl/tls13_client.c b/lib/libssl/tls13_client.c
index 56faf3f5d45..5b4ecdb47d1 100644
--- a/lib/libssl/tls13_client.c
+++ b/lib/libssl/tls13_client.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tls13_client.c,v 1.13 2019/02/28 17:51:19 jsing Exp $ */
+/* $OpenBSD: tls13_client.c,v 1.14 2019/03/25 17:21:18 jsing Exp $ */
/*
* Copyright (c) 2018, 2019 Joel Sing <jsing@openbsd.org>
*
@@ -527,7 +527,7 @@ tls13_server_certificate_verify_recv(struct tls13_ctx *ctx)
goto err;
if ((pkey = X509_get0_pubkey(cert)) == NULL)
goto err;
- if (!ssl_sigalg_pkey_ok(sigalg, pkey))
+ if (!ssl_sigalg_pkey_ok(sigalg, pkey, 1))
goto err;
if (CBS_len(&signature) > EVP_PKEY_size(pkey))