mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-01-31 17:53:28 -05:00
260 lines
9.1 KiB
C++
260 lines
9.1 KiB
C++
/*******************************************************************************
|
|
* libretroshare/src/pqi: authssl.h *
|
|
* *
|
|
* libretroshare: retroshare core library *
|
|
* *
|
|
* 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 *
|
|
* it under the terms of the GNU Lesser General Public License as *
|
|
* published by the Free Software Foundation, either version 3 of the *
|
|
* License, or (at your option) any later version. *
|
|
* *
|
|
* This program is distributed in the hope that it will be useful, *
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
* GNU Lesser General Public License for more details. *
|
|
* *
|
|
* You should have received a copy of the GNU Lesser General Public License *
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
|
|
* *
|
|
*******************************************************************************/
|
|
#pragma once
|
|
|
|
|
|
#include <openssl/evp.h>
|
|
#include <openssl/x509.h>
|
|
|
|
#include <string>
|
|
#include <map>
|
|
|
|
#include "util/rsthreads.h"
|
|
#include "pqi/pqi_base.h"
|
|
#include "pqi/pqinetwork.h"
|
|
#include "pqi/p3cfgmgr.h"
|
|
#include "util/rsmemory.h"
|
|
#include "retroshare/rsevents.h"
|
|
|
|
/**
|
|
* Functions to interact elegantly with X509 certificates, using this functions
|
|
* you can avoid annoying #ifdef *SSL_VERSION_NUMBER all around the code.
|
|
* Function names should be self descriptive.
|
|
*/
|
|
namespace RsX509Cert
|
|
{
|
|
std::string getCertName(const X509& x509);
|
|
std::string getCertLocation(const X509& x509);
|
|
std::string getCertOrg(const X509& x509);
|
|
RsPgpId getCertIssuer(const X509& x509);
|
|
std::string getCertIssuerString(const X509& x509);
|
|
RsPeerId getCertSslId(const X509& x509);
|
|
const EVP_PKEY* getPubKey(const X509& x509);
|
|
};
|
|
|
|
/**
|
|
* This is an implementation of SSL certificate authentication with PGP
|
|
* signatures, instead of centralized certification authority.
|
|
*/
|
|
class AuthSSL
|
|
{
|
|
public:
|
|
static AuthSSL& instance();
|
|
|
|
RS_DEPRECATED_FOR(AuthSSL::instance())
|
|
static AuthSSL* getAuthSSL();
|
|
|
|
/* Initialisation Functions (Unique) */
|
|
virtual bool validateOwnCertificate(X509 *x509, EVP_PKEY *pkey) = 0;
|
|
|
|
virtual bool active() = 0;
|
|
virtual int InitAuth(
|
|
const char* srvr_cert, const char* priv_key, const char* passwd,
|
|
std::string locationName ) = 0;
|
|
virtual bool CloseAuth() = 0;
|
|
|
|
/*********** Overloaded Functions from p3AuthMgr **********/
|
|
|
|
/* get Certificate Id */
|
|
virtual const RsPeerId& OwnId() = 0;
|
|
virtual std::string getOwnLocation() = 0;
|
|
|
|
/* Load/Save certificates */
|
|
virtual std::string SaveOwnCertificateToString() = 0;
|
|
|
|
/* Sign / Encrypt / Verify Data */
|
|
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 SignDataBin(std::string, unsigned char*, unsigned int*) = 0;
|
|
virtual bool SignDataBin(
|
|
const void*, uint32_t, unsigned char*, unsigned int* ) = 0;
|
|
virtual bool VerifyOwnSignBin(
|
|
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 failed
|
|
virtual bool encrypt(
|
|
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 X509* SignX509ReqWithGPG(X509_REQ* req, long days) = 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
|
|
* @param[in] verbose if true, prints the authentication result to screen.
|
|
* @return true if correctly signed, false otherwise
|
|
*/
|
|
virtual bool AuthX509WithGPG(
|
|
X509* x509,
|
|
bool verbose,
|
|
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;
|
|
|
|
/// SSL specific functions used in pqissl/pqissllistener
|
|
virtual SSL_CTX* getCTX() = 0;
|
|
|
|
/**
|
|
* This function parse X509 certificate from the file and return some
|
|
* verified informations, like ID and signer
|
|
* @return false on error, true otherwise
|
|
*/
|
|
virtual bool parseX509DetailsFromFile(
|
|
const std::string& certFilePath, RsPeerId& certId, RsPgpId& issuer,
|
|
std::string& location ) = 0;
|
|
|
|
virtual ~AuthSSL();
|
|
|
|
protected:
|
|
AuthSSL() {}
|
|
|
|
RS_SET_CONTEXT_DEBUG_LEVEL(2)
|
|
};
|
|
|
|
|
|
class AuthSSLimpl : public AuthSSL, public p3Config
|
|
{
|
|
public:
|
|
|
|
/** Initialisation Functions (Unique) */
|
|
AuthSSLimpl();
|
|
bool validateOwnCertificate(X509 *x509, EVP_PKEY *pkey) override;
|
|
|
|
bool active() override;
|
|
int InitAuth( const char *srvr_cert, const char *priv_key,
|
|
const char *passwd, std::string locationName )
|
|
override;
|
|
|
|
bool CloseAuth() override;
|
|
|
|
/*********** Overloaded Functions from p3AuthMgr **********/
|
|
|
|
const RsPeerId& OwnId() override;
|
|
virtual std::string getOwnLocation() override;
|
|
|
|
/* Load/Save certificates */
|
|
virtual std::string SaveOwnCertificateToString() override;
|
|
|
|
/* Sign / Encrypt / Verify Data */
|
|
bool SignData(std::string input, std::string &sign) override;
|
|
bool SignData(
|
|
const void *data, const uint32_t len, std::string &sign) override;
|
|
|
|
bool SignDataBin(std::string, unsigned char*, unsigned int*) override;
|
|
virtual bool SignDataBin(
|
|
const void*, uint32_t, unsigned char*, unsigned int*) override;
|
|
bool VerifyOwnSignBin(
|
|
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;
|
|
|
|
bool encrypt(
|
|
void*& out, int& outlen, const void* in, int inlen,
|
|
const RsPeerId& peerId ) override;
|
|
bool decrypt(void *&out, int &outlen, const void *in, int inlen) override;
|
|
|
|
virtual X509* SignX509ReqWithGPG(X509_REQ *req, long days) override;
|
|
|
|
/// @see AuthSSL
|
|
bool AuthX509WithGPG(X509 *x509, bool verbose, uint32_t& auth_diagnostic) override;
|
|
|
|
/// @see AuthSSL
|
|
int VerifyX509Callback(int preverify_ok, X509_STORE_CTX *ctx) override;
|
|
|
|
/// @see AuthSSL
|
|
bool parseX509DetailsFromFile(
|
|
const std::string& certFilePath, RsPeerId& certId,
|
|
RsPgpId& issuer, std::string& location ) override;
|
|
|
|
|
|
/*****************************************************************/
|
|
/*********************** p3config ******************************/
|
|
/* Key Functions to be overloaded for Full Configuration */
|
|
RsSerialiser* setupSerialiser() override;
|
|
bool saveList(bool &cleanup, std::list<RsItem *>& ) override;
|
|
bool loadList(std::list<RsItem *>& load) override;
|
|
/*****************************************************************/
|
|
|
|
public:
|
|
/* SSL specific functions used in pqissl/pqissllistener */
|
|
SSL_CTX* getCTX() override;
|
|
|
|
private:
|
|
|
|
bool LocalStoreCert(X509* x509);
|
|
bool RemoveX509(const RsPeerId id);
|
|
|
|
/*********** LOCKED Functions ******/
|
|
bool locked_FindCert(const RsPeerId& id, X509** cert);
|
|
|
|
/* Data */
|
|
/* these variables are constants -> don't need to protect */
|
|
SSL_CTX *sslctx;
|
|
RsPeerId mOwnId;
|
|
X509* mOwnCert;
|
|
|
|
/**
|
|
* If the location name is included in SSL certificate it becomes a public
|
|
* information, because anyone able to open an SSL connection to the host is
|
|
* able to read it. To avoid that location name is now stored separately and
|
|
* and not included in the SSL certificate.
|
|
*/
|
|
std::string mOwnLocationName;
|
|
|
|
RsMutex sslMtx; /* protects all below */
|
|
|
|
EVP_PKEY* mOwnPrivateKey;
|
|
EVP_PKEY* mOwnPublicKey;
|
|
|
|
int init;
|
|
std::map<RsPeerId, X509*> mCerts;
|
|
|
|
RsPgpId _last_gpgid_to_connect;
|
|
std::string _last_sslcn_to_connect;
|
|
RsPeerId _last_sslid_to_connect;
|
|
};
|