]> git.ipfire.org Git - thirdparty/squid.git/blame - src/security/PeerOptions.cc
Shuffle TLS NPN logic to libsecurity
[thirdparty/squid.git] / src / security / PeerOptions.cc
CommitLineData
9a2f63e7 1/*
be75380c 2 * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
9a2f63e7
AJ
3 *
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
7 */
8
9#include "squid.h"
8250ca31 10#include "base/Packable.h"
0b0e0864 11#include "Debug.h"
6bd62757 12#include "fatal.h"
0b0e0864 13#include "globals.h"
1cc44095 14#include "parser/Tokenizer.h"
b24e9ae7 15#include "parser/Tokenizer.h"
7f2cd2e8 16#include "Parsing.h"
9a2f63e7
AJ
17#include "security/PeerOptions.h"
18
19#if USE_OPENSSL
20#include "ssl/support.h"
21#endif
22
7e62a74f 23Security::PeerOptions Security::ProxyOutgoingConfig;
195f8adb 24
9a622f3e 25Security::PeerOptions::PeerOptions(const Security::PeerOptions &p) :
9a622f3e 26 sslOptions(p.sslOptions),
9a622f3e
AJ
27 caDir(p.caDir),
28 crlFile(p.crlFile),
29 sslCipher(p.sslCipher),
30 sslFlags(p.sslFlags),
31 sslDomain(p.sslDomain),
32 parsedOptions(p.parsedOptions),
33 parsedFlags(p.parsedFlags),
d1d72d43 34 certs(p.certs),
86a84cc0 35 caFiles(p.caFiles),
6b19d1f9 36 parsedCrl(p.parsedCrl),
9a622f3e
AJ
37 sslVersion(p.sslVersion),
38 encryptTransport(p.encryptTransport)
39{
8b253b83 40 memcpy(&flags, &p.flags, sizeof(flags));
9a622f3e
AJ
41}
42
0b0e0864
AJ
43void
44Security::PeerOptions::parse(const char *token)
45{
d4ab7b63
AJ
46 if (!*token) {
47 // config says just "ssl" or "tls" (or "tls-")
48 encryptTransport = true;
49 return;
50 }
51
41ee8990
AJ
52 if (strncmp(token, "disable", 7) == 0) {
53 clear();
d4ab7b63
AJ
54 return;
55 }
56
57 if (strncmp(token, "cert=", 5) == 0) {
d1d72d43
AJ
58 KeyData t;
59 t.privateKeyFile = t.certFile = SBuf(token + 5);
60 certs.emplace_back(t);
0b0e0864 61 } else if (strncmp(token, "key=", 4) == 0) {
d1d72d43
AJ
62 if (certs.empty() || certs.back().certFile.isEmpty()) {
63 debugs(3, DBG_PARSE_NOTE(1), "ERROR: cert= option must be set before key= is used.");
64 return;
0b0e0864 65 }
d1d72d43
AJ
66 KeyData &t = certs.back();
67 t.privateKeyFile = SBuf(token + 4);
0b0e0864 68 } else if (strncmp(token, "version=", 8) == 0) {
1cc44095 69 debugs(0, DBG_PARSE_NOTE(1), "UPGRADE WARNING: SSL version= is deprecated. Use options= to limit protocols instead.");
0b0e0864 70 sslVersion = xatoi(token + 8);
1cc44095
AJ
71 } else if (strncmp(token, "min-version=", 12) == 0) {
72 tlsMinVersion = SBuf(token + 12);
0b0e0864
AJ
73 } else if (strncmp(token, "options=", 8) == 0) {
74 sslOptions = SBuf(token + 8);
c62717bd 75 parsedOptions = parseOptions();
0b0e0864
AJ
76 } else if (strncmp(token, "cipher=", 7) == 0) {
77 sslCipher = SBuf(token + 7);
78 } else if (strncmp(token, "cafile=", 7) == 0) {
86a84cc0 79 caFiles.emplace_back(SBuf(token + 7));
0b0e0864
AJ
80 } else if (strncmp(token, "capath=", 7) == 0) {
81 caDir = SBuf(token + 7);
86a84cc0
AJ
82#if !USE_OPENSSL
83 debugs(3, DBG_PARSE_NOTE(1), "WARNING: capath= option requires --with-openssl.");
84#endif
0b0e0864
AJ
85 } else if (strncmp(token, "crlfile=", 8) == 0) {
86 crlFile = SBuf(token + 8);
6b19d1f9 87 loadCrlFile();
0b0e0864 88 } else if (strncmp(token, "flags=", 6) == 0) {
b24e9ae7 89 if (parsedFlags != 0) {
9a622f3e 90 debugs(3, DBG_PARSE_NOTE(1), "WARNING: Overwriting flags=" << sslFlags << " with " << SBuf(token + 6));
b24e9ae7 91 }
0b0e0864 92 sslFlags = SBuf(token + 6);
ec4defdb 93 parsedFlags = parseFlags();
0278bdcb
AJ
94 } else if (strncmp(token, "no-default-ca", 13) == 0) {
95 flags.noDefaultCa = true;
0b0e0864
AJ
96 } else if (strncmp(token, "domain=", 7) == 0) {
97 sslDomain = SBuf(token + 7);
b05d749d
AJ
98 } else if (strncmp(token, "no-npn", 6) == 0) {
99 flags.tlsNpn = false;
9a622f3e
AJ
100 } else {
101 debugs(3, DBG_CRITICAL, "ERROR: Unknown TLS option '" << token << "'");
d4ab7b63 102 return;
0b0e0864 103 }
d4ab7b63
AJ
104
105 encryptTransport = true;
0b0e0864
AJ
106}
107
8250ca31
AJ
108void
109Security::PeerOptions::dumpCfg(Packable *p, const char *pfx) const
110{
111 if (!encryptTransport) {
112 p->appendf(" %sdisable", pfx);
113 return; // no other settings are relevant
114 }
115
d1d72d43
AJ
116 for (auto &i : certs) {
117 if (!i.certFile.isEmpty())
118 p->appendf(" %scert=" SQUIDSBUFPH, pfx, SQUIDSBUFPRINT(i.certFile));
8250ca31 119
d1d72d43
AJ
120 if (!i.privateKeyFile.isEmpty() && i.privateKeyFile != i.certFile)
121 p->appendf(" %skey=" SQUIDSBUFPH, pfx, SQUIDSBUFPRINT(i.privateKeyFile));
122 }
8250ca31
AJ
123
124 if (!sslOptions.isEmpty())
125 p->appendf(" %soptions=" SQUIDSBUFPH, pfx, SQUIDSBUFPRINT(sslOptions));
126
127 if (!sslCipher.isEmpty())
128 p->appendf(" %scipher=" SQUIDSBUFPH, pfx, SQUIDSBUFPRINT(sslCipher));
129
86a84cc0
AJ
130 for (auto i : caFiles) {
131 p->appendf(" %scafile=" SQUIDSBUFPH, pfx, SQUIDSBUFPRINT(i));
132 }
8250ca31
AJ
133
134 if (!caDir.isEmpty())
135 p->appendf(" %scapath=" SQUIDSBUFPH, pfx, SQUIDSBUFPRINT(caDir));
136
137 if (!crlFile.isEmpty())
138 p->appendf(" %scrlfile=" SQUIDSBUFPH, pfx, SQUIDSBUFPRINT(crlFile));
139
140 if (!sslFlags.isEmpty())
141 p->appendf(" %sflags=" SQUIDSBUFPH, pfx, SQUIDSBUFPRINT(sslFlags));
0278bdcb
AJ
142
143 if (flags.noDefaultCa)
144 p->appendf(" %sno-default-ca", pfx);
b05d749d
AJ
145
146 if (!flags.tlsNpn)
147 p->appendf(" %sno-npn", pfx);
8250ca31
AJ
148}
149
585c27eb
AJ
150void
151Security::PeerOptions::updateTlsVersionLimits()
9a2f63e7 152{
1cc44095
AJ
153 if (!tlsMinVersion.isEmpty()) {
154 ::Parser::Tokenizer tok(tlsMinVersion);
155 int64_t v = 0;
bd71ba99 156 if (tok.skip('1') && tok.skip('.') && tok.int64(v, 10, false, 1) && v <= 3) {
1cc44095 157 // only account for TLS here - SSL versions are handled by options= parameter
bd71ba99 158 // avoid affecting options= parameter in cachemgr config report
8250ca31 159#if SSL_OP_NO_TLSv1
1cc44095 160 if (v > 0)
8250ca31
AJ
161 parsedOptions |= SSL_OP_NO_TLSv1;
162#endif
163#if SSL_OP_NO_TLSv1_1
1cc44095 164 if (v > 1)
8250ca31
AJ
165 parsedOptions |= SSL_OP_NO_TLSv1_1;
166#endif
167#if SSL_OP_NO_TLSv1_2
1cc44095 168 if (v > 2)
8250ca31
AJ
169 parsedOptions |= SSL_OP_NO_TLSv1_2;
170#endif
1cc44095
AJ
171
172 } else {
173 debugs(0, DBG_PARSE_NOTE(1), "WARNING: Unknown TLS minimum version: " << tlsMinVersion);
174 }
175
176 } else if (sslVersion > 2) {
177 // backward compatibility hack for sslversion= configuration
178 // only use if tls-min-version=N.N is not present
8250ca31
AJ
179 // values 0-2 for auto and SSLv2 are not supported any longer.
180 // Do it this way so we DO cause changes to options= in cachemgr config report
1cc44095
AJ
181 const char *add = NULL;
182 switch (sslVersion) {
183 case 3:
184 add = "NO_TLSv1,NO_TLSv1_1,NO_TLSv1_2";
185 break;
186 case 4:
187 add = "NO_SSLv3,NO_TLSv1_1,NO_TLSv1_2";
188 break;
189 case 5:
190 add = "NO_SSLv3,NO_TLSv1,NO_TLSv1_2";
191 break;
192 case 6:
193 add = "NO_SSLv3,NO_TLSv1,NO_TLSv1_1";
194 break;
195 default: // nothing
196 break;
197 }
198 if (add) {
199 if (!sslOptions.isEmpty())
200 sslOptions.append(",",1);
201 sslOptions.append(add, strlen(add));
202 }
203 sslVersion = 0; // prevent sslOptions being repeatedly appended
204 }
585c27eb 205}
1cc44095 206
885f0ecf
AJ
207Security::ContextPtr
208Security::PeerOptions::createBlankContext() const
209{
210 Security::ContextPtr t = nullptr;
211
212#if USE_OPENSSL
0a28c16a
AJ
213 Ssl::Initialize();
214
885f0ecf
AJ
215#if (OPENSSL_VERSION_NUMBER >= 0x10100000L)
216 t = SSL_CTX_new(TLS_client_method());
217#else
218 t = SSL_CTX_new(SSLv23_client_method());
219#endif
220 if (!t) {
221 const auto x = ERR_error_string(ERR_get_error(), nullptr);
222 fatalf("Failed to allocate TLS client context: %s\n", x);
223 }
224
225#elif USE_GNUTLS
226 // Initialize for X.509 certificate exchange
227 if (const int x = gnutls_certificate_allocate_credentials(&t)) {
228 fatalf("Failed to allocate TLS client context: error=%d\n", x);
229 }
230
231#else
232 fatal("Failed to allocate TLS client context: No TLS library\n");
233
234#endif
235
236 return t;
237}
238
96993ee0 239Security::ContextPtr
a465e144 240Security::PeerOptions::createClientContext(bool setOptions)
9a2f63e7 241{
96993ee0 242 Security::ContextPtr t = nullptr;
9a2f63e7 243
585c27eb 244 updateTlsVersionLimits();
86a84cc0 245
9a2f63e7 246#if USE_OPENSSL
1f1f29e8 247 // XXX: temporary performance regression. c_str() data copies and prevents this being a const method
d1d72d43 248 t = sslCreateClientContext(*this, (setOptions ? parsedOptions : 0), parsedFlags);
885f0ecf
AJ
249
250#elif USE_GNUTLS && WHEN_READY_FOR_GNUTLS
251 t = createBlankContext();
252
9a2f63e7 253#endif
36092741 254
86a84cc0 255 if (t) {
b05d749d 256 updateContextNpn(t);
86a84cc0
AJ
257 updateContextCa(t);
258 updateContextCrl(t);
259 }
6b19d1f9 260
9a2f63e7
AJ
261 return t;
262}
1f1f29e8 263
6bd62757
AJ
264/// set of options we can parse and what they map to
265static struct ssl_option {
266 const char *name;
267 long value;
268
269} ssl_options[] = {
270
271#if SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
272 {
273 "NETSCAPE_REUSE_CIPHER_CHANGE_BUG", SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
274 },
275#endif
276#if SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG
277 {
278 "SSLREF2_REUSE_CERT_TYPE_BUG", SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG
279 },
280#endif
281#if SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER
282 {
283 "MICROSOFT_BIG_SSLV3_BUFFER", SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER
284 },
285#endif
286#if SSL_OP_SSLEAY_080_CLIENT_DH_BUG
287 {
288 "SSLEAY_080_CLIENT_DH_BUG", SSL_OP_SSLEAY_080_CLIENT_DH_BUG
289 },
290#endif
291#if SSL_OP_TLS_D5_BUG
292 {
293 "TLS_D5_BUG", SSL_OP_TLS_D5_BUG
294 },
295#endif
296#if SSL_OP_TLS_BLOCK_PADDING_BUG
297 {
298 "TLS_BLOCK_PADDING_BUG", SSL_OP_TLS_BLOCK_PADDING_BUG
299 },
300#endif
301#if SSL_OP_TLS_ROLLBACK_BUG
302 {
303 "TLS_ROLLBACK_BUG", SSL_OP_TLS_ROLLBACK_BUG
304 },
305#endif
306#if SSL_OP_ALL
307 {
308 "ALL", (long)SSL_OP_ALL
309 },
310#endif
311#if SSL_OP_SINGLE_DH_USE
312 {
313 "SINGLE_DH_USE", SSL_OP_SINGLE_DH_USE
314 },
315#endif
316#if SSL_OP_EPHEMERAL_RSA
317 {
318 "EPHEMERAL_RSA", SSL_OP_EPHEMERAL_RSA
319 },
320#endif
321#if SSL_OP_PKCS1_CHECK_1
322 {
323 "PKCS1_CHECK_1", SSL_OP_PKCS1_CHECK_1
324 },
325#endif
326#if SSL_OP_PKCS1_CHECK_2
327 {
328 "PKCS1_CHECK_2", SSL_OP_PKCS1_CHECK_2
329 },
330#endif
331#if SSL_OP_NETSCAPE_CA_DN_BUG
332 {
333 "NETSCAPE_CA_DN_BUG", SSL_OP_NETSCAPE_CA_DN_BUG
334 },
335#endif
336#if SSL_OP_NON_EXPORT_FIRST
337 {
338 "NON_EXPORT_FIRST", SSL_OP_NON_EXPORT_FIRST
339 },
340#endif
341#if SSL_OP_CIPHER_SERVER_PREFERENCE
342 {
343 "CIPHER_SERVER_PREFERENCE", SSL_OP_CIPHER_SERVER_PREFERENCE
344 },
345#endif
346#if SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG
347 {
348 "NETSCAPE_DEMO_CIPHER_CHANGE_BUG", SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG
349 },
350#endif
351#if SSL_OP_NO_SSLv3
352 {
353 "NO_SSLv3", SSL_OP_NO_SSLv3
354 },
355#endif
356#if SSL_OP_NO_TLSv1
357 {
358 "NO_TLSv1", SSL_OP_NO_TLSv1
359 },
360#endif
361#if SSL_OP_NO_TLSv1_1
362 {
363 "NO_TLSv1_1", SSL_OP_NO_TLSv1_1
364 },
365#endif
366#if SSL_OP_NO_TLSv1_2
367 {
368 "NO_TLSv1_2", SSL_OP_NO_TLSv1_2
369 },
370#endif
371#if SSL_OP_NO_COMPRESSION
372 {
373 "No_Compression", SSL_OP_NO_COMPRESSION
374 },
375#endif
376#if SSL_OP_NO_TICKET
377 {
378 "NO_TICKET", SSL_OP_NO_TICKET
379 },
585c27eb
AJ
380#endif
381#if SSL_OP_SINGLE_ECDH_USE
382 {
383 "SINGLE_ECDH_USE", SSL_OP_SINGLE_ECDH_USE
384 },
6bd62757
AJ
385#endif
386 {
387 "", 0
388 },
389 {
390 NULL, 0
391 }
392};
393
c62717bd
AJ
394/**
395 * Pre-parse TLS options= parameter to be applied when the TLS objects created.
396 * Options must not used in the case of peek or stare bump mode.
397 */
6bd62757 398long
c62717bd 399Security::PeerOptions::parseOptions()
6bd62757
AJ
400{
401 long op = 0;
c62717bd 402 ::Parser::Tokenizer tok(sslOptions);
6bd62757 403
c62717bd 404 do {
6bd62757
AJ
405 enum {
406 MODE_ADD, MODE_REMOVE
407 } mode;
408
c62717bd 409 if (tok.skip('-') || tok.skip('!'))
6bd62757 410 mode = MODE_REMOVE;
c62717bd
AJ
411 else {
412 (void)tok.skip('+'); // default action is add. ignore if missing operator
6bd62757 413 mode = MODE_ADD;
c62717bd 414 }
6bd62757 415
c62717bd
AJ
416 static const CharacterSet optChars = CharacterSet("TLS-option", "_") + CharacterSet::ALPHA + CharacterSet::DIGIT;
417 int64_t hex = 0;
418 SBuf option;
419 long value = 0;
420
421 if (tok.int64(hex, 16, false)) {
422 /* Special case.. hex specification */
423 value = hex;
6bd62757
AJ
424 }
425
c62717bd
AJ
426 else if (tok.prefix(option, optChars)) {
427 // find the named option in our supported set
428 for (struct ssl_option *opttmp = ssl_options; opttmp->name; ++opttmp) {
429 if (option.cmp(opttmp->name) == 0) {
430 value = opttmp->value;
431 break;
432 }
6bd62757
AJ
433 }
434 }
435
c62717bd
AJ
436 if (!value) {
437 fatalf("Unknown TLS option '" SQUIDSBUFPH "'", SQUIDSBUFPRINT(option));
6bd62757
AJ
438 }
439
440 switch (mode) {
441
442 case MODE_ADD:
443 op |= value;
444 break;
445
446 case MODE_REMOVE:
447 op &= ~value;
448 break;
449 }
450
c62717bd
AJ
451 static const CharacterSet delims("TLS-option-delim",":,");
452 if (!tok.skipAll(delims) && !tok.atEnd()) {
453 fatalf("Unknown TLS option '" SQUIDSBUFPH "'", SQUIDSBUFPRINT(tok.remaining()));
454 }
6bd62757 455
c62717bd 456 } while (!tok.atEnd());
6bd62757
AJ
457
458#if SSL_OP_NO_SSLv2
459 // compliance with RFC 6176: Prohibiting Secure Sockets Layer (SSL) Version 2.0
460 op = op | SSL_OP_NO_SSLv2;
461#endif
462 return op;
463}
464
ec4defdb
AJ
465/**
466 * Parses the TLS flags squid.conf parameter
467 */
b24e9ae7 468long
ec4defdb 469Security::PeerOptions::parseFlags()
b24e9ae7 470{
ec4defdb 471 if (sslFlags.isEmpty())
b24e9ae7
AJ
472 return 0;
473
474 static struct {
475 SBuf label;
476 long mask;
477 } flagTokens[] = {
478 { SBuf("NO_DEFAULT_CA"), SSL_FLAG_NO_DEFAULT_CA },
479 { SBuf("DELAYED_AUTH"), SSL_FLAG_DELAYED_AUTH },
480 { SBuf("DONT_VERIFY_PEER"), SSL_FLAG_DONT_VERIFY_PEER },
481 { SBuf("DONT_VERIFY_DOMAIN"), SSL_FLAG_DONT_VERIFY_DOMAIN },
482 { SBuf("NO_SESSION_REUSE"), SSL_FLAG_NO_SESSION_REUSE },
483#if X509_V_FLAG_CRL_CHECK
484 { SBuf("VERIFY_CRL"), SSL_FLAG_VERIFY_CRL },
485 { SBuf("VERIFY_CRL_ALL"), SSL_FLAG_VERIFY_CRL_ALL },
486#endif
487 { SBuf(), 0 }
488 };
489
ec4defdb 490 ::Parser::Tokenizer tok(sslFlags);
b24e9ae7
AJ
491 static const CharacterSet delims("Flag-delimiter", ":,");
492
493 long fl = 0;
494 do {
495 long found = 0;
496 for (size_t i = 0; flagTokens[i].mask; ++i) {
497 if (tok.skip(flagTokens[i].label) == 0) {
498 found = flagTokens[i].mask;
499 break;
500 }
501 }
502 if (!found)
8250ca31 503 fatalf("Unknown TLS flag '" SQUIDSBUFPH "'", SQUIDSBUFPRINT(tok.remaining()));
8b253b83
AJ
504 if (found == SSL_FLAG_NO_DEFAULT_CA) {
505 debugs(83, DBG_PARSE_NOTE(2), "UPGRADE WARNING: flags=NO_DEFAULT_CA is deprecated. Use tls-no-default-ca instead.");
506 flags.noDefaultCa = true;
507 } else
508 fl |= found;
b24e9ae7
AJ
509 } while (tok.skipOne(delims));
510
511 return fl;
512}
513
6b19d1f9
AJ
514/// Load a CRLs list stored in the file whose /path/name is in crlFile
515/// replaces any CRL loaded previously
516void
517Security::PeerOptions::loadCrlFile()
518{
519 parsedCrl.clear();
520 if (crlFile.isEmpty())
521 return;
522
523#if USE_OPENSSL
524 BIO *in = BIO_new_file(crlFile.c_str(), "r");
525 if (!in) {
526 debugs(83, 2, "WARNING: Failed to open CRL file " << crlFile);
527 return;
528 }
529
530 while (X509_CRL *crl = PEM_read_bio_X509_CRL(in,NULL,NULL,NULL)) {
531 parsedCrl.emplace_back(Security::CrlPointer(crl));
532 }
533 BIO_free(in);
534#endif
535}
536
b05d749d
AJ
537#if USE_OPENSSL && defined(TLSEXT_TYPE_next_proto_neg)
538// Dummy next_proto_neg callback
539static int
540ssl_next_proto_cb(SSL *s, unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg)
541{
542 static const unsigned char supported_protos[] = {8, 'h','t','t', 'p', '/', '1', '.', '1'};
543 (void)SSL_select_next_proto(out, outlen, in, inlen, supported_protos, sizeof(supported_protos));
544 return SSL_TLSEXT_ERR_OK;
545}
546#endif
547
548void
549Security::PeerOptions::updateContextNpn(Security::ContextPtr &ctx)
550{
551 if (!flags.tlsNpn)
552 return;
553
554#if USE_OPENSSL && defined(TLSEXT_TYPE_next_proto_neg)
555 SSL_CTX_set_next_proto_select_cb(ctx, &ssl_next_proto_cb, nullptr);
556#endif
557
558 // NOTE: GnuTLS does not support the obsolete NPN extension.
559 // it does support ALPN per-session, not per-context.
560}
561
86a84cc0 562void
96993ee0 563Security::PeerOptions::updateContextCa(Security::ContextPtr &ctx)
86a84cc0
AJ
564{
565 debugs(83, 8, "Setting CA certificate locations.");
566
567 for (auto i : caFiles) {
568#if USE_OPENSSL
569 if (!SSL_CTX_load_verify_locations(ctx, i.c_str(), caDir.c_str())) {
570 const int ssl_error = ERR_get_error();
571 debugs(83, DBG_IMPORTANT, "WARNING: Ignoring error setting CA certificate locations: " << ERR_error_string(ssl_error, NULL));
572 }
573#elif USE_GNUTLS
574 if (gnutls_certificate_set_x509_trust_file(ctx, i.c_str(), GNUTLS_X509_FMT_PEM) < 0) {
575 debugs(83, DBG_IMPORTANT, "WARNING: Ignoring error setting CA certificate location: " << i);
576 }
577#endif
578 }
579
8b253b83 580 if (flags.noDefaultCa)
86a84cc0
AJ
581 return;
582
583#if USE_OPENSSL
584 if (!SSL_CTX_set_default_verify_paths(ctx)) {
585 const int ssl_error = ERR_get_error();
586 debugs(83, DBG_IMPORTANT, "WARNING: Ignoring error setting default trusted CA : "
587 << ERR_error_string(ssl_error, NULL));
588 }
589#elif USE_GNUTLS
590 if (gnutls_certificate_set_x509_system_trust(ctx) != GNUTLS_E_SUCCESS) {
591 debugs(83, DBG_IMPORTANT, "WARNING: Ignoring error setting default trusted CA.");
592 }
593#endif
594}
595
6b19d1f9 596void
96993ee0 597Security::PeerOptions::updateContextCrl(Security::ContextPtr &ctx)
6b19d1f9
AJ
598{
599#if USE_OPENSSL
600 bool verifyCrl = false;
601 X509_STORE *st = SSL_CTX_get_cert_store(ctx);
602 if (parsedCrl.size()) {
603 for (auto &i : parsedCrl) {
604 if (!X509_STORE_add_crl(st, i.get()))
605 debugs(83, 2, "WARNING: Failed to add CRL");
606 else
607 verifyCrl = true;
608 }
609 }
610
611#if X509_V_FLAG_CRL_CHECK
612 if ((parsedFlags & SSL_FLAG_VERIFY_CRL_ALL))
613 X509_STORE_set_flags(st, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
614 else if (verifyCrl || (parsedFlags & SSL_FLAG_VERIFY_CRL))
615 X509_STORE_set_flags(st, X509_V_FLAG_CRL_CHECK);
616#endif
617
618#endif /* USE_OPENSSL */
619}
620
1f1f29e8
AJ
621void
622parse_securePeerOptions(Security::PeerOptions *opt)
623{
624 while(const char *token = ConfigParser::NextToken())
625 opt->parse(token);
626}
627