PeerOptions.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2018 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);
80  parsedFlags = parseFlags();
81  } else if (strncmp(token, "default-ca=off", 14) == 0 || strncmp(token, "no-default-ca", 13) == 0) {
82  if (flags.tlsDefaultCa.configured() && flags.tlsDefaultCa)
83  fatalf("ERROR: previous default-ca settings conflict with %s", token);
84  flags.tlsDefaultCa.configure(false);
85  } else if (strncmp(token, "default-ca=on", 13) == 0 || strncmp(token, "default-ca", 10) == 0) {
86  if (flags.tlsDefaultCa.configured() && !flags.tlsDefaultCa)
87  fatalf("ERROR: previous default-ca settings conflict with %s", token);
88  flags.tlsDefaultCa.configure(true);
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()) {
153  ::Parser::Tokenizer tok(tlsMinVersion);
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 {
277  updateTlsVersionLimits();
278 
279  Security::ContextPointer t(createBlankContext());
280  if (t) {
281  if (setOptions)
282  updateContextOptions(t);
283 #if USE_OPENSSL
284  // XXX: temporary performance regression. c_str() data copies and prevents this being a const method
285  Ssl::InitClientContext(t, *this, parsedFlags);
286 #endif
287  updateContextNpn(t);
288  updateContextCa(t);
289  updateContextCrl(t);
290  }
291 
292  return t;
293 }
294 
295 #if USE_OPENSSL
296 static struct ssl_option {
298  const char *name;
299  long value;
300 
301 } ssl_options[] = {
302 
303 #if SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
304  {
305  "NETSCAPE_REUSE_CIPHER_CHANGE_BUG", SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
306  },
307 #endif
308 #if SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG
309  {
310  "SSLREF2_REUSE_CERT_TYPE_BUG", SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG
311  },
312 #endif
313 #if SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER
314  {
315  "MICROSOFT_BIG_SSLV3_BUFFER", SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER
316  },
317 #endif
318 #if SSL_OP_SSLEAY_080_CLIENT_DH_BUG
319  {
320  "SSLEAY_080_CLIENT_DH_BUG", SSL_OP_SSLEAY_080_CLIENT_DH_BUG
321  },
322 #endif
323 #if SSL_OP_TLS_D5_BUG
324  {
325  "TLS_D5_BUG", SSL_OP_TLS_D5_BUG
326  },
327 #endif
328 #if SSL_OP_TLS_BLOCK_PADDING_BUG
329  {
330  "TLS_BLOCK_PADDING_BUG", SSL_OP_TLS_BLOCK_PADDING_BUG
331  },
332 #endif
333 #if SSL_OP_TLS_ROLLBACK_BUG
334  {
335  "TLS_ROLLBACK_BUG", SSL_OP_TLS_ROLLBACK_BUG
336  },
337 #endif
338 #if SSL_OP_ALL
339  {
340  "ALL", (long)SSL_OP_ALL
341  },
342 #endif
343 #if SSL_OP_SINGLE_DH_USE
344  {
345  "SINGLE_DH_USE", SSL_OP_SINGLE_DH_USE
346  },
347 #endif
348 #if SSL_OP_EPHEMERAL_RSA
349  {
350  "EPHEMERAL_RSA", SSL_OP_EPHEMERAL_RSA
351  },
352 #endif
353 #if SSL_OP_PKCS1_CHECK_1
354  {
355  "PKCS1_CHECK_1", SSL_OP_PKCS1_CHECK_1
356  },
357 #endif
358 #if SSL_OP_PKCS1_CHECK_2
359  {
360  "PKCS1_CHECK_2", SSL_OP_PKCS1_CHECK_2
361  },
362 #endif
363 #if SSL_OP_NETSCAPE_CA_DN_BUG
364  {
365  "NETSCAPE_CA_DN_BUG", SSL_OP_NETSCAPE_CA_DN_BUG
366  },
367 #endif
368 #if SSL_OP_NON_EXPORT_FIRST
369  {
370  "NON_EXPORT_FIRST", SSL_OP_NON_EXPORT_FIRST
371  },
372 #endif
373 #if SSL_OP_CIPHER_SERVER_PREFERENCE
374  {
375  "CIPHER_SERVER_PREFERENCE", SSL_OP_CIPHER_SERVER_PREFERENCE
376  },
377 #endif
378 #if SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG
379  {
380  "NETSCAPE_DEMO_CIPHER_CHANGE_BUG", SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG
381  },
382 #endif
383 #if SSL_OP_NO_SSLv3
384  {
385  "NO_SSLv3", SSL_OP_NO_SSLv3
386  },
387 #endif
388 #if SSL_OP_NO_TLSv1
389  {
390  "NO_TLSv1", SSL_OP_NO_TLSv1
391  },
392 #endif
393 #if SSL_OP_NO_TLSv1_1
394  {
395  "NO_TLSv1_1", SSL_OP_NO_TLSv1_1
396  },
397 #endif
398 #if SSL_OP_NO_TLSv1_2
399  {
400  "NO_TLSv1_2", SSL_OP_NO_TLSv1_2
401  },
402 #endif
403 #if SSL_OP_NO_COMPRESSION
404  {
405  "No_Compression", SSL_OP_NO_COMPRESSION
406  },
407 #endif
408 #if SSL_OP_NO_TICKET
409  {
410  "NO_TICKET", SSL_OP_NO_TICKET
411  },
412 #endif
413 #if SSL_OP_SINGLE_ECDH_USE
414  {
415  "SINGLE_ECDH_USE", SSL_OP_SINGLE_ECDH_USE
416  },
417 #endif
418  {
419  "", 0
420  },
421  {
422  NULL, 0
423  }
424 };
425 #endif /* USE_OPENSSL */
426 
431 void
433 {
434 #if USE_OPENSSL
435  ::Parser::Tokenizer tok(sslOptions);
436  long op = 0;
437 
438  while (!tok.atEnd()) {
439  enum {
440  MODE_ADD, MODE_REMOVE
441  } mode;
442 
443  if (tok.skip('-') || tok.skip('!'))
444  mode = MODE_REMOVE;
445  else {
446  (void)tok.skip('+'); // default action is add. ignore if missing operator
447  mode = MODE_ADD;
448  }
449 
450  static const CharacterSet optChars = CharacterSet("TLS-option", "_") + CharacterSet::ALPHA + CharacterSet::DIGIT;
451  int64_t hex = 0;
452  SBuf option;
453  long value = 0;
454 
455  // Bug 4429: identify the full option name before determining text or numeric
456  if (tok.prefix(option, optChars)) {
457 
458  // find the named option in our supported set
459  for (struct ssl_option *opttmp = ssl_options; opttmp->name; ++opttmp) {
460  if (option.cmp(opttmp->name) == 0) {
461  value = opttmp->value;
462  break;
463  }
464  }
465 
466  // Special case.. hex specification
467  ::Parser::Tokenizer tmp(option);
468  if (!value && tmp.int64(hex, 16, false) && tmp.atEnd()) {
469  value = hex;
470  }
471  }
472 
473  if (value) {
474  switch (mode) {
475  case MODE_ADD:
476  op |= value;
477  break;
478  case MODE_REMOVE:
479  op &= ~value;
480  break;
481  }
482  } else {
483  debugs(83, DBG_PARSE_NOTE(1), "ERROR: Unknown TLS option " << option);
484  }
485 
486  static const CharacterSet delims("TLS-option-delim",":,");
487  if (!tok.skipAll(delims) && !tok.atEnd()) {
488  fatalf("Unknown TLS option '" SQUIDSBUFPH "'", SQUIDSBUFPRINT(tok.remaining()));
489  }
490 
491  }
492 
493 #if SSL_OP_NO_SSLv2
494  // compliance with RFC 6176: Prohibiting Secure Sockets Layer (SSL) Version 2.0
495  op = op | SSL_OP_NO_SSLv2;
496 #endif
497  parsedOptions = op;
498 
499 #elif USE_GNUTLS
500  if (sslOptions.isEmpty()) {
501  parsedOptions.reset();
502  return;
503  }
504 
505  const char *err = nullptr;
506  const char *priorities = sslOptions.c_str();
507  gnutls_priority_t op;
508  if (gnutls_priority_init(&op, priorities, &err) != GNUTLS_E_SUCCESS) {
509  fatalf("Unknown TLS option '%s'", err);
510  }
511  parsedOptions = Security::ParsedOptions(op, [](gnutls_priority_t p) {
512  debugs(83, 5, "gnutls_priority_deinit p=" << (void*)p);
513  gnutls_priority_deinit(p);
514  });
515 #endif
516 }
517 
521 long
523 {
524  if (sslFlags.isEmpty())
525  return 0;
526 
527  static struct {
528  SBuf label;
529  long mask;
530  } flagTokens[] = {
531  { SBuf("NO_DEFAULT_CA"), SSL_FLAG_NO_DEFAULT_CA },
532  { SBuf("DELAYED_AUTH"), SSL_FLAG_DELAYED_AUTH },
533  { SBuf("DONT_VERIFY_PEER"), SSL_FLAG_DONT_VERIFY_PEER },
534  { SBuf("DONT_VERIFY_DOMAIN"), SSL_FLAG_DONT_VERIFY_DOMAIN },
535  { SBuf("NO_SESSION_REUSE"), SSL_FLAG_NO_SESSION_REUSE },
536 #if X509_V_FLAG_CRL_CHECK
537  { SBuf("VERIFY_CRL"), SSL_FLAG_VERIFY_CRL },
538  { SBuf("VERIFY_CRL_ALL"), SSL_FLAG_VERIFY_CRL_ALL },
539 #endif
540  { SBuf(), 0 }
541  };
542 
543  ::Parser::Tokenizer tok(sslFlags);
544  static const CharacterSet delims("Flag-delimiter", ":,");
545 
546  long fl = 0;
547  do {
548  long found = 0;
549  for (size_t i = 0; flagTokens[i].mask; ++i) {
550  if (tok.skip(flagTokens[i].label)) {
551  found = flagTokens[i].mask;
552  break;
553  }
554  }
555  if (!found)
556  fatalf("Unknown TLS flag '" SQUIDSBUFPH "'", SQUIDSBUFPRINT(tok.remaining()));
557  if (found == SSL_FLAG_NO_DEFAULT_CA) {
558  if (flags.tlsDefaultCa.configured() && flags.tlsDefaultCa)
559  fatal("ERROR: previous default-ca settings conflict with sslflags=NO_DEFAULT_CA");
560  debugs(83, DBG_PARSE_NOTE(2), "WARNING: flags=NO_DEFAULT_CA is deprecated. Use tls-default-ca=off instead.");
561  flags.tlsDefaultCa.configure(false);
562  } else
563  fl |= found;
564  } while (tok.skipOne(delims));
565 
566  return fl;
567 }
568 
571 void
573 {
574  parsedCrl.clear();
575  if (crlFile.isEmpty())
576  return;
577 
578 #if USE_OPENSSL
579  BIO *in = BIO_new_file(crlFile.c_str(), "r");
580  if (!in) {
581  debugs(83, 2, "WARNING: Failed to open CRL file " << crlFile);
582  return;
583  }
584 
585  while (X509_CRL *crl = PEM_read_bio_X509_CRL(in,NULL,NULL,NULL)) {
586  parsedCrl.emplace_back(Security::CrlPointer(crl));
587  }
588  BIO_free(in);
589 #endif
590 }
591 
592 void
594 {
595 #if USE_OPENSSL
596  SSL_CTX_set_options(ctx.get(), parsedOptions);
597 #elif USE_GNUTLS
598  // NP: GnuTLS uses 'priorities' which are set per-session instead.
599 #endif
600 }
601 
602 #if USE_OPENSSL && defined(TLSEXT_TYPE_next_proto_neg)
603 // Dummy next_proto_neg callback
604 static int
605 ssl_next_proto_cb(SSL *s, unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg)
606 {
607  static const unsigned char supported_protos[] = {8, 'h','t','t', 'p', '/', '1', '.', '1'};
608  (void)SSL_select_next_proto(out, outlen, in, inlen, supported_protos, sizeof(supported_protos));
609  return SSL_TLSEXT_ERR_OK;
610 }
611 #endif
612 
613 void
615 {
616  if (!flags.tlsNpn)
617  return;
618 
619 #if USE_OPENSSL && defined(TLSEXT_TYPE_next_proto_neg)
620  SSL_CTX_set_next_proto_select_cb(ctx.get(), &ssl_next_proto_cb, nullptr);
621 #endif
622 
623  // NOTE: GnuTLS does not support the obsolete NPN extension.
624  // it does support ALPN per-session, not per-context.
625 }
626 
627 static const char *
629 {
630  debugs(83, 8, "Setting default system Trusted CA. ctx=" << (void*)ctx.get());
631 #if USE_OPENSSL
632  if (SSL_CTX_set_default_verify_paths(ctx.get()) == 0)
633  return Security::ErrorString(ERR_get_error());
634 
635 #elif USE_GNUTLS
636  auto x = gnutls_certificate_set_x509_system_trust(ctx.get());
637  if (x < 0)
638  return Security::ErrorString(x);
639 
640 #endif
641  return nullptr;
642 }
643 
644 void
646 {
647  debugs(83, 8, "Setting CA certificate locations.");
648 #if USE_OPENSSL
649  if (const char *path = caDir.isEmpty() ? nullptr : caDir.c_str()) {
650  if (!SSL_CTX_load_verify_locations(ctx.get(), nullptr, path)) {
651  const auto x = ERR_get_error();
652  debugs(83, DBG_IMPORTANT, "WARNING: Ignoring error setting CA certificate location " << path << ": " << Security::ErrorString(x));
653  }
654  }
655 #endif
656  for (auto i : caFiles) {
657 #if USE_OPENSSL
658  if (!SSL_CTX_load_verify_locations(ctx.get(), i.c_str(), nullptr)) {
659  const auto x = ERR_get_error();
660  debugs(83, DBG_IMPORTANT, "WARNING: Ignoring error setting CA certificate location " <<
661  i << ": " << Security::ErrorString(x));
662  }
663 #elif USE_GNUTLS
664  const auto x = gnutls_certificate_set_x509_trust_file(ctx.get(), i.c_str(), GNUTLS_X509_FMT_PEM);
665  if (x < 0) {
666  debugs(83, DBG_IMPORTANT, "WARNING: Ignoring error setting CA certificate location " <<
667  i << ": " << Security::ErrorString(x));
668  }
669 #endif
670  }
671 
672  if (!flags.tlsDefaultCa)
673  return;
674 
675  if (const char *err = loadSystemTrustedCa(ctx)) {
676  debugs(83, DBG_IMPORTANT, "WARNING: Ignoring error setting default trusted CA : " << err);
677  }
678 }
679 
680 void
682 {
683 #if USE_OPENSSL
684  bool verifyCrl = false;
685  X509_STORE *st = SSL_CTX_get_cert_store(ctx.get());
686  if (parsedCrl.size()) {
687  for (auto &i : parsedCrl) {
688  if (!X509_STORE_add_crl(st, i.get()))
689  debugs(83, 2, "WARNING: Failed to add CRL");
690  else
691  verifyCrl = true;
692  }
693  }
694 
695 #if X509_V_FLAG_CRL_CHECK
696  if ((parsedFlags & SSL_FLAG_VERIFY_CRL_ALL))
697  X509_STORE_set_flags(st, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
698  else if (verifyCrl || (parsedFlags & SSL_FLAG_VERIFY_CRL))
699  X509_STORE_set_flags(st, X509_V_FLAG_CRL_CHECK);
700 #endif
701 
702 #endif /* USE_OPENSSL */
703 }
704 
705 void
707 {
708 #if USE_OPENSSL
709  // 'options=' value being set to session is a GnuTLS specific thing.
710 #elif USE_GNUTLS
711  int x;
712  SBuf errMsg;
713  if (!parsedOptions) {
714  debugs(83, 5, "set GnuTLS default priority/options for session=" << s);
715  x = gnutls_set_default_priority(s.get());
716  static const SBuf defaults("default");
717  errMsg = defaults;
718  } else {
719  debugs(83, 5, "set GnuTLS options '" << sslOptions << "' for session=" << s);
720  x = gnutls_priority_set(s.get(), parsedOptions.get());
721  errMsg = sslOptions;
722  }
723 
724  if (x != GNUTLS_E_SUCCESS) {
725  debugs(83, DBG_IMPORTANT, "ERROR: Failed to set TLS options (" << errMsg << "). error: " << Security::ErrorString(x));
726  }
727 #endif
728 }
729 
730 void
732 {
733  while(const char *token = ConfigParser::NextToken())
734  opt->parse(token);
735 }
736 
#define SSL_FLAG_VERIFY_CRL
Definition: forward.h:50
int xatoi(const char *token)
Definition: Parsing.cc:43
SBuf certFile
path of file containing PEM format X.509 certificate
Definition: KeyData.h:27
Definition: SBuf.h:86
int i
Definition: membanger.c:49
void updateContextCrl(Security::ContextPointer &)
setup the CRL details for the given context
Definition: PeerOptions.cc:681
SBuf & append(const SBuf &S)
Definition: SBuf.cc:195
SBuf & chop(size_type pos, size_type n=npos)
Definition: SBuf.cc:540
long ParsedOptions
Definition: forward.h:129
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
#define DBG_CRITICAL
Definition: Debug.h:45
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:614
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:298
void updateContextCa(Security::ContextPointer &)
setup the CA details for the given context
Definition: PeerOptions.cc:645
static const char * loadSystemTrustedCa(Security::ContextPointer &ctx)
Definition: PeerOptions.cc:628
#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:706
static const CharacterSet DIGIT
Definition: CharacterSet.h:81
PeerOptions ProxyOutgoingConfig
configuration options for DIRECT server access
Definition: PeerOptions.cc:22
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
bool atEnd() const
whether the end of the buffer has been reached
Definition: Tokenizer.h:41
std::shared_ptr< SSL_CTX > ContextPointer
Definition: Context.h:29
void fatal(const char *message)
Definition: fatal.cc:28
optimized set of C chars, with quick membership test and merge support
Definition: CharacterSet.h:17
virtual Security::ContextPointer createBlankContext() const
generate an unset security context object
Definition: PeerOptions.cc:245
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:132
bool skip(const SBuf &tokenToSkip)
Definition: Tokenizer.cc:160
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:79
TLS certificate and private key details from squid.conf.
Definition: KeyData.h:20
const SBuf & remaining() const
the remaining unprocessed section of buffer
Definition: Tokenizer.h:44
#define SSL_FLAG_NO_SESSION_REUSE
Definition: forward.h:49
void updateContextOptions(Security::ContextPointer &) const
Setup the library specific &#39;options=&#39; parameters for the given context.
Definition: PeerOptions.cc:593
void appendf(const char *fmt,...) PRINTF_FORMAT_ARG2
Append operation with printf-style arguments.
Definition: Packable.h:61
int cmp(const SBuf &S, const size_type n) const
shorthand version for compare()
Definition: SBuf.h:264
SBuf::size_type skipAll(const CharacterSet &discardables)
Definition: Tokenizer.cc:120
set of options we can parse and what they map to
Definition: PeerOptions.cc:297
#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:432
void parse_securePeerOptions(Security::PeerOptions *opt)
Definition: PeerOptions.cc:731
#define SQUIDSBUFPRINT(s)
Definition: SBuf.h:32
const char * ErrorString(const ErrorCode code)
Definition: forward.h:96
#define NULL
Definition: types.h:166
#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:209

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors