2009-04-22 19:29:16 -04: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 19:07:51 -04:00
# ifdef WINDOWS_SYS
# include "util/rswin.h"
# endif // WINDOWS_SYS
2009-04-22 19:29:16 -04:00
# include "authssl.h"
2010-06-26 08:31:24 -04:00
# include "sslfns.h"
2009-04-22 19:29:16 -04:00
# include "pqinetwork.h"
2010-01-13 15:58:58 -05:00
# include "authgpg.h"
2017-04-24 16:47:08 -04:00
# include "rsitems/rsconfigitems.h"
2011-04-03 19:11:38 -04:00
# include "util/rsdir.h"
2012-04-14 18:38:24 -04:00
# include "util/rsstring.h"
2009-04-22 19:29:16 -04:00
2011-08-07 17:11:00 -04:00
# include "retroshare/rspeers.h" // for RsPeerDetails structure
2014-03-17 16:56:06 -04:00
# include "retroshare/rsids.h" // for RsPeerDetails structure
2014-01-07 17:51:22 -05:00
# include "rsserver/p3face.h"
2011-08-07 17:11:00 -04:00
2009-04-22 19:29:16 -04:00
/******************** notify of new Cert **************************/
# include <openssl/rand.h>
2013-09-26 19:53:06 -04:00
# include <openssl/ssl.h>
2009-04-22 19:29:16 -04:00
# include <iomanip>
2014-01-15 15:19:17 -05:00
/* SSL connection diagnostic */
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 ;
2014-01-28 16:33:17 -05:00
const uint32_t RS_SSL_HANDSHAKE_DIAGNOSTIC_CERTIFICATE_MISSING = 0x06 ;
2014-01-15 15:19:17 -05:00
2010-06-24 14:06:10 -04:00
/****
* # define AUTHSSL_DEBUG 1
* * */
2011-07-10 20:55:06 -04:00
// initialisation du pointeur de singleton
2012-12-26 13:12:19 -05:00
AuthSSL * AuthSSL : : instance_ssl = NULL ;
2012-05-15 09:51:24 -04: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 07:00:49 -04:00
# if defined( WINDOWS_SYS) && !defined(WIN_PTHREADS_H)
2012-05-15 09:51:24 -04: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 09:51:24 -04:00
return NULL ;
2016-01-12 21:10:11 -05:00
2012-05-15 09:51:24 -04: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 09:51:24 -04:00
return false ;
2016-01-12 21:10:11 -05:00
2012-05-15 09:51:24 -04: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 09:51:24 -04: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 06:35:38 -04:00
/* hidden function - for testing purposes() */
2012-12-26 13:12:19 -05:00
void AuthSSL : : setAuthSSL_debug ( AuthSSL * newssl )
2010-07-04 06:35:38 -04:00
{
instance_ssl = newssl ;
}
2012-12-26 13:12:19 -05:00
void AuthSSL : : AuthSSLInit ( )
2010-07-04 06:35:38 -04:00
{
2012-06-09 20:29:46 -04:00
if ( instance_ssl = = NULL )
{
instance_ssl = new AuthSSLimpl ( ) ;
}
2010-07-04 06:35:38 -04:00
}
AuthSSL * AuthSSL : : getAuthSSL ( )
{
return instance_ssl ;
}
AuthSSL : : AuthSSL ( )
{
return ;
}
2009-04-22 19:29:16 -04:00
/********************************************************************************/
/********************************************************************************/
2010-06-26 08:31:24 -04:00
/********************* Cert Search / Add / Remove **************************/
2009-04-22 19:29:16 -04:00
/********************************************************************************/
2010-06-26 08:31:24 -04:00
/********************************************************************************/
static int verify_x509_callback ( int preverify_ok , X509_STORE_CTX * ctx ) ;
2009-04-22 19:29:16 -04:00
2010-06-24 13:41:34 -04:00
2014-03-17 16:56:06 -04:00
sslcert : : sslcert ( X509 * x509 , const RsPeerId & pid )
2009-04-22 19:29:16 -04:00
{
certificate = x509 ;
id = pid ;
2017-02-19 16:38:02 -05:00
# if OPENSSL_VERSION_NUMBER < 0x10100000L
2009-04-22 19:29:16 -04:00
name = getX509CNString ( x509 - > cert_info - > subject ) ;
org = getX509OrgString ( x509 - > cert_info - > subject ) ;
location = getX509LocString ( x509 - > cert_info - > subject ) ;
2014-03-17 16:56:06 -04:00
issuer = RsPgpId ( std : : string ( getX509CNString ( x509 - > cert_info - > issuer ) ) ) ;
2017-02-19 16:38:02 -05: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 11:07:35 -04:00
2009-04-22 19:29:16 -04:00
authed = false ;
}
2010-06-26 08:31:24 -04: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 11:07:35 -04:00
2010-06-26 08:31:24 -04:00
/********************************************************************************/
/********************************************************************************/
/********************* Cert Search / Add / Remove **************************/
/********************************************************************************/
/********************************************************************************/
2009-05-23 11:07:35 -04:00
2009-04-22 19:29:16 -04:00
2010-07-04 06:35:38 -04:00
AuthSSLimpl : : AuthSSLimpl ( )
2014-03-29 01:20:57 -04:00
: p3Config ( ) , sslctx ( NULL ) ,
2011-07-04 18:59:39 -04:00
mOwnCert ( NULL ) , sslMtx ( " AuthSSL " ) , mOwnPrivateKey ( NULL ) , mOwnPublicKey ( NULL ) , init ( 0 )
2009-04-22 19:29:16 -04:00
{
}
2010-07-04 06:35:38 -04:00
bool AuthSSLimpl : : active ( )
2009-04-22 19:29:16 -04:00
{
return init ;
}
2010-01-13 16:02:39 -05:00
2010-07-04 06:35:38 -04:00
int AuthSSLimpl : : InitAuth ( const char * cert_file , const char * priv_key_file ,
2015-03-25 04:19:45 -04:00
const char * passwd , std : : string alternative_location_name )
2009-04-22 19:29:16 -04:00
{
# ifdef AUTHSSL_DEBUG
2010-07-04 06:35:38 -04:00
std : : cerr < < " AuthSSLimpl::InitAuth() " ;
2009-04-22 19:29:16 -04:00
std : : cerr < < std : : endl ;
# endif
2010-06-26 08:31:24 -04:00
/* single call here si don't need to invoke mutex yet */
2009-04-22 19:29:16 -04:00
static int initLib = 0 ;
if ( ! initLib )
{
initLib = 1 ;
2012-05-15 09:51:24 -04:00
if ( ! tls_init ( ) ) {
return 0 ;
}
2009-04-22 19:29:16 -04:00
SSL_load_error_strings ( ) ;
SSL_library_init ( ) ;
}
if ( init = = 1 )
{
2010-07-04 06:35:38 -04:00
std : : cerr < < " AuthSSLimpl::InitAuth already initialized. " < < std : : endl ;
2009-04-22 19:29:16 -04:00
return 1 ;
}
if ( ( cert_file = = NULL ) | |
( priv_key_file = = NULL ) | |
( passwd = = NULL ) )
{
2010-02-07 16:28:40 -05:00
//fprintf(stderr, "sslroot::initssl() missing parameters!\n");
2009-04-22 19:29:16 -04: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 15:07:40 -05:00
sslctx = SSL_CTX_new ( SSLv23_method ( ) ) ;
SSL_CTX_set_options ( sslctx , SSL_OP_NO_SSLv3 ) ;
2009-04-22 19:29:16 -04:00
2016-02-14 12:49:37 -05: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 08:28:45 -04: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 16:41:43 -05:00
// std::string cipherString = "kEDH:HIGH:!DSS:!aNULL:!3DES";
2013-09-14 08:28:45 -04:00
//
2013-12-28 16:41:43 -05:00
// The following safe primes are 2048/4096 bits long. Should be enough.
2013-09-14 08:28:45 -04:00
//
// std::string dh_prime_2048_dec = "30651576830996935311378276950670996791883170963804289256203421500259588715033040934547350194073369837229137842804826417332761673984632102152477971341551955103053338169949165519208562998954887445690136488713010579430413255432398961330773637820158790237012997356731669148258317860643591694814197514454546928317578771868379525705082166818553884557266645700906836702542808787791878865135741211056957383668479369231868698451684633965462539374994559481908068730787128654626819903401038534403722014687647173327537458614224702967073490136394698912372792187651228785689025073104374674728645661275001416541267543884923191810923";
//
std : : string dh_prime_2048_hex = " B3B86A844550486C7EA459FA468D3A8EFD71139593FE1C658BBEFA9B2FC0AD2628242C2CDC2F91F5B220ED29AAC271192A7374DFA28CDDCA70252F342D0821273940344A7A6A3CB70C7897A39864309F6CAC5C7EA18020EF882693CA2C12BB211B7BA8367D5A7C7252A5B5E840C9E8F081469EBA0B98BCC3F593A4D9C4D5DF539362084F1B9581316C1F80FDAD452FD56DBC6B8ED0775F596F7BB22A3FE2B4753764221528D33DB4140DE58083DB660E3E105123FC963BFF108AC3A268B7380FFA72005A1515C371287C5706FFA6062C9AC73A9B1A6AC842C2764CDACFC85556607E86611FDF486C222E4896CDF6908F239E177ACC641FCBFF72A758D1C10CBB " ;
std : : string dh_prime_4096_hex = " A6F5777292D9E6BB95559C9124B9119E6771F11F2048C8FE74F4E8140494520972A087EF1D60B73894F1C5D509DD15D96CF379E9DDD46CE51B748085BACB440D915565782C73AF3A9580CE788441D1DA4D114E3D302CAB45A061ABCFC1F7E9200AE019CB923B77E096FA9377454A16FFE91D86535FF23E075B3E714F785CD7606E9CBD9D06F01CAFA2271883D649F13ABE170D714F6B6EC064C5BF35C4F4BDA5EF5ED5E70D5DC78F1AC1CDC04EEDAE8ADD65C4A9E27368E0B2C8595DD7626D763BFFB15364B3CCA9FCE814B9226B35FE652F4B041F0FF6694D6A482B0EF48CA41163D083AD2DE7B7A068BB05C0453E9D008551C7F67993A3EF2C4874F0244F78C4E0997BD31AB3BD88446916B499B2513DD5BA002063BD38D2CE55D29D071399D5CEE99458AF6FDC104A61CA3FACDAC803CBDE62B4C0EAC946D0E12F05CE9E94497110D64E611D957423B8AA412D84EC83E6E70E0977A31D6EE056D0527D4667D7242A77C9B679D191562E4026DA9C35FF85666296D872ED548E0FFE1A677FCC373C1F490CAB4F53DFD8735C0F1DF02FEAD824A217FDF4E3404D38A5BBC719C6622630FCD34F6F1968AF1B66A4AB1A9FCF653DA96EB3A42AF6FCFEA0547B8F314A527C519949007D7FA1726FF3D33EC46393B0207AA029E5EA574BDAC94D78894B22A2E3303E65A3F820DF57DB44951DE4E973C016C57F7A242D0BC53BC563AF " ;
2014-05-11 14:42:16 -04:00
std : : string cipherString = " kEDH+HIGH:!DSS:!aNULL:!3DES:!EXP " ;
2013-09-14 08:28:45 -04:00
2013-08-21 17:36:33 -04:00
SSL_CTX_set_cipher_list ( sslctx , cipherString . c_str ( ) ) ;
2013-09-14 08:28:45 -04:00
DH * dh = DH_new ( ) ;
int codes = 0 ;
bool pfs_enabled = true ;
if ( dh )
{
2017-02-19 16:38:02 -05:00
# if OPENSSL_VERSION_NUMBER < 0x10100000L
2013-09-14 08:28:45 -04:00
BN_hex2bn ( & dh - > p , dh_prime_4096_hex . c_str ( ) ) ;
BN_hex2bn ( & dh - > g , " 5 " ) ;
2017-02-19 16:38:02 -05: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 08:28:45 -04: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 19:29:16 -04:00
// certificates (Set Local Server Certificate).
2011-04-03 19:11:38 -04:00
FILE * ownfp = RsDirUtil : : rs_fopen ( cert_file , " r " ) ;
2009-04-22 19:29:16 -04: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 06:35:38 -04:00
std : : cerr < < " AuthSSLimpl::InitAuth() PEM_read_X509() Failed " ;
2009-05-23 11:07:35 -04:00
std : : cerr < < std : : endl ;
2009-04-22 19:29:16 -04:00
return - 1 ;
}
SSL_CTX_use_certificate ( sslctx , x509 ) ;
2010-06-26 08:31:24 -04:00
mOwnPublicKey = X509_get_pubkey ( x509 ) ;
2009-04-22 19:29:16 -04:00
// get private key
2011-04-03 19:11:38 -04:00
FILE * pkfp = RsDirUtil : : rs_fopen ( priv_key_file , " rb " ) ;
2009-04-22 19:29:16 -04:00
if ( pkfp = = NULL )
{
std : : cerr < < " Couldn't Open PrivKey File! " < < std : : endl ;
CloseAuth ( ) ;
return - 1 ;
}
2010-06-26 08:31:24 -04:00
mOwnPrivateKey = PEM_read_PrivateKey ( pkfp , NULL , NULL , ( void * ) passwd ) ;
2009-04-22 19:29:16 -04:00
fclose ( pkfp ) ;
2010-06-26 08:31:24 -04:00
if ( mOwnPrivateKey = = NULL )
2009-04-22 19:29:16 -04:00
{
2010-07-04 06:35:38 -04:00
std : : cerr < < " AuthSSLimpl::InitAuth() PEM_read_PrivateKey() Failed " ;
2009-05-23 11:07:35 -04:00
std : : cerr < < std : : endl ;
2009-04-22 19:29:16 -04:00
return - 1 ;
}
2010-06-26 08:31:24 -04:00
SSL_CTX_use_PrivateKey ( sslctx , mOwnPrivateKey ) ;
2009-04-22 19:29:16 -04: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 16:56:06 -04:00
RsPeerId mownidstr ;
if ( ! getX509id ( x509 , mownidstr ) )
2009-04-22 19:29:16 -04:00
{
2010-07-04 06:35:38 -04:00
std : : cerr < < " AuthSSLimpl::InitAuth() getX509id() Failed " ;
2009-05-23 11:07:35 -04:00
std : : cerr < < std : : endl ;
2009-04-22 19:29:16 -04:00
/* bad certificate */
CloseAuth ( ) ;
return - 1 ;
}
2014-03-17 16:56:06 -04:00
mOwnId = mownidstr ;
assert ( ! mOwnId . isNull ( ) ) ;
2009-04-22 19:29:16 -04:00
/* Check that Certificate is Ok ( virtual function )
* for gpg / pgp or CA verification
*/
2013-09-14 08:28:45 -04:00
if ( ! validateOwnCertificate ( x509 , mOwnPrivateKey ) )
2009-05-23 11:07:35 -04:00
{
2010-07-04 06:35:38 -04:00
std : : cerr < < " AuthSSLimpl::InitAuth() validateOwnCertificate() Failed " ;
2009-05-23 11:07:35 -04:00
std : : cerr < < std : : endl ;
/* bad certificate */
CloseAuth ( ) ;
2010-06-26 08:31:24 -04:00
exit ( 1 ) ;
2009-05-23 11:07:35 -04:00
return - 1 ;
}
2009-04-22 19:29:16 -04:00
// enable verification of certificates (PEER)
2009-05-23 11:07:35 -04:00
// and install verify callback.
2009-04-22 19:29:16 -04:00
SSL_CTX_set_verify ( sslctx , SSL_VERIFY_PEER |
2009-05-23 11:07:35 -04:00
SSL_VERIFY_FAIL_IF_NO_PEER_CERT ,
verify_x509_callback ) ;
2009-04-22 19:29:16 -04:00
std : : cerr < < " SSL Verification Set " < < std : : endl ;
mOwnCert = new sslcert ( x509 , mOwnId ) ;
2016-10-22 17:48:19 -04: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 04:19:45 -04:00
2013-09-14 08:28:45 -04: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 19:29:16 -04:00
init = 1 ;
return 1 ;
}
2009-05-23 11:07:35 -04:00
/* Dummy function to be overloaded by real implementation */
2010-07-04 06:35:38 -04:00
bool AuthSSLimpl : : validateOwnCertificate ( X509 * x509 , EVP_PKEY * pkey )
2009-05-23 11:07:35 -04:00
{
2010-06-26 08:31:24 -04:00
( void ) pkey ; /* remove unused parameter warning */
2014-01-15 15:19:17 -05:00
uint32_t diagnostic ;
2010-06-26 08:31:24 -04:00
/* standard authentication */
2014-01-15 15:19:17 -05:00
if ( ! AuthX509WithGPG ( x509 , diagnostic ) )
2010-06-26 08:31:24 -04:00
{
return false ;
}
2009-05-23 11:07:35 -04:00
return true ;
}
2009-04-22 19:29:16 -04:00
2010-07-04 06:35:38 -04:00
bool AuthSSLimpl : : CloseAuth ( )
2009-04-22 19:29:16 -04:00
{
2012-05-15 09:51:24 -04:00
tls_cleanup ( ) ;
2009-04-22 19:29:16 -04:00
# ifdef AUTHSSL_DEBUG
2010-07-04 06:35:38 -04:00
std : : cerr < < " AuthSSLimpl::CloseAuth() " ;
2009-04-22 19:29:16 -04: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 06:35:38 -04:00
SSL_CTX * AuthSSLimpl : : getCTX ( )
2009-04-22 19:29:16 -04:00
{
# ifdef AUTHSSL_DEBUG
2010-07-04 06:35:38 -04:00
std : : cerr < < " AuthSSLimpl::getCTX() " ;
2009-04-22 19:29:16 -04:00
std : : cerr < < std : : endl ;
# endif
return sslctx ;
}
2014-03-17 16:56:06 -04:00
const RsPeerId & AuthSSLimpl : : OwnId ( )
2009-04-22 19:29:16 -04:00
{
# ifdef AUTHSSL_DEBUG
2010-07-04 06:35:38 -04:00
// std::cerr << "AuthSSLimpl::OwnId()" << std::endl;
2009-04-22 19:29:16 -04:00
# endif
2010-02-10 16:54:28 -05:00
return mOwnId ;
2009-04-22 19:29:16 -04:00
}
2010-07-04 06:35:38 -04:00
std : : string AuthSSLimpl : : getOwnLocation ( )
2010-01-13 16:29:21 -05:00
{
# ifdef AUTHSSL_DEBUG
2010-07-04 06:35:38 -04:00
std : : cerr < < " AuthSSLimpl::OwnId() " < < std : : endl ;
2010-01-13 16:29:21 -05:00
# endif
2010-02-10 16:54:28 -05:00
return mOwnCert - > location ;
2010-01-13 16:29:21 -05:00
}
2009-04-22 19:29:16 -04:00
2010-07-04 06:35:38 -04:00
std : : string AuthSSLimpl : : SaveOwnCertificateToString ( )
2009-04-22 19:29:16 -04:00
{
# ifdef AUTHSSL_DEBUG
2010-07-04 06:35:38 -04:00
std : : cerr < < " AuthSSLimpl::SaveOwnCertificateToString() " < < std : : endl ;
2009-04-22 19:29:16 -04:00
# endif
2010-06-26 08:31:24 -04:00
return saveX509ToPEM ( mOwnCert - > certificate ) ;
2010-02-25 17:42:42 -05:00
}
2009-04-22 19:29:16 -04:00
2010-06-26 08:31:24 -04:00
/********************************************************************************/
/********************************************************************************/
/********************* Cert Search / Add / Remove **************************/
/********************************************************************************/
/********************************************************************************/
2009-04-22 19:29:16 -04:00
2010-07-04 06:35:38 -04:00
bool AuthSSLimpl : : SignData ( std : : string input , std : : string & sign )
2009-04-22 19:29:16 -04:00
{
return SignData ( input . c_str ( ) , input . length ( ) , sign ) ;
}
2010-07-04 06:35:38 -04:00
bool AuthSSLimpl : : SignData ( const void * data , const uint32_t len , std : : string & sign )
2009-04-22 19:29:16 -04:00
{
RsStackMutex stack ( sslMtx ) ; /***** STACK LOCK MUTEX *****/
EVP_MD_CTX * mdctx = EVP_MD_CTX_create ( ) ;
2010-06-26 08:31:24 -04:00
unsigned int signlen = EVP_PKEY_size ( mOwnPrivateKey ) ;
2009-04-22 19:29:16 -04:00
unsigned char signature [ signlen ] ;
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 08:31:24 -04:00
if ( 0 = = EVP_SignFinal ( mdctx , signature , & signlen , mOwnPrivateKey ) )
2009-04-22 19:29:16 -04: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 18:38:24 -04:00
rs_sprintf_append ( sign , " %02x " , ( uint32_t ) ( signature [ i ] ) ) ;
2009-04-22 19:29:16 -04:00
}
return true ;
}
2010-07-04 06:35:38 -04:00
bool AuthSSLimpl : : SignDataBin ( std : : string input , unsigned char * sign , unsigned int * signlen )
2009-04-22 19:29:16 -04:00
{
return SignDataBin ( input . c_str ( ) , input . length ( ) , sign , signlen ) ;
}
2010-07-04 06:35:38 -04:00
bool AuthSSLimpl : : SignDataBin ( const void * data , const uint32_t len ,
2009-04-22 19:29:16 -04:00
unsigned char * sign , unsigned int * signlen )
{
RsStackMutex stack ( sslMtx ) ; /***** STACK LOCK MUTEX *****/
2010-06-26 08:31:24 -04:00
return SSL_SignDataBin ( data , len , sign , signlen , mOwnPrivateKey ) ;
}
2009-04-22 19:29:16 -04:00
2010-07-04 06:35:38 -04:00
bool AuthSSLimpl : : VerifySignBin ( const void * data , const uint32_t len ,
2014-03-17 16:56:06 -04:00
unsigned char * sign , unsigned int signlen , const RsPeerId & sslId )
2010-06-26 08:31:24 -04:00
{
/* find certificate.
* if we don ' t have - fail .
*/
2009-04-22 19:29:16 -04:00
2010-06-26 08:31:24 -04:00
RsStackMutex stack ( sslMtx ) ; /***** STACK LOCK MUTEX *****/
/* find the peer */
sslcert * peer ;
if ( sslId = = mOwnId )
{
peer = mOwnCert ;
2009-04-22 19:29:16 -04:00
}
2010-06-26 08:31:24 -04:00
else if ( ! locked_FindCert ( sslId , & peer ) )
2009-04-22 19:29:16 -04:00
{
2010-06-26 08:31:24 -04:00
std : : cerr < < " VerifySignBin() no peer " < < std : : endl ;
2009-04-22 19:29:16 -04:00
return false ;
}
2010-06-26 08:31:24 -04:00
return SSL_VerifySignBin ( data , len , sign , signlen , peer - > certificate ) ;
}
2010-02-03 16:21:04 -05:00
2010-07-04 06:35:38 -04:00
bool AuthSSLimpl : : VerifyOwnSignBin ( const void * data , const uint32_t len ,
2010-06-26 08:31:24 -04:00
unsigned char * sign , unsigned int signlen )
2009-04-22 19:29:16 -04:00
{
2010-06-26 08:31:24 -04:00
return SSL_VerifySignBin ( data , len , sign , signlen , mOwnCert - > certificate ) ;
2009-04-22 19:29:16 -04:00
}
2010-06-26 08:31:24 -04:00
/********************************************************************************/
/********************************************************************************/
/********************* Sign and Auth with GPG **************************/
/********************************************************************************/
/********************************************************************************/
2009-04-22 19:29:16 -04:00
2010-06-26 08:31:24 -04:00
/* Note these functions don't need Mutexes -
* only using GPG functions - which lock themselves
*/
2009-04-22 19:29:16 -04:00
2015-06-15 18:41:18 -04:00
X509 * AuthSSLimpl : : SignX509ReqWithGPG ( X509_REQ * req , long /*days*/ )
2010-01-13 15:52:31 -05: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 08:31:24 -04:00
//const EVP_MD *digest = EVP_sha1();
2010-01-13 15:52:31 -05:00
ASN1_INTEGER * serial = ASN1_INTEGER_new ( ) ;
EVP_PKEY * tmppkey ;
X509 * x509 = X509_new ( ) ;
if ( x509 = = NULL )
{
2010-07-04 06:35:38 -04:00
std : : cerr < < " AuthSSLimpl::SignX509Req() FAIL " < < std : : endl ;
2010-01-13 15:52:31 -05:00
return NULL ;
}
2010-06-26 08:31:24 -04:00
//long version = 0x00;
2014-12-03 18:03:03 -05:00
unsigned long chtype = MBSTRING_UTF8 ;
2010-01-13 15:52:31 -05:00
X509_NAME * issuer_name = X509_NAME_new ( ) ;
X509_NAME_add_entry_by_txt ( issuer_name , " CN " , chtype ,
2014-03-17 16:56:06 -04:00
( unsigned char * ) AuthGPG : : getAuthGPG ( ) - > getGPGOwnId ( ) . toStdString ( ) . c_str ( ) , - 1 , - 1 , 0 ) ;
2010-01-13 15:52:31 -05: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 16:56:06 -04:00
std : : cerr < < " AuthSSLimpl::SignX509Req() Issuer name: " < < AuthGPG : : getAuthGPG ( ) - > getGPGOwnId ( ) . toStdString ( ) < < std : : endl ;
2010-01-13 15:52:31 -05:00
BIGNUM * btmp = BN_new ( ) ;
if ( ! BN_pseudo_rand ( btmp , SERIAL_RAND_BITS , 0 , 0 ) )
{
2010-07-04 06:35:38 -04:00
std : : cerr < < " AuthSSLimpl::SignX509Req() rand FAIL " < < std : : endl ;
2010-01-13 15:52:31 -05:00
return NULL ;
}
if ( ! BN_to_ASN1_INTEGER ( btmp , serial ) )
{
2010-07-04 06:35:38 -04:00
std : : cerr < < " AuthSSLimpl::SignX509Req() asn1 FAIL " < < std : : endl ;
2010-01-13 15:52:31 -05:00
return NULL ;
}
BN_free ( btmp ) ;
if ( ! X509_set_serialNumber ( x509 , serial ) )
{
2010-07-04 06:35:38 -04:00
std : : cerr < < " AuthSSLimpl::SignX509Req() serial FAIL " < < std : : endl ;
2010-01-13 15:52:31 -05: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 06:35:38 -04:00
std : : cerr < < " AuthSSLimpl::SignX509Req() issue FAIL " < < std : : endl ;
2010-01-13 15:52:31 -05:00
return NULL ;
}
X509_NAME_free ( issuer_name ) ;
2015-03-25 04:19:45 -04: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 15:52:31 -05:00
2015-03-25 04:19:45 -04:00
// OLD code, sets validity time of cert to be between now and some days in the future
/*
2010-01-13 15:52:31 -05:00
if ( ! X509_gmtime_adj ( X509_get_notBefore ( x509 ) , 0 ) )
{
2010-07-04 06:35:38 -04:00
std : : cerr < < " AuthSSLimpl::SignX509Req() notbefore FAIL " < < std : : endl ;
2010-01-13 15:52:31 -05:00
return NULL ;
}
if ( ! X509_gmtime_adj ( X509_get_notAfter ( x509 ) , ( long ) 60 * 60 * 24 * days ) )
{
2010-07-04 06:35:38 -04:00
std : : cerr < < " AuthSSLimpl::SignX509Req() notafter FAIL " < < std : : endl ;
2010-01-13 15:52:31 -05:00
return NULL ;
}
2015-03-25 04:19:45 -04:00
*/
2010-01-13 15:52:31 -05:00
if ( ! X509_set_subject_name ( x509 , X509_REQ_get_subject_name ( req ) ) )
{
2010-07-04 06:35:38 -04:00
std : : cerr < < " AuthSSLimpl::SignX509Req() sub FAIL " < < std : : endl ;
2010-01-13 15:52:31 -05:00
return NULL ;
}
tmppkey = X509_REQ_get_pubkey ( req ) ;
if ( ! tmppkey | | ! X509_set_pubkey ( x509 , tmppkey ) )
{
2010-07-04 06:35:38 -04:00
std : : cerr < < " AuthSSLimpl::SignX509Req() pub FAIL " < < std : : endl ;
2010-01-13 15:52:31 -05: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 16:38:02 -05: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.
# if OPENSSL_VERSION_NUMBER < 0x10100000L
2017-02-25 17:16:43 -05:00
int ( * i2d ) ( X509_CINF * , unsigned char * * ) = i2d_X509_CINF ;
2010-01-13 15:52:31 -05: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 16:38:02 -05: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 08:31:24 -04:00
//EVP_PKEY *pkey = NULL;
2010-01-13 15:52:31 -05:00
const EVP_MD * type = EVP_sha1 ( ) ;
2017-02-20 16:54:25 -05:00
EVP_MD_CTX * ctx = EVP_MD_CTX_create ( ) ;
2017-05-08 05:55:23 -04:00
unsigned char * buf_in = NULL ;
2010-01-13 15:52:31 -05:00
unsigned char * buf_hashout = NULL , * buf_sigout = NULL ;
2013-07-18 18:10:30 -04:00
int inl = 0 , hashoutl = 0 ;
int sigoutl = 0 ;
2010-01-13 15:52:31 -05:00
X509_ALGOR * a ;
/* FIX ALGORITHMS */
2017-02-19 16:38:02 -05:00
a = const_cast < X509_ALGOR * > ( algor1 ) ;
# if OPENSSL_VERSION_NUMBER < 0x10100000L
2010-01-13 15:52:31 -05: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 16:38:02 -05:00
# else
X509_ALGOR_set0 ( a , OBJ_nid2obj ( EVP_MD_pkey_type ( type ) ) , V_ASN1_NULL , NULL ) ;
# endif
2010-01-13 15:52:31 -05:00
2017-02-19 16:38:02 -05:00
a = const_cast < X509_ALGOR * > ( algor2 ) ;
# if OPENSSL_VERSION_NUMBER < 0x10100000L
2010-01-13 15:52:31 -05: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 16:38:02 -05: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 15:52:31 -05:00
std : : cerr < < " Algorithms Fixed " < < std : : endl ;
/* input buffer */
2017-02-19 16:38:02 -05:00
# if OPENSSL_VERSION_NUMBER < 0x10100000L
2010-01-13 15:52:31 -05:00
inl = i2d ( data , NULL ) ;
buf_in = ( unsigned char * ) OPENSSL_malloc ( ( unsigned int ) inl ) ;
2017-02-19 16:38:02 -05:00
# else
inl = i2d_re_X509_tbs ( x509 , & buf_in ) ; // this does the i2d over x509->cert_info
# endif
2010-01-13 15:52:31 -05:00
2013-07-18 18:10:30 -04:00
hashoutl = EVP_MD_size ( type ) ;
2010-01-13 15:52:31 -05:00
buf_hashout = ( unsigned char * ) OPENSSL_malloc ( ( unsigned int ) hashoutl ) ;
2013-07-18 18:10:30 -04:00
sigoutl = 2048 ; // hashoutl; //EVP_PKEY_size(pkey);
2010-01-13 15:52:31 -05:00
buf_sigout = ( unsigned char * ) OPENSSL_malloc ( ( unsigned int ) sigoutl ) ;
if ( ( buf_in = = NULL ) | | ( buf_hashout = = NULL ) | | ( buf_sigout = = NULL ) )
{
hashoutl = 0 ;
sigoutl = 0 ;
2010-07-04 06:35:38 -04:00
fprintf ( stderr , " AuthSSLimpl::SignX509Req: ASN1err(ASN1_F_ASN1_SIGN,ERR_R_MALLOC_FAILURE) \n " ) ;
2010-01-13 15:52:31 -05:00
goto err ;
}
std : : cerr < < " Buffers Allocated " < < std : : endl ;
2017-02-19 16:38:02 -05:00
# if OPENSSL_VERSION_NUMBER < 0x10100000L
2017-05-08 05:55:23 -04:00
unsigned char * p = buf_in ;
2010-01-13 15:52:31 -05:00
i2d ( data , & p ) ;
2017-02-19 16:38:02 -05:00
# endif
2010-01-13 15:52:31 -05:00
/* data in buf_in, ready to be hashed */
2017-02-19 16:38:02 -05:00
EVP_DigestInit_ex ( ctx , type , NULL ) ;
EVP_DigestUpdate ( ctx , ( unsigned char * ) buf_in , inl ) ;
if ( ! EVP_DigestFinal ( ctx , ( unsigned char * ) buf_hashout ,
2010-01-13 15:52:31 -05:00
( unsigned int * ) & hashoutl ) )
{
hashoutl = 0 ;
2010-07-04 06:35:38 -04:00
fprintf ( stderr , " AuthSSLimpl::SignX509Req: ASN1err(ASN1_F_ASN1_SIGN,ERR_R_EVP_LIB) \n " ) ;
2010-01-13 15:52:31 -05:00
goto err ;
}
std : : cerr < < " Digest Applied: len: " < < hashoutl < < std : : endl ;
/* NOW Sign via GPG Functions */
2016-08-08 19:22:14 -04:00
if ( ! AuthGPG : : getAuthGPG ( ) - > SignDataBin ( buf_hashout , hashoutl , buf_sigout , ( unsigned int * ) & sigoutl , " AuthSSLimpl::SignX509ReqWithGPG() " ) )
2010-01-13 15:52:31 -05:00
{
sigoutl = 0 ;
goto err ;
}
std : : cerr < < " Buffer Sizes: in: " < < inl ;
std : : cerr < < " HashOut: " < < hashoutl ;
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 16:54:25 -05:00
EVP_MD_CTX_destroy ( ctx ) ;
2017-02-19 16:38:02 -05:00
2010-01-13 15:52:31 -05:00
return x509 ;
2010-06-26 08:31:24 -04:00
/* XXX CLEANUP */
2010-01-13 15:52:31 -05:00
err :
/* cleanup */
2013-07-18 18:10:30 -04:00
if ( buf_in ! = NULL )
OPENSSL_free ( buf_in ) ;
if ( buf_hashout ! = NULL )
OPENSSL_free ( buf_hashout ) ;
if ( buf_sigout ! = NULL )
OPENSSL_free ( buf_sigout ) ;
2010-01-13 15:52:31 -05:00
std : : cerr < < " GPGAuthMgr::SignX509Req() err: FAIL " < < std : : endl ;
return NULL ;
}
2010-06-26 08:31:24 -04: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 15:19:17 -05:00
bool AuthSSLimpl : : AuthX509WithGPG ( X509 * x509 , uint32_t & diagnostic )
2010-06-26 08:31:24 -04:00
{
2014-01-15 15:19:17 -05:00
# ifdef AUTHSSL_DEBUG
fprintf ( stderr , " AuthSSLimpl::AuthX509WithGPG() called \n " ) ;
# endif
2010-01-13 16:16:56 -05:00
2014-01-15 15:19:17 -05:00
if ( ! CheckX509Certificate ( x509 ) )
2010-06-26 08:31:24 -04:00
{
2014-01-15 15:19:17 -05: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 15:52:31 -05:00
2014-01-15 15:19:17 -05:00
/* extract CN for peer Id */
2017-02-19 16:38:02 -05:00
# if OPENSSL_VERSION_NUMBER < 0x10100000L
2014-03-17 16:56:06 -04:00
RsPgpId issuer ( std : : string ( getX509CNString ( x509 - > cert_info - > issuer ) ) ) ;
2017-02-19 16:38:02 -05:00
# else
RsPgpId issuer ( std : : string ( getX509CNString ( X509_get_issuer_name ( x509 ) ) ) ) ;
# endif
2014-01-15 15:19:17 -05:00
RsPeerDetails pd ;
# ifdef AUTHSSL_DEBUG
2014-03-17 16:56:06 -04:00
std : : cerr < < " Checking GPG issuer : " < < issuer . toStdString ( ) < < std : : endl ;
2014-01-15 15:19:17 -05: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 15:52:31 -05:00
2014-01-15 15:19:17 -05:00
/* verify GPG signature */
2010-01-13 15:52:31 -05:00
2014-01-15 15:19:17 -05:00
/*** NOW The Manual signing bit (HACKED FROM asn1/a_sign.c) ***/
int ( * i2d ) ( X509_CINF * , unsigned char * * ) = i2d_X509_CINF ;
2017-02-19 16:38:02 -05:00
# if OPENSSL_VERSION_NUMBER < 0x10100000L
2014-01-15 15:19:17 -05:00
ASN1_BIT_STRING * signature = x509 - > signature ;
X509_CINF * data = x509 - > cert_info ;
2017-02-19 16:38:02 -05:00
# else
const ASN1_BIT_STRING * signature = NULL ;
const X509_ALGOR * algor2 = NULL ;
X509_get0_signature ( & signature , & algor2 , x509 ) ;
# endif
2014-01-15 15:19:17 -05:00
const EVP_MD * type = EVP_sha1 ( ) ;
2010-01-13 15:52:31 -05:00
2017-02-20 16:54:25 -05:00
EVP_MD_CTX * ctx = EVP_MD_CTX_create ( ) ;
2014-01-15 15:19:17 -05:00
unsigned char * p , * buf_in = NULL ;
unsigned char * buf_hashout = NULL , * buf_sigout = NULL ;
int inl = 0 , hashoutl = 0 ;
int sigoutl = 0 ;
2010-01-13 15:52:31 -05:00
2014-01-15 15:19:17 -05:00
/* input buffer */
2017-02-19 16:38:02 -05:00
# if OPENSSL_VERSION_NUMBER < 0x10100000L
2014-01-15 15:19:17 -05:00
inl = i2d ( data , NULL ) ;
buf_in = ( unsigned char * ) OPENSSL_malloc ( ( unsigned int ) inl ) ;
2017-02-19 16:38:02 -05:00
# else
inl = i2d_re_X509_tbs ( x509 , & buf_in ) ; // this does the i2d over x509->cert_info
# endif
2010-01-13 15:52:31 -05:00
2014-01-15 15:19:17 -05:00
hashoutl = EVP_MD_size ( type ) ;
buf_hashout = ( unsigned char * ) OPENSSL_malloc ( ( unsigned int ) hashoutl ) ;
2010-01-13 15:52:31 -05:00
2014-01-15 15:19:17 -05:00
sigoutl = 2048 ; //hashoutl; //EVP_PKEY_size(pkey);
buf_sigout = ( unsigned char * ) OPENSSL_malloc ( ( unsigned int ) sigoutl ) ;
2010-01-13 15:52:31 -05:00
2014-01-15 15:19:17 -05:00
# ifdef AUTHSSL_DEBUG
std : : cerr < < " Buffer Sizes: in: " < < inl ;
std : : cerr < < " HashOut: " < < hashoutl ;
std : : cerr < < " SigOut: " < < sigoutl ;
std : : cerr < < std : : endl ;
# endif
2010-01-13 15:52:31 -05:00
2014-01-15 15:19:17 -05:00
if ( ( buf_in = = NULL ) | | ( buf_hashout = = NULL ) | | ( buf_sigout = = NULL ) ) {
hashoutl = 0 ;
sigoutl = 0 ;
fprintf ( stderr , " AuthSSLimpl::AuthX509: ASN1err(ASN1_F_ASN1_SIGN,ERR_R_MALLOC_FAILURE) \n " ) ;
diagnostic = RS_SSL_HANDSHAKE_DIAGNOSTIC_MALLOC_ERROR ;
goto err ;
}
p = buf_in ;
2010-01-13 15:52:31 -05:00
2014-01-15 15:19:17 -05:00
# ifdef AUTHSSL_DEBUG
std : : cerr < < " Buffers Allocated " < < std : : endl ;
# endif
2009-04-22 19:29:16 -04:00
2017-02-19 16:38:02 -05:00
# if OPENSSL_VERSION_NUMBER < 0x10100000L
2014-01-15 15:19:17 -05:00
i2d ( data , & p ) ;
2017-02-19 16:38:02 -05:00
# endif
2014-01-15 15:19:17 -05:00
/* data in buf_in, ready to be hashed */
2017-02-19 16:38:02 -05:00
EVP_DigestInit_ex ( ctx , type , NULL ) ;
EVP_DigestUpdate ( ctx , ( unsigned char * ) buf_in , inl ) ;
if ( ! EVP_DigestFinal ( ctx , ( unsigned char * ) buf_hashout ,
2014-01-15 15:19:17 -05:00
( unsigned int * ) & hashoutl ) )
{
hashoutl = 0 ;
fprintf ( stderr , " AuthSSLimpl::AuthX509: ASN1err(ASN1_F_ASN1_SIGN,ERR_R_EVP_LIB) \n " ) ;
diagnostic = RS_SSL_HANDSHAKE_DIAGNOSTIC_MALLOC_ERROR ;
goto err ;
}
2009-04-22 19:29:16 -04:00
2014-01-15 15:19:17 -05:00
# ifdef AUTHSSL_DEBUG
std : : cerr < < " Digest Applied: len: " < < hashoutl < < std : : endl ;
# endif
2010-01-13 15:52:31 -05:00
2014-01-15 15:19:17 -05:00
/* copy data into signature */
2016-05-17 10:39:56 -04:00
if ( sigoutl < signature - > length )
{
diagnostic = RS_SSL_HANDSHAKE_DIAGNOSTIC_MALLOC_ERROR ;
goto err ;
}
2014-01-15 15:19:17 -05:00
sigoutl = signature - > length ;
memmove ( buf_sigout , signature - > data , sigoutl ) ;
2010-01-13 15:52:31 -05:00
2014-01-15 15:19:17 -05:00
/* NOW check sign via GPG Functions */
//get the fingerprint of the key that is supposed to sign
# ifdef AUTHSSL_DEBUG
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 ;
std : : cerr < < " hashoutl = " < < hashoutl < < std : : endl ;
# endif
2010-01-24 08:59:22 -05:00
2014-01-15 15:19:17 -05:00
if ( ! AuthGPG : : getAuthGPG ( ) - > VerifySignBin ( buf_hashout , hashoutl , buf_sigout , ( unsigned int ) sigoutl , pd . fpr ) ) {
sigoutl = 0 ;
diagnostic = RS_SSL_HANDSHAKE_DIAGNOSTIC_WRONG_SIGNATURE ;
goto err ;
}
2010-01-13 16:16:18 -05:00
2014-01-15 15:19:17 -05:00
# ifdef AUTHSSL_DEBUG
std : : cerr < < " AuthSSLimpl::AuthX509() X509 authenticated " < < std : : endl ;
# endif
2017-02-20 16:54:25 -05:00
EVP_MD_CTX_destroy ( ctx ) ;
2010-02-25 17:42:42 -05:00
2014-01-15 15:19:17 -05:00
OPENSSL_free ( buf_in ) ;
OPENSSL_free ( buf_hashout ) ;
OPENSSL_free ( buf_sigout ) ;
2013-07-18 18:10:30 -04:00
2014-01-15 15:19:17 -05:00
diagnostic = RS_SSL_HANDSHAKE_DIAGNOSTIC_OK ;
2010-01-13 15:52:31 -05:00
2014-01-15 15:19:17 -05:00
return true ;
2011-01-01 15:37:10 -05:00
2014-01-15 15:19:17 -05:00
err :
std : : cerr < < " AuthSSLimpl::AuthX509() X509 NOT authenticated " < < std : : endl ;
if ( buf_in ! = NULL )
OPENSSL_free ( buf_in ) ;
if ( buf_hashout ! = NULL )
OPENSSL_free ( buf_hashout ) ;
if ( buf_sigout ! = NULL )
OPENSSL_free ( buf_sigout ) ;
return false ;
2010-01-13 15:52:31 -05:00
}
2010-06-26 08:31:24 -04:00
2009-04-22 19:29:16 -04:00
/* validate + get id */
2014-03-17 16:56:06 -04:00
bool AuthSSLimpl : : ValidateCertificate ( X509 * x509 , RsPeerId & peerId )
2009-04-22 19:29:16 -04:00
{
2014-01-15 15:19:17 -05:00
uint32_t auth_diagnostic ;
2009-04-22 19:29:16 -04:00
/* check self signed */
2014-01-15 15:19:17 -05:00
if ( ! AuthX509WithGPG ( x509 , auth_diagnostic ) )
2010-01-24 08:59:22 -05:00
{
2010-01-13 16:16:18 -05:00
# ifdef AUTHSSL_DEBUG
2010-07-04 06:35:38 -04:00
std : : cerr < < " AuthSSLimpl::ValidateCertificate() bad certificate. " ;
2010-01-24 08:59:22 -05:00
std : : cerr < < std : : endl ;
2009-05-23 11:07:35 -04:00
# endif
2010-01-24 08:59:22 -05:00
return false ;
}
2014-03-17 16:56:06 -04:00
RsPeerId peerIdstr ;
if ( ! getX509id ( x509 , peerIdstr ) )
2010-01-24 08:59:22 -05:00
{
# ifdef AUTHSSL_DEBUG
2010-07-04 06:35:38 -04:00
std : : cerr < < " AuthSSLimpl::ValidateCertificate() Cannot retrieve peer id from certificate.. " ;
2010-01-24 08:59:22 -05:00
std : : cerr < < std : : endl ;
# endif
return false ;
2010-01-13 16:16:18 -05:00
}
2014-03-17 16:56:06 -04:00
peerId = peerIdstr ;
2009-05-23 11:07:35 -04:00
# ifdef AUTHSSL_DEBUG
2010-07-04 06:35:38 -04:00
std : : cerr < < " AuthSSLimpl::ValidateCertificate() good certificate. " ;
2009-05-23 11:07:35 -04:00
std : : cerr < < std : : endl ;
# endif
2009-04-22 19:29:16 -04:00
2010-01-24 08:59:22 -05:00
return true ;
2009-04-22 19:29:16 -04:00
}
2010-06-26 08:31:24 -04:00
/********************************************************************************/
/********************************************************************************/
/**************************** encrypt / decrypt fns ****************************/
/********************************************************************************/
/********************************************************************************/
static int verify_x509_callback ( int preverify_ok , X509_STORE_CTX * ctx )
2010-06-25 17:50:46 -04:00
{
2010-06-26 08:31:24 -04:00
# ifdef AUTHSSL_DEBUG
2012-09-09 16:25:39 -04:00
std : : cerr < < " static verify_x509_callback called. " ;
std : : cerr < < std : : endl ;
2010-06-26 08:31:24 -04:00
# endif
2012-09-09 16:25:39 -04:00
int verify = AuthSSL : : getAuthSSL ( ) - > VerifyX509Callback ( preverify_ok , ctx ) ;
X509 * x509 = X509_STORE_CTX_get_current_cert ( ctx ) ;
if ( x509 ! = NULL )
2011-07-10 20:55:06 -04:00
{
2017-02-19 16:38:02 -05:00
# if OPENSSL_VERSION_NUMBER < 0x10100000L
2014-03-17 16:56:06 -04:00
RsPgpId gpgid ( std : : string ( getX509CNString ( x509 - > cert_info - > issuer ) ) ) ;
2017-02-19 16:38:02 -05:00
# else
RsPgpId gpgid ( std : : string ( getX509CNString ( X509_get_issuer_name ( x509 ) ) ) ) ;
# endif
2014-03-17 16:56:06 -04:00
if ( gpgid . isNull ( ) )
{
2017-02-19 16:38:02 -05:00
# if OPENSSL_VERSION_NUMBER < 0x10100000L
2014-03-17 16:56:06 -04:00
std : : cerr < < " verify_x509_callback(): wrong PGP id \" " < < std : : string ( getX509CNString ( x509 - > cert_info - > issuer ) ) < < " \" " < < std : : endl ;
2017-02-19 16:38:02 -05:00
# else
std : : cerr < < " verify_x509_callback(): wrong PGP id \" " < < std : : string ( getX509CNString ( X509_get_issuer_name ( x509 ) ) ) < < " \" " < < std : : endl ;
# endif
2014-03-17 16:56:06 -04:00
return false ;
}
2017-02-19 16:38:02 -05:00
# if OPENSSL_VERSION_NUMBER < 0x10100000L
2012-09-09 16:25:39 -04:00
std : : string sslcn = getX509CNString ( x509 - > cert_info - > subject ) ;
2017-02-19 16:38:02 -05:00
# else
std : : string sslcn = getX509CNString ( X509_get_subject_name ( x509 ) ) ;
# endif
2014-03-17 16:56:06 -04:00
RsPeerId sslid ;
2012-09-09 16:25:39 -04:00
getX509id ( x509 , sslid ) ;
2014-03-17 16:56:06 -04:00
if ( sslid . isNull ( ) )
{
2017-02-19 16:38:02 -05:00
std : : cerr < < " verify_x509_callback(): wrong PGP id \" " < < sslcn < < " \" " < < std : : endl ;
2014-03-17 16:56:06 -04:00
return false ;
}
2012-09-14 17:04:16 -04:00
AuthSSL : : getAuthSSL ( ) - > setCurrentConnectionAttemptInfo ( gpgid , sslid , sslcn ) ;
2012-09-09 16:25:39 -04:00
}
2010-06-26 08:31:24 -04:00
2012-09-09 16:25:39 -04:00
return verify ;
2010-06-25 17:50:46 -04:00
}
2010-07-04 06:35:38 -04:00
int AuthSSLimpl : : VerifyX509Callback ( int preverify_ok , X509_STORE_CTX * ctx )
2010-06-25 17:50:46 -04:00
{
2015-01-23 03:13:26 -05:00
char buf [ 256 ] ;
X509 * err_cert ;
err_cert = X509_STORE_CTX_get_current_cert ( ctx ) ;
2015-01-23 14:17:33 -05:00
# ifdef AUTHSSL_DEBUG
2015-06-15 18:41:18 -04:00
int err , depth ;
2015-01-23 03:13:26 -05:00
err = X509_STORE_CTX_get_error ( ctx ) ;
depth = X509_STORE_CTX_get_error_depth ( ctx ) ;
2015-01-23 14:17:33 -05:00
# endif
2015-01-23 03:13:26 -05: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 08:31:24 -04:00
2015-01-23 03:13:26 -05: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 08:31:24 -04:00
2015-01-23 03:13:26 -05:00
X509_NAME_oneline ( X509_get_subject_name ( err_cert ) , buf , 256 ) ;
2010-06-26 08:31:24 -04:00
2015-01-23 03:13:26 -05:00
# ifdef AUTHSSL_DEBUG
std : : cerr < < " AuthSSLimpl::VerifyX509Callback: depth: " < < depth < < " : " < < buf < < std : : endl ;
# endif
2010-06-26 08:31:24 -04:00
2015-01-23 03:13:26 -05: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 08:31:24 -04:00
2015-01-23 03:13:26 -05:00
if ( ! preverify_ok )
{
2010-06-26 08:31:24 -04:00
2015-01-23 03:13:26 -05: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 08:31:24 -04:00
2015-01-23 03:13:26 -05:00
# ifdef AUTHSSL_DEBUG
fprintf ( stderr , " Doing REAL PGP Certificates \n " ) ;
# endif
uint32_t auth_diagnostic ;
2010-06-26 08:31:24 -04:00
2015-01-23 03:13:26 -05:00
/* do the REAL Authentication */
if ( ! AuthX509WithGPG ( X509_STORE_CTX_get_current_cert ( ctx ) , auth_diagnostic ) )
2010-06-26 08:31:24 -04:00
{
2015-01-23 03:13:26 -05: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-02-19 16:38:02 -05:00
# if OPENSSL_VERSION_NUMBER < 0x10100000L
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 08:31:24 -04:00
2015-01-23 03:13:26 -05: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 08:31:24 -04:00
}
2015-01-23 03:13:26 -05: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 08:31:24 -04:00
2015-01-23 03:13:26 -05:00
if ( preverify_ok ) {
2010-06-26 08:31:24 -04:00
2015-01-23 03:13:26 -05:00
//sslcert *cert = NULL;
RsPeerId certId ;
getX509id ( X509_STORE_CTX_get_current_cert ( ctx ) , certId ) ;
2010-06-26 08:31:24 -04:00
2015-01-23 03:13:26 -05: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 08:31:24 -04:00
2015-01-23 03:13:26 -05:00
return preverify_ok ;
2010-06-25 17:50:46 -04:00
}
2009-04-22 19:29:16 -04:00
2010-06-26 08:31:24 -04:00
/********************************************************************************/
/********************************************************************************/
/**************************** encrypt / decrypt fns ****************************/
/********************************************************************************/
/********************************************************************************/
2014-03-17 16:56:06 -04:00
bool AuthSSLimpl : : encrypt ( void * & out , int & outlen , const void * in , int inlen , const RsPeerId & peerId )
2009-12-13 16:59:26 -05:00
{
2010-06-26 08:31:24 -04:00
RsStackMutex stack ( sslMtx ) ; /******* LOCKED ******/
2009-12-13 16:59:26 -05:00
# ifdef AUTHSSL_DEBUG
2010-07-04 06:35:38 -04:00
std : : cerr < < " AuthSSLimpl::encrypt() called for peerId : " < < peerId < < " with inlen : " < < inlen < < std : : endl ;
2009-12-13 16:59:26 -05:00
# endif
//TODO : use ssl to crypt the binary input buffer
2010-02-25 17:42:42 -05:00
// out = malloc(inlen);
// memcpy(out, in, inlen);
// outlen = inlen;
EVP_PKEY * public_key ;
if ( peerId = = mOwnId ) {
2010-06-26 08:31:24 -04:00
public_key = mOwnPublicKey ;
2010-02-25 17:42:42 -05:00
} else {
if ( ! mCerts [ peerId ] ) {
# ifdef AUTHSSL_DEBUG
2010-07-04 06:35:38 -04:00
std : : cerr < < " AuthSSLimpl::encrypt() public key not found. " < < std : : endl ;
2010-02-25 17:42:42 -05:00
# endif
return false ;
} else {
2017-02-19 16:38:02 -05:00
# if OPENSSL_VERSION_NUMBER < 0x10100000L
2010-02-25 17:42:42 -05:00
public_key = mCerts [ peerId ] - > certificate - > cert_info - > key - > pkey ;
2017-02-19 16:38:02 -05:00
# else
public_key = X509_get0_pubkey ( mCerts [ peerId ] - > certificate ) ;
# endif
2010-02-25 17:42:42 -05:00
}
}
2017-02-19 16:38:02 -05:00
EVP_CIPHER_CTX * ctx = EVP_CIPHER_CTX_new ( ) ;
2010-07-14 17:27:26 -04:00
int eklen , net_ekl ;
unsigned char * ek ;
unsigned char iv [ EVP_MAX_IV_LENGTH ] ;
int out_currOffset = 0 ;
2010-02-25 17:42:42 -05:00
int out_offset = 0 ;
2010-07-14 17:27:26 -04: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 17:27:26 -04: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 17:42:42 -05:00
2010-07-14 17:27:26 -04:00
int max_outlen = inlen + cipher_block_size + EVP_MAX_IV_LENGTH + max_evp_key_size + size_net_ekl ;
2010-02-25 17:42:42 -05:00
2010-07-14 17:27:26 -04:00
// intialize context and send store encrypted cipher in ek
2017-02-19 16:38:02 -05:00
if ( ! EVP_SealInit ( ctx , EVP_aes_128_cbc ( ) , & ek , & eklen , iv , & public_key , 1 ) ) {
2010-10-23 10:03:35 -04:00
free ( ek ) ;
return false ;
}
2010-01-24 08:59:22 -05:00
2010-07-14 17:27:26 -04: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 17:42:42 -05:00
2016-01-12 21:10:11 -05:00
if ( out = = NULL )
{
free ( ek ) ;
return false ;
}
2010-07-14 17:27:26 -04:00
net_ekl = htonl ( eklen ) ;
memcpy ( ( unsigned char * ) out + out_offset , & net_ekl , size_net_ekl ) ;
out_offset + = size_net_ekl ;
2010-02-25 17:42:42 -05:00
2010-07-14 17:27:26 -04:00
memcpy ( ( unsigned char * ) out + out_offset , ek , eklen ) ;
out_offset + = eklen ;
2010-02-25 17:42:42 -05:00
2010-07-14 17:27:26 -04:00
memcpy ( ( unsigned char * ) out + out_offset , iv , EVP_MAX_IV_LENGTH ) ;
out_offset + = EVP_MAX_IV_LENGTH ;
2010-02-25 17:42:42 -05:00
2010-07-14 17:27:26 -04:00
// now encrypt actual data
2017-02-19 16:38:02 -05:00
if ( ! EVP_SealUpdate ( ctx , ( unsigned char * ) out + out_offset , & out_currOffset , ( unsigned char * ) in , inlen ) ) {
2010-10-23 10:03:35 -04:00
free ( ek ) ;
2014-08-25 17:07:07 -04:00
free ( out ) ;
2010-10-23 10:03:35 -04:00
out = NULL ;
return false ;
}
2010-02-25 17:42:42 -05:00
2010-07-14 17:27:26 -04:00
// move along to partial block space
out_offset + = out_currOffset ;
2010-02-25 17:42:42 -05:00
2010-07-14 17:27:26 -04:00
// add padding
2017-02-19 16:38:02 -05:00
if ( ! EVP_SealFinal ( ctx , ( unsigned char * ) out + out_offset , & out_currOffset ) ) {
2010-10-23 10:03:35 -04:00
free ( ek ) ;
2014-08-25 17:07:07 -04:00
free ( out ) ;
2010-10-23 10:03:35 -04:00
out = NULL ;
return false ;
}
2010-02-25 17:42:42 -05:00
2010-07-14 17:27:26 -04:00
// move to end
out_offset + = out_currOffset ;
2010-02-25 17:42:42 -05:00
2010-07-14 17:27:26 -04:00
// make sure offset has not gone passed valid memory bounds
if ( out_offset > max_outlen ) return false ;
2010-02-25 17:42:42 -05:00
2010-07-14 17:27:26 -04:00
// free encrypted key data
free ( ek ) ;
2010-02-25 17:42:42 -05:00
2017-02-19 16:38:02 -05:00
EVP_CIPHER_CTX_free ( ctx ) ;
2011-05-15 08:01:23 -04:00
2010-07-14 17:27:26 -04:00
outlen = out_offset ;
2010-02-25 17:42:42 -05:00
2010-07-14 17:27:26 -04:00
# ifdef DISTRIB_DEBUG
std : : cerr < < " Authssl::encrypt() finished with outlen : " < < outlen < < std : : endl ;
# endif
2010-02-25 17:42:42 -05:00
return true ;
2009-12-13 16:59:26 -05:00
}
2010-07-04 06:35:38 -04:00
bool AuthSSLimpl : : decrypt ( void * & out , int & outlen , const void * in , int inlen )
2009-12-13 16:59:26 -05:00
{
2010-06-26 08:31:24 -04:00
RsStackMutex stack ( sslMtx ) ; /******* LOCKED ******/
2009-12-13 16:59:26 -05:00
# ifdef AUTHSSL_DEBUG
2010-07-04 06:35:38 -04:00
std : : cerr < < " AuthSSLimpl::decrypt() called with inlen : " < < inlen < < std : : endl ;
2009-12-13 16:59:26 -05:00
# endif
//TODO : use ssl to decrypt the binary input buffer
2010-02-25 17:42:42 -05:00
// out = malloc(inlen);
// memcpy(out, in, inlen);
// outlen = inlen;
2017-02-19 16:38:02 -05:00
EVP_CIPHER_CTX * ctx = EVP_CIPHER_CTX_new ( ) ;
2010-07-14 17:27:26 -04:00
int eklen = 0 , net_ekl = 0 ;
unsigned char * ek = NULL ;
unsigned char iv [ EVP_MAX_IV_LENGTH ] ;
2011-05-15 08:01:23 -04:00
int ek_mkl = EVP_PKEY_size ( mOwnPrivateKey ) ;
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 17:42:42 -05:00
2010-07-14 17:27:26 -04:00
int in_offset = 0 , out_currOffset = 0 ;
int size_net_ekl = sizeof ( net_ekl ) ;
2010-01-24 08:59:22 -05:00
2010-10-23 10:03:35 -04:00
if ( size_net_ekl > inlen ) {
free ( ek ) ;
return false ;
}
2010-09-18 15:09:11 -04:00
2010-07-14 17:27:26 -04:00
memcpy ( & net_ekl , ( unsigned char * ) in , size_net_ekl ) ;
eklen = ntohl ( net_ekl ) ;
in_offset + = size_net_ekl ;
2010-02-25 17:42:42 -05:00
2010-10-23 10:03:35 -04:00
if ( eklen > ( inlen - in_offset ) ) {
free ( ek ) ;
return false ;
}
2010-09-18 15:09:11 -04:00
2010-07-14 17:27:26 -04:00
memcpy ( ek , ( unsigned char * ) in + in_offset , eklen ) ;
in_offset + = eklen ;
2010-02-25 17:42:42 -05:00
2010-10-23 10:03:35 -04:00
if ( EVP_MAX_IV_LENGTH > ( inlen - in_offset ) ) {
free ( ek ) ;
return false ;
}
2010-09-18 15:09:11 -04:00
2010-07-14 17:27:26 -04:00
memcpy ( iv , ( unsigned char * ) in + in_offset , EVP_MAX_IV_LENGTH ) ;
in_offset + = EVP_MAX_IV_LENGTH ;
2010-02-25 17:42:42 -05:00
2010-07-14 17:27:26 -04:00
const EVP_CIPHER * cipher = EVP_aes_128_cbc ( ) ;
2010-02-25 17:42:42 -05:00
2017-02-19 16:38:02 -05:00
if ( 0 = = EVP_OpenInit ( ctx , cipher , ek , eklen , iv , mOwnPrivateKey ) ) {
2010-10-23 10:03:35 -04:00
free ( ek ) ;
return false ;
}
2010-02-25 17:42:42 -05:00
2016-01-12 21:43:04 -05:00
out = ( unsigned char * ) rs_malloc ( inlen - in_offset ) ;
2010-02-25 17:42:42 -05:00
2016-01-12 21:10:11 -05:00
if ( out = = NULL )
{
free ( ek ) ;
return false ;
}
2017-02-19 16:38:02 -05:00
if ( ! EVP_OpenUpdate ( ctx , ( unsigned char * ) out , & out_currOffset , ( unsigned char * ) in + in_offset , inlen - in_offset ) ) {
2010-10-23 10:03:35 -04:00
free ( ek ) ;
2014-08-25 17:07:07 -04:00
free ( out ) ;
2010-10-23 10:03:35 -04:00
out = NULL ;
return false ;
}
2010-02-25 17:42:42 -05:00
2010-07-14 17:27:26 -04:00
in_offset + = out_currOffset ;
outlen + = out_currOffset ;
2010-02-25 17:42:42 -05:00
2017-02-19 16:38:02 -05:00
if ( ! EVP_OpenFinal ( ctx , ( unsigned char * ) out + out_currOffset , & out_currOffset ) ) {
2010-10-23 10:03:35 -04:00
free ( ek ) ;
2014-08-25 17:07:07 -04:00
free ( out ) ;
2010-10-23 10:03:35 -04:00
out = NULL ;
return false ;
}
2010-02-25 17:42:42 -05:00
2010-07-14 17:27:26 -04:00
outlen + = out_currOffset ;
2010-02-25 17:42:42 -05:00
2010-09-18 15:09:11 -04:00
if ( ek ! = NULL )
free ( ek ) ;
2010-02-25 17:42:42 -05:00
2017-02-19 16:38:02 -05:00
EVP_CIPHER_CTX_free ( ctx ) ;
2011-05-15 08:01:23 -04:00
2014-08-25 17:07:07 -04:00
# ifdef AUTHSSL_DEBUG
std : : cerr < < " AuthSSLimpl::decrypt() finished with outlen : " < < outlen < < std : : endl ;
# endif
2010-02-25 17:42:42 -05:00
return true ;
}
2010-06-26 08:31:24 -04:00
/********************************************************************************/
/********************************************************************************/
/********************* Cert Search / Add / Remove **************************/
/********************************************************************************/
/********************************************************************************/
2014-03-17 16:56:06 -04:00
void AuthSSLimpl : : setCurrentConnectionAttemptInfo ( const RsPgpId & gpg_id , const RsPeerId & ssl_id , const std : : string & ssl_cn )
2012-09-09 16:25:39 -04:00
{
2012-09-14 17:04:16 -04:00
# ifdef AUTHSSL_DEBUG
2013-06-24 17:23:50 -04:00
std : : cerr < < " AuthSSL: registering connection attempt from: " < < std : : endl ;
2012-09-09 16:25:39 -04: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 17:04:16 -04:00
# endif
2012-09-09 16:25:39 -04:00
_last_gpgid_to_connect = gpg_id ;
_last_sslid_to_connect = ssl_id ;
_last_sslcn_to_connect = ssl_cn ;
}
2014-03-17 16:56:06 -04:00
void AuthSSLimpl : : getCurrentConnectionAttemptInfo ( RsPgpId & gpg_id , RsPeerId & ssl_id , std : : string & ssl_cn )
2012-09-14 17:04:16 -04:00
{
gpg_id = _last_gpgid_to_connect ;
ssl_id = _last_sslid_to_connect ;
ssl_cn = _last_sslcn_to_connect ;
}
2012-09-09 16:25:39 -04:00
2010-06-26 08:31:24 -04:00
/* store for discovery */
2014-03-17 16:56:06 -04:00
bool AuthSSLimpl : : FailedCertificate ( X509 * x509 , const RsPgpId & gpgid ,
const RsPeerId & sslid ,
2012-09-14 17:04:16 -04:00
const std : : string & sslcn ,
2013-09-13 10:35:19 -04:00
const struct sockaddr_storage & addr ,
2012-09-14 17:04:16 -04:00
bool incoming )
2010-06-26 08:31:24 -04:00
{
2013-09-13 10:35:19 -04:00
std : : string ip_address = sockaddr_storage_tostring ( addr ) ;
2012-09-09 16:25:39 -04:00
2014-02-01 09:16:15 -05:00
uint32_t auth_diagnostic = 0 ;
2014-01-16 14:57:08 -05:00
bool authed ;
if ( x509 = = NULL )
{
2014-01-28 16:33:17 -05:00
auth_diagnostic = RS_SSL_HANDSHAKE_DIAGNOSTIC_CERTIFICATE_MISSING ;
2014-01-16 14:57:08 -05:00
authed = false ;
}
else
authed = AuthX509WithGPG ( x509 , auth_diagnostic ) ;
2011-07-10 20:55:06 -04:00
2012-09-14 17:04:16 -04:00
if ( authed )
LocalStoreCert ( x509 ) ;
2011-07-10 20:55:06 -04:00
2012-09-17 16:49:52 -04:00
# ifdef AUTHSSL_DEBUG
2011-07-10 20:55:06 -04:00
std : : cerr < < " AuthSSLimpl::FailedCertificate() " ;
2012-09-17 16:49:52 -04:00
# endif
2011-07-10 20:55:06 -04:00
if ( incoming )
{
2014-03-17 16:56:06 -04:00
RsServer : : notify ( ) - > AddPopupMessage ( RS_POPUP_CONNECT_ATTEMPT , gpgid . toStdString ( ) , sslcn , sslid . toStdString ( ) ) ;
2014-01-15 15:19:17 -05:00
switch ( auth_diagnostic )
{
2014-03-17 16:56:06 -04:00
case RS_SSL_HANDSHAKE_DIAGNOSTIC_CERTIFICATE_MISSING : RsServer : : notify ( ) - > AddFeedItem ( RS_FEED_ITEM_SEC_MISSING_CERTIFICATE , gpgid . toStdString ( ) , sslid . toStdString ( ) , sslcn , ip_address ) ;
2014-01-28 16:33:17 -05:00
break ;
2014-03-17 16:56:06 -04:00
case RS_SSL_HANDSHAKE_DIAGNOSTIC_CERTIFICATE_NOT_VALID : RsServer : : notify ( ) - > AddFeedItem ( RS_FEED_ITEM_SEC_BAD_CERTIFICATE , gpgid . toStdString ( ) , sslid . toStdString ( ) , sslcn , ip_address ) ;
2014-01-15 15:19:17 -05:00
break ;
2014-03-17 16:56:06 -04:00
case RS_SSL_HANDSHAKE_DIAGNOSTIC_ISSUER_UNKNOWN : RsServer : : notify ( ) - > AddFeedItem ( RS_FEED_ITEM_SEC_UNKNOWN_IN , gpgid . toStdString ( ) , sslid . toStdString ( ) , sslcn , ip_address ) ;
2014-01-15 15:19:17 -05:00
break ;
2014-03-17 16:56:06 -04:00
case RS_SSL_HANDSHAKE_DIAGNOSTIC_MALLOC_ERROR : RsServer : : notify ( ) - > AddFeedItem ( RS_FEED_ITEM_SEC_INTERNAL_ERROR , gpgid . toStdString ( ) , sslid . toStdString ( ) , sslcn , ip_address ) ;
2014-01-15 15:19:17 -05:00
break ;
2014-03-17 16:56:06 -04:00
case RS_SSL_HANDSHAKE_DIAGNOSTIC_WRONG_SIGNATURE : RsServer : : notify ( ) - > AddFeedItem ( RS_FEED_ITEM_SEC_WRONG_SIGNATURE , gpgid . toStdString ( ) , sslid . toStdString ( ) , sslcn , ip_address ) ;
2014-01-15 15:19:17 -05:00
break ;
case RS_SSL_HANDSHAKE_DIAGNOSTIC_OK :
case RS_SSL_HANDSHAKE_DIAGNOSTIC_UNKNOWN :
default :
2014-03-17 16:56:06 -04:00
RsServer : : notify ( ) - > AddFeedItem ( RS_FEED_ITEM_SEC_CONNECT_ATTEMPT , gpgid . toStdString ( ) , sslid . toStdString ( ) , sslcn , ip_address ) ;
2014-01-15 15:19:17 -05:00
}
2012-09-14 17:04:16 -04:00
2012-09-17 16:49:52 -04:00
# ifdef AUTHSSL_DEBUG
2011-07-10 20:55:06 -04:00
std : : cerr < < " Incoming from: " ;
2012-09-17 16:49:52 -04:00
# endif
2011-07-10 20:55:06 -04:00
}
2012-09-14 17:04:16 -04:00
else
2011-07-10 20:55:06 -04:00
{
2012-09-14 17:04:16 -04:00
if ( authed )
2014-03-17 16:56:06 -04:00
RsServer : : notify ( ) - > AddFeedItem ( RS_FEED_ITEM_SEC_AUTH_DENIED , gpgid . toStdString ( ) , sslid . toStdString ( ) , sslcn , ip_address ) ;
2012-09-14 17:04:16 -04:00
else
2014-03-17 16:56:06 -04:00
RsServer : : notify ( ) - > AddFeedItem ( RS_FEED_ITEM_SEC_UNKNOWN_OUT , gpgid . toStdString ( ) , sslid . toStdString ( ) , sslcn , ip_address ) ;
2012-09-14 17:04:16 -04:00
2012-09-17 16:49:52 -04:00
# ifdef AUTHSSL_DEBUG
2011-07-10 20:55:06 -04:00
std : : cerr < < " Outgoing to: " ;
2012-09-17 16:49:52 -04:00
# endif
2011-07-10 20:55:06 -04:00
}
2012-09-09 16:25:39 -04:00
2012-09-17 16:49:52 -04:00
# ifdef AUTHSSL_DEBUG
2012-09-09 16:25:39 -04:00
std : : cerr < < " GpgId: " < < gpgid < < " SSLcn: " < < sslcn < < " peerId: " < < sslid < < " , ip address: " < < ip_address ;
std : : cerr < < std : : endl ;
2012-09-17 16:49:52 -04:00
# endif
2012-01-20 12:50:19 -05:00
2010-06-26 08:31:24 -04:00
return false ;
}
2014-03-17 16:56:06 -04:00
bool AuthSSLimpl : : CheckCertificate ( const RsPeerId & id , X509 * x509 )
2010-06-26 08:31:24 -04:00
{
( void ) id ; /* remove unused parameter warning */
2014-01-15 15:19:17 -05:00
uint32_t diagnos ;
2010-06-26 08:31:24 -04:00
/* if auths -> store */
2014-01-15 15:19:17 -05:00
if ( AuthX509WithGPG ( x509 , diagnos ) )
2010-06-26 08:31:24 -04:00
{
LocalStoreCert ( x509 ) ;
return true ;
}
return false ;
}
/* Locked search -> internal help function */
2014-03-17 16:56:06 -04:00
bool AuthSSLimpl : : locked_FindCert ( const RsPeerId & id , sslcert * * cert )
2010-06-26 08:31:24 -04:00
{
2014-03-17 16:56:06 -04:00
std : : map < RsPeerId , sslcert * > : : iterator it ;
2010-06-26 08:31:24 -04:00
if ( mCerts . end ( ) ! = ( it = mCerts . find ( id ) ) )
{
* cert = it - > second ;
return true ;
}
return false ;
}
/* Remove Certificate */
2014-03-17 16:56:06 -04:00
bool AuthSSLimpl : : RemoveX509 ( RsPeerId id )
2010-06-26 08:31:24 -04:00
{
2014-03-17 16:56:06 -04:00
std : : map < RsPeerId , sslcert * > : : iterator it ;
2010-06-26 08:31:24 -04: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 06:35:38 -04:00
bool AuthSSLimpl : : LocalStoreCert ( X509 * x509 )
2010-06-26 08:31:24 -04:00
{
//store the certificate in the local cert list
2014-03-17 16:56:06 -04:00
RsPeerId peerId ;
2010-06-26 08:31:24 -04:00
if ( ! getX509id ( x509 , peerId ) )
{
2010-07-04 06:35:38 -04:00
std : : cerr < < " AuthSSLimpl::LocalStoreCert() Cannot retrieve peer id from certificate. " < < std : : endl ;
2010-06-26 08:31:24 -04:00
# ifdef AUTHSSL_DEBUG
# endif
return false ;
}
2014-03-17 16:56:06 -04:00
if ( peerId . isNull ( ) )
{
std : : cerr < < " AuthSSLimpl::LocalStoreCert(): invalid peer id \" " < < peerId < < " \" " < < std : : endl ;
return false ;
}
2010-06-26 08:31:24 -04:00
RsStackMutex stack ( sslMtx ) ; /******* LOCKED ******/
if ( peerId = = mOwnId )
{
# ifdef AUTHSSL_DEBUG
2010-07-04 06:35:38 -04:00
std : : cerr < < " AuthSSLimpl::LocalStoreCert() not storing own certificate " < < std : : endl ;
2010-06-26 08:31:24 -04:00
# endif
return false ;
}
/* do a search */
2014-03-17 16:56:06 -04:00
std : : map < RsPeerId , sslcert * > : : iterator it ;
2010-06-26 08:31:24 -04: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 06:35:38 -04:00
std : : cerr < < " ERROR : AuthSSLimpl::LocalStoreCert() got two ssl certificates with identical ids -> dropping second " ;
2010-06-26 08:31:24 -04:00
std : : cerr < < std : : endl ;
return false ;
}
/* otherwise - we have it already */
return false ;
}
# ifdef AUTHSSL_DEBUG
2010-07-04 06:35:38 -04:00
std : : cerr < < " AuthSSLimpl::LocalStoreCert() storing certificate for " < < peerId < < std : : endl ;
2010-06-26 08:31:24 -04:00
# endif
mCerts [ peerId ] = new sslcert ( X509_dup ( x509 ) , peerId ) ;
/* flag for saving config */
IndicateConfigChanged ( ) ;
return true ;
}
/********************************************************************************/
/********************************************************************************/
/************************ Config Functions **********************************/
/********************************************************************************/
/********************************************************************************/
2010-07-04 06:35:38 -04:00
RsSerialiser * AuthSSLimpl : : setupSerialiser ( )
2010-02-25 17:42:42 -05:00
{
2010-07-04 06:35:38 -04:00
RsSerialiser * rss = new RsSerialiser ( ) ;
2010-02-25 17:42:42 -05:00
rss - > addSerialType ( new RsGeneralConfigSerialiser ( ) ) ;
return rss ;
}
2010-12-18 14:35:07 -05:00
bool AuthSSLimpl : : saveList ( bool & cleanup , std : : list < RsItem * > & lst )
2010-02-25 17:42:42 -05:00
{
# ifdef AUTHSSL_DEBUG
2010-07-04 06:35:38 -04:00
std : : cerr < < " AuthSSLimpl::saveList() called " < < std : : endl ;
2010-02-25 17:42:42 -05:00
# endif
RsStackMutex stack ( sslMtx ) ; /******* LOCKED ******/
cleanup = true ;
// Now save config for network digging strategies
RsConfigKeyValueSet * vitem = new RsConfigKeyValueSet ;
2014-03-17 16:56:06 -04:00
std : : map < RsPeerId , sslcert * > : : iterator mapIt ;
2014-10-24 18:07:26 -04:00
for ( mapIt = mCerts . begin ( ) ; mapIt ! = mCerts . end ( ) ; + + mapIt ) {
2010-02-25 17:42:42 -05:00
if ( mapIt - > first = = mOwnId ) {
continue ;
}
RsTlvKeyValue kv ;
2014-03-17 16:56:06 -04:00
kv . key = mapIt - > first . toStdString ( ) ;
2010-02-25 17:42:42 -05:00
# ifdef AUTHSSL_DEBUG
2010-07-04 06:35:38 -04:00
std : : cerr < < " AuthSSLimpl::saveList() called (mapIt->first) : " < < ( mapIt - > first ) < < std : : endl ;
2010-02-25 17:42:42 -05:00
# endif
2010-06-26 08:31:24 -04:00
kv . value = saveX509ToPEM ( mapIt - > second - > certificate ) ;
2010-02-25 17:42:42 -05:00
vitem - > tlvkvs . pairs . push_back ( kv ) ;
}
lst . push_back ( vitem ) ;
2010-12-18 14:35:07 -05:00
return true ;
2010-02-25 17:42:42 -05:00
}
2010-12-18 14:35:07 -05:00
bool AuthSSLimpl : : loadList ( std : : list < RsItem * > & load )
2010-02-25 17:42:42 -05:00
{
# ifdef AUTHSSL_DEBUG
2010-07-04 06:35:38 -04:00
std : : cerr < < " AuthSSLimpl::loadList() Item Count: " < < load . size ( ) < < std : : endl ;
2010-02-25 17:42:42 -05:00
# endif
/* load the list of accepted gpg keys */
std : : list < RsItem * > : : iterator it ;
2014-10-24 18:07:26 -04:00
for ( it = load . begin ( ) ; it ! = load . end ( ) ; + + it ) {
2010-02-25 17:42:42 -05:00
RsConfigKeyValueSet * vitem = dynamic_cast < RsConfigKeyValueSet * > ( * it ) ;
if ( vitem ) {
# ifdef AUTHSSL_DEBUG
2010-07-04 06:35:38 -04:00
std : : cerr < < " AuthSSLimpl::loadList() General Variable Config Item: " < < std : : endl ;
2010-02-25 17:42:42 -05:00
vitem - > print ( std : : cerr , 10 ) ;
std : : cerr < < std : : endl ;
# endif
std : : list < RsTlvKeyValue > : : iterator kit ;
2014-10-24 18:07:26 -04:00
for ( kit = vitem - > tlvkvs . pairs . begin ( ) ; kit ! = vitem - > tlvkvs . pairs . end ( ) ; + + kit ) {
2014-03-17 16:56:06 -04:00
if ( RsPeerId ( kit - > key ) = = mOwnId ) {
2010-02-25 17:42:42 -05:00
continue ;
}
2010-06-26 08:31:24 -04:00
X509 * peer = loadX509FromPEM ( kit - > value ) ;
/* authenticate it */
2014-02-01 09:16:15 -05:00
uint32_t diagnos ;
2014-01-15 15:19:17 -05:00
if ( AuthX509WithGPG ( peer , diagnos ) )
2010-06-26 08:31:24 -04:00
{
LocalStoreCert ( peer ) ;
}
2010-02-25 17:42:42 -05:00
}
}
delete ( * it ) ;
}
2015-12-30 18:20:09 -05:00
load . clear ( ) ;
2010-02-25 17:42:42 -05:00
return true ;
2009-12-13 16:59:26 -05:00
}
2009-04-22 19:29:16 -04:00
/********************************************************************************/
/********************************************************************************/
/********************************************************************************/
/********************************************************************************/
/********************************************************************************/