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