Cleanup huge amount of AuthSSL cruft

Make reduntant auth check in pqi effective (even if redundant only
  siganture was checked but friendess wasn't)
Evidence redundant auth check in pqi by putting it inside #ifdef this
  way the beaviior being the same with and without redundat check can be
  verified easier
Solve lot of compiler warnings and made code more readable
Remove dangerous sslcert wrapper
Remove misleading messeges and notification about peer not giving cert,
  FailedCertificate logic is wrong since many years as authentication is
  fully handled inside VerifyX509Callback
This commit is contained in:
Gioacchino Mazzurco 2019-05-03 01:27:32 +02:00
parent 8300e65cad
commit 41d4599fe3
No known key found for this signature in database
GPG key ID: A1FBCA3872E87051
11 changed files with 682 additions and 1083 deletions

File diff suppressed because it is too large Load diff

View file

@ -3,7 +3,8 @@
* * * *
* libretroshare: retroshare core library * * libretroshare: retroshare core library *
* * * *
* Copyright 2004-2008 by Robert Fernie, Retroshare Team. * * Copyright (C) 2004-2008 Robert Fernie <retroshare@lunamutt.com> *
* Copyright (C) 2019 Gioacchino Mazzurco <gio@eigenlab.org> *
* * * *
* This program is free software: you can redistribute it and/or modify * * This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as * * it under the terms of the GNU Lesser General Public License as *
@ -19,21 +20,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * * along with this program. If not, see <https://www.gnu.org/licenses/>. *
* * * *
*******************************************************************************/ *******************************************************************************/
#ifndef MRK_AUTH_SSL_HEADER #pragma once
#define MRK_AUTH_SSL_HEADER
/*
* This is an implementation of SSL certificate authentication, which is
* overloaded with pgp style signatures, and web-of-trust authentication.
*
* only the owner ssl cert is store, the rest is jeus callback verification
*
* To use as an SSL authentication system, you must use a common CA certificate.
* * The pqissl stuff doesn't need to differentiate between SSL, SSL + PGP,
* as its X509 certs.
* * The rsserver stuff has to distinguish between all three types ;(
*
*/
#include <openssl/evp.h> #include <openssl/evp.h>
#include <openssl/x509.h> #include <openssl/x509.h>
@ -42,57 +30,75 @@
#include <map> #include <map>
#include "util/rsthreads.h" #include "util/rsthreads.h"
#include "pqi/pqi_base.h" #include "pqi/pqi_base.h"
#include "pqi/pqinetwork.h" #include "pqi/pqinetwork.h"
#include "pqi/p3cfgmgr.h" #include "pqi/p3cfgmgr.h"
#include "util/rsmemory.h"
#include "retroshare/rsevents.h"
/* This #define removes Connection Manager references in AuthSSL. /**
* They should not be here. What about Objects and orthogonality? * Functions to interact elegantly with X509 certificates, using this functions
* This code is also stopping immediate reconnections from working. * you can avoid annoying #ifdef *SSL_VERSION_NUMBER all around the code.
* Function names should be self descriptive.
*/ */
namespace RsX509Cert
class AuthSSL;
class sslcert
{ {
public: std::string getCertName(const X509& x509);
sslcert(X509* x509, const RsPeerId& id); std::string getCertLocation(const X509& x509);
sslcert(); std::string getCertOrg(const X509& x509);
RsPgpId getCertIssuer(const X509& x509);
/* certificate parameters */ std::string getCertIssuerString(const X509& x509);
RsPeerId id; RsPeerId getCertSslId(const X509& x509);
std::string name; const EVP_PKEY* getPubKey(const X509& x509);
std::string location;
std::string org;
std::string email;
RsPgpId issuer;
PGPFingerprintType fpr;
/* Auth settings */
bool authed;
/* INTERNAL Parameters */
X509* certificate;
}; };
/* required to install instance */ /**
* Event triggered by AuthSSL when authentication of a connection attempt either
* fail or success
*/
struct RsAuthSslConnectionAutenticationEvent : RsEvent
{
RsAuthSslConnectionAutenticationEvent();
bool mSuccess;
RsPeerId mSslId;
std::string mSslCn;
RsPgpId mPgpId;
std::string mErrorMsg;
///* @see RsEvent @see RsSerializable
void serial_process( RsGenericSerializer::SerializeJob j,
RsGenericSerializer::SerializeContext& ctx) override
{
RsEvent::serial_process(j, ctx);
RS_SERIAL_PROCESS(mSuccess);
RS_SERIAL_PROCESS(mSslId);
RS_SERIAL_PROCESS(mSslCn);
RS_SERIAL_PROCESS(mPgpId);
RS_SERIAL_PROCESS(mErrorMsg);
}
};
/**
* This is an implementation of SSL certificate authentication with PGP
* signatures, instead of centralized certification authority.
*/
class AuthSSL class AuthSSL
{ {
public: public:
AuthSSL(); static AuthSSL& instance();
RS_DEPRECATED_FOR(AuthSSL::instance())
static AuthSSL* getAuthSSL(); static AuthSSL* getAuthSSL();
static void AuthSSLInit();
/* Initialisation Functions (Unique) */ /* Initialisation Functions (Unique) */
virtual bool validateOwnCertificate(X509 *x509, EVP_PKEY *pkey) = 0; virtual bool validateOwnCertificate(X509 *x509, EVP_PKEY *pkey) = 0;
virtual bool active() = 0; virtual bool active() = 0;
virtual int InitAuth(const char *srvr_cert, const char *priv_key, virtual int InitAuth(
const char *passwd, std::string alternative_location_name) = 0; const char* srvr_cert, const char* priv_key, const char* passwd,
std::string alternative_location_name ) = 0;
virtual bool CloseAuth() = 0; virtual bool CloseAuth() = 0;
/*********** Overloaded Functions from p3AuthMgr **********/ /*********** Overloaded Functions from p3AuthMgr **********/
@ -106,39 +112,69 @@ virtual std::string SaveOwnCertificateToString() = 0;
/* Sign / Encrypt / Verify Data */ /* Sign / Encrypt / Verify Data */
virtual bool SignData(std::string input, std::string &sign) = 0; virtual bool SignData(std::string input, std::string &sign) = 0;
virtual bool SignData(const void *data, const uint32_t len, std::string &sign) = 0; virtual bool SignData(
const void* data, const uint32_t len, std::string& sign ) = 0;
virtual bool SignDataBin(std::string, unsigned char*, unsigned int*) = 0; virtual bool SignDataBin(std::string, unsigned char*, unsigned int*) = 0;
virtual bool SignDataBin(const void*, uint32_t, unsigned char*, unsigned int*) = 0; virtual bool SignDataBin(
virtual bool VerifyOwnSignBin(const void*, uint32_t, unsigned char*, unsigned int) = 0; const void*, uint32_t, unsigned char*, unsigned int* ) = 0;
virtual bool VerifySignBin(const void *data, const uint32_t len, virtual bool VerifyOwnSignBin(
unsigned char *sign, unsigned int signlen, const RsPeerId& sslId) = 0; const void*, uint32_t, unsigned char*, unsigned int ) = 0;
virtual bool VerifySignBin(
const void* data, const uint32_t len, unsigned char* sign,
unsigned int signlen, const RsPeerId& sslId ) = 0;
// return : false if encrypt failed /// return false if failed
virtual bool encrypt(void *&out, int &outlen, const void *in, int inlen, const RsPeerId& peerId) = 0; virtual bool encrypt(
// return : false if decrypt fails void*& out, int& outlen, const void* in, int inlen,
const RsPeerId& peerId ) = 0;
/// return false if failed
virtual bool decrypt(void*& out, int& outlen, const void* in, int inlen) = 0; virtual bool decrypt(void*& out, int& outlen, const void* in, int inlen) = 0;
virtual X509* SignX509ReqWithGPG(X509_REQ* req, long days) = 0; virtual X509* SignX509ReqWithGPG(X509_REQ* req, long days) = 0;
virtual bool AuthX509WithGPG(X509 *x509,uint32_t& auth_diagnostic)=0;
/**
* @brief Verify PGP signature correcteness on given X509 certificate
* Beware this doesn't check if the PGP signer is friend or not, just if the
* signature is valid!
* @param[in] x509 pointer ti the X509 certificate to check
* @param[out] diagnostic one of RS_SSL_HANDSHAKE_DIAGNOSTIC_* diagnostic
* codes
* @return true if correctly signed, false otherwise
*/
virtual bool AuthX509WithGPG(
X509* x509,
uint32_t& diagnostic = RS_DEFAULT_STORAGE_PARAM(uint32_t)
) = 0;
/**
* @brief Callback provided to OpenSSL to authenticate connections
* This is the ultimate place where connection attempts get accepted
* if authenticated or refused if not authenticated.
* Emits @see RsAuthSslConnectionAutenticationEvent.
* @param preverify_ok passed by OpenSSL ignored as this call is the first
* in the authentication callback chain
* @param ctx OpenSSL connection context
* @return 0 if authentication failed, 1 if success see OpenSSL
* documentation
*/
virtual int VerifyX509Callback(int preverify_ok, X509_STORE_CTX* ctx) = 0; virtual int VerifyX509Callback(int preverify_ok, X509_STORE_CTX* ctx) = 0;
virtual bool ValidateCertificate(X509 *x509, RsPeerId& peerId) = 0; /* validate + get id */
public: /* SSL specific functions used in pqissl/pqissllistener */ /// SSL specific functions used in pqissl/pqissllistener
virtual SSL_CTX* getCTX() = 0; virtual SSL_CTX* getCTX() = 0;
/* Restored these functions: */ virtual void setCurrentConnectionAttemptInfo(
virtual void setCurrentConnectionAttemptInfo(const RsPgpId& gpg_id,const RsPeerId& ssl_id,const std::string& ssl_cn) = 0 ; const RsPgpId& gpg_id, const RsPeerId& ssl_id,
virtual void getCurrentConnectionAttemptInfo( RsPgpId& gpg_id, RsPeerId& ssl_id, std::string& ssl_cn) = 0 ; const std::string& ssl_cn ) = 0;
virtual void getCurrentConnectionAttemptInfo(
RsPgpId& gpg_id, RsPeerId& ssl_id, std::string& ssl_cn ) = 0;
virtual bool FailedCertificate(X509 *x509, const RsPgpId& gpgid,const RsPeerId& sslid,const std::string& sslcn,const struct sockaddr_storage &addr, bool incoming) = 0; /* store for discovery */ virtual ~AuthSSL();
virtual bool CheckCertificate(const RsPeerId& peerId, X509 *x509) = 0; /* check that they are exact match */
static void setAuthSSL_debug(AuthSSL*) ; // used for debug only. The real function is InitSSL() protected:
static AuthSSL *instance_ssl ; AuthSSL() {}
RS_SET_CONTEXT_DEBUG_LEVEL(2)
}; };
@ -146,64 +182,71 @@ class AuthSSLimpl : public AuthSSL, public p3Config
{ {
public: public:
/* Initialisation Functions (Unique) */ /** Initialisation Functions (Unique) */
AuthSSLimpl(); AuthSSLimpl();
bool validateOwnCertificate(X509 *x509, EVP_PKEY *pkey); bool validateOwnCertificate(X509 *x509, EVP_PKEY *pkey) override;
virtual bool active(); bool active() override;
virtual int InitAuth(const char *srvr_cert, const char *priv_key, int InitAuth( const char *srvr_cert, const char *priv_key,
const char *passwd, std::string alternative_location_name); const char *passwd, std::string alternative_location_name )
virtual bool CloseAuth(); override;
bool CloseAuth() override;
/*********** Overloaded Functions from p3AuthMgr **********/ /*********** Overloaded Functions from p3AuthMgr **********/
/* get Certificate Id */ const RsPeerId& OwnId() override;
virtual const RsPeerId& OwnId(); virtual std::string getOwnLocation() override;
virtual std::string getOwnLocation();
/* Load/Save certificates */ /* Load/Save certificates */
virtual std::string SaveOwnCertificateToString(); virtual std::string SaveOwnCertificateToString() override;
/* Sign / Encrypt / Verify Data */ /* Sign / Encrypt / Verify Data */
virtual bool SignData(std::string input, std::string &sign); bool SignData(std::string input, std::string &sign) override;
virtual bool SignData(const void *data, const uint32_t len, std::string &sign); bool SignData(
const void *data, const uint32_t len, std::string &sign) override;
virtual bool SignDataBin(std::string, unsigned char*, unsigned int*); bool SignDataBin(std::string, unsigned char*, unsigned int*) override;
virtual bool SignDataBin(const void*, uint32_t, unsigned char*, unsigned int*); virtual bool SignDataBin(
virtual bool VerifyOwnSignBin(const void*, uint32_t, unsigned char*, unsigned int); const void*, uint32_t, unsigned char*, unsigned int*) override;
virtual bool VerifySignBin(const void *data, const uint32_t len, bool VerifyOwnSignBin(
unsigned char *sign, unsigned int signlen, const RsPeerId& sslId); const void*, uint32_t, unsigned char*, unsigned int) override;
virtual bool VerifySignBin(
const void *data, const uint32_t len, unsigned char *sign,
unsigned int signlen, const RsPeerId& sslId) override;
// return : false if encrypt failed bool encrypt(
virtual bool encrypt(void *&out, int &outlen, const void *in, int inlen, const RsPeerId& peerId); void*& out, int& outlen, const void* in, int inlen,
// return : false if decrypt fails const RsPeerId& peerId ) override;
virtual bool decrypt(void *&out, int &outlen, const void *in, int inlen); bool decrypt(void *&out, int &outlen, const void *in, int inlen) override;
virtual X509* SignX509ReqWithGPG(X509_REQ *req, long days) override;
virtual X509* SignX509ReqWithGPG(X509_REQ *req, long days); /// @see AuthSSL
virtual bool AuthX509WithGPG(X509 *x509,uint32_t& auth_diagnostic); bool AuthX509WithGPG(X509 *x509,uint32_t& auth_diagnostic) override;
/// @see AuthSSL
virtual int VerifyX509Callback(int preverify_ok, X509_STORE_CTX *ctx); int VerifyX509Callback(int preverify_ok, X509_STORE_CTX *ctx) override;
virtual bool ValidateCertificate(X509 *x509, RsPeerId& peerId); /* validate + get id */
/*****************************************************************/ /*****************************************************************/
/*********************** p3config ******************************/ /*********************** p3config ******************************/
/* Key Functions to be overloaded for Full Configuration */ /* Key Functions to be overloaded for Full Configuration */
virtual RsSerialiser *setupSerialiser(); RsSerialiser* setupSerialiser() override;
virtual bool saveList(bool &cleanup, std::list<RsItem *>& ); bool saveList(bool &cleanup, std::list<RsItem *>& ) override;
virtual bool loadList(std::list<RsItem *>& load); bool loadList(std::list<RsItem *>& load) override;
/*****************************************************************/ /*****************************************************************/
public: /* SSL specific functions used in pqissl/pqissllistener */ public:
virtual SSL_CTX *getCTX(); /* SSL specific functions used in pqissl/pqissllistener */
SSL_CTX* getCTX() override;
/* Restored these functions: */ /* Restored these functions: */
virtual void setCurrentConnectionAttemptInfo(const RsPgpId& gpg_id,const RsPeerId& ssl_id,const std::string& ssl_cn) ; void setCurrentConnectionAttemptInfo(
virtual void getCurrentConnectionAttemptInfo( RsPgpId& gpg_id, RsPeerId& ssl_id, std::string& ssl_cn) ; const RsPgpId& gpg_id, const RsPeerId& ssl_id,
virtual bool FailedCertificate(X509 *x509, const RsPgpId& gpgid,const RsPeerId& sslid,const std::string& sslcn,const struct sockaddr_storage &addr, bool incoming); /* store for discovery */ const std::string& ssl_cn ) override;
virtual bool CheckCertificate(const RsPeerId& peerId, X509 *x509); /* check that they are exact match */ void getCurrentConnectionAttemptInfo(
RsPgpId& gpg_id, RsPeerId& ssl_id, std::string& ssl_cn ) override;
private: private:
@ -212,27 +255,23 @@ bool LocalStoreCert(X509* x509);
bool RemoveX509(const RsPeerId id); bool RemoveX509(const RsPeerId id);
/*********** LOCKED Functions ******/ /*********** LOCKED Functions ******/
bool locked_FindCert(const RsPeerId& id, sslcert **cert); bool locked_FindCert(const RsPeerId& id, X509** cert);
/* Data */ /* Data */
/* these variables are constants -> don't need to protect */ /* these variables are constants -> don't need to protect */
SSL_CTX *sslctx; SSL_CTX *sslctx;
RsPeerId mOwnId; RsPeerId mOwnId;
sslcert *mOwnCert; X509* mOwnCert;
RsMutex sslMtx; /* protects all below */ RsMutex sslMtx; /* protects all below */
EVP_PKEY* mOwnPrivateKey; EVP_PKEY* mOwnPrivateKey;
EVP_PKEY* mOwnPublicKey; EVP_PKEY* mOwnPublicKey;
int init; int init;
std::map<RsPeerId, X509*> mCerts;
std::map<RsPeerId, sslcert *> mCerts;
RsPgpId _last_gpgid_to_connect; RsPgpId _last_gpgid_to_connect;
std::string _last_sslcn_to_connect; std::string _last_sslcn_to_connect;
RsPeerId _last_sslid_to_connect; RsPeerId _last_sslid_to_connect;
}; };
#endif // MRK_AUTH_SSL_HEADER

View file

@ -1032,47 +1032,6 @@ bool p3LinkMgrIMPL::connectResult(const RsPeerId &id, bool success, bool isIncom
* From various sources * From various sources
*/ */
// from pqissl, when a connection failed due to security
void p3LinkMgrIMPL::notifyDeniedConnection(const RsPgpId& gpgid,const RsPeerId& sslid,const std::string& sslcn,const struct sockaddr_storage &/*addr*/, bool incoming)
{
std::cerr << "p3LinkMgrIMPL::notifyDeniedConnection()";
std::cerr << " pgpid: " << gpgid;
std::cerr << " sslid: " << sslid;
std::cerr << " sslcn: " << sslcn;
std::cerr << std::endl;
RsStackMutex stack(mLinkMtx); /****** STACK LOCK MUTEX *******/
std::map<RsPeerId, peerConnectState>::iterator it;
it = mFriendList.find(sslid);
if (it == mFriendList.end())
{
std::cerr << "p3LinkMgrIMPL::notifyDeniedConnection() of NON-FRIEND: " << sslid;
std::cerr << std::endl;
return;
}
it->second.wasDeniedConnection = true;
it->second.deniedTS = time(NULL);
if ((!incoming) && it->second.inConnAttempt)
{
it->second.deniedInConnAttempt = true;
it->second.deniedConnectionAttempt = it->second.currentConnAddrAttempt;
std::cerr << "p3LinkMgrIMPL::notifyDeniedConnection() Denied In Connection Attempt";
std::cerr << std::endl;
}
else
{
it->second.deniedInConnAttempt = false;
std::cerr << "p3LinkMgrIMPL::notifyDeniedConnection() Denied NOT In Connection Attempt";
std::cerr << std::endl;
}
return;
}
void p3LinkMgrIMPL::peerStatus(const RsPeerId& id, const pqiIpAddrSet &addrs, void p3LinkMgrIMPL::peerStatus(const RsPeerId& id, const pqiIpAddrSet &addrs,
uint32_t type, uint32_t flags, uint32_t source) uint32_t type, uint32_t flags, uint32_t source)
{ {

View file

@ -171,8 +171,6 @@ virtual bool connectAttempt(const RsPeerId &id, struct sockaddr_storage &raddr,
virtual bool connectResult(const RsPeerId &id, bool success, bool isIncomingConnection, uint32_t flags, const struct sockaddr_storage &remote_peer_address) = 0; virtual bool connectResult(const RsPeerId &id, bool success, bool isIncomingConnection, uint32_t flags, const struct sockaddr_storage &remote_peer_address) = 0;
virtual bool retryConnect(const RsPeerId &id) = 0; virtual bool retryConnect(const RsPeerId &id) = 0;
virtual void notifyDeniedConnection(const RsPgpId& gpgid,const RsPeerId& sslid,const std::string& sslcn,const struct sockaddr_storage &addr, bool incoming) = 0;
/* Network Addresses */ /* Network Addresses */
virtual bool setLocalAddress(const struct sockaddr_storage &addr) = 0; virtual bool setLocalAddress(const struct sockaddr_storage &addr) = 0;
virtual bool getLocalAddress(struct sockaddr_storage &addr) = 0; virtual bool getLocalAddress(struct sockaddr_storage &addr) = 0;
@ -230,8 +228,6 @@ virtual bool connectAttempt(const RsPeerId &id, struct sockaddr_storage &raddr,
virtual bool connectResult(const RsPeerId &id, bool success, bool isIncomingConnection, uint32_t flags, const struct sockaddr_storage &remote_peer_address); virtual bool connectResult(const RsPeerId &id, bool success, bool isIncomingConnection, uint32_t flags, const struct sockaddr_storage &remote_peer_address);
virtual bool retryConnect(const RsPeerId &id); virtual bool retryConnect(const RsPeerId &id);
virtual void notifyDeniedConnection(const RsPgpId& gpgid,const RsPeerId& sslid,const std::string& sslcn,const struct sockaddr_storage &addr, bool incoming);
/* Network Addresses */ /* Network Addresses */
virtual bool setLocalAddress(const struct sockaddr_storage &addr); virtual bool setLocalAddress(const struct sockaddr_storage &addr);
virtual bool getLocalAddress(struct sockaddr_storage &addr); virtual bool getLocalAddress(struct sockaddr_storage &addr);

View file

@ -1115,9 +1115,6 @@ int pqissl::SSL_Connection_Complete()
rslog(RSL_WARNING, pqisslzone, out); rslog(RSL_WARNING, pqisslzone, out);
// attempt real error.
Extract_Failed_SSL_Certificate();
rslog(RSL_ALERT, pqisslzone, "pqissl::SSL_Connection_Complete() -> calling reset()"); rslog(RSL_ALERT, pqisslzone, "pqissl::SSL_Connection_Complete() -> calling reset()");
reset_locked(); reset_locked();
waiting = WAITING_FAIL_INTERFACE; waiting = WAITING_FAIL_INTERFACE;
@ -1132,73 +1129,15 @@ int pqissl::SSL_Connection_Complete()
return 1; return 1;
} }
int pqissl::Extract_Failed_SSL_Certificate()
{
std::cerr << "pqissl::Extract_Failed_SSL_Certificate() FAILED Connection due to Security Issues";
std::cerr << std::endl;
#ifdef PQISSL_LOG_DEBUG
rslog(RSL_DEBUG_BASIC, pqisslzone,
"pqissl::Extract_Failed_SSL_Certificate()");
#endif
// Get the Peer Certificate....
X509 *peercert = SSL_get_peer_certificate(ssl_connection);
if (peercert == NULL)
{
rslog(RSL_WARNING, pqisslzone,
"pqissl::Extract_Failed_SSL_Certificate() Peer Didnt Give Cert");
std::cerr << "pqissl::Extract_Failed_SSL_Certificate() ERROR Peer Didn't Give Us Certificate";
std::cerr << std::endl;
return -1;
}
#ifdef PQISSL_LOG_DEBUG
rslog(RSL_DEBUG_BASIC, pqisslzone,
"pqissl::Extract_Failed_SSL_Certificate() Have Peer Cert - Registering");
#endif
std::cerr << "pqissl::Extract_Failed_SSL_Certificate() Passing FAILED Cert to AuthSSL for analysis";
std::cerr << std::endl;
// save certificate... (and ip locations)
// false for outgoing....
// we actually connected to remote_addr,
// which could be
// (pqissl's case) sslcert->serveraddr or sslcert->localaddr.
RsPeerId sslid ;
getX509id(peercert, sslid) ;
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
RsPgpId gpgid(getX509CNString(peercert->cert_info->issuer));
std::string sslcn = getX509CNString(peercert->cert_info->subject);
#else
RsPgpId gpgid(getX509CNString(X509_get_issuer_name(peercert)));
std::string sslcn = getX509CNString(X509_get_subject_name(peercert));
#endif
AuthSSL::getAuthSSL()->FailedCertificate(peercert, gpgid,sslid,sslcn,remote_addr, false);
mLinkMgr->notifyDeniedConnection(gpgid, sslid, sslcn, remote_addr, false);
return 1;
}
int pqissl::Authorise_SSL_Connection() int pqissl::Authorise_SSL_Connection()
{ {
#ifdef PQISSL_DEBUG Dbg3() << __PRETTY_FUNCTION__ << std::endl;
std::cerr << __PRETTY_FUNCTION__ << std::endl;
#endif
if (time(NULL) > ssl_connect_timeout) constexpr int failure = -1;
if (time(nullptr) > ssl_connect_timeout)
{ {
std::cerr << __PRETTY_FUNCTION__ << " Connection timed out reset!" RsInfo() << __PRETTY_FUNCTION__ << " Connection timed out reset!"
<< std::endl; << std::endl;
reset_locked(); reset_locked();
} }
@ -1206,85 +1145,71 @@ int pqissl::Authorise_SSL_Connection()
int err; int err;
if (0 >= (err = SSL_Connection_Complete())) return err; if (0 >= (err = SSL_Connection_Complete())) return err;
#ifdef PQISSL_LOG_DEBUG Dbg3() << __PRETTY_FUNCTION__ << "SSL_Connection_Complete success."
rslog(RSL_DEBUG_BASIC, pqisslzone, << std::endl;
"pqissl::Authorise_SSL_Connection() SSL_Connection_Complete");
#endif
// reset switch. // reset switch.
waiting = WAITING_NOT; waiting = WAITING_NOT;
X509* peercert = SSL_get_peer_certificate(ssl_connection); X509* peercert = SSL_get_peer_certificate(ssl_connection);
if (!peercert)
if (peercert == NULL)
{ {
rslog(RSL_WARNING, pqisslzone, RsFatal() << __PRETTY_FUNCTION__ << " failed to retrieve peer "
"pqissl::Authorise_SSL_Connection() Peer Didnt Give Cert"); << "certificate at this point this should never happen!"
<< std::endl;
rslog(RSL_ALERT, pqisslzone, "pqissl::Authorise_Connection_Complete() -> calling reset()"); print_stacktrace();
// Failed completely exit(failure);
reset_locked();
return -1;
} }
RsPeerId certPeerId; RsPeerId certPeerId = RsX509Cert::getCertSslId(*peercert);
getX509id(peercert, certPeerId); if (RsPeerId(certPeerId) != PeerId())
if (RsPeerId(certPeerId) != PeerId()) {
rslog(RSL_WARNING, pqisslzone,
"pqissl::Authorise_SSL_Connection() the cert Id doesn't match the Peer id we're trying to connect to.");
rslog(RSL_ALERT, pqisslzone, "pqissl::Authorise_Connection_Complete() -> calling reset()");
// Failed completely
reset_locked();
return -1;
}
#ifdef PQISSL_LOG_DEBUG
rslog(RSL_DEBUG_BASIC, pqisslzone,
"pqissl::Authorise_SSL_Connection() Have Peer Cert");
#endif
// save certificate... (and ip locations)
// false for outgoing....
// we actually connected to remote_addr,
// which could be
// (pqissl's case) sslcert->serveraddr or sslcert->localaddr.
AuthSSL::getAuthSSL()->CheckCertificate(PeerId(), peercert);
bool certCorrect = true; /* WE know it okay already! */
uint32_t check_result ;
uint32_t checking_flags = RSBANLIST_CHECKING_FLAGS_BLACKLIST;
if (rsPeers->servicePermissionFlags(PeerId()) & RS_NODE_PERM_REQUIRE_WL)
checking_flags |= RSBANLIST_CHECKING_FLAGS_WHITELIST;
if(rsBanList!=NULL && !rsBanList->isAddressAccepted(remote_addr,checking_flags,&check_result))
{ {
std::cerr << "(SS) refusing connection attempt from IP address " << sockaddr_storage_iptostring(remote_addr) << ". Reason: " << RsErr() << __PRETTY_FUNCTION__ << " the cert Id doesn't match the peer "
((check_result == RSBANLIST_CHECK_RESULT_NOT_WHITELISTED)?"not whitelisted (peer requires whitelist)":"blacklisted") << std::endl; << "id we're trying to connect to." << std::endl;
/* TODO: Considering how difficult is managing to get a connection to a
* friend nowadays on the Internet because of evil NAT everywhere.
* If the cert is from a friend anyway we should find a way to make good
* use of this connection instead of throwing it away... */
RsServer::notify()->AddFeedItem(RS_FEED_ITEM_SEC_IP_BLACKLISTED, PeerId().toStdString(), sockaddr_storage_iptostring(remote_addr), "", "", check_result);
reset_locked(); reset_locked();
return 0 ; return failure;
} }
// check it's the right one.
if (certCorrect) #ifdef RS_PQISSL_AUTH_REDUNDANT_CHECK
/* At this point the actual connection authentication has already been
* performed in AuthSSL::VerifyX509Callback, any furter authentication check
* like the following two are redundant. */
uint32_t authErrCode = 0;
if(!AuthSSL::instance().AuthX509WithGPG(peercert, authErrCode))
{ {
// then okay... RsFatal() << __PRETTY_FUNCTION__ << " failure verifying peer "
rslog(RSL_WARNING, pqisslzone, "pqissl::Authorise_SSL_Connection() Accepting Conn. Peer: " + PeerId().toStdString()); << "certificate signature. This should never happen at this "
<< "point!" << std::endl;
//std::cerr << "pqissl::Authorise_SSL_Connection(): accepting connection from " << sockaddr_storage_iptostring(remote_addr) << std::endl; print_stacktrace();
accept_locked(ssl_connection, sockfd, remote_addr); exit(failure);
return 1;
} }
rslog(RSL_WARNING, pqisslzone, "pqissl::Authorise_SSL_Connection() Something Wrong ... Shutdown. Peer: " + PeerId().toStdString()); RsPgpId pgpId = RsX509Cert::getCertIssuer(*peercert);
if( !AuthGPG::getAuthGPG()->isGPGAccepted(pgpId) )
{
RsErr() << __PRETTY_FUNCTION__ << " pgpId: " << pgpId
<< " is not friend. It is very unlikely to happen at this "
<< "point! Either the user must have been so fast to deny "
<< "friendship just after VerifyX509Callback have returned "
<< "success and just before this code being executed, or "
<< "something really fishy is happening! Share the full log "
<< "with developers." << std::endl;
print_stacktrace();
exit(failure);
}
#endif // def RS_PQISSL_AUTH_REDUNDANT_CHECK
// else shutdown ssl connection. Dbg2() << __PRETTY_FUNCTION__ << " Accepting connection to peer: "
rslog(RSL_ALERT, pqisslzone, "pqissl::Authorise_Connection_Complete() -> calling reset()"); << PeerId() << " with address: " << remote_addr << std::endl;
reset_locked(); return accept_locked(ssl_connection, sockfd, remote_addr);
return 0;
} }
@ -1303,10 +1228,15 @@ int pqissl::accept( SSL *ssl, int fd,
int pqissl::accept_locked( SSL *ssl, int fd, int pqissl::accept_locked( SSL *ssl, int fd,
const sockaddr_storage &foreign_addr ) const sockaddr_storage &foreign_addr )
{ {
#ifdef PQISSL_DEBUG Dbg3() << __PRETTY_FUNCTION__ << std::endl;
std::cerr << __PRETTY_FUNCTION__ << std::endl;
#endif
constexpr int failure = -1;
constexpr int success = 1;
#ifdef RS_PQISSL_BANLIST_REDUNDANT_CHECK
/* TODO: It make no sense to check banlist at this point, as we are actively
* attempting the connection, we decide the address to which to connect to,
* banned addresses should never get here */
uint32_t check_result; uint32_t check_result;
uint32_t checking_flags = RSBANLIST_CHECKING_FLAGS_BLACKLIST; uint32_t checking_flags = RSBANLIST_CHECKING_FLAGS_BLACKLIST;
@ -1329,12 +1259,13 @@ int pqissl::accept_locked( SSL *ssl, int fd,
sockaddr_storage_iptostring(foreign_addr), "", "", sockaddr_storage_iptostring(foreign_addr), "", "",
check_result); check_result);
reset_locked(); reset_locked();
return -1; return failure;
} }
#endif //def RS_BANLIST_REDUNDANT_CHECK
if (waiting != WAITING_NOT) if (waiting != WAITING_NOT)
{ {
std::cerr << __PRETTY_FUNCTION__ << " Peer: " << PeerId().toStdString() RsInfo() << __PRETTY_FUNCTION__ << " Peer: " << PeerId()
<< " - Two connections in progress - Shut 1 down!" << " - Two connections in progress - Shut 1 down!"
<< std::endl; << std::endl;
@ -1431,7 +1362,7 @@ int pqissl::accept_locked( SSL *ssl, int fd,
waiting = WAITING_FAIL_INTERFACE; // failed completely. waiting = WAITING_FAIL_INTERFACE; // failed completely.
reset_locked(); reset_locked();
return -1; return failure;
} }
#ifdef PQISSL_DEBUG #ifdef PQISSL_DEBUG
else std::cerr << __PRETTY_FUNCTION__ << " Socket made non-nlocking!" else std::cerr << __PRETTY_FUNCTION__ << " Socket made non-nlocking!"
@ -1456,7 +1387,7 @@ int pqissl::accept_locked( SSL *ssl, int fd,
sockaddr_storage addr; sockaddr_storage_copy(remote_addr, addr); sockaddr_storage addr; sockaddr_storage_copy(remote_addr, addr);
parent()->notifyEvent(this, NET_CONNECT_SUCCESS, addr); parent()->notifyEvent(this, NET_CONNECT_SUCCESS, addr);
} }
return 1; return success;
} }
/********** Implementation of BinInterface ************************** /********** Implementation of BinInterface **************************

View file

@ -3,8 +3,8 @@
* * * *
* libretroshare: retroshare core library * * libretroshare: retroshare core library *
* * * *
* Copyright 2004-2006 by Robert Fernie <retroshare@lunamutt.com> * * Copyright (C) 2004-2006 Robert Fernie <retroshare@lunamutt.com> *
* Copyright (C) 2015-2018 Gioacchino Mazzurco <gio@eigenlab.org> * * Copyright (C) 2015-2019 Gioacchino Mazzurco <gio@eigenlab.org> *
* * * *
* This program is free software: you can redistribute it and/or modify * * This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as * * it under the terms of the GNU Lesser General Public License as *
@ -20,8 +20,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * * along with this program. If not, see <https://www.gnu.org/licenses/>. *
* * * *
*******************************************************************************/ *******************************************************************************/
#ifndef MRK_PQI_SSL_HEADER #pragma once
#define MRK_PQI_SSL_HEADER
// operating system specific network header. // operating system specific network header.
#include "pqi/pqinetwork.h" #include "pqi/pqinetwork.h"
@ -32,6 +31,9 @@
#include "pqi/pqi_base.h" #include "pqi/pqi_base.h"
#include "pqi/authssl.h" #include "pqi/authssl.h"
#define RS_PQISSL_AUTH_REDUNDANT_CHECK 1
#define WAITING_NOT 0 #define WAITING_NOT 0
#define WAITING_DELAY 1 #define WAITING_DELAY 1
#define WAITING_SOCK_CONNECT 2 #define WAITING_SOCK_CONNECT 2
@ -159,8 +161,6 @@ int Initiate_SSL_Connection();
int SSL_Connection_Complete(); int SSL_Connection_Complete();
int Authorise_SSL_Connection(); int Authorise_SSL_Connection();
int Extract_Failed_SSL_Certificate(); // try to get cert anyway.
// check connection timeout. // check connection timeout.
bool CheckConnectionTimeout(); bool CheckConnectionTimeout();
@ -207,9 +207,6 @@ bool CheckConnectionTimeout();
private: private:
// ssl only fns. // ssl only fns.
int connectInterface(const struct sockaddr_storage &addr); int connectInterface(const struct sockaddr_storage &addr);
RS_SET_CONTEXT_DEBUG_LEVEL(1)
}; };
#endif // MRK_PQI_SSL_HEADER

