]> git.ipfire.org Git - thirdparty/squid.git/blame - src/security/PeerOptions.cc
Fix typo in rev.14350
[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 94 } else if (strncmp(token, "no-default-ca", 13) == 0) {
b2cd014b 95 flags.tlsDefaultCa = false;
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 142
b2cd014b 143 if (!flags.tlsDefaultCa)
0278bdcb 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
40bc593b
AJ
436 if (value) {
437 switch (mode) {
438 case MODE_ADD:
439 op |= value;
440 break;
441 case MODE_REMOVE:
442 op &= ~value;
443 break;
444 }
445 } else {
446 debugs(83, DBG_PARSE_NOTE(1), "ERROR: Unknown TLS option " << option);
6bd62757
AJ
447 }
448
c62717bd
AJ
449 static const CharacterSet delims("TLS-option-delim",":,");
450 if (!tok.skipAll(delims) && !tok.atEnd()) {
451 fatalf("Unknown TLS option '" SQUIDSBUFPH "'", SQUIDSBUFPRINT(tok.remaining()));
452 }
6bd62757 453
c62717bd 454 } while (!tok.atEnd());
6bd62757
AJ
455
456#if SSL_OP_NO_SSLv2
457 // compliance with RFC 6176: Prohibiting Secure Sockets Layer (SSL) Version 2.0
458 op = op | SSL_OP_NO_SSLv2;
459#endif
460 return op;
461}
462
ec4defdb
AJ
463/**
464 * Parses the TLS flags squid.conf parameter
465 */
b24e9ae7 466long
ec4defdb 467Security::PeerOptions::parseFlags()
b24e9ae7 468{
ec4defdb 469 if (sslFlags.isEmpty())
b24e9ae7
AJ
470 return 0;
471
472 static struct {
473 SBuf label;
474 long mask;
475 } flagTokens[] = {
476 { SBuf("NO_DEFAULT_CA"), SSL_FLAG_NO_DEFAULT_CA },
477 { SBuf("DELAYED_AUTH"), SSL_FLAG_DELAYED_AUTH },
478 { SBuf("DONT_VERIFY_PEER"), SSL_FLAG_DONT_VERIFY_PEER },
479 { SBuf("DONT_VERIFY_DOMAIN"), SSL_FLAG_DONT_VERIFY_DOMAIN },
480 { SBuf("NO_SESSION_REUSE"), SSL_FLAG_NO_SESSION_REUSE },
481#if X509_V_FLAG_CRL_CHECK
482 { SBuf("VERIFY_CRL"), SSL_FLAG_VERIFY_CRL },
483 { SBuf("VERIFY_CRL_ALL"), SSL_FLAG_VERIFY_CRL_ALL },
484#endif
485 { SBuf(), 0 }
486 };
487
ec4defdb 488 ::Parser::Tokenizer tok(sslFlags);
b24e9ae7
AJ
489 static const CharacterSet delims("Flag-delimiter", ":,");
490
491 long fl = 0;
492 do {
493 long found = 0;
494 for (size_t i = 0; flagTokens[i].mask; ++i) {
495 if (tok.skip(flagTokens[i].label) == 0) {
496 found = flagTokens[i].mask;
497 break;
498 }
499 }
500 if (!found)
8250ca31 501 fatalf("Unknown TLS flag '" SQUIDSBUFPH "'", SQUIDSBUFPRINT(tok.remaining()));
8b253b83
AJ
502 if (found == SSL_FLAG_NO_DEFAULT_CA) {
503 debugs(83, DBG_PARSE_NOTE(2), "UPGRADE WARNING: flags=NO_DEFAULT_CA is deprecated. Use tls-no-default-ca instead.");
91e078bf 504 flags.tlsDefaultCa = false;
8b253b83
AJ
505 } else
506 fl |= found;
b24e9ae7
AJ
507 } while (tok.skipOne(delims));
508
509 return fl;
510}
511
6b19d1f9
AJ
512/// Load a CRLs list stored in the file whose /path/name is in crlFile
513/// replaces any CRL loaded previously
514void
515Security::PeerOptions::loadCrlFile()
516{
517 parsedCrl.clear();
518 if (crlFile.isEmpty())
519 return;
520
521#if USE_OPENSSL
522 BIO *in = BIO_new_file(crlFile.c_str(), "r");
523 if (!in) {
524 debugs(83, 2, "WARNING: Failed to open CRL file " << crlFile);
525 return;
526 }
527
528 while (X509_CRL *crl = PEM_read_bio_X509_CRL(in,NULL,NULL,NULL)) {
529 parsedCrl.emplace_back(Security::CrlPointer(crl));
530 }
531 BIO_free(in);
532#endif
533}
534
b05d749d
AJ
535#if USE_OPENSSL && defined(TLSEXT_TYPE_next_proto_neg)
536// Dummy next_proto_neg callback
537static int
538ssl_next_proto_cb(SSL *s, unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg)
539{
540 static const unsigned char supported_protos[] = {8, 'h','t','t', 'p', '/', '1', '.', '1'};
541 (void)SSL_select_next_proto(out, outlen, in, inlen, supported_protos, sizeof(supported_protos));
542 return SSL_TLSEXT_ERR_OK;
543}
544#endif
545
546void
547Security::PeerOptions::updateContextNpn(Security::ContextPtr &ctx)
548{
549 if (!flags.tlsNpn)
550 return;
551
552#if USE_OPENSSL && defined(TLSEXT_TYPE_next_proto_neg)
553 SSL_CTX_set_next_proto_select_cb(ctx, &ssl_next_proto_cb, nullptr);
554#endif
555
556 // NOTE: GnuTLS does not support the obsolete NPN extension.
557 // it does support ALPN per-session, not per-context.
558}
559
86a84cc0 560void
96993ee0 561Security::PeerOptions::updateContextCa(Security::ContextPtr &ctx)
86a84cc0
AJ
562{
563 debugs(83, 8, "Setting CA certificate locations.");
564
565 for (auto i : caFiles) {
566#if USE_OPENSSL
567 if (!SSL_CTX_load_verify_locations(ctx, i.c_str(), caDir.c_str())) {
568 const int ssl_error = ERR_get_error();
569 debugs(83, DBG_IMPORTANT, "WARNING: Ignoring error setting CA certificate locations: " << ERR_error_string(ssl_error, NULL));
570 }
571#elif USE_GNUTLS
572 if (gnutls_certificate_set_x509_trust_file(ctx, i.c_str(), GNUTLS_X509_FMT_PEM) < 0) {
573 debugs(83, DBG_IMPORTANT, "WARNING: Ignoring error setting CA certificate location: " << i);
574 }
575#endif
576 }
577
b2cd014b 578 if (!flags.tlsDefaultCa)
86a84cc0
AJ
579 return;
580
581#if USE_OPENSSL
582 if (!SSL_CTX_set_default_verify_paths(ctx)) {
583 const int ssl_error = ERR_get_error();
584 debugs(83, DBG_IMPORTANT, "WARNING: Ignoring error setting default trusted CA : "
585 << ERR_error_string(ssl_error, NULL));
586 }
587#elif USE_GNUTLS
588 if (gnutls_certificate_set_x509_system_trust(ctx) != GNUTLS_E_SUCCESS) {
589 debugs(83, DBG_IMPORTANT, "WARNING: Ignoring error setting default trusted CA.");
590 }
591#endif
592}
593
6b19d1f9 594void
96993ee0 595Security::PeerOptions::updateContextCrl(Security::ContextPtr &ctx)
6b19d1f9
AJ
596{
597#if USE_OPENSSL
598 bool verifyCrl = false;
599 X509_STORE *st = SSL_CTX_get_cert_store(ctx);
600 if (parsedCrl.size()) {
601 for (auto &i : parsedCrl) {
602 if (!X509_STORE_add_crl(st, i.get()))
603 debugs(83, 2, "WARNING: Failed to add CRL");
604 else
605 verifyCrl = true;
606 }
607 }
608
609#if X509_V_FLAG_CRL_CHECK
610 if ((parsedFlags & SSL_FLAG_VERIFY_CRL_ALL))
611 X509_STORE_set_flags(st, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
612 else if (verifyCrl || (parsedFlags & SSL_FLAG_VERIFY_CRL))
613 X509_STORE_set_flags(st, X509_V_FLAG_CRL_CHECK);
614#endif
615
616#endif /* USE_OPENSSL */
617}
618
1f1f29e8
AJ
619void
620parse_securePeerOptions(Security::PeerOptions *opt)
621{
622 while(const char *token = ConfigParser::NextToken())
623 opt->parse(token);
624}
625