1 | #ifndef CPR_SSLOPTIONS_H |
2 | #define CPR_SSLOPTIONS_H |
3 | |
4 | #include <memory> |
5 | #include <string> |
6 | #include <vector> |
7 | |
8 | #include <cpr/filesystem.h> |
9 | #include <curl/curl.h> |
10 | |
11 | #include "cpr/util.h" |
12 | #include <utility> |
13 | |
14 | #define __LIBCURL_VERSION_GTE(major, minor) ((LIBCURL_VERSION_MAJOR > (major)) || ((LIBCURL_VERSION_MAJOR == (major)) && (LIBCURL_VERSION_MINOR >= (minor)))) |
15 | #define __LIBCURL_VERSION_LT(major, minor) ((LIBCURL_VERSION_MAJOR < (major)) || ((LIBCURL_VERSION_MAJOR == (major)) && (LIBCURL_VERSION_MINOR < (minor)))) |
16 | |
17 | #ifndef SUPPORT_ALPN |
18 | #define SUPPORT_ALPN __LIBCURL_VERSION_GTE(7, 36) |
19 | #endif |
20 | #ifndef SUPPORT_NPN |
21 | #define SUPPORT_NPN __LIBCURL_VERSION_GTE(7, 36) && __LIBCURL_VERSION_LT(7, 86) |
22 | #endif |
23 | |
24 | #ifndef SUPPORT_SSLv2 |
25 | #define SUPPORT_SSLv2 __LIBCURL_VERSION_LT(7, 19) |
26 | #endif |
27 | #ifndef SUPPORT_SSLv3 |
28 | #define SUPPORT_SSLv3 __LIBCURL_VERSION_LT(7, 39) |
29 | #endif |
30 | #ifndef SUPPORT_TLSv1_0 |
31 | #define SUPPORT_TLSv1_0 __LIBCURL_VERSION_GTE(7, 34) |
32 | #endif |
33 | #ifndef SUPPORT_TLSv1_1 |
34 | #define SUPPORT_TLSv1_1 __LIBCURL_VERSION_GTE(7, 34) |
35 | #endif |
36 | #ifndef SUPPORT_TLSv1_2 |
37 | #define SUPPORT_TLSv1_2 __LIBCURL_VERSION_GTE(7, 34) |
38 | #endif |
39 | #ifndef SUPPORT_TLSv1_3 |
40 | #define SUPPORT_TLSv1_3 __LIBCURL_VERSION_GTE(7, 52) |
41 | #endif |
42 | #ifndef SUPPORT_MAX_TLS_VERSION |
43 | #define SUPPORT_MAX_TLS_VERSION __LIBCURL_VERSION_GTE(7, 54) |
44 | #endif |
45 | #ifndef SUPPORT_MAX_TLSv1_1 |
46 | #define SUPPORT_MAX_TLSv1_1 __LIBCURL_VERSION_GTE(7, 54) |
47 | #endif |
48 | #ifndef SUPPORT_MAX_TLSv1_2 |
49 | #define SUPPORT_MAX_TLSv1_2 __LIBCURL_VERSION_GTE(7, 54) |
50 | #endif |
51 | #ifndef SUPPORT_MAX_TLSv1_3 |
52 | #define SUPPORT_MAX_TLSv1_3 __LIBCURL_VERSION_GTE(7, 54) |
53 | #endif |
54 | #ifndef SUPPORT_TLSv13_CIPHERS |
55 | #define SUPPORT_TLSv13_CIPHERS __LIBCURL_VERSION_GTE(7, 61) |
56 | #endif |
57 | #ifndef SUPPORT_SESSIONID_CACHE |
58 | #define SUPPORT_SESSIONID_CACHE __LIBCURL_VERSION_GTE(7, 16) |
59 | #endif |
60 | #ifndef SUPPORT_SSL_FALSESTART |
61 | #define SUPPORT_SSL_FALSESTART __LIBCURL_VERSION_GTE(7, 42) |
62 | #endif |
63 | #ifndef SUPPORT_SSL_NO_REVOKE |
64 | #define SUPPORT_SSL_NO_REVOKE __LIBCURL_VERSION_GTE(7, 44) |
65 | #endif |
66 | #ifndef SUPPORT_CURLOPT_SSLKEY_BLOB |
67 | #define SUPPORT_CURLOPT_SSLKEY_BLOB __LIBCURL_VERSION_GTE(7, 71) |
68 | #endif |
69 | #ifndef SUPPORT_CURLOPT_SSL_CTX_FUNCTION |
70 | #define SUPPORT_CURLOPT_SSL_CTX_FUNCTION __LIBCURL_VERSION_GTE(7, 11) |
71 | #endif |
72 | |
73 | namespace cpr { |
74 | |
75 | class VerifySsl { |
76 | public: |
77 | VerifySsl() = default; |
78 | // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions) |
79 | VerifySsl(bool p_verify) : verify(p_verify) {} |
80 | |
81 | explicit operator bool() const { |
82 | return verify; |
83 | } |
84 | |
85 | bool verify = true; |
86 | }; |
87 | |
88 | namespace ssl { |
89 | |
90 | // set SSL client certificate |
91 | class CertFile { |
92 | public: |
93 | // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions) |
94 | CertFile(fs::path&& p_filename) : filename(std::move(p_filename)) {} |
95 | |
96 | virtual ~CertFile() = default; |
97 | |
98 | const fs::path filename; |
99 | |
100 | virtual const char* GetCertType() const { |
101 | return "PEM" ; |
102 | } |
103 | }; |
104 | |
105 | using PemCert = CertFile; |
106 | |
107 | class DerCert : public CertFile { |
108 | public: |
109 | // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions) |
110 | DerCert(fs::path&& p_filename) : CertFile(std::move(p_filename)) {} |
111 | |
112 | virtual ~DerCert() = default; |
113 | |
114 | const char* GetCertType() const override { |
115 | return "DER" ; |
116 | } |
117 | }; |
118 | |
119 | // specify private keyfile for TLS and SSL client cert |
120 | class KeyFile { |
121 | public: |
122 | // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions) |
123 | KeyFile(fs::path&& p_filename) : filename(std::move(p_filename)) {} |
124 | |
125 | template <typename FileType, typename PassType> |
126 | KeyFile(FileType&& p_filename, PassType p_password) : filename(std::forward<FileType>(p_filename)), password(std::move(p_password)) {} |
127 | |
128 | virtual ~KeyFile() { |
129 | util::secureStringClear(s&: password); |
130 | } |
131 | |
132 | fs::path filename; |
133 | std::string password; |
134 | |
135 | virtual const char* GetKeyType() const { |
136 | return "PEM" ; |
137 | } |
138 | }; |
139 | |
140 | #if SUPPORT_CURLOPT_SSLKEY_BLOB |
141 | class KeyBlob { |
142 | public: |
143 | // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions) |
144 | KeyBlob(std::string&& p_blob) : blob(std::move(p_blob)) {} |
145 | |
146 | template <typename BlobType, typename PassType> |
147 | KeyBlob(BlobType&& p_blob, PassType p_password) : blob(std::forward<BlobType>(p_blob)), password(std::move(p_password)) {} |
148 | |
149 | virtual ~KeyBlob() { |
150 | util::secureStringClear(s&: password); |
151 | } |
152 | |
153 | std::string blob; |
154 | std::string password; |
155 | |
156 | virtual const char* GetKeyType() const { |
157 | return "PEM" ; |
158 | } |
159 | }; |
160 | #endif |
161 | |
162 | using PemKey = KeyFile; |
163 | |
164 | class DerKey : public KeyFile { |
165 | public: |
166 | // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions) |
167 | DerKey(fs::path&& p_filename) : KeyFile(std::move(p_filename)) {} |
168 | |
169 | template <typename FileType, typename PassType> |
170 | DerKey(FileType&& p_filename, PassType p_password) : KeyFile(std::forward<FileType>(p_filename), std::move(p_password)) {} |
171 | |
172 | virtual ~DerKey() = default; |
173 | |
174 | const char* GetKeyType() const override { |
175 | return "DER" ; |
176 | } |
177 | }; |
178 | |
179 | class PinnedPublicKey { |
180 | public: |
181 | // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions) |
182 | PinnedPublicKey(std::string&& p_pinned_public_key) : pinned_public_key(std::move(p_pinned_public_key)) {} |
183 | |
184 | const std::string pinned_public_key; |
185 | }; |
186 | |
187 | #if SUPPORT_ALPN |
188 | // This option enables/disables ALPN in the SSL handshake (if the SSL backend libcurl is built to |
189 | // use supports it), which can be used to negotiate http2. |
190 | class ALPN { |
191 | public: |
192 | ALPN() = default; |
193 | // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions) |
194 | ALPN(bool p_enabled) : enabled(p_enabled) {} |
195 | |
196 | explicit operator bool() const { |
197 | return enabled; |
198 | } |
199 | |
200 | bool enabled = true; |
201 | }; |
202 | #endif // SUPPORT_ALPN |
203 | |
204 | #if SUPPORT_NPN |
205 | // This option enables/disables NPN in the SSL handshake (if the SSL backend libcurl is built to |
206 | // use supports it), which can be used to negotiate http2. |
207 | class NPN { |
208 | public: |
209 | NPN() = default; |
210 | // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions) |
211 | NPN(bool p_enabled) : enabled(p_enabled) {} |
212 | |
213 | explicit operator bool() const { |
214 | return enabled; |
215 | } |
216 | |
217 | bool enabled = true; |
218 | }; |
219 | #endif // SUPPORT_NPN |
220 | |
221 | // This option determines whether libcurl verifies that the server cert is for the server it is |
222 | // known as. |
223 | class VerifyHost { |
224 | public: |
225 | VerifyHost() = default; |
226 | // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions) |
227 | VerifyHost(bool p_enabled) : enabled(p_enabled) {} |
228 | |
229 | explicit operator bool() const { |
230 | return enabled; |
231 | } |
232 | |
233 | bool enabled = true; |
234 | }; |
235 | |
236 | // This option determines whether libcurl verifies the authenticity of the peer's certificate. |
237 | class VerifyPeer { |
238 | public: |
239 | VerifyPeer() = default; |
240 | // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions) |
241 | VerifyPeer(bool p_enabled) : enabled(p_enabled) {} |
242 | |
243 | explicit operator bool() const { |
244 | return enabled; |
245 | } |
246 | |
247 | bool enabled = true; |
248 | }; |
249 | |
250 | // This option determines whether libcurl verifies the status of the server cert using the |
251 | // "Certificate Status Request" TLS extension (aka. OCSP stapling). |
252 | class VerifyStatus { |
253 | public: |
254 | // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions) |
255 | VerifyStatus(bool p_enabled) : enabled(p_enabled) {} |
256 | |
257 | explicit operator bool() const { |
258 | return enabled; |
259 | } |
260 | |
261 | bool enabled = false; |
262 | }; |
263 | |
264 | // TLS v1.0 or later |
265 | struct TLSv1 {}; |
266 | #if SUPPORT_SSLv2 |
267 | // SSL v2 (but not SSLv3) |
268 | struct SSLv2 {}; |
269 | #endif |
270 | #if SUPPORT_SSLv3 |
271 | // SSL v3 (but not SSLv2) |
272 | struct SSLv3 {}; |
273 | #endif |
274 | #if SUPPORT_TLSv1_0 |
275 | // TLS v1.0 or later (Added in 7.34.0) |
276 | struct TLSv1_0 {}; |
277 | #endif |
278 | #if SUPPORT_TLSv1_1 |
279 | // TLS v1.1 or later (Added in 7.34.0) |
280 | struct TLSv1_1 {}; |
281 | #endif |
282 | #if SUPPORT_TLSv1_2 |
283 | // TLS v1.2 or later (Added in 7.34.0) |
284 | struct TLSv1_2 {}; |
285 | #endif |
286 | #if SUPPORT_TLSv1_3 |
287 | // TLS v1.3 or later (Added in 7.52.0) |
288 | struct TLSv1_3 {}; |
289 | #endif |
290 | #if SUPPORT_MAX_TLS_VERSION |
291 | // The flag defines the maximum supported TLS version by libcurl, or the default value from the SSL |
292 | // library is used. |
293 | struct MaxTLSVersion {}; |
294 | #endif |
295 | #if SUPPORT_MAX_TLSv1_0 |
296 | // The flag defines maximum supported TLS version as TLSv1.0. (Added in 7.54.0) |
297 | struct MaxTLSv1_0 {}; |
298 | #endif |
299 | #if SUPPORT_MAX_TLSv1_1 |
300 | // The flag defines maximum supported TLS version as TLSv1.1. (Added in 7.54.0) |
301 | struct MaxTLSv1_1 {}; |
302 | #endif |
303 | #if SUPPORT_MAX_TLSv1_2 |
304 | // The flag defines maximum supported TLS version as TLSv1.2. (Added in 7.54.0) |
305 | struct MaxTLSv1_2 {}; |
306 | #endif |
307 | #if SUPPORT_MAX_TLSv1_3 |
308 | // The flag defines maximum supported TLS version as TLSv1.3. (Added in 7.54.0) |
309 | struct MaxTLSv1_3 {}; |
310 | #endif |
311 | |
312 | // path to Certificate Authority (CA) bundle |
313 | class CaInfo { |
314 | public: |
315 | // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions) |
316 | CaInfo(fs::path&& p_filename) : filename(std::move(p_filename)) {} |
317 | |
318 | fs::path filename; |
319 | }; |
320 | |
321 | // specify directory holding CA certificates |
322 | class CaPath { |
323 | public: |
324 | // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions) |
325 | CaPath(fs::path&& p_filename) : filename(std::move(p_filename)) {} |
326 | |
327 | fs::path filename; |
328 | }; |
329 | |
330 | #if SUPPORT_CURLOPT_SSL_CTX_FUNCTION |
331 | class CaBuffer { |
332 | public: |
333 | // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions) |
334 | CaBuffer(std::string&& p_buffer) : buffer(std::move(p_buffer)) {} |
335 | |
336 | const std::string buffer; |
337 | }; |
338 | #endif |
339 | |
340 | // specify a Certificate Revocation List file |
341 | class Crl { |
342 | public: |
343 | // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions) |
344 | Crl(fs::path&& p_filename) : filename(std::move(p_filename)) {} |
345 | |
346 | fs::path filename; |
347 | }; |
348 | |
349 | // specify ciphers to use for TLS |
350 | class Ciphers { |
351 | public: |
352 | // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions) |
353 | Ciphers(std::string&& p_ciphers) : ciphers(std::move(p_ciphers)) {} |
354 | |
355 | std::string ciphers; |
356 | }; |
357 | |
358 | #if SUPPORT_TLSv13_CIPHERS |
359 | // specify ciphers suites to use for TLS 1.3 |
360 | class TLS13_Ciphers { |
361 | public: |
362 | // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions) |
363 | TLS13_Ciphers(std::string&& p_ciphers) : ciphers(std::move(p_ciphers)) {} |
364 | |
365 | std::string ciphers; |
366 | }; |
367 | #endif |
368 | |
369 | #if SUPPORT_SESSIONID_CACHE |
370 | // enable/disable use of the SSL session-ID cache |
371 | class SessionIdCache { |
372 | public: |
373 | SessionIdCache() = default; |
374 | // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions) |
375 | SessionIdCache(bool p_enabled) : enabled(p_enabled) {} |
376 | |
377 | explicit operator bool() const { |
378 | return enabled; |
379 | } |
380 | |
381 | bool enabled = true; |
382 | }; |
383 | #endif |
384 | |
385 | #if SUPPORT_SSL_FALSESTART |
386 | class SslFastStart { |
387 | public: |
388 | SslFastStart() = default; |
389 | // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions) |
390 | SslFastStart(bool p_enabled) : enabled(p_enabled) {} |
391 | |
392 | explicit operator bool() const { |
393 | return enabled; |
394 | } |
395 | |
396 | bool enabled = false; |
397 | }; |
398 | #endif |
399 | |
400 | class NoRevoke { |
401 | public: |
402 | NoRevoke() = default; |
403 | // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions) |
404 | NoRevoke(bool p_enabled) : enabled(p_enabled) {} |
405 | |
406 | explicit operator bool() const { |
407 | return enabled; |
408 | } |
409 | |
410 | bool enabled = false; |
411 | }; |
412 | |
413 | } // namespace ssl |
414 | |
415 | struct SslOptions { |
416 | // We don't use fs::path here, as this leads to problems using windows |
417 | std::string cert_file; |
418 | std::string cert_type; |
419 | // We don't use fs::path here, as this leads to problems using windows |
420 | std::string key_file; |
421 | #if SUPPORT_CURLOPT_SSLKEY_BLOB |
422 | std::string key_blob; |
423 | #endif |
424 | std::string key_type; |
425 | std::string key_pass; |
426 | std::string pinned_public_key; |
427 | #if SUPPORT_ALPN |
428 | bool enable_alpn = true; |
429 | #endif // SUPPORT_ALPN |
430 | #if SUPPORT_NPN |
431 | bool enable_npn = true; |
432 | #endif // SUPPORT_ALPN |
433 | bool verify_host = true; |
434 | bool verify_peer = true; |
435 | bool verify_status = false; |
436 | int ssl_version = CURL_SSLVERSION_DEFAULT; |
437 | #if SUPPORT_SSL_NO_REVOKE |
438 | bool ssl_no_revoke = false; |
439 | #endif |
440 | #if SUPPORT_MAX_TLS_VERSION |
441 | int max_version = CURL_SSLVERSION_MAX_DEFAULT; |
442 | #endif |
443 | // We don't use fs::path here, as this leads to problems using windows |
444 | std::string ca_info; |
445 | // We don't use fs::path here, as this leads to problems using windows |
446 | std::string ca_path; |
447 | #if SUPPORT_CURLOPT_SSL_CTX_FUNCTION |
448 | std::string ca_buffer; |
449 | #endif |
450 | // We don't use fs::path here, as this leads to problems using windows |
451 | std::string crl_file; |
452 | std::string ciphers; |
453 | #if SUPPORT_TLSv13_CIPHERS |
454 | std::string tls13_ciphers; |
455 | #endif |
456 | #if SUPPORT_SESSIONID_CACHE |
457 | bool session_id_cache = true; |
458 | #endif |
459 | |
460 | ~SslOptions() noexcept { |
461 | #if SUPPORT_CURLOPT_SSLKEY_BLOB |
462 | util::secureStringClear(s&: key_blob); |
463 | #endif |
464 | util::secureStringClear(s&: key_pass); |
465 | } |
466 | |
467 | void SetOption(const ssl::CertFile& opt) { |
468 | cert_file = opt.filename.string(); |
469 | cert_type = opt.GetCertType(); |
470 | } |
471 | void SetOption(const ssl::KeyFile& opt) { |
472 | key_file = opt.filename.string(); |
473 | key_type = opt.GetKeyType(); |
474 | key_pass = opt.password; |
475 | } |
476 | #if SUPPORT_CURLOPT_SSLKEY_BLOB |
477 | void SetOption(const ssl::KeyBlob& opt) { |
478 | key_blob = opt.blob; |
479 | key_type = opt.GetKeyType(); |
480 | key_pass = opt.password; |
481 | } |
482 | #endif |
483 | void SetOption(const ssl::PinnedPublicKey& opt) { |
484 | pinned_public_key = opt.pinned_public_key; |
485 | } |
486 | |
487 | #if SUPPORT_ALPN |
488 | void SetOption(const ssl::ALPN& opt) { |
489 | enable_alpn = opt.enabled; |
490 | } |
491 | #endif // SUPPORT_ALPN |
492 | #if SUPPORT_NPN |
493 | void SetOption(const ssl::NPN& opt) { |
494 | enable_npn = opt.enabled; |
495 | } |
496 | #endif // SUPPORT_NPN |
497 | void SetOption(const ssl::VerifyHost& opt) { |
498 | verify_host = opt.enabled; |
499 | } |
500 | void SetOption(const ssl::VerifyPeer& opt) { |
501 | verify_peer = opt.enabled; |
502 | } |
503 | void SetOption(const ssl::VerifyStatus& opt) { |
504 | verify_status = opt.enabled; |
505 | } |
506 | void SetOption(const ssl::TLSv1& /*opt*/) { |
507 | ssl_version = CURL_SSLVERSION_TLSv1; |
508 | } |
509 | #if SUPPORT_SSL_NO_REVOKE |
510 | void SetOption(const ssl::NoRevoke& opt) { |
511 | ssl_no_revoke = opt.enabled; |
512 | } |
513 | #endif |
514 | #if SUPPORT_SSLv2 |
515 | void SetOption(const ssl::SSLv2& /*opt*/) { |
516 | ssl_version = CURL_SSLVERSION_SSLv2; |
517 | } |
518 | #endif |
519 | #if SUPPORT_SSLv3 |
520 | void SetOption(const ssl::SSLv3& /*opt*/) { |
521 | ssl_version = CURL_SSLVERSION_SSLv3; |
522 | } |
523 | #endif |
524 | #if SUPPORT_TLSv1_0 |
525 | void SetOption(const ssl::TLSv1_0& /*opt*/) { |
526 | ssl_version = CURL_SSLVERSION_TLSv1_0; |
527 | } |
528 | #endif |
529 | #if SUPPORT_TLSv1_1 |
530 | void SetOption(const ssl::TLSv1_1& /*opt*/) { |
531 | ssl_version = CURL_SSLVERSION_TLSv1_1; |
532 | } |
533 | #endif |
534 | #if SUPPORT_TLSv1_2 |
535 | void SetOption(const ssl::TLSv1_2& /*opt*/) { |
536 | ssl_version = CURL_SSLVERSION_TLSv1_2; |
537 | } |
538 | #endif |
539 | #if SUPPORT_TLSv1_3 |
540 | void SetOption(const ssl::TLSv1_3& /*opt*/) { |
541 | ssl_version = CURL_SSLVERSION_TLSv1_3; |
542 | } |
543 | #endif |
544 | #if SUPPORT_MAX_TLS_VERSION |
545 | void SetOption(const ssl::MaxTLSVersion& /*opt*/) { |
546 | max_version = CURL_SSLVERSION_DEFAULT; |
547 | } |
548 | #endif |
549 | #if SUPPORT_MAX_TLSv1_0 |
550 | void SetOption(const ssl::MaxTLSv1_0& opt) { |
551 | max_version = CURL_SSLVERSION_MAX_TLSv1_0; |
552 | } |
553 | #endif |
554 | #if SUPPORT_MAX_TLSv1_1 |
555 | void SetOption(const ssl::MaxTLSv1_1& /*opt*/) { |
556 | max_version = CURL_SSLVERSION_MAX_TLSv1_1; |
557 | } |
558 | #endif |
559 | #if SUPPORT_MAX_TLSv1_2 |
560 | void SetOption(const ssl::MaxTLSv1_2& /*opt*/) { |
561 | max_version = CURL_SSLVERSION_MAX_TLSv1_2; |
562 | } |
563 | #endif |
564 | #if SUPPORT_MAX_TLSv1_3 |
565 | void SetOption(const ssl::MaxTLSv1_3& /*opt*/) { |
566 | max_version = CURL_SSLVERSION_MAX_TLSv1_3; |
567 | } |
568 | #endif |
569 | void SetOption(const ssl::CaInfo& opt) { |
570 | ca_info = opt.filename.string(); |
571 | } |
572 | void SetOption(const ssl::CaPath& opt) { |
573 | ca_path = opt.filename.string(); |
574 | } |
575 | #if SUPPORT_CURLOPT_SSL_CTX_FUNCTION |
576 | void SetOption(const ssl::CaBuffer& opt) { |
577 | ca_buffer = opt.buffer; |
578 | } |
579 | #endif |
580 | void SetOption(const ssl::Crl& opt) { |
581 | crl_file = opt.filename.string(); |
582 | } |
583 | void SetOption(const ssl::Ciphers& opt) { |
584 | ciphers = opt.ciphers; |
585 | } |
586 | #if SUPPORT_TLSv13_CIPHERS |
587 | void SetOption(const ssl::TLS13_Ciphers& opt) { |
588 | tls13_ciphers = opt.ciphers; |
589 | } |
590 | #endif |
591 | #if SUPPORT_SESSIONID_CACHE |
592 | void SetOption(const ssl::SessionIdCache& opt) { |
593 | session_id_cache = opt.enabled; |
594 | } |
595 | #endif |
596 | }; |
597 | |
598 | namespace priv { |
599 | |
600 | template <typename T> |
601 | void set_ssl_option(SslOptions& opts, T&& t) { |
602 | opts.SetOption(std::forward<T>(t)); |
603 | } |
604 | |
605 | template <typename T, typename... Ts> |
606 | void set_ssl_option(SslOptions& opts, T&& t, Ts&&... ts) { |
607 | set_ssl_option(opts, std::forward<T>(t)); |
608 | set_ssl_option(opts, std::move(ts)...); |
609 | } |
610 | |
611 | } // namespace priv |
612 | |
613 | template <typename... Ts> |
614 | SslOptions Ssl(Ts&&... ts) { |
615 | SslOptions opts; |
616 | priv::set_ssl_option(opts, std::move(ts)...); |
617 | return opts; |
618 | } |
619 | |
620 | } // namespace cpr |
621 | |
622 | #endif |
623 | |