View file

@ -20,20 +20,20 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * * along with this program. If not, see <https://www.gnu.org/licenses/>. *
* * * *
*******************************************************************************/ *******************************************************************************/
#include "pqi/pqissl.h" #include "pqi/pqissl.h"
#include "pqi/pqissllistener.h" #include "pqi/pqissllistener.h"
#include "pqi/pqinetwork.h" #include "pqi/pqinetwork.h"
#include "pqi/sslfns.h" #include "pqi/sslfns.h"
#include "pqi/p3peermgr.h" #include "pqi/p3peermgr.h"
#include <errno.h>
#include <openssl/err.h>
#include "util/rsdebug.h" #include "util/rsdebug.h"
#include "util/rsstring.h" #include "util/rsstring.h"
#include "retroshare/rsbanlist.h" #include "retroshare/rsbanlist.h"
#include "pqi/authgpg.h"
#include <unistd.h> #include <unistd.h>
#include <errno.h>
#include <openssl/err.h>
static struct RsLog::logInfo pqissllistenzoneInfo = {RsLog::Default, "p3peermgr"}; static struct RsLog::logInfo pqissllistenzoneInfo = {RsLog::Default, "p3peermgr"};
#define pqissllistenzone &pqissllistenzoneInfo #define pqissllistenzone &pqissllistenzoneInfo
@ -486,9 +486,6 @@ int pqissllistenbase::continueSSL(IncomingSSLInfo& incoming_connexion_info, bool
break; break;
} }
/* we have failed -> get certificate if possible */
Extract_Failed_SSL_Certificate(incoming_connexion_info);
closeConnection(fd, incoming_connexion_info.ssl) ; closeConnection(fd, incoming_connexion_info.ssl) ;
pqioutput(PQL_WARNING, pqissllistenzone, "Read Error on the SSL Socket\nShutting it down!"); pqioutput(PQL_WARNING, pqissllistenzone, "Read Error on the SSL Socket\nShutting it down!");
@ -502,20 +499,11 @@ int pqissllistenbase::continueSSL(IncomingSSLInfo& incoming_connexion_info, bool
// //
X509 *x509 = SSL_get_peer_certificate(incoming_connexion_info.ssl) ; X509 *x509 = SSL_get_peer_certificate(incoming_connexion_info.ssl) ;
#ifdef DEBUG_LISTENNER if(x509)
std::cerr << "Info from certificate: " << std::endl;
#endif
if(x509 != NULL)
{ {
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) incoming_connexion_info.gpgid = RsX509Cert::getCertIssuer(*x509);
incoming_connexion_info.gpgid = RsPgpId(std::string(getX509CNString(x509->cert_info->issuer))); incoming_connexion_info.sslcn = RsX509Cert::getCertName(*x509);
incoming_connexion_info.sslcn = getX509CNString(x509->cert_info->subject); incoming_connexion_info.sslid = RsX509Cert::getCertSslId(*x509);
#else
incoming_connexion_info.gpgid = RsPgpId(std::string(getX509CNString(X509_get_issuer_name(x509))));
incoming_connexion_info.sslcn = getX509CNString(X509_get_subject_name(x509));
#endif
getX509id(x509,incoming_connexion_info.sslid);
#ifdef DEBUG_LISTENNER #ifdef DEBUG_LISTENNER
std::cerr << " Got PGP Id = " << incoming_connexion_info.gpgid << std::endl; std::cerr << " Got PGP Id = " << incoming_connexion_info.gpgid << std::endl;
@ -571,61 +559,6 @@ int pqissllistenbase::closeConnection(int fd, SSL *ssl)
return 1; return 1;
} }
int pqissllistenbase::Extract_Failed_SSL_Certificate(const IncomingSSLInfo& info)
{
pqioutput(PQL_DEBUG_BASIC, pqissllistenzone, "pqissllistenbase::Extract_Failed_SSL_Certificate()");
std::cerr << "pqissllistenbase::Extract_Failed_SSL_Certificate() FAILED CONNECTION due to security!";
std::cerr << std::endl;
// Get the Peer Certificate....
X509 *peercert = SSL_get_peer_certificate(info.ssl);
std::cerr << "Extract_Failed_SSL_Certificate: " << std::endl;
std::cerr << " SSL = " << (void*)info.ssl << std::endl;
std::cerr << " GPG id = " << info.gpgid << std::endl;
std::cerr << " SSL id = " << info.sslid << std::endl;
std::cerr << " SSL cn = " << info.sslcn << std::endl;
std::cerr << " addr+p = " << sockaddr_storage_tostring(info.addr) << std::endl;
if (peercert == NULL)
{
std::string out;
out += "pqissllistenbase::Extract_Failed_SSL_Certificate() from: ";
out += sockaddr_storage_tostring(info.addr);
out += " ERROR Peer didn't give Cert!";
std::cerr << out << std::endl;
AuthSSL::getAuthSSL()->FailedCertificate(peercert, info.gpgid,info.sslid,info.sslcn,info.addr, true);
pqioutput(PQL_WARNING, pqissllistenzone, out);
return -1;
}
pqioutput(PQL_DEBUG_BASIC, pqissllistenzone,
"pqissllistenbase::Extract_Failed_SSL_Certificate() Have Peer Cert - Registering");
{
std::string out;
out += "pqissllistenbase::Extract_Failed_SSL_Certificate() from: ";
out += sockaddr_storage_tostring(info.addr);
out += " Passing Cert to AuthSSL() for analysis";
std::cerr << out << std::endl;
pqioutput(PQL_WARNING, pqissllistenzone, out);
std::cerr << out << std::endl;
}
// save certificate... (and ip locations)
// false for outgoing....
AuthSSL::getAuthSSL()->FailedCertificate(peercert, info.gpgid,info.sslid,info.sslcn,info.addr, true);
return 1;
}
int pqissllistenbase::continueaccepts() int pqissllistenbase::continueaccepts()
{ {
@ -831,90 +764,67 @@ int pqissllistener::status()
int pqissllistener::completeConnection(int fd, IncomingSSLInfo& info) int pqissllistener::completeConnection(int fd, IncomingSSLInfo& info)
{ {
constexpr int failure = -1;
constexpr int success = 1;
// Get the Peer Certificate.... // Get the Peer Certificate....
X509* peercert = SSL_get_peer_certificate(info.ssl); X509* peercert = SSL_get_peer_certificate(info.ssl);
if(!peercert)
if (peercert == NULL)
{ {
pqioutput(PQL_WARNING, pqissllistenzone, RsFatal() << __PRETTY_FUNCTION__ << " failed to retrieve peer "
"pqissllistener::completeConnection() Peer Did Not Provide Cert!"); << "certificate at this point this should never happen!"
<< std::endl;
// failure -1, pending 0, sucess 1. print_stacktrace();
// pqissllistenbase will shutdown! exit(failure);
return -1;
} }
// Check cert. RsPgpId pgpId = RsX509Cert::getCertIssuer(*peercert);
RsPeerId newPeerId; RsPeerId newPeerId = RsX509Cert::getCertSslId(*peercert);
#ifdef RS_PQISSL_AUTH_REDUNDANT_CHECK
/* At this point the actual connection authentication has already been
* performed in AuthSSL::VerifyX509Callback, any furter authentication check
* like the following two are redundant. */
/**** uint32_t authErrCode = 0;
* As the validation is actually done before this... if(!AuthSSL::instance().AuthX509WithGPG(peercert, authErrCode))
* we should only need to call CheckCertificate here! {
****/ RsFatal() << __PRETTY_FUNCTION__ << " failure verifying peer "
<< "certificate signature. This should never happen at this "
<< "point!" << std::endl;
print_stacktrace();
exit(failure);
}
bool certOk = AuthSSL::getAuthSSL()->ValidateCertificate(peercert, newPeerId); if( !AuthGPG::getAuthGPG()->isGPGAccepted(pgpId) )
{
RsErr() << __PRETTY_FUNCTION__ << " pgpId: " << pgpId
<< " is not friend. It is very unlikely to happen at this "
<< "point! Either the user must have been so fast to deny "
<< "friendship just after VerifyX509Callback have returned "
<< "success and just before this code being executed, or "
<< "something really fishy is happening! Share the full log "
<< "with developers." << std::endl;
print_stacktrace();
exit(failure);
}
#endif //def RS_PQISSL_AUTH_REDUNDANT_CHECK
bool found = false; bool found = false;
std::map<RsPeerId, pqissl *>::iterator it; for(auto it = listenaddr.begin(); !found && it != listenaddr.end(); )
// Let connected one through as well! if ((npc == NULL) || (npc -> Connected()))
if (!certOk)
{ {
pqioutput(PQL_WARNING, pqissllistenzone, if (it -> first == newPeerId) found = true;
"pqissllistener::completeConnection() registerCertificate Failed!"); else ++it;
// bad - shutdown.
// pqissllistenbase will shutdown!
X509_free(peercert);
return -1;
}
else
{
std::string out = "pqissllistener::continueSSL()\nchecking: " + newPeerId.toStdString() + "\n";
// check if cert is in our list.....
for(it = listenaddr.begin();(found!=true) && (it!=listenaddr.end());)
{
out + "\tagainst: " + it->first.toStdString() + "\n";
if (it -> first == newPeerId)
{
// accept even if already connected.
out += "\t\tMatch!";
found = true;
}
else
{
++it;
}
}
pqioutput(PQL_DEBUG_BASIC, pqissllistenzone, out);
} }
if (found == false) if (found == false)
{ {
std::string out = "No Matching Certificate for Connection:"; Dbg1() << __PRETTY_FUNCTION__ << " got secure connection from address: "
out += sockaddr_storage_tostring(info.addr); << info.addr << " with previously unknown SSL certificate: "
out += "\npqissllistenbase: Will shut it down!"; << newPeerId << " signed by PGP friend: " << pgpId
pqioutput(PQL_WARNING, pqissllistenzone, out); << ". Adding the new location as SSL friend." << std::endl;
// but as it passed the authentication step, mPeerMgr->addFriend(newPeerId, pgpId);
// we can add it into the AuthSSL, and mConnMgr.
AuthSSL::getAuthSSL()->CheckCertificate(newPeerId, peercert);
/* now need to get GPG id too */
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
RsPgpId pgpid(std::string(getX509CNString(peercert->cert_info->issuer)));
#else
RsPgpId pgpid(std::string(getX509CNString(X509_get_issuer_name(peercert))));
#endif
mPeerMgr->addFriend(newPeerId, pgpid);
X509_free(peercert);
return -1;
} }
// Cleanup cert. // Cleanup cert.
@ -926,17 +836,14 @@ int pqissllistener::completeConnection(int fd, IncomingSSLInfo& info)
as.mSSL = info.ssl; as.mSSL = info.ssl;
as.mPeerId = newPeerId; as.mPeerId = newPeerId;
as.mAddr = info.addr; as.mAddr = info.addr;
as.mAcceptTS = time(NULL); as.mAcceptTS = time(nullptr);
accepted_ssl.push_back(as); accepted_ssl.push_back(as);
std::string out = "pqissllistener::completeConnection() Successful Connection with: " + newPeerId.toStdString(); Dbg1() << __PRETTY_FUNCTION__ << "Successful Connection with: "
out += " for Connection:"; << newPeerId << " with address: " << info.addr << std::endl;
out += sockaddr_storage_tostring(info.addr);
out += " Adding to WAIT-ACCEPT Queue";
pqioutput(PQL_WARNING, pqissllistenzone, out);
return 1; return success;
} }
int pqissllistener::finaliseConnection(int fd, SSL *ssl, const RsPeerId& peerId, const struct sockaddr_storage &remote_addr) int pqissllistener::finaliseConnection(int fd, SSL *ssl, const RsPeerId& peerId, const struct sockaddr_storage &remote_addr)

View file

@ -19,21 +19,20 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * * along with this program. If not, see <https://www.gnu.org/licenses/>. *
* * * *
*******************************************************************************/ *******************************************************************************/
#ifndef MRK_PQI_SSL_LISTEN_HEADER #pragma once
#define MRK_PQI_SSL_LISTEN_HEADER
#include <openssl/ssl.h> #include <openssl/ssl.h>
// operating system specific network header.
#include "pqi/pqinetwork.h"
#include <string> #include <string>
#include <map> #include <map>
#include "pqi/pqi_base.h" #include "pqi/pqi_base.h"
#include "pqi/pqilistener.h" #include "pqi/pqilistener.h"
#include "pqi/authssl.h" #include "pqi/authssl.h"
#include "util/rsdebug.h"
#include "pqi/pqinetwork.h"
#define RS_PQISSL_AUTH_REDUNDANT_CHECK 1
/***************************** pqi Net SSL Interface ********************************* /***************************** pqi Net SSL Interface *********************************
*/ */
@ -98,7 +97,7 @@ protected:
p3PeerMgr *mPeerMgr; p3PeerMgr *mPeerMgr;
private: private:
int Extract_Failed_SSL_Certificate(const IncomingSSLInfo&);
bool active; bool active;
int lsock; int lsock;
std::list<IncomingSSLInfo> incoming_ssl ; std::list<IncomingSSLInfo> incoming_ssl ;
@ -122,7 +121,6 @@ public:
private: private:
std::map<RsPeerId, pqissl*> listenaddr; std::map<RsPeerId, pqissl*> listenaddr;
RS_SET_CONTEXT_DEBUG_LEVEL(2)
}; };
#endif // MRK_PQI_SSL_LISTEN_HEADER

