2 * Copyright (C) 1996-2016 The Squid Software Foundation and contributors
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.
9 /* DEBUG: section 83 SSL accelerator support */
12 #include "ssl/support.h"
14 /* support.cc says this is needed */
21 #include "ip/Address.h"
22 #include "parser/BinaryTokenizer.h"
25 #if HAVE_OPENSSL_SSL_H
26 #include <openssl/ssl.h>
30 extern int socket_read_method(int, char *, int);
31 extern int socket_write_method(int, const char *, int);
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
);
43 static void squid_ssl_info(const SSL
*ssl
, int where
, int ret
);
45 /// Initialization structure for the BIO table with
46 /// Squid-specific methods and BIO method wrappers.
47 static BIO_METHOD SquidMethods
= {
53 NULL
, // squid_bio_gets not supported
57 NULL
// squid_callback_ctrl not supported
63 Ssl::Bio::Create(const int fd
, Ssl::Bio::Type type
)
65 if (BIO
*bio
= BIO_new(&SquidMethods
)) {
66 BIO_int_ctrl(bio
, BIO_C_SET_FD
, type
, fd
);
73 Ssl::Bio::Link(SSL
*ssl
, BIO
*bio
)
75 SSL_set_bio(ssl
, bio
, bio
); // cannot fail
76 SSL_set_info_callback(ssl
, &squid_ssl_info
); // does not provide diagnostic
79 Ssl::Bio::Bio(const int anFd
): fd_(anFd
)
81 debugs(83, 7, "Bio constructed, this=" << this << " FD " << fd_
);
86 debugs(83, 7, "Bio destructing, this=" << this << " FD " << fd_
);
89 int Ssl::Bio::write(const char *buf
, int size
, BIO
*table
)
93 const int result
= socket_write_method(fd_
, buf
, size
);
95 const int result
= default_write_method(fd_
, buf
, size
);
97 const int xerrno
= errno
;
98 debugs(83, 5, "FD " << fd_
<< " wrote " << result
<< " <= " << size
);
100 BIO_clear_retry_flags(table
);
102 const bool ignoreError
= ignoreErrno(xerrno
) != 0;
103 debugs(83, 5, "error: " << xerrno
<< " ignored: " << ignoreError
);
105 BIO_set_retry_write(table
);
112 Ssl::Bio::read(char *buf
, int size
, BIO
*table
)
116 const int result
= socket_read_method(fd_
, buf
, size
);
118 const int result
= default_read_method(fd_
, buf
, size
);
120 const int xerrno
= errno
;
121 debugs(83, 5, "FD " << fd_
<< " read " << result
<< " <= " << size
);
123 BIO_clear_retry_flags(table
);
125 const bool ignoreError
= ignoreErrno(xerrno
) != 0;
126 debugs(83, 5, "error: " << xerrno
<< " ignored: " << ignoreError
);
128 BIO_set_retry_read(table
);
135 Ssl::Bio::readAndBuffer(BIO
*table
, const char *description
)
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()
142 rbuf
.append(buf
, bytes
);
143 debugs(83, 5, "recorded " << bytes
<< " bytes of " << description
);
148 /// Called whenever the SSL connection state changes, an alert appears, or an
149 /// error occurs. See SSL_set_info_callback().
151 Ssl::Bio::stateChanged(const SSL
*ssl
, int where
, int ret
)
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.
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");
162 debugs(83, 7, "FD " << fd_
<< " now: 0x" << std::hex
<< where
<< std::dec
<< ' ' <<
163 SSL_state_string(ssl
) << " (" << SSL_state_string_long(ssl
) << ")");
167 Ssl::ClientBio::isClientHello(int state
)
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
179 Ssl::ClientBio::stateChanged(const SSL
*ssl
, int where
, int ret
)
181 Ssl::Bio::stateChanged(ssl
, where
, ret
);
185 Ssl::ClientBio::write(const char *buf
, int size
, BIO
*table
)
188 BIO_set_retry_write(table
);
192 return Ssl::Bio::write(buf
, size
, table
);
196 Ssl::ClientBio::read(char *buf
, int size
, BIO
*table
)
198 if (helloState
< atHelloReceived
) {
199 int bytes
= readAndBuffer(table
, "TLS client Hello");
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
);
210 } else if (helloSize
< 0) {
211 wrongProtocol
= true;
215 helloState
= atHelloStarted
; //Next state
218 if (helloState
== atHelloStarted
) {
219 debugs(83, 7, "SSL Header: " << Raw(nullptr, rbuf
.rawContent(), rbuf
.length()).hex());
221 if (helloSize
> (int)rbuf
.length()) {
222 BIO_set_retry_read(table
);
225 receivedHelloFeatures_
.get(rbuf
);
226 helloState
= atHelloReceived
;
230 debugs(83, 7, "Hold flag is set, retry latter. (Hold " << size
<< "bytes)");
231 BIO_set_retry_read(table
);
235 if (helloState
== atHelloReceived
) {
236 if (!rbuf
.isEmpty()) {
237 int bytes
= (size
<= (int)rbuf
.length() ? size
: rbuf
.length());
238 memcpy(buf
, rbuf
.rawContent(), bytes
);
242 return Ssl::Bio::read(buf
, size
, table
);
249 Ssl::ServerBio::stateChanged(const SSL
*ssl
, int where
, int ret
)
251 Ssl::Bio::stateChanged(ssl
, where
, ret
);
255 Ssl::ServerBio::setClientFeatures(const Ssl::Bio::sslFeatures
&features
)
257 clientFeatures
= features
;
261 Ssl::ServerBio::readAndBufferServerHelloMsg(BIO
*table
, const char *description
)
264 int ret
= readAndBuffer(table
, description
);
268 if (!parser_
.parseServerHello(rbuf
)) {
269 if (!parser_
.parseError
)
270 BIO_set_retry_read(table
);
278 Ssl::ServerBio::read(char *buf
, int size
, BIO
*table
)
280 if (!parser_
.parseDone
|| record_
) {
281 int ret
= readAndBufferServerHelloMsg(table
, "TLS server Hello");
282 if (!rbuf
.length() && parser_
.parseDone
&& ret
<= 0)
287 debugs(83, 7, "Hold flag is set on ServerBio, retry latter. (Hold " << size
<< "bytes)");
288 BIO_set_retry_read(table
);
292 if (parser_
.parseDone
&& !parser_
.parseError
) {
293 int unsent
= rbuf
.length() - rbufConsumePos
;
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");
301 return Ssl::Bio::read(buf
, size
, table
);
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.
315 adjustSSL(SSL
*ssl
, Ssl::Bio::sslFeatures
&features
)
317 #if SQUID_USE_OPENSSL_HELLO_OVERWRITE_HACK
319 debugs(83, 5, "No SSLv3 data found!");
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
);
328 const bool requireCompression
= features
.compressMethod
;
330 if (requireCompression
) {
331 debugs(83, 5, "Client Hello Data supports compression, but we do not!");
335 // Check ciphers list
338 while (token
!= std::string::npos
) {
339 end
= features
.clientRequestedCiphers
.find(':',token
);
341 cipher
.assign(features
.clientRequestedCiphers
, token
, end
- token
);
342 token
= (end
!= std::string::npos
? end
+ 1 : std::string::npos
);
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
)) {
354 debugs(83, 5, "Client Hello Data supports cipher '"<< cipher
<<"' but we do not support it!");
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!");
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
,
371 #if defined(TLSEXT_TYPE_opaque_prf_input)
372 TLSEXT_TYPE_opaque_prf_input
,
374 #if defined(TLSEXT_TYPE_heartbeat)
375 TLSEXT_TYPE_heartbeat
,
377 #if defined(TLSEXT_TYPE_renegotiate)
378 TLSEXT_TYPE_renegotiate
,
380 #if defined(TLSEXT_TYPE_ec_point_formats)
381 TLSEXT_TYPE_ec_point_formats
,
383 #if defined(TLSEXT_TYPE_elliptic_curves)
384 TLSEXT_TYPE_elliptic_curves
,
386 #if defined(TLSEXT_TYPE_session_ticket)
387 TLSEXT_TYPE_session_ticket
,
389 #if defined(TLSEXT_TYPE_status_request)
390 TLSEXT_TYPE_status_request
,
392 #if defined(TLSEXT_TYPE_use_srtp)
393 TLSEXT_TYPE_use_srtp
,
395 #if 0 //Allow 13172 Firefox supported extension for testing purposes
401 for (int i
= 0; supportedExtensions
[i
] != -1; i
++) {
402 if (*it
== supportedExtensions
[i
]) {
408 debugs(83, 5, "Extension " << *it
<< " does not supported!");
413 SSL3_BUFFER
*wb
=&(ssl
->s3
->wbuf
);
414 if (wb
->len
< (size_t)features
.helloMessage
.length())
417 debugs(83, 5, "OpenSSL SSL struct will be adjusted to mimic client hello data!");
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();
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
;
440 Ssl::ServerBio::write(const char *buf
, int size
, BIO
*table
)
444 debugs(83, 7, "Hold write, for SSL connection on " << fd_
<< "will not write bytes of size " << size
);
445 BIO_set_retry_write(table
);
449 if (!helloBuild
&& (bumpMode_
== Ssl::bumpPeek
|| bumpMode_
== Ssl::bumpStare
)) {
451 buf
[1] >= 3 //it is an SSL Version3 message
452 && buf
[0] == 0x16 // and it is a Handshake/Hello message
455 //Hello message is the first message we write to server
456 assert(helloMsg
.isEmpty());
458 auto ssl
= fd_table
[fd_
].ssl
.get();
459 if (clientFeatures
.initialized_
&& ssl
) {
460 if (bumpMode_
== Ssl::bumpPeek
) {
461 if (adjustSSL(ssl
, clientFeatures
))
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*/
468 if (adjustSSL(ssl
, clientFeatures
)) {
470 helloMsg
.append(clientFeatures
.helloMessage
);
471 debugs(83, 7, "SSL HELLO message for FD " << fd_
<< ": Random number is adjusted for stare mode");
476 // If we do not build any hello message, copy the current
477 if (helloMsg
.isEmpty())
478 helloMsg
.append(buf
, size
);
481 helloMsgSize
= helloMsg
.length();
485 // Do not write yet.....
486 BIO_set_retry_write(table
);
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
);
502 // Sending hello message complete. Do not send more data for now...
505 // spoof openSSL that we write what it ask us to write
508 return Ssl::Bio::write(buf
, size
, table
);
512 Ssl::ServerBio::flush(BIO
*table
)
514 if (!helloMsg
.isEmpty()) {
515 int ret
= Ssl::Bio::write(helloMsg
.rawContent(), helloMsg
.length(), table
);
516 helloMsg
.consume(ret
);
521 Ssl::ServerBio::extractHelloFeatures()
523 if (!receivedHelloFeatures_
.initialized_
)
524 receivedHelloFeatures_
.get(rbuf
, false);
528 Ssl::ServerBio::resumingSession()
530 return parser_
.ressumingSession
;
534 /// initializes BIO table after allocation
536 squid_bio_create(BIO
*bi
)
538 bi
->init
= 0; // set when we store Bio object and socket fd (BIO_C_SET_FD)
545 /// cleans BIO table before deallocation
547 squid_bio_destroy(BIO
*table
)
549 delete static_cast<Ssl::Bio
*>(table
->ptr
);
554 /// wrapper for Bio::write()
556 squid_bio_write(BIO
*table
, const char *buf
, int size
)
558 Ssl::Bio
*bio
= static_cast<Ssl::Bio
*>(table
->ptr
);
560 return bio
->write(buf
, size
, table
);
563 /// wrapper for Bio::read()
565 squid_bio_read(BIO
*table
, char *buf
, int size
)
567 Ssl::Bio
*bio
= static_cast<Ssl::Bio
*>(table
->ptr
);
569 return bio
->read(buf
, size
, table
);
572 /// implements puts() via write()
574 squid_bio_puts(BIO
*table
, const char *str
)
577 return squid_bio_write(table
, str
, strlen(str
));
580 /// other BIO manipulations (those without dedicated callbacks in BIO table)
582 squid_bio_ctrl(BIO
*table
, int cmd
, long arg1
, void *arg2
)
584 debugs(83, 5, table
<< ' ' << cmd
<< '(' << arg1
<< ", " << arg2
<< ')');
589 const int fd
= *static_cast<int*>(arg2
);
591 if (arg1
== Ssl::Bio::BIO_TO_SERVER
)
592 bio
= new Ssl::ServerBio(fd
);
594 bio
= new Ssl::ClientBio(fd
);
603 Ssl::Bio
*bio
= static_cast<Ssl::Bio
*>(table
->ptr
);
606 *static_cast<int*>(arg2
) = bio
->fd();
612 // Should implemented if the SSL_dup openSSL API function
613 // used anywhere in squid.
618 Ssl::Bio
*bio
= static_cast<Ssl::Bio
*>(table
->ptr
);
625 /* we may also need to implement these:
627 case BIO_C_FILE_SEEK:
628 case BIO_C_FILE_TELL:
630 case BIO_CTRL_GET_CLOSE:
631 case BIO_CTRL_SET_CLOSE:
632 case BIO_CTRL_PENDING:
633 case BIO_CTRL_WPENDING:
640 return 0; /* NOTREACHED */
643 /// wrapper for Bio::stateChanged()
645 squid_ssl_info(const SSL
*ssl
, int where
, int ret
)
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
);
653 Ssl::Bio::sslFeatures::sslFeatures():
658 unknownCiphers(false),
660 tlsTicketsExtension(false),
662 tlsStatusRequest(false),
665 memset(client_random
, 0, SSL3_RANDOM_SIZE
);
668 int Ssl::Bio::sslFeatures::toSquidSSLVersion() const
670 if (sslVersion
== SSL2_VERSION
)
672 else if (sslVersion
== SSL3_VERSION
)
674 else if (sslVersion
== TLS1_VERSION
)
676 #if OPENSSL_VERSION_NUMBER >= 0x10001000L
677 else if (sslVersion
== TLS1_1_VERSION
)
679 else if (sslVersion
== TLS1_2_VERSION
)
687 Ssl::Bio::sslFeatures::get(const SSL
*ssl
)
689 sslVersion
= SSL_version(ssl
);
690 debugs(83, 7, "SSL version: " << SSL_get_version(ssl
) << " (" << sslVersion
<< ")");
692 #if defined(TLSEXT_NAMETYPE_host_name)
693 if (const char *server
= SSL_get_servername(ssl
, TLSEXT_NAMETYPE_host_name
))
695 debugs(83, 7, "SNI server name: " << serverName
);
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
704 debugs(83, 7, "SSL compression: " << compressMethod
);
706 STACK_OF(SSL_CIPHER
) * ciphers
= NULL
;
708 ciphers
= ssl
->session
->ciphers
;
710 ciphers
= ssl
->cipher_list
;
712 for (int i
= 0; i
< sk_SSL_CIPHER_num(ciphers
); ++i
) {
713 SSL_CIPHER
*c
= sk_SSL_CIPHER_value(ciphers
, i
);
715 if (!clientRequestedCiphers
.empty())
716 clientRequestedCiphers
.append(":");
717 clientRequestedCiphers
.append(c
->name
);
721 debugs(83, 7, "Ciphers requested by client: " << clientRequestedCiphers
);
723 if (sslVersion
>=3 && ssl
->s3
&& ssl
->s3
->client_random
[0]) {
724 memcpy(client_random
, ssl
->s3
->client_random
, SSL3_RANDOM_SIZE
);
732 Ssl::Bio::sslFeatures::parseMsgHead(const SBuf
&buf
)
734 debugs(83, 7, "SSL Header: " << Raw(nullptr, buf
.rawContent(), buf
.length()).hex());
736 if (buf
.length() < 5)
739 if (helloMsgSize
> 0)
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
);
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];
763 debugs(83, 7, "Not an SSL acceptable handshake message (SSLv2 message?)");
764 return (helloMsgSize
= -1);
767 // Set object as initialized. Even if we did not full parsing yet
768 // The basic features, like the SSL version is set
774 Ssl::Bio::sslFeatures::get(const SBuf
&buf
, bool record
)
777 if ((msgSize
= parseMsgHead(buf
)) <= 0) {
778 debugs(83, 7, "Not a known SSL handshake message");
782 if (msgSize
> (int)buf
.length()) {
783 debugs(83, 2, "Partial SSL handshake message, can not parse!");
790 const unsigned char *msg
= (const unsigned char *)buf
.rawContent();
792 return parseV23Hello(msg
, (size_t)msgSize
);
794 // Hello messages require 5 bytes header + 1 byte Msg type + 3 bytes for Msg size
795 if (buf
.length() < 9)
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
);
811 Ssl::Bio::sslFeatures::parseV3ServerHello(const unsigned char *messageContainer
, size_t messageContainerSize
)
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;
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");
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");
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
);
840 // The size should be enough to hold at least the following
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");
850 // The sessionID stored at 39 position, after sessionID length field
851 sessionId
.assign(reinterpret_cast<const char *>(serverHello
+ 39), sessIdLen
);
853 // Check if there are extensions in hello message
854 // RFC5246 section 7.4.1.4
855 if (helloSize
> 42 + sessIdLen
+ 2) {
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");
866 const unsigned char *ext
= pToExtensions
;
867 while (ext
+ 4 <= pToExtensions
+ extensionsLen
) {
868 const size_t extType
= (ext
[0] << 8) | ext
[1];
870 const size_t extLen
= (ext
[0] << 8) | ext
[1];
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;
884 Ssl::Bio::sslFeatures::parseV3Hello(const unsigned char *messageContainer
, size_t messageContainerSize
)
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;
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");
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");
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");
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());
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
);
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");
933 // The sessionID stored art 39 position, after sessionID length field
934 sessionId
.assign(reinterpret_cast<const char *>(clientHello
+ 39), sessIDLen
);
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");
947 #if (OPENSSL_VERSION_NUMBER >= 0x10100000L)
948 const SSL_METHOD
*method
= TLS_method();
950 const SSL_METHOD
*method
= SSLv23_method();
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
));
956 if (!clientRequestedCiphers
.empty())
957 clientRequestedCiphers
.append(":");
958 clientRequestedCiphers
.append(c
->name
);
960 unknownCiphers
= true;
963 debugs(83, 7, "Ciphers requested by client: " << clientRequestedCiphers
);
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)
972 debugs(83, 7, "SSL compression methods number: " << static_cast<int>(compression
[0]));
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");
984 const unsigned char *ext
= pToExtensions
;
985 while (ext
+ 4 <= pToExtensions
+ extensionsLen
) {
986 const size_t extType
= (ext
[0] << 8) | ext
[1];
988 const size_t extLen
= (ext
[0] << 8) | ext
[1];
990 debugs(83, 7, "TLS Extension: " << std::hex
<< extType
<< " of size:" << extLen
);
992 if (ext
+ extLen
> pToExtensions
+ extensionsLen
) {
993 debugs(83, 2, "Extension " << std::hex
<< extType
<< " length parser error");
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;
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
);
1026 extensions
.push_back(extType
);
1035 Ssl::Bio::sslFeatures::parseV23Hello(const unsigned char *hello
, size_t size
)
1037 debugs(83, 7, "Get fake features from v23 ClientHello message.");
1041 // Get the SSL/TLS version supported by client
1042 sslVersion
= (hello
[3] << 8) | hello
[4];
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;
1048 if (size
< ciphersLen
+ 11)
1052 #if (OPENSSL_VERSION_NUMBER >= 0x10100000L)
1053 const SSL_METHOD
*method
= TLS_method();
1055 const SSL_METHOD
*method
= SSLv23_method();
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)
1064 const SSL_CIPHER
*c
= method
->get_cipher_by_char((ciphers
+ i
+ 1));
1066 if (!clientRequestedCiphers
.empty())
1067 clientRequestedCiphers
.append(":");
1068 clientRequestedCiphers
.append(c
->name
);
1072 debugs(83, 7, "Ciphers requested by client: " << clientRequestedCiphers
);
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
);
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
1089 Ssl::Bio::sslFeatures::applyToSSL(SSL
*ssl
, Ssl::BumpMode bumpMode
) const
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());
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
);
1110 #if defined(TLSEXT_STATUSTYPE_ocsp)
1111 if (tlsStatusRequest
)
1112 SSL_set_tlsext_status_type(ssl
, TLSEXT_STATUSTYPE_ocsp
);
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());
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
));
1128 Ssl::Bio::sslFeatures::print(std::ostream
&os
) const
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();
1139 #endif /* USE_SSL */