]> git.ipfire.org Git - thirdparty/squid.git/blame - src/ssl/bio.cc
Source Format Enforcement (#963)
[thirdparty/squid.git] / src / ssl / bio.cc
CommitLineData
b3a8ae1b 1/*
bf95c10a 2 * Copyright (C) 1996-2022 The Squid Software Foundation and contributors
b3a8ae1b 3 *
bbc27441
AJ
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.
b3a8ae1b
AR
7 */
8
bbc27441
AJ
9/* DEBUG: section 83 SSL accelerator support */
10
b3a8ae1b 11#include "squid.h"
d620ae0e 12#include "ssl/support.h"
b3a8ae1b
AR
13
14/* support.cc says this is needed */
31855516 15#if USE_OPENSSL
b3a8ae1b
AR
16
17#include "comm.h"
2e198b84 18#include "fd.h"
d620ae0e
CT
19#include "fde.h"
20#include "globals.h"
40f1e76d 21#include "ip/Address.h"
7c8ee688 22#include "parser/BinaryTokenizer.h"
edb876ab 23#include "SquidTime.h"
b3a8ae1b 24#include "ssl/bio.h"
8693472e 25
b3a8ae1b
AR
26#if _SQUID_WINDOWS_
27extern int socket_read_method(int, char *, int);
28extern int socket_write_method(int, const char *, int);
29#endif
30
31/* BIO callbacks */
32static int squid_bio_write(BIO *h, const char *buf, int num);
33static int squid_bio_read(BIO *h, char *buf, int size);
34static int squid_bio_puts(BIO *h, const char *str);
35//static int squid_bio_gets(BIO *h, char *str, int size);
36static long squid_bio_ctrl(BIO *h, int cmd, long arg1, void *arg2);
37static int squid_bio_create(BIO *h);
38static int squid_bio_destroy(BIO *data);
39/* SSL callbacks */
40static void squid_ssl_info(const SSL *ssl, int where, int ret);
41
17e98f24
AJ
42#if HAVE_LIBCRYPTO_BIO_METH_NEW
43static BIO_METHOD *SquidMethods = nullptr;
44#else
b3a8ae1b
AR
45/// Initialization structure for the BIO table with
46/// Squid-specific methods and BIO method wrappers.
47static BIO_METHOD SquidMethods = {
48 BIO_TYPE_SOCKET,
49 "squid",
50 squid_bio_write,
51 squid_bio_read,
52 squid_bio_puts,
53 NULL, // squid_bio_gets not supported
54 squid_bio_ctrl,
55 squid_bio_create,
56 squid_bio_destroy,
57 NULL // squid_callback_ctrl not supported
58};
093deea9 59#endif
b3a8ae1b
AR
60
61BIO *
86f77270 62Ssl::Bio::Create(const int fd, Security::Io::Type type)
b3a8ae1b 63{
17e98f24 64#if HAVE_LIBCRYPTO_BIO_METH_NEW
093deea9
CT
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 }
24b30fdc 75 BIO_METHOD *useMethod = SquidMethods;
17e98f24
AJ
76#else
77 BIO_METHOD *useMethod = &SquidMethods;
093deea9 78#endif
ac756c8c 79
2a268a06
CT
80 if (BIO *bio = BIO_new(useMethod)) {
81 BIO_int_ctrl(bio, BIO_C_SET_FD, type, fd);
82 return bio;
83 }
b3a8ae1b
AR
84 return NULL;
85}
86
87void
88Ssl::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
b3a8ae1b
AR
94Ssl::Bio::Bio(const int anFd): fd_(anFd)
95{
96 debugs(83, 7, "Bio constructed, this=" << this << " FD " << fd_);
97}
98
99Ssl::Bio::~Bio()
100{
101 debugs(83, 7, "Bio destructing, this=" << this << " FD " << fd_);
b3a8ae1b
AR
102}
103
104int 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
126int
127Ssl::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
149/// Called whenever the SSL connection state changes, an alert appears, or an
150/// error occurs. See SSL_set_info_callback().
151void
8b082ed9 152Ssl::Bio::stateChanged(const SSL *ssl, int where, int)
b3a8ae1b
AR
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
d620ae0e 163 debugs(83, 7, "FD " << fd_ << " now: 0x" << std::hex << where << std::dec << ' ' <<
b3a8ae1b
AR
164 SSL_state_string(ssl) << " (" << SSL_state_string_long(ssl) << ")");
165}
166
edb876ab
CT
167Ssl::ClientBio::ClientBio(const int anFd):
168 Bio(anFd),
169 holdRead_(false),
170 holdWrite_(false),
edb876ab
CT
171 abortReason(nullptr)
172{
173 renegotiations.configure(10*1000);
174}
175
e1f72a8b 176void
d620ae0e
CT
177Ssl::ClientBio::stateChanged(const SSL *ssl, int where, int ret)
178{
179 Ssl::Bio::stateChanged(ssl, where, ret);
edb876ab
CT
180 // detect client-initiated renegotiations DoS (CVE-2011-1473)
181 if (where & SSL_CB_HANDSHAKE_START) {
182 const int reneg = renegotiations.count(1);
183
184 if (abortReason)
185 return; // already decided and informed the admin
186
187 if (reneg > RenegotiationsLimit) {
188 abortReason = "renegotiate requests flood";
189 debugs(83, DBG_IMPORTANT, "Terminating TLS connection [from " << fd_table[fd_].ipaddr << "] due to " << abortReason << ". This connection received " <<
190 reneg << " renegotiate requests in the last " <<
191 RenegotiationsWindow << " seconds (and " <<
192 renegotiations.remembered() << " requests total).");
193 }
194 }
d620ae0e
CT
195}
196
197int
198Ssl::ClientBio::write(const char *buf, int size, BIO *table)
199{
edb876ab
CT
200 if (abortReason) {
201 debugs(83, 3, "BIO on FD " << fd_ << " is aborted");
202 BIO_clear_retry_flags(table);
203 return -1;
204 }
205
d620ae0e
CT
206 if (holdWrite_) {
207 BIO_set_retry_write(table);
208 return 0;
209 }
210
211 return Ssl::Bio::write(buf, size, table);
212}
213
d620ae0e
CT
214int
215Ssl::ClientBio::read(char *buf, int size, BIO *table)
216{
edb876ab
CT
217 if (abortReason) {
218 debugs(83, 3, "BIO on FD " << fd_ << " is aborted");
219 BIO_clear_retry_flags(table);
220 return -1;
221 }
222
d620ae0e
CT
223 if (holdRead_) {
224 debugs(83, 7, "Hold flag is set, retry latter. (Hold " << size << "bytes)");
225 BIO_set_retry_read(table);
226 return -1;
227 }
228
3cae14a6
CT
229 if (!rbuf.isEmpty()) {
230 int bytes = (size <= (int)rbuf.length() ? size : rbuf.length());
231 memcpy(buf, rbuf.rawContent(), bytes);
232 rbuf.consume(bytes);
233 return bytes;
234 } else
235 return Ssl::Bio::read(buf, size, table);
d620ae0e
CT
236
237 return -1;
238}
239
d20cf186
AR
240Ssl::ServerBio::ServerBio(const int anFd):
241 Bio(anFd),
242 helloMsgSize(0),
243 helloBuild(false),
244 allowSplice(false),
245 allowBump(false),
246 holdWrite_(false),
247 record_(false),
248 parsedHandshake(false),
0bffe3ce 249 parseError(false),
d20cf186 250 bumpMode_(bumpNone),
cd29a421
CT
251 rbufConsumePos(0),
252 parser_(Security::HandshakeParser::fromServer)
d20cf186
AR
253{
254}
255
d620ae0e
CT
256void
257Ssl::ServerBio::stateChanged(const SSL *ssl, int where, int ret)
258{
259 Ssl::Bio::stateChanged(ssl, where, ret);
260}
261
262void
21530947 263Ssl::ServerBio::setClientFeatures(Security::TlsDetails::Pointer const &details, SBuf const &aHello)
d620ae0e 264{
21530947 265 clientTlsDetails = details;
6744c1a8 266 clientSentHello = aHello;
d620ae0e
CT
267};
268
55369ae6 269int
a465cd53 270Ssl::ServerBio::read(char *buf, int size, BIO *table)
55369ae6 271{
d20cf186 272 if (parsedHandshake) // done parsing TLS Hello
a465cd53 273 return readAndGive(buf, size, table);
d20cf186
AR
274 else
275 return readAndParse(buf, size, table);
a465cd53 276}
55369ae6 277
a465cd53
AR
278/// Read and give everything to OpenSSL.
279int
280Ssl::ServerBio::readAndGive(char *buf, const int size, BIO *table)
6821c276 281{
a465cd53
AR
282 // If we have unused buffered bytes, give those bytes to OpenSSL now,
283 // before reading more. TODO: Read if we have buffered less than size?
284 if (rbufConsumePos < rbuf.length())
285 return giveBuffered(buf, size);
55369ae6 286
a465cd53
AR
287 if (record_) {
288 const int result = readAndBuffer(table);
289 if (result <= 0)
290 return result;
291 return giveBuffered(buf, size);
55369ae6
AR
292 }
293
a465cd53 294 return Ssl::Bio::read(buf, size, table);
55369ae6
AR
295}
296
a465cd53 297/// Read and give everything to our parser.
d20cf186 298/// When/if parsing is finished (successfully or not), start giving to OpenSSL.
d620ae0e 299int
a465cd53 300Ssl::ServerBio::readAndParse(char *buf, const int size, BIO *table)
d620ae0e 301{
a465cd53
AR
302 const int result = readAndBuffer(table);
303 if (result <= 0)
304 return result;
6821c276 305
d20cf186
AR
306 try {
307 if (!parser_.parseHello(rbuf)) {
308 // need more data to finish parsing
6821c276 309 BIO_set_retry_read(table);
a465cd53
AR
310 return -1;
311 }
d20cf186
AR
312 parsedHandshake = true; // done parsing (successfully)
313 }
314 catch (const std::exception &ex) {
315 debugs(83, 2, "parsing error on FD " << fd_ << ": " << ex.what());
316 parsedHandshake = true; // done parsing (due to an error)
0bffe3ce 317 parseError = true;
55369ae6
AR
318 }
319
a465cd53 320 return giveBuffered(buf, size);
6821c276 321}
55369ae6 322
a465cd53
AR
323/// Reads more data into the read buffer. Returns either the number of bytes
324/// read or, on errors (including "try again" errors), a negative number.
d620ae0e 325int
a465cd53 326Ssl::ServerBio::readAndBuffer(BIO *table)
d620ae0e 327{
672337d1
CT
328 char *space = rbuf.rawAppendStart(SQUID_TCP_SO_RCVBUF);
329 const int result = Ssl::Bio::read(space, SQUID_TCP_SO_RCVBUF, table);
a465cd53
AR
330 if (result <= 0)
331 return result;
6821c276 332
672337d1 333 rbuf.rawAppendFinish(space, result);
a465cd53
AR
334 return result;
335}
6821c276 336
a465cd53
AR
337/// give previously buffered bytes to OpenSSL
338/// returns the number of bytes given
339int
340Ssl::ServerBio::giveBuffered(char *buf, const int size)
341{
342 if (rbuf.length() <= rbufConsumePos)
343 return -1; // buffered nothing yet
344
345 const int unsent = rbuf.length() - rbufConsumePos;
346 const int bytes = (size <= unsent ? size : unsent);
347 memcpy(buf, rbuf.rawContent() + rbufConsumePos, bytes);
348 rbufConsumePos += bytes;
349 debugs(83, 7, bytes << "<=" << size << " bytes to OpenSSL");
350 return bytes;
d620ae0e
CT
351}
352
353int
354Ssl::ServerBio::write(const char *buf, int size, BIO *table)
355{
356
357 if (holdWrite_) {
a465cd53 358 debugs(83, 7, "postpone writing " << size << " bytes to SSL FD " << fd_);
d620ae0e
CT
359 BIO_set_retry_write(table);
360 return -1;
361 }
362
5d65362c 363 if (!helloBuild && (bumpMode_ == Ssl::bumpPeek || bumpMode_ == Ssl::bumpStare)) {
4ba1501c
CT
364 // We have not seen any bytes, so the buffer must start with an
365 // OpenSSL-generated TLSPlaintext record containing, for example, a
366 // ClientHello or an alert message. We check these assumptions before we
367 // substitute that record/message with clientSentHello.
368 // TODO: Move these checks to where we actually rely on them.
369 debugs(83, 7, "to-server" << Raw("TLSPlaintext", buf, size).hex());
6744c1a8
CT
370 Must(size >= 2); // enough for version and content_type checks below
371 Must(buf[1] >= 3); // record's version.major; determines buf[0] meaning
4ba1501c 372 Must(20 <= buf[0] && buf[0] <= 23); // valid TLSPlaintext.content_type
6744c1a8
CT
373
374 //Hello message is the first message we write to server
375 assert(helloMsg.isEmpty());
376
084fa674
AR
377 if (bumpMode_ == Ssl::bumpPeek) {
378 // we should not be here if we failed to parse the client-sent ClientHello
379 Must(!clientSentHello.isEmpty());
380 allowSplice = true;
381 // Replace OpenSSL-generated ClientHello with client-sent one.
382 helloMsg.append(clientSentHello);
383 debugs(83, 7, "FD " << fd_ << ": Using client-sent ClientHello for peek mode");
384 } else { /*Ssl::bumpStare*/
385 allowBump = true;
d620ae0e 386 }
084fa674 387
6744c1a8 388 // if we did not use the client-sent ClientHello, then use the OpenSSL-generated one
8693472e 389 if (helloMsg.isEmpty())
7f4e9b73
CT
390 helloMsg.append(buf, size);
391
d620ae0e 392 helloBuild = true;
8693472e 393 helloMsgSize = helloMsg.length();
7f4e9b73
CT
394
395 if (allowSplice) {
e1f72a8b 396 // Do not write yet.....
7f4e9b73
CT
397 BIO_set_retry_write(table);
398 return -1;
399 }
d620ae0e
CT
400 }
401
8693472e 402 if (!helloMsg.isEmpty()) {
d620ae0e 403 debugs(83, 7, "buffered write for FD " << fd_);
8693472e 404 int ret = Ssl::Bio::write(helloMsg.rawContent(), helloMsg.length(), table);
d620ae0e 405 helloMsg.consume(ret);
8693472e 406 if (!helloMsg.isEmpty()) {
d620ae0e
CT
407 // We need to retry sendind data.
408 // Say to openSSL to retry sending hello message
409 BIO_set_retry_write(table);
410 return -1;
411 }
412
413 // Sending hello message complete. Do not send more data for now...
7f4e9b73
CT
414 holdWrite_ = true;
415
a95989ed
CT
416 // spoof openSSL that we write what it ask us to write
417 return size;
d620ae0e
CT
418 } else
419 return Ssl::Bio::write(buf, size, table);
420}
421
422void
423Ssl::ServerBio::flush(BIO *table)
424{
8693472e
CT
425 if (!helloMsg.isEmpty()) {
426 int ret = Ssl::Bio::write(helloMsg.rawContent(), helloMsg.length(), table);
d620ae0e
CT
427 helloMsg.consume(ret);
428 }
429}
430
89c5ca0f
CT
431bool
432Ssl::ServerBio::resumingSession()
433{
d9219c2b 434 return parser_.resumingSession;
55369ae6 435}
89c5ca0f 436
cd29a421
CT
437bool
438Ssl::ServerBio::encryptedCertificates() const
439{
440 return parser_.details->tlsSupportedVersion &&
70ac5b29 441 Security::Tls1p3orLater(parser_.details->tlsSupportedVersion);
cd29a421
CT
442}
443
b3a8ae1b
AR
444/// initializes BIO table after allocation
445static int
446squid_bio_create(BIO *bi)
447{
17e98f24 448#if !HAVE_LIBCRYPTO_BIO_GET_INIT
b3a8ae1b
AR
449 bi->init = 0; // set when we store Bio object and socket fd (BIO_C_SET_FD)
450 bi->num = 0;
b3a8ae1b 451 bi->flags = 0;
093deea9
CT
452#else
453 // No need to set more, openSSL initialize BIO memory to zero.
454#endif
455
456 BIO_set_data(bi, NULL);
b3a8ae1b
AR
457 return 1;
458}
459
460/// cleans BIO table before deallocation
461static int
462squid_bio_destroy(BIO *table)
463{
093deea9
CT
464 delete static_cast<Ssl::Bio*>(BIO_get_data(table));
465 BIO_set_data(table, NULL);
b3a8ae1b
AR
466 return 1;
467}
468
469/// wrapper for Bio::write()
470static int
471squid_bio_write(BIO *table, const char *buf, int size)
472{
093deea9 473 Ssl::Bio *bio = static_cast<Ssl::Bio*>(BIO_get_data(table));
b3a8ae1b
AR
474 assert(bio);
475 return bio->write(buf, size, table);
476}
477
478/// wrapper for Bio::read()
479static int
480squid_bio_read(BIO *table, char *buf, int size)
481{
093deea9 482 Ssl::Bio *bio = static_cast<Ssl::Bio*>(BIO_get_data(table));
b3a8ae1b
AR
483 assert(bio);
484 return bio->read(buf, size, table);
485}
486
487/// implements puts() via write()
488static int
489squid_bio_puts(BIO *table, const char *str)
490{
491 assert(str);
492 return squid_bio_write(table, str, strlen(str));
493}
494
495/// other BIO manipulations (those without dedicated callbacks in BIO table)
496static long
497squid_bio_ctrl(BIO *table, int cmd, long arg1, void *arg2)
498{
499 debugs(83, 5, table << ' ' << cmd << '(' << arg1 << ", " << arg2 << ')');
500
501 switch (cmd) {
502 case BIO_C_SET_FD: {
503 assert(arg2);
504 const int fd = *static_cast<int*>(arg2);
d620ae0e 505 Ssl::Bio *bio;
86f77270 506 if (arg1 == Security::Io::BIO_TO_SERVER)
d620ae0e
CT
507 bio = new Ssl::ServerBio(fd);
508 else
509 bio = new Ssl::ClientBio(fd);
093deea9
CT
510 assert(!BIO_get_data(table));
511 BIO_set_data(table, bio);
512 BIO_set_init(table, 1);
b3a8ae1b
AR
513 return 0;
514 }
515
516 case BIO_C_GET_FD:
093deea9
CT
517 if (BIO_get_init(table)) {
518 Ssl::Bio *bio = static_cast<Ssl::Bio*>(BIO_get_data(table));
b3a8ae1b
AR
519 assert(bio);
520 if (arg2)
521 *static_cast<int*>(arg2) = bio->fd();
522 return bio->fd();
523 }
524 return -1;
525
54f3b032 526 case BIO_CTRL_DUP:
e1f72a8b 527 // Should implemented if the SSL_dup openSSL API function
54f3b032
CT
528 // used anywhere in squid.
529 return 0;
530
b3a8ae1b 531 case BIO_CTRL_FLUSH:
093deea9
CT
532 if (BIO_get_init(table)) {
533 Ssl::Bio *bio = static_cast<Ssl::Bio*>(BIO_get_data(table));
b3a8ae1b 534 assert(bio);
d620ae0e 535 bio->flush(table);
b3a8ae1b
AR
536 return 1;
537 }
538 return 0;
539
f53969cc
SM
540 /* we may also need to implement these:
541 case BIO_CTRL_RESET:
542 case BIO_C_FILE_SEEK:
543 case BIO_C_FILE_TELL:
544 case BIO_CTRL_INFO:
545 case BIO_CTRL_GET_CLOSE:
546 case BIO_CTRL_SET_CLOSE:
547 case BIO_CTRL_PENDING:
548 case BIO_CTRL_WPENDING:
549 */
b3a8ae1b
AR
550 default:
551 return 0;
552
553 }
554
555 return 0; /* NOTREACHED */
556}
557
558/// wrapper for Bio::stateChanged()
559static void
560squid_ssl_info(const SSL *ssl, int where, int ret)
561{
562 if (BIO *table = SSL_get_rbio(ssl)) {
093deea9 563 if (Ssl::Bio *bio = static_cast<Ssl::Bio*>(BIO_get_data(table)))
b3a8ae1b
AR
564 bio->stateChanged(ssl, where, ret);
565 }
566}
567
21530947
CT
568void
569applyTlsDetailsToSSL(SSL *ssl, Security::TlsDetails::Pointer const &details, Ssl::BumpMode bumpMode)
d620ae0e 570{
21530947
CT
571 // To increase the possibility for bumping after peek mode selection or
572 // splicing after stare mode selection it is good to set the
573 // SSL protocol version.
d9219c2b
CT
574 // The SSL_set_ssl_method is wrong here because it will restrict the
575 // permitted transport version to be identical to the version used in the
576 // ClientHello message.
21530947
CT
577 // For example will prevent comunnicating with a tls1.0 server if the
578 // client sent and tlsv1.2 Hello message.
e1f72a8b 579#if defined(TLSEXT_NAMETYPE_host_name)
21530947
CT
580 if (!details->serverName.isEmpty()) {
581 SSL_set_tlsext_host_name(ssl, details->serverName.c_str());
458fd470 582 }
e68e8b9a 583#endif
2bcab852 584
21530947
CT
585 if (!details->ciphers.empty()) {
586 SBuf strCiphers;
587 for (auto cipherId: details->ciphers) {
588 unsigned char cbytes[3];
589 cbytes[0] = (cipherId >> 8) & 0xFF;
590 cbytes[1] = cipherId & 0xFF;
591 cbytes[2] = 0;
24b30fdc 592 if (const auto c = SSL_CIPHER_find(ssl, cbytes)) {
21530947
CT
593 if (!strCiphers.isEmpty())
594 strCiphers.append(":");
093deea9 595 strCiphers.append(SSL_CIPHER_get_name(c));
d620ae0e
CT
596 }
597 }
21530947
CT
598 if (!strCiphers.isEmpty())
599 SSL_set_cipher_list(ssl, strCiphers.c_str());
d620ae0e 600 }
d620ae0e 601
8693472e 602#if defined(SSL_OP_NO_COMPRESSION) /* XXX: OpenSSL 0.9.8k lacks SSL_OP_NO_COMPRESSION */
67c99fc6 603 if (!details->compressionSupported)
a95989ed
CT
604 SSL_set_options(ssl, SSL_OP_NO_COMPRESSION);
605#endif
606
cd29a421
CT
607#if defined(SSL_OP_NO_TLSv1_3)
608 // avoid "inappropriate fallback" OpenSSL error messages
609 if (details->tlsSupportedVersion && Security::Tls1p2orEarlier(details->tlsSupportedVersion))
610 SSL_set_options(ssl, SSL_OP_NO_TLSv1_3);
611#endif
612
89c5ca0f 613#if defined(TLSEXT_STATUSTYPE_ocsp)
21530947 614 if (details->tlsStatusRequest)
89c5ca0f
CT
615 SSL_set_tlsext_status_type(ssl, TLSEXT_STATUSTYPE_ocsp);
616#endif
617
618#if defined(TLSEXT_TYPE_application_layer_protocol_negotiation)
21530947 619 if (!details->tlsAppLayerProtoNeg.isEmpty()) {
89c5ca0f 620 if (bumpMode == Ssl::bumpPeek)
3152460d 621 SSL_set_alpn_protos(ssl, (const unsigned char*)details->tlsAppLayerProtoNeg.rawContent(), details->tlsAppLayerProtoNeg.length());
89c5ca0f
CT
622 else {
623 static const unsigned char supported_protos[] = {8, 'h','t','t', 'p', '/', '1', '.', '1'};
624 SSL_set_alpn_protos(ssl, supported_protos, sizeof(supported_protos));
625 }
626 }
627#endif
a95989ed
CT
628}
629
21530947 630#endif // USE_OPENSSL
f53969cc 631