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