xref: /haiku/src/kits/network/libnetapi/SecureSocket.cpp (revision 445d4fd926c569e7b9ae28017da86280aaecbae2)
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.
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 
119 BSecureSocket::Private::Private()
120 	:
121 	fSSL(NULL),
122 	fBIO(BIO_new(BIO_s_socket()))
123 {
124 }
125 
126 
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
141 BSecureSocket::Private::InitCheck()
142 {
143 	if (fBIO == NULL)
144 		return B_NO_MEMORY;
145 	return B_OK;
146 }
147 
148 
149 status_t
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*
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
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
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
296 BSecureSocket::Private::_CreateContext()
297 {
298 	// We want SSL to report errors in human readable format.
299 	SSL_load_error_strings();
300 
301 	// "SSLv23" means "any SSL or TLS version". We disable SSL v2 and v3 below
302 	// to keep only TLS 1.0 and above.
303 	sContext = SSL_CTX_new(SSLv23_method());
304 
305 #if TRACE_SSL
306 	// For debugging purposes: get all SSL messages to the standard error.
307 	SSL_CTX_set_info_callback(sContext, apps_ssl_info_callback);
308 #endif
309 
310 	// Disable legacy protocols. They have known vulnerabilities.
311 	SSL_CTX_set_options(sContext, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
312 
313 	// Disable SSL/TLS compression to prevent the CRIME attack.
314 	SSL_CTX_set_options(sContext, SSL_OP_NO_COMPRESSION);
315 
316 	// Don't bother us with ERROR_WANT_READ.
317 	SSL_CTX_set_mode(sContext, SSL_MODE_AUTO_RETRY);
318 
319 	// Setup cipher suites.
320 	// Only accept reasonably secure ones ("HIGH") and disable some known
321 	// broken stuff (https://wiki.openssl.org/index.php/SSL/TLS_Client)
322 	SSL_CTX_set_cipher_list(sContext, "HIGH:!aNULL:!PSK:!SRP:!MD5:!RC4");
323 
324 	// Setup certificate verification
325 	SSL_CTX_set_default_verify_file(sContext);
326 
327 	// OpenSSL 1.0.2 and later: use the alternate "trusted first" algorithm to
328 	// validate certificate chains. This makes the validation stop as soon as a
329 	// recognized certificate is found in the chain, instead of validating the
330 	// whole chain, then seeing if the root certificate is known.
331 #ifdef X509_V_FLAG_TRUSTED_FIRST
332 	X509_VERIFY_PARAM* verifyParam = X509_VERIFY_PARAM_new();
333 	X509_VERIFY_PARAM_set_flags(verifyParam, X509_V_FLAG_TRUSTED_FIRST);
334 	SSL_CTX_set1_param(sContext, verifyParam);
335 
336 	// TODO we need to free this after freeing the SSL context (which we
337 	// currently never do)
338 	// X509_VERIFY_PARAM_free(verifyParam);
339 #endif
340 
341 	// Get an unique index number for storing application data in SSL
342 	// structs. We will store a pointer to the BSecureSocket class there.
343 	sDataIndex = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL);
344 
345 #ifdef TRACE_SESSION_KEY
346 	FILE *keylog = NULL;
347 	const char *logpath = getenv("SSLKEYLOGFILE");
348 	if (logpath)
349 		keylog = fopen(logpath, "w+");
350 	if (keylog) {
351 		fprintf(keylog, "# Key Log File generated by Haiku Network Kit\n");
352 		sKeyLogBIO = BIO_new_fp(keylog, BIO_NOCLOSE);
353 	}
354 #endif
355 }
356 
357 
358 // # pragma mark - BSecureSocket
359 
360 
361 BSecureSocket::BSecureSocket()
362 	:
363 	fPrivate(new(std::nothrow) BSecureSocket::Private())
364 {
365 	fInitStatus = fPrivate != NULL ? fPrivate->InitCheck() : B_NO_MEMORY;
366 }
367 
368 
369 BSecureSocket::BSecureSocket(const BNetworkAddress& peer, bigtime_t timeout)
370 	:
371 	fPrivate(new(std::nothrow) BSecureSocket::Private())
372 {
373 	fInitStatus = fPrivate != NULL ? fPrivate->InitCheck() : B_NO_MEMORY;
374 	Connect(peer, timeout);
375 }
376 
377 
378 BSecureSocket::BSecureSocket(const BSecureSocket& other)
379 	:
380 	BSocket(other)
381 {
382 	fPrivate = new(std::nothrow) BSecureSocket::Private(*other.fPrivate);
383 		// TODO: this won't work this way! - write working copy constructor for
384 		// Private.
385 
386 	if (fPrivate != NULL)
387 		SSL_set_ex_data(fPrivate->fSSL, Private::sDataIndex, this);
388 	else
389 		fInitStatus = B_NO_MEMORY;
390 
391 }
392 
393 
394 BSecureSocket::~BSecureSocket()
395 {
396 	delete fPrivate;
397 }
398 
399 
400 status_t
401 BSecureSocket::Accept(BAbstractSocket*& _socket)
402 {
403 	int fd = -1;
404 	BNetworkAddress peer;
405 	status_t error = AcceptNext(fd, peer);
406 	if (error != B_OK)
407 		return error;
408 	BSecureSocket* socket = new(std::nothrow) BSecureSocket();
409 	ObjectDeleter<BSecureSocket> socketDeleter(socket);
410 	if (socket == NULL || socket->InitCheck() != B_OK) {
411 		close(fd);
412 		return B_NO_MEMORY;
413 	}
414 
415 	socket->_SetTo(fd, fLocal, peer);
416 	error = socket->_SetupAccept();
417 	if (error != B_OK)
418 		return error;
419 
420 	_socket = socket;
421 	socketDeleter.Detach();
422 
423 	return B_OK;
424 }
425 
426 
427 status_t
428 BSecureSocket::Connect(const BNetworkAddress& peer, bigtime_t timeout)
429 {
430 	status_t status = InitCheck();
431 	if (status != B_OK)
432 		return status;
433 
434 	status = BSocket::Connect(peer, timeout);
435 	if (status != B_OK)
436 		return status;
437 
438 	return _SetupConnect(peer.HostName().String());
439 }
440 
441 
442 void
443 BSecureSocket::Disconnect()
444 {
445 	if (IsConnected()) {
446 		if (fPrivate->fSSL != NULL)
447 			SSL_shutdown(fPrivate->fSSL);
448 
449 		BSocket::Disconnect();
450 	}
451 }
452 
453 
454 status_t
455 BSecureSocket::WaitForReadable(bigtime_t timeout) const
456 {
457 	if (fInitStatus != B_OK)
458 		return fInitStatus;
459 	if (!IsConnected())
460 		return B_ERROR;
461 
462 	if (SSL_pending(fPrivate->fSSL) > 0)
463 		return B_OK;
464 
465 	return BSocket::WaitForReadable(timeout);
466 }
467 
468 
469 status_t
470 BSecureSocket::InitCheck()
471 {
472 	if (fPrivate == NULL)
473 		return B_NO_MEMORY;
474 
475 	status_t state = fPrivate->InitCheck();
476 	return state;
477 }
478 
479 
480 bool
481 BSecureSocket::CertificateVerificationFailed(BCertificate&, const char*)
482 {
483 	return false;
484 }
485 
486 
487 //	#pragma mark - BDataIO implementation
488 
489 
490 ssize_t
491 BSecureSocket::Read(void* buffer, size_t size)
492 {
493 	if (!IsConnected())
494 		return B_ERROR;
495 
496 	int bytesRead;
497 	int retry;
498 	do {
499 		bytesRead = SSL_read(fPrivate->fSSL, buffer, size);
500 		if (bytesRead > 0)
501 			return bytesRead;
502 
503 		if (errno != EINTR) {
504 			// Don't retry in cases of "no data available" for non-blocking
505 			// sockets.
506 			int error = SSL_get_error(fPrivate->fSSL, bytesRead);
507 			if (error == SSL_ERROR_WANT_READ || error == SSL_ERROR_WANT_WRITE)
508 				return B_WOULD_BLOCK;
509 		}
510 
511 		// See if the error was retryable. We may have been interrupted by
512 		// a signal, in which case we will retry. But it is also possible that
513 		// another error has occurred which is not retryable. openssl will
514 		// decide for us here.
515 		retry = BIO_should_retry(SSL_get_rbio(fPrivate->fSSL));
516 	} while (retry != 0);
517 
518 	return fPrivate->ErrorCode(bytesRead);
519 }
520 
521 
522 ssize_t
523 BSecureSocket::Write(const void* buffer, size_t size)
524 {
525 	if (!IsConnected())
526 		return B_ERROR;
527 
528 	int bytesWritten;
529 	int retry;
530 	do {
531 		bytesWritten = SSL_write(fPrivate->fSSL, buffer, size);
532 		if (bytesWritten >= 0)
533 			return bytesWritten;
534 
535 		if (errno != EINTR) {
536 			// Don't retry in cases of "no buffer space available" for
537 			// non-blocking sockets.
538 			int error = SSL_get_error(fPrivate->fSSL, bytesWritten);
539 			if (error == SSL_ERROR_WANT_READ || error == SSL_ERROR_WANT_WRITE)
540 				return B_WOULD_BLOCK;
541 		}
542 
543 		// See if the error was retryable. We may have been interrupted by
544 		// a signal, in which case we will retry. But it is also possible that
545 		// another error has occurred which is not retryable. openssl will
546 		// decide for us here.
547 		retry = BIO_should_retry(SSL_get_wbio(fPrivate->fSSL));
548 	} while (retry != 0);
549 
550 	return fPrivate->ErrorCode(bytesWritten);
551 }
552 
553 
554 status_t
555 BSecureSocket::_SetupCommon(const char* host)
556 {
557 	// Do this only after BSocket::Connect has checked wether we're already
558 	// connected. We don't want to kill an existing SSL session, as that would
559 	// likely crash the protocol loop for it.
560 	if (fPrivate->fSSL != NULL) {
561 		SSL_free(fPrivate->fSSL);
562 	}
563 
564 	fPrivate->fSSL = SSL_new(BSecureSocket::Private::Context());
565 	if (fPrivate->fSSL == NULL) {
566 		BSocket::Disconnect();
567 		return B_NO_MEMORY;
568 	}
569 
570 	BIO_set_fd(fPrivate->fBIO, fSocket, BIO_NOCLOSE);
571 	SSL_set_bio(fPrivate->fSSL, fPrivate->fBIO, fPrivate->fBIO);
572 	SSL_set_ex_data(fPrivate->fSSL, Private::sDataIndex, this);
573 	if (host != NULL && host[0] != '\0') {
574 		SSL_set_tlsext_host_name(fPrivate->fSSL, host);
575 		X509_VERIFY_PARAM_set1_host(SSL_get0_param(fPrivate->fSSL), host, 0);
576 	}
577 
578 	return B_OK;
579 }
580 
581 
582 status_t
583 BSecureSocket::_SetupConnect(const char* host)
584 {
585 	status_t error = _SetupCommon(host);
586 	if (error != B_OK)
587 		return error;
588 
589 	int returnValue = SSL_connect(fPrivate->fSSL);
590 	if (returnValue <= 0) {
591 		TRACE("SSLConnection can't connect\n");
592 		BSocket::Disconnect();
593 		return fPrivate->ErrorCode(returnValue);
594 	}
595 
596 #ifdef TRACE_SESSION_KEY
597 	fprintf(stderr, "SSL SESSION INFO:\n");
598 	//SSL_SESSION_print_fp(stderr, SSL_get_session(fPrivate->fSSL));
599 	SSL_SESSION_print_keylog(fPrivate->sKeyLogBIO, SSL_get_session(fPrivate->fSSL));
600 	SSL_SESSION_print_client_random(fPrivate->sKeyLogBIO, fPrivate->fSSL);
601 	fprintf(stderr, "\n");
602 #endif
603 
604 	return B_OK;
605 }
606 
607 
608 status_t
609 BSecureSocket::_SetupAccept()
610 {
611 	status_t error = _SetupCommon();
612 	if (error != B_OK)
613 		return error;
614 
615 	int returnValue = SSL_accept(fPrivate->fSSL);
616 	if (returnValue <= 0) {
617 		TRACE("SSLConnection can't accept\n");
618 		BSocket::Disconnect();
619 		return fPrivate->ErrorCode(returnValue);
620 	}
621 
622 	return B_OK;
623 }
624 
625 
626 #else	// OPENSSL_ENABLED
627 
628 
629 // #pragma mark - No-SSL stubs
630 
631 
632 BSecureSocket::BSecureSocket()
633 {
634 }
635 
636 
637 BSecureSocket::BSecureSocket(const BNetworkAddress& peer, bigtime_t timeout)
638 {
639 	fInitStatus = B_UNSUPPORTED;
640 }
641 
642 
643 BSecureSocket::BSecureSocket(const BSecureSocket& other)
644 	:
645 	BSocket(other)
646 {
647 }
648 
649 
650 BSecureSocket::~BSecureSocket()
651 {
652 }
653 
654 
655 bool
656 BSecureSocket::CertificateVerificationFailed(BCertificate& certificate, const char*)
657 {
658 	(void)certificate;
659 	return false;
660 }
661 
662 
663 status_t
664 BSecureSocket::Accept(BAbstractSocket*& _socket)
665 {
666 	return B_UNSUPPORTED;
667 }
668 
669 
670 status_t
671 BSecureSocket::Connect(const BNetworkAddress& peer, bigtime_t timeout)
672 {
673 	return fInitStatus = B_UNSUPPORTED;
674 }
675 
676 
677 void
678 BSecureSocket::Disconnect()
679 {
680 }
681 
682 
683 status_t
684 BSecureSocket::WaitForReadable(bigtime_t timeout) const
685 {
686 	return B_UNSUPPORTED;
687 }
688 
689 
690 //	#pragma mark - BDataIO implementation
691 
692 
693 ssize_t
694 BSecureSocket::Read(void* buffer, size_t size)
695 {
696 	return B_UNSUPPORTED;
697 }
698 
699 
700 ssize_t
701 BSecureSocket::Write(const void* buffer, size_t size)
702 {
703 	return B_UNSUPPORTED;
704 }
705 
706 
707 status_t
708 BSecureSocket::InitCheck()
709 {
710 	return B_UNSUPPORTED;
711 }
712 
713 
714 status_t
715 BSecureSocket::_SetupCommon(const char* host)
716 {
717 	return B_UNSUPPORTED;
718 }
719 
720 
721 status_t
722 BSecureSocket::_SetupConnect(const char* host)
723 {
724 	return B_UNSUPPORTED;
725 }
726 
727 
728 status_t
729 BSecureSocket::_SetupAccept()
730 {
731 	return B_UNSUPPORTED;
732 }
733 
734 
735 #endif	// !OPENSSL_ENABLED
736