Convert more things to Array.
This adds a CopyFrom companion to Init as a replacement for CBS_stow.
Bug: 132
Change-Id: I4d77291b07552bd2286a09f8ba33655d6d97c853
Reviewed-on: https://boringssl-review.googlesource.com/20670
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/handshake.cc b/ssl/handshake.cc
index dece144..d95677f 100644
--- a/ssl/handshake.cc
+++ b/ssl/handshake.cc
@@ -144,13 +144,10 @@
}
SSL_HANDSHAKE::~SSL_HANDSHAKE() {
- OPENSSL_free(cookie);
- OPENSSL_free(key_share_bytes);
OPENSSL_free(ecdh_public_key);
OPENSSL_free(peer_sigalgs);
OPENSSL_free(server_params);
ssl->ctx->x509_method->hs_flush_cached_ca_names(this);
- OPENSSL_free(certificate_types);
OPENSSL_free(key_block);
}
diff --git a/ssl/handshake_client.cc b/ssl/handshake_client.cc
index 62e15e2..9d2a1fb 100644
--- a/ssl/handshake_client.cc
+++ b/ssl/handshake_client.cc
@@ -976,13 +976,10 @@
// Initialize ECDH and save the peer public key for later.
hs->key_share = SSLKeyShare::Create(group_id);
- uint8_t *peer_key = nullptr;
- size_t peer_key_len = 0;
if (!hs->key_share ||
- !CBS_stow(&point, &peer_key, &peer_key_len)) {
+ !hs->peer_key.CopyFrom(point)) {
return ssl_hs_error;
}
- hs->peer_key.Reset(peer_key, peer_key_len);
} else if (!(alg_k & SSL_kPSK)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE);
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
@@ -1109,8 +1106,7 @@
return ssl_hs_error;
}
- if (!CBS_stow(&certificate_types, &hs->certificate_types,
- &hs->num_certificate_types)) {
+ if (!hs->certificate_types.CopyFrom(certificate_types)) {
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
return ssl_hs_error;
}
diff --git a/ssl/internal.h b/ssl/internal.h
index 17fe602..31cbdeb 100644
--- a/ssl/internal.h
+++ b/ssl/internal.h
@@ -158,6 +158,8 @@
#include <openssl/span.h>
#include <openssl/stack.h>
+#include "../crypto/internal.h"
+
#if defined(OPENSSL_WINDOWS)
// Windows defines struct timeval in winsock2.h.
@@ -314,6 +316,16 @@
return true;
}
+ // CopyFrom replaces the array with a newly-allocated copy of |in|. It returns
+ // true on success and false on error.
+ bool CopyFrom(Span<const uint8_t> in) {
+ if (!Init(in.size())) {
+ return false;
+ }
+ OPENSSL_memcpy(data_, in.data(), in.size());
+ return true;
+ }
+
private:
T *data_ = nullptr;
size_t size_ = 0;
@@ -1284,13 +1296,11 @@
SSLTranscript transcript;
// cookie is the value of the cookie received from the server, if any.
- uint8_t *cookie = nullptr;
- size_t cookie_len = 0;
+ Array<uint8_t> cookie;
// key_share_bytes is the value of the previously sent KeyShare extension by
// the client in TLS 1.3.
- uint8_t *key_share_bytes = nullptr;
- size_t key_share_bytes_len = 0;
+ Array<uint8_t> key_share_bytes;
// ecdh_public_key, for servers, is the key share to be sent to the client in
// TLS 1.3.
@@ -1332,8 +1342,7 @@
// certificate_types, on the client, contains the set of certificate types
// received in a CertificateRequest message.
- uint8_t *certificate_types = nullptr;
- size_t num_certificate_types = 0;
+ Array<uint8_t> certificate_types;
// local_pubkey is the public key we are authenticating as.
UniquePtr<EVP_PKEY> local_pubkey;
diff --git a/ssl/ssl_lib.cc b/ssl/ssl_lib.cc
index 7a75776..262f9b2 100644
--- a/ssl/ssl_lib.cc
+++ b/ssl/ssl_lib.cc
@@ -2022,8 +2022,8 @@
*out_types = NULL;
return 0;
}
- *out_types = ssl->s3->hs->certificate_types;
- return ssl->s3->hs->num_certificate_types;
+ *out_types = ssl->s3->hs->certificate_types.data();
+ return ssl->s3->hs->certificate_types.size();
}
EVP_PKEY *SSL_get_privatekey(const SSL *ssl) {
diff --git a/ssl/t1_lib.cc b/ssl/t1_lib.cc
index 6301505..7f3308b 100644
--- a/ssl/t1_lib.cc
+++ b/ssl/t1_lib.cc
@@ -149,19 +149,16 @@
// This function does an initial scan over the extensions block to filter those
// out.
static int tls1_check_duplicate_extensions(const CBS *cbs) {
- CBS extensions = *cbs;
- size_t num_extensions = 0, i = 0;
- uint16_t *extension_types = NULL;
- int ret = 0;
-
// First pass: count the extensions.
+ size_t num_extensions = 0;
+ CBS extensions = *cbs;
while (CBS_len(&extensions) > 0) {
uint16_t type;
CBS extension;
if (!CBS_get_u16(&extensions, &type) ||
!CBS_get_u16_length_prefixed(&extensions, &extension)) {
- goto done;
+ return 0;
}
num_extensions++;
@@ -171,39 +168,34 @@
return 1;
}
- extension_types =
- (uint16_t *)OPENSSL_malloc(sizeof(uint16_t) * num_extensions);
- if (extension_types == NULL) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
- goto done;
+ Array<uint16_t> extension_types;
+ if (!extension_types.Init(num_extensions)) {
+ return 0;
}
// Second pass: gather the extension types.
extensions = *cbs;
- for (i = 0; i < num_extensions; i++) {
+ for (size_t i = 0; i < extension_types.size(); i++) {
CBS extension;
if (!CBS_get_u16(&extensions, &extension_types[i]) ||
!CBS_get_u16_length_prefixed(&extensions, &extension)) {
// This should not happen.
- goto done;
+ return 0;
}
}
assert(CBS_len(&extensions) == 0);
// Sort the extensions and make sure there are no duplicates.
- qsort(extension_types, num_extensions, sizeof(uint16_t), compare_uint16_t);
- for (i = 1; i < num_extensions; i++) {
+ qsort(extension_types.data(), extension_types.size(), sizeof(uint16_t),
+ compare_uint16_t);
+ for (size_t i = 1; i < num_extensions; i++) {
if (extension_types[i - 1] == extension_types[i]) {
- goto done;
+ return 0;
}
}
- ret = 1;
-
-done:
- OPENSSL_free(extension_types);
- return ret;
+ return 1;
}
int ssl_client_hello_init(SSL *ssl, SSL_CLIENT_HELLO *out,
@@ -2102,13 +2094,11 @@
// We received a HelloRetryRequest without a new curve, so there is no new
// share to append. Leave |hs->key_share| as-is.
if (group_id == 0 &&
- !CBB_add_bytes(&kse_bytes, hs->key_share_bytes,
- hs->key_share_bytes_len)) {
+ !CBB_add_bytes(&kse_bytes, hs->key_share_bytes.data(),
+ hs->key_share_bytes.size())) {
return 0;
}
- OPENSSL_free(hs->key_share_bytes);
- hs->key_share_bytes = NULL;
- hs->key_share_bytes_len = 0;
+ hs->key_share_bytes.Reset();
if (group_id == 0) {
return CBB_flush(out);
}
@@ -2142,15 +2132,11 @@
return 0;
}
- if (!hs->received_hello_retry_request) {
- // Save the contents of the extension to repeat it in the second
- // ClientHello.
- hs->key_share_bytes_len = CBB_len(&kse_bytes);
- hs->key_share_bytes =
- (uint8_t *)BUF_memdup(CBB_data(&kse_bytes), CBB_len(&kse_bytes));
- if (hs->key_share_bytes == NULL) {
- return 0;
- }
+ // Save the contents of the extension to repeat it in the second ClientHello.
+ if (!hs->received_hello_retry_request &&
+ !hs->key_share_bytes.CopyFrom(
+ MakeConstSpan(CBB_data(&kse_bytes), CBB_len(&kse_bytes)))) {
+ return 0;
}
return CBB_flush(out);
@@ -2310,7 +2296,7 @@
// https://tools.ietf.org/html/draft-ietf-tls-tls13-16#section-4.2.2
static int ext_cookie_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) {
- if (hs->cookie == NULL) {
+ if (hs->cookie.size() == 0) {
return 1;
}
@@ -2318,15 +2304,13 @@
if (!CBB_add_u16(out, TLSEXT_TYPE_cookie) ||
!CBB_add_u16_length_prefixed(out, &contents) ||
!CBB_add_u16_length_prefixed(&contents, &cookie) ||
- !CBB_add_bytes(&cookie, hs->cookie, hs->cookie_len) ||
+ !CBB_add_bytes(&cookie, hs->cookie.data(), hs->cookie.size()) ||
!CBB_flush(out)) {
return 0;
}
// The cookie is no longer needed in memory.
- OPENSSL_free(hs->cookie);
- hs->cookie = NULL;
- hs->cookie_len = 0;
+ hs->cookie.Reset();
return 1;
}
diff --git a/ssl/tls13_client.cc b/ssl/tls13_client.cc
index 2ac6195..b6ff840 100644
--- a/ssl/tls13_client.cc
+++ b/ssl/tls13_client.cc
@@ -99,7 +99,7 @@
return ssl_hs_error;
}
- if (!CBS_stow(&cookie_value, &hs->cookie, &hs->cookie_len)) {
+ if (!hs->cookie.CopyFrom(cookie_value)) {
return ssl_hs_error;
}
}
@@ -841,10 +841,7 @@
void ssl_clear_tls13_state(SSL_HANDSHAKE *hs) {
hs->key_share.reset();
-
- OPENSSL_free(hs->key_share_bytes);
- hs->key_share_bytes = NULL;
- hs->key_share_bytes_len = 0;
+ hs->key_share_bytes.Reset();
}
} // namespace bssl