PeerOptions.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2019 The Squid Software Foundation and contributors
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"
10 #include "base/Packable.h"
11 #include "Debug.h"
12 #include "fatal.h"
13 #include "globals.h"
14 #include "parser/Tokenizer.h"
15 #include "Parsing.h"
16 #include "security/PeerOptions.h"
17 
18 #if USE_OPENSSL
19 #include "ssl/support.h"
20 #endif
21 
23 
25 {
26  // init options consistent with an empty sslOptions
27  parseOptions();
28 }
29 
30 void
31 Security::PeerOptions::parse(const char *token)
32 {
33  if (!*token) {
34  // config says just "ssl" or "tls" (or "tls-")
35  encryptTransport = true;
36  return;
37  }
38 
39  if (strncmp(token, "disable", 7) == 0) {
40  clear();
41  return;
42  }
43 
44  if (strncmp(token, "cert=", 5) == 0) {
45  KeyData t;
46  t.privateKeyFile = t.certFile = SBuf(token + 5);
47  certs.emplace_back(t);
48  } else if (strncmp(token, "key=", 4) == 0) {
49  if (certs.empty() || certs.back().certFile.isEmpty()) {
50  fatal("cert= option must be set before key= is used.");
51  return;
52  }
53  KeyData &t = certs.back();
54  t.privateKeyFile = SBuf(token + 4);
55  } else if (strncmp(token, "version=", 8) == 0) {
56  debugs(0, DBG_PARSE_NOTE(1), "UPGRADE WARNING: SSL version= is deprecated. Use options= to limit protocols instead.");
57  sslVersion = xatoi(token + 8);
58  } else if (strncmp(token, "min-version=", 12) == 0) {
59  tlsMinVersion = SBuf(token + 12);
60  } else if (strncmp(token, "options=", 8) == 0) {
61  sslOptions = SBuf(token + 8);
62  parseOptions();
63  } else if (strncmp(token, "cipher=", 7) == 0) {
64  sslCipher = SBuf(token + 7);
65  } else if (strncmp(token, "cafile=", 7) == 0) {
66  caFiles.emplace_back(SBuf(token + 7));
67  } else if (strncmp(token, "capath=", 7) == 0) {
68  caDir = SBuf(token + 7);
69 #if !USE_OPENSSL
70  debugs(3, DBG_PARSE_NOTE(1), "WARNING: capath= option requires --with-openssl.");
71 #endif
72  } else if (strncmp(token, "crlfile=", 8) == 0) {
73  crlFile = SBuf(token + 8);
74  loadCrlFile();
75  } else if (strncmp(token, "flags=", 6) == 0) {
76  if (parsedFlags != 0) {
77  debugs(3, DBG_PARSE_NOTE(1), "WARNING: Overwriting flags=" << sslFlags << " with " << SBuf(token + 6));
78  }
79  sslFlags = SBuf(token + 6);
81  } else if (strncmp(token, "default-ca=off", 14) == 0 || strncmp(token, "no-default-ca", 13) == 0) {
83  fatalf("ERROR: previous default-ca settings conflict with %s", token);
85  } else if (strncmp(token, "default-ca=on", 13) == 0 || strncmp(token, "default-ca", 10) == 0) {
87  fatalf("ERROR: previous default-ca settings conflict with %s", token);
89  } else if (strncmp(token, "domain=", 7) == 0) {
90  sslDomain = SBuf(token + 7);
91  } else if (strncmp(token, "no-npn", 6) == 0) {
92  flags.tlsNpn = false;
93  } else {
94  debugs(3, DBG_CRITICAL, "ERROR: Unknown TLS option '" << token << "'");
95  return;
96  }
97 
98  encryptTransport = true;
99 }
100 
101 void
102 Security::PeerOptions::dumpCfg(Packable *p, const char *pfx) const
103 {
104  if (!encryptTransport) {
105  p->appendf(" %sdisable", pfx);
106  return; // no other settings are relevant
107  }
108 
109  for (auto &i : certs) {
110  if (!i.certFile.isEmpty())
111  p->appendf(" %scert=" SQUIDSBUFPH, pfx, SQUIDSBUFPRINT(i.certFile));
112 
113  if (!i.privateKeyFile.isEmpty() && i.privateKeyFile != i.certFile)
114  p->appendf(" %skey=" SQUIDSBUFPH, pfx, SQUIDSBUFPRINT(i.privateKeyFile));
115  }
116 
117  if (!sslOptions.isEmpty())
118  p->appendf(" %soptions=" SQUIDSBUFPH, pfx, SQUIDSBUFPRINT(sslOptions));
119 
120  if (!sslCipher.isEmpty())
121  p->appendf(" %scipher=" SQUIDSBUFPH, pfx, SQUIDSBUFPRINT(sslCipher));
122 
123  for (auto i : caFiles) {
124  p->appendf(" %scafile=" SQUIDSBUFPH, pfx, SQUIDSBUFPRINT(i));
125  }
126 
127  if (!caDir.isEmpty())
128  p->appendf(" %scapath=" SQUIDSBUFPH, pfx, SQUIDSBUFPRINT(caDir));
129 
130  if (!crlFile.isEmpty())
131  p->appendf(" %scrlfile=" SQUIDSBUFPH, pfx, SQUIDSBUFPRINT(crlFile));
132 
133  if (!sslFlags.isEmpty())
134  p->appendf(" %sflags=" SQUIDSBUFPH, pfx, SQUIDSBUFPRINT(sslFlags));
135 
136  if (flags.tlsDefaultCa.configured()) {
137  // default ON for peers / upstream servers
138  // default OFF for listening ports
139  if (flags.tlsDefaultCa)
140  p->appendf(" %sdefault-ca", pfx);
141  else
142  p->appendf(" %sdefault-ca=off", pfx);
143  }
144 
145  if (!flags.tlsNpn)
146  p->appendf(" %sno-npn", pfx);
147 }
148 
149 void
151 {
152  if (!tlsMinVersion.isEmpty()) {
154  int64_t v = 0;
155  if (tok.skip('1') && tok.skip('.') && tok.int64(v, 10, false, 1) && v <= 3) {
156  // only account for TLS here - SSL versions are handled by options= parameter
157  // avoid affecting options= parameter in cachemgr config report
158 #if USE_OPENSSL
159 #if SSL_OP_NO_TLSv1
160  if (v > 0)
161  parsedOptions |= SSL_OP_NO_TLSv1;
162 #endif
163 #if SSL_OP_NO_TLSv1_1
164  if (v > 1)
165  parsedOptions |= SSL_OP_NO_TLSv1_1;
166 #endif
167 #if SSL_OP_NO_TLSv1_2
168  if (v > 2)
169  parsedOptions |= SSL_OP_NO_TLSv1_2;
170 #endif
171 
172 #elif USE_GNUTLS
173  // XXX: update parsedOptions directly to avoid polluting 'options=' dumps
174  SBuf add;
175  if (v > 0)
176  add.append(":-VERS-TLS1.0");
177  if (v > 1)
178  add.append(":-VERS-TLS1.1");
179  if (v > 2)
180  add.append(":-VERS-TLS1.2");
181 
182  if (sslOptions.isEmpty())
183  add.chop(1); // remove the initial ':'
184  sslOptions.append(add);
185 #endif
186 
187  } else {
188  debugs(0, DBG_PARSE_NOTE(1), "WARNING: Unknown TLS minimum version: " << tlsMinVersion);
189  }
190 
191  return;
192  }
193 
194  if (sslVersion > 2) {
195  // backward compatibility hack for sslversion= configuration
196  // only use if tls-min-version=N.N is not present
197  // values 0-2 for auto and SSLv2 are not supported any longer.
198  // Do it this way so we DO cause changes to options= in cachemgr config report
199  const char *add = nullptr;
200  switch (sslVersion) {
201  case 3:
202 #if USE_OPENSSL
203  parsedOptions |= (SSL_OP_NO_TLSv1|SSL_OP_NO_TLSv1_1|SSL_OP_NO_TLSv1_2);
204 #elif USE_GNUTLS
205  add = ":-VERS-TLS1.0:-VERS-TLS1.1:-VERS-TLS1.2";
206 #endif
207  break;
208  case 4:
209 #if USE_OPENSSL
210  parsedOptions |= (SSL_OP_NO_SSLv3|SSL_OP_NO_TLSv1_1|SSL_OP_NO_TLSv1_2);
211 #elif USE_GNUTLS
212  add = ":+VERS-TLS1.0:-VERS-TLS1.1:-VERS-TLS1.2";
213 #endif
214  break;
215  case 5:
216 #if USE_OPENSSL
217  parsedOptions |= (SSL_OP_NO_SSLv3|SSL_OP_NO_TLSv1|SSL_OP_NO_TLSv1_2);
218 #elif USE_GNUTLS
219  add = ":-VERS-TLS1.0:+VERS-TLS1.1:-VERS-TLS1.2";
220 #endif
221  break;
222  case 6:
223 #if USE_OPENSSL
224  parsedOptions |= (SSL_OP_NO_SSLv3|SSL_OP_NO_TLSv1|SSL_OP_NO_TLSv1_1);
225 #elif USE_GNUTLS
226  add = ":-VERS-TLS1.0:-VERS-TLS1.1";
227 #endif
228  break;
229  default: // nothing
230  break;
231  }
232  if (add) {
233 #if USE_GNUTLS // do not bother otherwise
234  if (sslOptions.isEmpty())
235  sslOptions.append(add+1, strlen(add+1));
236  else
237  sslOptions.append(add, strlen(add));
238 #endif
239  }
240  sslVersion = 0; // prevent sslOptions being repeatedly appended
241  }
242 }
243 
246 {
248 #if USE_OPENSSL
249  Ssl::Initialize();
250 
251  SSL_CTX *t = SSL_CTX_new(TLS_client_method());
252  if (!t) {
253  const auto x = ERR_get_error();
254  fatalf("Failed to allocate TLS client context: %s\n", Security::ErrorString(x));
255  }
256  ctx = convertContextFromRawPtr(t);
257 
258 #elif USE_GNUTLS
259  // Initialize for X.509 certificate exchange
260  gnutls_certificate_credentials_t t;
261  if (const int x = gnutls_certificate_allocate_credentials(&t)) {
262  fatalf("Failed to allocate TLS client context: %s\n", Security::ErrorString(x));
263  }
264  ctx = convertContextFromRawPtr(t);
265 
266 #else
267  debugs(83, 1, "WARNING: Failed to allocate TLS client context: No TLS library");
268 
269 #endif
270 
271  return ctx;
272 }
273 
276 {
278 
280  if (t) {
281  if (setOptions)
283 #if USE_OPENSSL
284  // XXX: temporary performance regression. c_str() data copies and prevents this being a const method
286 #endif
287  updateContextNpn(t);
288  updateContextCa(t);
289  updateContextCrl(t);
291  }
292 
293  return t;
294 }
295 
296 #if USE_OPENSSL
297 static struct ssl_option {
299  const char *name;
300  long value;
301 
302 } ssl_options[] = {
303 
304 #if SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
305  {
306  "NETSCAPE_REUSE_CIPHER_CHANGE_BUG", SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
307  },
308 #endif
309 #if SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG
310  {
311  "SSLREF2_REUSE_CERT_TYPE_BUG", SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG
312  },
313 #endif
314 #if SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER
315  {
316  "MICROSOFT_BIG_SSLV3_BUFFER", SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER
317  },
318 #endif
319 #if SSL_OP_SSLEAY_080_CLIENT_DH_BUG
320  {
321  "SSLEAY_080_CLIENT_DH_BUG", SSL_OP_SSLEAY_080_CLIENT_DH_BUG
322  },
323 #endif
324 #if SSL_OP_TLS_D5_BUG
325  {
326  "TLS_D5_BUG", SSL_OP_TLS_D5_BUG
327  },
328 #endif
329 #if SSL_OP_TLS_BLOCK_PADDING_BUG
330  {
331  "TLS_BLOCK_PADDING_BUG", SSL_OP_TLS_BLOCK_PADDING_BUG
332  },
333 #endif
334 #if SSL_OP_TLS_ROLLBACK_BUG
335  {
336  "TLS_ROLLBACK_BUG", SSL_OP_TLS_ROLLBACK_BUG
337  },
338 #endif
339 #if SSL_OP_ALL
340  {
341  "ALL", (long)SSL_OP_ALL
342  },
343 #endif
344 #if SSL_OP_SINGLE_DH_USE
345  {
346  "SINGLE_DH_USE", SSL_OP_SINGLE_DH_USE
347  },
348 #endif
349 #if SSL_OP_EPHEMERAL_RSA
350  {
351  "EPHEMERAL_RSA", SSL_OP_EPHEMERAL_RSA
352  },
353 #endif
354 #if SSL_OP_PKCS1_CHECK_1
355  {
356  "PKCS1_CHECK_1", SSL_OP_PKCS1_CHECK_1
357  },
358 #endif
359 #if SSL_OP_PKCS1_CHECK_2
360  {
361  "PKCS1_CHECK_2", SSL_OP_PKCS1_CHECK_2
362  },
363 #endif
364 #if SSL_OP_NETSCAPE_CA_DN_BUG
365  {
366  "NETSCAPE_CA_DN_BUG", SSL_OP_NETSCAPE_CA_DN_BUG
367  },
368 #endif
369 #if SSL_OP_NON_EXPORT_FIRST
370  {
371  "NON_EXPORT_FIRST", SSL_OP_NON_EXPORT_FIRST
372  },
373 #endif
374 #if SSL_OP_CIPHER_SERVER_PREFERENCE
375  {
376  "CIPHER_SERVER_PREFERENCE", SSL_OP_CIPHER_SERVER_PREFERENCE
377  },
378 #endif
379 #if SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG
380  {
381  "NETSCAPE_DEMO_CIPHER_CHANGE_BUG", SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG
382  },
383 #endif
384 #if SSL_OP_NO_SSLv3
385  {
386  "NO_SSLv3", SSL_OP_NO_SSLv3
387  },
388 #endif
389 #if SSL_OP_NO_TLSv1
390  {
391  "NO_TLSv1", SSL_OP_NO_TLSv1
392  },
393 #endif
394 #if SSL_OP_NO_TLSv1_1
395  {
396  "NO_TLSv1_1", SSL_OP_NO_TLSv1_1
397  },
398 #endif
399 #if SSL_OP_NO_TLSv1_2
400  {
401  "NO_TLSv1_2", SSL_OP_NO_TLSv1_2
402  },
403 #endif
404 #if SSL_OP_NO_COMPRESSION
405  {
406  "No_Compression", SSL_OP_NO_COMPRESSION
407  },
408 #endif
409 #if SSL_OP_NO_TICKET
410  {
411  "NO_TICKET", SSL_OP_NO_TICKET
412  },
413 #endif
414 #if SSL_OP_SINGLE_ECDH_USE
415  {
416  "SINGLE_ECDH_USE", SSL_OP_SINGLE_ECDH_USE
417  },
418 #endif
419  {
420  "", 0
421  },
422  {
423  NULL, 0
424  }
425 };
426 #endif /* USE_OPENSSL */
427 
432 void
434 {
435 #if USE_OPENSSL
437  long op = 0;
438 
439  while (!tok.atEnd()) {
440  enum {
441  MODE_ADD, MODE_REMOVE
442  } mode;
443 
444  if (tok.skip('-') || tok.skip('!'))
445  mode = MODE_REMOVE;
446  else {
447  (void)tok.skip('+'); // default action is add. ignore if missing operator
448  mode = MODE_ADD;
449  }
450 
451  static const CharacterSet optChars = CharacterSet("TLS-option", "_") + CharacterSet::ALPHA + CharacterSet::DIGIT;
452  int64_t hex = 0;
453  SBuf option;
454  long value = 0;
455 
456  // Bug 4429: identify the full option name before determining text or numeric
457  if (tok.prefix(option, optChars)) {
458 
459  // find the named option in our supported set
460  for (struct ssl_option *opttmp = ssl_options; opttmp->name; ++opttmp) {
461  if (option.cmp(opttmp->name) == 0) {
462  value = opttmp->value;
463  break;
464  }
465  }
466 
467  // Special case.. hex specification
468  ::Parser::Tokenizer tmp(option);
469  if (!value && tmp.int64(hex, 16, false) && tmp.atEnd()) {
470  value = hex;
471  }
472  }
473 
474  if (value) {
475  switch (mode) {
476  case MODE_ADD:
477  op |= value;
478  break;
479  case MODE_REMOVE:
480  op &= ~value;
481  break;
482  }
483  } else {
484  debugs(83, DBG_PARSE_NOTE(1), "ERROR: Unknown TLS option " << option);
485  }
486 
487  static const CharacterSet delims("TLS-option-delim",":,");
488  if (!tok.skipAll(delims) && !tok.atEnd()) {
489  fatalf("Unknown TLS option '" SQUIDSBUFPH "'", SQUIDSBUFPRINT(tok.remaining()));
490  }
491 
492  }
493 
494 #if SSL_OP_NO_SSLv2
495  // compliance with RFC 6176: Prohibiting Secure Sockets Layer (SSL) Version 2.0
496  op = op | SSL_OP_NO_SSLv2;
497 #endif
498  parsedOptions = op;
499 
500 #elif USE_GNUTLS
501  if (sslOptions.isEmpty()) {
502  parsedOptions.reset();
503  return;
504  }
505 
506  const char *err = nullptr;
507  const char *priorities = sslOptions.c_str();
508  gnutls_priority_t op;
509  if (gnutls_priority_init(&op, priorities, &err) != GNUTLS_E_SUCCESS) {
510  fatalf("Unknown TLS option '%s'", err);
511  }
512  parsedOptions = Security::ParsedOptions(op, [](gnutls_priority_t p) {
513  debugs(83, 5, "gnutls_priority_deinit p=" << (void*)p);
514  gnutls_priority_deinit(p);
515  });
516 #endif
517 }
518 
522 long
524 {
525  if (sslFlags.isEmpty())
526  return 0;
527 
528  static struct {
529  SBuf label;
530  long mask;
531  } flagTokens[] = {
532  { SBuf("NO_DEFAULT_CA"), SSL_FLAG_NO_DEFAULT_CA },
533  { SBuf("DELAYED_AUTH"), SSL_FLAG_DELAYED_AUTH },
534  { SBuf("DONT_VERIFY_PEER"), SSL_FLAG_DONT_VERIFY_PEER },
535  { SBuf("DONT_VERIFY_DOMAIN"), SSL_FLAG_DONT_VERIFY_DOMAIN },
536  { SBuf("NO_SESSION_REUSE"), SSL_FLAG_NO_SESSION_REUSE },
537 #if X509_V_FLAG_CRL_CHECK
538  { SBuf("VERIFY_CRL"), SSL_FLAG_VERIFY_CRL },
539  { SBuf("VERIFY_CRL_ALL"), SSL_FLAG_VERIFY_CRL_ALL },
540 #endif
541  { SBuf(), 0 }
542  };
543 
545  static const CharacterSet delims("Flag-delimiter", ":,");
546 
547  long fl = 0;
548  do {
549  long found = 0;
550  for (size_t i = 0; flagTokens[i].mask; ++i) {
551  if (tok.skip(flagTokens[i].label)) {
552  found = flagTokens[i].mask;
553  break;
554  }
555  }
556  if (!found)
557  fatalf("Unknown TLS flag '" SQUIDSBUFPH "'", SQUIDSBUFPRINT(tok.remaining()));
558  if (found == SSL_FLAG_NO_DEFAULT_CA) {
560  fatal("ERROR: previous default-ca settings conflict with sslflags=NO_DEFAULT_CA");
561  debugs(83, DBG_PARSE_NOTE(2), "WARNING: flags=NO_DEFAULT_CA is deprecated. Use tls-default-ca=off instead.");
563  } else
564  fl |= found;
565  } while (tok.skipOne(delims));
566 
567  return fl;
568 }
569 
572 void
574 {
575  parsedCrl.clear();
576  if (crlFile.isEmpty())
577  return;
578 
579 #if USE_OPENSSL
580  BIO *in = BIO_new_file(crlFile.c_str(), "r");
581  if (!in) {
582  debugs(83, 2, "WARNING: Failed to open CRL file " << crlFile);
583  return;
584  }
585 
586  while (X509_CRL *crl = PEM_read_bio_X509_CRL(in,NULL,NULL,NULL)) {
587  parsedCrl.emplace_back(Security::CrlPointer(crl));
588  }
589  BIO_free(in);
590 #endif
591 }
592 
593 void
595 {
596 #if USE_OPENSSL
597  SSL_CTX_set_options(ctx.get(), parsedOptions);
598 #elif USE_GNUTLS
599  // NP: GnuTLS uses 'priorities' which are set per-session instead.
600 #endif
601 }
602 
603 #if USE_OPENSSL && defined(TLSEXT_TYPE_next_proto_neg)
604 // Dummy next_proto_neg callback
605 static int
606 ssl_next_proto_cb(SSL *s, unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg)
607 {
608  static const unsigned char supported_protos[] = {8, 'h','t','t', 'p', '/', '1', '.', '1'};
609  (void)SSL_select_next_proto(out, outlen, in, inlen, supported_protos, sizeof(supported_protos));
610  return SSL_TLSEXT_ERR_OK;
611 }
612 #endif
613 
614 void
616 {
617  if (!flags.tlsNpn)
618  return;
619 
620 #if USE_OPENSSL && defined(TLSEXT_TYPE_next_proto_neg)
621  SSL_CTX_set_next_proto_select_cb(ctx.get(), &ssl_next_proto_cb, nullptr);
622 #endif
623 
624  // NOTE: GnuTLS does not support the obsolete NPN extension.
625  // it does support ALPN per-session, not per-context.
626 }
627 
628 static const char *
630 {
631  debugs(83, 8, "Setting default system Trusted CA. ctx=" << (void*)ctx.get());
632 #if USE_OPENSSL
633  if (SSL_CTX_set_default_verify_paths(ctx.get()) == 0)
634  return Security::ErrorString(ERR_get_error());
635 
636 #elif USE_GNUTLS
637  auto x = gnutls_certificate_set_x509_system_trust(ctx.get());
638  if (x < 0)
639  return Security::ErrorString(x);
640 
641 #endif
642  return nullptr;
643 }
644 
645 void
647 {
648  debugs(83, 8, "Setting CA certificate locations.");
649 #if USE_OPENSSL
650  if (const char *path = caDir.isEmpty() ? nullptr : caDir.c_str()) {
651  if (!SSL_CTX_load_verify_locations(ctx.get(), nullptr, path)) {
652  const auto x = ERR_get_error();
653  debugs(83, DBG_IMPORTANT, "WARNING: Ignoring error setting CA certificate location " << path << ": " << Security::ErrorString(x));
654  }
655  }
656 #endif
657  for (auto i : caFiles) {
658 #if USE_OPENSSL
659  if (!SSL_CTX_load_verify_locations(ctx.get(), i.c_str(), nullptr)) {
660  const auto x = ERR_get_error();
661  debugs(83, DBG_IMPORTANT, "WARNING: Ignoring error setting CA certificate location " <<
662  i << ": " << Security::ErrorString(x));
663  }
664 #elif USE_GNUTLS
665  const auto x = gnutls_certificate_set_x509_trust_file(ctx.get(), i.c_str(), GNUTLS_X509_FMT_PEM);
666  if (x < 0) {
667  debugs(83, DBG_IMPORTANT, "WARNING: Ignoring error setting CA certificate location " <<
668  i << ": " << Security::ErrorString(x));
669  }
670 #endif
671  }
672 
673  if (!flags.tlsDefaultCa)
674  return;
675 
676  if (const char *err = loadSystemTrustedCa(ctx)) {
677  debugs(83, DBG_IMPORTANT, "WARNING: Ignoring error setting default trusted CA : " << err);
678  }
679 }
680 
681 void
683 {
684 #if USE_OPENSSL
685  bool verifyCrl = false;
686  X509_STORE *st = SSL_CTX_get_cert_store(ctx.get());
687  if (parsedCrl.size()) {
688  for (auto &i : parsedCrl) {
689  if (!X509_STORE_add_crl(st, i.get()))
690  debugs(83, 2, "WARNING: Failed to add CRL");
691  else
692  verifyCrl = true;
693  }
694  }
695 
696 #if X509_V_FLAG_CRL_CHECK
698  X509_STORE_set_flags(st, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
699  else if (verifyCrl || (parsedFlags & SSL_FLAG_VERIFY_CRL))
700  X509_STORE_set_flags(st, X509_V_FLAG_CRL_CHECK);
701 #endif
702 
703 #endif /* USE_OPENSSL */
704 }
705 
706 void
708 {
709 #if USE_OPENSSL
710 #if defined(X509_V_FLAG_PARTIAL_CHAIN)
711  const auto st = SSL_CTX_get_cert_store(ctx.get());
712  assert(st);
713  if (X509_STORE_set_flags(st, X509_V_FLAG_PARTIAL_CHAIN) != 1) {
714  debugs(83, DBG_IMPORTANT, "ERROR: Failed to enable trust in intermediate CA certificates: " <<
715  Security::ErrorString(ERR_get_error()));
716  }
717 #endif
718 #elif USE_GNUTLS
719  // Modern GnuTLS versions trust intermediate CA certificates by default.
720 #endif /* TLS library */
721 }
722 
723 void
725 {
726 #if USE_OPENSSL
727  // 'options=' value being set to session is a GnuTLS specific thing.
728 #elif USE_GNUTLS
729  int x;
730  SBuf errMsg;
731  if (!parsedOptions) {
732  debugs(83, 5, "set GnuTLS default priority/options for session=" << s);
733  x = gnutls_set_default_priority(s.get());
734  static const SBuf defaults("default");
735  errMsg = defaults;
736  } else {
737  debugs(83, 5, "set GnuTLS options '" << sslOptions << "' for session=" << s);
738  x = gnutls_priority_set(s.get(), parsedOptions.get());
739  errMsg = sslOptions;
740  }
741 
742  if (x != GNUTLS_E_SUCCESS) {
743  debugs(83, DBG_IMPORTANT, "ERROR: Failed to set TLS options (" << errMsg << "). error: " << Security::ErrorString(x));
744  }
745 #endif
746 }
747 
748 void
750 {
751  while(const char *token = ConfigParser::NextToken())
752  opt->parse(token);
753 }
754 
#define SSL_FLAG_VERIFY_CRL
Definition: forward.h:50
int xatoi(const char *token)
Definition: Parsing.cc:43
#define assert(EX)
Definition: assert.h:17
SBuf certFile
path of file containing PEM format X.509 certificate
Definition: KeyData.h:27
virtual void clear()
reset the configuration details to default
Definition: PeerOptions.h:36
Definition: SBuf.h:86
Security::ContextPointer convertContextFromRawPtr(T ctx) const
Definition: PeerOptions.h:94
int i
Definition: membanger.c:49
void updateContextCrl(Security::ContextPointer &)
setup the CRL details for the given context
Definition: PeerOptions.cc:682
SBuf & append(const SBuf &S)
Definition: SBuf.cc:195
Security::ParsedOptions parsedOptions
parsed value of sslOptions
Definition: PeerOptions.h:85
bool encryptTransport
whether transport encryption (TLS/SSL) is to be used on connections to the peer
Definition: PeerOptions.h:128
SBuf & chop(size_type pos, size_type n=npos)
Definition: SBuf.cc:540
Security::CertRevokeList parsedCrl
CRL to use when verifying the remote end certificate.
Definition: PeerOptions.h:90
YesNoNone tlsDefaultCa
whether to use the system default Trusted CA when verifying the remote end certificate ...
Definition: PeerOptions.h:120
bool isEmpty() const
Definition: SBuf.h:420
SBuf sslOptions
library-specific options string
Definition: PeerOptions.h:75
long ParsedOptions
Definition: forward.h:129
#define DBG_CRITICAL
Definition: Debug.h:45
bool tlsNpn
whether to use the TLS NPN extension on these connections
Definition: PeerOptions.h:123
char * p
Definition: membanger.c:43
#define DBG_PARSE_NOTE(x)
Definition: Debug.h:50
static const CharacterSet ALPHA
Definition: CharacterSet.h:73
#define SSL_FLAG_NO_DEFAULT_CA
Definition: forward.h:45
#define SSL_FLAG_DONT_VERIFY_PEER
Definition: forward.h:47
TLS squid.conf settings for a remote server peer.
Definition: PeerOptions.h:22
void updateContextNpn(Security::ContextPointer &)
setup the NPN extension details for the given context
Definition: PeerOptions.cc:615
SBuf privateKeyFile
path of file containing private key in PEM format
Definition: KeyData.h:28
#define TLS_client_method
Definition: openssl.h:154
void fatalf(const char *fmt,...)
Definition: fatal.cc:68
#define SSL_FLAG_DONT_VERIFY_DOMAIN
Definition: forward.h:48
void EVH void * arg
Definition: stub_event.cc:16
const char * name
Definition: PeerOptions.cc:299
void updateContextCa(Security::ContextPointer &)
setup the CA details for the given context
Definition: PeerOptions.cc:646
static const char * loadSystemTrustedCa(Security::ContextPointer &ctx)
Definition: PeerOptions.cc:629
virtual Security::ContextPointer createBlankContext() const
generate an unset security context object
Definition: PeerOptions.cc:245
#define debugs(SECTION, LEVEL, CONTENT)
Definition: Debug.h:124
#define DBG_IMPORTANT
Definition: Debug.h:46
#define SSL_FLAG_DELAYED_AUTH
Definition: forward.h:46
void updateSessionOptions(Security::SessionPointer &)
setup any library-specific options that can be set for the given session
Definition: PeerOptions.cc:724
static const CharacterSet DIGIT
Definition: CharacterSet.h:81
PeerOptions ProxyOutgoingConfig
configuration options for DIRECT server access
Definition: PeerOptions.cc:22
void updateContextTrust(Security::ContextPointer &)
decide which CAs to trust
Definition: PeerOptions.cc:707
static struct ssl_option ssl_options[]
static char * NextToken()
bool InitClientContext(Security::ContextPointer &, Security::PeerOptions &, long flags)
initialize a TLS client context with OpenSSL specific settings
Definition: support.cc:531
SBuf crlFile
path of file containing Certificate Revoke List
Definition: PeerOptions.h:77
std::shared_ptr< SSL_CTX > ContextPointer
Definition: Context.h:29
void fatal(const char *message)
Definition: fatal.cc:28
const char * c_str()
Definition: SBuf.cc:526
const SBuf & remaining() const
the remaining unprocessed section of buffer
Definition: Tokenizer.h:44
optimized set of C chars, with quick membership test and merge support
Definition: CharacterSet.h:17
Security::ContextPointer createClientContext(bool setOptions)
generate a security client-context from these configured options
Definition: PeerOptions.cc:275
Definition: parse.c:160
bool skipOne(const CharacterSet &discardables)
Definition: Tokenizer.cc:151
void configure(bool beSet)
enables or disables the option; updating to &#39;configured&#39; state
Definition: YesNoNone.h:53
bool configured() const
Definition: YesNoNone.h:67
SBuf sslFlags
flags defining what TLS operations Squid performs
Definition: PeerOptions.h:80
bool skip(const SBuf &tokenToSkip)
Definition: Tokenizer.cc:179
virtual void parse(const char *)
parse a TLS squid.conf option
Definition: PeerOptions.cc:31
void Initialize()
Definition: support.cc:479
bool prefix(SBuf &returnedToken, const CharacterSet &tokenChars, SBuf::size_type limit=SBuf::npos)
Definition: Tokenizer.cc:81
bool atEnd() const
whether the end of the buffer has been reached
Definition: Tokenizer.h:41
SBuf tlsMinVersion
version label for minimum TLS version to permit
Definition: PeerOptions.h:83
SBuf caDir
path of directory containing a set of trusted Certificate Authorities
Definition: PeerOptions.h:76
void updateContextOptions(Security::ContextPointer &) const
Setup the library specific &#39;options=&#39; parameters for the given context.
Definition: PeerOptions.cc:594
virtual void dumpCfg(Packable *, const char *pfx) const
output squid.conf syntax with &#39;pfx&#39; prefix on parameters for the stored settings
Definition: PeerOptions.cc:102
TLS certificate and private key details from squid.conf.
Definition: KeyData.h:20
int cmp(const SBuf &S, const size_type n) const
shorthand version for compare()
Definition: SBuf.h:264
#define SSL_FLAG_NO_SESSION_REUSE
Definition: forward.h:49
std::list< SBuf > caFiles
paths of files containing trusted Certificate Authority
Definition: PeerOptions.h:89
void appendf(const char *fmt,...) PRINTF_FORMAT_ARG2
Append operation with printf-style arguments.
Definition: Packable.h:61
struct Security::PeerOptions::flags_ flags
SBuf::size_type skipAll(const CharacterSet &discardables)
Definition: Tokenizer.cc:139
std::list< Security::KeyData > certs
details from the cert= and file= config parameters
Definition: PeerOptions.h:88
set of options we can parse and what they map to
Definition: PeerOptions.cc:298
#define SQUIDSBUFPH
Definition: SBuf.h:31
void updateTlsVersionLimits()
sync the context options with tls-min-version=N configuration
Definition: PeerOptions.cc:150
void parseOptions()
parsed value of sslOptions
Definition: PeerOptions.cc:433
void parse_securePeerOptions(Security::PeerOptions *opt)
Definition: PeerOptions.cc:749
#define SQUIDSBUFPRINT(s)
Definition: SBuf.h:32
const char * ErrorString(const ErrorCode code)
Definition: forward.h:96
#define NULL
Definition: types.h:166
long parsedFlags
parsed value of sslFlags
Definition: PeerOptions.h:86
#define SSL_FLAG_VERIFY_CRL_ALL
Definition: forward.h:51
std::shared_ptr< SSL > SessionPointer
Definition: Session.h:42
bool int64(int64_t &result, int base=0, bool allowSign=true, SBuf::size_type limit=SBuf::npos)
Definition: Tokenizer.cc:228

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors