From 56358cbe81dd0d11267a06133ce227c2c53f10f7 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Felix=20D=C3=B6rre?= Date: Sat, 10 Jan 2015 00:25:03 +0100 Subject: [PATCH] fix: Fix memory-leak in CRL.cpp, revocation from DB, multiple CAs --- src/apps/client.cpp | 9 +++++++-- src/config.cpp | 27 ++++++++++++++++++++++----- src/crypto/CRL.cpp | 6 +++--- src/crypto/simpleOpensslSigner.cpp | 21 +++++++++++---------- src/crypto/simpleOpensslSigner.h | 2 +- src/crypto/sslUtil.cpp | 3 ++- src/crypto/sslUtil.h | 14 ++++++++++++-- src/db/database.h | 2 ++ src/db/mysql.cpp | 20 ++++++++++++++++++++ src/db/mysql.h | 1 + 10 files changed, 81 insertions(+), 24 deletions(-) diff --git a/src/apps/client.cpp b/src/apps/client.cpp index 2f0480f..1793de0 100644 --- a/src/apps/client.cpp +++ b/src/apps/client.cpp @@ -148,8 +148,13 @@ int main( int argc, const char* argv[] ) { std::cout << " [" << x.first << ']' << std::endl; } - sign->revoke( CAs.at( "unassured" ), "12345" ); - jp->finishJob( job ); + try { + auto data = jp->getRevocationInfo( job ); + sign->revoke( CAs.at( data.second ), data.first ); + jp->finishJob( job ); + } catch( const char* c ) { + std::cout << "Exception: " << c << std::endl; + } } else { log << "Unknown job type" << job->task << std::endl; jp->failJob( job ); diff --git a/src/config.cpp b/src/config.cpp index b746bad..e88ec2b 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -88,12 +88,29 @@ int parseProfiles() { prof.eku = map->at( "eku" ); prof.ku = map->at( "ku" ); - if( CAs.find( map->at( "ca" ) ) == CAs.end() ) { - std::shared_ptr ca( new CAConfig( map->at( "ca" ) ) ); - CAs.emplace( map->at( "ca" ), ca ); - } + std::string cas = map->at( "ca" ); + + for( size_t pos = 0; pos != std::string::npos; ) { + size_t end = cas.find( ",", pos ); + std::string sub; + + if( end == std::string::npos ) { + sub = cas.substr( pos ); + } else { + sub = cas.substr( pos, end - pos ); + end++; + } + + pos = end; - prof.ca = CAs.at( map->at( "ca" ) ); + if( CAs.find( sub ) == CAs.end() ) { + std::shared_ptr ca( new CAConfig( sub ) ); + CAs.emplace( sub, ca ); + } + + prof.ca.push_back( CAs.at( sub ) ); + + } profiles.emplace( profileName, prof ); std::cout << "Profile: " << profileName << " up and running." << std::endl; diff --git a/src/crypto/CRL.cpp b/src/crypto/CRL.cpp index dd32670..b7a69fe 100644 --- a/src/crypto/CRL.cpp +++ b/src/crypto/CRL.cpp @@ -118,7 +118,7 @@ void CRL::setSignature( std::string signature ) { const unsigned char* data = ( unsigned char* )( signature.data() ); const unsigned char* buffer = data; d2i_X509_ALGOR( &crl->sig_alg, &buffer, signature.size() ); - d2i_ASN1_BIT_STRING( &crl->signature, &buffer, signature.size() + buffer - data ); - d2i_ASN1_UTCTIME( &crl->crl->lastUpdate, &buffer, signature.size() + buffer - data ); - d2i_ASN1_UTCTIME( &crl->crl->nextUpdate, &buffer, signature.size() + buffer - data ); + d2i_ASN1_BIT_STRING( &crl->signature, &buffer, signature.size() + data - buffer ); + d2i_ASN1_UTCTIME( &crl->crl->lastUpdate, &buffer, signature.size() + data - buffer ); + d2i_ASN1_UTCTIME( &crl->crl->nextUpdate, &buffer, signature.size() + data - buffer ); } diff --git a/src/crypto/simpleOpensslSigner.cpp b/src/crypto/simpleOpensslSigner.cpp index b7497e6..b686820 100644 --- a/src/crypto/simpleOpensslSigner.cpp +++ b/src/crypto/simpleOpensslSigner.cpp @@ -25,9 +25,9 @@ SimpleOpensslSigner::SimpleOpensslSigner() { SimpleOpensslSigner::~SimpleOpensslSigner() { } -std::pair, std::string> SimpleOpensslSigner::nextSerial( Profile& prof ) { +std::pair, std::string> SimpleOpensslSigner::nextSerial( Profile& prof, std::shared_ptr ca ) { uint16_t profile = prof.id; - std::string res = readFile( prof.ca->path + "/serial" ); + std::string res = readFile( ca->path + "/serial" ); BIGNUM* bn = 0; @@ -64,7 +64,7 @@ std::pair, std::string> SimpleOpensslSigner::nextSerial( OPENSSL_free( ref ); } ); - writeFile( prof.ca->path + "/serial", serStr.get() ); + writeFile( ca->path + "/serial", serStr.get() ); return std::pair, std::string>( std::shared_ptr( BN_bin2bn( data.get(), len + 4 + 16 , 0 ), BN_free ), std::string( serStr.get() ) ); } @@ -75,8 +75,9 @@ std::shared_ptr SimpleOpensslSigner::sign( std::shared_ptrprofile << std::endl; Profile& prof = profiles.at( cert->profile ); + std::shared_ptr ca = prof.getCA(); - if( !prof.ca ) { + if( !ca ) { throw "CA-key not found"; } @@ -142,21 +143,21 @@ std::shared_ptr SimpleOpensslSigner::sign( std::shared_ptrca ); + c.setIssuerNameFrom( ca->ca ); c.setPubkeyFrom( req ); std::shared_ptr ser; std::string num; - std::tie( ser, num ) = nextSerial( prof ); + std::tie( ser, num ) = nextSerial( prof, ca ); c.setSerialNumber( ser.get() ); c.setTimes( 0, 60 * 60 * 24 * 10 ); signlog << "FINE: Setting extensions." << std::endl; - c.setExtensions( prof.ca->ca, cert->SANs, prof ); + c.setExtensions( ca->ca, cert->SANs, prof ); signlog << "FINE: Signed" << std::endl; - std::shared_ptr output = c.sign( prof.ca->caKey, cert->md ); + std::shared_ptr output = c.sign( ca->caKey, cert->md ); signlog << "FINE: all went well" << std::endl; - signlog << "FINE: crt went to: " << writeBackFile( num, output->certificate, prof.ca->path ) << std::endl; - output->ca_name = prof.ca->name; + signlog << "FINE: crt went to: " << writeBackFile( num, output->certificate, ca->path ) << std::endl; + output->ca_name = ca->name; output->log = signlog.str(); return output; } diff --git a/src/crypto/simpleOpensslSigner.h b/src/crypto/simpleOpensslSigner.h index 8b38655..1c848e5 100644 --- a/src/crypto/simpleOpensslSigner.h +++ b/src/crypto/simpleOpensslSigner.h @@ -10,7 +10,7 @@ class SimpleOpensslSigner : public Signer { private: static std::shared_ptr lib_ref; - std::pair, std::string> nextSerial( Profile& prof ); + std::pair, std::string> nextSerial( Profile& prof, std::shared_ptr ca ); public: SimpleOpensslSigner(); ~SimpleOpensslSigner(); diff --git a/src/crypto/sslUtil.cpp b/src/crypto/sslUtil.cpp index fd00e8f..9487e42 100644 --- a/src/crypto/sslUtil.cpp +++ b/src/crypto/sslUtil.cpp @@ -168,7 +168,6 @@ std::shared_ptr openSerial( const std::string name ) { } setupSerial( f ); - std::shared_ptr b( BIO_new_fd( fileno( f ), 0 ), BIO_free ); return b; } @@ -178,4 +177,6 @@ CAConfig::CAConfig( std::string name ) { this->path = "ca/" + name; ca = loadX509FromFile( path + "/ca.crt" ); caKey = loadPkeyFromFile( path + "/ca.key" ); + ASN1_TIME* tm = X509_get_notBefore( ca ); + notBefore = std::shared_ptr( tm, ASN1_TIME_free ); } diff --git a/src/crypto/sslUtil.h b/src/crypto/sslUtil.h index 7a68504..a85871a 100644 --- a/src/crypto/sslUtil.h +++ b/src/crypto/sslUtil.h @@ -2,6 +2,7 @@ #include #include #include +#include #include class CAConfig { @@ -11,18 +12,27 @@ public: std::shared_ptr ca; std::shared_ptr caKey; + std::shared_ptr notBefore; CAConfig( std::string name ); }; - struct Profile { uint16_t id; std::string eku; std::string ku; - std::shared_ptr ca; + std::vector> ca; + std::shared_ptr getCA() { + for( auto it = ca.rbegin(); it != ca.rend(); it++ ) { + if( X509_cmp_current_time( ( *it )->notBefore.get() ) < 0 ) { + return *it; + } + } + + return ca[0]; + } }; extern std::shared_ptr ssl_lib_ref; diff --git a/src/db/database.h b/src/db/database.h index f23f610..b67ce66 100644 --- a/src/db/database.h +++ b/src/db/database.h @@ -46,6 +46,7 @@ struct SignedCertificate { std::string certHash; std::string crt_name; std::string log; + std::string ca_name; }; class JobProvider { @@ -55,4 +56,5 @@ public: virtual void failJob( std::shared_ptr job ) = 0; virtual std::shared_ptr fetchTBSCert( std::shared_ptr job ) = 0; virtual void writeBack( std::shared_ptr job, std::shared_ptr res ) = 0; + virtual std::pair getRevocationInfo( std::shared_ptr job ) = 0; }; diff --git a/src/db/mysql.cpp b/src/db/mysql.cpp index e3fbca5..7bb93d0 100644 --- a/src/db/mysql.cpp +++ b/src/db/mysql.cpp @@ -327,3 +327,23 @@ void MySQLJobProvider::writeBack( std::shared_ptr job, std::shared_ptr MySQLJobProvider::getRevocationInfo( std::shared_ptr job ) { + std::string q = "SELECT certs.serial, cacerts.keyname FROM certs INNER JOIN cacerts ON certs.caId = cacerts.id WHERE certs.id = '" + this->escape_string( job->target ) + "' "; + int err = 0; + std::shared_ptr resu; + std::tie( err, resu ) = query( q ); + + if( err ) { + throw "Error while looking ca cert id"; + } + + MYSQL_ROW row = mysql_fetch_row( resu.get() ); + unsigned long* l = mysql_fetch_lengths( resu.get() ); + + if( !row || !l ) { + throw "Error while inserting new ca cert"; + } + + return std::pair( std::string( row[0], row[0] + l[0] ), std::string( row[1], row[1] + l[1] ) ); +} diff --git a/src/db/mysql.h b/src/db/mysql.h index b1f78ce..9096fe5 100644 --- a/src/db/mysql.h +++ b/src/db/mysql.h @@ -35,4 +35,5 @@ public: void failJob( std::shared_ptr job ); std::shared_ptr fetchTBSCert( std::shared_ptr job ); void writeBack( std::shared_ptr job, std::shared_ptr res ); + std::pair getRevocationInfo( std::shared_ptr job ); }; -- 2.39.2