1 /*
2 * Copyright 2013-2016 Haiku, Inc.
3 * Copyright 2011-2015, Axel Dörfler, axeld@pinc-software.de.
4 * Copyright 2016, Rene Gollent, rene@gollent.com.
5 * Copyright 2010, Clemens Zeidler <haiku@clemens-zeidler.de>
6 * Distributed under the terms of the MIT License.
7 */
8
9
10 #include <SecureSocket.h>
11
12 #ifdef OPENSSL_ENABLED
13 # include <openssl/ssl.h>
14 # include <openssl/ssl3.h> // for TRACE_SESSION_KEY only
15 # include <openssl/err.h>
16 #endif
17
18 #include <pthread.h>
19
20 #include <Certificate.h>
21 #include <FindDirectory.h>
22 #include <Path.h>
23
24 #include <AutoDeleter.h>
25
26 #include "CertificatePrivate.h"
27
28
29 //#define TRACE_SOCKET
30 #ifdef TRACE_SOCKET
31 # define TRACE(x...) printf(x)
32 #else
33 # define TRACE(x...) ;
34 #endif
35
36 //#define TRACE_SESSION_KEY
37
38
39 #ifdef OPENSSL_ENABLED
40
41 #ifdef TRACE_SESSION_KEY
42
43 // print client random id and master key in NSS keylog format
44 // as session ID is not enough.
SSL_SESSION_print_client_random(BIO * bp,const SSL * ssl)45 int SSL_SESSION_print_client_random(BIO *bp, const SSL *ssl)
46 {
47 const SSL_SESSION *x = SSL_get_session(ssl);
48 size_t i;
49
50 if (x == NULL)
51 goto err;
52 if (x->session_id_length == 0 || x->master_key_length == 0)
53 goto err;
54
55 if (BIO_puts(bp, "CLIENT_RANDOM ") <= 0)
56 goto err;
57
58 for (i = 0; i < sizeof(ssl->s3->client_random); i++) {
59 if (BIO_printf(bp, "%02X", ssl->s3->client_random[i]) <= 0)
60 goto err;
61 }
62 if (BIO_puts(bp, " ") <= 0)
63 goto err;
64 for (i = 0; i < (size_t)x->master_key_length; i++) {
65 if (BIO_printf(bp, "%02X", x->master_key[i]) <= 0)
66 goto err;
67 }
68 if (BIO_puts(bp, "\n") <= 0)
69 goto err;
70
71 return (1);
72 err:
73 return (0);
74 }
75
76
77 #endif /* TRACE_SESSION_KEY */
78
79 class BSecureSocket::Private {
80 public:
81 Private();
82 ~Private();
83
84 status_t InitCheck();
85 status_t ErrorCode(int returnValue);
86
87 static SSL_CTX* Context();
88 static int VerifyCallback(int ok, X509_STORE_CTX* ctx);
89
90 private:
91 static void _CreateContext();
92
93 public:
94 SSL* fSSL;
95 BIO* fBIO;
96 static int sDataIndex;
97
98 private:
99 static SSL_CTX* sContext;
100 // FIXME When do we SSL_CTX_free it?
101 static pthread_once_t sInitOnce;
102 #ifdef TRACE_SESSION_KEY
103 public:
104 static BIO* sKeyLogBIO;
105 #endif
106
107 };
108
109
110 /* static */ SSL_CTX* BSecureSocket::Private::sContext = NULL;
111 /* static */ int BSecureSocket::Private::sDataIndex;
112 /* static */ pthread_once_t BSecureSocket::Private::sInitOnce
113 = PTHREAD_ONCE_INIT;
114 #ifdef TRACE_SESSION_KEY
115 /* static */ BIO* BSecureSocket::Private::sKeyLogBIO = NULL;
116 #endif
117
118
Private()119 BSecureSocket::Private::Private()
120 :
121 fSSL(NULL),
122 fBIO(BIO_new(BIO_s_socket()))
123 {
124 }
125
126
~Private()127 BSecureSocket::Private::~Private()
128 {
129 // SSL_free also frees the underlying BIO.
130 if (fSSL != NULL)
131 SSL_free(fSSL);
132 else {
133 // The SSL session was never created (Connect() was not called or
134 // failed). We must free the BIO we created in the constructor.
135 BIO_free(fBIO);
136 }
137 }
138
139
140 status_t
InitCheck()141 BSecureSocket::Private::InitCheck()
142 {
143 if (fBIO == NULL)
144 return B_NO_MEMORY;
145 return B_OK;
146 }
147
148
149 status_t
ErrorCode(int returnValue)150 BSecureSocket::Private::ErrorCode(int returnValue)
151 {
152 int error = SSL_get_error(fSSL, returnValue);
153 switch (error) {
154 case SSL_ERROR_NONE:
155 // Shouldn't happen...
156 return B_NO_ERROR;
157 case SSL_ERROR_ZERO_RETURN:
158 // Socket is closed
159 return B_IO_ERROR;
160 case SSL_ERROR_SSL:
161 // Probably no certificate
162 return B_NOT_ALLOWED;
163
164 case SSL_ERROR_SYSCALL:
165 {
166 unsigned long error2;
167 // Check for extra errors in the error stack...
168 for (;;) {
169 error2 = ERR_get_error();
170 if (error2 == 0)
171 break;
172 fprintf(stderr, "SSL ERR %s\n", ERR_error_string(error2, NULL));
173 }
174
175 if (returnValue == 0)
176 {
177 // unexpected EOF, the remote host closed the socket without
178 // telling us why.
179 return ECONNREFUSED;
180 }
181
182 if (returnValue == -1)
183 {
184 fprintf(stderr, "SSL rv -1 %s\n", ERR_error_string(error, NULL));
185 return errno;
186 }
187
188 fprintf(stderr, "SSL rv other %s\n", ERR_error_string(error, NULL));
189 return B_ERROR;
190 }
191
192 case SSL_ERROR_WANT_READ:
193 case SSL_ERROR_WANT_WRITE:
194 case SSL_ERROR_WANT_CONNECT:
195 case SSL_ERROR_WANT_ACCEPT:
196 case SSL_ERROR_WANT_X509_LOOKUP:
197 default:
198 // TODO: translate SSL error codes!
199 fprintf(stderr, "SSL other %s\n", ERR_error_string(error, NULL));
200 return B_ERROR;
201 }
202 }
203
204
205 /* static */ SSL_CTX*
Context()206 BSecureSocket::Private::Context()
207 {
208 // We use lazy initialisation here, because reading certificates from disk
209 // and parsing them is a relatively long operation and uses some memory.
210 // We don't want programs that don't use SSL to waste resources with that.
211 pthread_once(&sInitOnce, _CreateContext);
212
213 return sContext;
214 }
215
216
217 /*! This is called each time a certificate verification occurs. It allows us to
218 catch failures and report them.
219 */
220 /* static */ int
VerifyCallback(int ok,X509_STORE_CTX * ctx)221 BSecureSocket::Private::VerifyCallback(int ok, X509_STORE_CTX* ctx)
222 {
223 // OpenSSL already checked the certificate again the certificate store for
224 // us, and tells the result of that in the ok parameter.
225
226 // If the verification succeeded, no need for any further checks. Let's
227 // proceed with the connection.
228 if (ok)
229 return ok;
230
231 // The certificate verification failed. Signal this to the BSecureSocket.
232
233 // First of all, get the affected BSecureSocket
234 SSL* ssl = (SSL*)X509_STORE_CTX_get_ex_data(ctx,
235 SSL_get_ex_data_X509_STORE_CTX_idx());
236 BSecureSocket* socket = (BSecureSocket*)SSL_get_ex_data(ssl, sDataIndex);
237
238 // Get the certificate that we could not validate (this may not be the one
239 // we got from the server, but something higher up in the certificate
240 // chain)
241 X509* x509 = X509_STORE_CTX_get_current_cert(ctx);
242 BCertificate::Private* certificate
243 = new(std::nothrow) BCertificate::Private(x509);
244
245 if (certificate == NULL)
246 return 0;
247
248 int error = X509_STORE_CTX_get_error(ctx);
249 const char* message = X509_verify_cert_error_string(error);
250
251 // Let the BSecureSocket (or subclass) decide if we should continue anyway.
252 BCertificate failedCertificate(certificate);
253 return socket->CertificateVerificationFailed(failedCertificate, message);
254 }
255
256
257 #if TRACE_SSL
apps_ssl_info_callback(const SSL * s,int where,int ret)258 static void apps_ssl_info_callback(const SSL *s, int where, int ret)
259 {
260 const char *str;
261 int w;
262
263 w=where& ~SSL_ST_MASK;
264
265 if (w & SSL_ST_CONNECT)
266 str="SSL_connect";
267 else if (w & SSL_ST_ACCEPT)
268 str="SSL_accept";
269 else
270 str="undefined";
271
272 if (where & SSL_CB_LOOP) {
273 fprintf(stderr, "%s:%s\n", str, SSL_state_string_long(s));
274 } else if (where & SSL_CB_ALERT) {
275 str = (where & SSL_CB_READ) ? "read" : "write";
276 fprintf(stderr, "SSL3 alert %s:%s:%s\n",
277 str,
278 SSL_alert_type_string_long(ret),
279 SSL_alert_desc_string_long(ret));
280 } else if (where & SSL_CB_EXIT) {
281 if (ret == 0)
282 fprintf(stderr, "%s:failed in %s\n",
283 str, SSL_state_string_long(s));
284 else if (ret < 0) {
285 fprintf(stderr, "%s:error in %s\n",
286 str, SSL_state_string_long(s));
287 }
288 }
289 }
290
291
292 #endif
293
294
295 /* static */ void
_CreateContext()296 BSecureSocket::Private::_CreateContext()
297 {
298 // "SSLv23" means "any SSL or TLS version". We disable SSL v2 and v3 below
299 // to keep only TLS 1.0 and above.
300 sContext = SSL_CTX_new(SSLv23_method());
301
302 #if TRACE_SSL
303 // For debugging purposes: get all SSL messages to the standard error.
304 SSL_CTX_set_info_callback(sContext, apps_ssl_info_callback);
305 #endif
306
307 // Disable legacy protocols. They have known vulnerabilities.
308 SSL_CTX_set_options(sContext, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
309
310 // Disable SSL/TLS compression to prevent the CRIME attack.
311 SSL_CTX_set_options(sContext, SSL_OP_NO_COMPRESSION);
312
313 // Don't bother us with ERROR_WANT_READ.
314 SSL_CTX_set_mode(sContext, SSL_MODE_AUTO_RETRY);
315
316 // Setup cipher suites.
317 // Only accept reasonably secure ones ("HIGH") and disable some known
318 // broken stuff (https://wiki.openssl.org/index.php/SSL/TLS_Client)
319 SSL_CTX_set_cipher_list(sContext, "HIGH:!aNULL:!PSK:!SRP:!MD5:!RC4");
320
321 // Setup certificate verification
322 SSL_CTX_set_default_verify_file(sContext);
323
324 // OpenSSL 1.0.2 and later: use the alternate "trusted first" algorithm to
325 // validate certificate chains. This makes the validation stop as soon as a
326 // recognized certificate is found in the chain, instead of validating the
327 // whole chain, then seeing if the root certificate is known.
328 #ifdef X509_V_FLAG_TRUSTED_FIRST
329 X509_VERIFY_PARAM* verifyParam = X509_VERIFY_PARAM_new();
330 X509_VERIFY_PARAM_set_flags(verifyParam, X509_V_FLAG_TRUSTED_FIRST);
331 SSL_CTX_set1_param(sContext, verifyParam);
332
333 // TODO we need to free this after freeing the SSL context (which we
334 // currently never do)
335 // X509_VERIFY_PARAM_free(verifyParam);
336 #endif
337
338 // Get an unique index number for storing application data in SSL
339 // structs. We will store a pointer to the BSecureSocket class there.
340 sDataIndex = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL);
341
342 #ifdef TRACE_SESSION_KEY
343 FILE *keylog = NULL;
344 const char *logpath = getenv("SSLKEYLOGFILE");
345 if (logpath)
346 keylog = fopen(logpath, "w+");
347 if (keylog) {
348 fprintf(keylog, "# Key Log File generated by Haiku Network Kit\n");
349 sKeyLogBIO = BIO_new_fp(keylog, BIO_NOCLOSE);
350 }
351 #endif
352 }
353
354
355 // # pragma mark - BSecureSocket
356
357
BSecureSocket()358 BSecureSocket::BSecureSocket()
359 :
360 fPrivate(new(std::nothrow) BSecureSocket::Private())
361 {
362 fInitStatus = fPrivate != NULL ? fPrivate->InitCheck() : B_NO_MEMORY;
363 }
364
365
BSecureSocket(const BNetworkAddress & peer,bigtime_t timeout)366 BSecureSocket::BSecureSocket(const BNetworkAddress& peer, bigtime_t timeout)
367 :
368 fPrivate(new(std::nothrow) BSecureSocket::Private())
369 {
370 fInitStatus = fPrivate != NULL ? fPrivate->InitCheck() : B_NO_MEMORY;
371 Connect(peer, timeout);
372 }
373
374
BSecureSocket(const BSecureSocket & other)375 BSecureSocket::BSecureSocket(const BSecureSocket& other)
376 :
377 BSocket(other)
378 {
379 fPrivate = new(std::nothrow) BSecureSocket::Private(*other.fPrivate);
380 // TODO: this won't work this way! - write working copy constructor for
381 // Private.
382
383 if (fPrivate != NULL)
384 SSL_set_ex_data(fPrivate->fSSL, Private::sDataIndex, this);
385 else
386 fInitStatus = B_NO_MEMORY;
387
388 }
389
390
~BSecureSocket()391 BSecureSocket::~BSecureSocket()
392 {
393 delete fPrivate;
394 }
395
396
397 status_t
Accept(BAbstractSocket * & _socket)398 BSecureSocket::Accept(BAbstractSocket*& _socket)
399 {
400 int fd = -1;
401 BNetworkAddress peer;
402 status_t error = AcceptNext(fd, peer);
403 if (error != B_OK)
404 return error;
405 BSecureSocket* socket = new(std::nothrow) BSecureSocket();
406 ObjectDeleter<BSecureSocket> socketDeleter(socket);
407 if (socket == NULL || socket->InitCheck() != B_OK) {
408 close(fd);
409 return B_NO_MEMORY;
410 }
411
412 socket->_SetTo(fd, fLocal, peer);
413 error = socket->_SetupAccept();
414 if (error != B_OK)
415 return error;
416
417 _socket = socket;
418 socketDeleter.Detach();
419
420 return B_OK;
421 }
422
423
424 status_t
Connect(const BNetworkAddress & peer,bigtime_t timeout)425 BSecureSocket::Connect(const BNetworkAddress& peer, bigtime_t timeout)
426 {
427 status_t status = InitCheck();
428 if (status != B_OK)
429 return status;
430
431 status = BSocket::Connect(peer, timeout);
432 if (status != B_OK)
433 return status;
434
435 return _SetupConnect(peer.HostName().String());
436 }
437
438
439 void
Disconnect()440 BSecureSocket::Disconnect()
441 {
442 if (IsConnected()) {
443 if (fPrivate->fSSL != NULL)
444 SSL_shutdown(fPrivate->fSSL);
445
446 BSocket::Disconnect();
447 }
448 }
449
450
451 status_t
WaitForReadable(bigtime_t timeout) const452 BSecureSocket::WaitForReadable(bigtime_t timeout) const
453 {
454 if (fInitStatus != B_OK)
455 return fInitStatus;
456 if (!IsConnected())
457 return B_ERROR;
458
459 if (SSL_pending(fPrivate->fSSL) > 0)
460 return B_OK;
461
462 return BSocket::WaitForReadable(timeout);
463 }
464
465
466 status_t
InitCheck()467 BSecureSocket::InitCheck()
468 {
469 if (fPrivate == NULL)
470 return B_NO_MEMORY;
471
472 status_t state = fPrivate->InitCheck();
473 return state;
474 }
475
476
477 bool
CertificateVerificationFailed(BCertificate &,const char *)478 BSecureSocket::CertificateVerificationFailed(BCertificate&, const char*)
479 {
480 return false;
481 }
482
483
484 // #pragma mark - BDataIO implementation
485
486
487 ssize_t
Read(void * buffer,size_t size)488 BSecureSocket::Read(void* buffer, size_t size)
489 {
490 if (!IsConnected())
491 return B_ERROR;
492
493 int bytesRead;
494 int retry;
495 do {
496 bytesRead = SSL_read(fPrivate->fSSL, buffer, size);
497 if (bytesRead > 0)
498 return bytesRead;
499
500 if (errno != EINTR) {
501 // Don't retry in cases of "no data available" for non-blocking
502 // sockets.
503 int error = SSL_get_error(fPrivate->fSSL, bytesRead);
504 if (error == SSL_ERROR_WANT_READ || error == SSL_ERROR_WANT_WRITE)
505 return B_WOULD_BLOCK;
506 }
507
508 // See if the error was retryable. We may have been interrupted by
509 // a signal, in which case we will retry. But it is also possible that
510 // another error has occurred which is not retryable. openssl will
511 // decide for us here.
512 retry = BIO_should_retry(SSL_get_rbio(fPrivate->fSSL));
513 } while (retry != 0);
514
515 return fPrivate->ErrorCode(bytesRead);
516 }
517
518
519 ssize_t
Write(const void * buffer,size_t size)520 BSecureSocket::Write(const void* buffer, size_t size)
521 {
522 if (!IsConnected())
523 return B_ERROR;
524
525 int bytesWritten;
526 int retry;
527 do {
528 bytesWritten = SSL_write(fPrivate->fSSL, buffer, size);
529 if (bytesWritten >= 0)
530 return bytesWritten;
531
532 if (errno != EINTR) {
533 // Don't retry in cases of "no buffer space available" for
534 // non-blocking sockets.
535 int error = SSL_get_error(fPrivate->fSSL, bytesWritten);
536 if (error == SSL_ERROR_WANT_READ || error == SSL_ERROR_WANT_WRITE)
537 return B_WOULD_BLOCK;
538 }
539
540 // See if the error was retryable. We may have been interrupted by
541 // a signal, in which case we will retry. But it is also possible that
542 // another error has occurred which is not retryable. openssl will
543 // decide for us here.
544 retry = BIO_should_retry(SSL_get_wbio(fPrivate->fSSL));
545 } while (retry != 0);
546
547 return fPrivate->ErrorCode(bytesWritten);
548 }
549
550
551 status_t
_SetupCommon(const char * host)552 BSecureSocket::_SetupCommon(const char* host)
553 {
554 // Do this only after BSocket::Connect has checked wether we're already
555 // connected. We don't want to kill an existing SSL session, as that would
556 // likely crash the protocol loop for it.
557 if (fPrivate->fSSL != NULL) {
558 SSL_free(fPrivate->fSSL);
559 }
560
561 fPrivate->fSSL = SSL_new(BSecureSocket::Private::Context());
562 if (fPrivate->fSSL == NULL) {
563 BSocket::Disconnect();
564 return B_NO_MEMORY;
565 }
566
567 BIO_set_fd(fPrivate->fBIO, fSocket, BIO_NOCLOSE);
568 SSL_set_bio(fPrivate->fSSL, fPrivate->fBIO, fPrivate->fBIO);
569 SSL_set_ex_data(fPrivate->fSSL, Private::sDataIndex, this);
570 if (host != NULL && host[0] != '\0') {
571 SSL_set_tlsext_host_name(fPrivate->fSSL, host);
572 X509_VERIFY_PARAM_set1_host(SSL_get0_param(fPrivate->fSSL), host, 0);
573 }
574
575 return B_OK;
576 }
577
578
579 status_t
_SetupConnect(const char * host)580 BSecureSocket::_SetupConnect(const char* host)
581 {
582 status_t error = _SetupCommon(host);
583 if (error != B_OK)
584 return error;
585
586 int returnValue = SSL_connect(fPrivate->fSSL);
587 if (returnValue <= 0) {
588 TRACE("SSLConnection can't connect\n");
589 BSocket::Disconnect();
590 return fPrivate->ErrorCode(returnValue);
591 }
592
593 #ifdef TRACE_SESSION_KEY
594 fprintf(stderr, "SSL SESSION INFO:\n");
595 //SSL_SESSION_print_fp(stderr, SSL_get_session(fPrivate->fSSL));
596 SSL_SESSION_print_keylog(fPrivate->sKeyLogBIO, SSL_get_session(fPrivate->fSSL));
597 SSL_SESSION_print_client_random(fPrivate->sKeyLogBIO, fPrivate->fSSL);
598 fprintf(stderr, "\n");
599 #endif
600
601 return B_OK;
602 }
603
604
605 status_t
_SetupAccept()606 BSecureSocket::_SetupAccept()
607 {
608 status_t error = _SetupCommon();
609 if (error != B_OK)
610 return error;
611
612 int returnValue = SSL_accept(fPrivate->fSSL);
613 if (returnValue <= 0) {
614 TRACE("SSLConnection can't accept\n");
615 BSocket::Disconnect();
616 return fPrivate->ErrorCode(returnValue);
617 }
618
619 return B_OK;
620 }
621
622
623 #else // OPENSSL_ENABLED
624
625
626 // #pragma mark - No-SSL stubs
627
628
BSecureSocket()629 BSecureSocket::BSecureSocket()
630 {
631 }
632
633
BSecureSocket(const BNetworkAddress & peer,bigtime_t timeout)634 BSecureSocket::BSecureSocket(const BNetworkAddress& peer, bigtime_t timeout)
635 {
636 fInitStatus = B_UNSUPPORTED;
637 }
638
639
BSecureSocket(const BSecureSocket & other)640 BSecureSocket::BSecureSocket(const BSecureSocket& other)
641 :
642 BSocket(other)
643 {
644 }
645
646
~BSecureSocket()647 BSecureSocket::~BSecureSocket()
648 {
649 }
650
651
652 bool
CertificateVerificationFailed(BCertificate & certificate,const char *)653 BSecureSocket::CertificateVerificationFailed(BCertificate& certificate, const char*)
654 {
655 (void)certificate;
656 return false;
657 }
658
659
660 status_t
Accept(BAbstractSocket * & _socket)661 BSecureSocket::Accept(BAbstractSocket*& _socket)
662 {
663 return B_UNSUPPORTED;
664 }
665
666
667 status_t
Connect(const BNetworkAddress & peer,bigtime_t timeout)668 BSecureSocket::Connect(const BNetworkAddress& peer, bigtime_t timeout)
669 {
670 return fInitStatus = B_UNSUPPORTED;
671 }
672
673
674 void
Disconnect()675 BSecureSocket::Disconnect()
676 {
677 }
678
679
680 status_t
WaitForReadable(bigtime_t timeout) const681 BSecureSocket::WaitForReadable(bigtime_t timeout) const
682 {
683 return B_UNSUPPORTED;
684 }
685
686
687 // #pragma mark - BDataIO implementation
688
689
690 ssize_t
Read(void * buffer,size_t size)691 BSecureSocket::Read(void* buffer, size_t size)
692 {
693 return B_UNSUPPORTED;
694 }
695
696
697 ssize_t
Write(const void * buffer,size_t size)698 BSecureSocket::Write(const void* buffer, size_t size)
699 {
700 return B_UNSUPPORTED;
701 }
702
703
704 status_t
InitCheck()705 BSecureSocket::InitCheck()
706 {
707 return B_UNSUPPORTED;
708 }
709
710
711 status_t
_SetupCommon(const char * host)712 BSecureSocket::_SetupCommon(const char* host)
713 {
714 return B_UNSUPPORTED;
715 }
716
717
718 status_t
_SetupConnect(const char * host)719 BSecureSocket::_SetupConnect(const char* host)
720 {
721 return B_UNSUPPORTED;
722 }
723
724
725 status_t
_SetupAccept()726 BSecureSocket::_SetupAccept()
727 {
728 return B_UNSUPPORTED;
729 }
730
731
732 #endif // !OPENSSL_ENABLED
733