Fix a number of sigalg scope issues.
peer_sigalgs should live on SSL_HANDSHAKE. This both releases a little
bit of memory after the handshake is over and also avoids the bug where
the sigalgs get dropped if SSL_set_SSL_CTX is called at a bad time. See
also upstream's 14e14bf6964965d02ce89805d9de867f000095aa.
This only affects consumers using the old SNI callback and not
select_certificate_cb.
Add a test that the SNI callback works as expected. In doing so, add an
SSL_CTX version of the signing preferences API. This is a property of
the cert/key pair (really just the key) and should be tied to that. This
makes it a bit easier to have the regression test work with TLS 1.2 too.
I thought we'd fixed this already, but apparently not... :-/
BUG=95
Change-Id: I75b02fad4059e6aa46c3b05183a07d72880711b3
Reviewed-on: https://boringssl-review.googlesource.com/10445
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
index dbf4313..0b08400 100644
--- a/ssl/t1_lib.c
+++ b/ssl/t1_lib.c
@@ -594,16 +594,15 @@
* settings. */
void ssl_set_client_disabled(SSL *ssl) {
CERT *c = ssl->cert;
- const uint16_t *sigalgs;
- size_t i, sigalgslen;
int have_rsa = 0, have_ecdsa = 0;
c->mask_a = 0;
c->mask_k = 0;
/* Now go through all signature algorithms seeing if we support any for RSA,
* DSA, ECDSA. Do this for all versions not just TLS 1.2. */
- sigalgslen = tls12_get_psigalgs(ssl, &sigalgs);
- for (i = 0; i < sigalgslen; i++) {
+ const uint16_t *sigalgs;
+ size_t num_sigalgs = tls12_get_psigalgs(ssl, &sigalgs);
+ for (size_t i = 0; i < num_sigalgs; i++) {
switch (sigalgs[i]) {
case SSL_SIGN_RSA_PSS_SHA512:
case SSL_SIGN_RSA_PSS_SHA384:
@@ -1130,19 +1129,18 @@
return 1;
}
- const uint16_t *sigalgs_data;
- const size_t sigalgs_len = tls12_get_psigalgs(ssl, &sigalgs_data);
+ const uint16_t *sigalgs;
+ const size_t num_sigalgs = tls12_get_psigalgs(ssl, &sigalgs);
- CBB contents, sigalgs;
+ CBB contents, sigalgs_cbb;
if (!CBB_add_u16(out, TLSEXT_TYPE_signature_algorithms) ||
!CBB_add_u16_length_prefixed(out, &contents) ||
- !CBB_add_u16_length_prefixed(&contents, &sigalgs)) {
+ !CBB_add_u16_length_prefixed(&contents, &sigalgs_cbb)) {
return 0;
}
- size_t i;
- for (i = 0; i < sigalgs_len; i++) {
- if (!CBB_add_u16(&sigalgs, sigalgs_data[i])) {
+ for (size_t i = 0; i < num_sigalgs; i++) {
+ if (!CBB_add_u16(&sigalgs_cbb, sigalgs[i])) {
return 0;
}
}
@@ -1156,9 +1154,9 @@
static int ext_sigalgs_parse_clienthello(SSL *ssl, uint8_t *out_alert,
CBS *contents) {
- OPENSSL_free(ssl->cert->peer_sigalgs);
- ssl->cert->peer_sigalgs = NULL;
- ssl->cert->peer_sigalgslen = 0;
+ OPENSSL_free(ssl->s3->hs->peer_sigalgs);
+ ssl->s3->hs->peer_sigalgs = NULL;
+ ssl->s3->hs->num_peer_sigalgs = 0;
if (contents == NULL) {
return 1;
@@ -3025,13 +3023,12 @@
return 1;
}
- CERT *const cert = ssl->cert;
- OPENSSL_free(cert->peer_sigalgs);
- cert->peer_sigalgs = NULL;
- cert->peer_sigalgslen = 0;
+ SSL_HANDSHAKE *hs = ssl->s3->hs;
+ OPENSSL_free(hs->peer_sigalgs);
+ hs->peer_sigalgs = NULL;
+ hs->num_peer_sigalgs = 0;
size_t num_sigalgs = CBS_len(in_sigalgs);
-
if (num_sigalgs % 2 != 0) {
return 0;
}
@@ -3045,18 +3042,16 @@
/* This multiplication doesn't overflow because sizeof(uint16_t) is two
* and we just divided |num_sigalgs| by two. */
- cert->peer_sigalgs = OPENSSL_malloc(num_sigalgs * sizeof(uint16_t));
- if (cert->peer_sigalgs == NULL) {
+ hs->peer_sigalgs = OPENSSL_malloc(num_sigalgs * sizeof(uint16_t));
+ if (hs->peer_sigalgs == NULL) {
return 0;
}
- cert->peer_sigalgslen = num_sigalgs;
+ hs->num_peer_sigalgs = num_sigalgs;
CBS sigalgs;
CBS_init(&sigalgs, CBS_data(in_sigalgs), CBS_len(in_sigalgs));
-
- size_t i;
- for (i = 0; i < num_sigalgs; i++) {
- if (!CBS_get_u16(&sigalgs, &cert->peer_sigalgs[i])) {
+ for (size_t i = 0; i < num_sigalgs; i++) {
+ if (!CBS_get_u16(&sigalgs, &hs->peer_sigalgs[i])) {
return 0;
}
}
@@ -3066,7 +3061,7 @@
int tls1_choose_signature_algorithm(SSL *ssl, uint16_t *out) {
CERT *cert = ssl->cert;
- size_t i, j;
+ SSL_HANDSHAKE *hs = ssl->s3->hs;
/* Before TLS 1.2, the signature algorithm isn't negotiated as part of the
* handshake. It is fixed at MD5-SHA1 for RSA and SHA1 for ECDSA. */
@@ -3085,25 +3080,25 @@
}
const uint16_t *sigalgs;
- size_t sigalgs_len = tls12_get_psigalgs(ssl, &sigalgs);
+ size_t num_sigalgs = tls12_get_psigalgs(ssl, &sigalgs);
if (cert->sigalgs != NULL) {
sigalgs = cert->sigalgs;
- sigalgs_len = cert->sigalgs_len;
+ num_sigalgs = cert->num_sigalgs;
}
- const uint16_t *peer_sigalgs = cert->peer_sigalgs;
- size_t peer_sigalgs_len = cert->peer_sigalgslen;
- if (peer_sigalgs_len == 0 && ssl3_protocol_version(ssl) < TLS1_3_VERSION) {
+ const uint16_t *peer_sigalgs = hs->peer_sigalgs;
+ size_t num_peer_sigalgs = hs->num_peer_sigalgs;
+ if (num_peer_sigalgs == 0 && ssl3_protocol_version(ssl) < TLS1_3_VERSION) {
/* If the client didn't specify any signature_algorithms extension then
* we can assume that it supports SHA1. See
* http://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */
static const uint16_t kDefaultPeerAlgorithms[] = {SSL_SIGN_RSA_PKCS1_SHA1,
SSL_SIGN_ECDSA_SHA1};
peer_sigalgs = kDefaultPeerAlgorithms;
- peer_sigalgs_len = OPENSSL_ARRAY_SIZE(kDefaultPeerAlgorithms);
+ num_peer_sigalgs = OPENSSL_ARRAY_SIZE(kDefaultPeerAlgorithms);
}
- for (i = 0; i < sigalgs_len; i++) {
+ for (size_t i = 0; i < num_sigalgs; i++) {
uint16_t sigalg = sigalgs[i];
/* SSL_SIGN_RSA_PKCS1_MD5_SHA1 is an internal value and should never be
* negotiated. */
@@ -3112,7 +3107,7 @@
continue;
}
- for (j = 0; j < peer_sigalgs_len; j++) {
+ for (size_t j = 0; j < num_peer_sigalgs; j++) {
if (sigalg == peer_sigalgs[j]) {
*out = sigalg;
return 1;