]> WPIA git - cassiopeia.git/commitdiff
upd: extract remote signer class, mostly
authorFelix Dörre <felix@dogcraft.de>
Mon, 22 Dec 2014 23:08:53 +0000 (00:08 +0100)
committerBenny Baumann <BenBE@geshi.org>
Sat, 24 Jan 2015 16:39:49 +0000 (17:39 +0100)
src/opensslBIO.cpp
src/opensslBIO.h
src/recordHandler.cpp
src/recordHandler.h
src/remoteSigner.cpp [new file with mode: 0644]
src/remoteSigner.h [new file with mode: 0644]
src/slipBio.cpp
test/src/bioWrapper.cpp
test/src/slipBioTest.cpp

index 57a07d160056ef0d682d96f16d6b5d6d6307456a..35628229ffdcbf00f162d5b134fb8196ecc4f582 100644 (file)
@@ -1,31 +1,30 @@
 #include "opensslBIO.h"
 
-OpensslBIOWrapper::OpensslBIOWrapper( BIO* b ) {
+OpensslBIOWrapper::OpensslBIOWrapper( std::shared_ptr<BIO> b ) {
     this->b = b;
 }
 
 OpensslBIOWrapper::~OpensslBIOWrapper() {
-    BIO_free( b );
 }
 
 int OpensslBIOWrapper::write( const char* buf, int num ) {
-    return BIO_write( b, buf, num );
+    return BIO_write( b.get(), buf, num );
 }
 
 int OpensslBIOWrapper::read( char* buf, int size ) {
-    return BIO_read( b, buf, size );
+    return BIO_read( b.get(), buf, size );
 }
 
 long OpensslBIOWrapper::ctrl( int cmod, long arg1, void* arg2 ) {
-    return BIO_ctrl( b, cmod, arg1, arg2 );
+    return BIO_ctrl( b.get(), cmod, arg1, arg2 );
 }
 
 int OpensslBIOWrapper::puts( const char* str ) {
-    return BIO_puts( b, str );
+    return BIO_puts( b.get(), str );
 }
 
 int OpensslBIOWrapper::gets( char* str, int size ) {
-    return BIO_gets( b, str, size );
+    return BIO_gets( b.get(), str, size );
 }
 
 const char* OpensslBIOWrapper::getName() {
index 9c7e12e111c6f2a64ed3b40a1f54ce767553bbca..a3d7188c02e74800808994edaf98793007e0763c 100644 (file)
@@ -1,12 +1,13 @@
 #pragma once
 
+#include <memory>
 #include "bios.h"
 
 class OpensslBIOWrapper : public OpensslBIO {
 private:
-    BIO* b;
+    std::shared_ptr<BIO> b;
 public:
-    OpensslBIOWrapper( BIO* b );
+    OpensslBIOWrapper( std::shared_ptr<BIO> b );
     virtual ~OpensslBIOWrapper();
 
     int write( const char* buf, int num );
index b1c5ac4280b083158fcefb49581ff16c73803c49..ab9c3229555e93ee84490c20cff36c2bdb09ba2d 100644 (file)
@@ -27,6 +27,11 @@ int gencb( int a, int b, BN_GENCB* g ) {
     return 1;
 }
 
+int vfy( int prevfy, X509_STORE_CTX* ct ) {
+    ( void ) ct;
+    return prevfy;
+}
+
 static std::shared_ptr<DH> dh_param;
 
 std::shared_ptr<SSL_CTX> generateSSLContext( bool server ) {
@@ -36,6 +41,20 @@ std::shared_ptr<SSL_CTX> generateSSLContext( bool server ) {
         throw "Cannot set cipher list. Your source is broken.";
     }
 
+    SSL_CTX_set_verify( ctx.get(), SSL_VERIFY_NONE, vfy );
+    SSL_CTX_use_certificate_file( ctx.get(), "testdata/server.crt", SSL_FILETYPE_PEM );
+    SSL_CTX_use_PrivateKey_file( ctx.get(), "testdata/server.key", SSL_FILETYPE_PEM );
+    std::shared_ptr<STACK_OF( X509_NAME )> cert_names(
+        SSL_load_client_CA_file( "testdata/server.crt" ),
+        []( STACK_OF( X509_NAME ) *st ) {
+            std::cout << "freeing" << std::endl;
+            sk_X509_NAME_free( st );
+        } );
+
+    if( cert_names ) {
+        SSL_CTX_set_client_CA_list( ctx.get(), cert_names.get() );
+    }
+
     if( server ) {
         if( !dh_param ) {
             FILE* paramfile = fopen( "dh_param.pem", "r" );
@@ -87,16 +106,18 @@ public:
     DefaultRecordHandler* parent;
     std::shared_ptr<Signer> signer;
 
-    RecordHandlerSession( DefaultRecordHandler* parent, std::shared_ptr<Signer> signer, std::shared_ptr<SSL_CTX> ctx, BIO* output ) :
+    RecordHandlerSession( DefaultRecordHandler* parent, std::shared_ptr<Signer> signer, std::shared_ptr<SSL_CTX> ctx, std::shared_ptr<BIO> output ) :
         tbs( new TBSCertificate() ) {
         this->parent = parent;
         this->signer = signer;
 
         ssl = SSL_new( ctx.get() );
-        BIO* bio = BIO_new( BIO_f_ssl() );
+        std::shared_ptr<BIO> bio( BIO_new( BIO_f_ssl() ), [output]( BIO * p ) {
+            BIO_free( p );
+        } );
         SSL_set_accept_state( ssl );
-        SSL_set_bio( ssl, output, output );
-        BIO_set_ssl( bio, ssl, BIO_NOCLOSE );
+        SSL_set_bio( ssl, output.get(), output.get() );
+        BIO_set_ssl( bio.get(), ssl, BIO_NOCLOSE );
         io = std::shared_ptr<OpensslBIOWrapper>( new OpensslBIOWrapper( bio ) );
     }
 
@@ -110,8 +131,11 @@ public:
     }
 
     void work() {
+        std::cout << "done" << std::endl;
         std::vector<char> buffer( 2048, 0 );
+        std::cout << "reading" << std::endl;
         int res = io->read( buffer.data(), buffer.capacity() );
+        std::cout << "read" << std::endl;
 
         if( res <= 0 ) {
             parent->reset();
@@ -144,7 +168,7 @@ public:
             break;
 
         case RecordHeader::SignerCommand::SET_SIGNATURE_TYPE:
-            tbs->md = "sha256"; // TODO use content ;-)
+            tbs->md = data;
             break;
 
         case RecordHeader::SignerCommand::SET_PROFILE:
@@ -202,7 +226,7 @@ public:
     }
 };
 
-DefaultRecordHandler::DefaultRecordHandler( std::shared_ptr<Signer> signer, BIO* bio ) :
+DefaultRecordHandler::DefaultRecordHandler( std::shared_ptr<Signer> signer, std::shared_ptr<BIO> bio ) :
     currentSession() {
 
     this->signer = signer;
@@ -225,18 +249,10 @@ void DefaultRecordHandler::handle() {
         currentSession = std::shared_ptr<RecordHandlerSession>( new RecordHandlerSession( this, signer, ctx, bio ) );
     }
 
+    std::cout << "really allocated: " << currentSession << ";" << std::endl;
     currentSession->work();
 }
 
-int count = 0;
-
-void send( std::shared_ptr<OpensslBIOWrapper> bio, RecordHeader& head, RecordHeader::SignerCommand cmd, std::string data ) {
-    head.command = ( uint16_t ) cmd;
-    head.command_count++;
-    head.totalLength = data.size();
-    sendCommand( head, data, bio );
-}
-
 void setupSerial( FILE* f ) {
     struct termios attr;
 
@@ -258,7 +274,8 @@ void setupSerial( FILE* f ) {
 int handlermain( int argc, const char* argv[] ) {
     ( void ) argc;
     ( void ) argv;
-    std::shared_ptr<OpensslBIOWrapper> bio( new OpensslBIOWrapper( BIO_new_fd( 0, 0 ) ) );
+
+    std::shared_ptr<OpensslBIOWrapper> bio( new OpensslBIOWrapper( std::shared_ptr<BIO>( BIO_new_fd( 0, 0 ), BIO_free ) ) );
     std::string data =
         "-----BEGIN CERTIFICATE REQUEST-----\n"
         "MIIBSzCBtQIBADAMMQowCAYDVQQDDAFhMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB\n"
@@ -269,6 +286,7 @@ int handlermain( int argc, const char* argv[] ) {
         "/f49zIcVtUJuZuEwY6uDZQqfAm+8CLNpOCICH/Qw7YOe+s/Yw7a8rk5VqLtgxR4M\n"
         "z6DUeVL0zYFoLUxIje9yDU3pWmPvyVaBPdo0DguZwFMfiWwzhkUDeQgyeaiMvQA=\n"
         "-----END CERTIFICATE REQUEST-----";
+
     RecordHeader head;
     head.flags = 0;
     head.sessid = 13;
@@ -287,38 +305,19 @@ int handlermain( int argc, const char* argv[] ) {
 
         setupSerial( f );
 
-        BIO* b = BIO_new_fd( fileno( f ), 0 );
-        BIO* slip1 = BIO_new( toBio<SlipBIO>() );
+        std::shared_ptr<BIO> b( BIO_new_fd( fileno( f ), 0 ), BIO_free );
+        std::shared_ptr<BIO> slip1( BIO_new( toBio<SlipBIO>() ), BIO_free );
         ( ( SlipBIO* )slip1->ptr )->setTarget( std::shared_ptr<OpensslBIO>( new OpensslBIOWrapper( b ) ) );
         std::cout << "Initing tlsv1_2" << std::endl;
         std::shared_ptr<SSL_CTX> ctx = generateSSLContext( false );
-        SSL* ssl = SSL_new( ctx.get() );
-        BIO* bio = BIO_new( BIO_f_ssl() );
-        SSL_set_connect_state( ssl );
-        SSL_set_bio( ssl, slip1, slip1 );
-        BIO_set_ssl( bio, ssl, BIO_NOCLOSE );
-        std::shared_ptr<OpensslBIOWrapper> conn( new OpensslBIOWrapper( bio ) );
-        send( conn, head, RecordHeader::SignerCommand::SET_CSR, data );
-        send( conn, head, RecordHeader::SignerCommand::SET_SIGNATURE_TYPE, "sha256" );
-        send( conn, head, RecordHeader::SignerCommand::SET_PROFILE, "1" );
-        send( conn, head, RecordHeader::SignerCommand::ADD_AVA, "CN,commonName" );
-        send( conn, head, RecordHeader::SignerCommand::ADD_SAN, "DNS,*.example.com" );
-        send( conn, head, RecordHeader::SignerCommand::SIGN, "" );
-        send( conn, head, RecordHeader::SignerCommand::LOG_SAVED, "" );
-        std::vector<char> buffer( 2048 * 4 );
-
-        for( int i = 0; i < 2; i++ ) {
-            try {
-                int length = conn->read( buffer.data(), buffer.size() );
-                RecordHeader head;
-                std::string payload = parseCommand( head, std::string( buffer.data(), length ) );
-                std::cout << "Data: " << std::endl << payload << std::endl;
-            } catch( const char* msg ) {
-                std::cout << msg << std::endl;
-                return -1;
-            }
-        }
-
+        std::shared_ptr<RemoteSigner> sign( new RemoteSigner( slip1, ctx ) );
+        std::shared_ptr<TBSCertificate> cert( new TBSCertificate() );
+        cert->csr_type = "csr";
+        cert->csr_content = data;
+        cert->md = "sha256";
+        cert->profile = "1";
+
+        auto res = sign->sign( cert );
         std::cout << "sent things" << std::endl;
 
         return 0;
@@ -333,8 +332,9 @@ int handlermain( int argc, const char* argv[] ) {
 
     setupSerial( f );
 
-    BIO* conn =  BIO_new_fd( fileno( f ), 0 );
-    BIO* slip1 = BIO_new( toBio<SlipBIO>() );
+    std::shared_ptr<BIO> conn( BIO_new_fd( fileno( f ), 0 ), BIO_free );
+    std::shared_ptr<BIO> slip1( BIO_new( toBio<SlipBIO>() ), BIO_free );
+
     ( ( SlipBIO* )slip1->ptr )->setTarget( std::shared_ptr<OpensslBIO>( new OpensslBIOWrapper( conn ) ) );
 
     try {
index 5212272cebeccd82a762538c9ff767b82b7c1740..e9b1e20bdd74c0591e9fa28e8f0ea12c805d5be6 100644 (file)
@@ -19,12 +19,12 @@ class RecordHandlerSession;
 
 class DefaultRecordHandler {
 private:
-    BIO* bio;
+    std::shared_ptr<BIO> bio;
     std::shared_ptr<SSL_CTX> ctx;
     std::shared_ptr<Signer> signer;
     std::shared_ptr<RecordHandlerSession> currentSession;
 public:
-    DefaultRecordHandler( std::shared_ptr<Signer> signer, BIO* bio );
+    DefaultRecordHandler( std::shared_ptr<Signer> signer, std::shared_ptr<BIO> bio );
     void handle();
     void reset();
 };
diff --git a/src/remoteSigner.cpp b/src/remoteSigner.cpp
new file mode 100644 (file)
index 0000000..9cc3a2d
--- /dev/null
@@ -0,0 +1,61 @@
+#include "remoteSigner.h"
+
+#include <iostream>
+
+RemoteSigner::RemoteSigner( std::shared_ptr<BIO> target, std::shared_ptr<SSL_CTX> ctx ) {
+    this->target = target;
+    this->ctx = ctx;
+}
+RemoteSigner::~RemoteSigner() {
+}
+
+void RemoteSigner::send( std::shared_ptr<OpensslBIOWrapper> bio, RecordHeader& head, RecordHeader::SignerCommand cmd, std::string data ) {
+    head.command = ( uint16_t ) cmd;
+    head.command_count++;
+    head.totalLength = data.size();
+    sendCommand( head, data, bio );
+
+}
+
+std::shared_ptr<SignedCertificate> RemoteSigner::sign( std::shared_ptr<TBSCertificate> cert ) {
+    std::shared_ptr<SSL> ssl( SSL_new( ctx.get() ), SSL_free );
+    std::shared_ptr<BIO> bio( BIO_new( BIO_f_ssl() ), BIO_free );
+    SSL_set_connect_state( ssl.get() );
+    SSL_set_bio( ssl.get(), target.get(), target.get() );
+    BIO_set_ssl( bio.get(), ssl.get(), BIO_NOCLOSE );
+    std::shared_ptr<OpensslBIOWrapper> conn( new OpensslBIOWrapper( bio ) );
+    RecordHeader head;
+    head.flags = 0;
+    head.sessid = 13;
+
+    if( cert->csr_type == "csr" ) {
+        send( conn, head, RecordHeader::SignerCommand::SET_CSR, cert->csr_content );
+    } else {
+        std::cout << "Unknown csr_type: " << cert->csr_type;
+        return std::shared_ptr<SignedCertificate>();
+    }
+
+    send( conn, head, RecordHeader::SignerCommand::SET_SIGNATURE_TYPE, cert->md );
+    send( conn, head, RecordHeader::SignerCommand::SET_PROFILE, cert->profile );
+    send( conn, head, RecordHeader::SignerCommand::ADD_AVA, "CN,commonName" );
+    send( conn, head, RecordHeader::SignerCommand::ADD_SAN, "DNS,*.example.com" );
+    send( conn, head, RecordHeader::SignerCommand::SIGN, "" );
+    send( conn, head, RecordHeader::SignerCommand::LOG_SAVED, "" );
+    std::shared_ptr<SignedCertificate> result = std::shared_ptr<SignedCertificate>( new SignedCertificate() );
+    std::vector<char> buffer( 2048 * 4 );
+
+    for( int i = 0; i < 2; i++ ) {
+        try {
+            int length = conn->read( buffer.data(), buffer.size() );
+            RecordHeader head;
+            std::string payload = parseCommand( head, std::string( buffer.data(), length ) );
+            std::cout << "Data: " << std::endl << payload << std::endl;
+        } catch( const char* msg ) {
+            std::cout << msg << std::endl;
+            return std::shared_ptr<SignedCertificate>();
+        }
+    }
+
+    return result;
+}
+
diff --git a/src/remoteSigner.h b/src/remoteSigner.h
new file mode 100644 (file)
index 0000000..36c9339
--- /dev/null
@@ -0,0 +1,22 @@
+#pragma once
+#include <memory>
+#include <openssl/ssl.h>
+
+#include "database.h"
+#include "signer.h"
+#include "bios.h"
+#include "opensslBIO.h"
+#include "record.h"
+
+
+class RemoteSigner : public Signer {
+private:
+    std::shared_ptr<BIO> target;
+    std::shared_ptr<SSL_CTX> ctx;
+    int count = 0;
+    void send( std::shared_ptr<OpensslBIOWrapper> bio, RecordHeader& head, RecordHeader::SignerCommand cmd, std::string data );
+public:
+    RemoteSigner( std::shared_ptr<BIO> target, std::shared_ptr<SSL_CTX> ctx );
+    ~RemoteSigner();
+    std::shared_ptr<SignedCertificate> sign( std::shared_ptr<TBSCertificate> cert );
+};
index 725e837a228122da085b14a3f4f88e581d7f34e3..ced5a6fb4639a6a6dafbcacb96b4055f993e4136 100644 (file)
@@ -37,6 +37,7 @@ SlipBIO::SlipBIO() {
     this->decodeTarget = 0;
     this->decodePos = 0;
     this->rawPos = 0;
+    this->failed = false;
 }
 
 void SlipBIO::setTarget( std::shared_ptr<OpensslBIO> target ) {
@@ -45,6 +46,7 @@ void SlipBIO::setTarget( std::shared_ptr<OpensslBIO> target ) {
 
 SlipBIO::SlipBIO( std::shared_ptr<OpensslBIO> target ) {
     this->target = target;
+
     this->buffer = std::vector<char>( 4096 );
     this->decodeTarget = 0;
     this->decodePos = 0;
index 73d7c3600ebb14d12cf0cf4f10ff4dadcded486f..a2706f8bab7ca4a45b84cf8800621c6ed29b0876 100644 (file)
@@ -39,7 +39,7 @@ const char* OpensslBIO1::getName() {
 BOOST_AUTO_TEST_SUITE( TestBioWrapper )
 
 BOOST_AUTO_TEST_CASE( BasicCalls ) {
-    BIO* n = BIO_new( toBio<OpensslBIO1>() );
+    std::shared_ptr<BIO> n( BIO_new( toBio<OpensslBIO1>() ), BIO_free );
     OpensslBIO* o = new OpensslBIOWrapper( n );
     OpensslBIO1* data = ( OpensslBIO1* ) n->ptr;
 
index 7b45158ba010dbc88d5f7c259d1ddc78161b1815..b88ccec7caaca487cbcda75dfce81b02a6eb36ec 100644 (file)
@@ -113,9 +113,9 @@ BOOST_AUTO_TEST_CASE( TestSSLThroughSLIP ) {
     BIO* bio1, *bio2;
     BOOST_REQUIRE_EQUAL( BIO_new_bio_pair( &bio1, 8096, &bio2, 8096 ), 1 );
     BIO* slip1 = BIO_new( toBio<SlipBIO>() );
-    ( ( SlipBIO* )slip1->ptr )->setTarget( std::shared_ptr<OpensslBIO>( new OpensslBIOWrapper( bio1 ) ) );
+    ( ( SlipBIO* )slip1->ptr )->setTarget( std::shared_ptr<OpensslBIO>( new OpensslBIOWrapper( std::shared_ptr<BIO>( bio1, BIO_free ) ) ) );
     BIO* slip2 = BIO_new( toBio<SlipBIO>() );
-    ( ( SlipBIO* )slip2->ptr )->setTarget( std::shared_ptr<OpensslBIO>( new OpensslBIOWrapper( bio2 ) ) );
+    ( ( SlipBIO* )slip2->ptr )->setTarget( std::shared_ptr<OpensslBIO>( new OpensslBIOWrapper( std::shared_ptr<BIO>( bio2, BIO_free ) ) ) );
 
     auto meth = TLSv1_method();
     auto c_ctx = SSL_CTX_new( meth );