bio.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 /* DEBUG: section 83 SSL accelerator support */
10 
11 #include "squid.h"
12 #include "ssl/support.h"
13 
14 /* support.cc says this is needed */
15 #if USE_OPENSSL
16 
17 #include "comm.h"
18 #include "fd.h"
19 #include "fde.h"
20 #include "globals.h"
21 #include "ip/Address.h"
22 #include "parser/BinaryTokenizer.h"
23 #include "SquidTime.h"
24 #include "ssl/bio.h"
25 
26 #if _SQUID_WINDOWS_
27 extern int socket_read_method(int, char *, int);
28 extern int socket_write_method(int, const char *, int);
29 #endif
30 
31 /* BIO callbacks */
32 static int squid_bio_write(BIO *h, const char *buf, int num);
33 static int squid_bio_read(BIO *h, char *buf, int size);
34 static int squid_bio_puts(BIO *h, const char *str);
35 //static int squid_bio_gets(BIO *h, char *str, int size);
36 static long squid_bio_ctrl(BIO *h, int cmd, long arg1, void *arg2);
37 static int squid_bio_create(BIO *h);
38 static int squid_bio_destroy(BIO *data);
39 /* SSL callbacks */
40 static void squid_ssl_info(const SSL *ssl, int where, int ret);
41 
42 #if HAVE_LIBCRYPTO_BIO_METH_NEW
43 static BIO_METHOD *SquidMethods = nullptr;
44 #else
45 static BIO_METHOD SquidMethods = {
48  BIO_TYPE_SOCKET,
49  "squid",
53  NULL, // squid_bio_gets not supported
57  NULL // squid_callback_ctrl not supported
58 };
59 #endif
60 
61 BIO *
63 {
64 #if HAVE_LIBCRYPTO_BIO_METH_NEW
65  if (!SquidMethods) {
66  SquidMethods = BIO_meth_new(BIO_TYPE_SOCKET, "squid");
67  BIO_meth_set_write(SquidMethods, squid_bio_write);
68  BIO_meth_set_read(SquidMethods, squid_bio_read);
69  BIO_meth_set_puts(SquidMethods, squid_bio_puts);
70  BIO_meth_set_gets(SquidMethods, NULL);
71  BIO_meth_set_ctrl(SquidMethods, squid_bio_ctrl);
72  BIO_meth_set_create(SquidMethods, squid_bio_create);
73  BIO_meth_set_destroy(SquidMethods, squid_bio_destroy);
74  }
75  BIO_METHOD *useMethod = SquidMethods;
76 #else
77  BIO_METHOD *useMethod = &SquidMethods;
78 #endif
79 
80  if (BIO *bio = BIO_new(useMethod)) {
81  BIO_int_ctrl(bio, BIO_C_SET_FD, type, fd);
82  return bio;
83  }
84  return NULL;
85 }
86 
87 void
88 Ssl::Bio::Link(SSL *ssl, BIO *bio)
89 {
90  SSL_set_bio(ssl, bio, bio); // cannot fail
91  SSL_set_info_callback(ssl, &squid_ssl_info); // does not provide diagnostic
92 }
93 
94 Ssl::Bio::Bio(const int anFd): fd_(anFd)
95 {
96  debugs(83, 7, "Bio constructed, this=" << this << " FD " << fd_);
97 }
98 
100 {
101  debugs(83, 7, "Bio destructing, this=" << this << " FD " << fd_);
102 }
103 
104 int Ssl::Bio::write(const char *buf, int size, BIO *table)
105 {
106  errno = 0;
107 #if _SQUID_WINDOWS_
108  const int result = socket_write_method(fd_, buf, size);
109 #else
110  const int result = default_write_method(fd_, buf, size);
111 #endif
112  const int xerrno = errno;
113  debugs(83, 5, "FD " << fd_ << " wrote " << result << " <= " << size);
114 
115  BIO_clear_retry_flags(table);
116  if (result < 0) {
117  const bool ignoreError = ignoreErrno(xerrno) != 0;
118  debugs(83, 5, "error: " << xerrno << " ignored: " << ignoreError);
119  if (ignoreError)
120  BIO_set_retry_write(table);
121  }
122 
123  return result;
124 }
125 
126 int
127 Ssl::Bio::read(char *buf, int size, BIO *table)
128 {
129  errno = 0;
130 #if _SQUID_WINDOWS_
131  const int result = socket_read_method(fd_, buf, size);
132 #else
133  const int result = default_read_method(fd_, buf, size);
134 #endif
135  const int xerrno = errno;
136  debugs(83, 5, "FD " << fd_ << " read " << result << " <= " << size);
137 
138  BIO_clear_retry_flags(table);
139  if (result < 0) {
140  const bool ignoreError = ignoreErrno(xerrno) != 0;
141  debugs(83, 5, "error: " << xerrno << " ignored: " << ignoreError);
142  if (ignoreError)
143  BIO_set_retry_read(table);
144  }
145 
146  return result;
147 }
148 
151 void
152 Ssl::Bio::stateChanged(const SSL *ssl, int where, int ret)
153 {
154  // Here we can use (where & STATE) to check the current state.
155  // Many STATE values are possible, including: SSL_CB_CONNECT_LOOP,
156  // SSL_CB_ACCEPT_LOOP, SSL_CB_HANDSHAKE_START, and SSL_CB_HANDSHAKE_DONE.
157  // For example:
158  // if (where & SSL_CB_HANDSHAKE_START)
159  // debugs(83, 9, "Trying to establish the SSL connection");
160  // else if (where & SSL_CB_HANDSHAKE_DONE)
161  // debugs(83, 9, "SSL connection established");
162 
163  debugs(83, 7, "FD " << fd_ << " now: 0x" << std::hex << where << std::dec << ' ' <<
164  SSL_state_string(ssl) << " (" << SSL_state_string_long(ssl) << ")");
165 }
166 
168  Bio(anFd),
169  holdRead_(false),
170  holdWrite_(false),
171  helloSize(0),
172  abortReason(nullptr)
173 {
174  renegotiations.configure(10*1000);
175 }
176 
177 void
178 Ssl::ClientBio::stateChanged(const SSL *ssl, int where, int ret)
179 {
180  Ssl::Bio::stateChanged(ssl, where, ret);
181  // detect client-initiated renegotiations DoS (CVE-2011-1473)
182  if (where & SSL_CB_HANDSHAKE_START) {
183  const int reneg = renegotiations.count(1);
184 
185  if (abortReason)
186  return; // already decided and informed the admin
187 
188  if (reneg > RenegotiationsLimit) {
189  abortReason = "renegotiate requests flood";
190  debugs(83, DBG_IMPORTANT, "Terminating TLS connection [from " << fd_table[fd_].ipaddr << "] due to " << abortReason << ". This connection received " <<
191  reneg << " renegotiate requests in the last " <<
192  RenegotiationsWindow << " seconds (and " <<
193  renegotiations.remembered() << " requests total).");
194  }
195  }
196 }
197 
198 int
199 Ssl::ClientBio::write(const char *buf, int size, BIO *table)
200 {
201  if (abortReason) {
202  debugs(83, 3, "BIO on FD " << fd_ << " is aborted");
203  BIO_clear_retry_flags(table);
204  return -1;
205  }
206 
207  if (holdWrite_) {
208  BIO_set_retry_write(table);
209  return 0;
210  }
211 
212  return Ssl::Bio::write(buf, size, table);
213 }
214 
215 int
216 Ssl::ClientBio::read(char *buf, int size, BIO *table)
217 {
218  if (abortReason) {
219  debugs(83, 3, "BIO on FD " << fd_ << " is aborted");
220  BIO_clear_retry_flags(table);
221  return -1;
222  }
223 
224  if (holdRead_) {
225  debugs(83, 7, "Hold flag is set, retry latter. (Hold " << size << "bytes)");
226  BIO_set_retry_read(table);
227  return -1;
228  }
229 
230  if (!rbuf.isEmpty()) {
231  int bytes = (size <= (int)rbuf.length() ? size : rbuf.length());
232  memcpy(buf, rbuf.rawContent(), bytes);
233  rbuf.consume(bytes);
234  return bytes;
235  } else
236  return Ssl::Bio::read(buf, size, table);
237 
238  return -1;
239 }
240 
242  Bio(anFd),
243  helloMsgSize(0),
244  helloBuild(false),
245  allowSplice(false),
246  allowBump(false),
247  holdWrite_(false),
248  holdRead_(true),
249  record_(false),
250  parsedHandshake(false),
251  parseError(false),
252  bumpMode_(bumpNone),
253  rbufConsumePos(0)
254 {
255 }
256 
257 void
258 Ssl::ServerBio::stateChanged(const SSL *ssl, int where, int ret)
259 {
260  Ssl::Bio::stateChanged(ssl, where, ret);
261 }
262 
263 void
265 {
266  clientTlsDetails = details;
267  clientSentHello = aHello;
268 };
269 
270 int
271 Ssl::ServerBio::read(char *buf, int size, BIO *table)
272 {
273  if (parsedHandshake) // done parsing TLS Hello
274  return readAndGive(buf, size, table);
275  else
276  return readAndParse(buf, size, table);
277 }
278 
280 int
281 Ssl::ServerBio::readAndGive(char *buf, const int size, BIO *table)
282 {
283  // If we have unused buffered bytes, give those bytes to OpenSSL now,
284  // before reading more. TODO: Read if we have buffered less than size?
285  if (rbufConsumePos < rbuf.length())
286  return giveBuffered(buf, size);
287 
288  if (record_) {
289  const int result = readAndBuffer(table);
290  if (result <= 0)
291  return result;
292  return giveBuffered(buf, size);
293  }
294 
295  return Ssl::Bio::read(buf, size, table);
296 }
297 
300 int
301 Ssl::ServerBio::readAndParse(char *buf, const int size, BIO *table)
302 {
303  const int result = readAndBuffer(table);
304  if (result <= 0)
305  return result;
306 
307  try {
308  if (!parser_.parseHello(rbuf)) {
309  // need more data to finish parsing
310  BIO_set_retry_read(table);
311  return -1;
312  }
313  parsedHandshake = true; // done parsing (successfully)
314  }
315  catch (const std::exception &ex) {
316  debugs(83, 2, "parsing error on FD " << fd_ << ": " << ex.what());
317  parsedHandshake = true; // done parsing (due to an error)
318  parseError = true;
319  }
320 
321  if (holdRead_) {
322  debugs(83, 7, "Hold flag is set, retry latter. (Hold " << size << "bytes)");
323  BIO_set_retry_read(table);
324  return -1;
325  }
326 
327  return giveBuffered(buf, size);
328 }
329 
332 int
334 {
335  char *space = rbuf.rawAppendStart(SQUID_TCP_SO_RCVBUF);
336  const int result = Ssl::Bio::read(space, SQUID_TCP_SO_RCVBUF, table);
337  if (result <= 0)
338  return result;
339 
340  rbuf.rawAppendFinish(space, result);
341  return result;
342 }
343 
346 int
348 {
349  if (rbuf.length() <= rbufConsumePos)
350  return -1; // buffered nothing yet
351 
352  const int unsent = rbuf.length() - rbufConsumePos;
353  const int bytes = (size <= unsent ? size : unsent);
354  memcpy(buf, rbuf.rawContent() + rbufConsumePos, bytes);
355  rbufConsumePos += bytes;
356  debugs(83, 7, bytes << "<=" << size << " bytes to OpenSSL");
357  return bytes;
358 }
359 
360 // This function makes the required checks to examine if the client hello
361 // message is compatible with the features provided by OpenSSL toolkit.
362 // If the features are compatible and can be supported it tries to rewrite SSL
363 // structure members, to replace the hello message created by openSSL, with the
364 // web client SSL hello message.
365 // This is mostly possible in the cases where the web client uses openSSL
366 // library similar with this one used by squid.
367 static bool
368 adjustSSL(SSL *ssl, Security::TlsDetails::Pointer const &details, SBuf &helloMessage)
369 {
370 #if SQUID_USE_OPENSSL_HELLO_OVERWRITE_HACK
371  if (!details)
372  return false;
373 
374  if (!ssl->s3) {
375  debugs(83, 5, "No SSLv3 data found!");
376  return false;
377  }
378 
379  // If the client supports compression but our context does not support
380  // we can not adjust.
381 #if !defined(OPENSSL_NO_COMP)
382  const bool requireCompression = (details->compressionSupported && ssl->ctx->comp_methods == nullptr);
383 #else
384  const bool requireCompression = details->compressionSupported;
385 #endif
386  if (requireCompression) {
387  debugs(83, 5, "Client Hello Data supports compression, but we do not!");
388  return false;
389  }
390 
391 #if !defined(SSL_TLSEXT_HB_ENABLED)
392  if (details->doHeartBeats) {
393  debugs(83, 5, "Client Hello Data supports HeartBeats but we do not support!");
394  return false;
395  }
396 #endif
397 
398  if (details->unsupportedExtensions) {
399  debugs(83, 5, "Client Hello contains extensions that we do not support!");
400  return false;
401  }
402 
403  SSL3_BUFFER *wb=&(ssl->s3->wbuf);
404  if (wb->len < (size_t)helloMessage.length()) {
405  debugs(83, 5, "Client Hello exceeds OpenSSL buffer: " << helloMessage.length() << " >= " << wb->len);
406  return false;
407  }
408 
409  /* Check whether all on-the-wire ciphers are supported by OpenSSL. */
410 
411  const auto &wireCiphers = details->ciphers;
412  Security::TlsDetails::Ciphers::size_type ciphersToFind = wireCiphers.size();
413 
414  // RFC 5746: "TLS_EMPTY_RENEGOTIATION_INFO_SCSV is not a true cipher suite".
415  // It is commonly seen on the wire, including in from-OpenSSL traffic, but
416  // SSL_get_ciphers() does not return this _pseudo_ cipher suite in my tests.
417  // If OpenSSL supports scsvCipher, we count it (at most once) further below.
418 #if defined(TLSEXT_TYPE_renegotiate)
419  // the 0x00FFFF mask converts 3-byte OpenSSL cipher to our 2-byte cipher
420  const uint16_t scsvCipher = SSL3_CK_SCSV & 0x00FFFF;
421 #else
422  const uint16_t scsvCipher = 0;
423 #endif
424 
425  STACK_OF(SSL_CIPHER) *cipher_stack = SSL_get_ciphers(ssl);
426  const int supportedCipherCount = sk_SSL_CIPHER_num(cipher_stack);
427  for (int idx = 0; idx < supportedCipherCount && ciphersToFind > 0; ++idx) {
428  const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(cipher_stack, idx);
429  const auto id = SSL_CIPHER_get_id(cipher) & 0x00FFFF;
430  if (wireCiphers.find(id) != wireCiphers.end() && (!scsvCipher || id != scsvCipher))
431  --ciphersToFind;
432  }
433 
434  if (ciphersToFind > 0 && scsvCipher && wireCiphers.find(scsvCipher) != wireCiphers.end())
435  --ciphersToFind;
436 
437  if (ciphersToFind > 0) {
438  // TODO: Add slowlyReportUnsupportedCiphers() to slowly find and report each of them
439  debugs(83, 5, "Client Hello Data has " << ciphersToFind << " ciphers that we do not support!");
440  return false;
441  }
442 
443  debugs(83, 5, "OpenSSL SSL struct will be adjusted to mimic client hello data!");
444 
445  //Adjust ssl structure data.
446  // We need to fix the random in SSL struct:
447  if (details->clientRandom.length() == SSL3_RANDOM_SIZE)
448  memcpy(ssl->s3->client_random, details->clientRandom.c_str(), SSL3_RANDOM_SIZE);
449  memcpy(wb->buf, helloMessage.rawContent(), helloMessage.length());
450  wb->left = helloMessage.length();
451 
452  size_t mainHelloSize = helloMessage.length() - 5;
453  const char *mainHello = helloMessage.rawContent() + 5;
454  assert((size_t)ssl->init_buf->max > mainHelloSize);
455  memcpy(ssl->init_buf->data, mainHello, mainHelloSize);
456  debugs(83, 5, "Hello Data init and adjustd sizes :" << ssl->init_num << " = "<< mainHelloSize);
457  ssl->init_num = mainHelloSize;
458  ssl->s3->wpend_ret = mainHelloSize;
459  ssl->s3->wpend_tot = mainHelloSize;
460  return true;
461 #else
462  return false;
463 #endif
464 }
465 
466 int
467 Ssl::ServerBio::write(const char *buf, int size, BIO *table)
468 {
469 
470  if (holdWrite_) {
471  debugs(83, 7, "postpone writing " << size << " bytes to SSL FD " << fd_);
472  BIO_set_retry_write(table);
473  return -1;
474  }
475 
476  if (!helloBuild && (bumpMode_ == Ssl::bumpPeek || bumpMode_ == Ssl::bumpStare)) {
477  // buf contains OpenSSL-generated ClientHello. We assume it has a
478  // complete ClientHello and nothing else, but cannot fully verify
479  // that quickly. We only verify that buf starts with a v3+ record
480  // containing ClientHello.
481  Must(size >= 2); // enough for version and content_type checks below
482  Must(buf[1] >= 3); // record's version.major; determines buf[0] meaning
483  Must(buf[0] == 22); // TLSPlaintext.content_type == handshake in v3+
484 
485  //Hello message is the first message we write to server
486  assert(helloMsg.isEmpty());
487 
488  if (auto ssl = fd_table[fd_].ssl.get()) {
489  if (bumpMode_ == Ssl::bumpPeek) {
490  // we should not be here if we failed to parse the client-sent ClientHello
491  Must(!clientSentHello.isEmpty());
492  if (adjustSSL(ssl, clientTlsDetails, clientSentHello))
493  allowBump = true;
494  allowSplice = true;
495  // Replace OpenSSL-generated ClientHello with client-sent one.
496  helloMsg.append(clientSentHello);
497  debugs(83, 7, "FD " << fd_ << ": Using client-sent ClientHello for peek mode");
498  } else { /*Ssl::bumpStare*/
499  allowBump = true;
500  if (!clientSentHello.isEmpty() && adjustSSL(ssl, clientTlsDetails, clientSentHello)) {
501  allowSplice = true;
502  helloMsg.append(clientSentHello);
503  debugs(83, 7, "FD " << fd_ << ": Using client-sent ClientHello for stare mode");
504  }
505  }
506  }
507  // if we did not use the client-sent ClientHello, then use the OpenSSL-generated one
508  if (helloMsg.isEmpty())
509  helloMsg.append(buf, size);
510 
511  helloBuild = true;
512  helloMsgSize = helloMsg.length();
513  //allowBump = true;
514 
515  if (allowSplice) {
516  // Do not write yet.....
517  BIO_set_retry_write(table);
518  return -1;
519  }
520  }
521 
522  if (!helloMsg.isEmpty()) {
523  debugs(83, 7, "buffered write for FD " << fd_);
524  int ret = Ssl::Bio::write(helloMsg.rawContent(), helloMsg.length(), table);
525  helloMsg.consume(ret);
526  if (!helloMsg.isEmpty()) {
527  // We need to retry sendind data.
528  // Say to openSSL to retry sending hello message
529  BIO_set_retry_write(table);
530  return -1;
531  }
532 
533  // Sending hello message complete. Do not send more data for now...
534  holdWrite_ = true;
535 
536  // spoof openSSL that we write what it ask us to write
537  return size;
538  } else
539  return Ssl::Bio::write(buf, size, table);
540 }
541 
542 void
544 {
545  if (!helloMsg.isEmpty()) {
546  int ret = Ssl::Bio::write(helloMsg.rawContent(), helloMsg.length(), table);
547  helloMsg.consume(ret);
548  }
549 }
550 
551 bool
553 {
554  return parser_.resumingSession;
555 }
556 
558 static int
560 {
561 #if !HAVE_LIBCRYPTO_BIO_GET_INIT
562  bi->init = 0; // set when we store Bio object and socket fd (BIO_C_SET_FD)
563  bi->num = 0;
564  bi->flags = 0;
565 #else
566  // No need to set more, openSSL initialize BIO memory to zero.
567 #endif
568 
569  BIO_set_data(bi, NULL);
570  return 1;
571 }
572 
574 static int
575 squid_bio_destroy(BIO *table)
576 {
577  delete static_cast<Ssl::Bio*>(BIO_get_data(table));
578  BIO_set_data(table, NULL);
579  return 1;
580 }
581 
583 static int
584 squid_bio_write(BIO *table, const char *buf, int size)
585 {
586  Ssl::Bio *bio = static_cast<Ssl::Bio*>(BIO_get_data(table));
587  assert(bio);
588  return bio->write(buf, size, table);
589 }
590 
592 static int
593 squid_bio_read(BIO *table, char *buf, int size)
594 {
595  Ssl::Bio *bio = static_cast<Ssl::Bio*>(BIO_get_data(table));
596  assert(bio);
597  return bio->read(buf, size, table);
598 }
599 
601 static int
602 squid_bio_puts(BIO *table, const char *str)
603 {
604  assert(str);
605  return squid_bio_write(table, str, strlen(str));
606 }
607 
609 static long
610 squid_bio_ctrl(BIO *table, int cmd, long arg1, void *arg2)
611 {
612  debugs(83, 5, table << ' ' << cmd << '(' << arg1 << ", " << arg2 << ')');
613 
614  switch (cmd) {
615  case BIO_C_SET_FD: {
616  assert(arg2);
617  const int fd = *static_cast<int*>(arg2);
618  Ssl::Bio *bio;
619  if (arg1 == Security::Io::BIO_TO_SERVER)
620  bio = new Ssl::ServerBio(fd);
621  else
622  bio = new Ssl::ClientBio(fd);
623  assert(!BIO_get_data(table));
624  BIO_set_data(table, bio);
625  BIO_set_init(table, 1);
626  return 0;
627  }
628 
629  case BIO_C_GET_FD:
630  if (BIO_get_init(table)) {
631  Ssl::Bio *bio = static_cast<Ssl::Bio*>(BIO_get_data(table));
632  assert(bio);
633  if (arg2)
634  *static_cast<int*>(arg2) = bio->fd();
635  return bio->fd();
636  }
637  return -1;
638 
639  case BIO_CTRL_DUP:
640  // Should implemented if the SSL_dup openSSL API function
641  // used anywhere in squid.
642  return 0;
643 
644  case BIO_CTRL_FLUSH:
645  if (BIO_get_init(table)) {
646  Ssl::Bio *bio = static_cast<Ssl::Bio*>(BIO_get_data(table));
647  assert(bio);
648  bio->flush(table);
649  return 1;
650  }
651  return 0;
652 
653  /* we may also need to implement these:
654  case BIO_CTRL_RESET:
655  case BIO_C_FILE_SEEK:
656  case BIO_C_FILE_TELL:
657  case BIO_CTRL_INFO:
658  case BIO_CTRL_GET_CLOSE:
659  case BIO_CTRL_SET_CLOSE:
660  case BIO_CTRL_PENDING:
661  case BIO_CTRL_WPENDING:
662  */
663  default:
664  return 0;
665 
666  }
667 
668  return 0; /* NOTREACHED */
669 }
670 
672 static void
673 squid_ssl_info(const SSL *ssl, int where, int ret)
674 {
675  if (BIO *table = SSL_get_rbio(ssl)) {
676  if (Ssl::Bio *bio = static_cast<Ssl::Bio*>(BIO_get_data(table)))
677  bio->stateChanged(ssl, where, ret);
678  }
679 }
680 
681 void
683 {
684  // To increase the possibility for bumping after peek mode selection or
685  // splicing after stare mode selection it is good to set the
686  // SSL protocol version.
687  // The SSL_set_ssl_method is wrong here because it will restrict the
688  // permitted transport version to be identical to the version used in the
689  // ClientHello message.
690  // For example will prevent comunnicating with a tls1.0 server if the
691  // client sent and tlsv1.2 Hello message.
692 #if defined(TLSEXT_NAMETYPE_host_name)
693  if (!details->serverName.isEmpty()) {
694  SSL_set_tlsext_host_name(ssl, details->serverName.c_str());
695  }
696 #endif
697 
698  if (!details->ciphers.empty()) {
699  SBuf strCiphers;
700  for (auto cipherId: details->ciphers) {
701  unsigned char cbytes[3];
702  cbytes[0] = (cipherId >> 8) & 0xFF;
703  cbytes[1] = cipherId & 0xFF;
704  cbytes[2] = 0;
705  if (const auto c = SSL_CIPHER_find(ssl, cbytes)) {
706  if (!strCiphers.isEmpty())
707  strCiphers.append(":");
708  strCiphers.append(SSL_CIPHER_get_name(c));
709  }
710  }
711  if (!strCiphers.isEmpty())
712  SSL_set_cipher_list(ssl, strCiphers.c_str());
713  }
714 
715 #if defined(SSL_OP_NO_COMPRESSION) /* XXX: OpenSSL 0.9.8k lacks SSL_OP_NO_COMPRESSION */
716  if (!details->compressionSupported)
717  SSL_set_options(ssl, SSL_OP_NO_COMPRESSION);
718 #endif
719 
720 #if defined(TLSEXT_STATUSTYPE_ocsp)
721  if (details->tlsStatusRequest)
722  SSL_set_tlsext_status_type(ssl, TLSEXT_STATUSTYPE_ocsp);
723 #endif
724 
725 #if defined(TLSEXT_TYPE_application_layer_protocol_negotiation)
726  if (!details->tlsAppLayerProtoNeg.isEmpty()) {
727  if (bumpMode == Ssl::bumpPeek)
728  SSL_set_alpn_protos(ssl, (const unsigned char*)details->tlsAppLayerProtoNeg.rawContent(), details->tlsAppLayerProtoNeg.length());
729  else {
730  static const unsigned char supported_protos[] = {8, 'h','t','t', 'p', '/', '1', '.', '1'};
731  SSL_set_alpn_protos(ssl, supported_protos, sizeof(supported_protos));
732  }
733  }
734 #endif
735 }
736 
737 #endif // USE_OPENSSL
738 
static int squid_bio_puts(BIO *h, const char *str)
implements puts() via write()
Definition: bio.cc:602
STACK_OF(X509)*X509_STORE_CTX_get0_untrusted(X509_STORE_CTX *ctx)
Definition: openssl.h:195
static long squid_bio_ctrl(BIO *h, int cmd, long arg1, void *arg2)
other BIO manipulations (those without dedicated callbacks in BIO table)
Definition: bio.cc:610
static BIO * Create(const int fd, Security::Io::Type type)
Definition: bio.cc:62
#define fd_table
Definition: fde.h:157
const SSL_CIPHER * SSL_CIPHER_find(SSL *ssl, const unsigned char *ptr)
Definition: openssl.h:137
#define assert(EX)
Definition: assert.h:17
int type
Definition: errorpage.cc:78
Definition: SBuf.h:86
static void Link(SSL *ssl, BIO *bio)
Tells ssl connection to use BIO and monitor state via stateChanged()
Definition: bio.cc:88
virtual void flush(BIO *table)
Definition: bio.h:47
virtual int write(const char *buf, int size, BIO *table)
The ClientBio version of the Ssl::Bio::write method.
Definition: bio.cc:199
int default_read_method(int, char *, int)
Definition: fd.cc:146
SBuf & append(const SBuf &S)
Definition: SBuf.cc:195
virtual int write(const char *buf, int size, BIO *table)
Writes the given data to socket.
Definition: bio.cc:104
const char * bumpMode(int bm)
Definition: support.h:145
const int fd_
the SSL socket we are reading and writing
Definition: bio.h:63
static int squid_bio_write(BIO *h, const char *buf, int num)
wrapper for Bio::write()
Definition: bio.cc:584
#define Must(condition)
Like assert() but throws an exception instead of aborting the process.
Definition: TextException.h:69
bool isEmpty() const
Definition: SBuf.h:420
void setClientFeatures(Security::TlsDetails::Pointer const &details, SBuf const &hello)
Sets the random number to use in client SSL HELLO message.
Definition: bio.cc:264
void BIO_set_init(BIO *table, int init)
Definition: openssl.h:72
int default_write_method(int, const char *, int)
Definition: fd.cc:156
virtual ~Bio()
Definition: bio.cc:99
void * BIO_get_data(BIO *table)
Definition: openssl.h:60
static int squid_bio_create(BIO *h)
initializes BIO table after allocation
Definition: bio.cc:559
virtual int write(const char *buf, int size, BIO *table)
Definition: bio.cc:467
static int squid_bio_read(BIO *h, char *buf, int size)
wrapper for Bio::read()
Definition: bio.cc:593
void const char HLPCB void * data
Definition: stub_helper.cc:16
size_type length() const
Returns the number of bytes stored in SBuf.
Definition: SBuf.h:404
#define debugs(SECTION, LEVEL, CONTENT)
Definition: Debug.h:124
#define true
Definition: GnuRegex.c:234
#define DBG_IMPORTANT
Definition: Debug.h:46
virtual int read(char *buf, int size, BIO *table)
Definition: bio.cc:271
int giveBuffered(char *buf, const int size)
Definition: bio.cc:347
static void squid_ssl_info(const SSL *ssl, int where, int ret)
wrapper for Bio::stateChanged()
Definition: bio.cc:673
void BIO_set_data(BIO *table, void *data)
Definition: openssl.h:66
BIO source and sink node, handling socket I/O and monitoring SSL state.
Definition: bio.h:33
const char * c_str()
Definition: SBuf.cc:526
virtual int read(char *buf, int size, BIO *table)
Reads data from socket.
Definition: bio.cc:127
ClientBio(const int anFd)
Definition: bio.cc:167
void const char * buf
Definition: stub_helper.cc:16
void applyTlsDetailsToSSL(SSL *ssl, Security::TlsDetails::Pointer const &details, Ssl::BumpMode bumpMode)
Definition: bio.cc:682
bool SIGHDLR int STUB void int
Definition: stub_tools.cc:68
void configure(double horizonSeconds)
0=remember nothing; -1=forget nothing; new value triggers clear()
int ignoreErrno(int ierrno)
Definition: comm.cc:1477
static BIO_METHOD SquidMethods
Definition: bio.cc:47
bool resumingSession()
Definition: bio.cc:552
FadingCounter renegotiations
client requested renegotiations limit control
Definition: bio.h:102
virtual void stateChanged(const SSL *ssl, int where, int ret)
Definition: bio.cc:152
virtual void stateChanged(const SSL *ssl, int where, int ret)
Definition: bio.cc:178
static bool adjustSSL(SSL *ssl, Security::TlsDetails::Pointer const &details, SBuf &helloMessage)
Definition: bio.cc:368
virtual void flush(BIO *table)
Definition: bio.cc:543
int fd() const
The SSL socket descriptor.
Definition: bio.h:49
virtual int read(char *buf, int size, BIO *table)
Definition: bio.cc:216
Bio(const int anFd)
Definition: bio.cc:94
ServerBio(const int anFd)
Definition: bio.cc:241
BumpMode
Definition: support.h:131
int readAndBuffer(BIO *table)
Definition: bio.cc:333
static int squid_bio_destroy(BIO *data)
cleans BIO table before deallocation
Definition: bio.cc:575
int readAndGive(char *buf, const int size, BIO *table)
Read and give everything to OpenSSL.
Definition: bio.cc:281
int readAndParse(char *buf, const int size, BIO *table)
Definition: bio.cc:301
const char * rawContent() const
Definition: SBuf.cc:519
virtual void stateChanged(const SSL *ssl, int where, int ret)
The ServerBio version of the Ssl::Bio::stateChanged method.
Definition: bio.cc:258
#define NULL
Definition: types.h:166
int size
Definition: ModDevPoll.cc:77
#define false
Definition: GnuRegex.c:233
int BIO_get_init(BIO *table)
Definition: openssl.h:80

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors