/******************************************************************************* * libretroshare/src/pqi: authssl.h * * * * libretroshare: retroshare core library * * * * Copyright (C) 2004-2008 Robert Fernie * * Copyright (C) 2019 Gioacchino Mazzurco * * * * 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 . * * * *******************************************************************************/ #pragma once #include #include #include #include #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" #include "retroshare/rsinit.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; // Loads the public/private keypair and sets it to be used in TLS handshakes. // Return values: // true : ok // false : error // virtual bool InitAuth( const char* srvr_cert, const char* priv_key, const char* passwd, std::string locationName,RsInit::LoadCertificateStatus& error_code ) = 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(); virtual ~AuthSSLimpl(); bool validateOwnCertificate(X509 *x509, EVP_PKEY *pkey) override; bool active() override; virtual bool InitAuth( const char* srvr_cert, const char* priv_key, const char* passwd, std::string locationName,RsInit::LoadCertificateStatus& error_code ) 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& ) override; bool loadList(std::list& 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 mCerts; RsPgpId _last_gpgid_to_connect; std::string _last_sslcn_to_connect; RsPeerId _last_sslid_to_connect; };