Skip to content

Commit 8b7fd79

Browse files
impl(common+storage): remove OpenSSL dependency on Windows (#13785)
On Windows, call the [CNG] APIs instead of OpenSSL to calculate MD5 checksums, compute SHA256 values and signatures. Customers using REST-only libraries can then use only Windows native cryptography libraries. [CNG]: https://learn.microsoft.com/en-us/windows/win32/seccng/cng-portal
1 parent eaeff36 commit 8b7fd79

47 files changed

Lines changed: 1217 additions & 318 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,6 @@ cmake-build-*/
3131
# `google-cloud-cpp` developers use this file to configure the development
3232
# workflow build.
3333
.cloudcxxrc
34+
35+
# Ignore the file with user-defined CMake presets
36+
CMakeUserPresets.json

ci/cloudbuild/builds/cmake-install.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ expected_dirs+=(
9494
./include/google/cloud/gkehub/v1/multiclusteringress
9595
./include/google/cloud/grpc_utils
9696
./include/google/cloud/internal
97+
./include/google/cloud/internal/win32
9798
# no RPC services in google/cloud/metastore/logging
9899
./include/google/cloud/metastore/logging
99100
./include/google/cloud/metastore/logging/v1

cmake/AddPkgConfig.cmake

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,10 @@ endmacro ()
4242
# * ARGN: the names of any pkgconfig modules the generated module depends on
4343
#
4444
function (google_cloud_cpp_add_pkgconfig library name description)
45-
cmake_parse_arguments(_opt "WITH_SHORT_TARGET" "" "" ${ARGN})
45+
cmake_parse_arguments(
46+
_opt "WITH_SHORT_TARGET" ""
47+
"LIBS;WIN32_LIBS;NON_WIN32_LIBS;WIN32_REQUIRES;NON_WIN32_REQUIRES"
48+
${ARGN})
4649
if (_opt_WITH_SHORT_TARGET)
4750
set(target "${library}")
4851
else ()
@@ -60,6 +63,24 @@ function (google_cloud_cpp_add_pkgconfig library name description)
6063
else ()
6164
set(GOOGLE_CLOUD_CPP_PC_LIBS "-lgoogle_cloud_cpp_${library}")
6265
endif ()
66+
list(TRANSFORM _opt_LIBS PREPEND "-l" OUTPUT_VARIABLE _opt_LIBS)
67+
string(JOIN " " GOOGLE_CLOUD_CPP_PC_LIBS "${GOOGLE_CLOUD_CPP_PC_LIBS}"
68+
${_opt_LIBS})
69+
if (WIN32)
70+
list(TRANSFORM _opt_WIN32_LIBS PREPEND "-l" OUTPUT_VARIABLE
71+
_opt_WIN32_LIBS)
72+
string(JOIN " " GOOGLE_CLOUD_CPP_PC_LIBS "${GOOGLE_CLOUD_CPP_PC_LIBS}"
73+
${_opt_WIN32_LIBS})
74+
string(JOIN " " GOOGLE_CLOUD_CPP_PC_REQUIRES
75+
"${GOOGLE_CLOUD_CPP_PC_REQUIRES}" ${_opt_WIN32_REQUIRES})
76+
else ()
77+
list(TRANSFORM _opt_NON_WIN32_LIBS PREPEND "-l" OUTPUT_VARIABLE
78+
_opt_NON_WIN32_LIBS)
79+
string(JOIN " " GOOGLE_CLOUD_CPP_PC_LIBS "${GOOGLE_CLOUD_CPP_PC_LIBS}"
80+
${_opt_NON_WIN32_LIBS})
81+
string(JOIN " " GOOGLE_CLOUD_CPP_PC_REQUIRES
82+
"${GOOGLE_CLOUD_CPP_PC_REQUIRES}" ${_opt_NON_WIN32_REQUIRES})
83+
endif ()
6384
get_target_property(target_defs ${target} INTERFACE_COMPILE_DEFINITIONS)
6485
if (target_defs)
6586
foreach (def ${target_defs})

google/cloud/BUILD.bazel

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,19 @@ cc_library(
7676
],
7777
"//conditions:default": [],
7878
}),
79+
linkopts = select({
80+
"@platforms//os:windows": [
81+
"-DEFAULTLIB:bcrypt.lib",
82+
],
83+
"//conditions:default": [],
84+
}),
85+
local_defines = select({
86+
"@platforms//os:windows": [
87+
"WIN32_LEAN_AND_MEAN",
88+
"_WIN32_WINNT=0x0A00",
89+
],
90+
"//conditions:default": [],
91+
}),
7992
target_compatible_with = select(
8093
{
8194
":enable_opentelemetry_valid": [],
@@ -99,7 +112,6 @@ to your build command, or set this value in your `.bazelrc` file(s).
99112
"//:__pkg__",
100113
],
101114
deps = [
102-
"@boringssl//:crypto",
103115
"@com_google_absl//absl/base",
104116
"@com_google_absl//absl/functional:function_ref",
105117
"@com_google_absl//absl/strings",
@@ -113,6 +125,11 @@ to your build command, or set this value in your `.bazelrc` file(s).
113125
"@io_opentelemetry_cpp//api",
114126
],
115127
"//conditions:default": [],
128+
}) + select({
129+
"@platforms//os:windows": [],
130+
"//conditions:default": [
131+
"@boringssl//:crypto",
132+
],
116133
}),
117134
)
118135

@@ -265,24 +282,34 @@ cc_library(
265282
name = "google_cloud_cpp_rest_internal",
266283
srcs = google_cloud_cpp_rest_internal_srcs,
267284
hdrs = google_cloud_cpp_rest_internal_hdrs,
268-
# These are needed to use the BoringSSL libraries, and should be set in
269-
# any downstream dependency too.
270-
defines = select({
285+
linkopts = select({
286+
"@platforms//os:windows": [
287+
"-DEFAULTLIB:bcrypt.lib",
288+
"-DEFAULTLIB:crypt32.lib",
289+
],
290+
"//conditions:default": [],
291+
}),
292+
local_defines = select({
271293
"@platforms//os:windows": [
272294
"WIN32_LEAN_AND_MEAN",
295+
"_WIN32_WINNT=0x0A00",
273296
],
274297
"//conditions:default": [],
275298
}),
276299
visibility = ["//:__subpackages__"],
277300
deps = [
278301
":google_cloud_cpp_common",
279-
"@boringssl//:crypto",
280-
"@boringssl//:ssl",
281302
"@com_github_curl_curl//:curl",
282303
"@com_github_nlohmann_json//:nlohmann_json",
283304
"@com_google_absl//absl/functional:function_ref",
284305
"@com_google_absl//absl/types:span",
285-
],
306+
] + select({
307+
"@platforms//os:windows": [],
308+
"//conditions:default": [
309+
"@boringssl//:crypto",
310+
"@boringssl//:ssl",
311+
],
312+
}),
286313
)
287314

288315
[cc_test(

google/cloud/config-rest.cmake.in

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ find_dependency(google_cloud_cpp_common)
1717
find_dependency(absl)
1818
find_dependency(CURL)
1919
find_dependency(nlohmann_json)
20-
find_dependency(OpenSSL)
20+
if (NOT WIN32)
21+
find_dependency(OpenSSL)
22+
endif ()
2123

2224
include("${CMAKE_CURRENT_LIST_DIR}/google_cloud_cpp_rest_internal-targets.cmake")

google/cloud/google_cloud_cpp_common.cmake

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@
1414
# limitations under the License.
1515
# ~~~
1616

17-
find_package(OpenSSL REQUIRED)
17+
if (NOT WIN32)
18+
find_package(OpenSSL REQUIRED)
19+
endif ()
1820

1921
# Generate the version information from the CMake values.
2022
configure_file(internal/version_info.h.in
@@ -179,8 +181,14 @@ target_link_libraries(
179181
absl::str_format
180182
absl::time
181183
absl::variant
182-
Threads::Threads
183-
OpenSSL::Crypto)
184+
Threads::Threads)
185+
if (WIN32)
186+
target_compile_definitions(google_cloud_cpp_common
187+
PRIVATE WIN32_LEAN_AND_MEAN)
188+
target_link_libraries(google_cloud_cpp_common PUBLIC bcrypt)
189+
else ()
190+
target_link_libraries(google_cloud_cpp_common PUBLIC OpenSSL::Crypto)
191+
endif ()
184192

185193
if (opentelemetry IN_LIST GOOGLE_CLOUD_CPP_ENABLE)
186194
find_package(opentelemetry-cpp CONFIG)
@@ -249,8 +257,11 @@ google_cloud_cpp_add_pkgconfig(
249257
"absl_time"
250258
"absl_time_zone"
251259
"absl_variant"
252-
"openssl"
253-
"${GOOGLE_CLOUD_CPP_OPENTELEMETRY_API}")
260+
"${GOOGLE_CLOUD_CPP_OPENTELEMETRY_API}"
261+
NON_WIN32_REQUIRES
262+
openssl
263+
WIN32_LIBS
264+
bcrypt)
254265

255266
# Create and install the CMake configuration files.
256267
configure_file("config.cmake.in" "google_cloud_cpp_common-config.cmake" @ONLY)

google/cloud/google_cloud_cpp_rest_internal.bzl

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ google_cloud_cpp_rest_internal_hdrs = [
5454
"internal/oauth2_refreshing_credentials_wrapper.h",
5555
"internal/oauth2_service_account_credentials.h",
5656
"internal/oauth2_universe_domain.h",
57-
"internal/openssl_util.h",
57+
"internal/parse_service_account_p12_file.h",
5858
"internal/populate_rest_options.h",
5959
"internal/rest_carrier.h",
6060
"internal/rest_client.h",
@@ -65,10 +65,12 @@ google_cloud_cpp_rest_internal_hdrs = [
6565
"internal/rest_request.h",
6666
"internal/rest_response.h",
6767
"internal/rest_retry_loop.h",
68+
"internal/sign_using_sha256.h",
6869
"internal/tracing_http_payload.h",
6970
"internal/tracing_rest_client.h",
7071
"internal/tracing_rest_response.h",
7172
"internal/unified_rest_credentials.h",
73+
"internal/win32/win32_helpers.h",
7274
"rest_options.h",
7375
]
7476

@@ -105,7 +107,8 @@ google_cloud_cpp_rest_internal_srcs = [
105107
"internal/oauth2_refreshing_credentials_wrapper.cc",
106108
"internal/oauth2_service_account_credentials.cc",
107109
"internal/oauth2_universe_domain.cc",
108-
"internal/openssl_util.cc",
110+
"internal/openssl/parse_service_account_p12_file.cc",
111+
"internal/openssl/sign_using_sha256.cc",
109112
"internal/populate_rest_options.cc",
110113
"internal/rest_carrier.cc",
111114
"internal/rest_context.cc",
@@ -117,4 +120,7 @@ google_cloud_cpp_rest_internal_srcs = [
117120
"internal/tracing_rest_client.cc",
118121
"internal/tracing_rest_response.cc",
119122
"internal/unified_rest_credentials.cc",
123+
"internal/win32/parse_service_account_p12_file.cc",
124+
"internal/win32/sign_using_sha256.cc",
125+
"internal/win32/win32_helpers.cc",
120126
]

google/cloud/google_cloud_cpp_rest_internal.cmake

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@
1616

1717
include(IncludeNlohmannJson)
1818
find_package(CURL REQUIRED)
19-
find_package(OpenSSL REQUIRED)
19+
if (NOT WIN32)
20+
find_package(OpenSSL REQUIRED)
21+
endif ()
2022

2123
# the library
2224
add_library(
@@ -90,8 +92,9 @@ add_library(
9092
internal/oauth2_service_account_credentials.h
9193
internal/oauth2_universe_domain.cc
9294
internal/oauth2_universe_domain.h
93-
internal/openssl_util.cc
94-
internal/openssl_util.h
95+
internal/openssl/parse_service_account_p12_file.cc
96+
internal/openssl/sign_using_sha256.cc
97+
internal/parse_service_account_p12_file.h
9598
internal/populate_rest_options.cc
9699
internal/populate_rest_options.h
97100
internal/rest_carrier.cc
@@ -109,6 +112,7 @@ add_library(
109112
internal/rest_response.cc
110113
internal/rest_response.h
111114
internal/rest_retry_loop.h
115+
internal/sign_using_sha256.h
112116
internal/tracing_http_payload.cc
113117
internal/tracing_http_payload.h
114118
internal/tracing_rest_client.cc
@@ -117,15 +121,25 @@ add_library(
117121
internal/tracing_rest_response.h
118122
internal/unified_rest_credentials.cc
119123
internal/unified_rest_credentials.h
124+
internal/win32/parse_service_account_p12_file.cc
125+
internal/win32/sign_using_sha256.cc
126+
internal/win32/win32_helpers.cc
127+
internal/win32/win32_helpers.h
120128
rest_options.h)
121129
target_link_libraries(
122130
google_cloud_cpp_rest_internal
123131
PUBLIC absl::span google-cloud-cpp::common CURL::libcurl
124-
nlohmann_json::nlohmann_json OpenSSL::SSL OpenSSL::Crypto)
132+
nlohmann_json::nlohmann_json)
125133
if (WIN32)
134+
target_compile_definitions(google_cloud_cpp_rest_internal
135+
PRIVATE WIN32_LEAN_AND_MEAN)
126136
# We use `setsockopt()` directly, which requires the ws2_32 (Winsock2 for
127137
# Windows32?) library on Windows.
128-
target_link_libraries(google_cloud_cpp_rest_internal PUBLIC ws2_32)
138+
target_link_libraries(google_cloud_cpp_rest_internal PUBLIC ws2_32 bcrypt
139+
crypt32)
140+
else ()
141+
target_link_libraries(google_cloud_cpp_rest_internal PUBLIC OpenSSL::SSL
142+
OpenSSL::Crypto)
129143
endif ()
130144
google_cloud_cpp_add_common_options(google_cloud_cpp_rest_internal)
131145
target_include_directories(
@@ -165,9 +179,17 @@ google_cloud_cpp_install_headers(google_cloud_cpp_rest_internal
165179
include/google/cloud)
166180

167181
google_cloud_cpp_add_pkgconfig(
168-
rest_internal "REST library for the Google Cloud C++ Client Library"
182+
rest_internal
183+
"REST library for the Google Cloud C++ Client Library"
169184
"Provides REST Transport for the Google Cloud C++ Client Library."
170-
"google_cloud_cpp_common" "libcurl" "openssl")
185+
"google_cloud_cpp_common"
186+
"libcurl"
187+
NON_WIN32_REQUIRES
188+
openssl
189+
WIN32_LIBS
190+
ws2_32
191+
bcrypt
192+
crypt32)
171193

172194
# Create and install the CMake configuration files.
173195
include(CMakePackageConfigHelpers)

google/cloud/internal/curl_wrappers.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,10 @@
2020
#include "google/cloud/log.h"
2121
#include "absl/strings/match.h"
2222
#include "absl/strings/str_split.h"
23+
#ifndef _WIN32
2324
#include <openssl/crypto.h>
2425
#include <openssl/opensslv.h>
26+
#endif
2527
#include <algorithm>
2628
#include <cctype>
2729
#include <csignal>
@@ -40,6 +42,9 @@ namespace {
4042
// LibreSSL calls itself OpenSSL > 2.0, but it really is based on SSL 1.0.2
4143
// and requires locks.
4244
#define GOOGLE_CLOUD_CPP_SSL_REQUIRES_LOCKS 1
45+
#elif defined(_WIN32)
46+
// We don't use OpenSSL on Windows.
47+
#define GOOGLE_CLOUD_CPP_SSL_REQUIRES_LOCKS 0
4348
#elif OPENSSL_VERSION_NUMBER < 0x10100000L // Older than version 1.1.0
4449
// Before 1.1.0 OpenSSL requires locks to be used by multiple threads.
4550
#define GOOGLE_CLOUD_CPP_SSL_REQUIRES_LOCKS 1

google/cloud/internal/curl_wrappers_locking_already_present_test.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15+
#ifndef _WIN32
1516
#include "google/cloud/internal/curl_options.h"
1617
#include "google/cloud/internal/curl_wrappers.h"
1718
#include <gmock/gmock.h>
@@ -42,3 +43,4 @@ GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
4243
} // namespace rest_internal
4344
} // namespace cloud
4445
} // namespace google
46+
#endif // _WIN32

0 commit comments

Comments
 (0)