Store the peer_sigalgs as an Array.
Bug: 132
Change-Id: I710dbd4906bb7a8b971831be0121df5b78e4f9e0
Reviewed-on: https://boringssl-review.googlesource.com/20672
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.cc b/ssl/t1_lib.cc
index 7a83ed4..1fe360b 100644
--- a/ssl/t1_lib.cc
+++ b/ssl/t1_lib.cc
@@ -1011,10 +1011,7 @@
static int ext_sigalgs_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
CBS *contents) {
- OPENSSL_free(hs->peer_sigalgs);
- hs->peer_sigalgs = NULL;
- hs->num_peer_sigalgs = 0;
-
+ hs->peer_sigalgs.Reset();
if (contents == NULL) {
return 1;
}
@@ -2350,6 +2347,29 @@
return 1;
}
+static bool parse_u16_array(const CBS *cbs, Array<uint16_t> *out) {
+ CBS copy = *cbs;
+ if ((CBS_len(©) & 1) != 0) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
+ return false;
+ }
+
+ Array<uint16_t> ret;
+ if (!ret.Init(CBS_len(©) / 2)) {
+ return false;
+ }
+ for (size_t i = 0; i < ret.size(); i++) {
+ if (!CBS_get_u16(©, &ret[i])) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ return false;
+ }
+ }
+
+ assert(CBS_len(©) == 0);
+ *out = std::move(ret);
+ return 1;
+}
+
static int ext_supported_groups_parse_clienthello(SSL_HANDSHAKE *hs,
uint8_t *out_alert,
CBS *contents) {
@@ -2360,24 +2380,11 @@
CBS supported_group_list;
if (!CBS_get_u16_length_prefixed(contents, &supported_group_list) ||
CBS_len(&supported_group_list) == 0 ||
- (CBS_len(&supported_group_list) & 1) != 0 ||
- CBS_len(contents) != 0) {
+ CBS_len(contents) != 0 ||
+ !parse_u16_array(&supported_group_list, &hs->peer_supported_group_list)) {
return 0;
}
- Array<uint16_t> groups;
- if (!groups.Init(CBS_len(&supported_group_list) / 2)) {
- return 0;
- }
- for (size_t i = 0; i < groups.size(); i++) {
- if (!CBS_get_u16(&supported_group_list, &groups[i])) {
- *out_alert = SSL_AD_INTERNAL_ERROR;
- return 0;
- }
- }
-
- assert(CBS_len(&supported_group_list) == 0);
- hs->peer_supported_group_list = std::move(groups);
return 1;
}
@@ -3141,39 +3148,7 @@
return 1;
}
- 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;
- }
- num_sigalgs /= 2;
-
- // supported_signature_algorithms in the certificate request is
- // allowed to be empty.
- if (num_sigalgs == 0) {
- return 1;
- }
-
- // This multiplication doesn't overflow because sizeof(uint16_t) is two
- // and we just divided |num_sigalgs| by two.
- hs->peer_sigalgs = (uint16_t *)OPENSSL_malloc(num_sigalgs * sizeof(uint16_t));
- if (hs->peer_sigalgs == NULL) {
- return 0;
- }
- hs->num_peer_sigalgs = num_sigalgs;
-
- CBS sigalgs;
- CBS_init(&sigalgs, CBS_data(in_sigalgs), CBS_len(in_sigalgs));
- for (size_t i = 0; i < num_sigalgs; i++) {
- if (!CBS_get_u16(&sigalgs, &hs->peer_sigalgs[i])) {
- return 0;
- }
- }
-
- return 1;
+ return parse_u16_array(in_sigalgs, &hs->peer_sigalgs);
}
int tls1_get_legacy_signature_algorithm(uint16_t *out, const EVP_PKEY *pkey) {
@@ -3203,36 +3178,31 @@
return 1;
}
- const uint16_t *sigalgs = cert->sigalgs;
- size_t num_sigalgs = cert->num_sigalgs;
- if (sigalgs == NULL) {
- sigalgs = kSignSignatureAlgorithms;
- num_sigalgs = OPENSSL_ARRAY_SIZE(kSignSignatureAlgorithms);
+ Span<const uint16_t> sigalgs = kSignSignatureAlgorithms;
+ if (cert->sigalgs != nullptr) {
+ sigalgs = MakeConstSpan(cert->sigalgs, cert->num_sigalgs);
}
- 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) {
+ Span<const uint16_t> peer_sigalgs = hs->peer_sigalgs;
+ if (peer_sigalgs.size() == 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;
- num_peer_sigalgs = OPENSSL_ARRAY_SIZE(kDefaultPeerAlgorithms);
}
- for (size_t i = 0; i < num_sigalgs; i++) {
- uint16_t sigalg = sigalgs[i];
+ for (uint16_t sigalg : sigalgs) {
// SSL_SIGN_RSA_PKCS1_MD5_SHA1 is an internal value and should never be
// negotiated.
if (sigalg == SSL_SIGN_RSA_PKCS1_MD5_SHA1 ||
- !ssl_private_key_supports_signature_algorithm(hs, sigalgs[i])) {
+ !ssl_private_key_supports_signature_algorithm(hs, sigalg)) {
continue;
}
- for (size_t j = 0; j < num_peer_sigalgs; j++) {
- if (sigalg == peer_sigalgs[j]) {
+ for (uint16_t peer_sigalg : peer_sigalgs) {
+ if (sigalg == peer_sigalg) {
*out = sigalg;
return 1;
}