2009-04-22 23:29:16 +00:00
/*
* libretroshare / src / pqi : authssl . cc
*
* 3 P / PQI network interface for RetroShare .
*
* Copyright 2004 - 2008 by Robert Fernie .
*
* This library is free software ; you can redistribute it and / or
* modify it under the terms of the GNU Library General Public
* License Version 2 as published by the Free Software Foundation .
*
* This library 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
* Library General Public License for more details .
*
* You should have received a copy of the GNU Library General Public
* License along with this library ; if not , write to the Free Software
* Foundation , Inc . , 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307
* USA .
*
* Please report all bugs and problems to " retroshare@lunamutt.com " .
*
*
* This class is designed to provide authentication using ssl certificates
* only . It is intended to be wrapped by an gpgauthmgr to provide
* pgp + ssl web - of - trust authentication .
*
*/
2012-10-09 23:07:51 +00:00
# ifdef WINDOWS_SYS
# include "util/rswin.h"
# endif // WINDOWS_SYS
2009-04-22 23:29:16 +00:00
# include "authssl.h"
2010-06-26 12:31:24 +00:00
# include "sslfns.h"
2009-04-22 23:29:16 +00:00
# include "pqinetwork.h"
2010-01-13 20:58:58 +00:00
# include "authgpg.h"
2017-04-24 22:47:08 +02:00
# include "rsitems/rsconfigitems.h"
2011-04-03 23:11:38 +00:00
# include "util/rsdir.h"
2012-04-14 22:38:24 +00:00
# include "util/rsstring.h"
2017-11-19 18:21:56 +01:00
# include "pgp/pgpkeyutil.h"
2009-04-22 23:29:16 +00:00
2011-08-07 21:11:00 +00:00
# include "retroshare/rspeers.h" // for RsPeerDetails structure
2017-11-19 19:34:54 +01:00
# include "retroshare/rsids.h" // for RsPeerDetails structure
2014-01-07 22:51:22 +00:00
# include "rsserver/p3face.h"
2011-08-07 21:11:00 +00:00
2009-04-22 23:29:16 +00:00
/******************** notify of new Cert **************************/
# include <openssl/rand.h>
2013-09-26 23:53:06 +00:00
# include <openssl/ssl.h>
2009-04-22 23:29:16 +00:00
# include <iomanip>
2014-01-15 20:19:17 +00:00
/* SSL connection diagnostic */
2017-11-19 18:21:56 +01:00
const uint32_t RS_SSL_HANDSHAKE_DIAGNOSTIC_UNKNOWN = 0x00 ;
const uint32_t RS_SSL_HANDSHAKE_DIAGNOSTIC_OK = 0x01 ;
const uint32_t RS_SSL_HANDSHAKE_DIAGNOSTIC_CERTIFICATE_NOT_VALID = 0x02 ;
const uint32_t RS_SSL_HANDSHAKE_DIAGNOSTIC_ISSUER_UNKNOWN = 0x03 ;
const uint32_t RS_SSL_HANDSHAKE_DIAGNOSTIC_MALLOC_ERROR = 0x04 ;
const uint32_t RS_SSL_HANDSHAKE_DIAGNOSTIC_WRONG_SIGNATURE = 0x05 ;
const uint32_t RS_SSL_HANDSHAKE_DIAGNOSTIC_CERTIFICATE_MISSING = 0x06 ;
const uint32_t RS_SSL_HANDSHAKE_DIAGNOSTIC_HASH_ALGORITHM_NOT_ACCEPTED = 0x07 ;
const uint32_t RS_SSL_HANDSHAKE_DIAGNOSTIC_KEY_ALGORITHM_NOT_ACCEPTED = 0x08 ;
const uint32_t RS_SSL_HANDSHAKE_DIAGNOSTIC_WRONG_SIGNATURE_TYPE = 0x09 ;
const uint32_t RS_SSL_HANDSHAKE_DIAGNOSTIC_WRONG_SIGNATURE_VERSION = 0x0a ;
2014-01-15 20:19:17 +00:00
2010-06-24 18:06:10 +00:00
/****
* # define AUTHSSL_DEBUG 1
* * */
2011-07-11 00:55:06 +00:00
// initialisation du pointeur de singleton
2012-12-26 18:12:19 +00:00
AuthSSL * AuthSSL : : instance_ssl = NULL ;
2012-05-15 13:51:24 +00:00
static pthread_mutex_t * mutex_buf = NULL ;
struct CRYPTO_dynlock_value
{
pthread_mutex_t mutex ;
} ;
/**
* OpenSSL locking function .
*
* @ param mode lock mode
* @ param n lock number
* @ param file source file name
* @ param line source file line number
* @ return none
*/
static void locking_function ( int mode , int n , const char */ * file */ , int /*line*/ )
{
if ( mode & CRYPTO_LOCK ) {
pthread_mutex_lock ( & mutex_buf [ n ] ) ;
} else {
pthread_mutex_unlock ( & mutex_buf [ n ] ) ;
}
}
/**
* OpenSSL uniq id function .
*
* @ return thread id
*/
static unsigned long id_function ( void )
{
2013-10-21 11:00:49 +00:00
# if defined( WINDOWS_SYS) && !defined(WIN_PTHREADS_H)
2012-05-15 13:51:24 +00:00
return ( unsigned long ) pthread_self ( ) . p ;
# else
return ( unsigned long ) pthread_self ( ) ;
# endif
}
/**
* OpenSSL allocate and initialize dynamic crypto lock .
*
* @ param file source file name
* @ param line source file line number
*/
static struct CRYPTO_dynlock_value * dyn_create_function ( const char */ * file */ , int /*line*/ )
{
struct CRYPTO_dynlock_value * value ;
2016-01-12 21:43:04 -05:00
value = ( struct CRYPTO_dynlock_value * ) rs_malloc ( sizeof ( struct CRYPTO_dynlock_value ) ) ;
2016-01-12 21:10:11 -05:00
if ( ! value )
2012-05-15 13:51:24 +00:00
return NULL ;
2016-01-12 21:10:11 -05:00
2012-05-15 13:51:24 +00:00
pthread_mutex_init ( & value - > mutex , NULL ) ;
return value ;
}
/**
* OpenSSL dynamic locking function .
*
* @ param mode lock mode
* @ param l lock structure pointer
* @ param file source file name
* @ param line source file line number
* @ return none
*/
static void dyn_lock_function ( int mode , struct CRYPTO_dynlock_value * l , const char */ * file */ , int /*line*/ )
{
if ( mode & CRYPTO_LOCK ) {
pthread_mutex_lock ( & l - > mutex ) ;
} else {
pthread_mutex_unlock ( & l - > mutex ) ;
}
}
/**
* OpenSSL destroy dynamic crypto lock .
*
* @ param l lock structure pointer
* @ param file source file name
* @ param line source file line number
* @ return none
*/
static void dyn_destroy_function ( struct CRYPTO_dynlock_value * l , const char */ * file */ , int /*line*/ )
{
pthread_mutex_destroy ( & l - > mutex ) ;
free ( l ) ;
}
/**
* Initialize TLS library .
*
* @ return true on success , false on error
*/
bool tls_init ( )
{
/* static locks area */
2016-01-12 21:43:04 -05:00
mutex_buf = ( pthread_mutex_t * ) rs_malloc ( CRYPTO_num_locks ( ) * sizeof ( pthread_mutex_t ) ) ;
2016-01-12 21:10:11 -05:00
if ( mutex_buf = = NULL )
2012-05-15 13:51:24 +00:00
return false ;
2016-01-12 21:10:11 -05:00
2012-05-15 13:51:24 +00:00
for ( int i = 0 ; i < CRYPTO_num_locks ( ) ; i + + ) {
pthread_mutex_init ( & mutex_buf [ i ] , NULL ) ;
}
/* static locks callbacks */
CRYPTO_set_locking_callback ( locking_function ) ;
CRYPTO_set_id_callback ( id_function ) ;
/* dynamic locks callbacks */
CRYPTO_set_dynlock_create_callback ( dyn_create_function ) ;
CRYPTO_set_dynlock_lock_callback ( dyn_lock_function ) ;
CRYPTO_set_dynlock_destroy_callback ( dyn_destroy_function ) ;
return true ;
}
/**
* Cleanup TLS library .
*
* @ return 0
*/
void tls_cleanup ( )
{
CRYPTO_set_dynlock_create_callback ( NULL ) ;
CRYPTO_set_dynlock_lock_callback ( NULL ) ;
CRYPTO_set_dynlock_destroy_callback ( NULL ) ;
CRYPTO_set_locking_callback ( NULL ) ;
CRYPTO_set_id_callback ( NULL ) ;
2015-10-07 18:59:58 -04:00
if ( mutex_buf ! = NULL ) {
2012-05-15 13:51:24 +00:00
for ( int i = 0 ; i < CRYPTO_num_locks ( ) ; i + + ) {
pthread_mutex_destroy ( & mutex_buf [ i ] ) ;
}
free ( mutex_buf ) ;
mutex_buf = NULL ;
}
}
2010-07-04 10:35:38 +00:00
/* hidden function - for testing purposes() */
2012-12-26 18:12:19 +00:00
void AuthSSL : : setAuthSSL_debug ( AuthSSL * newssl )
2010-07-04 10:35:38 +00:00
{
instance_ssl = newssl ;
}
2012-12-26 18:12:19 +00:00
void AuthSSL : : AuthSSLInit ( )
2010-07-04 10:35:38 +00:00
{
2012-06-10 00:29:46 +00:00
if ( instance_ssl = = NULL )
{
instance_ssl = new AuthSSLimpl ( ) ;
}
2010-07-04 10:35:38 +00:00
}
AuthSSL * AuthSSL : : getAuthSSL ( )
{
return instance_ssl ;
}
AuthSSL : : AuthSSL ( )
{
return ;
}
2009-04-22 23:29:16 +00:00
/********************************************************************************/
/********************************************************************************/
2010-06-26 12:31:24 +00:00
/********************* Cert Search / Add / Remove **************************/
2009-04-22 23:29:16 +00:00
/********************************************************************************/
2010-06-26 12:31:24 +00:00
/********************************************************************************/
static int verify_x509_callback ( int preverify_ok , X509_STORE_CTX * ctx ) ;
2009-04-22 23:29:16 +00:00
2010-06-24 17:41:34 +00:00
2014-03-17 20:56:06 +00:00
sslcert : : sslcert ( X509 * x509 , const RsPeerId & pid )
2009-04-22 23:29:16 +00:00
{
certificate = x509 ;
id = pid ;
2017-05-21 10:48:58 +02:00
# if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
2017-07-21 18:40:43 +02:00
// cppcheck-suppress useInitializationList
2009-04-22 23:29:16 +00:00
name = getX509CNString ( x509 - > cert_info - > subject ) ;
org = getX509OrgString ( x509 - > cert_info - > subject ) ;
location = getX509LocString ( x509 - > cert_info - > subject ) ;
2014-03-17 20:56:06 +00:00
issuer = RsPgpId ( std : : string ( getX509CNString ( x509 - > cert_info - > issuer ) ) ) ;
2017-02-19 22:38:02 +01:00
# else
name = getX509CNString ( X509_get_subject_name ( x509 ) ) ;
org = getX509OrgString ( X509_get_subject_name ( x509 ) ) ;
location = getX509LocString ( X509_get_subject_name ( x509 ) ) ;
issuer = RsPgpId ( std : : string ( getX509CNString ( X509_get_issuer_name ( x509 ) ) ) ) ;
# endif
email = " " ;
2009-05-23 15:07:35 +00:00
2009-04-22 23:29:16 +00:00
authed = false ;
}
2010-06-26 12:31:24 +00:00
/************************************************************************
*
*
* CODE IS DIVIDED INTO
*
* 1 ) SSL Setup .
* 3 ) Cert Access .
* 4 ) Cert Sign / Verify .
* 5 ) Cert Authentication
* 2 ) Cert Add / Remove
* 6 ) Cert Storage
*/
2009-05-23 15:07:35 +00:00
2010-06-26 12:31:24 +00:00
/********************************************************************************/
/********************************************************************************/
/********************* Cert Search / Add / Remove **************************/
/********************************************************************************/
/********************************************************************************/
2009-05-23 15:07:35 +00:00
2009-04-22 23:29:16 +00:00
2010-07-04 10:35:38 +00:00
AuthSSLimpl : : AuthSSLimpl ( )
2014-03-29 05:20:57 +00:00
: p3Config ( ) , sslctx ( NULL ) ,
2011-07-04 22:59:39 +00:00
mOwnCert ( NULL ) , sslMtx ( " AuthSSL " ) , mOwnPrivateKey ( NULL ) , mOwnPublicKey ( NULL ) , init ( 0 )
2009-04-22 23:29:16 +00:00
{
}
2010-07-04 10:35:38 +00:00
bool AuthSSLimpl : : active ( )
2009-04-22 23:29:16 +00:00
{
return init ;
}
2010-01-13 21:02:39 +00:00
2010-07-04 10:35:38 +00:00
int AuthSSLimpl : : InitAuth ( const char * cert_file , const char * priv_key_file ,
2015-03-25 08:19:45 +00:00
const char * passwd , std : : string alternative_location_name )
2009-04-22 23:29:16 +00:00
{
# ifdef AUTHSSL_DEBUG
2010-07-04 10:35:38 +00:00
std : : cerr < < " AuthSSLimpl::InitAuth() " ;
2009-04-22 23:29:16 +00:00
std : : cerr < < std : : endl ;
# endif
2010-06-26 12:31:24 +00:00
/* single call here si don't need to invoke mutex yet */
2009-04-22 23:29:16 +00:00
static int initLib = 0 ;
if ( ! initLib )
{
initLib = 1 ;
2012-05-15 13:51:24 +00:00
if ( ! tls_init ( ) ) {
return 0 ;
}
2009-04-22 23:29:16 +00:00
SSL_load_error_strings ( ) ;
SSL_library_init ( ) ;
}
if ( init = = 1 )
{
2010-07-04 10:35:38 +00:00
std : : cerr < < " AuthSSLimpl::InitAuth already initialized. " < < std : : endl ;
2009-04-22 23:29:16 +00:00
return 1 ;
}
if ( ( cert_file = = NULL ) | |
( priv_key_file = = NULL ) | |
( passwd = = NULL ) )
{
2010-02-07 21:28:40 +00:00
//fprintf(stderr, "sslroot::initssl() missing parameters!\n");
2009-04-22 23:29:16 +00:00
return 0 ;
}
// actions_to_seed_PRNG();
RAND_seed ( passwd , strlen ( passwd ) ) ;
std : : cerr < < " SSL Library Init! " < < std : : endl ;
// setup connection method
2015-02-19 20:07:40 +00:00
sslctx = SSL_CTX_new ( SSLv23_method ( ) ) ;
SSL_CTX_set_options ( sslctx , SSL_OP_NO_SSLv3 ) ;
2009-04-22 23:29:16 +00:00
2016-02-14 18:49:37 +01:00
//SSL_OP_SINGLE_DH_USE CVE-2016-0701
//https://www.openssl.org/docs/manmaster/ssl/SSL_CTX_set_options.html
//If "strong" primes were used, it is not strictly necessary to generate a new DH key during each handshake but it is also recommended. SSL_OP_SINGLE_DH_USE should therefore be enabled whenever temporary/ephemeral DH parameters are used.
//SSL_CTX_set_options() adds the options set via bitmask in options to ctx. Options already set before are not cleared!
SSL_CTX_set_options ( sslctx , SSL_OP_SINGLE_DH_USE ) ;
2013-09-14 12:28:45 +00:00
// Setup cipher lists:
//
// std::string cipherString = "HIGH:!DSS:!aNULL:!3DES";
// std::string cipherString = "DEFAULT";
//
// The current cipher list asks in priority for EDH which provides PFS. However EDH needs proper
// parameters to be set on the server side, so if we're a client for a RS instance that has no DH params,
// the connection will be refused. So we happend the HIGH cipher suite just after. In oder to force
// PFS, at the risk of not always connecting, one should use:
//
2013-12-28 21:41:43 +00:00
// std::string cipherString = "kEDH:HIGH:!DSS:!aNULL:!3DES";
2013-09-14 12:28:45 +00:00
//
2013-12-28 21:41:43 +00:00
// The following safe primes are 2048/4096 bits long. Should be enough.
2013-09-14 12:28:45 +00:00
//
// std::string dh_prime_2048_dec = "30651576830996935311378276950670996791883170963804289256203421500259588715033040934547350194073369837229137842804826417332761673984632102152477971341551955103053338169949165519208562998954887445690136488713010579430413255432398961330773637820158790237012997356731669148258317860643591694814197514454546928317578771868379525705082166818553884557266645700906836702542808787791878865135741211056957383668479369231868698451684633965462539374994559481908068730787128654626819903401038534403722014687647173327537458614224702967073490136394698912372792187651228785689025073104374674728645661275001416541267543884923191810923";
//
2017-07-21 18:40:43 +02:00
//Not used (should be here: /libretroshare/src/gxstunnel/p3gxstunnel.cc:1131
//std::string dh_prime_2048_hex = "B3B86A844550486C7EA459FA468D3A8EFD71139593FE1C658BBEFA9B2FC0AD2628242C2CDC2F91F5B220ED29AAC271192A7374DFA28CDDCA70252F342D0821273940344A7A6A3CB70C7897A39864309F6CAC5C7EA18020EF882693CA2C12BB211B7BA8367D5A7C7252A5B5E840C9E8F081469EBA0B98BCC3F593A4D9C4D5DF539362084F1B9581316C1F80FDAD452FD56DBC6B8ED0775F596F7BB22A3FE2B4753764221528D33DB4140DE58083DB660E3E105123FC963BFF108AC3A268B7380FFA72005A1515C371287C5706FFA6062C9AC73A9B1A6AC842C2764CDACFC85556607E86611FDF486C222E4896CDF6908F239E177ACC641FCBFF72A758D1C10CBB" ;
2013-09-14 12:28:45 +00:00
std : : string dh_prime_4096_hex = " A6F5777292D9E6BB95559C9124B9119E6771F11F2048C8FE74F4E8140494520972A087EF1D60B73894F1C5D509DD15D96CF379E9DDD46CE51B748085BACB440D915565782C73AF3A9580CE788441D1DA4D114E3D302CAB45A061ABCFC1F7E9200AE019CB923B77E096FA9377454A16FFE91D86535FF23E075B3E714F785CD7606E9CBD9D06F01CAFA2271883D649F13ABE170D714F6B6EC064C5BF35C4F4BDA5EF5ED5E70D5DC78F1AC1CDC04EEDAE8ADD65C4A9E27368E0B2C8595DD7626D763BFFB15364B3CCA9FCE814B9226B35FE652F4B041F0FF6694D6A482B0EF48CA41163D083AD2DE7B7A068BB05C0453E9D008551C7F67993A3EF2C4874F0244F78C4E0997BD31AB3BD88446916B499B2513DD5BA002063BD38D2CE55D29D071399D5CEE99458AF6FDC104A61CA3FACDAC803CBDE62B4C0EAC946D0E12F05CE9E94497110D64E611D957423B8AA412D84EC83E6E70E0977A31D6EE056D0527D4667D7242A77C9B679D191562E4026DA9C35FF85666296D872ED548E0FFE1A677FCC373C1F490CAB4F53DFD8735C0F1DF02FEAD824A217FDF4E3404D38A5BBC719C6622630FCD34F6F1968AF1B66A4AB1A9FCF653DA96EB3A42AF6FCFEA0547B8F314A527C519949007D7FA1726FF3D33EC46393B0207AA029E5EA574BDAC94D78894B22A2E3303E65A3F820DF57DB44951DE4E973C016C57F7A242D0BC53BC563AF " ;
2014-05-11 18:42:16 +00:00
std : : string cipherString = " kEDH+HIGH:!DSS:!aNULL:!3DES:!EXP " ;
2013-09-14 12:28:45 +00:00
2013-08-21 21:36:33 +00:00
SSL_CTX_set_cipher_list ( sslctx , cipherString . c_str ( ) ) ;
2013-09-14 12:28:45 +00:00
DH * dh = DH_new ( ) ;
int codes = 0 ;
bool pfs_enabled = true ;
if ( dh )
{
2017-05-21 10:48:58 +02:00
# if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
2013-09-14 12:28:45 +00:00
BN_hex2bn ( & dh - > p , dh_prime_4096_hex . c_str ( ) ) ;
BN_hex2bn ( & dh - > g , " 5 " ) ;
2017-02-19 22:38:02 +01:00
# else
BIGNUM * pp = NULL , * gg = NULL ;
BN_hex2bn ( & pp , dh_prime_4096_hex . c_str ( ) ) ;
BN_hex2bn ( & gg , " 5 " ) ;
DH_set0_pqg ( dh , pp , NULL , gg ) ;
# endif
2013-09-14 12:28:45 +00:00
std : : cout . flush ( ) ;
if ( DH_check ( dh , & codes ) & & codes = = 0 )
SSL_CTX_set_tmp_dh ( sslctx , dh ) ;
else
pfs_enabled = false ;
}
else
pfs_enabled = false ;
2009-04-22 23:29:16 +00:00
// certificates (Set Local Server Certificate).
2011-04-03 23:11:38 +00:00
FILE * ownfp = RsDirUtil : : rs_fopen ( cert_file , " r " ) ;
2009-04-22 23:29:16 +00:00
if ( ownfp = = NULL )
{
std : : cerr < < " Couldn't open Own Certificate! " < < std : : endl ;
return - 1 ;
}
// get xPGP certificate.
X509 * x509 = PEM_read_X509 ( ownfp , NULL , NULL , NULL ) ;
fclose ( ownfp ) ;
if ( x509 = = NULL )
{
2010-07-04 10:35:38 +00:00
std : : cerr < < " AuthSSLimpl::InitAuth() PEM_read_X509() Failed " ;
2009-05-23 15:07:35 +00:00
std : : cerr < < std : : endl ;
2009-04-22 23:29:16 +00:00
return - 1 ;
}
SSL_CTX_use_certificate ( sslctx , x509 ) ;
2010-06-26 12:31:24 +00:00
mOwnPublicKey = X509_get_pubkey ( x509 ) ;
2009-04-22 23:29:16 +00:00
// get private key
2011-04-03 23:11:38 +00:00
FILE * pkfp = RsDirUtil : : rs_fopen ( priv_key_file , " rb " ) ;
2009-04-22 23:29:16 +00:00
if ( pkfp = = NULL )
{
std : : cerr < < " Couldn't Open PrivKey File! " < < std : : endl ;
CloseAuth ( ) ;
return - 1 ;
}
2010-06-26 12:31:24 +00:00
mOwnPrivateKey = PEM_read_PrivateKey ( pkfp , NULL , NULL , ( void * ) passwd ) ;
2009-04-22 23:29:16 +00:00
fclose ( pkfp ) ;
2010-06-26 12:31:24 +00:00
if ( mOwnPrivateKey = = NULL )
2009-04-22 23:29:16 +00:00
{
2010-07-04 10:35:38 +00:00
std : : cerr < < " AuthSSLimpl::InitAuth() PEM_read_PrivateKey() Failed " ;
2009-05-23 15:07:35 +00:00
std : : cerr < < std : : endl ;
2009-04-22 23:29:16 +00:00
return - 1 ;
}
2010-06-26 12:31:24 +00:00
SSL_CTX_use_PrivateKey ( sslctx , mOwnPrivateKey ) ;
2009-04-22 23:29:16 +00:00
if ( 1 ! = SSL_CTX_check_private_key ( sslctx ) )
{
std : : cerr < < " Issues With Private Key! - Doesn't match your Cert " < < std : : endl ;
std : : cerr < < " Check your input key/certificate: " < < std : : endl ;
std : : cerr < < priv_key_file < < " & " < < cert_file ;
std : : cerr < < std : : endl ;
CloseAuth ( ) ;
return - 1 ;
}
2014-03-17 20:56:06 +00:00
RsPeerId mownidstr ;
if ( ! getX509id ( x509 , mownidstr ) )
2009-04-22 23:29:16 +00:00
{
2010-07-04 10:35:38 +00:00
std : : cerr < < " AuthSSLimpl::InitAuth() getX509id() Failed " ;
2009-05-23 15:07:35 +00:00
std : : cerr < < std : : endl ;
2009-04-22 23:29:16 +00:00
/* bad certificate */
CloseAuth ( ) ;
return - 1 ;
}
2014-03-17 20:56:06 +00:00
mOwnId = mownidstr ;
assert ( ! mOwnId . isNull ( ) ) ;
2009-04-22 23:29:16 +00:00
/* Check that Certificate is Ok ( virtual function )
* for gpg / pgp or CA verification
*/
2013-09-14 12:28:45 +00:00
if ( ! validateOwnCertificate ( x509 , mOwnPrivateKey ) )
2009-05-23 15:07:35 +00:00
{
2010-07-04 10:35:38 +00:00
std : : cerr < < " AuthSSLimpl::InitAuth() validateOwnCertificate() Failed " ;
2009-05-23 15:07:35 +00:00
std : : cerr < < std : : endl ;
/* bad certificate */
CloseAuth ( ) ;
2010-06-26 12:31:24 +00:00
exit ( 1 ) ;
2009-05-23 15:07:35 +00:00
return - 1 ;
}
2009-04-22 23:29:16 +00:00
// enable verification of certificates (PEER)
2009-05-23 15:07:35 +00:00
// and install verify callback.
2009-04-22 23:29:16 +00:00
SSL_CTX_set_verify ( sslctx , SSL_VERIFY_PEER |
2009-05-23 15:07:35 +00:00
SSL_VERIFY_FAIL_IF_NO_PEER_CERT ,
verify_x509_callback ) ;
2009-04-22 23:29:16 +00:00
std : : cerr < < " SSL Verification Set " < < std : : endl ;
mOwnCert = new sslcert ( x509 , mOwnId ) ;
2016-10-22 23:48:19 +02:00
// New locations don't store the name in the cert.
// If empty, use the external supplied value.
if ( mOwnCert - > location = = " " )
mOwnCert - > location = alternative_location_name ;
2015-03-25 08:19:45 +00:00
2013-09-14 12:28:45 +00:00
std : : cerr < < " Inited SSL context: " < < std : : endl ;
std : : cerr < < " Certificate: " < < mOwnId < < std : : endl ;
std : : cerr < < " cipher list: " < < cipherString < < std : : endl ;
std : : cerr < < " PFS enabled: " < < ( pfs_enabled ? " YES " : " NO " ) ;
if ( codes > 0 )
{
std : : cerr < < " (reason: " ;
if ( codes & DH_CHECK_P_NOT_PRIME ) std : : cerr < < " Not a prime number, " ;
if ( codes & DH_CHECK_P_NOT_SAFE_PRIME ) std : : cerr < < " Not a safe prime number, " ;
if ( codes & DH_UNABLE_TO_CHECK_GENERATOR ) std : : cerr < < " unable to check generator, " ;
if ( codes & DH_NOT_SUITABLE_GENERATOR ) std : : cerr < < " not a suitable generator " ;
std : : cerr < < " ) " < < std : : endl ;
}
else
std : : cerr < < std : : endl ;
2009-04-22 23:29:16 +00:00
init = 1 ;
return 1 ;
}
2009-05-23 15:07:35 +00:00
/* Dummy function to be overloaded by real implementation */
2010-07-04 10:35:38 +00:00
bool AuthSSLimpl : : validateOwnCertificate ( X509 * x509 , EVP_PKEY * pkey )
2009-05-23 15:07:35 +00:00
{
2010-06-26 12:31:24 +00:00
( void ) pkey ; /* remove unused parameter warning */
2014-01-15 20:19:17 +00:00
uint32_t diagnostic ;
2010-06-26 12:31:24 +00:00
/* standard authentication */
2014-01-15 20:19:17 +00:00
if ( ! AuthX509WithGPG ( x509 , diagnostic ) )
2010-06-26 12:31:24 +00:00
{
2017-11-19 18:38:46 +01:00
std : : cerr < < " Validate Own certificate ERROR: diagnostic = " < < diagnostic < < std : : endl ;
2010-06-26 12:31:24 +00:00
return false ;
}
2009-05-23 15:07:35 +00:00
return true ;
}
2009-04-22 23:29:16 +00:00
2010-07-04 10:35:38 +00:00
bool AuthSSLimpl : : CloseAuth ( )
2009-04-22 23:29:16 +00:00
{
2012-05-15 13:51:24 +00:00
tls_cleanup ( ) ;
2009-04-22 23:29:16 +00:00
# ifdef AUTHSSL_DEBUG
2010-07-04 10:35:38 +00:00
std : : cerr < < " AuthSSLimpl::CloseAuth() " ;
2009-04-22 23:29:16 +00:00
std : : cerr < < std : : endl ;
# endif
SSL_CTX_free ( sslctx ) ;
// clean up private key....
// remove certificates etc -> opposite of initssl.
init = 0 ;
return 1 ;
}
/* Context handling */
2010-07-04 10:35:38 +00:00
SSL_CTX * AuthSSLimpl : : getCTX ( )
2009-04-22 23:29:16 +00:00
{
# ifdef AUTHSSL_DEBUG
2010-07-04 10:35:38 +00:00
std : : cerr < < " AuthSSLimpl::getCTX() " ;
2009-04-22 23:29:16 +00:00
std : : cerr < < std : : endl ;
# endif
return sslctx ;
}
2014-03-17 20:56:06 +00:00
const RsPeerId & AuthSSLimpl : : OwnId ( )
2009-04-22 23:29:16 +00:00
{
# ifdef AUTHSSL_DEBUG
2010-07-04 10:35:38 +00:00
// std::cerr << "AuthSSLimpl::OwnId()" << std::endl;
2009-04-22 23:29:16 +00:00
# endif
2010-02-10 21:54:28 +00:00
return mOwnId ;
2009-04-22 23:29:16 +00:00
}
2010-07-04 10:35:38 +00:00
std : : string AuthSSLimpl : : getOwnLocation ( )
2010-01-13 21:29:21 +00:00
{
# ifdef AUTHSSL_DEBUG
2010-07-04 10:35:38 +00:00
std : : cerr < < " AuthSSLimpl::OwnId() " < < std : : endl ;
2010-01-13 21:29:21 +00:00
# endif
2010-02-10 21:54:28 +00:00
return mOwnCert - > location ;
2010-01-13 21:29:21 +00:00
}
2009-04-22 23:29:16 +00:00
2010-07-04 10:35:38 +00:00
std : : string AuthSSLimpl : : SaveOwnCertificateToString ( )
2009-04-22 23:29:16 +00:00
{
# ifdef AUTHSSL_DEBUG
2010-07-04 10:35:38 +00:00
std : : cerr < < " AuthSSLimpl::SaveOwnCertificateToString() " < < std : : endl ;
2009-04-22 23:29:16 +00:00
# endif
2010-06-26 12:31:24 +00:00
return saveX509ToPEM ( mOwnCert - > certificate ) ;
2010-02-25 22:42:42 +00:00
}
2009-04-22 23:29:16 +00:00
2010-06-26 12:31:24 +00:00
/********************************************************************************/
/********************************************************************************/
/********************* Cert Search / Add / Remove **************************/
/********************************************************************************/
/********************************************************************************/
2009-04-22 23:29:16 +00:00
2010-07-04 10:35:38 +00:00
bool AuthSSLimpl : : SignData ( std : : string input , std : : string & sign )
2009-04-22 23:29:16 +00:00
{
return SignData ( input . c_str ( ) , input . length ( ) , sign ) ;
}
2010-07-04 10:35:38 +00:00
bool AuthSSLimpl : : SignData ( const void * data , const uint32_t len , std : : string & sign )
2009-04-22 23:29:16 +00:00
{
RsStackMutex stack ( sslMtx ) ; /***** STACK LOCK MUTEX *****/
EVP_MD_CTX * mdctx = EVP_MD_CTX_create ( ) ;
2010-06-26 12:31:24 +00:00
unsigned int signlen = EVP_PKEY_size ( mOwnPrivateKey ) ;
2017-06-01 10:16:30 +02:00
unsigned char signature [ signlen ] ;
memset ( signature , 0 , signlen ) ;
2009-04-22 23:29:16 +00:00
if ( 0 = = EVP_SignInit ( mdctx , EVP_sha1 ( ) ) )
{
std : : cerr < < " EVP_SignInit Failure! " < < std : : endl ;
EVP_MD_CTX_destroy ( mdctx ) ;
return false ;
}
if ( 0 = = EVP_SignUpdate ( mdctx , data , len ) )
{
std : : cerr < < " EVP_SignUpdate Failure! " < < std : : endl ;
EVP_MD_CTX_destroy ( mdctx ) ;
return false ;
}
2010-06-26 12:31:24 +00:00
if ( 0 = = EVP_SignFinal ( mdctx , signature , & signlen , mOwnPrivateKey ) )
2009-04-22 23:29:16 +00:00
{
std : : cerr < < " EVP_SignFinal Failure! " < < std : : endl ;
EVP_MD_CTX_destroy ( mdctx ) ;
return false ;
}
EVP_MD_CTX_destroy ( mdctx ) ;
sign . clear ( ) ;
for ( uint32_t i = 0 ; i < signlen ; i + + )
{
2012-04-14 22:38:24 +00:00
rs_sprintf_append ( sign , " %02x " , ( uint32_t ) ( signature [ i ] ) ) ;
2009-04-22 23:29:16 +00:00
}
return true ;
}
2010-07-04 10:35:38 +00:00
bool AuthSSLimpl : : SignDataBin ( std : : string input , unsigned char * sign , unsigned int * signlen )
2009-04-22 23:29:16 +00:00
{
return SignDataBin ( input . c_str ( ) , input . length ( ) , sign , signlen ) ;
}
2010-07-04 10:35:38 +00:00
bool AuthSSLimpl : : SignDataBin ( const void * data , const uint32_t len ,
2009-04-22 23:29:16 +00:00
unsigned char * sign , unsigned int * signlen )
{
RsStackMutex stack ( sslMtx ) ; /***** STACK LOCK MUTEX *****/
2010-06-26 12:31:24 +00:00
return SSL_SignDataBin ( data , len , sign , signlen , mOwnPrivateKey ) ;
}
2009-04-22 23:29:16 +00:00
2010-07-04 10:35:38 +00:00
bool AuthSSLimpl : : VerifySignBin ( const void * data , const uint32_t len ,
2014-03-17 20:56:06 +00:00
unsigned char * sign , unsigned int signlen , const RsPeerId & sslId )
2010-06-26 12:31:24 +00:00
{
/* find certificate.
* if we don ' t have - fail .
*/
2009-04-22 23:29:16 +00:00
2010-06-26 12:31:24 +00:00
RsStackMutex stack ( sslMtx ) ; /***** STACK LOCK MUTEX *****/
/* find the peer */
sslcert * peer ;
if ( sslId = = mOwnId )
{
peer = mOwnCert ;
2009-04-22 23:29:16 +00:00
}
2010-06-26 12:31:24 +00:00
else if ( ! locked_FindCert ( sslId , & peer ) )
2009-04-22 23:29:16 +00:00
{
2010-06-26 12:31:24 +00:00
std : : cerr < < " VerifySignBin() no peer " < < std : : endl ;
2009-04-22 23:29:16 +00:00
return false ;
}
2010-06-26 12:31:24 +00:00
return SSL_VerifySignBin ( data , len , sign , signlen , peer - > certificate ) ;
}
2010-02-03 21:21:04 +00:00
2010-07-04 10:35:38 +00:00
bool AuthSSLimpl : : VerifyOwnSignBin ( const void * data , const uint32_t len ,
2010-06-26 12:31:24 +00:00
unsigned char * sign , unsigned int signlen )
2009-04-22 23:29:16 +00:00
{
2010-06-26 12:31:24 +00:00
return SSL_VerifySignBin ( data , len , sign , signlen , mOwnCert - > certificate ) ;
2009-04-22 23:29:16 +00:00
}
2010-06-26 12:31:24 +00:00
/********************************************************************************/
/********************************************************************************/
/********************* Sign and Auth with GPG **************************/
/********************************************************************************/
/********************************************************************************/
2009-04-22 23:29:16 +00:00
2010-06-26 12:31:24 +00:00
/* Note these functions don't need Mutexes -
* only using GPG functions - which lock themselves
*/
2009-04-22 23:29:16 +00:00
2015-06-15 22:41:18 +00:00
X509 * AuthSSLimpl : : SignX509ReqWithGPG ( X509_REQ * req , long /*days*/ )
2010-01-13 20:52:31 +00:00
{
/* Transform the X509_REQ into a suitable format to
* generate DIGEST hash . ( for SSL to do grunt work )
*/
# define SERIAL_RAND_BITS 64
2010-06-26 12:31:24 +00:00
//const EVP_MD *digest = EVP_sha1();
2010-01-13 20:52:31 +00:00
EVP_PKEY * tmppkey ;
X509 * x509 = X509_new ( ) ;
if ( x509 = = NULL )
{
2010-07-04 10:35:38 +00:00
std : : cerr < < " AuthSSLimpl::SignX509Req() FAIL " < < std : : endl ;
2010-01-13 20:52:31 +00:00
return NULL ;
}
2010-06-26 12:31:24 +00:00
//long version = 0x00;
2014-12-03 23:03:03 +00:00
unsigned long chtype = MBSTRING_UTF8 ;
2010-01-13 20:52:31 +00:00
X509_NAME * issuer_name = X509_NAME_new ( ) ;
X509_NAME_add_entry_by_txt ( issuer_name , " CN " , chtype ,
2014-03-17 20:56:06 +00:00
( unsigned char * ) AuthGPG : : getAuthGPG ( ) - > getGPGOwnId ( ) . toStdString ( ) . c_str ( ) , - 1 , - 1 , 0 ) ;
2010-01-13 20:52:31 +00:00
/****
X509_NAME_add_entry_by_NID ( issuer_name , 48 , 0 ,
( unsigned char * ) " email@email.com " , - 1 , - 1 , 0 ) ;
X509_NAME_add_entry_by_txt ( issuer_name , " O " , chtype ,
( unsigned char * ) " org " , - 1 , - 1 , 0 ) ;
X509_NAME_add_entry_by_txt ( x509_name , " L " , chtype ,
( unsigned char * ) " loc " , - 1 , - 1 , 0 ) ;
* * * */
2014-03-17 20:56:06 +00:00
std : : cerr < < " AuthSSLimpl::SignX509Req() Issuer name: " < < AuthGPG : : getAuthGPG ( ) - > getGPGOwnId ( ) . toStdString ( ) < < std : : endl ;
2010-01-13 20:52:31 +00:00
2017-11-22 00:02:11 +01:00
# ifdef V07_NON_BACKWARD_COMPATIBLE_CHANGE_002
static const uint64_t CERTIFICATE_SERIAL_NUMBER = RS_CERTIFICATE_VERSION_NUMBER_07_0001 ;
# else
# ifdef V07_NON_BACKWARD_COMPATIBLE_CHANGE_001
static const uint64_t CERTIFICATE_SERIAL_NUMBER = RS_CERTIFICATE_VERSION_NUMBER_06_0001 ;
# else
static const uint64_t CERTIFICATE_SERIAL_NUMBER = RS_CERTIFICATE_VERSION_NUMBER_06_0000 ;
# endif
# endif
2010-01-13 20:52:31 +00:00
BIGNUM * btmp = BN_new ( ) ;
2017-11-22 00:02:11 +01:00
BN_set_word ( btmp , CERTIFICATE_SERIAL_NUMBER ) ;
# ifdef OLD_CODE
2010-01-13 20:52:31 +00:00
if ( ! BN_pseudo_rand ( btmp , SERIAL_RAND_BITS , 0 , 0 ) )
{
2010-07-04 10:35:38 +00:00
std : : cerr < < " AuthSSLimpl::SignX509Req() rand FAIL " < < std : : endl ;
2010-01-13 20:52:31 +00:00
return NULL ;
}
2017-11-22 00:02:11 +01:00
# endif
ASN1_INTEGER * serial = ASN1_INTEGER_new ( ) ;
2010-01-13 20:52:31 +00:00
if ( ! BN_to_ASN1_INTEGER ( btmp , serial ) )
{
2010-07-04 10:35:38 +00:00
std : : cerr < < " AuthSSLimpl::SignX509Req() asn1 FAIL " < < std : : endl ;
2010-01-13 20:52:31 +00:00
return NULL ;
}
BN_free ( btmp ) ;
if ( ! X509_set_serialNumber ( x509 , serial ) )
{
2010-07-04 10:35:38 +00:00
std : : cerr < < " AuthSSLimpl::SignX509Req() serial FAIL " < < std : : endl ;
2010-01-13 20:52:31 +00:00
return NULL ;
}
ASN1_INTEGER_free ( serial ) ;
/* Generate SUITABLE issuer name.
* Must reference OpenPGP key , that is used to verify it
*/
if ( ! X509_set_issuer_name ( x509 , issuer_name ) )
{
2010-07-04 10:35:38 +00:00
std : : cerr < < " AuthSSLimpl::SignX509Req() issue FAIL " < < std : : endl ;
2010-01-13 20:52:31 +00:00
return NULL ;
}
X509_NAME_free ( issuer_name ) ;
2015-03-25 08:19:45 +00:00
// NEW code, set validity time between null and null
// (does not leak the key creation date to the outside anymore. for more privacy)
ASN1_TIME_set ( X509_get_notBefore ( x509 ) , 0 ) ;
ASN1_TIME_set ( X509_get_notAfter ( x509 ) , 0 ) ;
2010-01-13 20:52:31 +00:00
if ( ! X509_set_subject_name ( x509 , X509_REQ_get_subject_name ( req ) ) )
{
2010-07-04 10:35:38 +00:00
std : : cerr < < " AuthSSLimpl::SignX509Req() sub FAIL " < < std : : endl ;
2010-01-13 20:52:31 +00:00
return NULL ;
}
tmppkey = X509_REQ_get_pubkey ( req ) ;
if ( ! tmppkey | | ! X509_set_pubkey ( x509 , tmppkey ) )
{
2010-07-04 10:35:38 +00:00
std : : cerr < < " AuthSSLimpl::SignX509Req() pub FAIL " < < std : : endl ;
2010-01-13 20:52:31 +00:00
return NULL ;
}
std : : cerr < < " X509 Cert, prepared for signing " < < std : : endl ;
/*** NOW The Manual signing bit (HACKED FROM asn1/a_sign.c) ***/
2017-02-19 22:38:02 +01:00
//
// The code has been copied in order to use the PGP signing instead of supplying the
// private EVP_KEY to ASN1_sign(), which would be another alternative.
2017-05-21 10:48:58 +02:00
# if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
2017-02-25 23:16:43 +01:00
int ( * i2d ) ( X509_CINF * , unsigned char * * ) = i2d_X509_CINF ;
2010-01-13 20:52:31 +00:00
X509_ALGOR * algor1 = x509 - > cert_info - > signature ;
X509_ALGOR * algor2 = x509 - > sig_alg ;
ASN1_BIT_STRING * signature = x509 - > signature ;
X509_CINF * data = x509 - > cert_info ;
2017-02-19 22:38:02 +01:00
# else
const X509_ALGOR * algor1 = X509_get0_tbs_sigalg ( x509 ) ;
const X509_ALGOR * algor2 = NULL ;
const ASN1_BIT_STRING * tmp_signature = NULL ;
X509_get0_signature ( & tmp_signature , & algor2 , x509 ) ;
ASN1_BIT_STRING * signature = const_cast < ASN1_BIT_STRING * > ( tmp_signature ) ;
# endif
2010-06-26 12:31:24 +00:00
//EVP_PKEY *pkey = NULL;
2017-11-19 20:15:36 +01:00
# ifdef V07_NON_BACKWARD_COMPATIBLE_CHANGE_002
2017-11-19 18:21:56 +01:00
const EVP_MD * type = EVP_sha256 ( ) ;
# else
2010-01-13 20:52:31 +00:00
const EVP_MD * type = EVP_sha1 ( ) ;
2017-11-19 18:21:56 +01:00
# endif
2010-01-13 20:52:31 +00:00
2017-02-20 22:54:25 +01:00
EVP_MD_CTX * ctx = EVP_MD_CTX_create ( ) ;
2017-11-20 22:26:14 +01:00
int inl = 0 ;
2010-01-13 20:52:31 +00:00
X509_ALGOR * a ;
/* FIX ALGORITHMS */
2017-02-19 22:38:02 +01:00
a = const_cast < X509_ALGOR * > ( algor1 ) ;
2017-05-21 10:48:58 +02:00
# if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
2010-01-13 20:52:31 +00:00
ASN1_TYPE_free ( a - > parameter ) ;
a - > parameter = ASN1_TYPE_new ( ) ;
a - > parameter - > type = V_ASN1_NULL ;
ASN1_OBJECT_free ( a - > algorithm ) ;
a - > algorithm = OBJ_nid2obj ( type - > pkey_type ) ;
2017-02-19 22:38:02 +01:00
# else
X509_ALGOR_set0 ( a , OBJ_nid2obj ( EVP_MD_pkey_type ( type ) ) , V_ASN1_NULL , NULL ) ;
# endif
2010-01-13 20:52:31 +00:00
2017-02-19 22:38:02 +01:00
a = const_cast < X509_ALGOR * > ( algor2 ) ;
2017-05-21 10:48:58 +02:00
# if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
2010-01-13 20:52:31 +00:00
ASN1_TYPE_free ( a - > parameter ) ;
a - > parameter = ASN1_TYPE_new ( ) ;
a - > parameter - > type = V_ASN1_NULL ;
ASN1_OBJECT_free ( a - > algorithm ) ;
2017-02-19 22:38:02 +01:00
a - > algorithm = OBJ_nid2obj ( type - > pkey_type ) ;
# else
X509_ALGOR_set0 ( a , OBJ_nid2obj ( EVP_MD_pkey_type ( type ) ) , V_ASN1_NULL , NULL ) ;
# endif
2010-01-13 20:52:31 +00:00
std : : cerr < < " Algorithms Fixed " < < std : : endl ;
2017-11-20 22:26:14 +01:00
unsigned int sigoutl = 2048 ; // hashoutl; //EVP_PKEY_size(pkey);
unsigned char * buf_sigout = ( unsigned char * ) OPENSSL_malloc ( ( unsigned int ) sigoutl ) ;
2010-01-13 20:52:31 +00:00
/* input buffer */
2017-05-21 10:48:58 +02:00
# if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
2010-01-13 20:52:31 +00:00
inl = i2d ( data , NULL ) ;
2017-07-21 18:40:43 +02:00
unsigned char * buf_in = ( unsigned char * ) OPENSSL_malloc ( ( unsigned int ) inl ) ;
2017-11-20 22:26:14 +01:00
if ( buf_in = = NULL )
{
sigoutl = 0 ;
fprintf ( stderr , " AuthSSLimpl::SignX509Req: ASN1err(ASN1_F_ASN1_SIGN,ERR_R_MALLOC_FAILURE) \n " ) ;
return NULL ;
}
unsigned char * p = buf_in ; // This because i2d modifies the pointer after writing to it.
i2d ( data , & p ) ;
2017-02-19 22:38:02 +01:00
# else
2017-07-21 18:40:43 +02:00
unsigned char * buf_in = NULL ;
2017-02-19 22:38:02 +01:00
inl = i2d_re_X509_tbs ( x509 , & buf_in ) ; // this does the i2d over x509->cert_info
# endif
2010-01-13 20:52:31 +00:00
2017-11-19 20:15:36 +01:00
# ifdef V07_NON_BACKWARD_COMPATIBLE_CHANGE_003
2017-11-20 22:26:14 +01:00
if ( ( buf_in = = NULL ) | | ( buf_sigout = = NULL ) )
2017-11-19 18:21:56 +01:00
{
sigoutl = 0 ;
fprintf ( stderr , " AuthSSLimpl::SignX509Req: ASN1err(ASN1_F_ASN1_SIGN,ERR_R_MALLOC_FAILURE) \n " ) ;
goto err ;
}
std : : cerr < < " Buffers Allocated " < < std : : endl ;
/* NOW Sign via GPG Functions */
if ( ! AuthGPG : : getAuthGPG ( ) - > SignDataBin ( buf_in , inl , buf_sigout , ( unsigned int * ) & sigoutl , " AuthSSLimpl::SignX509ReqWithGPG() " ) )
{
sigoutl = 0 ;
goto err ;
}
# else
2017-11-20 22:26:14 +01:00
unsigned int hashoutl = EVP_MD_size ( type ) ;
2017-07-21 18:40:43 +02:00
unsigned char * buf_hashout = ( unsigned char * ) OPENSSL_malloc ( ( unsigned int ) hashoutl ) ;
2010-01-13 20:52:31 +00:00
2017-11-19 18:21:56 +01:00
if ( ( buf_hashout = = NULL ) | | ( buf_sigout = = NULL ) )
{
hashoutl = 0 ;
sigoutl = 0 ;
fprintf ( stderr , " AuthSSLimpl::SignX509Req: ASN1err(ASN1_F_ASN1_SIGN,ERR_R_MALLOC_FAILURE) \n " ) ;
goto err ;
}
2010-01-13 20:52:31 +00:00
std : : cerr < < " Buffers Allocated " < < std : : endl ;
/* data in buf_in, ready to be hashed */
2017-02-19 22:38:02 +01:00
EVP_DigestInit_ex ( ctx , type , NULL ) ;
EVP_DigestUpdate ( ctx , ( unsigned char * ) buf_in , inl ) ;
2017-11-19 18:21:56 +01:00
if ( ! EVP_DigestFinal ( ctx , ( unsigned char * ) buf_hashout , ( unsigned int * ) & hashoutl ) )
{
hashoutl = 0 ;
fprintf ( stderr , " AuthSSLimpl::SignX509Req: ASN1err(ASN1_F_ASN1_SIGN,ERR_R_EVP_LIB) \n " ) ;
goto err ;
}
2010-01-13 20:52:31 +00:00
2017-11-19 18:21:56 +01:00
std : : cerr < < " Digest Applied: len: " < < hashoutl < < std : : endl ;
2010-01-13 20:52:31 +00:00
/* NOW Sign via GPG Functions */
2016-08-09 01:22:14 +02:00
if ( ! AuthGPG : : getAuthGPG ( ) - > SignDataBin ( buf_hashout , hashoutl , buf_sigout , ( unsigned int * ) & sigoutl , " AuthSSLimpl::SignX509ReqWithGPG() " ) )
2010-01-13 20:52:31 +00:00
{
sigoutl = 0 ;
goto err ;
}
2017-11-19 18:21:56 +01:00
# endif
2010-01-13 20:52:31 +00:00
std : : cerr < < " Buffer Sizes: in: " < < inl ;
2017-11-20 22:44:34 +01:00
# ifndef V07_NON_BACKWARD_COMPATIBLE_CHANGE_003
2010-01-13 20:52:31 +00:00
std : : cerr < < " HashOut: " < < hashoutl ;
2017-11-20 22:44:34 +01:00
# endif
2010-01-13 20:52:31 +00:00
std : : cerr < < " SigOut: " < < sigoutl ;
std : : cerr < < std : : endl ;
//passphrase = "NULL";
std : : cerr < < " Signature done: len: " < < sigoutl < < std : : endl ;
/* ADD Signature back into Cert... Signed!. */
if ( signature - > data ! = NULL ) OPENSSL_free ( signature - > data ) ;
signature - > data = buf_sigout ;
buf_sigout = NULL ;
signature - > length = sigoutl ;
/* In the interests of compatibility, I'll make sure that
* the bit string has a ' not - used bits ' value of 0
*/
signature - > flags & = ~ ( ASN1_STRING_FLAG_BITS_LEFT | 0x07 ) ;
signature - > flags | = ASN1_STRING_FLAG_BITS_LEFT ;
std : : cerr < < " Certificate Complete " < < std : : endl ;
2017-02-20 22:54:25 +01:00
EVP_MD_CTX_destroy ( ctx ) ;
2017-02-19 22:38:02 +01:00
2017-11-19 18:21:56 +01:00
// debug
2017-11-20 22:26:14 +01:00
// {
// int pkey_nid = OBJ_obj2nid(x509->sig_alg->algorithm);
// const char* sslbuf = OBJ_nid2ln(pkey_nid);
// std::cerr << "Signature hash algorithm: " << sslbuf << std::endl;
// }
2017-11-19 18:21:56 +01:00
2010-01-13 20:52:31 +00:00
return x509 ;
2010-06-26 12:31:24 +00:00
/* XXX CLEANUP */
2010-01-13 20:52:31 +00:00
err :
/* cleanup */
2013-07-18 22:10:30 +00:00
if ( buf_in ! = NULL )
OPENSSL_free ( buf_in ) ;
2017-11-19 20:15:36 +01:00
# ifndef V07_NON_BACKWARD_COMPATIBLE_CHANGE_003
2013-07-18 22:10:30 +00:00
if ( buf_hashout ! = NULL )
OPENSSL_free ( buf_hashout ) ;
2017-11-19 19:34:54 +01:00
# endif
2013-07-18 22:10:30 +00:00
if ( buf_sigout ! = NULL )
OPENSSL_free ( buf_sigout ) ;
2010-01-13 20:52:31 +00:00
std : : cerr < < " GPGAuthMgr::SignX509Req() err: FAIL " < < std : : endl ;
return NULL ;
}
2010-06-26 12:31:24 +00:00
/* This function, checks that the X509 is signed by a known GPG key,
* NB : we do not have to have approved this person as a friend .
* this is important - as it allows non - friends messages to be validated .
*/
2014-01-15 20:19:17 +00:00
bool AuthSSLimpl : : AuthX509WithGPG ( X509 * x509 , uint32_t & diagnostic )
2010-06-26 12:31:24 +00:00
{
2014-01-15 20:19:17 +00:00
# ifdef AUTHSSL_DEBUG
fprintf ( stderr , " AuthSSLimpl::AuthX509WithGPG() called \n " ) ;
# endif
2010-01-13 21:16:56 +00:00
2014-01-15 20:19:17 +00:00
if ( ! CheckX509Certificate ( x509 ) )
2010-06-26 12:31:24 +00:00
{
2014-01-15 20:19:17 +00:00
std : : cerr < < " AuthSSLimpl::AuthX509() X509 NOT authenticated : Certificate failed basic checks " < < std : : endl ;
diagnostic = RS_SSL_HANDSHAKE_DIAGNOSTIC_CERTIFICATE_NOT_VALID ;
return false ;
}
2010-01-13 20:52:31 +00:00
2014-01-15 20:19:17 +00:00
/* extract CN for peer Id */
2017-05-21 10:48:58 +02:00
# if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
2014-03-17 20:56:06 +00:00
RsPgpId issuer ( std : : string ( getX509CNString ( x509 - > cert_info - > issuer ) ) ) ;
2017-02-19 22:38:02 +01:00
# else
RsPgpId issuer ( std : : string ( getX509CNString ( X509_get_issuer_name ( x509 ) ) ) ) ;
# endif
2014-01-15 20:19:17 +00:00
RsPeerDetails pd ;
# ifdef AUTHSSL_DEBUG
2014-03-17 20:56:06 +00:00
std : : cerr < < " Checking GPG issuer : " < < issuer . toStdString ( ) < < std : : endl ;
2014-01-15 20:19:17 +00:00
# endif
if ( ! AuthGPG : : getAuthGPG ( ) - > getGPGDetails ( issuer , pd ) ) {
std : : cerr < < " AuthSSLimpl::AuthX509() X509 NOT authenticated : AuthGPG::getAuthGPG()->getGPGDetails() returned false. " < < std : : endl ;
diagnostic = RS_SSL_HANDSHAKE_DIAGNOSTIC_ISSUER_UNKNOWN ;
return false ;
}
2010-01-13 20:52:31 +00:00
2014-01-15 20:19:17 +00:00
/* verify GPG signature */
2010-01-13 20:52:31 +00:00
2014-01-15 20:19:17 +00:00
/*** NOW The Manual signing bit (HACKED FROM asn1/a_sign.c) ***/
2017-02-19 22:38:02 +01:00
2017-05-21 10:48:58 +02:00
# if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
2017-05-08 12:05:58 +02:00
int ( * i2d ) ( X509_CINF * , unsigned char * * ) = i2d_X509_CINF ;
2014-01-15 20:19:17 +00:00
ASN1_BIT_STRING * signature = x509 - > signature ;
X509_CINF * data = x509 - > cert_info ;
2017-02-19 22:38:02 +01:00
# else
const ASN1_BIT_STRING * signature = NULL ;
const X509_ALGOR * algor2 = NULL ;
X509_get0_signature ( & signature , & algor2 , x509 ) ;
# endif
2017-11-22 22:56:40 +01:00
uint32_t certificate_version = getX509RetroshareCertificateVersion ( x509 ) ;
2010-01-13 20:52:31 +00:00
2017-02-20 22:54:25 +01:00
EVP_MD_CTX * ctx = EVP_MD_CTX_create ( ) ;
2017-11-22 22:56:40 +01:00
int inl = 0 ;
2010-01-13 20:52:31 +00:00
2017-11-22 22:56:40 +01:00
const unsigned char * signed_data = NULL ;
uint32_t signed_data_length = 0 ;
2014-01-15 20:19:17 +00:00
/* input buffer */
2017-05-21 10:48:58 +02:00
# if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
2014-01-15 20:19:17 +00:00
inl = i2d ( data , NULL ) ;
2017-07-21 18:40:43 +02:00
unsigned char * buf_in = ( unsigned char * ) OPENSSL_malloc ( ( unsigned int ) inl ) ;
2017-05-08 13:01:34 +02:00
unsigned char * p = NULL ;
2017-02-19 22:38:02 +01:00
# else
2017-07-21 18:40:43 +02:00
unsigned char * buf_in = NULL ;
2017-02-19 22:38:02 +01:00
inl = i2d_re_X509_tbs ( x509 , & buf_in ) ; // this does the i2d over x509->cert_info
# endif
2010-01-13 20:52:31 +00:00
2017-11-22 23:46:57 +01:00
if ( buf_in = = NULL )
2017-11-22 00:02:11 +01:00
{
2014-01-15 20:19:17 +00:00
fprintf ( stderr , " AuthSSLimpl::AuthX509: ASN1err(ASN1_F_ASN1_SIGN,ERR_R_MALLOC_FAILURE) \n " ) ;
diagnostic = RS_SSL_HANDSHAKE_DIAGNOSTIC_MALLOC_ERROR ;
2017-11-22 23:46:57 +01:00
return false ;
2014-01-15 20:19:17 +00:00
}
2010-01-13 20:52:31 +00:00
2014-01-15 20:19:17 +00:00
# ifdef AUTHSSL_DEBUG
std : : cerr < < " Buffers Allocated " < < std : : endl ;
# endif
2009-04-22 23:29:16 +00:00
2017-05-21 10:48:58 +02:00
# if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
2017-05-08 13:01:34 +02:00
p = buf_in ;
2014-01-15 20:19:17 +00:00
i2d ( data , & p ) ;
2017-02-19 22:38:02 +01:00
# endif
2017-11-22 23:46:57 +01:00
{ // this scope is to avoid cross-initialization jumps to err.
2017-11-19 18:21:56 +01:00
2017-11-22 22:56:40 +01:00
const Sha1CheckSum sha1 = RsDirUtil : : sha1sum ( buf_in , inl ) ; // olds the memory until destruction
2017-11-22 00:02:11 +01:00
2017-11-22 22:56:40 +01:00
if ( certificate_version < RS_CERTIFICATE_VERSION_NUMBER_07_0001 )
2017-11-22 00:02:11 +01:00
{
2017-11-22 23:46:57 +01:00
// If the certificate belongs to 0.6 version, we hash it here, and then re-hash the hash it in the PGP signature.
2017-11-22 22:56:40 +01:00
signed_data = sha1 . toByteArray ( ) ;
signed_data_length = sha1 . SIZE_IN_BYTES ;
}
else
{
signed_data = buf_in ;
signed_data_length = inl ;
2017-11-22 00:02:11 +01:00
}
2017-11-22 22:56:40 +01:00
/* NOW check sign via GPG Functions */
//get the fingerprint of the key that is supposed to sign
2014-01-15 20:19:17 +00:00
# ifdef AUTHSSL_DEBUG
2017-11-22 22:56:40 +01:00
std : : cerr < < " AuthSSLimpl::AuthX509() verifying the gpg sig with keyprint : " < < pd . fpr < < std : : endl ;
std : : cerr < < " Sigoutl = " < < sigoutl < < std : : endl ;
std : : cerr < < " pd.fpr = " < < pd . fpr < < std : : endl ;
2014-01-15 20:19:17 +00:00
# endif
2010-01-13 20:52:31 +00:00
2017-11-22 22:56:40 +01:00
// Take a early look at signature parameters. In particular we dont accept signatures with unsecure hash algorithms.
2017-11-19 18:21:56 +01:00
2017-11-22 22:56:40 +01:00
PGPSignatureInfo signature_info ;
2017-11-22 23:46:57 +01:00
PGPKeyManagement : : parseSignature ( signature - > data , signature - > length , signature_info ) ;
2017-11-19 18:21:56 +01:00
2017-11-22 22:56:40 +01:00
if ( signature_info . signature_version ! = PGP_PACKET_TAG_SIGNATURE_VERSION_V4 )
{
diagnostic = RS_SSL_HANDSHAKE_DIAGNOSTIC_WRONG_SIGNATURE_VERSION ;
2017-11-22 23:46:57 +01:00
goto err ;
2017-11-22 22:56:40 +01:00
}
2010-01-24 13:59:22 +00:00
2017-11-22 22:56:40 +01:00
std : : string sigtypestring ;
2017-11-19 18:38:46 +01:00
2017-11-22 22:56:40 +01:00
switch ( signature_info . signature_type )
{
2017-11-19 18:38:46 +01:00
case PGP_PACKET_TAG_SIGNATURE_TYPE_BINARY_DOCUMENT :
2017-11-22 22:56:40 +01:00
break ;
2017-11-19 18:21:56 +01:00
2017-11-19 18:38:46 +01:00
case PGP_PACKET_TAG_SIGNATURE_TYPE_STANDALONE_SIG :
2017-11-19 18:21:56 +01:00
case PGP_PACKET_TAG_SIGNATURE_TYPE_CANONICAL_TEXT :
case PGP_PACKET_TAG_SIGNATURE_TYPE_UNKNOWN :
default :
2017-11-22 22:56:40 +01:00
diagnostic = RS_SSL_HANDSHAKE_DIAGNOSTIC_WRONG_SIGNATURE_TYPE ;
2017-11-22 23:46:57 +01:00
goto err ;
2017-11-22 22:56:40 +01:00
}
2017-11-19 18:21:56 +01:00
2017-11-22 22:56:40 +01:00
switch ( signature_info . public_key_algorithm )
{
2017-11-19 18:38:46 +01:00
case PGP_PACKET_TAG_PUBLIC_KEY_ALGORITHM_RSA_ES :
case PGP_PACKET_TAG_PUBLIC_KEY_ALGORITHM_RSA_S : sigtypestring = " RSA " ;
2017-11-22 22:56:40 +01:00
break ;
2017-11-19 18:38:46 +01:00
case PGP_PACKET_TAG_PUBLIC_KEY_ALGORITHM_DSA : sigtypestring = " DSA " ;
2017-11-22 22:56:40 +01:00
break ;
2017-11-19 18:38:46 +01:00
case PGP_PACKET_TAG_PUBLIC_KEY_ALGORITHM_RSA_E :
case PGP_PACKET_TAG_PUBLIC_KEY_ALGORITHM_UNKNOWN :
2017-11-22 22:56:40 +01:00
default :
diagnostic = RS_SSL_HANDSHAKE_DIAGNOSTIC_HASH_ALGORITHM_NOT_ACCEPTED ;
2017-11-22 23:46:57 +01:00
goto err ;
2017-11-22 22:56:40 +01:00
}
2017-11-19 18:38:46 +01:00
2017-11-22 22:56:40 +01:00
switch ( signature_info . hash_algorithm )
{
2017-11-19 18:38:46 +01:00
case PGP_PACKET_TAG_HASH_ALGORITHM_SHA1 : sigtypestring + = " +SHA1 " ; break ;
case PGP_PACKET_TAG_HASH_ALGORITHM_SHA256 : sigtypestring + = " +SHA256 " ; break ;
case PGP_PACKET_TAG_HASH_ALGORITHM_SHA512 : sigtypestring + = " +SHA512 " ; break ;
2017-11-19 18:21:56 +01:00
2017-11-22 22:56:40 +01:00
// We dont accept signatures with unknown or week hash algorithms.
2017-11-19 18:21:56 +01:00
case PGP_PACKET_TAG_HASH_ALGORITHM_MD5 :
case PGP_PACKET_TAG_HASH_ALGORITHM_UNKNOWN :
default :
diagnostic = RS_SSL_HANDSHAKE_DIAGNOSTIC_HASH_ALGORITHM_NOT_ACCEPTED ;
2017-11-22 23:46:57 +01:00
goto err ;
2017-11-22 22:56:40 +01:00
}
2017-11-19 18:21:56 +01:00
2017-11-22 22:56:40 +01:00
// passed, verify the signature itself
2017-11-19 18:21:56 +01:00
2017-11-22 23:46:57 +01:00
if ( ! AuthGPG : : getAuthGPG ( ) - > VerifySignBin ( signed_data , signed_data_length , signature - > data , signature - > length , pd . fpr ) )
2017-11-22 00:02:11 +01:00
{
diagnostic = RS_SSL_HANDSHAKE_DIAGNOSTIC_WRONG_SIGNATURE ;
goto err ;
}
2010-01-13 21:16:18 +00:00
2017-11-22 22:56:40 +01:00
RsPeerId peerIdstr ;
getX509id ( x509 , peerIdstr ) ;
2017-11-19 19:57:38 +01:00
2017-11-22 23:46:57 +01:00
std : : string fpr = pd . fpr . toStdString ( ) ;
std : : cerr < < " Verified " < < sigtypestring < < " signature of certificate " < < peerIdstr < < " , Version " < < std : : hex < < certificate_version
< < std : : dec < < " using PGP key " ;
for ( uint32_t i = 0 ; i < fpr . length ( ) ; i + = 4 )
std : : cerr < < fpr . substr ( i , 4 ) < < " " ;
std : : cerr < < std : : endl ;
2017-11-19 18:38:46 +01:00
}
2014-01-15 20:19:17 +00:00
# ifdef AUTHSSL_DEBUG
std : : cerr < < " AuthSSLimpl::AuthX509() X509 authenticated " < < std : : endl ;
# endif
2017-02-20 22:54:25 +01:00
EVP_MD_CTX_destroy ( ctx ) ;
2010-02-25 22:42:42 +00:00
2014-01-15 20:19:17 +00:00
OPENSSL_free ( buf_in ) ;
2013-07-18 22:10:30 +00:00
2014-01-15 20:19:17 +00:00
diagnostic = RS_SSL_HANDSHAKE_DIAGNOSTIC_OK ;
2010-01-13 20:52:31 +00:00
2014-01-15 20:19:17 +00:00
return true ;
2011-01-01 20:37:10 +00:00
2014-01-15 20:19:17 +00:00
err :
std : : cerr < < " AuthSSLimpl::AuthX509() X509 NOT authenticated " < < std : : endl ;
if ( buf_in ! = NULL )
OPENSSL_free ( buf_in ) ;
2017-11-22 23:46:57 +01:00
2014-01-15 20:19:17 +00:00
return false ;
2010-01-13 20:52:31 +00:00
}
2010-06-26 12:31:24 +00:00
2009-04-22 23:29:16 +00:00
/* validate + get id */
2014-03-17 20:56:06 +00:00
bool AuthSSLimpl : : ValidateCertificate ( X509 * x509 , RsPeerId & peerId )
2009-04-22 23:29:16 +00:00
{
2014-01-15 20:19:17 +00:00
uint32_t auth_diagnostic ;
2009-04-22 23:29:16 +00:00
/* check self signed */
2014-01-15 20:19:17 +00:00
if ( ! AuthX509WithGPG ( x509 , auth_diagnostic ) )
2010-01-24 13:59:22 +00:00
{
2010-01-13 21:16:18 +00:00
# ifdef AUTHSSL_DEBUG
2010-07-04 10:35:38 +00:00
std : : cerr < < " AuthSSLimpl::ValidateCertificate() bad certificate. " ;
2010-01-24 13:59:22 +00:00
std : : cerr < < std : : endl ;
2009-05-23 15:07:35 +00:00
# endif
2010-01-24 13:59:22 +00:00
return false ;
}
2014-03-17 20:56:06 +00:00
RsPeerId peerIdstr ;
if ( ! getX509id ( x509 , peerIdstr ) )
2010-01-24 13:59:22 +00:00
{
# ifdef AUTHSSL_DEBUG
2010-07-04 10:35:38 +00:00
std : : cerr < < " AuthSSLimpl::ValidateCertificate() Cannot retrieve peer id from certificate.. " ;
2010-01-24 13:59:22 +00:00
std : : cerr < < std : : endl ;
# endif
return false ;
2010-01-13 21:16:18 +00:00
}
2014-03-17 20:56:06 +00:00
peerId = peerIdstr ;
2009-05-23 15:07:35 +00:00
# ifdef AUTHSSL_DEBUG
2010-07-04 10:35:38 +00:00
std : : cerr < < " AuthSSLimpl::ValidateCertificate() good certificate. " ;
2009-05-23 15:07:35 +00:00
std : : cerr < < std : : endl ;
# endif
2009-04-22 23:29:16 +00:00
2010-01-24 13:59:22 +00:00
return true ;
2009-04-22 23:29:16 +00:00
}
2010-06-26 12:31:24 +00:00
/********************************************************************************/
/********************************************************************************/
/**************************** encrypt / decrypt fns ****************************/
/********************************************************************************/
/********************************************************************************/
static int verify_x509_callback ( int preverify_ok , X509_STORE_CTX * ctx )
2010-06-25 21:50:46 +00:00
{
2010-06-26 12:31:24 +00:00
# ifdef AUTHSSL_DEBUG
2012-09-09 20:25:39 +00:00
std : : cerr < < " static verify_x509_callback called. " ;
std : : cerr < < std : : endl ;
2010-06-26 12:31:24 +00:00
# endif
2012-09-09 20:25:39 +00:00
int verify = AuthSSL : : getAuthSSL ( ) - > VerifyX509Callback ( preverify_ok , ctx ) ;
X509 * x509 = X509_STORE_CTX_get_current_cert ( ctx ) ;
if ( x509 ! = NULL )
2011-07-11 00:55:06 +00:00
{
2017-05-21 10:48:58 +02:00
# if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
2014-03-17 20:56:06 +00:00
RsPgpId gpgid ( std : : string ( getX509CNString ( x509 - > cert_info - > issuer ) ) ) ;
2017-02-19 22:38:02 +01:00
# else
RsPgpId gpgid ( std : : string ( getX509CNString ( X509_get_issuer_name ( x509 ) ) ) ) ;
# endif
2014-03-17 20:56:06 +00:00
if ( gpgid . isNull ( ) )
{
2017-05-21 10:48:58 +02:00
# if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
2014-03-17 20:56:06 +00:00
std : : cerr < < " verify_x509_callback(): wrong PGP id \" " < < std : : string ( getX509CNString ( x509 - > cert_info - > issuer ) ) < < " \" " < < std : : endl ;
2017-02-19 22:38:02 +01:00
# else
std : : cerr < < " verify_x509_callback(): wrong PGP id \" " < < std : : string ( getX509CNString ( X509_get_issuer_name ( x509 ) ) ) < < " \" " < < std : : endl ;
# endif
2014-03-17 20:56:06 +00:00
return false ;
}
2017-05-21 10:48:58 +02:00
# if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
2012-09-09 20:25:39 +00:00
std : : string sslcn = getX509CNString ( x509 - > cert_info - > subject ) ;
2017-02-19 22:38:02 +01:00
# else
std : : string sslcn = getX509CNString ( X509_get_subject_name ( x509 ) ) ;
# endif
2014-03-17 20:56:06 +00:00
RsPeerId sslid ;
2012-09-09 20:25:39 +00:00
getX509id ( x509 , sslid ) ;
2014-03-17 20:56:06 +00:00
if ( sslid . isNull ( ) )
{
2017-02-19 22:38:02 +01:00
std : : cerr < < " verify_x509_callback(): wrong PGP id \" " < < sslcn < < " \" " < < std : : endl ;
2014-03-17 20:56:06 +00:00
return false ;
}
2012-09-14 21:04:16 +00:00
AuthSSL : : getAuthSSL ( ) - > setCurrentConnectionAttemptInfo ( gpgid , sslid , sslcn ) ;
2012-09-09 20:25:39 +00:00
}
2010-06-26 12:31:24 +00:00
2012-09-09 20:25:39 +00:00
return verify ;
2010-06-25 21:50:46 +00:00
}
2010-07-04 10:35:38 +00:00
int AuthSSLimpl : : VerifyX509Callback ( int preverify_ok , X509_STORE_CTX * ctx )
2010-06-25 21:50:46 +00:00
{
2015-01-23 08:13:26 +00:00
char buf [ 256 ] ;
X509 * err_cert ;
err_cert = X509_STORE_CTX_get_current_cert ( ctx ) ;
2015-01-23 19:17:33 +00:00
# ifdef AUTHSSL_DEBUG
2015-06-15 22:41:18 +00:00
int err , depth ;
2015-01-23 08:13:26 +00:00
err = X509_STORE_CTX_get_error ( ctx ) ;
depth = X509_STORE_CTX_get_error_depth ( ctx ) ;
2015-01-23 19:17:33 +00:00
# endif
2015-01-23 08:13:26 +00:00
if ( err_cert = = NULL )
{
std : : cerr < < " AuthSSLimpl::VerifyX509Callback(): Cannot get certificate. Error! " < < std : : endl ;
return false ;
}
# ifdef AUTHSSL_DEBUG
std : : cerr < < " AuthSSLimpl::VerifyX509Callback(preverify_ok: " < < preverify_ok
< < " Err: " < < err < < " Depth: " < < depth < < std : : endl ;
# endif
2010-06-26 12:31:24 +00:00
2015-01-23 08:13:26 +00:00
/*
* Retrieve the pointer to the SSL of the connection currently treated
* and the application specific data stored into the SSL object .
*/
2010-06-26 12:31:24 +00:00
2015-01-23 08:13:26 +00:00
X509_NAME_oneline ( X509_get_subject_name ( err_cert ) , buf , 256 ) ;
2010-06-26 12:31:24 +00:00
2015-01-23 08:13:26 +00:00
# ifdef AUTHSSL_DEBUG
std : : cerr < < " AuthSSLimpl::VerifyX509Callback: depth: " < < depth < < " : " < < buf < < std : : endl ;
# endif
2010-06-26 12:31:24 +00:00
2015-01-23 08:13:26 +00:00
if ( ! preverify_ok ) {
# ifdef AUTHSSL_DEBUG
fprintf ( stderr , " Verify error:num=%d:%s:depth=%d:%s \n " , err ,
X509_verify_cert_error_string ( err ) , depth , buf ) ;
# endif
}
/*
* At this point , err contains the last verification error . We can use
* it for something special
*/
2010-06-26 12:31:24 +00:00
2015-01-23 08:13:26 +00:00
if ( ! preverify_ok )
{
2010-06-26 12:31:24 +00:00
2015-01-23 08:13:26 +00:00
X509_NAME_oneline ( X509_get_issuer_name ( X509_STORE_CTX_get_current_cert ( ctx ) ) , buf , 256 ) ;
# ifdef AUTHSSL_DEBUG
printf ( " issuer= %s \n " , buf ) ;
# endif
2010-06-26 12:31:24 +00:00
2015-01-23 08:13:26 +00:00
# ifdef AUTHSSL_DEBUG
fprintf ( stderr , " Doing REAL PGP Certificates \n " ) ;
# endif
uint32_t auth_diagnostic ;
2010-06-26 12:31:24 +00:00
2015-01-23 08:13:26 +00:00
/* do the REAL Authentication */
if ( ! AuthX509WithGPG ( X509_STORE_CTX_get_current_cert ( ctx ) , auth_diagnostic ) )
2010-06-26 12:31:24 +00:00
{
2015-01-23 08:13:26 +00:00
# ifdef AUTHSSL_DEBUG
fprintf ( stderr , " AuthSSLimpl::VerifyX509Callback() X509 not authenticated. \n " ) ;
# endif
std : : cerr < < " (WW) Certificate was rejected because authentication failed. Diagnostic = " < < auth_diagnostic < < std : : endl ;
return false ;
}
2017-05-21 10:48:58 +02:00
# if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
2017-02-19 22:38:02 +01:00
RsPgpId pgpid ( std : : string ( getX509CNString ( X509_STORE_CTX_get_current_cert ( ctx ) - > cert_info - > issuer ) ) ) ;
# else
RsPgpId pgpid ( std : : string ( getX509CNString ( X509_get_issuer_name ( X509_STORE_CTX_get_current_cert ( ctx ) ) ) ) ) ;
# endif
2010-06-26 12:31:24 +00:00
2015-01-23 08:13:26 +00:00
if ( pgpid ! = AuthGPG : : getAuthGPG ( ) - > getGPGOwnId ( ) & & ! AuthGPG : : getAuthGPG ( ) - > isGPGAccepted ( pgpid ) )
{
# ifdef AUTHSSL_DEBUG
fprintf ( stderr , " AuthSSLimpl::VerifyX509Callback() pgp key not accepted : \n " ) ;
fprintf ( stderr , " issuer pgpid : " ) ;
fprintf ( stderr , " %s \n " , pgpid . c_str ( ) ) ;
fprintf ( stderr , " \n AuthGPG::getAuthGPG()->getGPGOwnId() : " ) ;
fprintf ( stderr , " %s \n " , AuthGPG : : getAuthGPG ( ) - > getGPGOwnId ( ) . c_str ( ) ) ;
fprintf ( stderr , " \n " ) ;
# endif
return false ;
2010-06-26 12:31:24 +00:00
}
2015-01-23 08:13:26 +00:00
preverify_ok = true ;
} else {
# ifdef AUTHSSL_DEBUG
fprintf ( stderr , " A normal certificate is probably a security breach attempt. We sould fail it !!! \n " ) ;
# endif
preverify_ok = false ;
}
2010-06-26 12:31:24 +00:00
2015-01-23 08:13:26 +00:00
if ( preverify_ok ) {
2010-06-26 12:31:24 +00:00
2015-01-23 08:13:26 +00:00
//sslcert *cert = NULL;
RsPeerId certId ;
getX509id ( X509_STORE_CTX_get_current_cert ( ctx ) , certId ) ;
2010-06-26 12:31:24 +00:00
2015-01-23 08:13:26 +00:00
}
# ifdef AUTHSSL_DEBUG
if ( preverify_ok ) {
fprintf ( stderr , " AuthSSLimpl::VerifyX509Callback returned true. \n " ) ;
} else {
fprintf ( stderr , " AuthSSLimpl::VerifyX509Callback returned false. \n " ) ;
}
# endif
2010-06-26 12:31:24 +00:00
2015-01-23 08:13:26 +00:00
return preverify_ok ;
2010-06-25 21:50:46 +00:00
}
2009-04-22 23:29:16 +00:00
2010-06-26 12:31:24 +00:00
/********************************************************************************/
/********************************************************************************/
/**************************** encrypt / decrypt fns ****************************/
/********************************************************************************/
/********************************************************************************/
2014-03-17 20:56:06 +00:00
bool AuthSSLimpl : : encrypt ( void * & out , int & outlen , const void * in , int inlen , const RsPeerId & peerId )
2009-12-13 21:59:26 +00:00
{
2010-06-26 12:31:24 +00:00
RsStackMutex stack ( sslMtx ) ; /******* LOCKED ******/
2009-12-13 21:59:26 +00:00
# ifdef AUTHSSL_DEBUG
2010-07-04 10:35:38 +00:00
std : : cerr < < " AuthSSLimpl::encrypt() called for peerId : " < < peerId < < " with inlen : " < < inlen < < std : : endl ;
2009-12-13 21:59:26 +00:00
# endif
//TODO : use ssl to crypt the binary input buffer
2010-02-25 22:42:42 +00:00
// out = malloc(inlen);
// memcpy(out, in, inlen);
// outlen = inlen;
EVP_PKEY * public_key ;
if ( peerId = = mOwnId ) {
2010-06-26 12:31:24 +00:00
public_key = mOwnPublicKey ;
2010-02-25 22:42:42 +00:00
} else {
if ( ! mCerts [ peerId ] ) {
# ifdef AUTHSSL_DEBUG
2010-07-04 10:35:38 +00:00
std : : cerr < < " AuthSSLimpl::encrypt() public key not found. " < < std : : endl ;
2010-02-25 22:42:42 +00:00
# endif
return false ;
} else {
2017-05-21 10:48:58 +02:00
# if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
2010-02-25 22:42:42 +00:00
public_key = mCerts [ peerId ] - > certificate - > cert_info - > key - > pkey ;
2017-02-19 22:38:02 +01:00
# else
public_key = X509_get0_pubkey ( mCerts [ peerId ] - > certificate ) ;
# endif
2010-02-25 22:42:42 +00:00
}
}
2017-02-19 22:38:02 +01:00
EVP_CIPHER_CTX * ctx = EVP_CIPHER_CTX_new ( ) ;
2010-07-14 21:27:26 +00:00
int eklen , net_ekl ;
unsigned char * ek ;
unsigned char iv [ EVP_MAX_IV_LENGTH ] ;
int out_currOffset = 0 ;
2010-02-25 22:42:42 +00:00
int out_offset = 0 ;
2010-07-14 21:27:26 +00:00
int max_evp_key_size = EVP_PKEY_size ( public_key ) ;
2016-01-12 21:43:04 -05:00
ek = ( unsigned char * ) rs_malloc ( max_evp_key_size ) ;
2016-01-12 21:10:11 -05:00
if ( ek = = NULL )
return false ;
2010-07-14 21:27:26 +00:00
const EVP_CIPHER * cipher = EVP_aes_128_cbc ( ) ;
int cipher_block_size = EVP_CIPHER_block_size ( cipher ) ;
int size_net_ekl = sizeof ( net_ekl ) ;
2010-02-25 22:42:42 +00:00
2010-07-14 21:27:26 +00:00
int max_outlen = inlen + cipher_block_size + EVP_MAX_IV_LENGTH + max_evp_key_size + size_net_ekl ;
2010-02-25 22:42:42 +00:00
2010-07-14 21:27:26 +00:00
// intialize context and send store encrypted cipher in ek
2017-02-19 22:38:02 +01:00
if ( ! EVP_SealInit ( ctx , EVP_aes_128_cbc ( ) , & ek , & eklen , iv , & public_key , 1 ) ) {
2010-10-23 14:03:35 +00:00
free ( ek ) ;
return false ;
}
2010-01-24 13:59:22 +00:00
2010-07-14 21:27:26 +00:00
// now assign memory to out accounting for data, and cipher block size, key length, and key length val
2016-01-12 21:43:04 -05:00
out = ( unsigned char * ) rs_malloc ( inlen + cipher_block_size + size_net_ekl + eklen + EVP_MAX_IV_LENGTH ) ;
2010-02-25 22:42:42 +00:00
2016-01-12 21:10:11 -05:00
if ( out = = NULL )
{
free ( ek ) ;
return false ;
}
2010-07-14 21:27:26 +00:00
net_ekl = htonl ( eklen ) ;
memcpy ( ( unsigned char * ) out + out_offset , & net_ekl , size_net_ekl ) ;
out_offset + = size_net_ekl ;
2010-02-25 22:42:42 +00:00
2010-07-14 21:27:26 +00:00
memcpy ( ( unsigned char * ) out + out_offset , ek , eklen ) ;
out_offset + = eklen ;
2010-02-25 22:42:42 +00:00
2010-07-14 21:27:26 +00:00
memcpy ( ( unsigned char * ) out + out_offset , iv , EVP_MAX_IV_LENGTH ) ;
out_offset + = EVP_MAX_IV_LENGTH ;
2010-02-25 22:42:42 +00:00
2010-07-14 21:27:26 +00:00
// now encrypt actual data
2017-02-19 22:38:02 +01:00
if ( ! EVP_SealUpdate ( ctx , ( unsigned char * ) out + out_offset , & out_currOffset , ( unsigned char * ) in , inlen ) ) {
2010-10-23 14:03:35 +00:00
free ( ek ) ;
2014-08-25 21:07:07 +00:00
free ( out ) ;
2010-10-23 14:03:35 +00:00
out = NULL ;
return false ;
}
2010-02-25 22:42:42 +00:00
2010-07-14 21:27:26 +00:00
// move along to partial block space
out_offset + = out_currOffset ;
2010-02-25 22:42:42 +00:00
2010-07-14 21:27:26 +00:00
// add padding
2017-02-19 22:38:02 +01:00
if ( ! EVP_SealFinal ( ctx , ( unsigned char * ) out + out_offset , & out_currOffset ) ) {
2010-10-23 14:03:35 +00:00
free ( ek ) ;
2014-08-25 21:07:07 +00:00
free ( out ) ;
2010-10-23 14:03:35 +00:00
out = NULL ;
return false ;
}
2010-02-25 22:42:42 +00:00
2010-07-14 21:27:26 +00:00
// move to end
out_offset + = out_currOffset ;
2010-02-25 22:42:42 +00:00
2010-07-14 21:27:26 +00:00
// make sure offset has not gone passed valid memory bounds
if ( out_offset > max_outlen ) return false ;
2010-02-25 22:42:42 +00:00
2010-07-14 21:27:26 +00:00
// free encrypted key data
free ( ek ) ;
2010-02-25 22:42:42 +00:00
2017-02-19 22:38:02 +01:00
EVP_CIPHER_CTX_free ( ctx ) ;
2011-05-15 12:01:23 +00:00
2010-07-14 21:27:26 +00:00
outlen = out_offset ;
2010-02-25 22:42:42 +00:00
2010-07-14 21:27:26 +00:00
# ifdef DISTRIB_DEBUG
std : : cerr < < " Authssl::encrypt() finished with outlen : " < < outlen < < std : : endl ;
# endif
2010-02-25 22:42:42 +00:00
return true ;
2009-12-13 21:59:26 +00:00
}
2010-07-04 10:35:38 +00:00
bool AuthSSLimpl : : decrypt ( void * & out , int & outlen , const void * in , int inlen )
2009-12-13 21:59:26 +00:00
{
2010-06-26 12:31:24 +00:00
RsStackMutex stack ( sslMtx ) ; /******* LOCKED ******/
2009-12-13 21:59:26 +00:00
# ifdef AUTHSSL_DEBUG
2010-07-04 10:35:38 +00:00
std : : cerr < < " AuthSSLimpl::decrypt() called with inlen : " < < inlen < < std : : endl ;
2009-12-13 21:59:26 +00:00
# endif
//TODO : use ssl to decrypt the binary input buffer
2010-02-25 22:42:42 +00:00
// out = malloc(inlen);
// memcpy(out, in, inlen);
// outlen = inlen;
2017-02-19 22:38:02 +01:00
EVP_CIPHER_CTX * ctx = EVP_CIPHER_CTX_new ( ) ;
2010-07-14 21:27:26 +00:00
int eklen = 0 , net_ekl = 0 ;
unsigned char iv [ EVP_MAX_IV_LENGTH ] ;
2011-05-15 12:01:23 +00:00
int ek_mkl = EVP_PKEY_size ( mOwnPrivateKey ) ;
2017-07-21 18:40:43 +02:00
unsigned char * ek = ( unsigned char * ) malloc ( ek_mkl ) ;
2016-01-12 21:10:11 -05:00
if ( ek = = NULL )
{
std : : cerr < < " (EE) Cannot allocate memory for " < < ek_mkl < < " bytes in " < < __PRETTY_FUNCTION__ < < std : : endl ;
return false ;
}
2010-02-25 22:42:42 +00:00
2010-07-14 21:27:26 +00:00
int in_offset = 0 , out_currOffset = 0 ;
int size_net_ekl = sizeof ( net_ekl ) ;
2010-01-24 13:59:22 +00:00
2010-10-23 14:03:35 +00:00
if ( size_net_ekl > inlen ) {
free ( ek ) ;
return false ;
}
2010-09-18 19:09:11 +00:00
2010-07-14 21:27:26 +00:00
memcpy ( & net_ekl , ( unsigned char * ) in , size_net_ekl ) ;
eklen = ntohl ( net_ekl ) ;
in_offset + = size_net_ekl ;
2010-02-25 22:42:42 +00:00
2010-10-23 14:03:35 +00:00
if ( eklen > ( inlen - in_offset ) ) {
free ( ek ) ;
return false ;
}
2010-09-18 19:09:11 +00:00
2010-07-14 21:27:26 +00:00
memcpy ( ek , ( unsigned char * ) in + in_offset , eklen ) ;
in_offset + = eklen ;
2010-02-25 22:42:42 +00:00
2010-10-23 14:03:35 +00:00
if ( EVP_MAX_IV_LENGTH > ( inlen - in_offset ) ) {
free ( ek ) ;
return false ;
}
2010-09-18 19:09:11 +00:00
2010-07-14 21:27:26 +00:00
memcpy ( iv , ( unsigned char * ) in + in_offset , EVP_MAX_IV_LENGTH ) ;
in_offset + = EVP_MAX_IV_LENGTH ;
2010-02-25 22:42:42 +00:00
2010-07-14 21:27:26 +00:00
const EVP_CIPHER * cipher = EVP_aes_128_cbc ( ) ;
2010-02-25 22:42:42 +00:00
2017-02-19 22:38:02 +01:00
if ( 0 = = EVP_OpenInit ( ctx , cipher , ek , eklen , iv , mOwnPrivateKey ) ) {
2010-10-23 14:03:35 +00:00
free ( ek ) ;
return false ;
}
2010-02-25 22:42:42 +00:00
2016-01-12 21:43:04 -05:00
out = ( unsigned char * ) rs_malloc ( inlen - in_offset ) ;
2010-02-25 22:42:42 +00:00
2016-01-12 21:10:11 -05:00
if ( out = = NULL )
{
free ( ek ) ;
return false ;
}
2017-02-19 22:38:02 +01:00
if ( ! EVP_OpenUpdate ( ctx , ( unsigned char * ) out , & out_currOffset , ( unsigned char * ) in + in_offset , inlen - in_offset ) ) {
2010-10-23 14:03:35 +00:00
free ( ek ) ;
2014-08-25 21:07:07 +00:00
free ( out ) ;
2010-10-23 14:03:35 +00:00
out = NULL ;
return false ;
}
2010-02-25 22:42:42 +00:00
2017-07-21 18:40:43 +02:00
//in_offset += out_currOffset;
2010-07-14 21:27:26 +00:00
outlen + = out_currOffset ;
2010-02-25 22:42:42 +00:00
2017-02-19 22:38:02 +01:00
if ( ! EVP_OpenFinal ( ctx , ( unsigned char * ) out + out_currOffset , & out_currOffset ) ) {
2010-10-23 14:03:35 +00:00
free ( ek ) ;
2014-08-25 21:07:07 +00:00
free ( out ) ;
2010-10-23 14:03:35 +00:00
out = NULL ;
return false ;
}
2010-02-25 22:42:42 +00:00
2010-07-14 21:27:26 +00:00
outlen + = out_currOffset ;
2010-02-25 22:42:42 +00:00
2010-09-18 19:09:11 +00:00
if ( ek ! = NULL )
free ( ek ) ;
2010-02-25 22:42:42 +00:00
2017-02-19 22:38:02 +01:00
EVP_CIPHER_CTX_free ( ctx ) ;
2011-05-15 12:01:23 +00:00
2014-08-25 21:07:07 +00:00
# ifdef AUTHSSL_DEBUG
std : : cerr < < " AuthSSLimpl::decrypt() finished with outlen : " < < outlen < < std : : endl ;
# endif
2010-02-25 22:42:42 +00:00
return true ;
}
2010-06-26 12:31:24 +00:00
/********************************************************************************/
/********************************************************************************/
/********************* Cert Search / Add / Remove **************************/
/********************************************************************************/
/********************************************************************************/
2014-03-17 20:56:06 +00:00
void AuthSSLimpl : : setCurrentConnectionAttemptInfo ( const RsPgpId & gpg_id , const RsPeerId & ssl_id , const std : : string & ssl_cn )
2012-09-09 20:25:39 +00:00
{
2012-09-14 21:04:16 +00:00
# ifdef AUTHSSL_DEBUG
2013-06-24 21:23:50 +00:00
std : : cerr < < " AuthSSL: registering connection attempt from: " < < std : : endl ;
2012-09-09 20:25:39 +00:00
std : : cerr < < " GPG id: " < < gpg_id < < std : : endl ;
std : : cerr < < " SSL id: " < < ssl_id < < std : : endl ;
std : : cerr < < " SSL cn: " < < ssl_cn < < std : : endl ;
2012-09-14 21:04:16 +00:00
# endif
2012-09-09 20:25:39 +00:00
_last_gpgid_to_connect = gpg_id ;
_last_sslid_to_connect = ssl_id ;
_last_sslcn_to_connect = ssl_cn ;
}
2014-03-17 20:56:06 +00:00
void AuthSSLimpl : : getCurrentConnectionAttemptInfo ( RsPgpId & gpg_id , RsPeerId & ssl_id , std : : string & ssl_cn )
2012-09-14 21:04:16 +00:00
{
gpg_id = _last_gpgid_to_connect ;
ssl_id = _last_sslid_to_connect ;
ssl_cn = _last_sslcn_to_connect ;
}
2012-09-09 20:25:39 +00:00
2010-06-26 12:31:24 +00:00
/* store for discovery */
2014-03-17 20:56:06 +00:00
bool AuthSSLimpl : : FailedCertificate ( X509 * x509 , const RsPgpId & gpgid ,
const RsPeerId & sslid ,
2012-09-14 21:04:16 +00:00
const std : : string & sslcn ,
2013-09-13 14:35:19 +00:00
const struct sockaddr_storage & addr ,
2012-09-14 21:04:16 +00:00
bool incoming )
2010-06-26 12:31:24 +00:00
{
2013-09-13 14:35:19 +00:00
std : : string ip_address = sockaddr_storage_tostring ( addr ) ;
2012-09-09 20:25:39 +00:00
2014-02-01 14:16:15 +00:00
uint32_t auth_diagnostic = 0 ;
2014-01-16 19:57:08 +00:00
bool authed ;
if ( x509 = = NULL )
{
2014-01-28 21:33:17 +00:00
auth_diagnostic = RS_SSL_HANDSHAKE_DIAGNOSTIC_CERTIFICATE_MISSING ;
2014-01-16 19:57:08 +00:00
authed = false ;
}
else
authed = AuthX509WithGPG ( x509 , auth_diagnostic ) ;
2011-07-11 00:55:06 +00:00
2012-09-14 21:04:16 +00:00
if ( authed )
LocalStoreCert ( x509 ) ;
2011-07-11 00:55:06 +00:00
2012-09-17 20:49:52 +00:00
# ifdef AUTHSSL_DEBUG
2011-07-11 00:55:06 +00:00
std : : cerr < < " AuthSSLimpl::FailedCertificate() " ;
2012-09-17 20:49:52 +00:00
# endif
2011-07-11 00:55:06 +00:00
if ( incoming )
{
2014-03-17 20:56:06 +00:00
RsServer : : notify ( ) - > AddPopupMessage ( RS_POPUP_CONNECT_ATTEMPT , gpgid . toStdString ( ) , sslcn , sslid . toStdString ( ) ) ;
2014-01-15 20:19:17 +00:00
switch ( auth_diagnostic )
{
2016-10-09 14:32:52 +02:00
case RS_SSL_HANDSHAKE_DIAGNOSTIC_CERTIFICATE_MISSING :
RsServer : : notify ( ) - > notifyConnectionWithoutCert ( ) ;
RsServer : : notify ( ) - > AddFeedItem ( RS_FEED_ITEM_SEC_MISSING_CERTIFICATE , gpgid . toStdString ( ) , sslid . toStdString ( ) , sslcn , ip_address ) ;
break ;
case RS_SSL_HANDSHAKE_DIAGNOSTIC_CERTIFICATE_NOT_VALID :
RsServer : : notify ( ) - > AddFeedItem ( RS_FEED_ITEM_SEC_BAD_CERTIFICATE , gpgid . toStdString ( ) , sslid . toStdString ( ) , sslcn , ip_address ) ;
break ;
case RS_SSL_HANDSHAKE_DIAGNOSTIC_ISSUER_UNKNOWN :
RsServer : : notify ( ) - > AddFeedItem ( RS_FEED_ITEM_SEC_UNKNOWN_IN , gpgid . toStdString ( ) , sslid . toStdString ( ) , sslcn , ip_address ) ;
break ;
case RS_SSL_HANDSHAKE_DIAGNOSTIC_MALLOC_ERROR :
RsServer : : notify ( ) - > AddFeedItem ( RS_FEED_ITEM_SEC_INTERNAL_ERROR , gpgid . toStdString ( ) , sslid . toStdString ( ) , sslcn , ip_address ) ;
break ;
case RS_SSL_HANDSHAKE_DIAGNOSTIC_WRONG_SIGNATURE :
RsServer : : notify ( ) - > AddFeedItem ( RS_FEED_ITEM_SEC_WRONG_SIGNATURE , gpgid . toStdString ( ) , sslid . toStdString ( ) , sslcn , ip_address ) ;
break ;
case RS_SSL_HANDSHAKE_DIAGNOSTIC_OK :
case RS_SSL_HANDSHAKE_DIAGNOSTIC_UNKNOWN :
default :
RsServer : : notify ( ) - > AddFeedItem ( RS_FEED_ITEM_SEC_CONNECT_ATTEMPT , gpgid . toStdString ( ) , sslid . toStdString ( ) , sslcn , ip_address ) ;
2014-01-15 20:19:17 +00:00
}
2012-09-14 21:04:16 +00:00
2012-09-17 20:49:52 +00:00
# ifdef AUTHSSL_DEBUG
2011-07-11 00:55:06 +00:00
std : : cerr < < " Incoming from: " ;
2012-09-17 20:49:52 +00:00
# endif
2011-07-11 00:55:06 +00:00
}
2012-09-14 21:04:16 +00:00
else
2011-07-11 00:55:06 +00:00
{
2012-09-14 21:04:16 +00:00
if ( authed )
2014-03-17 20:56:06 +00:00
RsServer : : notify ( ) - > AddFeedItem ( RS_FEED_ITEM_SEC_AUTH_DENIED , gpgid . toStdString ( ) , sslid . toStdString ( ) , sslcn , ip_address ) ;
2012-09-14 21:04:16 +00:00
else
2014-03-17 20:56:06 +00:00
RsServer : : notify ( ) - > AddFeedItem ( RS_FEED_ITEM_SEC_UNKNOWN_OUT , gpgid . toStdString ( ) , sslid . toStdString ( ) , sslcn , ip_address ) ;
2012-09-14 21:04:16 +00:00
2012-09-17 20:49:52 +00:00
# ifdef AUTHSSL_DEBUG
2011-07-11 00:55:06 +00:00
std : : cerr < < " Outgoing to: " ;
2012-09-17 20:49:52 +00:00
# endif
2011-07-11 00:55:06 +00:00
}
2012-09-09 20:25:39 +00:00
2012-09-17 20:49:52 +00:00
# ifdef AUTHSSL_DEBUG
2012-09-09 20:25:39 +00:00
std : : cerr < < " GpgId: " < < gpgid < < " SSLcn: " < < sslcn < < " peerId: " < < sslid < < " , ip address: " < < ip_address ;
std : : cerr < < std : : endl ;
2012-09-17 20:49:52 +00:00
# endif
2012-01-20 17:50:19 +00:00
2010-06-26 12:31:24 +00:00
return false ;
}
2014-03-17 20:56:06 +00:00
bool AuthSSLimpl : : CheckCertificate ( const RsPeerId & id , X509 * x509 )
2010-06-26 12:31:24 +00:00
{
( void ) id ; /* remove unused parameter warning */
2014-01-15 20:19:17 +00:00
uint32_t diagnos ;
2010-06-26 12:31:24 +00:00
/* if auths -> store */
2014-01-15 20:19:17 +00:00
if ( AuthX509WithGPG ( x509 , diagnos ) )
2010-06-26 12:31:24 +00:00
{
LocalStoreCert ( x509 ) ;
return true ;
}
return false ;
}
/* Locked search -> internal help function */
2014-03-17 20:56:06 +00:00
bool AuthSSLimpl : : locked_FindCert ( const RsPeerId & id , sslcert * * cert )
2010-06-26 12:31:24 +00:00
{
2014-03-17 20:56:06 +00:00
std : : map < RsPeerId , sslcert * > : : iterator it ;
2010-06-26 12:31:24 +00:00
if ( mCerts . end ( ) ! = ( it = mCerts . find ( id ) ) )
{
* cert = it - > second ;
return true ;
}
return false ;
}
/* Remove Certificate */
2014-03-17 20:56:06 +00:00
bool AuthSSLimpl : : RemoveX509 ( RsPeerId id )
2010-06-26 12:31:24 +00:00
{
2014-03-17 20:56:06 +00:00
std : : map < RsPeerId , sslcert * > : : iterator it ;
2010-06-26 12:31:24 +00:00
RsStackMutex stack ( sslMtx ) ; /******* LOCKED ******/
if ( mCerts . end ( ) ! = ( it = mCerts . find ( id ) ) )
{
sslcert * cert = it - > second ;
/* clean up */
X509_free ( cert - > certificate ) ;
cert - > certificate = NULL ;
delete cert ;
mCerts . erase ( it ) ;
return true ;
}
return false ;
}
2010-07-04 10:35:38 +00:00
bool AuthSSLimpl : : LocalStoreCert ( X509 * x509 )
2010-06-26 12:31:24 +00:00
{
//store the certificate in the local cert list
2014-03-17 20:56:06 +00:00
RsPeerId peerId ;
2010-06-26 12:31:24 +00:00
if ( ! getX509id ( x509 , peerId ) )
{
2010-07-04 10:35:38 +00:00
std : : cerr < < " AuthSSLimpl::LocalStoreCert() Cannot retrieve peer id from certificate. " < < std : : endl ;
2010-06-26 12:31:24 +00:00
# ifdef AUTHSSL_DEBUG
# endif
return false ;
}
2014-03-17 20:56:06 +00:00
if ( peerId . isNull ( ) )
{
std : : cerr < < " AuthSSLimpl::LocalStoreCert(): invalid peer id \" " < < peerId < < " \" " < < std : : endl ;
return false ;
}
2010-06-26 12:31:24 +00:00
RsStackMutex stack ( sslMtx ) ; /******* LOCKED ******/
if ( peerId = = mOwnId )
{
# ifdef AUTHSSL_DEBUG
2010-07-04 10:35:38 +00:00
std : : cerr < < " AuthSSLimpl::LocalStoreCert() not storing own certificate " < < std : : endl ;
2010-06-26 12:31:24 +00:00
# endif
return false ;
}
/* do a search */
2014-03-17 20:56:06 +00:00
std : : map < RsPeerId , sslcert * > : : iterator it ;
2010-06-26 12:31:24 +00:00
if ( mCerts . end ( ) ! = ( it = mCerts . find ( peerId ) ) )
{
sslcert * cert = it - > second ;
/* found something */
/* check that they are exact */
if ( 0 ! = X509_cmp ( cert - > certificate , x509 ) )
{
/* MAJOR ERROR */
2010-07-04 10:35:38 +00:00
std : : cerr < < " ERROR : AuthSSLimpl::LocalStoreCert() got two ssl certificates with identical ids -> dropping second " ;
2010-06-26 12:31:24 +00:00
std : : cerr < < std : : endl ;
return false ;
}
/* otherwise - we have it already */
return false ;
}
# ifdef AUTHSSL_DEBUG
2010-07-04 10:35:38 +00:00
std : : cerr < < " AuthSSLimpl::LocalStoreCert() storing certificate for " < < peerId < < std : : endl ;
2010-06-26 12:31:24 +00:00
# endif
mCerts [ peerId ] = new sslcert ( X509_dup ( x509 ) , peerId ) ;
/* flag for saving config */
IndicateConfigChanged ( ) ;
return true ;
}
/********************************************************************************/
/********************************************************************************/
/************************ Config Functions **********************************/
/********************************************************************************/
/********************************************************************************/
2010-07-04 10:35:38 +00:00
RsSerialiser * AuthSSLimpl : : setupSerialiser ( )
2010-02-25 22:42:42 +00:00
{
2010-07-04 10:35:38 +00:00
RsSerialiser * rss = new RsSerialiser ( ) ;
2010-02-25 22:42:42 +00:00
rss - > addSerialType ( new RsGeneralConfigSerialiser ( ) ) ;
return rss ;
}
2010-12-18 19:35:07 +00:00
bool AuthSSLimpl : : saveList ( bool & cleanup , std : : list < RsItem * > & lst )
2010-02-25 22:42:42 +00:00
{
# ifdef AUTHSSL_DEBUG
2010-07-04 10:35:38 +00:00
std : : cerr < < " AuthSSLimpl::saveList() called " < < std : : endl ;
2010-02-25 22:42:42 +00:00
# endif
RsStackMutex stack ( sslMtx ) ; /******* LOCKED ******/
cleanup = true ;
// Now save config for network digging strategies
RsConfigKeyValueSet * vitem = new RsConfigKeyValueSet ;
2014-03-17 20:56:06 +00:00
std : : map < RsPeerId , sslcert * > : : iterator mapIt ;
2014-10-24 22:07:26 +00:00
for ( mapIt = mCerts . begin ( ) ; mapIt ! = mCerts . end ( ) ; + + mapIt ) {
2010-02-25 22:42:42 +00:00
if ( mapIt - > first = = mOwnId ) {
continue ;
}
RsTlvKeyValue kv ;
2014-03-17 20:56:06 +00:00
kv . key = mapIt - > first . toStdString ( ) ;
2010-02-25 22:42:42 +00:00
# ifdef AUTHSSL_DEBUG
2010-07-04 10:35:38 +00:00
std : : cerr < < " AuthSSLimpl::saveList() called (mapIt->first) : " < < ( mapIt - > first ) < < std : : endl ;
2010-02-25 22:42:42 +00:00
# endif
2010-06-26 12:31:24 +00:00
kv . value = saveX509ToPEM ( mapIt - > second - > certificate ) ;
2010-02-25 22:42:42 +00:00
vitem - > tlvkvs . pairs . push_back ( kv ) ;
}
lst . push_back ( vitem ) ;
2010-12-18 19:35:07 +00:00
return true ;
2010-02-25 22:42:42 +00:00
}
2010-12-18 19:35:07 +00:00
bool AuthSSLimpl : : loadList ( std : : list < RsItem * > & load )
2010-02-25 22:42:42 +00:00
{
# ifdef AUTHSSL_DEBUG
2010-07-04 10:35:38 +00:00
std : : cerr < < " AuthSSLimpl::loadList() Item Count: " < < load . size ( ) < < std : : endl ;
2010-02-25 22:42:42 +00:00
# endif
/* load the list of accepted gpg keys */
std : : list < RsItem * > : : iterator it ;
2014-10-24 22:07:26 +00:00
for ( it = load . begin ( ) ; it ! = load . end ( ) ; + + it ) {
2010-02-25 22:42:42 +00:00
RsConfigKeyValueSet * vitem = dynamic_cast < RsConfigKeyValueSet * > ( * it ) ;
if ( vitem ) {
# ifdef AUTHSSL_DEBUG
2010-07-04 10:35:38 +00:00
std : : cerr < < " AuthSSLimpl::loadList() General Variable Config Item: " < < std : : endl ;
2010-02-25 22:42:42 +00:00
vitem - > print ( std : : cerr , 10 ) ;
std : : cerr < < std : : endl ;
# endif
std : : list < RsTlvKeyValue > : : iterator kit ;
2014-10-24 22:07:26 +00:00
for ( kit = vitem - > tlvkvs . pairs . begin ( ) ; kit ! = vitem - > tlvkvs . pairs . end ( ) ; + + kit ) {
2014-03-17 20:56:06 +00:00
if ( RsPeerId ( kit - > key ) = = mOwnId ) {
2010-02-25 22:42:42 +00:00
continue ;
}
2010-06-26 12:31:24 +00:00
X509 * peer = loadX509FromPEM ( kit - > value ) ;
/* authenticate it */
2014-02-01 14:16:15 +00:00
uint32_t diagnos ;
2014-01-15 20:19:17 +00:00
if ( AuthX509WithGPG ( peer , diagnos ) )
2010-06-26 12:31:24 +00:00
{
LocalStoreCert ( peer ) ;
}
2010-02-25 22:42:42 +00:00
}
}
delete ( * it ) ;
}
2015-12-30 18:20:09 -05:00
load . clear ( ) ;
2010-02-25 22:42:42 +00:00
return true ;
2009-12-13 21:59:26 +00:00
}
2009-04-22 23:29:16 +00:00
/********************************************************************************/
/********************************************************************************/
/********************************************************************************/
/********************************************************************************/
/********************************************************************************/