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.
45int 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);
72err:
73	return (0);
74}
75
76
77#endif /* TRACE_SESSION_KEY */
78
79class BSecureSocket::Private {
80public:
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
90private:
91	static	void				_CreateContext();
92
93public:
94			SSL*				fSSL;
95			BIO*				fBIO;
96	static	int					sDataIndex;
97
98private:
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
103public:
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
119BSecureSocket::Private::Private()
120	:
121	fSSL(NULL),
122	fBIO(BIO_new(BIO_s_socket()))
123{
124}
125
126
127BSecureSocket::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
140status_t
141BSecureSocket::Private::InitCheck()
142{
143	if (fBIO == NULL)
144		return B_NO_MEMORY;
145	return B_OK;
146}
147
148
149status_t
150BSecureSocket::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*
206BSecureSocket::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
221BSecureSocket::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
258static 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
296BSecureSocket::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
361BSecureSocket::BSecureSocket()
362	:
363	fPrivate(new(std::nothrow) BSecureSocket::Private())
364{
365	fInitStatus = fPrivate != NULL ? fPrivate->InitCheck() : B_NO_MEMORY;
366}
367
368
369BSecureSocket::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
378BSecureSocket::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
394BSecureSocket::~BSecureSocket()
395{
396	delete fPrivate;
397}
398
399
400status_t
401BSecureSocket::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
427status_t
428BSecureSocket::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
442void
443BSecureSocket::Disconnect()
444{
445	if (IsConnected()) {
446		if (fPrivate->fSSL != NULL)
447			SSL_shutdown(fPrivate->fSSL);
448
449		BSocket::Disconnect();
450	}
451}
452
453
454status_t
455BSecureSocket::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
469status_t
470BSecureSocket::InitCheck()
471{
472	if (fPrivate == NULL)
473		return B_NO_MEMORY;
474
475	status_t state = fPrivate->InitCheck();
476	return state;
477}
478
479
480bool
481BSecureSocket::CertificateVerificationFailed(BCertificate&, const char*)
482{
483	return false;
484}
485
486
487//	#pragma mark - BDataIO implementation
488
489
490ssize_t
491BSecureSocket::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
522ssize_t
523BSecureSocket::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
554status_t
555BSecureSocket::_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
582status_t
583BSecureSocket::_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
608status_t
609BSecureSocket::_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
632BSecureSocket::BSecureSocket()
633{
634}
635
636
637BSecureSocket::BSecureSocket(const BNetworkAddress& peer, bigtime_t timeout)
638{
639	fInitStatus = B_UNSUPPORTED;
640}
641
642
643BSecureSocket::BSecureSocket(const BSecureSocket& other)
644	:
645	BSocket(other)
646{
647}
648
649
650BSecureSocket::~BSecureSocket()
651{
652}
653
654
655bool
656BSecureSocket::CertificateVerificationFailed(BCertificate& certificate, const char*)
657{
658	(void)certificate;
659	return false;
660}
661
662
663status_t
664BSecureSocket::Accept(BAbstractSocket*& _socket)
665{
666	return B_UNSUPPORTED;
667}
668
669
670status_t
671BSecureSocket::Connect(const BNetworkAddress& peer, bigtime_t timeout)
672{
673	return fInitStatus = B_UNSUPPORTED;
674}
675
676
677void
678BSecureSocket::Disconnect()
679{
680}
681
682
683status_t
684BSecureSocket::WaitForReadable(bigtime_t timeout) const
685{
686	return B_UNSUPPORTED;
687}
688
689
690//	#pragma mark - BDataIO implementation
691
692
693ssize_t
694BSecureSocket::Read(void* buffer, size_t size)
695{
696	return B_UNSUPPORTED;
697}
698
699
700ssize_t
701BSecureSocket::Write(const void* buffer, size_t size)
702{
703	return B_UNSUPPORTED;
704}
705
706
707status_t
708BSecureSocket::InitCheck()
709{
710	return B_UNSUPPORTED;
711}
712
713
714status_t
715BSecureSocket::_SetupCommon(const char* host)
716{
717	return B_UNSUPPORTED;
718}
719
720
721status_t
722BSecureSocket::_SetupConnect(const char* host)
723{
724	return B_UNSUPPORTED;
725}
726
727
728status_t
729BSecureSocket::_SetupAccept()
730{
731	return B_UNSUPPORTED;
732}
733
734
735#endif	// !OPENSSL_ENABLED
736