]> WPIA git - cassiopeia.git/commitdiff
add: Basic implementation to generate the certificate serial
authorFelix Dörre <felix@dogcraft.de>
Sun, 2 Nov 2014 01:16:21 +0000 (02:16 +0100)
committerBenny Baumann <BenBE@geshi.org>
Fri, 7 Nov 2014 22:53:04 +0000 (23:53 +0100)
.gitignore
src/X509.cpp
src/X509.h
src/database.h
src/main.cpp
src/mysql.cpp
src/simpleOpensslSigner.cpp
src/simpleOpensslSigner.h

index 5abf918e1702c7a9c47a14b1302261515e3a6245..56e0b1c730ec09f2d7678c9bc606a6f877bfdfb4 100644 (file)
@@ -27,3 +27,11 @@ obj
 
 # Emacs
 *~
+\#*#
+
+# Devel key files
+*.crt
+*.key
+*.csr
+config.txt
+serial
index 9219e394bc8a1f06897252ea2c0a670cbd38e66d..19901e41b0c19b38d322f744722c3e2b703df0ef 100644 (file)
@@ -119,8 +119,8 @@ void X509Cert::setPubkeyFrom( std::shared_ptr<X509Req> req ) {
     }
 }
 
-void X509Cert::setSerialNumber( int num ) {
-    ASN1_INTEGER_set( target.get()->cert_info->serialNumber, num );
+void X509Cert::setSerialNumber( BIGNUM* num ) {
+    BN_to_ASN1_INTEGER( num , target->cert_info->serialNumber );
 }
 
 void X509Cert::setTimes( uint32_t before, uint32_t after ) {
@@ -216,6 +216,10 @@ std::shared_ptr<SignedCertificate> X509Cert::sign( std::shared_ptr<EVP_PKEY> caK
     BIO_get_mem_ptr( mem.get(), &buf );
     std::shared_ptr<SignedCertificate> res = std::shared_ptr<SignedCertificate>( new SignedCertificate() );
     res->certificate = std::string( buf->data, buf->data + buf->length );
-    res->serial = ASN1_INTEGER_get( target.get()->cert_info->serialNumber );
+    BIGNUM* ser = ASN1_INTEGER_to_BN( target->cert_info->serialNumber, NULL );
+    char* serStr = BN_bn2hex( ser );
+    res->serial = std::string( serStr );
+    OPENSSL_free( serStr );
+    BN_free( ser );
     return res;
 }
index 994c9d60cb73a7f7e75150ef1baba7312d5b3c21..ac6c6354dcc60fa536e5559f7cc38fff2613cb8f 100644 (file)
@@ -28,7 +28,7 @@ public:
     X509Cert();
     void setIssuerNameFrom( std::shared_ptr<X509> ca );
     void setPubkeyFrom( std::shared_ptr<X509Req> r );
-    void setSerialNumber( int num );
+    void setSerialNumber( BIGNUM* num );
     void setExtensions( std::shared_ptr<X509> caCert, std::vector<std::shared_ptr<SAN>>& sans );
     void setTimes( uint32_t before, uint32_t after );
     std::shared_ptr<SignedCertificate> sign( std::shared_ptr<EVP_PKEY> caKey );
index 71d44acbb82b29932d90e0059bbe504114c93c60..7829da81e94cde4a0a6371e03cb319a0cf2b0a97 100644 (file)
@@ -35,7 +35,7 @@ struct TBSCertificate {
 
 struct SignedCertificate {
     std::string certificate;
-    uint32_t serial;
+    std::string serial;
     uint32_t before;
     uint32_t after;
     std::string pkHash;
index eb93eec38c1ed1e0163cf1a6e89f6e45b8412510..56ff30fd3e8cc8a2670b4832b1297bd141737e8f 100644 (file)
@@ -49,6 +49,7 @@ std::string writeBackFile( uint32_t serial, std::string cert ) {
     file.open( filename.c_str() );
     file << cert.c_str();
     file.close();
+    std::cout << "wrote to " << filename << std::endl;
     return filename;
 }
 
index 3c2cb960ca7563e6ad537cd7c4549ebb542167c9..23f71df8cea093786be1e7b2f90cebb1e7581214 100644 (file)
@@ -249,7 +249,7 @@ void MySQLJobProvider::writeBack( std::shared_ptr<Job> job, std::shared_ptr<Sign
         throw "Error while writing back";
     }
 
-    std::string q = "UPDATE certs SET crt_name='" + this->escape_string( res->crt_name ) + "', serial='" + this->escape_string( std::to_string( res->serial ) ) + "', created=NOW() WHERE id='" + this->escape_string( job->id ) + "' LIMIT 1";
+    std::string q = "UPDATE certs SET crt_name='" + this->escape_string( res->crt_name ) + "', serial='" + this->escape_string( res->serial ) + "', created=NOW() WHERE id='" + this->escape_string( job->target ) + "' LIMIT 1";
 
     // TODO write more thingies back
 
index 931f22ef84d14bb73074ee2d33aa9ba146e14072..c8d0bdf7a5cbaaa6d52ec4fa5f89c410bbf4cf0e 100644 (file)
@@ -1,6 +1,7 @@
 #include "simpleOpensslSigner.h"
 
 #include <iostream>
+#include <fstream>
 
 #include <openssl/ssl.h>
 #include <openssl/err.h>
@@ -69,7 +70,50 @@ SimpleOpensslSigner::SimpleOpensslSigner() {
     caKey = loadPkeyFromFile( profiles[0].key );
 }
 
-int serial = 10;
+SimpleOpensslSigner::~SimpleOpensslSigner() {
+}
+
+std::shared_ptr<BIGNUM> SimpleOpensslSigner::nextSerial() {
+    std::ifstream serialif( "serial" );
+    std::string res;
+    serialif >> res;
+    serialif.close();
+
+    BIGNUM* bn = 0;
+
+    if( res == "" ) {
+        bn = BN_new();
+
+        if( !bn ) {
+            throw "Initing serial failed";
+        }
+    } else {
+        if( !BN_hex2bn( &bn, res.c_str() + 1 ) ) {
+            throw "Parsing serial failed.";
+        }
+    }
+
+    std::shared_ptr<BIGNUM> serial = std::shared_ptr<BIGNUM>( bn, BN_free );
+
+    std::shared_ptr<unsigned char> data = std::shared_ptr<unsigned char>( ( unsigned char* ) malloc( BN_num_bytes( serial.get() ) + 20 ), free );
+    int len = BN_bn2bin( serial.get(), data.get() );
+    data.get()[len] = 0x0;
+    data.get()[len + 1] = 0x0; // profile id
+    data.get()[len + 2] = 0x0;
+    data.get()[len + 3] = 0x0; // signer id
+
+    if( !RAND_bytes( data.get() + len + 4, 16 ) || !BN_add_word( serial.get(), 1 ) ) {
+        throw "Big number math failed while calcing serials.";
+    }
+
+    char* serStr = BN_bn2hex( serial.get() );
+    std::ofstream serialf( "serial" );
+    serialf << serStr;
+    serialf.close();
+    OPENSSL_free( serStr );
+
+    return std::shared_ptr<BIGNUM>( BN_bin2bn( data.get(), len + 4 + 16 , 0 ), BN_free );
+}
 
 std::shared_ptr<SignedCertificate> SimpleOpensslSigner::sign( std::shared_ptr<TBSCertificate> cert ) {
     if( !caKey ) {
@@ -107,7 +151,8 @@ std::shared_ptr<SignedCertificate> SimpleOpensslSigner::sign( std::shared_ptr<TB
 
     c.setIssuerNameFrom( caCert );
     c.setPubkeyFrom( req );
-    c.setSerialNumber( serial++ );
+    std::shared_ptr<BIGNUM> ser = nextSerial();
+    c.setSerialNumber( ser.get() );
     c.setTimes( 0, 60 * 60 * 24 * 10 );
     c.setExtensions( caCert, cert->SANs );
 
index 5f1d207b429fbeca092de2d8f6d979be9cfe5d18..2b2774dc1579eb88f5e274d13d8ff602ea29cb1d 100644 (file)
@@ -10,7 +10,9 @@ private:
     static std::shared_ptr<int> lib_ref;
     std::shared_ptr<EVP_PKEY> caKey;
     std::shared_ptr<X509> caCert;
+    std::shared_ptr<BIGNUM> nextSerial();
 public:
     SimpleOpensslSigner();
+    ~SimpleOpensslSigner();
     std::shared_ptr<SignedCertificate> sign( std::shared_ptr<TBSCertificate> cert );
 };