X-Git-Url: https://code.wpia.club/?a=blobdiff_plain;f=src%2FsimpleOpensslSigner.cpp;h=0096d5ec0457f67ca4f42058fbb8778124753254;hb=2c79061a72b54efdcac10b6beca62bf53f7383c8;hp=01189958fd70986c6dc8e49f6a4ea785c38ecaa3;hpb=aef2ba57f652658f3bebfa24e706c0083a56e6bf;p=cassiopeia.git diff --git a/src/simpleOpensslSigner.cpp b/src/simpleOpensslSigner.cpp index 0118995..0096d5e 100644 --- a/src/simpleOpensslSigner.cpp +++ b/src/simpleOpensslSigner.cpp @@ -10,6 +10,9 @@ #include #include "X509.h" +#include "util.h" + +extern std::vector profiles; std::shared_ptr SimpleOpensslSigner::lib_ref( new int( SSL_library_init() ), @@ -62,16 +65,70 @@ std::shared_ptr loadPkeyFromFile( std::string filename ) { } ); } -std::shared_ptr SimpleOpensslSigner::caCert = loadX509FromFile( "assured.crt" ); +SimpleOpensslSigner::SimpleOpensslSigner() { + caCert = loadX509FromFile( profiles[0].cert ); + caKey = loadPkeyFromFile( profiles[0].key ); +} + +SimpleOpensslSigner::~SimpleOpensslSigner() { +} + +std::shared_ptr SimpleOpensslSigner::nextSerial( uint16_t profile ) { + std::string res = readFile( "serial" ); + + 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 serial = std::shared_ptr( bn, BN_free ); + + std::shared_ptr data = std::shared_ptr( ( unsigned char* ) malloc( BN_num_bytes( serial.get() ) + 20 ), free ); + int len = BN_bn2bin( serial.get(), data.get() ); -std::shared_ptr SimpleOpensslSigner::caKey = loadPkeyFromFile( "assured.key" ); + data.get()[len] = 0x0; + data.get()[len + 1] = 0x0; // signer id + + data.get()[len + 2] = profile >> 8; + data.get()[len + 3] = profile & 0xFF; // profile id + + if( !RAND_bytes( data.get() + len + 4, 16 ) || !BN_add_word( serial.get(), 1 ) ) { + throw "Big number math failed while calcing serials."; + } + + std::shared_ptr serStr = std::shared_ptr( + BN_bn2hex( serial.get() ), + []( char* ref ) { + OPENSSL_free( ref ); + } ); + writeFile( "serial", serStr.get() ); + + return std::shared_ptr( BN_bin2bn( data.get(), len + 4 + 16 , 0 ), BN_free ); +} std::shared_ptr SimpleOpensslSigner::sign( std::shared_ptr cert ) { if( !caKey ) { throw "CA-key not found"; } - std::shared_ptr req = X509Req::parse( cert->csr_content ); + std::shared_ptr req; + + if( cert->csr_type == "SPKAC" ) { + req = X509Req::parseSPKAC( cert->csr_content ); + } else if( cert->csr_type == "CSR" ) { + req = X509Req::parseCSR( cert->csr_content ); + } else { + throw "Error, unknown REQ rype " + ( cert->csr_type ); + } int i = req->verify(); @@ -92,15 +149,46 @@ std::shared_ptr SimpleOpensslSigner::sign( std::shared_ptr a : cert->AVAs ) { + if( a->name == "CN" ) { + c.addRDN( NID_commonName, a->value ); + } else if( a->name == "EMAIL" ) { + c.addRDN( NID_pkcs9_emailAddress, a->value ); + } else if( a->name == "C" ) { + c.addRDN( NID_countryName, a->value ); + } else if( a->name == "L" ) { + c.addRDN( NID_localityName, a->value ); + } else if( a->name == "ST" ) { + c.addRDN( NID_stateOrProvinceName, a->value ); + } else if( a->name == "O" ) { + c.addRDN( NID_organizationName, a->value ); + } else if( a->name == "OU" ) { + c.addRDN( NID_organizationalUnitName, a->value ); + } else { + throw "unknown AVA-type"; + } + } + c.setIssuerNameFrom( caCert ); c.setPubkeyFrom( req ); - c.setSerialNumber( 4711 ); + long int profile = strtol( cert->profile.c_str(), 0, 10 ); + + if( profile > 0xFFFF || profile < 0 || ( profile == 0 && cert->profile != "0" ) ) { + throw "invalid profile id"; + } + + std::shared_ptr ser = nextSerial( profile ); + c.setSerialNumber( ser.get() ); c.setTimes( 0, 60 * 60 * 24 * 10 ); c.setExtensions( caCert, cert->SANs ); - std::string output = c.sign( caKey ); - - std::shared_ptr output = c.sign( caKey ); + std::shared_ptr output = c.sign( caKey, cert->md ); return output; }