Introduce bssl::Array<T> and use it in SSLKeyShare.
An Array<T> is an owning Span<T>. It's similar to absl::FixedArray<T>
but plays well with OPENSSL_malloc and doesn't implement inlining. With
OPENSSL_cleanse folded into OPENSSL_free, we could go nuts with
UniquePtr<uint8_t>, but having the pointer and length tied together is
nice for other reasons. Notably, Array<T> plays great with Span<T>.
Also switch the other parameter to a Span.
Bug: 132
Change-Id: I4cdcf810cf2838208c8ba9fcc6215c1e369dffb8
Reviewed-on: https://boringssl-review.googlesource.com/20667
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/ssl_key_share.cc b/ssl/ssl_key_share.cc
index 207f11e..3ceb180 100644
--- a/ssl/ssl_key_share.cc
+++ b/ssl/ssl_key_share.cc
@@ -17,6 +17,8 @@
#include <assert.h>
#include <string.h>
+#include <utility>
+
#include <openssl/bn.h>
#include <openssl/bytestring.h>
#include <openssl/curve25519.h>
@@ -71,8 +73,8 @@
return true;
}
- bool Finish(uint8_t **out_secret, size_t *out_secret_len, uint8_t *out_alert,
- const uint8_t *peer_key, size_t peer_key_len) override {
+ bool Finish(Array<uint8_t> *out_secret, uint8_t *out_alert,
+ Span<const uint8_t> peer_key) override {
assert(private_key_);
*out_alert = SSL_AD_INTERNAL_ERROR;
@@ -95,8 +97,8 @@
return false;
}
- if (!EC_POINT_oct2point(group.get(), peer_point.get(), peer_key,
- peer_key_len, bn_ctx.get())) {
+ if (!EC_POINT_oct2point(group.get(), peer_point.get(), peer_key.data(),
+ peer_key.size(), bn_ctx.get())) {
*out_alert = SSL_AD_DECODE_ERROR;
return false;
}
@@ -110,14 +112,13 @@
}
// Encode the x-coordinate left-padded with zeros.
- size_t secret_len = (EC_GROUP_get_degree(group.get()) + 7) / 8;
- UniquePtr<uint8_t> secret((uint8_t *)OPENSSL_malloc(secret_len));
- if (!secret || !BN_bn2bin_padded(secret.get(), secret_len, x)) {
+ Array<uint8_t> secret;
+ if (!secret.Init((EC_GROUP_get_degree(group.get()) + 7) / 8) ||
+ !BN_bn2bin_padded(secret.data(), secret.size(), x)) {
return false;
}
- *out_secret = secret.release();
- *out_secret_len = secret_len;
+ *out_secret = std::move(secret);
return true;
}
@@ -142,24 +143,24 @@
return !!CBB_add_bytes(out, public_key, sizeof(public_key));
}
- bool Finish(uint8_t **out_secret, size_t *out_secret_len, uint8_t *out_alert,
- const uint8_t *peer_key, size_t peer_key_len) override {
+ bool Finish(Array<uint8_t> *out_secret, uint8_t *out_alert,
+ Span<const uint8_t> peer_key) override {
*out_alert = SSL_AD_INTERNAL_ERROR;
- UniquePtr<uint8_t> secret((uint8_t *)OPENSSL_malloc(32));
- if (!secret) {
+ Array<uint8_t> secret;
+ if (!secret.Init(32)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
return false;
}
- if (peer_key_len != 32 || !X25519(secret.get(), private_key_, peer_key)) {
+ if (peer_key.size() != 32 ||
+ !X25519(secret.data(), private_key_, peer_key.data())) {
*out_alert = SSL_AD_DECODE_ERROR;
OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ECPOINT);
return false;
}
- *out_secret = secret.release();
- *out_secret_len = 32;
+ *out_secret = std::move(secret);
return true;
}
@@ -202,12 +203,11 @@
}
}
-bool SSLKeyShare::Accept(CBB *out_public_key, uint8_t **out_secret,
- size_t *out_secret_len, uint8_t *out_alert,
- const uint8_t *peer_key, size_t peer_key_len) {
+bool SSLKeyShare::Accept(CBB *out_public_key, Array<uint8_t> *out_secret,
+ uint8_t *out_alert, Span<const uint8_t> peer_key) {
*out_alert = SSL_AD_INTERNAL_ERROR;
return Offer(out_public_key) &&
- Finish(out_secret, out_secret_len, out_alert, peer_key, peer_key_len);
+ Finish(out_secret, out_alert, peer_key);
}
int ssl_nid_to_group_id(uint16_t *out_group_id, int nid) {