Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 16 additions & 36 deletions google/cloud/internal/openssl/ssl_ec_curves.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
#include <openssl/ec.h>
#include <openssl/ssl.h>
#include <algorithm>
#include <array>
#include <memory>
#include <string>
#include <vector>
Expand All @@ -27,14 +26,12 @@ namespace cloud {
namespace rest_internal {
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN

#if OPENSSL_VERSION_NUMBER >= 0x30500000L || defined(OPENSSL_IS_BORINGSSL)
#if OPENSSL_VERSION_NUMBER >= 0x30500000L
namespace {
struct OpenSslDeleter {
#if OPENSSL_VERSION_NUMBER >= 0x30500000L
void operator()(STACK_OF(OPENSSL_CSTRING) * ptr) {
sk_OPENSSL_CSTRING_free(ptr);
}
#endif
void operator()(SSL_CTX* ptr) { SSL_CTX_free(ptr); }
};
} // namespace
Expand All @@ -56,44 +53,27 @@ std::vector<std::string> AvailableCryptoGroups() {
if (name != nullptr) groups.emplace_back(name);
}
}
#else // OPENSSL_VERSION_NUMBER < 0x30500000L
std::vector<std::string> builtin_groups;
#elif defined(OPENSSL_IS_BORINGSSL) && defined(SSL_GROUP_SECP256R1)
// BoringSSL reports the names of all the TLS groups it supports. It added
// `SSL_get_all_group_names()` in the same change as the `SSL_GROUP_*`
// macros, so we use the latter to detect the former.
std::vector<char const*> names(SSL_get_all_group_names(nullptr, 0));
SSL_get_all_group_names(names.data(), names.size());
for (char const* name : names) {
if (name != nullptr) groups.emplace_back(name);
}
#elif defined(OPENSSL_IS_BORINGSSL)
// Versions of BoringSSL without `SSL_get_all_group_names()` predate support
// for X25519MLKEM768. Returning an empty list leaves the library's default
// groups unchanged.
#else // OpenSSL < 3.5
size_t const num_curves = EC_get_builtin_curves(nullptr, 0);
std::vector<EC_builtin_curve> builtin(num_curves);
EC_get_builtin_curves(builtin.data(), num_curves);
for (auto const& c : builtin) {
char const* name = OBJ_nid2sn(c.nid);
if (name != nullptr) builtin_groups.emplace_back(name);
}
#ifdef OPENSSL_IS_BORINGSSL
// "secp224r1" can be included in the builtin curves, but it results in a
// "CURL error [59]=Couldn't use specified SSL cipher" error.
for (auto const& curve : builtin_groups) {
if (curve == "secp224r1") continue;
groups.emplace_back(curve);
}

// Unlike OpenSSL, BoringSSL does not provide a way to query the available
// curves, so we have to probe the library using a temporary SSL_CTX.
std::array<std::string_view, 3> constexpr kCandidates{
"X25519",
"X25519MLKEM768",
"X25519Kyber768Draft00",
};

auto ctx =
std::unique_ptr<SSL_CTX, OpenSslDeleter>(SSL_CTX_new(TLS_method()));
if (!ctx) return groups;
for (auto const& curve : kCandidates) {
// SSL_CTX_set1_curves_list returns 1 if the curve(s) are
// recognized/supported
if (SSL_CTX_set1_curves_list(ctx.get(), curve.data()) == 1) {
groups.emplace_back(curve);
}
if (name != nullptr) groups.emplace_back(name);
}
#else
groups = std::move(builtin_groups);
#endif // OPENSSL_IS_BORINGSSL
#endif // OPENSSL_VERSION_NUMBER >= 0x30500000L
Comment thread
colinmoy marked this conversation as resolved.
return groups;
}
Expand Down
Loading