]> git.ipfire.org Git - thirdparty/squid.git/blob - src/ssl/bio.cc
merge new SSL messages parser from lp:fetch-cert branch
[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 "parser/BinaryTokenizer.h"
23 #include "ssl/bio.h"
24
25 #if HAVE_OPENSSL_SSL_H
26 #include <openssl/ssl.h>
27 #endif
28
29 #if _SQUID_WINDOWS_
30 extern int socket_read_method(int, char *, int);
31 extern int socket_write_method(int, const char *, int);
32 #endif
33
34 /* BIO callbacks */
35 static int squid_bio_write(BIO *h, const char *buf, int num);
36 static int squid_bio_read(BIO *h, char *buf, int size);
37 static int squid_bio_puts(BIO *h, const char *str);
38 //static int squid_bio_gets(BIO *h, char *str, int size);
39 static long squid_bio_ctrl(BIO *h, int cmd, long arg1, void *arg2);
40 static int squid_bio_create(BIO *h);
41 static int squid_bio_destroy(BIO *data);
42 /* SSL callbacks */
43 static void squid_ssl_info(const SSL *ssl, int where, int ret);
44
45 /// Initialization structure for the BIO table with
46 /// Squid-specific methods and BIO method wrappers.
47 static 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 };
59
60 /* Ssl:Bio */
61
62 BIO *
63 Ssl::Bio::Create(const int fd, Ssl::Bio::Type type)
64 {
65 if (BIO *bio = BIO_new(&SquidMethods)) {
66 BIO_int_ctrl(bio, BIO_C_SET_FD, type, fd);
67 return bio;
68 }
69 return NULL;
70 }
71
72 void
73 Ssl::Bio::Link(SSL *ssl, BIO *bio)
74 {
75 SSL_set_bio(ssl, bio, bio); // cannot fail
76 SSL_set_info_callback(ssl, &squid_ssl_info); // does not provide diagnostic
77 }
78
79 Ssl::Bio::Bio(const int anFd): fd_(anFd)
80 {
81 debugs(83, 7, "Bio constructed, this=" << this << " FD " << fd_);
82 }
83
84 Ssl::Bio::~Bio()
85 {
86 debugs(83, 7, "Bio destructing, this=" << this << " FD " << fd_);
87 }
88
89 int Ssl::Bio::write(const char *buf, int size, BIO *table)
90 {
91 errno = 0;
92 #if _SQUID_WINDOWS_
93 const int result = socket_write_method(fd_, buf, size);
94 #else
95 const int result = default_write_method(fd_, buf, size);
96 #endif
97 const int xerrno = errno;
98 debugs(83, 5, "FD " << fd_ << " wrote " << result << " <= " << size);
99
100 BIO_clear_retry_flags(table);
101 if (result < 0) {
102 const bool ignoreError = ignoreErrno(xerrno) != 0;
103 debugs(83, 5, "error: " << xerrno << " ignored: " << ignoreError);
104 if (ignoreError)
105 BIO_set_retry_write(table);
106 }
107
108 return result;
109 }
110
111 int
112 Ssl::Bio::read(char *buf, int size, BIO *table)
113 {
114 errno = 0;
115 #if _SQUID_WINDOWS_
116 const int result = socket_read_method(fd_, buf, size);
117 #else
118 const int result = default_read_method(fd_, buf, size);
119 #endif
120 const int xerrno = errno;
121 debugs(83, 5, "FD " << fd_ << " read " << result << " <= " << size);
122
123 BIO_clear_retry_flags(table);
124 if (result < 0) {
125 const bool ignoreError = ignoreErrno(xerrno) != 0;
126 debugs(83, 5, "error: " << xerrno << " ignored: " << ignoreError);
127 if (ignoreError)
128 BIO_set_retry_read(table);
129 }
130
131 return result;
132 }
133
134 int
135 Ssl::Bio::readAndBuffer(BIO *table, const char *description)
136 {
137 char buf[SQUID_TCP_SO_RCVBUF ];
138 const int bytes = Ssl::Bio::read(buf, sizeof(buf), table);
139 debugs(83, 5, "read " << bytes << " bytes"); // move to Ssl::Bio::read()
140
141 if (bytes > 0) {
142 rbuf.append(buf, bytes);
143 debugs(83, 5, "recorded " << bytes << " bytes of " << description);
144 }
145 return bytes;
146 }
147
148 /// Called whenever the SSL connection state changes, an alert appears, or an
149 /// error occurs. See SSL_set_info_callback().
150 void
151 Ssl::Bio::stateChanged(const SSL *ssl, int where, int ret)
152 {
153 // Here we can use (where & STATE) to check the current state.
154 // Many STATE values are possible, including: SSL_CB_CONNECT_LOOP,
155 // SSL_CB_ACCEPT_LOOP, SSL_CB_HANDSHAKE_START, and SSL_CB_HANDSHAKE_DONE.
156 // For example:
157 // if (where & SSL_CB_HANDSHAKE_START)
158 // debugs(83, 9, "Trying to establish the SSL connection");
159 // else if (where & SSL_CB_HANDSHAKE_DONE)
160 // debugs(83, 9, "SSL connection established");
161
162 debugs(83, 7, "FD " << fd_ << " now: 0x" << std::hex << where << std::dec << ' ' <<
163 SSL_state_string(ssl) << " (" << SSL_state_string_long(ssl) << ")");
164 }
165
166 bool
167 Ssl::ClientBio::isClientHello(int state)
168 {
169 return (
170 state == SSL3_ST_SR_CLNT_HELLO_A ||
171 state == SSL23_ST_SR_CLNT_HELLO_A ||
172 state == SSL23_ST_SR_CLNT_HELLO_B ||
173 state == SSL3_ST_SR_CLNT_HELLO_B ||
174 state == SSL3_ST_SR_CLNT_HELLO_C
175 );
176 }
177
178 void
179 Ssl::ClientBio::stateChanged(const SSL *ssl, int where, int ret)
180 {
181 Ssl::Bio::stateChanged(ssl, where, ret);
182 }
183
184 int
185 Ssl::ClientBio::write(const char *buf, int size, BIO *table)
186 {
187 if (holdWrite_) {
188 BIO_set_retry_write(table);
189 return 0;
190 }
191
192 return Ssl::Bio::write(buf, size, table);
193 }
194
195 int
196 Ssl::ClientBio::read(char *buf, int size, BIO *table)
197 {
198 if (helloState < atHelloReceived) {
199 int bytes = readAndBuffer(table, "TLS client Hello");
200 if (bytes <= 0)
201 return bytes;
202 }
203
204 if (helloState == atHelloNone) {
205 helloSize = receivedHelloFeatures_.parseMsgHead(rbuf);
206 if (helloSize == 0) {
207 // Not enough bytes to get hello message size
208 BIO_set_retry_read(table);
209 return -1;
210 } else if (helloSize < 0) {
211 wrongProtocol = true;
212 return -1;
213 }
214
215 helloState = atHelloStarted; //Next state
216 }
217
218 if (helloState == atHelloStarted) {
219 debugs(83, 7, "SSL Header: " << Raw(nullptr, rbuf.rawContent(), rbuf.length()).hex());
220
221 if (helloSize > (int)rbuf.length()) {
222 BIO_set_retry_read(table);
223 return -1;
224 }
225 receivedHelloFeatures_.get(rbuf);
226 helloState = atHelloReceived;
227 }
228
229 if (holdRead_) {
230 debugs(83, 7, "Hold flag is set, retry latter. (Hold " << size << "bytes)");
231 BIO_set_retry_read(table);
232 return -1;
233 }
234
235 if (helloState == atHelloReceived) {
236 if (!rbuf.isEmpty()) {
237 int bytes = (size <= (int)rbuf.length() ? size : rbuf.length());
238 memcpy(buf, rbuf.rawContent(), bytes);
239 rbuf.consume(bytes);
240 return bytes;
241 } else
242 return Ssl::Bio::read(buf, size, table);
243 }
244
245 return -1;
246 }
247
248 void
249 Ssl::ServerBio::stateChanged(const SSL *ssl, int where, int ret)
250 {
251 Ssl::Bio::stateChanged(ssl, where, ret);
252 }
253
254 void
255 Ssl::ServerBio::setClientFeatures(const Ssl::Bio::sslFeatures &features)
256 {
257 clientFeatures = features;
258 };
259
260 int
261 Ssl::ServerBio::readAndBufferServerHelloMsg(BIO *table, const char *description)
262 {
263
264 int ret = readAndBuffer(table, description);
265 if (ret <= 0)
266 return ret;
267
268 if (!parser_.parseServerHello(rbuf)) {
269 if (!parser_.parseError)
270 BIO_set_retry_read(table);
271 return -1;
272 }
273
274 return 1;
275 }
276
277 int
278 Ssl::ServerBio::read(char *buf, int size, BIO *table)
279 {
280 if (!parser_.parseDone || record_) {
281 int ret = readAndBufferServerHelloMsg(table, "TLS server Hello");
282 if (!rbuf.length() && parser_.parseDone && ret <= 0)
283 return ret;
284 }
285
286 if (holdRead_) {
287 debugs(83, 7, "Hold flag is set on ServerBio, retry latter. (Hold " << size << "bytes)");
288 BIO_set_retry_read(table);
289 return -1;
290 }
291
292 if (parser_.parseDone && !parser_.parseError) {
293 int unsent = rbuf.length() - rbufConsumePos;
294 if (unsent > 0) {
295 int bytes = (size <= unsent ? size : unsent);
296 memcpy(buf, rbuf.rawContent() + rbufConsumePos, bytes);
297 rbufConsumePos += bytes;
298 debugs(83, 7, "Pass " << bytes << " bytes to openSSL as read");
299 return bytes;
300 } else
301 return Ssl::Bio::read(buf, size, table);
302 }
303
304 return -1;
305 }
306
307 // This function makes the required checks to examine if the client hello
308 // message is compatible with the features provided by OpenSSL toolkit.
309 // If the features are compatible and can be supported it tries to rewrite SSL
310 // structure members, to replace the hello message created by openSSL, with the
311 // web client SSL hello message.
312 // This is mostly possible in the cases where the web client uses openSSL
313 // library similar with this one used by squid.
314 static bool
315 adjustSSL(SSL *ssl, Ssl::Bio::sslFeatures &features)
316 {
317 #if SQUID_USE_OPENSSL_HELLO_OVERWRITE_HACK
318 if (!ssl->s3) {
319 debugs(83, 5, "No SSLv3 data found!");
320 return false;
321 }
322
323 // If the client supports compression but our context does not support
324 // we can not adjust.
325 #if !defined(OPENSSL_NO_COMP)
326 const bool requireCompression = (features.compressMethod && ssl->ctx->comp_methods == NULL);
327 #else
328 const bool requireCompression = features.compressMethod;
329 #endif
330 if (requireCompression) {
331 debugs(83, 5, "Client Hello Data supports compression, but we do not!");
332 return false;
333 }
334
335 // Check ciphers list
336 size_t token = 0;
337 size_t end = 0;
338 while (token != std::string::npos) {
339 end = features.clientRequestedCiphers.find(':',token);
340 std::string cipher;
341 cipher.assign(features.clientRequestedCiphers, token, end - token);
342 token = (end != std::string::npos ? end + 1 : std::string::npos);
343 bool found = false;
344 STACK_OF(SSL_CIPHER) *cipher_stack = SSL_get_ciphers(ssl);
345 for (int i = 0; i < sk_SSL_CIPHER_num(cipher_stack); i++) {
346 SSL_CIPHER *c = sk_SSL_CIPHER_value(cipher_stack, i);
347 const char *cname = SSL_CIPHER_get_name(c);
348 if (cipher.compare(cname)) {
349 found = true;
350 break;
351 }
352 }
353 if (!found) {
354 debugs(83, 5, "Client Hello Data supports cipher '"<< cipher <<"' but we do not support it!");
355 return false;
356 }
357 }
358
359 #if !defined(SSL_TLSEXT_HB_ENABLED)
360 if (features.doHeartBeats) {
361 debugs(83, 5, "Client Hello Data supports HeartBeats but we do not support!");
362 return false;
363 }
364 #endif
365
366 for (std::list<int>::iterator it = features.extensions.begin(); it != features.extensions.end(); ++it) {
367 static int supportedExtensions[] = {
368 #if defined(TLSEXT_TYPE_server_name)
369 TLSEXT_TYPE_server_name,
370 #endif
371 #if defined(TLSEXT_TYPE_opaque_prf_input)
372 TLSEXT_TYPE_opaque_prf_input,
373 #endif
374 #if defined(TLSEXT_TYPE_heartbeat)
375 TLSEXT_TYPE_heartbeat,
376 #endif
377 #if defined(TLSEXT_TYPE_renegotiate)
378 TLSEXT_TYPE_renegotiate,
379 #endif
380 #if defined(TLSEXT_TYPE_ec_point_formats)
381 TLSEXT_TYPE_ec_point_formats,
382 #endif
383 #if defined(TLSEXT_TYPE_elliptic_curves)
384 TLSEXT_TYPE_elliptic_curves,
385 #endif
386 #if defined(TLSEXT_TYPE_session_ticket)
387 TLSEXT_TYPE_session_ticket,
388 #endif
389 #if defined(TLSEXT_TYPE_status_request)
390 TLSEXT_TYPE_status_request,
391 #endif
392 #if defined(TLSEXT_TYPE_use_srtp)
393 TLSEXT_TYPE_use_srtp,
394 #endif
395 #if 0 //Allow 13172 Firefox supported extension for testing purposes
396 13172,
397 #endif
398 -1
399 };
400 bool found = false;
401 for (int i = 0; supportedExtensions[i] != -1; i++) {
402 if (*it == supportedExtensions[i]) {
403 found = true;
404 break;
405 }
406 }
407 if (!found) {
408 debugs(83, 5, "Extension " << *it << " does not supported!");
409 return false;
410 }
411 }
412
413 SSL3_BUFFER *wb=&(ssl->s3->wbuf);
414 if (wb->len < (size_t)features.helloMessage.length())
415 return false;
416
417 debugs(83, 5, "OpenSSL SSL struct will be adjusted to mimic client hello data!");
418
419 //Adjust ssl structure data.
420 // We need to fix the random in SSL struct:
421 memcpy(ssl->s3->client_random, features.client_random, SSL3_RANDOM_SIZE);
422 memcpy(wb->buf, features.helloMessage.rawContent(), features.helloMessage.length());
423 wb->left = features.helloMessage.length();
424
425 size_t mainHelloSize = features.helloMessage.length() - 5;
426 const char *mainHello = features.helloMessage.rawContent() + 5;
427 assert((size_t)ssl->init_buf->max > mainHelloSize);
428 memcpy(ssl->init_buf->data, mainHello, mainHelloSize);
429 debugs(83, 5, "Hello Data init and adjustd sizes :" << ssl->init_num << " = "<< mainHelloSize);
430 ssl->init_num = mainHelloSize;
431 ssl->s3->wpend_ret = mainHelloSize;
432 ssl->s3->wpend_tot = mainHelloSize;
433 return true;
434 #else
435 return false;
436 #endif
437 }
438
439 int
440 Ssl::ServerBio::write(const char *buf, int size, BIO *table)
441 {
442
443 if (holdWrite_) {
444 debugs(83, 7, "Hold write, for SSL connection on " << fd_ << "will not write bytes of size " << size);
445 BIO_set_retry_write(table);
446 return -1;
447 }
448
449 if (!helloBuild && (bumpMode_ == Ssl::bumpPeek || bumpMode_ == Ssl::bumpStare)) {
450 if (
451 buf[1] >= 3 //it is an SSL Version3 message
452 && buf[0] == 0x16 // and it is a Handshake/Hello message
453 ) {
454
455 //Hello message is the first message we write to server
456 assert(helloMsg.isEmpty());
457
458 auto ssl = fd_table[fd_].ssl.get();
459 if (clientFeatures.initialized_ && ssl) {
460 if (bumpMode_ == Ssl::bumpPeek) {
461 if (adjustSSL(ssl, clientFeatures))
462 allowBump = true;
463 allowSplice = true;
464 helloMsg.append(clientFeatures.helloMessage);
465 debugs(83, 7, "SSL HELLO message for FD " << fd_ << ": Random number is adjusted for peek mode");
466 } else { /*Ssl::bumpStare*/
467 allowBump = true;
468 if (adjustSSL(ssl, clientFeatures)) {
469 allowSplice = true;
470 helloMsg.append(clientFeatures.helloMessage);
471 debugs(83, 7, "SSL HELLO message for FD " << fd_ << ": Random number is adjusted for stare mode");
472 }
473 }
474 }
475 }
476 // If we do not build any hello message, copy the current
477 if (helloMsg.isEmpty())
478 helloMsg.append(buf, size);
479
480 helloBuild = true;
481 helloMsgSize = helloMsg.length();
482 //allowBump = true;
483
484 if (allowSplice) {
485 // Do not write yet.....
486 BIO_set_retry_write(table);
487 return -1;
488 }
489 }
490
491 if (!helloMsg.isEmpty()) {
492 debugs(83, 7, "buffered write for FD " << fd_);
493 int ret = Ssl::Bio::write(helloMsg.rawContent(), helloMsg.length(), table);
494 helloMsg.consume(ret);
495 if (!helloMsg.isEmpty()) {
496 // We need to retry sendind data.
497 // Say to openSSL to retry sending hello message
498 BIO_set_retry_write(table);
499 return -1;
500 }
501
502 // Sending hello message complete. Do not send more data for now...
503 holdWrite_ = true;
504
505 // spoof openSSL that we write what it ask us to write
506 return size;
507 } else
508 return Ssl::Bio::write(buf, size, table);
509 }
510
511 void
512 Ssl::ServerBio::flush(BIO *table)
513 {
514 if (!helloMsg.isEmpty()) {
515 int ret = Ssl::Bio::write(helloMsg.rawContent(), helloMsg.length(), table);
516 helloMsg.consume(ret);
517 }
518 }
519
520 void
521 Ssl::ServerBio::extractHelloFeatures()
522 {
523 if (!receivedHelloFeatures_.initialized_)
524 receivedHelloFeatures_.get(rbuf, false);
525 }
526
527 bool
528 Ssl::ServerBio::resumingSession()
529 {
530 return parser_.ressumingSession;
531 }
532
533
534 /// initializes BIO table after allocation
535 static int
536 squid_bio_create(BIO *bi)
537 {
538 bi->init = 0; // set when we store Bio object and socket fd (BIO_C_SET_FD)
539 bi->num = 0;
540 bi->ptr = NULL;
541 bi->flags = 0;
542 return 1;
543 }
544
545 /// cleans BIO table before deallocation
546 static int
547 squid_bio_destroy(BIO *table)
548 {
549 delete static_cast<Ssl::Bio*>(table->ptr);
550 table->ptr = NULL;
551 return 1;
552 }
553
554 /// wrapper for Bio::write()
555 static int
556 squid_bio_write(BIO *table, const char *buf, int size)
557 {
558 Ssl::Bio *bio = static_cast<Ssl::Bio*>(table->ptr);
559 assert(bio);
560 return bio->write(buf, size, table);
561 }
562
563 /// wrapper for Bio::read()
564 static int
565 squid_bio_read(BIO *table, char *buf, int size)
566 {
567 Ssl::Bio *bio = static_cast<Ssl::Bio*>(table->ptr);
568 assert(bio);
569 return bio->read(buf, size, table);
570 }
571
572 /// implements puts() via write()
573 static int
574 squid_bio_puts(BIO *table, const char *str)
575 {
576 assert(str);
577 return squid_bio_write(table, str, strlen(str));
578 }
579
580 /// other BIO manipulations (those without dedicated callbacks in BIO table)
581 static long
582 squid_bio_ctrl(BIO *table, int cmd, long arg1, void *arg2)
583 {
584 debugs(83, 5, table << ' ' << cmd << '(' << arg1 << ", " << arg2 << ')');
585
586 switch (cmd) {
587 case BIO_C_SET_FD: {
588 assert(arg2);
589 const int fd = *static_cast<int*>(arg2);
590 Ssl::Bio *bio;
591 if (arg1 == Ssl::Bio::BIO_TO_SERVER)
592 bio = new Ssl::ServerBio(fd);
593 else
594 bio = new Ssl::ClientBio(fd);
595 assert(!table->ptr);
596 table->ptr = bio;
597 table->init = 1;
598 return 0;
599 }
600
601 case BIO_C_GET_FD:
602 if (table->init) {
603 Ssl::Bio *bio = static_cast<Ssl::Bio*>(table->ptr);
604 assert(bio);
605 if (arg2)
606 *static_cast<int*>(arg2) = bio->fd();
607 return bio->fd();
608 }
609 return -1;
610
611 case BIO_CTRL_DUP:
612 // Should implemented if the SSL_dup openSSL API function
613 // used anywhere in squid.
614 return 0;
615
616 case BIO_CTRL_FLUSH:
617 if (table->init) {
618 Ssl::Bio *bio = static_cast<Ssl::Bio*>(table->ptr);
619 assert(bio);
620 bio->flush(table);
621 return 1;
622 }
623 return 0;
624
625 /* we may also need to implement these:
626 case BIO_CTRL_RESET:
627 case BIO_C_FILE_SEEK:
628 case BIO_C_FILE_TELL:
629 case BIO_CTRL_INFO:
630 case BIO_CTRL_GET_CLOSE:
631 case BIO_CTRL_SET_CLOSE:
632 case BIO_CTRL_PENDING:
633 case BIO_CTRL_WPENDING:
634 */
635 default:
636 return 0;
637
638 }
639
640 return 0; /* NOTREACHED */
641 }
642
643 /// wrapper for Bio::stateChanged()
644 static void
645 squid_ssl_info(const SSL *ssl, int where, int ret)
646 {
647 if (BIO *table = SSL_get_rbio(ssl)) {
648 if (Ssl::Bio *bio = static_cast<Ssl::Bio*>(table->ptr))
649 bio->stateChanged(ssl, where, ret);
650 }
651 }
652
653 Ssl::Bio::sslFeatures::sslFeatures():
654 sslHelloVersion(-1),
655 sslVersion(-1),
656 compressMethod(-1),
657 helloMsgSize(0),
658 unknownCiphers(false),
659 doHeartBeats(true),
660 tlsTicketsExtension(false),
661 hasTlsTicket(false),
662 tlsStatusRequest(false),
663 initialized_(false)
664 {
665 memset(client_random, 0, SSL3_RANDOM_SIZE);
666 }
667
668 int Ssl::Bio::sslFeatures::toSquidSSLVersion() const
669 {
670 if (sslVersion == SSL2_VERSION)
671 return 2;
672 else if (sslVersion == SSL3_VERSION)
673 return 3;
674 else if (sslVersion == TLS1_VERSION)
675 return 4;
676 #if OPENSSL_VERSION_NUMBER >= 0x10001000L
677 else if (sslVersion == TLS1_1_VERSION)
678 return 5;
679 else if (sslVersion == TLS1_2_VERSION)
680 return 6;
681 #endif
682 else
683 return 1;
684 }
685
686 bool
687 Ssl::Bio::sslFeatures::get(const SSL *ssl)
688 {
689 sslVersion = SSL_version(ssl);
690 debugs(83, 7, "SSL version: " << SSL_get_version(ssl) << " (" << sslVersion << ")");
691
692 #if defined(TLSEXT_NAMETYPE_host_name)
693 if (const char *server = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name))
694 serverName = server;
695 debugs(83, 7, "SNI server name: " << serverName);
696 #endif
697
698 #if !defined(OPENSSL_NO_COMP)
699 if (ssl->session->compress_meth)
700 compressMethod = ssl->session->compress_meth;
701 else if (sslVersion >= 3) //if it is 3 or newer version then compression is disabled
702 #endif
703 compressMethod = 0;
704 debugs(83, 7, "SSL compression: " << compressMethod);
705
706 STACK_OF(SSL_CIPHER) * ciphers = NULL;
707 if (ssl->server)
708 ciphers = ssl->session->ciphers;
709 else
710 ciphers = ssl->cipher_list;
711 if (ciphers) {
712 for (int i = 0; i < sk_SSL_CIPHER_num(ciphers); ++i) {
713 SSL_CIPHER *c = sk_SSL_CIPHER_value(ciphers, i);
714 if (c != NULL) {
715 if (!clientRequestedCiphers.empty())
716 clientRequestedCiphers.append(":");
717 clientRequestedCiphers.append(c->name);
718 }
719 }
720 }
721 debugs(83, 7, "Ciphers requested by client: " << clientRequestedCiphers);
722
723 if (sslVersion >=3 && ssl->s3 && ssl->s3->client_random[0]) {
724 memcpy(client_random, ssl->s3->client_random, SSL3_RANDOM_SIZE);
725 }
726
727 initialized_ = true;
728 return true;
729 }
730
731 int
732 Ssl::Bio::sslFeatures::parseMsgHead(const SBuf &buf)
733 {
734 debugs(83, 7, "SSL Header: " << Raw(nullptr, buf.rawContent(), buf.length()).hex());
735
736 if (buf.length() < 5)
737 return 0;
738
739 if (helloMsgSize > 0)
740 return helloMsgSize;
741
742 const unsigned char *head = (const unsigned char *)buf.rawContent();
743 // Check for SSLPlaintext/TLSPlaintext record
744 // RFC6101 section 5.2.1
745 // RFC5246 section 6.2.1
746 if (head[0] == 0x16) {
747 debugs(83, 7, "SSL version 3 handshake message");
748 // The SSL version exist in the 2nd and 3rd bytes
749 sslHelloVersion = (head[1] << 8) | head[2];
750 debugs(83, 7, "SSL Version :" << std::hex << std::setw(8) << std::setfill('0') << sslVersion);
751 // The hello message size exist in 4th and 5th bytes
752 helloMsgSize = (head[3] << 8) + head[4];
753 debugs(83, 7, "SSL Header Size: " << helloMsgSize);
754 helloMsgSize +=5;
755 } else if ((head[0] & 0x80) && head[2] == 0x01 && head[3] == 0x03) {
756 debugs(83, 7, "SSL version 2 handshake message with v3 support");
757 sslHelloVersion = 0x0002;
758 debugs(83, 7, "SSL Version :" << std::hex << std::setw(8) << std::setfill('0') << sslVersion);
759 // The hello message size exist in 2nd byte
760 helloMsgSize = head[1];
761 helloMsgSize +=2;
762 } else {
763 debugs(83, 7, "Not an SSL acceptable handshake message (SSLv2 message?)");
764 return (helloMsgSize = -1);
765 }
766
767 // Set object as initialized. Even if we did not full parsing yet
768 // The basic features, like the SSL version is set
769 initialized_ = true;
770 return helloMsgSize;
771 }
772
773 bool
774 Ssl::Bio::sslFeatures::get(const SBuf &buf, bool record)
775 {
776 int msgSize;
777 if ((msgSize = parseMsgHead(buf)) <= 0) {
778 debugs(83, 7, "Not a known SSL handshake message");
779 return false;
780 }
781
782 if (msgSize > (int)buf.length()) {
783 debugs(83, 2, "Partial SSL handshake message, can not parse!");
784 return false;
785 }
786
787 if (record)
788 helloMessage = buf;
789
790 const unsigned char *msg = (const unsigned char *)buf.rawContent();
791 if (msg[0] & 0x80)
792 return parseV23Hello(msg, (size_t)msgSize);
793 else {
794 // Hello messages require 5 bytes header + 1 byte Msg type + 3 bytes for Msg size
795 if (buf.length() < 9)
796 return false;
797
798 // Check for the Handshake/Message type
799 // The type 2 is a ServerHello, the type 1 is a ClientHello
800 // RFC5246 section 7.4
801 if (msg[5] == 0x2) { // ServerHello message
802 return parseV3ServerHello(msg, (size_t)msgSize);
803 } else if (msg[5] == 0x1) // ClientHello message,
804 return parseV3Hello(msg, (size_t)msgSize);
805 }
806
807 return false;
808 }
809
810 bool
811 Ssl::Bio::sslFeatures::parseV3ServerHello(const unsigned char *messageContainer, size_t messageContainerSize)
812 {
813 // Parse a ServerHello Handshake message
814 // RFC5246 section 7.4, 7.4.1.3
815 // The ServerHello starts at messageContainer + 5
816 const unsigned char *serverHello = messageContainer + 5;
817
818 // The Length field (bytes 1-3) plus 4 bytes of the serverHello message header (1 handshake type + 3 hello length)
819 const size_t helloSize = ((serverHello[1] << 16) | (serverHello[2] << 8) | serverHello[3]) + 4;
820 debugs(83, 7, "ServerHello message size: " << helloSize);
821 if (helloSize > messageContainerSize) {
822 debugs(83, 2, "ServerHello parse error");
823 return false;
824 }
825
826 // helloSize should be at least 38 bytes long:
827 // (SSL Version + Random + SessionId Length + Cipher Suite + Compression Method)
828 if (helloSize < 38) {
829 debugs(83, 2, "Too short ServerHello message");
830 return false;
831 }
832
833 debugs(83, 7, "Get fake features from v3 ServerHello message.");
834 // Get the correct version of the sub-hello message
835 sslVersion = (serverHello[4] << 8) | serverHello[5];
836 // At the position 38 (HelloHeader (6bytes) + SSL3_RANDOM_SIZE (32bytes))
837 const size_t sessIdLen = static_cast<size_t>(serverHello[38]);
838 debugs(83, 7, "Session ID Length: " << sessIdLen);
839
840 // The size should be enough to hold at least the following
841 // 4 (hello header)
842 // + 2 (SSL Version) + 32 (random) + 1 (sessionId length)
843 // + sessIdLength + 2 (cipher suite) + 1 (compression method)
844 // = 42 + sessIdLength
845 if (42 + sessIdLen > helloSize) {
846 debugs(83, 2, "ciphers length parse error");
847 return false;
848 }
849
850 // The sessionID stored at 39 position, after sessionID length field
851 sessionId.assign(reinterpret_cast<const char *>(serverHello + 39), sessIdLen);
852
853 // Check if there are extensions in hello message
854 // RFC5246 section 7.4.1.4
855 if (helloSize > 42 + sessIdLen + 2) {
856 // 42 + sessIdLen
857 const unsigned char *pToExtensions = serverHello + 42 + sessIdLen;
858 const size_t extensionsLen = (pToExtensions[0] << 8) | pToExtensions[1];
859 // Check if the hello size can hold extensions
860 if (42 + 2 + sessIdLen + extensionsLen > helloSize ) {
861 debugs(83, 2, "Extensions length parse error");
862 return false;
863 }
864
865 pToExtensions += 2;
866 const unsigned char *ext = pToExtensions;
867 while (ext + 4 <= pToExtensions + extensionsLen) {
868 const size_t extType = (ext[0] << 8) | ext[1];
869 ext += 2;
870 const size_t extLen = (ext[0] << 8) | ext[1];
871 ext += 2;
872 debugs(83, 7, "TLS Extension: " << std::hex << extType << " of size:" << extLen);
873 // SessionTicket TLS Extension, RFC5077 section 3.2
874 if (extType == 0x23) {
875 tlsTicketsExtension = true;
876 }
877 ext += extLen;
878 }
879 }
880 return true;
881 }
882
883 bool
884 Ssl::Bio::sslFeatures::parseV3Hello(const unsigned char *messageContainer, size_t messageContainerSize)
885 {
886 // Parse a ClientHello Handshake message
887 // RFC5246 section 7.4, 7.4.1.2
888 // The ClientHello starts at messageContainer + 5
889 const unsigned char * clientHello = messageContainer + 5;
890
891 debugs(83, 7, "Get fake features from v3 ClientHello message.");
892 // The Length field (bytes 1-3) plus 4 bytes of the clientHello message header (1 handshake type + 3 hello length)
893 const size_t helloSize = ((clientHello[1] << 16) | (clientHello[2] << 8) | clientHello[3]) + 4;
894 debugs(83, 7, "ClientHello message size: " << helloSize);
895 if (helloSize > messageContainerSize) {
896 debugs(83, 2, "ClientHello parse error");
897 return false;
898 }
899
900 // helloSize should be at least 38 bytes long:
901 // (SSL Version(2) + Random(32) + SessionId Length(1) + Cipher Suite Length(2) + Compression Method Length(1))
902 if (helloSize < 38) {
903 debugs(83, 2, "Too short ClientHello message");
904 return false;
905 }
906
907 //For SSLv3 or TLSv1.* protocols we can get some more informations
908 if (messageContainer[1] != 0x3 || clientHello[0] != 0x1 /*HELLO A message*/) {
909 debugs(83, 2, "Not an SSLv3/TLSv1.x client hello message, stop parsing here");
910 return true;
911 }
912
913 // Get the correct version of the sub-hello message
914 sslVersion = (clientHello[4] << 8) | clientHello[5];
915 //Get Client Random number. It starts on the position 6 of clientHello message
916 memcpy(client_random, clientHello + 6, SSL3_RANDOM_SIZE);
917 debugs(83, 7, "Client random: " << Raw(nullptr, (char *)client_random, SSL3_RANDOM_SIZE).hex());
918
919 // At the position 38 (6+SSL3_RANDOM_SIZE)
920 const size_t sessIDLen = static_cast<size_t>(clientHello[38]);
921 debugs(83, 7, "Session ID Length: " << sessIDLen);
922
923 // The helloSize should be enough to hold at least the following
924 // 1 handshake type + 3 hello Length
925 // + 2 (SSL Version) + 32 (random) + 1 (sessionId length)
926 // + sessIdLength + 2 (cipher suite length) + 1 (compression method length)
927 // = 42 + sessIdLength
928 if (42 + sessIDLen > helloSize) {
929 debugs(83, 2, "Session ID length parse error");
930 return false;
931 }
932
933 // The sessionID stored art 39 position, after sessionID length field
934 sessionId.assign(reinterpret_cast<const char *>(clientHello + 39), sessIDLen);
935
936 //Ciphers list. It is stored after the Session ID.
937 // It is a variable-length vector(RFC5246 section 4.3)
938 const unsigned char *ciphers = clientHello + 39 + sessIDLen;
939 const size_t ciphersLen = (ciphers[0] << 8) | ciphers[1];
940 if (42 + sessIDLen + ciphersLen > helloSize) {
941 debugs(83, 2, "ciphers length parse error");
942 return false;
943 }
944
945 ciphers += 2;
946 if (ciphersLen) {
947 #if (OPENSSL_VERSION_NUMBER >= 0x10100000L)
948 const SSL_METHOD *method = TLS_method();
949 #else
950 const SSL_METHOD *method = SSLv23_method();
951 #endif
952 for (size_t i = 0; i < ciphersLen; i += 2) {
953 // each cipher in v3/tls HELLO message is of size 2
954 const SSL_CIPHER *c = method->get_cipher_by_char((ciphers + i));
955 if (c != NULL) {
956 if (!clientRequestedCiphers.empty())
957 clientRequestedCiphers.append(":");
958 clientRequestedCiphers.append(c->name);
959 } else
960 unknownCiphers = true;
961 }
962 }
963 debugs(83, 7, "Ciphers requested by client: " << clientRequestedCiphers);
964
965 // Compression field: 1 bytes the number of compression methods and
966 // 1 byte for each compression method
967 const unsigned char *compression = ciphers + ciphersLen;
968 if (compression[0] > 1)
969 compressMethod = 1;
970 else
971 compressMethod = 0;
972 debugs(83, 7, "SSL compression methods number: " << static_cast<int>(compression[0]));
973
974 // Parse Extensions, RFC5246 section 7.4.1.4
975 const unsigned char *pToExtensions = compression + 1 + static_cast<int>(compression[0]);
976 if ((size_t)((pToExtensions - clientHello) + 2) < helloSize) {
977 const size_t extensionsLen = (pToExtensions[0] << 8) | pToExtensions[1];
978 if ((pToExtensions - clientHello) + 2 + extensionsLen > helloSize) {
979 debugs(83, 2, "Extensions length parse error");
980 return false;
981 }
982
983 pToExtensions += 2;
984 const unsigned char *ext = pToExtensions;
985 while (ext + 4 <= pToExtensions + extensionsLen) {
986 const size_t extType = (ext[0] << 8) | ext[1];
987 ext += 2;
988 const size_t extLen = (ext[0] << 8) | ext[1];
989 ext += 2;
990 debugs(83, 7, "TLS Extension: " << std::hex << extType << " of size:" << extLen);
991
992 if (ext + extLen > pToExtensions + extensionsLen) {
993 debugs(83, 2, "Extension " << std::hex << extType << " length parser error");
994 return false;
995 }
996
997 //The SNI extension has the type 0 (extType == 0)
998 // RFC6066 sections 3, 10.2
999 // The two first bytes indicates the length of the SNI data (should be extLen-2)
1000 // The next byte is the hostname type, it should be '0' for normal hostname (ext[2] == 0)
1001 // The 3rd and 4th bytes are the length of the hostname
1002 if (extType == 0 && ext[2] == 0) {
1003 const size_t hostLen = (ext[3] << 8) | ext[4];
1004 if (hostLen < extLen)
1005 serverName.assign(reinterpret_cast<const char *>(ext+5), hostLen);
1006 debugs(83, 7, "Found server name: " << serverName);
1007 } else if (extType == 15 && ext[0] != 0) {
1008 // The heartBeats are the type 15, RFC6520
1009 doHeartBeats = true;
1010 } else if (extType == 0x23) {
1011 //SessionTicket TLS Extension RFC5077
1012 tlsTicketsExtension = true;
1013 if (extLen != 0)
1014 hasTlsTicket = true;
1015 } else if (extType == 0x05) {
1016 // RFC6066 sections 8, 10.2
1017 tlsStatusRequest = true;
1018 } else if (extType == 0x3374) {
1019 // detected TLS next protocol negotiate extension
1020 } else if (extType == 0x10) {
1021 // Application-Layer Protocol Negotiation Extension, RFC7301
1022 const size_t listLen = (ext[0] << 8) | ext[1];
1023 if (listLen < extLen)
1024 tlsAppLayerProtoNeg.assign(reinterpret_cast<const char *>(ext+5), listLen);
1025 } else
1026 extensions.push_back(extType);
1027
1028 ext += extLen;
1029 }
1030 }
1031 return true;
1032 }
1033
1034 bool
1035 Ssl::Bio::sslFeatures::parseV23Hello(const unsigned char *hello, size_t size)
1036 {
1037 debugs(83, 7, "Get fake features from v23 ClientHello message.");
1038 if (size < 7)
1039 return false;
1040
1041 // Get the SSL/TLS version supported by client
1042 sslVersion = (hello[3] << 8) | hello[4];
1043
1044 //Ciphers list. It is stored after the Session ID.
1045 const unsigned int ciphersLen = (hello[5] << 8) | hello[6];
1046 const unsigned char *ciphers = hello + 11;
1047
1048 if (size < ciphersLen + 11)
1049 return false;
1050
1051 if (ciphersLen) {
1052 #if (OPENSSL_VERSION_NUMBER >= 0x10100000L)
1053 const SSL_METHOD *method = TLS_method();
1054 #else
1055 const SSL_METHOD *method = SSLv23_method();
1056 #endif
1057 for (unsigned int i = 0; i < ciphersLen; i += 3) {
1058 // The v2 hello messages cipher has 3 bytes.
1059 // The v2 cipher has the first byte not null
1060 // Because we are going to sent only v3 message we
1061 // are ignoring these ciphers
1062 if (ciphers[i] != 0)
1063 continue;
1064 const SSL_CIPHER *c = method->get_cipher_by_char((ciphers + i + 1));
1065 if (c != NULL) {
1066 if (!clientRequestedCiphers.empty())
1067 clientRequestedCiphers.append(":");
1068 clientRequestedCiphers.append(c->name);
1069 }
1070 }
1071 }
1072 debugs(83, 7, "Ciphers requested by client: " << clientRequestedCiphers);
1073
1074 const unsigned int sessionIdLength = (hello[7] << 8) | hello[8];
1075 debugs(83, 7, "SessionID length: " << sessionIdLength);
1076 // SessionID starts at: hello+11+ciphersLen
1077 if (sessionIdLength)
1078 sessionId.assign((const char *)(hello + 11 + ciphersLen), sessionIdLength);
1079
1080 const unsigned int challengeLength = (hello[5] << 9) | hello[10];
1081 debugs(83, 7, "Challenge Length: " << challengeLength);
1082 //challenge starts at: hello+11+ciphersLen+sessionIdLength
1083
1084 compressMethod = 0;
1085 return true;
1086 }
1087
1088 void
1089 Ssl::Bio::sslFeatures::applyToSSL(SSL *ssl, Ssl::BumpMode bumpMode) const
1090 {
1091 // To increase the possibility for bumping after peek mode selection or
1092 // splicing after stare mode selection it is good to set the
1093 // SSL protocol version.
1094 // The SSL_set_ssl_method is not the correct method because it will strict
1095 // SSL version which can be used to the SSL version used for client hello message.
1096 // For example will prevent comunnicating with a tls1.0 server if the
1097 // client sent and tlsv1.2 Hello message.
1098 #if defined(TLSEXT_NAMETYPE_host_name)
1099 if (!serverName.isEmpty()) {
1100 SSL_set_tlsext_host_name(ssl, serverName.c_str());
1101 }
1102 #endif
1103 if (!clientRequestedCiphers.empty())
1104 SSL_set_cipher_list(ssl, clientRequestedCiphers.c_str());
1105 #if defined(SSL_OP_NO_COMPRESSION) /* XXX: OpenSSL 0.9.8k lacks SSL_OP_NO_COMPRESSION */
1106 if (compressMethod == 0)
1107 SSL_set_options(ssl, SSL_OP_NO_COMPRESSION);
1108 #endif
1109
1110 #if defined(TLSEXT_STATUSTYPE_ocsp)
1111 if (tlsStatusRequest)
1112 SSL_set_tlsext_status_type(ssl, TLSEXT_STATUSTYPE_ocsp);
1113 #endif
1114
1115 #if defined(TLSEXT_TYPE_application_layer_protocol_negotiation)
1116 if (!tlsAppLayerProtoNeg.isEmpty()) {
1117 if (bumpMode == Ssl::bumpPeek)
1118 SSL_set_alpn_protos(ssl, (const unsigned char*)tlsAppLayerProtoNeg.rawContent(), tlsAppLayerProtoNeg.length());
1119 else {
1120 static const unsigned char supported_protos[] = {8, 'h','t','t', 'p', '/', '1', '.', '1'};
1121 SSL_set_alpn_protos(ssl, supported_protos, sizeof(supported_protos));
1122 }
1123 }
1124 #endif
1125 }
1126
1127 std::ostream &
1128 Ssl::Bio::sslFeatures::print(std::ostream &os) const
1129 {
1130 static std::string buf;
1131 // TODO: Also print missing features like the HeartBeats and AppLayerProtoNeg
1132 return os << "v" << sslVersion <<
1133 " SNI:" << (serverName.isEmpty() ? SBuf("-") : serverName) <<
1134 " comp:" << compressMethod <<
1135 " Ciphers:" << clientRequestedCiphers <<
1136 " Random:" << Raw(nullptr, (char *)client_random, SSL3_RANDOM_SIZE).hex();
1137 }
1138
1139 #endif /* USE_SSL */
1140