]> git.ipfire.org Git - thirdparty/squid.git/blob - src/ssl/bio.cc
merge from trunk r14590
[thirdparty/squid.git] / src / ssl / bio.cc
1 /*
2 * Copyright (C) 1996-2016 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 "ssl/bio.h"
23
24 #if HAVE_OPENSSL_SSL_H
25 #include <openssl/ssl.h>
26 #endif
27
28 #if _SQUID_WINDOWS_
29 extern int socket_read_method(int, char *, int);
30 extern int socket_write_method(int, const char *, int);
31 #endif
32
33 /* BIO callbacks */
34 static int squid_bio_write(BIO *h, const char *buf, int num);
35 static int squid_bio_read(BIO *h, char *buf, int size);
36 static int squid_bio_puts(BIO *h, const char *str);
37 //static int squid_bio_gets(BIO *h, char *str, int size);
38 static long squid_bio_ctrl(BIO *h, int cmd, long arg1, void *arg2);
39 static int squid_bio_create(BIO *h);
40 static int squid_bio_destroy(BIO *data);
41 /* SSL callbacks */
42 static void squid_ssl_info(const SSL *ssl, int where, int ret);
43
44 /// Initialization structure for the BIO table with
45 /// Squid-specific methods and BIO method wrappers.
46 static BIO_METHOD SquidMethods = {
47 BIO_TYPE_SOCKET,
48 "squid",
49 squid_bio_write,
50 squid_bio_read,
51 squid_bio_puts,
52 NULL, // squid_bio_gets not supported
53 squid_bio_ctrl,
54 squid_bio_create,
55 squid_bio_destroy,
56 NULL // squid_callback_ctrl not supported
57 };
58
59
60 /* BinaryTokenizer */
61
62 BinaryTokenizer::BinaryTokenizer(): BinaryTokenizer(SBuf())
63 {
64 }
65
66 BinaryTokenizer::BinaryTokenizer(const SBuf &data):
67 context(""),
68 data_(data),
69 parsed_(0),
70 syncPoint_(0)
71 {
72 }
73
74 /// debugging helper that prints a "standard" debugs() trailer
75 #define BinaryTokenizer_tail(size, start) \
76 " occupying " << (size) << " bytes @" << (start) << " in " << this;
77
78 /// logs and throws if fewer than size octets remain; no other side effects
79 void
80 BinaryTokenizer::want(uint64_t size, const char *description) const
81 {
82 if (parsed_ + size > data_.length()) {
83 debugs(83, 5, (parsed_ + size - data_.length()) << " more bytes for " <<
84 context << description << BinaryTokenizer_tail(size, parsed_));
85 throw InsufficientInput();
86 }
87 }
88
89 /// debugging helper for parsed number fields
90 void
91 BinaryTokenizer::got(uint32_t value, uint64_t size, const char *description) const
92 {
93 debugs(83, 7, context << description << '=' << value <<
94 BinaryTokenizer_tail(size, parsed_ - size));
95 }
96
97 /// debugging helper for parsed areas/blobs
98 void
99 BinaryTokenizer::got(const SBuf &value, uint64_t size, const char *description) const
100 {
101 debugs(83, 7, context << description << '=' <<
102 Raw(nullptr, value.rawContent(), value.length()).hex() <<
103 BinaryTokenizer_tail(size, parsed_ - size));
104
105 }
106
107 /// debugging helper for skipped fields
108 void
109 BinaryTokenizer::skipped(uint64_t size, const char *description) const
110 {
111 debugs(83, 7, context << description << BinaryTokenizer_tail(size, parsed_ - size));
112
113 }
114
115 /// Returns the next ready-for-shift byte, adjusting the number of parsed bytes.
116 /// The larger 32-bit return type helps callers shift/merge octets into numbers.
117 /// This internal method does not perform out-of-bounds checks.
118 uint32_t
119 BinaryTokenizer::octet()
120 {
121 // While char may be signed, we view data characters as unsigned,
122 // which helps to arrive at the right 32-bit return value.
123 return static_cast<uint8_t>(data_[parsed_++]);
124 }
125
126 void
127 BinaryTokenizer::reset(const SBuf &data)
128 {
129 *this = BinaryTokenizer(data);
130 }
131
132 void
133 BinaryTokenizer::rollback()
134 {
135 parsed_ = syncPoint_;
136 }
137
138 void
139 BinaryTokenizer::commit()
140 {
141 if (context && *context)
142 debugs(83, 6, context << BinaryTokenizer_tail(parsed_ - syncPoint_, syncPoint_));
143 syncPoint_ = parsed_;
144 }
145
146 bool
147 BinaryTokenizer::atEnd() const
148 {
149 return parsed_ >= data_.length();
150 }
151
152 uint8_t
153 BinaryTokenizer::uint8(const char *description)
154 {
155 want(1, description);
156 const uint8_t result = octet();
157 got(result, 1, description);
158 return result;
159 }
160
161 uint16_t
162 BinaryTokenizer::uint16(const char *description)
163 {
164 want(2, description);
165 const uint16_t result = (octet() << 8) | octet();
166 got(result, 2, description);
167 return result;
168 }
169
170 uint32_t
171 BinaryTokenizer::uint24(const char *description)
172 {
173 want(3, description);
174 const uint32_t result = (octet() << 16) | (octet() << 8) | octet();
175 got(result, 3, description);
176 return result;
177 }
178
179 uint32_t
180 BinaryTokenizer::uint32(const char *description)
181 {
182 want(4, description);
183 const uint32_t result = (octet() << 24) | (octet() << 16) | (octet() << 8) | octet();
184 got(result, 4, description);
185 return result;
186 }
187
188 SBuf
189 BinaryTokenizer::area(uint64_t size, const char *description)
190 {
191 want(size, description);
192 const SBuf result = data_.substr(parsed_, size);
193 parsed_ += size;
194 got(result, size, description);
195 return result;
196 }
197
198 void
199 BinaryTokenizer::skip(uint64_t size, const char *description)
200 {
201 want(size, description);
202 parsed_ += size;
203 skipped(size, description);
204 }
205
206
207 /* Ssl::Rfc5246 */
208
209 Ssl::Rfc5246::FieldGroup::FieldGroup(BinaryTokenizer &tk, const char *description) {
210 tk.context = description;
211 }
212
213 void
214 Ssl::Rfc5246::FieldGroup::commit(BinaryTokenizer &tk) {
215 tk.commit();
216 tk.context = "";
217 }
218
219
220 Ssl::Rfc5246::ProtocolVersion::ProtocolVersion(BinaryTokenizer &tk):
221 vMajor(tk.uint8(".vMajor")),
222 vMinor(tk.uint8(".vMinor"))
223 {
224 }
225
226 Ssl::Rfc5246::TLSPlaintext::TLSPlaintext(BinaryTokenizer &tk):
227 FieldGroup(tk, "TLSPlaintext"),
228 type(tk.uint8(".type")),
229 version(tk),
230 length(tk.uint16(".length")),
231 fragment(tk.area(length, ".fragment"))
232 {
233 commit(tk);
234 }
235
236 Ssl::Rfc5246::Handshake::Handshake(BinaryTokenizer &tk):
237 FieldGroup(tk, "Handshake"),
238 msg_type(tk.uint8(".msg_type")),
239 length(tk.uint24(".length")),
240 body(tk.area(length, ".body"))
241 {
242 commit(tk);
243 }
244
245 Ssl::Rfc5246::Alert::Alert(BinaryTokenizer &tk):
246 FieldGroup(tk, "Alert"),
247 level(tk.uint8(".level")),
248 description(tk.uint8(".description"))
249 {
250 commit(tk);
251 }
252
253 Ssl::Rfc5246::P24String::P24String(BinaryTokenizer &tk, const char *description):
254 FieldGroup(tk, description),
255 length(tk.uint24(".length")),
256 body(tk.area(length, ".body"))
257 {
258 commit(tk);
259 }
260
261
262 /* Ssl:Bio */
263
264 /// debugging helper to print various parsed records and messages
265 class DebugFrame
266 {
267 public:
268 DebugFrame(const char *aName, uint64_t aType, uint64_t aSize):
269 name(aName), type(aType), size(aSize) {}
270
271 const char *name;
272 uint64_t type;
273 uint64_t size;
274 };
275
276 inline std::ostream &
277 operator <<(std::ostream &os, const DebugFrame &frame)
278 {
279 return os << frame.size << "-byte type-" << frame.type << ' ' << frame.name;
280 }
281
282 BIO *
283 Ssl::Bio::Create(const int fd, Ssl::Bio::Type type)
284 {
285 if (BIO *bio = BIO_new(&SquidMethods)) {
286 BIO_int_ctrl(bio, BIO_C_SET_FD, type, fd);
287 return bio;
288 }
289 return NULL;
290 }
291
292 void
293 Ssl::Bio::Link(SSL *ssl, BIO *bio)
294 {
295 SSL_set_bio(ssl, bio, bio); // cannot fail
296 SSL_set_info_callback(ssl, &squid_ssl_info); // does not provide diagnostic
297 }
298
299 Ssl::Bio::Bio(const int anFd): fd_(anFd)
300 {
301 debugs(83, 7, "Bio constructed, this=" << this << " FD " << fd_);
302 }
303
304 Ssl::Bio::~Bio()
305 {
306 debugs(83, 7, "Bio destructing, this=" << this << " FD " << fd_);
307 }
308
309 int Ssl::Bio::write(const char *buf, int size, BIO *table)
310 {
311 errno = 0;
312 #if _SQUID_WINDOWS_
313 const int result = socket_write_method(fd_, buf, size);
314 #else
315 const int result = default_write_method(fd_, buf, size);
316 #endif
317 const int xerrno = errno;
318 debugs(83, 5, "FD " << fd_ << " wrote " << result << " <= " << size);
319
320 BIO_clear_retry_flags(table);
321 if (result < 0) {
322 const bool ignoreError = ignoreErrno(xerrno) != 0;
323 debugs(83, 5, "error: " << xerrno << " ignored: " << ignoreError);
324 if (ignoreError)
325 BIO_set_retry_write(table);
326 }
327
328 return result;
329 }
330
331 int
332 Ssl::Bio::read(char *buf, int size, BIO *table)
333 {
334 errno = 0;
335 #if _SQUID_WINDOWS_
336 const int result = socket_read_method(fd_, buf, size);
337 #else
338 const int result = default_read_method(fd_, buf, size);
339 #endif
340 const int xerrno = errno;
341 debugs(83, 5, "FD " << fd_ << " read " << result << " <= " << size);
342
343 BIO_clear_retry_flags(table);
344 if (result < 0) {
345 const bool ignoreError = ignoreErrno(xerrno) != 0;
346 debugs(83, 5, "error: " << xerrno << " ignored: " << ignoreError);
347 if (ignoreError)
348 BIO_set_retry_read(table);
349 }
350
351 return result;
352 }
353
354 int
355 Ssl::Bio::readAndBuffer(BIO *table, const char *description)
356 {
357 char buf[SQUID_TCP_SO_RCVBUF ];
358 const int bytes = Ssl::Bio::read(buf, sizeof(buf), table);
359 debugs(83, 5, "read " << bytes << " bytes"); // move to Ssl::Bio::read()
360
361 if (bytes > 0) {
362 rbuf.append(buf, bytes);
363 debugs(83, 5, "recorded " << bytes << " bytes of " << description);
364 }
365 return bytes;
366 }
367
368 /// Called whenever the SSL connection state changes, an alert appears, or an
369 /// error occurs. See SSL_set_info_callback().
370 void
371 Ssl::Bio::stateChanged(const SSL *ssl, int where, int ret)
372 {
373 // Here we can use (where & STATE) to check the current state.
374 // Many STATE values are possible, including: SSL_CB_CONNECT_LOOP,
375 // SSL_CB_ACCEPT_LOOP, SSL_CB_HANDSHAKE_START, and SSL_CB_HANDSHAKE_DONE.
376 // For example:
377 // if (where & SSL_CB_HANDSHAKE_START)
378 // debugs(83, 9, "Trying to establish the SSL connection");
379 // else if (where & SSL_CB_HANDSHAKE_DONE)
380 // debugs(83, 9, "SSL connection established");
381
382 debugs(83, 7, "FD " << fd_ << " now: 0x" << std::hex << where << std::dec << ' ' <<
383 SSL_state_string(ssl) << " (" << SSL_state_string_long(ssl) << ")");
384 }
385
386 bool
387 Ssl::ClientBio::isClientHello(int state)
388 {
389 return (
390 state == SSL3_ST_SR_CLNT_HELLO_A ||
391 state == SSL23_ST_SR_CLNT_HELLO_A ||
392 state == SSL23_ST_SR_CLNT_HELLO_B ||
393 state == SSL3_ST_SR_CLNT_HELLO_B ||
394 state == SSL3_ST_SR_CLNT_HELLO_C
395 );
396 }
397
398 void
399 Ssl::ClientBio::stateChanged(const SSL *ssl, int where, int ret)
400 {
401 Ssl::Bio::stateChanged(ssl, where, ret);
402 }
403
404 int
405 Ssl::ClientBio::write(const char *buf, int size, BIO *table)
406 {
407 if (holdWrite_) {
408 BIO_set_retry_write(table);
409 return 0;
410 }
411
412 return Ssl::Bio::write(buf, size, table);
413 }
414
415 int
416 Ssl::ClientBio::read(char *buf, int size, BIO *table)
417 {
418 if (helloState < atHelloReceived) {
419 int bytes = readAndBuffer(table, "TLS client Hello");
420 if (bytes <= 0)
421 return bytes;
422 }
423
424 if (helloState == atHelloNone) {
425 helloSize = receivedHelloFeatures_.parseMsgHead(rbuf);
426 if (helloSize == 0) {
427 // Not enough bytes to get hello message size
428 BIO_set_retry_read(table);
429 return -1;
430 } else if (helloSize < 0) {
431 wrongProtocol = true;
432 return -1;
433 }
434
435 helloState = atHelloStarted; //Next state
436 }
437
438 if (helloState == atHelloStarted) {
439 debugs(83, 7, "SSL Header: " << Raw(nullptr, rbuf.rawContent(), rbuf.length()).hex());
440
441 if (helloSize > (int)rbuf.length()) {
442 BIO_set_retry_read(table);
443 return -1;
444 }
445 receivedHelloFeatures_.get(rbuf);
446 helloState = atHelloReceived;
447 }
448
449 if (holdRead_) {
450 debugs(83, 7, "Hold flag is set, retry latter. (Hold " << size << "bytes)");
451 BIO_set_retry_read(table);
452 return -1;
453 }
454
455 if (helloState == atHelloReceived) {
456 if (!rbuf.isEmpty()) {
457 int bytes = (size <= (int)rbuf.length() ? size : rbuf.length());
458 memcpy(buf, rbuf.rawContent(), bytes);
459 rbuf.consume(bytes);
460 return bytes;
461 } else
462 return Ssl::Bio::read(buf, size, table);
463 }
464
465 return -1;
466 }
467
468 void
469 Ssl::ServerBio::stateChanged(const SSL *ssl, int where, int ret)
470 {
471 Ssl::Bio::stateChanged(ssl, where, ret);
472 }
473
474 void
475 Ssl::ServerBio::setClientFeatures(const Ssl::Bio::sslFeatures &features)
476 {
477 clientFeatures = features;
478 };
479
480 int
481 Ssl::ServerBio::readAndBufferServerHelloMsg(BIO *table, const char *description)
482 {
483
484 int ret = readAndBuffer(table, description);
485 if (ret <= 0)
486 return ret;
487
488 if (!parser_.parseServerHello(rbuf)) {
489 if (!parser_.parseError)
490 BIO_set_retry_read(table);
491 return -1;
492 }
493
494 return 1;
495 }
496
497 int
498 Ssl::ServerBio::read(char *buf, int size, BIO *table)
499 {
500 if (!parser_.parseDone || record_) {
501 int ret = readAndBufferServerHelloMsg(table, "TLS server Hello");
502 if (!rbuf.length() && parser_.parseDone && ret <= 0)
503 return ret;
504 }
505
506 if (holdRead_) {
507 debugs(83, 7, "Hold flag is set on ServerBio, retry latter. (Hold " << size << "bytes)");
508 BIO_set_retry_read(table);
509 return -1;
510 }
511
512 if (parser_.parseDone && !parser_.parseError) {
513 int unsent = rbuf.length() - rbufConsumePos;
514 if (unsent > 0) {
515 int bytes = (size <= unsent ? size : unsent);
516 memcpy(buf, rbuf.rawContent() + rbufConsumePos, bytes);
517 rbufConsumePos += bytes;
518 debugs(83, 7, "Pass " << bytes << " bytes to openSSL as read");
519 return bytes;
520 } else
521 return Ssl::Bio::read(buf, size, table);
522 }
523
524 return -1;
525 }
526
527 // This function makes the required checks to examine if the client hello
528 // message is compatible with the features provided by OpenSSL toolkit.
529 // If the features are compatible and can be supported it tries to rewrite SSL
530 // structure members, to replace the hello message created by openSSL, with the
531 // web client SSL hello message.
532 // This is mostly possible in the cases where the web client uses openSSL
533 // library similar with this one used by squid.
534 static bool
535 adjustSSL(SSL *ssl, Ssl::Bio::sslFeatures &features)
536 {
537 #if SQUID_USE_OPENSSL_HELLO_OVERWRITE_HACK
538 if (!ssl->s3) {
539 debugs(83, 5, "No SSLv3 data found!");
540 return false;
541 }
542
543 // If the client supports compression but our context does not support
544 // we can not adjust.
545 #if !defined(OPENSSL_NO_COMP)
546 const bool requireCompression = (features.compressMethod && ssl->ctx->comp_methods == NULL);
547 #else
548 const bool requireCompression = features.compressMethod;
549 #endif
550 if (requireCompression) {
551 debugs(83, 5, "Client Hello Data supports compression, but we do not!");
552 return false;
553 }
554
555 // Check ciphers list
556 size_t token = 0;
557 size_t end = 0;
558 while (token != std::string::npos) {
559 end = features.clientRequestedCiphers.find(':',token);
560 std::string cipher;
561 cipher.assign(features.clientRequestedCiphers, token, end - token);
562 token = (end != std::string::npos ? end + 1 : std::string::npos);
563 bool found = false;
564 STACK_OF(SSL_CIPHER) *cipher_stack = SSL_get_ciphers(ssl);
565 for (int i = 0; i < sk_SSL_CIPHER_num(cipher_stack); i++) {
566 SSL_CIPHER *c = sk_SSL_CIPHER_value(cipher_stack, i);
567 const char *cname = SSL_CIPHER_get_name(c);
568 if (cipher.compare(cname)) {
569 found = true;
570 break;
571 }
572 }
573 if (!found) {
574 debugs(83, 5, "Client Hello Data supports cipher '"<< cipher <<"' but we do not support it!");
575 return false;
576 }
577 }
578
579 #if !defined(SSL_TLSEXT_HB_ENABLED)
580 if (features.doHeartBeats) {
581 debugs(83, 5, "Client Hello Data supports HeartBeats but we do not support!");
582 return false;
583 }
584 #endif
585
586 for (std::list<int>::iterator it = features.extensions.begin(); it != features.extensions.end(); ++it) {
587 static int supportedExtensions[] = {
588 #if defined(TLSEXT_TYPE_server_name)
589 TLSEXT_TYPE_server_name,
590 #endif
591 #if defined(TLSEXT_TYPE_opaque_prf_input)
592 TLSEXT_TYPE_opaque_prf_input,
593 #endif
594 #if defined(TLSEXT_TYPE_heartbeat)
595 TLSEXT_TYPE_heartbeat,
596 #endif
597 #if defined(TLSEXT_TYPE_renegotiate)
598 TLSEXT_TYPE_renegotiate,
599 #endif
600 #if defined(TLSEXT_TYPE_ec_point_formats)
601 TLSEXT_TYPE_ec_point_formats,
602 #endif
603 #if defined(TLSEXT_TYPE_elliptic_curves)
604 TLSEXT_TYPE_elliptic_curves,
605 #endif
606 #if defined(TLSEXT_TYPE_session_ticket)
607 TLSEXT_TYPE_session_ticket,
608 #endif
609 #if defined(TLSEXT_TYPE_status_request)
610 TLSEXT_TYPE_status_request,
611 #endif
612 #if defined(TLSEXT_TYPE_use_srtp)
613 TLSEXT_TYPE_use_srtp,
614 #endif
615 #if 0 //Allow 13172 Firefox supported extension for testing purposes
616 13172,
617 #endif
618 -1
619 };
620 bool found = false;
621 for (int i = 0; supportedExtensions[i] != -1; i++) {
622 if (*it == supportedExtensions[i]) {
623 found = true;
624 break;
625 }
626 }
627 if (!found) {
628 debugs(83, 5, "Extension " << *it << " does not supported!");
629 return false;
630 }
631 }
632
633 SSL3_BUFFER *wb=&(ssl->s3->wbuf);
634 if (wb->len < (size_t)features.helloMessage.length())
635 return false;
636
637 debugs(83, 5, "OpenSSL SSL struct will be adjusted to mimic client hello data!");
638
639 //Adjust ssl structure data.
640 // We need to fix the random in SSL struct:
641 memcpy(ssl->s3->client_random, features.client_random, SSL3_RANDOM_SIZE);
642 memcpy(wb->buf, features.helloMessage.rawContent(), features.helloMessage.length());
643 wb->left = features.helloMessage.length();
644
645 size_t mainHelloSize = features.helloMessage.length() - 5;
646 const char *mainHello = features.helloMessage.rawContent() + 5;
647 assert((size_t)ssl->init_buf->max > mainHelloSize);
648 memcpy(ssl->init_buf->data, mainHello, mainHelloSize);
649 debugs(83, 5, "Hello Data init and adjustd sizes :" << ssl->init_num << " = "<< mainHelloSize);
650 ssl->init_num = mainHelloSize;
651 ssl->s3->wpend_ret = mainHelloSize;
652 ssl->s3->wpend_tot = mainHelloSize;
653 return true;
654 #else
655 return false;
656 #endif
657 }
658
659 int
660 Ssl::ServerBio::write(const char *buf, int size, BIO *table)
661 {
662
663 if (holdWrite_) {
664 debugs(83, 7, "Hold write, for SSL connection on " << fd_ << "will not write bytes of size " << size);
665 BIO_set_retry_write(table);
666 return -1;
667 }
668
669 if (!helloBuild && (bumpMode_ == Ssl::bumpPeek || bumpMode_ == Ssl::bumpStare)) {
670 if (
671 buf[1] >= 3 //it is an SSL Version3 message
672 && buf[0] == 0x16 // and it is a Handshake/Hello message
673 ) {
674
675 //Hello message is the first message we write to server
676 assert(helloMsg.isEmpty());
677
678 auto ssl = fd_table[fd_].ssl.get();
679 if (clientFeatures.initialized_ && ssl) {
680 if (bumpMode_ == Ssl::bumpPeek) {
681 if (adjustSSL(ssl, clientFeatures))
682 allowBump = true;
683 allowSplice = true;
684 helloMsg.append(clientFeatures.helloMessage);
685 debugs(83, 7, "SSL HELLO message for FD " << fd_ << ": Random number is adjusted for peek mode");
686 } else { /*Ssl::bumpStare*/
687 allowBump = true;
688 if (adjustSSL(ssl, clientFeatures)) {
689 allowSplice = true;
690 helloMsg.append(clientFeatures.helloMessage);
691 debugs(83, 7, "SSL HELLO message for FD " << fd_ << ": Random number is adjusted for stare mode");
692 }
693 }
694 }
695 }
696 // If we do not build any hello message, copy the current
697 if (helloMsg.isEmpty())
698 helloMsg.append(buf, size);
699
700 helloBuild = true;
701 helloMsgSize = helloMsg.length();
702 //allowBump = true;
703
704 if (allowSplice) {
705 // Do not write yet.....
706 BIO_set_retry_write(table);
707 return -1;
708 }
709 }
710
711 if (!helloMsg.isEmpty()) {
712 debugs(83, 7, "buffered write for FD " << fd_);
713 int ret = Ssl::Bio::write(helloMsg.rawContent(), helloMsg.length(), table);
714 helloMsg.consume(ret);
715 if (!helloMsg.isEmpty()) {
716 // We need to retry sendind data.
717 // Say to openSSL to retry sending hello message
718 BIO_set_retry_write(table);
719 return -1;
720 }
721
722 // Sending hello message complete. Do not send more data for now...
723 holdWrite_ = true;
724
725 // spoof openSSL that we write what it ask us to write
726 return size;
727 } else
728 return Ssl::Bio::write(buf, size, table);
729 }
730
731 void
732 Ssl::ServerBio::flush(BIO *table)
733 {
734 if (!helloMsg.isEmpty()) {
735 int ret = Ssl::Bio::write(helloMsg.rawContent(), helloMsg.length(), table);
736 helloMsg.consume(ret);
737 }
738 }
739
740 void
741 Ssl::ServerBio::extractHelloFeatures()
742 {
743 if (!receivedHelloFeatures_.initialized_)
744 receivedHelloFeatures_.get(rbuf, false);
745 }
746
747 bool
748 Ssl::ServerBio::resumingSession()
749 {
750 return parser_.ressumingSession;
751 }
752
753
754 /// initializes BIO table after allocation
755 static int
756 squid_bio_create(BIO *bi)
757 {
758 bi->init = 0; // set when we store Bio object and socket fd (BIO_C_SET_FD)
759 bi->num = 0;
760 bi->ptr = NULL;
761 bi->flags = 0;
762 return 1;
763 }
764
765 /// cleans BIO table before deallocation
766 static int
767 squid_bio_destroy(BIO *table)
768 {
769 delete static_cast<Ssl::Bio*>(table->ptr);
770 table->ptr = NULL;
771 return 1;
772 }
773
774 /// wrapper for Bio::write()
775 static int
776 squid_bio_write(BIO *table, const char *buf, int size)
777 {
778 Ssl::Bio *bio = static_cast<Ssl::Bio*>(table->ptr);
779 assert(bio);
780 return bio->write(buf, size, table);
781 }
782
783 /// wrapper for Bio::read()
784 static int
785 squid_bio_read(BIO *table, char *buf, int size)
786 {
787 Ssl::Bio *bio = static_cast<Ssl::Bio*>(table->ptr);
788 assert(bio);
789 return bio->read(buf, size, table);
790 }
791
792 /// implements puts() via write()
793 static int
794 squid_bio_puts(BIO *table, const char *str)
795 {
796 assert(str);
797 return squid_bio_write(table, str, strlen(str));
798 }
799
800 /// other BIO manipulations (those without dedicated callbacks in BIO table)
801 static long
802 squid_bio_ctrl(BIO *table, int cmd, long arg1, void *arg2)
803 {
804 debugs(83, 5, table << ' ' << cmd << '(' << arg1 << ", " << arg2 << ')');
805
806 switch (cmd) {
807 case BIO_C_SET_FD: {
808 assert(arg2);
809 const int fd = *static_cast<int*>(arg2);
810 Ssl::Bio *bio;
811 if (arg1 == Ssl::Bio::BIO_TO_SERVER)
812 bio = new Ssl::ServerBio(fd);
813 else
814 bio = new Ssl::ClientBio(fd);
815 assert(!table->ptr);
816 table->ptr = bio;
817 table->init = 1;
818 return 0;
819 }
820
821 case BIO_C_GET_FD:
822 if (table->init) {
823 Ssl::Bio *bio = static_cast<Ssl::Bio*>(table->ptr);
824 assert(bio);
825 if (arg2)
826 *static_cast<int*>(arg2) = bio->fd();
827 return bio->fd();
828 }
829 return -1;
830
831 case BIO_CTRL_DUP:
832 // Should implemented if the SSL_dup openSSL API function
833 // used anywhere in squid.
834 return 0;
835
836 case BIO_CTRL_FLUSH:
837 if (table->init) {
838 Ssl::Bio *bio = static_cast<Ssl::Bio*>(table->ptr);
839 assert(bio);
840 bio->flush(table);
841 return 1;
842 }
843 return 0;
844
845 /* we may also need to implement these:
846 case BIO_CTRL_RESET:
847 case BIO_C_FILE_SEEK:
848 case BIO_C_FILE_TELL:
849 case BIO_CTRL_INFO:
850 case BIO_CTRL_GET_CLOSE:
851 case BIO_CTRL_SET_CLOSE:
852 case BIO_CTRL_PENDING:
853 case BIO_CTRL_WPENDING:
854 */
855 default:
856 return 0;
857
858 }
859
860 return 0; /* NOTREACHED */
861 }
862
863 /// wrapper for Bio::stateChanged()
864 static void
865 squid_ssl_info(const SSL *ssl, int where, int ret)
866 {
867 if (BIO *table = SSL_get_rbio(ssl)) {
868 if (Ssl::Bio *bio = static_cast<Ssl::Bio*>(table->ptr))
869 bio->stateChanged(ssl, where, ret);
870 }
871 }
872
873 Ssl::Bio::sslFeatures::sslFeatures():
874 sslHelloVersion(-1),
875 sslVersion(-1),
876 compressMethod(-1),
877 helloMsgSize(0),
878 unknownCiphers(false),
879 doHeartBeats(true),
880 tlsTicketsExtension(false),
881 hasTlsTicket(false),
882 tlsStatusRequest(false),
883 initialized_(false)
884 {
885 memset(client_random, 0, SSL3_RANDOM_SIZE);
886 }
887
888 int Ssl::Bio::sslFeatures::toSquidSSLVersion() const
889 {
890 if (sslVersion == SSL2_VERSION)
891 return 2;
892 else if (sslVersion == SSL3_VERSION)
893 return 3;
894 else if (sslVersion == TLS1_VERSION)
895 return 4;
896 #if OPENSSL_VERSION_NUMBER >= 0x10001000L
897 else if (sslVersion == TLS1_1_VERSION)
898 return 5;
899 else if (sslVersion == TLS1_2_VERSION)
900 return 6;
901 #endif
902 else
903 return 1;
904 }
905
906 bool
907 Ssl::Bio::sslFeatures::get(const SSL *ssl)
908 {
909 sslVersion = SSL_version(ssl);
910 debugs(83, 7, "SSL version: " << SSL_get_version(ssl) << " (" << sslVersion << ")");
911
912 #if defined(TLSEXT_NAMETYPE_host_name)
913 if (const char *server = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name))
914 serverName = server;
915 debugs(83, 7, "SNI server name: " << serverName);
916 #endif
917
918 #if !defined(OPENSSL_NO_COMP)
919 if (ssl->session->compress_meth)
920 compressMethod = ssl->session->compress_meth;
921 else if (sslVersion >= 3) //if it is 3 or newer version then compression is disabled
922 #endif
923 compressMethod = 0;
924 debugs(83, 7, "SSL compression: " << compressMethod);
925
926 STACK_OF(SSL_CIPHER) * ciphers = NULL;
927 if (ssl->server)
928 ciphers = ssl->session->ciphers;
929 else
930 ciphers = ssl->cipher_list;
931 if (ciphers) {
932 for (int i = 0; i < sk_SSL_CIPHER_num(ciphers); ++i) {
933 SSL_CIPHER *c = sk_SSL_CIPHER_value(ciphers, i);
934 if (c != NULL) {
935 if (!clientRequestedCiphers.empty())
936 clientRequestedCiphers.append(":");
937 clientRequestedCiphers.append(c->name);
938 }
939 }
940 }
941 debugs(83, 7, "Ciphers requested by client: " << clientRequestedCiphers);
942
943 if (sslVersion >=3 && ssl->s3 && ssl->s3->client_random[0]) {
944 memcpy(client_random, ssl->s3->client_random, SSL3_RANDOM_SIZE);
945 }
946
947 initialized_ = true;
948 return true;
949 }
950
951 int
952 Ssl::Bio::sslFeatures::parseMsgHead(const SBuf &buf)
953 {
954 debugs(83, 7, "SSL Header: " << Raw(nullptr, buf.rawContent(), buf.length()).hex());
955
956 if (buf.length() < 5)
957 return 0;
958
959 if (helloMsgSize > 0)
960 return helloMsgSize;
961
962 const unsigned char *head = (const unsigned char *)buf.rawContent();
963 // Check for SSLPlaintext/TLSPlaintext record
964 // RFC6101 section 5.2.1
965 // RFC5246 section 6.2.1
966 if (head[0] == 0x16) {
967 debugs(83, 7, "SSL version 3 handshake message");
968 // The SSL version exist in the 2nd and 3rd bytes
969 sslHelloVersion = (head[1] << 8) | head[2];
970 debugs(83, 7, "SSL Version :" << std::hex << std::setw(8) << std::setfill('0') << sslVersion);
971 // The hello message size exist in 4th and 5th bytes
972 helloMsgSize = (head[3] << 8) + head[4];
973 debugs(83, 7, "SSL Header Size: " << helloMsgSize);
974 helloMsgSize +=5;
975 } else if ((head[0] & 0x80) && head[2] == 0x01 && head[3] == 0x03) {
976 debugs(83, 7, "SSL version 2 handshake message with v3 support");
977 sslHelloVersion = 0x0002;
978 debugs(83, 7, "SSL Version :" << std::hex << std::setw(8) << std::setfill('0') << sslVersion);
979 // The hello message size exist in 2nd byte
980 helloMsgSize = head[1];
981 helloMsgSize +=2;
982 } else {
983 debugs(83, 7, "Not an SSL acceptable handshake message (SSLv2 message?)");
984 return (helloMsgSize = -1);
985 }
986
987 // Set object as initialized. Even if we did not full parsing yet
988 // The basic features, like the SSL version is set
989 initialized_ = true;
990 return helloMsgSize;
991 }
992
993 bool
994 Ssl::Bio::sslFeatures::get(const SBuf &buf, bool record)
995 {
996 int msgSize;
997 if ((msgSize = parseMsgHead(buf)) <= 0) {
998 debugs(83, 7, "Not a known SSL handshake message");
999 return false;
1000 }
1001
1002 if (msgSize > (int)buf.length()) {
1003 debugs(83, 2, "Partial SSL handshake message, can not parse!");
1004 return false;
1005 }
1006
1007 if (record)
1008 helloMessage = buf;
1009
1010 const unsigned char *msg = (const unsigned char *)buf.rawContent();
1011 if (msg[0] & 0x80)
1012 return parseV23Hello(msg, (size_t)msgSize);
1013 else {
1014 // Hello messages require 5 bytes header + 1 byte Msg type + 3 bytes for Msg size
1015 if (buf.length() < 9)
1016 return false;
1017
1018 // Check for the Handshake/Message type
1019 // The type 2 is a ServerHello, the type 1 is a ClientHello
1020 // RFC5246 section 7.4
1021 if (msg[5] == 0x2) { // ServerHello message
1022 return parseV3ServerHello(msg, (size_t)msgSize);
1023 } else if (msg[5] == 0x1) // ClientHello message,
1024 return parseV3Hello(msg, (size_t)msgSize);
1025 }
1026
1027 return false;
1028 }
1029
1030 bool
1031 Ssl::Bio::sslFeatures::parseV3ServerHello(const unsigned char *messageContainer, size_t messageContainerSize)
1032 {
1033 // Parse a ServerHello Handshake message
1034 // RFC5246 section 7.4, 7.4.1.3
1035 // The ServerHello starts at messageContainer + 5
1036 const unsigned char *serverHello = messageContainer + 5;
1037
1038 // The Length field (bytes 1-3) plus 4 bytes of the serverHello message header (1 handshake type + 3 hello length)
1039 const size_t helloSize = ((serverHello[1] << 16) | (serverHello[2] << 8) | serverHello[3]) + 4;
1040 debugs(83, 7, "ServerHello message size: " << helloSize);
1041 if (helloSize > messageContainerSize) {
1042 debugs(83, 2, "ServerHello parse error");
1043 return false;
1044 }
1045
1046 // helloSize should be at least 38 bytes long:
1047 // (SSL Version + Random + SessionId Length + Cipher Suite + Compression Method)
1048 if (helloSize < 38) {
1049 debugs(83, 2, "Too short ServerHello message");
1050 return false;
1051 }
1052
1053 debugs(83, 7, "Get fake features from v3 ServerHello message.");
1054 // Get the correct version of the sub-hello message
1055 sslVersion = (serverHello[4] << 8) | serverHello[5];
1056 // At the position 38 (HelloHeader (6bytes) + SSL3_RANDOM_SIZE (32bytes))
1057 const size_t sessIdLen = static_cast<size_t>(serverHello[38]);
1058 debugs(83, 7, "Session ID Length: " << sessIdLen);
1059
1060 // The size should be enough to hold at least the following
1061 // 4 (hello header)
1062 // + 2 (SSL Version) + 32 (random) + 1 (sessionId length)
1063 // + sessIdLength + 2 (cipher suite) + 1 (compression method)
1064 // = 42 + sessIdLength
1065 if (42 + sessIdLen > helloSize) {
1066 debugs(83, 2, "ciphers length parse error");
1067 return false;
1068 }
1069
1070 // The sessionID stored at 39 position, after sessionID length field
1071 sessionId.assign(reinterpret_cast<const char *>(serverHello + 39), sessIdLen);
1072
1073 // Check if there are extensions in hello message
1074 // RFC5246 section 7.4.1.4
1075 if (helloSize > 42 + sessIdLen + 2) {
1076 // 42 + sessIdLen
1077 const unsigned char *pToExtensions = serverHello + 42 + sessIdLen;
1078 const size_t extensionsLen = (pToExtensions[0] << 8) | pToExtensions[1];
1079 // Check if the hello size can hold extensions
1080 if (42 + 2 + sessIdLen + extensionsLen > helloSize ) {
1081 debugs(83, 2, "Extensions length parse error");
1082 return false;
1083 }
1084
1085 pToExtensions += 2;
1086 const unsigned char *ext = pToExtensions;
1087 while (ext + 4 <= pToExtensions + extensionsLen) {
1088 const size_t extType = (ext[0] << 8) | ext[1];
1089 ext += 2;
1090 const size_t extLen = (ext[0] << 8) | ext[1];
1091 ext += 2;
1092 debugs(83, 7, "TLS Extension: " << std::hex << extType << " of size:" << extLen);
1093 // SessionTicket TLS Extension, RFC5077 section 3.2
1094 if (extType == 0x23) {
1095 tlsTicketsExtension = true;
1096 }
1097 ext += extLen;
1098 }
1099 }
1100 return true;
1101 }
1102
1103 bool
1104 Ssl::Bio::sslFeatures::parseV3Hello(const unsigned char *messageContainer, size_t messageContainerSize)
1105 {
1106 // Parse a ClientHello Handshake message
1107 // RFC5246 section 7.4, 7.4.1.2
1108 // The ClientHello starts at messageContainer + 5
1109 const unsigned char * clientHello = messageContainer + 5;
1110
1111 debugs(83, 7, "Get fake features from v3 ClientHello message.");
1112 // The Length field (bytes 1-3) plus 4 bytes of the clientHello message header (1 handshake type + 3 hello length)
1113 const size_t helloSize = ((clientHello[1] << 16) | (clientHello[2] << 8) | clientHello[3]) + 4;
1114 debugs(83, 7, "ClientHello message size: " << helloSize);
1115 if (helloSize > messageContainerSize) {
1116 debugs(83, 2, "ClientHello parse error");
1117 return false;
1118 }
1119
1120 // helloSize should be at least 38 bytes long:
1121 // (SSL Version(2) + Random(32) + SessionId Length(1) + Cipher Suite Length(2) + Compression Method Length(1))
1122 if (helloSize < 38) {
1123 debugs(83, 2, "Too short ClientHello message");
1124 return false;
1125 }
1126
1127 //For SSLv3 or TLSv1.* protocols we can get some more informations
1128 if (messageContainer[1] != 0x3 || clientHello[0] != 0x1 /*HELLO A message*/) {
1129 debugs(83, 2, "Not an SSLv3/TLSv1.x client hello message, stop parsing here");
1130 return true;
1131 }
1132
1133 // Get the correct version of the sub-hello message
1134 sslVersion = (clientHello[4] << 8) | clientHello[5];
1135 //Get Client Random number. It starts on the position 6 of clientHello message
1136 memcpy(client_random, clientHello + 6, SSL3_RANDOM_SIZE);
1137 debugs(83, 7, "Client random: " << Raw(nullptr, (char *)client_random, SSL3_RANDOM_SIZE).hex());
1138
1139 // At the position 38 (6+SSL3_RANDOM_SIZE)
1140 const size_t sessIDLen = static_cast<size_t>(clientHello[38]);
1141 debugs(83, 7, "Session ID Length: " << sessIDLen);
1142
1143 // The helloSize should be enough to hold at least the following
1144 // 1 handshake type + 3 hello Length
1145 // + 2 (SSL Version) + 32 (random) + 1 (sessionId length)
1146 // + sessIdLength + 2 (cipher suite length) + 1 (compression method length)
1147 // = 42 + sessIdLength
1148 if (42 + sessIDLen > helloSize) {
1149 debugs(83, 2, "Session ID length parse error");
1150 return false;
1151 }
1152
1153 // The sessionID stored art 39 position, after sessionID length field
1154 sessionId.assign(reinterpret_cast<const char *>(clientHello + 39), sessIDLen);
1155
1156 //Ciphers list. It is stored after the Session ID.
1157 // It is a variable-length vector(RFC5246 section 4.3)
1158 const unsigned char *ciphers = clientHello + 39 + sessIDLen;
1159 const size_t ciphersLen = (ciphers[0] << 8) | ciphers[1];
1160 if (42 + sessIDLen + ciphersLen > helloSize) {
1161 debugs(83, 2, "ciphers length parse error");
1162 return false;
1163 }
1164
1165 ciphers += 2;
1166 if (ciphersLen) {
1167 #if (OPENSSL_VERSION_NUMBER >= 0x10100000L)
1168 const SSL_METHOD *method = TLS_method();
1169 #else
1170 const SSL_METHOD *method = SSLv23_method();
1171 #endif
1172 for (size_t i = 0; i < ciphersLen; i += 2) {
1173 // each cipher in v3/tls HELLO message is of size 2
1174 const SSL_CIPHER *c = method->get_cipher_by_char((ciphers + i));
1175 if (c != NULL) {
1176 if (!clientRequestedCiphers.empty())
1177 clientRequestedCiphers.append(":");
1178 clientRequestedCiphers.append(c->name);
1179 } else
1180 unknownCiphers = true;
1181 }
1182 }
1183 debugs(83, 7, "Ciphers requested by client: " << clientRequestedCiphers);
1184
1185 // Compression field: 1 bytes the number of compression methods and
1186 // 1 byte for each compression method
1187 const unsigned char *compression = ciphers + ciphersLen;
1188 if (compression[0] > 1)
1189 compressMethod = 1;
1190 else
1191 compressMethod = 0;
1192 debugs(83, 7, "SSL compression methods number: " << static_cast<int>(compression[0]));
1193
1194 // Parse Extensions, RFC5246 section 7.4.1.4
1195 const unsigned char *pToExtensions = compression + 1 + static_cast<int>(compression[0]);
1196 if ((size_t)((pToExtensions - clientHello) + 2) < helloSize) {
1197 const size_t extensionsLen = (pToExtensions[0] << 8) | pToExtensions[1];
1198 if ((pToExtensions - clientHello) + 2 + extensionsLen > helloSize) {
1199 debugs(83, 2, "Extensions length parse error");
1200 return false;
1201 }
1202
1203 pToExtensions += 2;
1204 const unsigned char *ext = pToExtensions;
1205 while (ext + 4 <= pToExtensions + extensionsLen) {
1206 const size_t extType = (ext[0] << 8) | ext[1];
1207 ext += 2;
1208 const size_t extLen = (ext[0] << 8) | ext[1];
1209 ext += 2;
1210 debugs(83, 7, "TLS Extension: " << std::hex << extType << " of size:" << extLen);
1211
1212 if (ext + extLen > pToExtensions + extensionsLen) {
1213 debugs(83, 2, "Extension " << std::hex << extType << " length parser error");
1214 return false;
1215 }
1216
1217 //The SNI extension has the type 0 (extType == 0)
1218 // RFC6066 sections 3, 10.2
1219 // The two first bytes indicates the length of the SNI data (should be extLen-2)
1220 // The next byte is the hostname type, it should be '0' for normal hostname (ext[2] == 0)
1221 // The 3rd and 4th bytes are the length of the hostname
1222 if (extType == 0 && ext[2] == 0) {
1223 const size_t hostLen = (ext[3] << 8) | ext[4];
1224 if (hostLen < extLen)
1225 serverName.assign(reinterpret_cast<const char *>(ext+5), hostLen);
1226 debugs(83, 7, "Found server name: " << serverName);
1227 } else if (extType == 15 && ext[0] != 0) {
1228 // The heartBeats are the type 15, RFC6520
1229 doHeartBeats = true;
1230 } else if (extType == 0x23) {
1231 //SessionTicket TLS Extension RFC5077
1232 tlsTicketsExtension = true;
1233 if (extLen != 0)
1234 hasTlsTicket = true;
1235 } else if (extType == 0x05) {
1236 // RFC6066 sections 8, 10.2
1237 tlsStatusRequest = true;
1238 } else if (extType == 0x3374) {
1239 // detected TLS next protocol negotiate extension
1240 } else if (extType == 0x10) {
1241 // Application-Layer Protocol Negotiation Extension, RFC7301
1242 const size_t listLen = (ext[0] << 8) | ext[1];
1243 if (listLen < extLen)
1244 tlsAppLayerProtoNeg.assign(reinterpret_cast<const char *>(ext+5), listLen);
1245 } else
1246 extensions.push_back(extType);
1247
1248 ext += extLen;
1249 }
1250 }
1251 return true;
1252 }
1253
1254 bool
1255 Ssl::Bio::sslFeatures::parseV23Hello(const unsigned char *hello, size_t size)
1256 {
1257 debugs(83, 7, "Get fake features from v23 ClientHello message.");
1258 if (size < 7)
1259 return false;
1260
1261 // Get the SSL/TLS version supported by client
1262 sslVersion = (hello[3] << 8) | hello[4];
1263
1264 //Ciphers list. It is stored after the Session ID.
1265 const unsigned int ciphersLen = (hello[5] << 8) | hello[6];
1266 const unsigned char *ciphers = hello + 11;
1267
1268 if (size < ciphersLen + 11)
1269 return false;
1270
1271 if (ciphersLen) {
1272 #if (OPENSSL_VERSION_NUMBER >= 0x10100000L)
1273 const SSL_METHOD *method = TLS_method();
1274 #else
1275 const SSL_METHOD *method = SSLv23_method();
1276 #endif
1277 for (unsigned int i = 0; i < ciphersLen; i += 3) {
1278 // The v2 hello messages cipher has 3 bytes.
1279 // The v2 cipher has the first byte not null
1280 // Because we are going to sent only v3 message we
1281 // are ignoring these ciphers
1282 if (ciphers[i] != 0)
1283 continue;
1284 const SSL_CIPHER *c = method->get_cipher_by_char((ciphers + i + 1));
1285 if (c != NULL) {
1286 if (!clientRequestedCiphers.empty())
1287 clientRequestedCiphers.append(":");
1288 clientRequestedCiphers.append(c->name);
1289 }
1290 }
1291 }
1292 debugs(83, 7, "Ciphers requested by client: " << clientRequestedCiphers);
1293
1294 const unsigned int sessionIdLength = (hello[7] << 8) | hello[8];
1295 debugs(83, 7, "SessionID length: " << sessionIdLength);
1296 // SessionID starts at: hello+11+ciphersLen
1297 if (sessionIdLength)
1298 sessionId.assign((const char *)(hello + 11 + ciphersLen), sessionIdLength);
1299
1300 const unsigned int challengeLength = (hello[5] << 9) | hello[10];
1301 debugs(83, 7, "Challenge Length: " << challengeLength);
1302 //challenge starts at: hello+11+ciphersLen+sessionIdLength
1303
1304 compressMethod = 0;
1305 return true;
1306 }
1307
1308 void
1309 Ssl::Bio::sslFeatures::applyToSSL(SSL *ssl, Ssl::BumpMode bumpMode) const
1310 {
1311 // To increase the possibility for bumping after peek mode selection or
1312 // splicing after stare mode selection it is good to set the
1313 // SSL protocol version.
1314 // The SSL_set_ssl_method is not the correct method because it will strict
1315 // SSL version which can be used to the SSL version used for client hello message.
1316 // For example will prevent comunnicating with a tls1.0 server if the
1317 // client sent and tlsv1.2 Hello message.
1318 #if defined(TLSEXT_NAMETYPE_host_name)
1319 if (!serverName.isEmpty()) {
1320 SSL_set_tlsext_host_name(ssl, serverName.c_str());
1321 }
1322 #endif
1323 if (!clientRequestedCiphers.empty())
1324 SSL_set_cipher_list(ssl, clientRequestedCiphers.c_str());
1325 #if defined(SSL_OP_NO_COMPRESSION) /* XXX: OpenSSL 0.9.8k lacks SSL_OP_NO_COMPRESSION */
1326 if (compressMethod == 0)
1327 SSL_set_options(ssl, SSL_OP_NO_COMPRESSION);
1328 #endif
1329
1330 #if defined(TLSEXT_STATUSTYPE_ocsp)
1331 if (tlsStatusRequest)
1332 SSL_set_tlsext_status_type(ssl, TLSEXT_STATUSTYPE_ocsp);
1333 #endif
1334
1335 #if defined(TLSEXT_TYPE_application_layer_protocol_negotiation)
1336 if (!tlsAppLayerProtoNeg.isEmpty()) {
1337 if (bumpMode == Ssl::bumpPeek)
1338 SSL_set_alpn_protos(ssl, (const unsigned char*)tlsAppLayerProtoNeg.rawContent(), tlsAppLayerProtoNeg.length());
1339 else {
1340 static const unsigned char supported_protos[] = {8, 'h','t','t', 'p', '/', '1', '.', '1'};
1341 SSL_set_alpn_protos(ssl, supported_protos, sizeof(supported_protos));
1342 }
1343 }
1344 #endif
1345 }
1346
1347 std::ostream &
1348 Ssl::Bio::sslFeatures::print(std::ostream &os) const
1349 {
1350 static std::string buf;
1351 // TODO: Also print missing features like the HeartBeats and AppLayerProtoNeg
1352 return os << "v" << sslVersion <<
1353 " SNI:" << (serverName.isEmpty() ? SBuf("-") : serverName) <<
1354 " comp:" << compressMethod <<
1355 " Ciphers:" << clientRequestedCiphers <<
1356 " Random:" << Raw(nullptr, (char *)client_random, SSL3_RANDOM_SIZE).hex();
1357 }
1358
1359 /// parses a single TLS Record Layer frame
1360 void
1361 Ssl::HandshakeParser::parseRecord()
1362 {
1363 const Rfc5246::TLSPlaintext record(tkRecords);
1364
1365 Must(record.length <= (1 << 14)); // RFC 5246: length MUST NOT exceed 2^14
1366
1367 // RFC 5246: MUST NOT send zero-length [non-application] fragments
1368 Must(record.length || record.type == Rfc5246::ContentType::ctApplicationData);
1369
1370 if (currentContentType != record.type) {
1371 Must(tkMessages.atEnd()); // no currentContentType leftovers
1372 fragments = record.fragment;
1373 tkMessages.reset(fragments);
1374 currentContentType = record.type;
1375 } else {
1376 fragments.append(record.fragment);
1377 tkMessages.reinput(fragments);
1378 tkMessages.rollback();
1379 }
1380 parseMessages();
1381 }
1382
1383 /// parses one or more "higher-level protocol" frames of currentContentType
1384 void
1385 Ssl::HandshakeParser::parseMessages()
1386 {
1387 debugs(83, 7, DebugFrame("fragments", currentContentType, fragments.length()));
1388 while (!tkMessages.atEnd()) {
1389 switch (currentContentType) {
1390 case Rfc5246::ContentType::ctChangeCipherSpec:
1391 parseChangeCipherCpecMessage();
1392 continue;
1393 case Rfc5246::ContentType::ctAlert:
1394 parseAlertMessage();
1395 continue;
1396 case Rfc5246::ContentType::ctHandshake:
1397 parseHandshakeMessage();
1398 continue;
1399 case Rfc5246::ContentType::ctApplicationData:
1400 parseApplicationDataMessage();
1401 continue;
1402 }
1403 skipMessage("unknown ContentType msg");
1404 }
1405 }
1406
1407 void
1408 Ssl::HandshakeParser::parseChangeCipherCpecMessage()
1409 {
1410 Must(currentContentType == Rfc5246::ContentType::ctChangeCipherSpec);
1411 // we are currently ignoring Change Cipher Spec Protocol messages
1412 // Everything after this message may be is encrypted
1413 // The continuing parsing is pointless, abort here and set parseDone
1414 skipMessage("ChangeCipherCpec msg");
1415 ressumingSession = true;
1416 parseDone = true;
1417 }
1418
1419 void
1420 Ssl::HandshakeParser::parseAlertMessage()
1421 {
1422 Must(currentContentType == Rfc5246::ContentType::ctAlert);
1423 const Rfc5246::Alert alert(tkMessages);
1424 debugs(83, 3, "level " << alert.level << " description " << alert.description);
1425 // we are currently ignoring Alert Protocol messages
1426 }
1427
1428 void
1429 Ssl::HandshakeParser::parseHandshakeMessage()
1430 {
1431 Must(currentContentType == Rfc5246::ContentType::ctHandshake);
1432
1433 const Rfc5246::Handshake message(tkMessages);
1434
1435 switch (message.msg_type) {
1436 case Rfc5246::HandshakeType::hskServerHello:
1437 Must(state < atHelloReceived);
1438 // TODO: Parse ServerHello in message.body; extract version/session
1439 // If the server is resuming a session, stop parsing w/o certificates
1440 // because all subsequent [Finished] messages will be encrypted, right?
1441 state = atHelloReceived;
1442 return;
1443 case Rfc5246::HandshakeType::hskCertificate:
1444 Must(state < atCertificatesReceived);
1445 parseServerCertificates(message.body);
1446 state = atCertificatesReceived;
1447 return;
1448 case Rfc5246::HandshakeType::hskServerHelloDone:
1449 Must(state < atHelloDoneReceived);
1450 // zero-length
1451 state = atHelloDoneReceived;
1452 parseDone = true;
1453 return;
1454 }
1455 debugs(83, 5, "ignoring " <<
1456 DebugFrame("handshake msg", message.msg_type, message.length));
1457 }
1458
1459 void
1460 Ssl::HandshakeParser::parseApplicationDataMessage()
1461 {
1462 Must(currentContentType == Rfc5246::ContentType::ctApplicationData);
1463 skipMessage("app data");
1464 }
1465
1466 void
1467 Ssl::HandshakeParser::skipMessage(const char *description)
1468 {
1469 // tkMessages/fragments can only contain messages of the same ContentType.
1470 // To skip a message, we can and should skip everything we have [left]. If
1471 // we have partial messages, debugging will mislead about their boundaries.
1472 tkMessages.skip(tkMessages.leftovers().length(), description);
1473 tkMessages.commit();
1474 }
1475
1476 /// parseServerHelloTry() wrapper that maintains parseDone/parseError state
1477 bool
1478 Ssl::HandshakeParser::parseServerHello(const SBuf &data)
1479 {
1480 try {
1481 tkRecords.reinput(data); // data contains _everything_ read so far
1482 tkRecords.rollback();
1483 while (!tkRecords.atEnd() && !parseDone)
1484 parseRecord();
1485 debugs(83, 7, "success; done: " << parseDone);
1486 return parseDone;
1487 }
1488 catch (const BinaryTokenizer::InsufficientInput &) {
1489 debugs(83, 5, "need more data");
1490 Must(!parseError);
1491 }
1492 catch (const std::exception &ex) {
1493 debugs(83, 2, "parsing error: " << ex.what());
1494 parseError = true;
1495 }
1496 return false;
1497 }
1498
1499 X509 *
1500 Ssl::HandshakeParser::ParseCertificate(const SBuf &raw)
1501 {
1502 typedef const unsigned char *x509Data;
1503 const x509Data x509Start = reinterpret_cast<x509Data>(raw.rawContent());
1504 x509Data x509Pos = x509Start;
1505 X509 *x509 = d2i_X509(nullptr, &x509Pos, raw.length());
1506 Must(x509); // successfully parsed
1507 Must(x509Pos == x509Start + raw.length()); // no leftovers
1508 return x509;
1509 }
1510
1511 void
1512 Ssl::HandshakeParser::parseServerCertificates(const SBuf &raw)
1513 {
1514 BinaryTokenizer tkList(raw);
1515 const Rfc5246::P24String list(tkList, "CertificateList");
1516 Must(tkList.atEnd()); // no leftovers after all certificates
1517
1518 BinaryTokenizer tkItems(list.body);
1519 while (!tkItems.atEnd()) {
1520 const Rfc5246::P24String item(tkItems, "Certificate");
1521 X509 *cert = ParseCertificate(item.body);
1522 if (!serverCertificates.get())
1523 serverCertificates.reset(sk_X509_new_null());
1524 sk_X509_push(serverCertificates.get(), cert);
1525 debugs(83, 7, "parsed " << sk_X509_num(serverCertificates.get()) << " certificates so far");
1526 }
1527
1528 }
1529
1530 #endif /* USE_SSL */
1531