Skip to content

Commit 93c2ad6

Browse files
fwosarFabian Wosar
andauthored
Implement support for CURLOPT_CAINFO_BLOB (#1269)
Co-authored-by: Fabian Wosar <[email protected]>
1 parent ec62ffb commit 93c2ad6

File tree

3 files changed

+52
-0
lines changed

3 files changed

+52
-0
lines changed

cpr/session.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -594,6 +594,16 @@ void Session::SetSslOptions(const SslOptions& options) {
594594
if (!options.ca_info.empty()) {
595595
curl_easy_setopt(curl_->handle, CURLOPT_CAINFO, options.ca_info.c_str());
596596
}
597+
#if SUPPORT_CURLOPT_CAINFO_BLOB
598+
if (!options.ca_info_blob.empty()) {
599+
std::string cainfo_blob(options.ca_info_blob);
600+
curl_blob blob{};
601+
blob.data = cainfo_blob.data();
602+
blob.len = cainfo_blob.length();
603+
blob.flags = CURL_BLOB_COPY;
604+
curl_easy_setopt(curl_->handle, CURLOPT_CAINFO_BLOB, &blob);
605+
}
606+
#endif
597607
if (!options.ca_path.empty()) {
598608
curl_easy_setopt(curl_->handle, CURLOPT_CAPATH, options.ca_path.c_str());
599609
}

include/cpr/ssl_options.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@
6767
#ifndef SUPPORT_CURLOPT_SSL_CTX_FUNCTION
6868
#define SUPPORT_CURLOPT_SSL_CTX_FUNCTION LIBCURL_VERSION_NUM >= 0x070B00 // 7.11.0
6969
#endif
70+
#ifndef SUPPORT_CURLOPT_CAINFO_BLOB
71+
#define SUPPORT_CURLOPT_CAINFO_BLOB LIBCURL_VERSION_NUM >= 0x074D00 // 7.77.0
72+
#endif
7073

7174
namespace cpr {
7275

@@ -312,6 +315,17 @@ class CaInfo {
312315
fs::path filename;
313316
};
314317

318+
#if SUPPORT_CURLOPT_CAINFO_BLOB
319+
// Certificate Authority (CA) bundle as blob
320+
class CaInfoBlob {
321+
public:
322+
// NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
323+
CaInfoBlob(std::string&& p_blob) : blob(std::move(p_blob)) {}
324+
325+
std::string blob;
326+
};
327+
#endif
328+
315329
// specify directory holding CA certificates
316330
class CaPath {
317331
public:
@@ -436,6 +450,9 @@ struct SslOptions {
436450
#endif
437451
// We don't use fs::path here, as this leads to problems using windows
438452
std::string ca_info;
453+
#if SUPPORT_CURLOPT_CAINFO_BLOB
454+
std::string ca_info_blob;
455+
#endif
439456
// We don't use fs::path here, as this leads to problems using windows
440457
std::string ca_path;
441458
#if SUPPORT_CURLOPT_SSL_CTX_FUNCTION
@@ -556,6 +573,11 @@ struct SslOptions {
556573
void SetOption(const ssl::CaInfo& opt) {
557574
ca_info = opt.filename.string();
558575
}
576+
#if SUPPORT_CURLOPT_CAINFO_BLOB
577+
void SetOption(const ssl::CaInfoBlob& opt) {
578+
ca_info_blob = opt.blob;
579+
}
580+
#endif
559581
void SetOption(const ssl::CaPath& opt) {
560582
ca_path = opt.filename.string();
561583
}

test/ssl_tests.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,26 @@ TEST(SslTests, LoadKeyFromBlobTestSimpel) {
180180
}
181181
#endif
182182

183+
#if SUPPORT_CURLOPT_CAINFO_BLOB
184+
TEST(SslTests, CaInfoBlobTestSimpel) {
185+
std::this_thread::sleep_for(std::chrono::seconds(1));
186+
187+
Url url{server->GetBaseUrl() + "/hello.html"};
188+
std::string baseDirPath{server->getBaseDirPath()};
189+
std::string crtPath{baseDirPath + "certificates/"};
190+
std::string keyPath{baseDirPath + "keys/"};
191+
192+
SslOptions sslOpts = Ssl(ssl::CaInfoBlob{loadFileContent(crtPath + "ca-bundle.crt")}, ssl::CertFile{crtPath + "client.crt"}, ssl::KeyFile{keyPath + "client.key"}, ssl::VerifyPeer{true}, ssl::PinnedPublicKey{keyPath + "server.pub"}, ssl::VerifyHost{true}, ssl::VerifyStatus{false});
193+
Response response = cpr::Get(url, sslOpts, Timeout{5000}, Verbose{});
194+
std::string expected_text = "Hello world!";
195+
EXPECT_EQ(expected_text, response.text);
196+
EXPECT_EQ(url, response.url);
197+
EXPECT_EQ(std::string{"text/html"}, response.header["content-type"]);
198+
EXPECT_EQ(200, response.status_code);
199+
EXPECT_EQ(ErrorCode::OK, response.error.code) << response.error.message;
200+
}
201+
#endif
202+
183203
fs::path GetBasePath(const std::string& execPath) {
184204
return fs::path(fs::path{execPath}.parent_path().string() + "/").make_preferred();
185205
}

0 commit comments

Comments
 (0)