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 );
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;
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 );
}
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;
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() ) );
}
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";
}
}
}
- 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;
}
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();
}
setupSerial( f );
-
std::shared_ptr<BIO> b( BIO_new_fd( fileno( f ), 0 ), BIO_free );
return b;
}
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 );
}
#include <openssl/ssl.h>
#include <memory>
#include <string>
+#include <vector>
#include <cinttypes>
class CAConfig {
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;
std::string certHash;
std::string crt_name;
std::string log;
+ std::string ca_name;
};
class JobProvider {
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;
};
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] ) );
+}
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 );
};