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

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors