]> WPIA git - cassiopeia.git/commitdiff
fix: Fix memory-leak in CRL.cpp, revocation from DB, multiple CAs
authorFelix Dörre <felix@dogcraft.de>
Fri, 9 Jan 2015 23:25:03 +0000 (00:25 +0100)
committerBenny Baumann <BenBE@geshi.org>
Sat, 24 Jan 2015 17:33:29 +0000 (18:33 +0100)
src/apps/client.cpp
src/config.cpp
src/crypto/CRL.cpp
src/crypto/simpleOpensslSigner.cpp
src/crypto/simpleOpensslSigner.h
src/crypto/sslUtil.cpp
src/crypto/sslUtil.h
src/db/database.h
src/db/mysql.cpp
src/db/mysql.h

index 2f0480f7f8a59669f019d717b48022df580ed40a..1793de0027177b6a79e84598d88e92b4a24f02fa 100644 (file)
@@ -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 );
index b746bad11a88049338853537be38250c1297bb6a..e88ec2bee52e3331a9c67ea13777964832826c41 100644 (file)
@@ -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<CAConfig> 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<CAConfig> 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;
index dd32670bcae8467bf4136c9c35187c7816dd7bdc..b7a69fe80fee40dde9f3dba19587c4860ff5c27a 100644 (file)
@@ -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 );
 }
index b7497e6107cf1ce30b53907a8c70d8cdcf4e6ab3..b6868201f87319695424bdd276ca2594885a35b8 100644 (file)
@@ -25,9 +25,9 @@ SimpleOpensslSigner::SimpleOpensslSigner() {
 SimpleOpensslSigner::~SimpleOpensslSigner() {
 }
 
-std::pair<std::shared_ptr<BIGNUM>, std::string> SimpleOpensslSigner::nextSerial( Profile& prof ) {
+std::pair<std::shared_ptr<BIGNUM>, std::string> SimpleOpensslSigner::nextSerial( Profile& prof, std::shared_ptr<CAConfig> 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::shared_ptr<BIGNUM>, std::string> SimpleOpensslSigner::nextSerial(
             OPENSSL_free( ref );
         } );
 
-    writeFile( prof.ca->path + "/serial", serStr.get() );
+    writeFile( ca->path + "/serial", serStr.get() );
 
     return std::pair<std::shared_ptr<BIGNUM>, std::string>( std::shared_ptr<BIGNUM>( BN_bin2bn( data.get(), len + 4 + 16 , 0 ), BN_free ), std::string( serStr.get() ) );
 }
@@ -75,8 +75,9 @@ std::shared_ptr<SignedCertificate> SimpleOpensslSigner::sign( std::shared_ptr<TB
     signlog << "FINE: profile is " << cert->profile << std::endl;
 
     Profile& prof = profiles.at( cert->profile );
+    std::shared_ptr<CAConfig> ca = prof.getCA();
 
-    if( !prof.ca ) {
+    if( !ca ) {
         throw "CA-key not found";
     }
 
@@ -142,21 +143,21 @@ std::shared_ptr<SignedCertificate> SimpleOpensslSigner::sign( std::shared_ptr<TB
         }
     }
 
-    c.setIssuerNameFrom( prof.ca->ca );
+    c.setIssuerNameFrom( ca->ca );
     c.setPubkeyFrom( req );
 
     std::shared_ptr<BIGNUM> 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<SignedCertificate> output = c.sign( prof.ca->caKey, cert->md );
+    std::shared_ptr<SignedCertificate> 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;
 }
index 8b3865505205f60522580bbd0051dcd3cf15ef33..1c848e5e69c2d17d9a411842f742d8921a70fc03 100644 (file)
@@ -10,7 +10,7 @@
 class SimpleOpensslSigner : public Signer {
 private:
     static std::shared_ptr<int> lib_ref;
-    std::pair<std::shared_ptr<BIGNUM>, std::string> nextSerial( Profile& prof );
+    std::pair<std::shared_ptr<BIGNUM>, std::string> nextSerial( Profile& prof, std::shared_ptr<CAConfig> ca );
 public:
     SimpleOpensslSigner();
     ~SimpleOpensslSigner();
index fd00e8fb85a94db8367299a6d52e676c5cd278bb..9487e42a7253a98d581f7509498e477b8f314da4 100644 (file)
@@ -168,7 +168,6 @@ std::shared_ptr<BIO> openSerial( const std::string name ) {
     }
 
     setupSerial( f );
-
     std::shared_ptr<BIO> 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<ASN1_TIME>( tm, ASN1_TIME_free );
 }
index 7a6850451f81566477930f14791a7223b7e34686..a85871a4520751bf2101ebfe8e1ccef62af9c2a6 100644 (file)
@@ -2,6 +2,7 @@
 #include <openssl/ssl.h>
 #include <memory>
 #include <string>
+#include <vector>
 #include <cinttypes>
 
 class CAConfig {
@@ -11,18 +12,27 @@ public:
 
     std::shared_ptr<X509> ca;
     std::shared_ptr<EVP_PKEY> caKey;
+    std::shared_ptr<ASN1_TIME> notBefore;
     CAConfig( std::string name );
 
 };
 
-
 struct Profile {
     uint16_t id;
 
     std::string eku;
     std::string ku;
 
-    std::shared_ptr<CAConfig> ca;
+    std::vector<std::shared_ptr<CAConfig>> ca;
+    std::shared_ptr<CAConfig> 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<int> ssl_lib_ref;
index f23f61012588a297be5d2d577adc36d3716c0bf3..b67ce665107d3b2aa11107a734aa29a7f10320a5 100644 (file)
@@ -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> job ) = 0;
     virtual std::shared_ptr<TBSCertificate> fetchTBSCert( std::shared_ptr<Job> job ) = 0;
     virtual void writeBack( std::shared_ptr<Job> job, std::shared_ptr<SignedCertificate> res ) = 0;
+    virtual std::pair<std::string, std::string> getRevocationInfo( std::shared_ptr<Job> job ) = 0;
 };
index e3fbca5e6a7d4e6336eb6155be002b18ba609e49..7bb93d01746891b75ce815830f28de16ab3c4526 100644 (file)
@@ -327,3 +327,23 @@ void MySQLJobProvider::writeBack( std::shared_ptr<Job> job, std::shared_ptr<Sign
         throw "Error while writing back";
     }
 }
+
+std::pair<std::string, std::string> MySQLJobProvider::getRevocationInfo( std::shared_ptr<Job> 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<MYSQL_RES> 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, std::string>( std::string( row[0], row[0] + l[0] ), std::string( row[1], row[1] + l[1] ) );
+}
index b1f78cef90bb8c051737a050ba5ee854fe27011b..9096fe5fac04dff08d57a93760b218bca5cdc89e 100644 (file)
@@ -35,4 +35,5 @@ public:
     void failJob( std::shared_ptr<Job> job );
     std::shared_ptr<TBSCertificate> fetchTBSCert( std::shared_ptr<Job> job );
     void writeBack( std::shared_ptr<Job> job, std::shared_ptr<SignedCertificate> res );
+    std::pair<std::string, std::string> getRevocationInfo( std::shared_ptr<Job> job );
 };