]> WPIA git - cassiopeia.git/commitdiff
chg: Split off X509-related API
authorFelix Dörre <felix@dogcraft.de>
Sun, 2 Nov 2014 00:01:47 +0000 (01:01 +0100)
committerBenny Baumann <BenBE@geshi.org>
Fri, 7 Nov 2014 22:53:04 +0000 (23:53 +0100)
src/X509.cpp [new file with mode: 0644]
src/X509.h [new file with mode: 0644]
src/main.cpp
src/simpleOpensslSigner.cpp

diff --git a/src/X509.cpp b/src/X509.cpp
new file mode 100644 (file)
index 0000000..2e441b2
--- /dev/null
@@ -0,0 +1,120 @@
+#include "X509.h"
+
+#include <openssl/ssl.h>
+#include <openssl/bio.h>
+#include <openssl/x509v3.h>
+
+X509Req::X509Req( X509_REQ* csr ) {
+    req = std::shared_ptr<X509_REQ>( csr, X509_REQ_free );
+    EVP_PKEY* pkt = X509_REQ_get_pubkey( req.get() );
+
+    if( !pkt ) {
+        throw "Error extracting public key";
+    }
+
+    pk = std::shared_ptr<EVP_PKEY>( pkt, EVP_PKEY_free );
+}
+
+int X509Req::verify() {
+    return X509_REQ_verify( req.get(), pk.get() );
+}
+
+std::shared_ptr<EVP_PKEY> X509Req::getPkey() {
+    return pk;
+}
+
+std::shared_ptr<X509Req> X509Req::parse( std::string filename ) {
+    std::shared_ptr<BIO> in = std::shared_ptr<BIO>( BIO_new_mem_buf( const_cast<char*>( filename.c_str() ), -1 ), BIO_free );
+    X509_REQ* req = PEM_read_bio_X509_REQ( in.get(), NULL, NULL, NULL );
+
+    if( !req ) {
+        throw "Error parsing CSR";
+    }
+
+    return std::shared_ptr<X509Req>( new X509Req( req ) );
+}
+
+int add_ext( std::shared_ptr<X509> issuer, std::shared_ptr<X509> subj, int nid, const char* value ) {
+    X509_EXTENSION* ex;
+    X509V3_CTX ctx;
+
+    /* This sets the 'context' of the extensions. */
+    /* No configuration database */
+    X509V3_set_ctx_nodb( &ctx );
+
+    /* Issuer and subject certs: both the target since it is self signed,
+     * no request and no CRL
+     */
+    X509V3_set_ctx( &ctx, issuer.get(), subj.get(), NULL, NULL, 0 );
+    ex = X509V3_EXT_conf_nid( NULL, &ctx, nid, const_cast<char*>( value ) );
+
+    if( !ex ) {
+        return 0;
+    }
+
+    X509_add_ext( subj.get(), ex, -1 );
+    X509_EXTENSION_free( ex );
+
+    return 1;
+}
+
+X509Cert::X509Cert() {
+    X509* c = X509_new();
+
+    if( !c ) {
+        throw "malloc failed";
+    }
+
+    target = std::shared_ptr<X509>( c, X509_free );
+
+    if( !X509_set_version( c, 2 ) ) {
+        throw "Setting X509-version to 3 failed";
+    }
+}
+
+void X509Cert::setIssuerNameFrom( std::shared_ptr<X509> caCert ) {
+    if( !X509_set_issuer_name( target.get(), X509_get_subject_name( caCert.get() ) ) ) {
+        throw "Error setting Issuer name";
+    }
+}
+
+void X509Cert::setPubkeyFrom( std::shared_ptr<X509Req> req ) {
+    std::shared_ptr<EVP_PKEY> pktmp = req->getPkey();
+
+    if( !X509_set_pubkey( target.get(), pktmp.get() ) ) {
+        throw "Setting public key failed.";
+    }
+}
+
+void X509Cert::setSerialNumber( int num ) {
+    ASN1_INTEGER_set( target.get()->cert_info->serialNumber, num );
+}
+
+void X509Cert::setTimes( long before, long after ) {
+    X509_gmtime_adj( X509_get_notBefore( target.get() ), before );
+    X509_gmtime_adj( X509_get_notAfter( target.get() ), after );
+}
+
+void X509Cert::setExtensions( std::shared_ptr<X509> caCert ) {
+    add_ext( caCert, target, NID_basic_constraints, "critical,CA:FALSE" );
+    add_ext( caCert, target, NID_subject_key_identifier, "hash" );
+    add_ext( caCert, target, NID_authority_key_identifier, "keyid,issuer:always" );
+    add_ext( caCert, target, NID_key_usage, "critical,nonRepudiation,digitalSignature,keyEncipherment" );
+    add_ext( caCert, target, NID_ext_key_usage, "clientAuth, serverAuth" );
+    add_ext( caCert, target, NID_info_access, "OCSP;URI:http://ocsp.cacert.org" );
+    add_ext( caCert, target, NID_crl_distribution_points, "URI:http://crl.cacert.org/class3-revoke.crl" );
+}
+
+std::string X509Cert::sign( std::shared_ptr<EVP_PKEY> caKey ) {
+    if( !X509_sign( target.get(), caKey.get(), EVP_sha512() ) ) {
+        throw "Signing failed.";
+    }
+
+    X509_print_fp( stdout, target.get() );
+    std::shared_ptr<BIO> mem = std::shared_ptr<BIO>( BIO_new( BIO_s_mem() ), BIO_free );
+    PEM_write_bio_X509( mem.get(), target.get() );
+    BUF_MEM* buf;
+    BIO_get_mem_ptr( mem.get(), &buf );
+    std::string output( buf->data, buf->data + buf->length );
+    return output;
+}
diff --git a/src/X509.h b/src/X509.h
new file mode 100644 (file)
index 0000000..a9d60e6
--- /dev/null
@@ -0,0 +1,28 @@
+#pragma once
+#include <memory>
+#include <openssl/ssl.h>
+
+class X509Req {
+private:
+    std::shared_ptr<EVP_PKEY> pk;
+    std::shared_ptr<X509_REQ> req;
+    X509Req( X509_REQ* csr );
+public:
+    static std::shared_ptr<X509Req> parse( std::string filename );
+    int verify();
+    std::shared_ptr<EVP_PKEY> getPkey();
+};
+
+class X509Cert {
+private:
+    std::shared_ptr<X509> target;
+public:
+    X509Cert();
+    void setIssuerNameFrom( std::shared_ptr<X509> ca );
+    void setPubkeyFrom( std::shared_ptr<X509Req> r );
+    void setSerialNumber( int num );
+    void setExtensions( std::shared_ptr<X509> caCert );
+    void setTimes( long before, long after );
+    std::string sign( std::shared_ptr<EVP_PKEY> caKey );
+};
+
index b57d3435b88942686878f91f1feacd63d2351ef0..e03c361be0d91c363f64bb41083086f9469a46bf 100644 (file)
@@ -40,11 +40,15 @@ int main( int argc, const char* argv[] ) {
     }
 
     if( job->task == "sign" ) {
     }
 
     if( job->task == "sign" ) {
-        std::shared_ptr<TBSCertificate> cert = jp->fetchTBSCert( job );
-        std::cout << "Found a CSR at '" << cert->csr << "' signing" << std::endl;
-        std::ifstream t( cert->csr );
-        cert->csr_content = std::string( std::istreambuf_iterator<char>( t ), std::istreambuf_iterator<char>() );
-        sign->sign( cert );
+        try {
+            std::shared_ptr<TBSCertificate> cert = jp->fetchTBSCert( job );
+            std::cout << "Found a CSR at '" << cert->csr << "' signing" << std::endl;
+            std::ifstream t( cert->csr );
+            cert->csr_content = std::string( std::istreambuf_iterator<char>( t ), std::istreambuf_iterator<char>() );
+            sign->sign( cert );
+        } catch( const char* c ) {
+            std::cerr << c << std::endl;
+        }
     }
 
     if( !jp->finishJob( job ) ) {
     }
 
     if( !jp->finishJob( job ) ) {
index 3ef4b5eecad6e1f47ad9e13b286dede467552457..89151a665fa0c9f8214e57ff25ffd33ba6164666 100644 (file)
@@ -9,6 +9,8 @@
 #include <openssl/engine.h>
 #include <openssl/x509v3.h>
 
 #include <openssl/engine.h>
 #include <openssl/x509v3.h>
 
+#include "X509.h"
+
 std::shared_ptr<int> SimpleOpensslSigner::lib_ref(
     new int( SSL_library_init() ),
     []( int* ref ) {
 std::shared_ptr<int> SimpleOpensslSigner::lib_ref(
     new int( SSL_library_init() ),
     []( int* ref ) {
@@ -61,58 +63,14 @@ std::shared_ptr<X509> SimpleOpensslSigner::caCert = loadX509FromFile( "assured.c
 
 std::shared_ptr<EVP_PKEY> SimpleOpensslSigner::caKey = loadPkeyFromFile( "assured.key" );
 
 
 std::shared_ptr<EVP_PKEY> SimpleOpensslSigner::caKey = loadPkeyFromFile( "assured.key" );
 
-int add_ext( std::shared_ptr<X509> issuer, X509* subj, int nid, const char* value ) {
-    X509_EXTENSION* ex;
-    X509V3_CTX ctx;
-    /* This sets the 'context' of the extensions. */
-    /* No configuration database */
-    X509V3_set_ctx_nodb( &ctx );
-    /* Issuer and subject certs: both the target since it is self signed,
-     * no request and no CRL
-     */
-    X509V3_set_ctx( &ctx, issuer.get(), subj, NULL, NULL, 0 );
-    ex = X509V3_EXT_conf_nid( NULL, &ctx, nid, const_cast<char*>( value ) );
-
-    if( !ex ) {
-        return 0;
-    }
-
-    X509_add_ext( subj, ex, -1 );
-    X509_EXTENSION_free( ex );
-    return 1;
-}
-
 void SimpleOpensslSigner::sign( std::shared_ptr<TBSCertificate> cert ) {
     if( !caKey ) {
         throw "CA-key not found";
     }
 
 void SimpleOpensslSigner::sign( std::shared_ptr<TBSCertificate> cert ) {
     if( !caKey ) {
         throw "CA-key not found";
     }
 
-    std::shared_ptr<BIO> in = std::shared_ptr<BIO>(
-        BIO_new_mem_buf( const_cast<char*>( cert->csr_content.c_str() ), -1 ),
-        []( BIO * ref ) {
-            BIO_free( ref );
-        } );
-    std::shared_ptr<X509_REQ> req = std::shared_ptr<X509_REQ>(
-        PEM_read_bio_X509_REQ( in.get(), NULL, NULL, NULL ),
-        []( X509_REQ * ref ) {
-            if( ref ) {
-                X509_REQ_free( ref );
-            }
-        } );
-
-    if( !req ) {
-        throw "Error parsing CSR";
-    }
-
-    EVP_PKEY* pktmp = X509_REQ_get_pubkey( req.get() );
-
-    if( !pktmp ) {
-        throw "Error extracting pubkey";
-    }
+    std::shared_ptr<X509Req> req = X509Req::parse( cert->csr_content );
 
 
-    EVP_PKEY_free( pktmp );
-
-    int i = X509_REQ_verify( req.get(), pktmp );
+    int i = req->verify();
 
     if( i < 0 ) {
         throw "Signature problems ... ";
 
     if( i < 0 ) {
         throw "Signature problems ... ";
@@ -123,56 +81,21 @@ void SimpleOpensslSigner::sign( std::shared_ptr<TBSCertificate> cert ) {
     }
 
     // Construct the Certificate
     }
 
     // Construct the Certificate
-
-    std::shared_ptr<X509> ret = std::shared_ptr<X509>( X509_new(), X509_free );
+    X509Cert c = X509Cert();
+    std::shared_ptr<X509> retsh = std::shared_ptr<X509>( X509_new(), X509_free );
+    X509* ret = retsh.get();
 
     if( !ret ) {
         throw "Creating X509 failed.";
     }
 
 
     if( !ret ) {
         throw "Creating X509 failed.";
     }
 
-    X509_CINF* ci = ret->cert_info;
-
-    if( !X509_set_version( ret.get(), 2 ) ) {
-        throw "Setting X509-version to 3 failed";
-    }
-
-    if( !X509_set_issuer_name( ret.get(), X509_get_subject_name( caCert.get() ) ) ) {
-        throw "Error setting Issuer name";
-    }
+    c.setIssuerNameFrom( caCert );
+    c.setPubkeyFrom( req );
+    c.setSerialNumber( 4711 );
+    c.setTimes( 0, 1000 * 60 * 60 * 24 * 10 );
+    c.setExtensions( caCert );
 
 
-    // Serial and Pubkey
-    ASN1_INTEGER_set( ci->serialNumber, 4711 );
-    pktmp = X509_REQ_get_pubkey( req.get() );
-
-    if( !X509_set_pubkey( ret.get(), pktmp ) ) {
-        EVP_PKEY_free( pktmp );
-        throw "Setting public key failed.";
-    } else {
-        EVP_PKEY_free( pktmp );
-    }
-
-    // Dates
-    X509_gmtime_adj( X509_get_notBefore( ret.get() ), 0 );
-    X509_gmtime_adj( X509_get_notAfter( ret.get() ), ( long )60 * 60 * 24 * 10 );
-
-    // Extensions
-    add_ext( caCert, ret.get(), NID_basic_constraints, "critical,CA:FALSE" );
-    add_ext( caCert, ret.get(), NID_subject_key_identifier, "hash" );
-    add_ext( caCert, ret.get(), NID_authority_key_identifier, "keyid,issuer:always" );
-    add_ext( caCert, ret.get(), NID_key_usage, "critical,nonRepudiation,digitalSignature,keyEncipherment" );
-    add_ext( caCert, ret.get(), NID_ext_key_usage, "clientAuth, serverAut" );
-    add_ext( caCert, ret.get(), NID_info_access, "OCSP;URI:http://ocsp.cacert.org" );
-    add_ext( caCert, ret.get(), NID_crl_distribution_points, "URI:http://crl.cacert.org/class3-revoke.crl" );
-
-    if( !X509_sign( ret.get(), caKey.get(), EVP_sha512() ) ) {
-        throw "Signing failed.";
-    }
+    std::string output = c.sign( caKey );
 
 
-    X509_print_fp( stdout, ret.get() );
-    std::shared_ptr<BIO> mem = std::shared_ptr<BIO>( BIO_new( BIO_s_mem() ), BIO_free );
-    PEM_write_bio_X509( mem.get(), ret.get() );
-    BUF_MEM* buf;
-    BIO_get_mem_ptr( mem.get(), &buf );
-    std::string output( buf->data, buf->data + buf->length );
     std::cout << "Certificate:" << std::endl << output << std::endl;
 }
     std::cout << "Certificate:" << std::endl << output << std::endl;
 }