741 lines
16 KiB
C++
741 lines
16 KiB
C++
/*
|
|
* Copyright 2013-2016 Haiku, Inc.
|
|
* Copyright 2011-2015, Axel Dörfler, [email protected].
|
|
* Copyright 2016, Rene Gollent, [email protected].
|
|
* Copyright 2010, Clemens Zeidler <[email protected]>
|
|
* Distributed under the terms of the MIT License.
|
|
*/
|
|
|
|
|
|
#include <SecureSocket.h>
|
|
|
|
#ifdef OPENSSL_ENABLED
|
|
# include <openssl/ssl.h>
|
|
# include <openssl/ssl3.h> // for TRACE_SESSION_KEY only
|
|
# include <openssl/err.h>
|
|
#endif
|
|
|
|
#include <pthread.h>
|
|
|
|
#include <Certificate.h>
|
|
#include <FindDirectory.h>
|
|
#include <Path.h>
|
|
|
|
#include <AutoDeleter.h>
|
|
|
|
#include "CertificatePrivate.h"
|
|
|
|
|
|
//#define TRACE_SOCKET
|
|
#ifdef TRACE_SOCKET
|
|
# define TRACE(x...) printf(x)
|
|
#else
|
|
# define TRACE(x...) ;
|
|
#endif
|
|
|
|
//#define TRACE_SESSION_KEY
|
|
|
|
|
|
#ifdef OPENSSL_ENABLED
|
|
|
|
#ifdef TRACE_SESSION_KEY
|
|
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
|
/*
|
|
* print session id and master key in NSS keylog format (RSA
|
|
* Session-ID:<session id> Master-Key:<master key>)
|
|
*/
|
|
int SSL_SESSION_print_keylog(BIO *bp, const SSL_SESSION *x)
|
|
{
|
|
size_t i;
|
|
|
|
if (x == NULL)
|
|
goto err;
|
|
if (x->session_id_length == 0 || x->master_key_length == 0)
|
|
goto err;
|
|
|
|
/*
|
|
* the RSA prefix is required by the format's definition although there's
|
|
* nothing RSA-specific in the output, therefore, we don't have to check if
|
|
* the cipher suite is based on RSA
|
|
*/
|
|
if (BIO_puts(bp, "RSA ") <= 0)
|
|
goto err;
|
|
|
|
if (BIO_puts(bp, "Session-ID:") <= 0)
|
|
goto err;
|
|
for (i = 0; i < x->session_id_length; i++) {
|
|
if (BIO_printf(bp, "%02X", x->session_id[i]) <= 0)
|
|
goto err;
|
|
}
|
|
if (BIO_puts(bp, " Master-Key:") <= 0)
|
|
goto err;
|
|
for (i = 0; i < (size_t)x->master_key_length; i++) {
|
|
if (BIO_printf(bp, "%02X", x->master_key[i]) <= 0)
|
|
goto err;
|
|
}
|
|
if (BIO_puts(bp, "\n") <= 0)
|
|
goto err;
|
|
|
|
return (1);
|
|
err:
|
|
return (0);
|
|
}
|
|
#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
|
|
/*
|
|
* print client random id and master key in NSS keylog format
|
|
* as session ID is not enough.
|
|
*/
|
|
int SSL_SESSION_print_client_random(BIO *bp, const SSL *ssl)
|
|
{
|
|
const SSL_SESSION *x = SSL_get_session(ssl);
|
|
size_t i;
|
|
|
|
if (x == NULL)
|
|
goto err;
|
|
if (x->session_id_length == 0 || x->master_key_length == 0)
|
|
goto err;
|
|
|
|
/*
|
|
* the RSA prefix is required by the format's definition although there's
|
|
* nothing RSA-specific in the output, therefore, we don't have to check if
|
|
* the cipher suite is based on RSA
|
|
*/
|
|
if (BIO_puts(bp, "CLIENT_RANDOM ") <= 0)
|
|
goto err;
|
|
|
|
for (i = 0; i < sizeof(ssl->s3->client_random); i++) {
|
|
if (BIO_printf(bp, "%02X", ssl->s3->client_random[i]) <= 0)
|
|
goto err;
|
|
}
|
|
if (BIO_puts(bp, " ") <= 0)
|
|
goto err;
|
|
for (i = 0; i < (size_t)x->master_key_length; i++) {
|
|
if (BIO_printf(bp, "%02X", x->master_key[i]) <= 0)
|
|
goto err;
|
|
}
|
|
if (BIO_puts(bp, "\n") <= 0)
|
|
goto err;
|
|
|
|
return (1);
|
|
err:
|
|
return (0);
|
|
}
|
|
#endif /* TRACE_SESSION_KEY */
|
|
|
|
class BSecureSocket::Private {
|
|
public:
|
|
Private();
|
|
~Private();
|
|
|
|
status_t InitCheck();
|
|
status_t ErrorCode(int returnValue);
|
|
|
|
static SSL_CTX* Context();
|
|
static int VerifyCallback(int ok, X509_STORE_CTX* ctx);
|
|
|
|
private:
|
|
static void _CreateContext();
|
|
|
|
public:
|
|
SSL* fSSL;
|
|
BIO* fBIO;
|
|
static int sDataIndex;
|
|
|
|
private:
|
|
static SSL_CTX* sContext;
|
|
// FIXME When do we SSL_CTX_free it?
|
|
static pthread_once_t sInitOnce;
|
|
#ifdef TRACE_SESSION_KEY
|
|
public:
|
|
static BIO* sKeyLogBIO;
|
|
#endif
|
|
|
|
};
|
|
|
|
|
|
/* static */ SSL_CTX* BSecureSocket::Private::sContext = NULL;
|
|
/* static */ int BSecureSocket::Private::sDataIndex;
|
|
/* static */ pthread_once_t BSecureSocket::Private::sInitOnce
|
|
= PTHREAD_ONCE_INIT;
|
|
#ifdef TRACE_SESSION_KEY
|
|
/* static */ BIO* BSecureSocket::Private::sKeyLogBIO = NULL;
|
|
#endif
|
|
|
|
|
|
BSecureSocket::Private::Private()
|
|
:
|
|
fSSL(NULL),
|
|
fBIO(BIO_new(BIO_s_socket()))
|
|
{
|
|
}
|
|
|
|
|
|
BSecureSocket::Private::~Private()
|
|
{
|
|
// SSL_free also frees the underlying BIO.
|
|
if (fSSL != NULL)
|
|
SSL_free(fSSL);
|
|
else {
|
|
// The SSL session was never created (Connect() was not called or
|
|
// failed). We must free the BIO we created in the constructor.
|
|
BIO_free(fBIO);
|
|
}
|
|
}
|
|
|
|
|
|
status_t
|
|
BSecureSocket::Private::InitCheck()
|
|
{
|
|
if (fBIO == NULL)
|
|
return B_NO_MEMORY;
|
|
return B_OK;
|
|
}
|
|
|
|
|
|
status_t
|
|
BSecureSocket::Private::ErrorCode(int returnValue)
|
|
{
|
|
int error = SSL_get_error(fSSL, returnValue);
|
|
switch (error) {
|
|
case SSL_ERROR_NONE:
|
|
// Shouldn't happen...
|
|
return B_NO_ERROR;
|
|
case SSL_ERROR_ZERO_RETURN:
|
|
// Socket is closed
|
|
return B_CANCELED;
|
|
case SSL_ERROR_SSL:
|
|
// Probably no certificate
|
|
return B_NOT_ALLOWED;
|
|
|
|
case SSL_ERROR_WANT_READ:
|
|
case SSL_ERROR_WANT_WRITE:
|
|
case SSL_ERROR_WANT_CONNECT:
|
|
case SSL_ERROR_WANT_ACCEPT:
|
|
case SSL_ERROR_WANT_X509_LOOKUP:
|
|
case SSL_ERROR_SYSCALL:
|
|
default:
|
|
// TODO: translate SSL error codes!
|
|
fprintf(stderr, "SSL %s\n", ERR_error_string(error, NULL));
|
|
return B_ERROR;
|
|
}
|
|
}
|
|
|
|
|
|
/* static */ SSL_CTX*
|
|
BSecureSocket::Private::Context()
|
|
{
|
|
// We use lazy initialisation here, because reading certificates from disk
|
|
// and parsing them is a relatively long operation and uses some memory.
|
|
// We don't want programs that don't use SSL to waste resources with that.
|
|
pthread_once(&sInitOnce, _CreateContext);
|
|
|
|
return sContext;
|
|
}
|
|
|
|
|
|
/*! This is called each time a certificate verification occurs. It allows us to
|
|
catch failures and report them.
|
|
*/
|
|
/* static */ int
|
|
BSecureSocket::Private::VerifyCallback(int ok, X509_STORE_CTX* ctx)
|
|
{
|
|
// OpenSSL already checked the certificate again the certificate store for
|
|
// us, and tells the result of that in the ok parameter.
|
|
|
|
// If the verification succeeded, no need for any further checks. Let's
|
|
// proceed with the connection.
|
|
if (ok)
|
|
return ok;
|
|
|
|
// The certificate verification failed. Signal this to the BSecureSocket.
|
|
|
|
// First of all, get the affected BSecureSocket
|
|
SSL* ssl = (SSL*)X509_STORE_CTX_get_ex_data(ctx,
|
|
SSL_get_ex_data_X509_STORE_CTX_idx());
|
|
BSecureSocket* socket = (BSecureSocket*)SSL_get_ex_data(ssl, sDataIndex);
|
|
|
|
// Get the certificate that we could not validate (this may not be the one
|
|
// we got from the server, but something higher up in the certificate
|
|
// chain)
|
|
X509* x509 = X509_STORE_CTX_get_current_cert(ctx);
|
|
BCertificate::Private* certificate
|
|
= new(std::nothrow) BCertificate::Private(x509);
|
|
|
|
if (certificate == NULL)
|
|
return 0;
|
|
|
|
int error = X509_STORE_CTX_get_error(ctx);
|
|
const char* message = X509_verify_cert_error_string(error);
|
|
|
|
// Let the BSecureSocket (or subclass) decide if we should continue anyway.
|
|
BCertificate failedCertificate(certificate);
|
|
return socket->CertificateVerificationFailed(failedCertificate, message);
|
|
}
|
|
|
|
|
|
#if TRACE_SSL
|
|
static void apps_ssl_info_callback(const SSL *s, int where, int ret)
|
|
{
|
|
const char *str;
|
|
int w;
|
|
|
|
w=where& ~SSL_ST_MASK;
|
|
|
|
if (w & SSL_ST_CONNECT)
|
|
str="SSL_connect";
|
|
else if (w & SSL_ST_ACCEPT)
|
|
str="SSL_accept";
|
|
else
|
|
str="undefined";
|
|
|
|
if (where & SSL_CB_LOOP) {
|
|
fprintf(stderr,"%s:%s\n", str, SSL_state_string_long(s));
|
|
} else if (where & SSL_CB_ALERT) {
|
|
str = (where & SSL_CB_READ) ? "read" : "write";
|
|
fprintf(stderr,"SSL3 alert %s:%s:%s\n",
|
|
str,
|
|
SSL_alert_type_string_long(ret),
|
|
SSL_alert_desc_string_long(ret));
|
|
} else if (where & SSL_CB_EXIT) {
|
|
if (ret == 0)
|
|
fprintf(stderr,"%s:failed in %s\n",
|
|
str,SSL_state_string_long(s));
|
|
else if (ret < 0) {
|
|
fprintf(stderr,"%s:error in %s\n",
|
|
str,SSL_state_string_long(s));
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
|
|
/* static */ void
|
|
BSecureSocket::Private::_CreateContext()
|
|
{
|
|
// We want SSL to report errors in human readable format.
|
|
SSL_load_error_strings();
|
|
|
|
sContext = SSL_CTX_new(SSLv23_method());
|
|
|
|
#if TRACE_SSL
|
|
// For debugging purposes: get all SSL messages to the standard error.
|
|
SSL_CTX_set_info_callback(sContext, apps_ssl_info_callback);
|
|
#endif
|
|
|
|
// Disable legacy protocols. They have known vulnerabilities.
|
|
SSL_CTX_set_options(sContext, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
|
|
|
|
// Disable SSL/TLS compression to prevent the CRIME attack.
|
|
SSL_CTX_set_options(sContext, SSL_OP_NO_COMPRESSION);
|
|
|
|
// Don't bother us with ERROR_WANT_READ.
|
|
SSL_CTX_set_mode(sContext, SSL_MODE_AUTO_RETRY);
|
|
|
|
// Setup cipher suites.
|
|
// These suites are mostly the same ones used by Firefox 47 and Chrome 50.
|
|
SSL_CTX_set_cipher_list(sContext,
|
|
"ECDHE-ECDSA-AES128-GCM-SHA256:"
|
|
"ECDHE-RSA-AES128-GCM-SHA256:"
|
|
"ECDHE-ECDSA-AES256-GCM-SHA384:"
|
|
"ECDHE-RSA-AES256-GCM-SHA384:"
|
|
"ECDHE-ECDSA-CHACHA20-POLY1305-SHA256:"
|
|
"ECDHE-RSA-CHACHA20-POLY1305-SHA256:"
|
|
"ECDHE-ECDSA-AES256-SHA:"
|
|
"ECDHE-ECDSA-AES128-SHA:"
|
|
"ECDHE-RSA-AES128-SHA:"
|
|
"ECDHE-RSA-AES256-SHA:"
|
|
"DHE-RSA-AES128-SHA:"
|
|
"DHE-RSA-AES256-SHA:"
|
|
"AES128-SHA:"
|
|
"AES256-SHA");
|
|
|
|
// Let OpenSSL choose the most appropriate D-H curve for us
|
|
SSL_CTX_set_ecdh_auto(sContext, 1);
|
|
|
|
// Setup certificate verification
|
|
BPath certificateStore;
|
|
find_directory(B_SYSTEM_DATA_DIRECTORY, &certificateStore);
|
|
certificateStore.Append("ssl/CARootCertificates.pem");
|
|
// TODO we may want to add a non-packaged certificate directory?
|
|
// (would make it possible to store user-added certificate exceptions
|
|
// there)
|
|
SSL_CTX_load_verify_locations(sContext, certificateStore.Path(), NULL);
|
|
SSL_CTX_set_verify(sContext, SSL_VERIFY_PEER, VerifyCallback);
|
|
|
|
// OpenSSL 1.0.2 and later: use the alternate "trusted first" algorithm to validate certificate
|
|
// chains. This makes the validation stop as soon as a recognized certificate is found in the
|
|
// chain, instead of validating the whole chain, then seeing if the root certificate is known.
|
|
#ifdef X509_V_FLAG_TRUSTED_FIRST
|
|
X509_VERIFY_PARAM* verifyParam = X509_VERIFY_PARAM_new();
|
|
X509_VERIFY_PARAM_set_flags(verifyParam, X509_V_FLAG_TRUSTED_FIRST);
|
|
SSL_CTX_set1_param(sContext, verifyParam);
|
|
|
|
// TODO we need to free this after freeing the SSL context (which we currently never do)
|
|
// X509_VERIFY_PARAM_free(verifyParam);
|
|
#endif
|
|
|
|
// Get an unique index number for storing application data in SSL
|
|
// structs. We will store a pointer to the BSecureSocket class there.
|
|
sDataIndex = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL);
|
|
|
|
#ifdef TRACE_SESSION_KEY
|
|
FILE *keylog = NULL;
|
|
const char *logpath = getenv("SSLKEYLOGFILE");
|
|
if (logpath)
|
|
keylog = fopen(logpath, "w+");
|
|
if (keylog) {
|
|
fprintf(keylog, "# Key Log File generated by Haiku Network Kit\n");
|
|
sKeyLogBIO = BIO_new_fp(keylog, BIO_NOCLOSE);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
|
|
// # pragma mark - BSecureSocket
|
|
|
|
|
|
BSecureSocket::BSecureSocket()
|
|
:
|
|
fPrivate(new(std::nothrow) BSecureSocket::Private())
|
|
{
|
|
fInitStatus = fPrivate != NULL ? fPrivate->InitCheck() : B_NO_MEMORY;
|
|
}
|
|
|
|
|
|
BSecureSocket::BSecureSocket(const BNetworkAddress& peer, bigtime_t timeout)
|
|
:
|
|
fPrivate(new(std::nothrow) BSecureSocket::Private())
|
|
{
|
|
fInitStatus = fPrivate != NULL ? fPrivate->InitCheck() : B_NO_MEMORY;
|
|
Connect(peer, timeout);
|
|
}
|
|
|
|
|
|
BSecureSocket::BSecureSocket(const BSecureSocket& other)
|
|
:
|
|
BSocket(other)
|
|
{
|
|
fPrivate = new(std::nothrow) BSecureSocket::Private(*other.fPrivate);
|
|
// TODO: this won't work this way! - write working copy constructor for
|
|
// Private.
|
|
|
|
if (fPrivate != NULL)
|
|
SSL_set_ex_data(fPrivate->fSSL, Private::sDataIndex, this);
|
|
else
|
|
fInitStatus = B_NO_MEMORY;
|
|
|
|
}
|
|
|
|
|
|
BSecureSocket::~BSecureSocket()
|
|
{
|
|
delete fPrivate;
|
|
}
|
|
|
|
|
|
status_t
|
|
BSecureSocket::Accept(BAbstractSocket*& _socket)
|
|
{
|
|
int fd = -1;
|
|
BNetworkAddress peer;
|
|
status_t error = AcceptNext(fd, peer);
|
|
if (error != B_OK)
|
|
return error;
|
|
BSecureSocket* socket = new(std::nothrow) BSecureSocket();
|
|
ObjectDeleter<BSecureSocket> socketDeleter(socket);
|
|
if (socket == NULL || socket->InitCheck() != B_OK) {
|
|
close(fd);
|
|
return B_NO_MEMORY;
|
|
}
|
|
|
|
socket->_SetTo(fd, fLocal, peer);
|
|
error = socket->_SetupAccept();
|
|
if (error != B_OK)
|
|
return error;
|
|
|
|
_socket = socket;
|
|
socketDeleter.Detach();
|
|
|
|
return B_OK;
|
|
}
|
|
|
|
|
|
status_t
|
|
BSecureSocket::Connect(const BNetworkAddress& peer, bigtime_t timeout)
|
|
{
|
|
status_t status = InitCheck();
|
|
if (status != B_OK)
|
|
return status;
|
|
|
|
status = BSocket::Connect(peer, timeout);
|
|
if (status != B_OK)
|
|
return status;
|
|
|
|
return _SetupConnect(peer.HostName().String());
|
|
}
|
|
|
|
|
|
void
|
|
BSecureSocket::Disconnect()
|
|
{
|
|
if (IsConnected()) {
|
|
if (fPrivate->fSSL != NULL)
|
|
SSL_shutdown(fPrivate->fSSL);
|
|
|
|
BSocket::Disconnect();
|
|
}
|
|
}
|
|
|
|
|
|
status_t
|
|
BSecureSocket::WaitForReadable(bigtime_t timeout) const
|
|
{
|
|
if (fInitStatus != B_OK)
|
|
return fInitStatus;
|
|
if (!IsConnected())
|
|
return B_ERROR;
|
|
|
|
if (SSL_pending(fPrivate->fSSL) > 0)
|
|
return B_OK;
|
|
|
|
return BSocket::WaitForReadable(timeout);
|
|
}
|
|
|
|
|
|
status_t
|
|
BSecureSocket::InitCheck()
|
|
{
|
|
if (fPrivate == NULL)
|
|
return B_NO_MEMORY;
|
|
|
|
status_t state = fPrivate->InitCheck();
|
|
return state;
|
|
}
|
|
|
|
|
|
bool
|
|
BSecureSocket::CertificateVerificationFailed(BCertificate&, const char*)
|
|
{
|
|
// Until apps actually make use of the certificate API, let's keep the old
|
|
// behavior and accept all connections, even if the certificate validation
|
|
// didn't work.
|
|
return true;
|
|
}
|
|
|
|
|
|
// #pragma mark - BDataIO implementation
|
|
|
|
|
|
ssize_t
|
|
BSecureSocket::Read(void* buffer, size_t size)
|
|
{
|
|
if (!IsConnected())
|
|
return B_ERROR;
|
|
|
|
int bytesRead = SSL_read(fPrivate->fSSL, buffer, size);
|
|
if (bytesRead >= 0)
|
|
return bytesRead;
|
|
|
|
return fPrivate->ErrorCode(bytesRead);
|
|
}
|
|
|
|
|
|
ssize_t
|
|
BSecureSocket::Write(const void* buffer, size_t size)
|
|
{
|
|
if (!IsConnected())
|
|
return B_ERROR;
|
|
|
|
int bytesWritten = SSL_write(fPrivate->fSSL, buffer, size);
|
|
if (bytesWritten >= 0)
|
|
return bytesWritten;
|
|
|
|
return fPrivate->ErrorCode(bytesWritten);
|
|
}
|
|
|
|
|
|
status_t
|
|
BSecureSocket::_SetupCommon(const char* host)
|
|
{
|
|
// Do this only after BSocket::Connect has checked wether we're already
|
|
// connected. We don't want to kill an existing SSL session, as that would
|
|
// likely crash the protocol loop for it.
|
|
if (fPrivate->fSSL != NULL) {
|
|
SSL_free(fPrivate->fSSL);
|
|
}
|
|
|
|
fPrivate->fSSL = SSL_new(BSecureSocket::Private::Context());
|
|
if (fPrivate->fSSL == NULL) {
|
|
BSocket::Disconnect();
|
|
return B_NO_MEMORY;
|
|
}
|
|
|
|
BIO_set_fd(fPrivate->fBIO, fSocket, BIO_NOCLOSE);
|
|
SSL_set_bio(fPrivate->fSSL, fPrivate->fBIO, fPrivate->fBIO);
|
|
SSL_set_ex_data(fPrivate->fSSL, Private::sDataIndex, this);
|
|
if (host != NULL) {
|
|
BString hostString = host;
|
|
if (hostString != "")
|
|
SSL_set_tlsext_host_name(fPrivate->fSSL, host);
|
|
}
|
|
|
|
|
|
return B_OK;
|
|
}
|
|
|
|
|
|
status_t
|
|
BSecureSocket::_SetupConnect(const char* host)
|
|
{
|
|
status_t error = _SetupCommon(host);
|
|
if (error != B_OK)
|
|
return error;
|
|
|
|
int returnValue = SSL_connect(fPrivate->fSSL);
|
|
if (returnValue <= 0) {
|
|
TRACE("SSLConnection can't connect\n");
|
|
BSocket::Disconnect();
|
|
return fPrivate->ErrorCode(returnValue);
|
|
}
|
|
|
|
#ifdef TRACE_SESSION_KEY
|
|
fprintf(stderr, "SSL SESSION INFO:\n");
|
|
//SSL_SESSION_print_fp(stderr, SSL_get_session(fPrivate->fSSL));
|
|
SSL_SESSION_print_keylog(fPrivate->sKeyLogBIO, SSL_get_session(fPrivate->fSSL));
|
|
SSL_SESSION_print_client_random(fPrivate->sKeyLogBIO, fPrivate->fSSL);
|
|
fprintf(stderr, "\n");
|
|
#endif
|
|
|
|
return B_OK;
|
|
}
|
|
|
|
|
|
status_t
|
|
BSecureSocket::_SetupAccept()
|
|
{
|
|
status_t error = _SetupCommon();
|
|
if (error != B_OK)
|
|
return error;
|
|
|
|
int returnValue = SSL_accept(fPrivate->fSSL);
|
|
if (returnValue <= 0) {
|
|
TRACE("SSLConnection can't accept\n");
|
|
BSocket::Disconnect();
|
|
return fPrivate->ErrorCode(returnValue);
|
|
}
|
|
|
|
return B_OK;
|
|
}
|
|
|
|
|
|
#else // OPENSSL_ENABLED
|
|
|
|
|
|
// #pragma mark - No-SSL stubs
|
|
|
|
|
|
BSecureSocket::BSecureSocket()
|
|
{
|
|
}
|
|
|
|
|
|
BSecureSocket::BSecureSocket(const BNetworkAddress& peer, bigtime_t timeout)
|
|
{
|
|
fInitStatus = B_UNSUPPORTED;
|
|
}
|
|
|
|
|
|
BSecureSocket::BSecureSocket(const BSecureSocket& other)
|
|
:
|
|
BSocket(other)
|
|
{
|
|
}
|
|
|
|
|
|
BSecureSocket::~BSecureSocket()
|
|
{
|
|
}
|
|
|
|
|
|
bool
|
|
BSecureSocket::CertificateVerificationFailed(BCertificate& certificate, const char*)
|
|
{
|
|
(void)certificate;
|
|
return false;
|
|
}
|
|
|
|
|
|
status_t
|
|
BSecureSocket::Accept(BAbstractSocket*& _socket)
|
|
{
|
|
return B_UNSUPPORTED;
|
|
}
|
|
|
|
|
|
status_t
|
|
BSecureSocket::Connect(const BNetworkAddress& peer, bigtime_t timeout)
|
|
{
|
|
return fInitStatus = B_UNSUPPORTED;
|
|
}
|
|
|
|
|
|
void
|
|
BSecureSocket::Disconnect()
|
|
{
|
|
}
|
|
|
|
|
|
status_t
|
|
BSecureSocket::WaitForReadable(bigtime_t timeout) const
|
|
{
|
|
return B_UNSUPPORTED;
|
|
}
|
|
|
|
|
|
// #pragma mark - BDataIO implementation
|
|
|
|
|
|
ssize_t
|
|
BSecureSocket::Read(void* buffer, size_t size)
|
|
{
|
|
return B_UNSUPPORTED;
|
|
}
|
|
|
|
|
|
ssize_t
|
|
BSecureSocket::Write(const void* buffer, size_t size)
|
|
{
|
|
return B_UNSUPPORTED;
|
|
}
|
|
|
|
|
|
status_t
|
|
BSecureSocket::InitCheck()
|
|
{
|
|
return B_UNSUPPORTED;
|
|
}
|
|
|
|
|
|
status_t
|
|
BSecureSocket::_SetupCommon(const char* host)
|
|
{
|
|
return B_UNSUPPORTED;
|
|
}
|
|
|
|
|
|
status_t
|
|
BSecureSocket::_SetupConnect(const char* host)
|
|
{
|
|
return B_UNSUPPORTED;
|
|
}
|
|
|
|
|
|
status_t
|
|
BSecureSocket::_SetupAccept()
|
|
{
|
|
return B_UNSUPPORTED;
|
|
}
|
|
|
|
|
|
#endif // !OPENSSL_ENABLED
|