diff --git a/ssl/ssl_cipher.cc b/ssl/ssl_cipher.cc index 54459a19..58995003 100644 --- a/ssl/ssl_cipher.cc +++ b/ssl/ssl_cipher.cc @@ -157,7 +157,7 @@ namespace bssl { // kCiphers is an array of all supported ciphers, sorted by id. -static const SSL_CIPHER kCiphers[] = { +static constexpr SSL_CIPHER kCiphers[] = { // The RSA ciphers // Cipher 02 { @@ -556,19 +556,6 @@ static const CIPHER_ALIAS kCipherAliases[] = { static const size_t kCipherAliasesLen = OPENSSL_ARRAY_SIZE(kCipherAliases); -static int ssl_cipher_id_cmp(const void *in_a, const void *in_b) { - const SSL_CIPHER *a = reinterpret_cast(in_a); - const SSL_CIPHER *b = reinterpret_cast(in_b); - - if (a->id > b->id) { - return 1; - } else if (a->id < b->id) { - return -1; - } else { - return 0; - } -} - bool ssl_cipher_get_evp_aead(const EVP_AEAD **out_aead, size_t *out_mac_secret_len, size_t *out_fixed_iv_len, const SSL_CIPHER *cipher, @@ -1323,6 +1310,36 @@ size_t ssl_cipher_get_record_split_len(const SSL_CIPHER *cipher) { using namespace bssl; +static constexpr int ssl_cipher_id_cmp_inner(const SSL_CIPHER *a, + const SSL_CIPHER *b) { + // C++11's constexpr functions must have a body consisting of just a + // return-statement. + return (a->id > b->id) ? 1 : ((a->id < b->id) ? -1 : 0); +} + +static int ssl_cipher_id_cmp(const void *in_a, const void *in_b) { + return ssl_cipher_id_cmp_inner(reinterpret_cast(in_a), + reinterpret_cast(in_b)); +} + +template +static constexpr size_t countof(T const (&)[N]) { + return N; +} + +template +static constexpr int check_order(const T (&arr)[I], size_t N) { + // C++11's constexpr functions must have a body consisting of just a + // return-statement. + return N > 1 ? ((ssl_cipher_id_cmp_inner(&arr[N - 2], &arr[N - 1]) < 0) + ? check_order(arr, N - 1) + : 0) + : 1; +} + +static_assert(check_order(kCiphers, countof(kCiphers)) == 1, + "Ciphers are not sorted, bsearch won't work"); + const SSL_CIPHER *SSL_get_cipher_by_value(uint16_t value) { SSL_CIPHER c;