View file

@ -31,6 +31,7 @@
#include "pqi/pqi_base.h" #include "pqi/pqi_base.h"
#include "util/rsdir.h" #include "util/rsdir.h"
#include "util/rsstring.h" #include "util/rsstring.h"
#include "pqi/authssl.h"
#include <openssl/ssl.h> #include <openssl/ssl.h>
#include <openssl/err.h> #include <openssl/err.h>
@ -675,13 +676,6 @@ int pem_passwd_cb(char *buf, int size, int rwflag, void *password)
return(strlen(buf)); return(strlen(buf));
} }
/* XXX FIX */
bool CheckX509Certificate(X509 */*x509*/)
{
return true;
}
uint64_t getX509SerialNumber(X509 *cert) uint64_t getX509SerialNumber(X509 *cert)
{ {
ASN1_INTEGER *serial = X509_get_serialNumber(cert); ASN1_INTEGER *serial = X509_get_serialNumber(cert);
@ -711,67 +705,39 @@ uint32_t getX509RetroshareCertificateVersion(X509 *cert)
} }
} }
// Not dependent on sslroot. load, and detroys the X509 memory. int LoadCheckX509(
int LoadCheckX509(const char *cert_file, RsPgpId& issuerName, std::string &location, RsPeerId &userId) const char* cert_file, RsPgpId& issuer, std::string& location,
RsPeerId& userId )
{ {
/* This function loads the X509 certificate from the file, constexpr int failure = 0;
* and checks the certificate constexpr int success = 1;
*/
FILE *tmpfp = RsDirUtil::rs_fopen(cert_file, "r"); FILE *tmpfp = RsDirUtil::rs_fopen(cert_file, "r");
if (tmpfp == NULL) if (tmpfp == nullptr)
{ {
#ifdef AUTHSSL_DEBUG RsErr() << __PRETTY_FUNCTION__ << " Failed to open Certificate File: "
std::cerr << "sslroot::LoadCheckAndGetX509Name()"; << cert_file << std::endl;
std::cerr << " Failed to open Certificate File:" << cert_file; return failure;
std::cerr << std::endl;
#endif
return 0;
} }
// get xPGP certificate. // get xPGP certificate.
X509 *x509 = PEM_read_X509(tmpfp, NULL, NULL, NULL); X509* x509 = PEM_read_X509(tmpfp, nullptr, nullptr, nullptr);
fclose(tmpfp); fclose(tmpfp);
// check the certificate. if(!x509)
bool valid = false;
if (x509)
{ {
valid = CheckX509Certificate(x509); RsErr() << __PRETTY_FUNCTION__ << " PEM_read_X509 failed!" << std::endl;
if (valid) return failure;
{
valid = getX509id(x509, userId);
}
} }
if (valid) userId = RsX509Cert::getCertSslId(*x509);
{ issuer = RsX509Cert::getCertIssuer(*x509);
// extract the name. location = RsX509Cert::getCertLocation(*x509);
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
issuerName = RsPgpId(std::string(getX509CNString(x509->cert_info->issuer)));
location = getX509LocString(x509->cert_info->subject);
#else
issuerName = RsPgpId(std::string(getX509CNString(X509_get_issuer_name(x509))));
location = getX509LocString(X509_get_subject_name(x509));
#endif
}
#ifdef AUTHSSL_DEBUG
std::cout << getX509Info(x509) << std::endl ;
#endif
// clean up.
X509_free(x509); X509_free(x509);
if (valid) if(userId.isNull() || issuer.isNull()) return failure;
{ else return success;
// happy!
return 1;
}
else
{
// something went wrong!
return 0;
}
} }
std::string getX509NameString(X509_NAME *name) std::string getX509NameString(X509_NAME *name)
@ -896,10 +862,9 @@ std::string getX509Info(X509 *cert)
/********** SSL ERROR STUFF ******************************************/ /********** SSL ERROR STUFF ******************************************/
int printSSLError(SSL *ssl, int retval, int err, unsigned long err2, std::string &out) int printSSLError(
SSL*, int retval, int err, unsigned long err2, std::string& out )
{ {
(void) ssl; /* remove unused parameter warnings */
std::string reason; std::string reason;
std::string mainreason = std::string("UNKNOWN ERROR CODE"); std::string mainreason = std::string("UNKNOWN ERROR CODE");
@ -939,7 +904,18 @@ int printSSLError(SSL *ssl, int retval, int err, unsigned long err2, std::string
{ {
mainreason = std::string("SSL_ERROR_SSL"); mainreason = std::string("SSL_ERROR_SSL");
} }
rs_sprintf_append(out, "RetVal(%d) -> SSL Error: %s\n\t + ERR Error: %s\n", retval, mainreason.c_str(), ERR_error_string(err2, NULL)); rs_sprintf_append( out,
"RetVal(%d) -> SSL Error: %s\n\t + ERR Error: %s\n",
retval, mainreason.c_str(),
ERR_error_string(err2, nullptr) );
return 1; return 1;
} }
std::string sslErrorToString(int retval, int err, unsigned long err2)
{
std::string ret;
// When printSSLError will be removed it's code will be moved here
printSSLError(nullptr, retval, err, err2, ret);
return ret;
}

View file

@ -1,4 +1,4 @@
/******************************************************************************* /*******************************************************************************
* libretroshare/src/pqi: sslfns.h * * libretroshare/src/pqi: sslfns.h *
* * * *
* libretroshare: retroshare core library * * libretroshare: retroshare core library *
@ -19,8 +19,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * * along with this program. If not, see <https://www.gnu.org/licenses/>. *
* * * *
*******************************************************************************/ *******************************************************************************/
#ifndef RS_PQI_SSL_HELPER_H #pragma once
#define RS_PQI_SSL_HELPER_H
/* Functions in this file are SSL only, /* Functions in this file are SSL only,
* and have no dependence on SSLRoot() etc. * and have no dependence on SSLRoot() etc.
@ -32,9 +31,12 @@
#include <openssl/evp.h> #include <openssl/evp.h>
#include <openssl/x509.h> #include <openssl/x509.h>
#include <inttypes.h>
#include <retroshare/rstypes.h>
#include <string> #include <string>
#include <inttypes.h>
#include "util/rsdeprecate.h"
#include "retroshare/rstypes.h"
/**** /****
* #define AUTHSSL_DEBUG 1 * #define AUTHSSL_DEBUG 1
@ -113,9 +115,12 @@ bool getX509id(X509 *x509, RsPeerId &xid);
int pem_passwd_cb(char *buf, int size, int rwflag, void *password); int pem_passwd_cb(char *buf, int size, int rwflag, void *password);
bool CheckX509Certificate(X509 *x509); /** This function loads the X509 certificate from the file, and checks the
// Not dependent on sslroot. load, and detroys the X509 memory. * certificate.
int LoadCheckX509(const char *cert_file, RsPgpId& issuer, std::string &location, RsPeerId& userId); * Not dependent on sslroot. load, and detroys the X509 memory. */
int LoadCheckX509(
const char* cert_file, RsPgpId& issuer, std::string& location,
RsPeerId& userId );
std::string getX509NameString(X509_NAME *name); std::string getX509NameString(X509_NAME *name);
@ -131,7 +136,8 @@ uint32_t getX509RetroshareCertificateVersion(X509 *cert) ;
/********** SSL ERROR STUFF ******************************************/ /********** SSL ERROR STUFF ******************************************/
int printSSLError(SSL *ssl, int retval, int err, unsigned long err2, std::string &out); RS_DEPRECATED_FOR(sslErrorToString)
int printSSLError(
#endif /* RS_PQI_SSL_HELPER_H */ SSL* unused, int retval, int err, unsigned long err2, std::string& out);
std::string sslErrorToString(int retval, int err, unsigned long err2);

View file

@ -397,9 +397,8 @@ int RsInit::InitRetroShare(int argc, char **argv, bool /* strictCheck */)
* 2) Get List of Available Accounts. * 2) Get List of Available Accounts.
* 4) Get List of GPG Accounts. * 4) Get List of GPG Accounts.
*/ */
/* create singletons */ /* Initialize AuthSSL */
AuthSSL::AuthSSLInit(); AuthSSL::instance().InitAuth(nullptr, nullptr, nullptr, "");
AuthSSL::getAuthSSL() -> InitAuth(NULL, NULL, NULL, "");
rsLoginHelper = new RsLoginHelper; rsLoginHelper = new RsLoginHelper;