Give ssl_cipher_preference_list_st a destructor.
Change-Id: I578a284c6a8cae773a97d3d30ad8a5cd13f56164
Reviewed-on: https://boringssl-review.googlesource.com/27491
Commit-Queue: Steven Valdez <svaldez@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
Reviewed-by: Steven Valdez <svaldez@google.com>
diff --git a/ssl/ssl_cipher.cc b/ssl/ssl_cipher.cc
index 32e6c2c..f02fa8a 100644
--- a/ssl/ssl_cipher.cc
+++ b/ssl/ssl_cipher.cc
@@ -811,9 +811,14 @@
*head = curr;
}
-static void ssl_cipher_collect_ciphers(CIPHER_ORDER *co_list,
- CIPHER_ORDER **head_p,
- CIPHER_ORDER **tail_p) {
+static bool ssl_cipher_collect_ciphers(Array<CIPHER_ORDER> *out_co_list,
+ CIPHER_ORDER **out_head,
+ CIPHER_ORDER **out_tail) {
+ Array<CIPHER_ORDER> co_list;
+ if (!co_list.Init(kCiphersLen)) {
+ return false;
+ }
+
size_t co_list_num = 0;
for (const SSL_CIPHER &cipher : kCiphers) {
// TLS 1.3 ciphers do not participate in this mechanism.
@@ -844,9 +849,35 @@
co_list[co_list_num - 1].next = NULL;
- *head_p = &co_list[0];
- *tail_p = &co_list[co_list_num - 1];
+ *out_head = &co_list[0];
+ *out_tail = &co_list[co_list_num - 1];
+ } else {
+ *out_head = nullptr;
+ *out_tail = nullptr;
}
+ *out_co_list = std::move(co_list);
+ return true;
+}
+
+SSLCipherPreferenceList::~SSLCipherPreferenceList() {
+ OPENSSL_free(in_group_flags);
+}
+
+bool SSLCipherPreferenceList::Init(UniquePtr<STACK_OF(SSL_CIPHER)> ciphers_arg,
+ Span<const bool> in_group_flags_arg) {
+ if (sk_SSL_CIPHER_num(ciphers_arg.get()) != in_group_flags_arg.size()) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ return false;
+ }
+
+ Array<bool> copy;
+ if (!copy.CopyFrom(in_group_flags_arg)) {
+ return false;
+ }
+ ciphers = std::move(ciphers_arg);
+ size_t unused_len;
+ copy.Release(&in_group_flags, &unused_len);
+ return true;
}
// ssl_cipher_apply_rule applies the rule type |rule| to ciphers matching its
@@ -1201,15 +1232,8 @@
return true;
}
-bool ssl_create_cipher_list(
- struct ssl_cipher_preference_list_st **out_cipher_list,
- const char *rule_str, bool strict) {
- STACK_OF(SSL_CIPHER) *cipherstack = NULL;
- CIPHER_ORDER *co_list = NULL, *head = NULL, *tail = NULL, *curr;
- uint8_t *in_group_flags = NULL;
- unsigned int num_in_group_flags = 0;
- struct ssl_cipher_preference_list_st *pref_list = NULL;
-
+bool ssl_create_cipher_list(SSLCipherPreferenceList **out_cipher_list,
+ const char *rule_str, bool strict) {
// Return with error if nothing to do.
if (rule_str == NULL || out_cipher_list == NULL) {
return false;
@@ -1218,14 +1242,12 @@
// Now we have to collect the available ciphers from the compiled in ciphers.
// We cannot get more than the number compiled in, so it is used for
// allocation.
- co_list = (CIPHER_ORDER *)OPENSSL_malloc(sizeof(CIPHER_ORDER) * kCiphersLen);
- if (co_list == NULL) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
+ Array<CIPHER_ORDER> co_list;
+ CIPHER_ORDER *head = nullptr, *tail = nullptr;
+ if (!ssl_cipher_collect_ciphers(&co_list, &head, &tail)) {
return false;
}
- ssl_cipher_collect_ciphers(co_list, &head, &tail);
-
// Now arrange all ciphers by preference:
// TODO(davidben): Compute this order once and copy it.
@@ -1285,7 +1307,7 @@
if (strncmp(rule_str, "DEFAULT", 7) == 0) {
if (!ssl_cipher_process_rulestr(SSL_DEFAULT_CIPHER_LIST, &head, &tail,
strict)) {
- goto err;
+ return false;
}
rule_p += 7;
if (*rule_p == ':') {
@@ -1295,75 +1317,52 @@
if (*rule_p != '\0' &&
!ssl_cipher_process_rulestr(rule_p, &head, &tail, strict)) {
- goto err;
+ return false;
}
// Allocate new "cipherstack" for the result, return with error
// if we cannot get one.
- cipherstack = sk_SSL_CIPHER_new_null();
- if (cipherstack == NULL) {
- goto err;
- }
-
- in_group_flags = (uint8_t *)OPENSSL_malloc(kCiphersLen);
- if (!in_group_flags) {
- goto err;
+ UniquePtr<STACK_OF(SSL_CIPHER)> cipherstack(sk_SSL_CIPHER_new_null());
+ Array<bool> in_group_flags;
+ if (cipherstack == nullptr ||
+ !in_group_flags.Init(kCiphersLen)) {
+ return false;
}
// The cipher selection for the list is done. The ciphers are added
// to the resulting precedence to the STACK_OF(SSL_CIPHER).
- for (curr = head; curr != NULL; curr = curr->next) {
+ size_t num_in_group_flags = 0;
+ for (CIPHER_ORDER *curr = head; curr != NULL; curr = curr->next) {
if (curr->active) {
- if (!sk_SSL_CIPHER_push(cipherstack, curr->cipher)) {
- goto err;
+ if (!sk_SSL_CIPHER_push(cipherstack.get(), curr->cipher)) {
+ return false;
}
in_group_flags[num_in_group_flags++] = curr->in_group;
}
}
- OPENSSL_free(co_list); // Not needed any longer
- co_list = NULL;
- pref_list = (ssl_cipher_preference_list_st *)OPENSSL_malloc(
- sizeof(struct ssl_cipher_preference_list_st));
- if (!pref_list) {
- goto err;
+ UniquePtr<SSLCipherPreferenceList> pref_list =
+ MakeUnique<SSLCipherPreferenceList>();
+ if (!pref_list ||
+ !pref_list->Init(
+ std::move(cipherstack),
+ MakeConstSpan(in_group_flags).subspan(0, num_in_group_flags))) {
+ return false;
}
- pref_list->ciphers = cipherstack;
- pref_list->in_group_flags = NULL;
- if (num_in_group_flags) {
- pref_list->in_group_flags = (uint8_t *)OPENSSL_malloc(num_in_group_flags);
- if (!pref_list->in_group_flags) {
- goto err;
- }
- OPENSSL_memcpy(pref_list->in_group_flags, in_group_flags,
- num_in_group_flags);
+
+ if (*out_cipher_list) {
+ Delete(*out_cipher_list);
}
- OPENSSL_free(in_group_flags);
- in_group_flags = NULL;
- if (*out_cipher_list != NULL) {
- ssl_cipher_preference_list_free(*out_cipher_list);
- }
- *out_cipher_list = pref_list;
- pref_list = NULL;
+ *out_cipher_list = pref_list.release();
// Configuring an empty cipher list is an error but still updates the
// output.
- if (sk_SSL_CIPHER_num((*out_cipher_list)->ciphers) == 0) {
+ if (sk_SSL_CIPHER_num((*out_cipher_list)->ciphers.get()) == 0) {
OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CIPHER_MATCH);
return false;
}
return true;
-
-err:
- OPENSSL_free(co_list);
- OPENSSL_free(in_group_flags);
- sk_SSL_CIPHER_free(cipherstack);
- if (pref_list) {
- OPENSSL_free(pref_list->in_group_flags);
- }
- OPENSSL_free(pref_list);
- return false;
}
uint16_t ssl_cipher_get_value(const SSL_CIPHER *cipher) {