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