send( conn, head, RecordHeader::SignerCommand::SET_SIGNATURE_TYPE, cert->md );
send( conn, head, RecordHeader::SignerCommand::SET_PROFILE, cert->profile );
+ send( conn, head, RecordHeader::SignerCommand::SET_WISH_FROM, cert->wishFrom );
+ send( conn, head, RecordHeader::SignerCommand::SET_WISH_TO, cert->wishTo );
for( auto ava : cert->AVAs ) {
if( ava->name.find( "," ) != std::string::npos ) {
std::shared_ptr<SignedCertificate> result = std::shared_ptr<SignedCertificate>( new SignedCertificate() );
std::vector<char> buffer( 2048 * 4 );
- for( int i = 0; i < 2; i++ ) {
+ for( int i = 0; i < 3; i++ ) {
try {
int length = conn->read( buffer.data(), buffer.size() );
result->log = payload;
break;
+ case RecordHeader::SignerResult::SIGNING_CA:
+ result->ca_name = payload;
+ break;
+
default:
std::cout << "Invalid Message" << std::endl;
break;
[]( char* p ) {
OPENSSL_free( p );
} ); // OPENSSL_free is a macro...
+
+ extractTimes( pem, result );
+
result->serial = std::string( serStr.get() );
}
return result;
}
-std::shared_ptr<CRL> RemoteSigner::revoke( std::shared_ptr<CAConfig> ca, std::string serial ) {
+std::pair<std::shared_ptr<CRL>, std::string> RemoteSigner::revoke( std::shared_ptr<CAConfig> ca, std::vector<std::string> serials ) {
( void )BIO_reset( target.get() );
std::shared_ptr<SSL> ssl( SSL_new( ctx.get() ), SSL_free );
head.flags = 0;
head.sessid = 13;
- std::string payload = ca->name + std::string( "\0", 1 ) + serial;
+ for( std::string serial : serials ) {
+ send( conn, head, RecordHeader::SignerCommand::ADD_SERIAL, serial );
+ }
+
+ std::string payload = ca->name;
send( conn, head, RecordHeader::SignerCommand::REVOKE, payload );
std::vector<char> buffer( 2048 * 4 );
int length = conn->read( buffer.data(), buffer.size() );
if( length <= 0 ) {
- std::cout << "Error, no response data" << std::endl;
- return std::shared_ptr<CRL>();
+ throw "Error, no response data";
}
payload = parseCommand( head, std::string( buffer.data(), length ), log );
- switch( ( RecordHeader::SignerResult ) head.command ) {
- case RecordHeader::SignerResult::REVOKED:
- std::cout << "CRL: " << std::endl << payload << std::endl;
- break;
+ std::shared_ptr<CRL> crl( new CRL( ca->path + std::string( "/ca.crl" ) ) );
+ std::string date;
+
+ if( ( RecordHeader::SignerResult ) head.command != RecordHeader::SignerResult::REVOKED ) {
+ throw "Protocol violation";
+ }
+
+ const unsigned char* buffer2 = ( const unsigned char* ) payload.data();
+ const unsigned char* pos = buffer2;
+ ASN1_TIME* time = d2i_ASN1_TIME( NULL, &pos, payload.size() );
+ ASN1_TIME_free( time );
+ date = payload.substr( 0, pos - buffer2 );
+ std::string rest = payload.substr( pos - buffer2 );
+
+ for( std::string serial : serials ) {
+ crl->revoke( serial, date );
+ }
+
+ crl->setSignature( rest );
+ bool ok = crl->verify( ca );
+
+ if( ok ) {
+ ( *log ) << "CRL verificated successfully" << std::endl;
+ writeFile( ca->path + std::string( "/ca.crl" ), crl->toString() );
+ } else {
+ ( *log ) << "CRL is broken" << std::endl;
+ send( conn, head, RecordHeader::SignerCommand::GET_FULL_CRL, ca->name );
+ length = conn->read( buffer.data(), buffer.size() );
+
+ if( length <= 0 ) {
+ throw "Error, no response data";
+ }
+
+ payload = parseCommand( head, std::string( buffer.data(), length ), log );
+
+ if( ( RecordHeader::SignerResult ) head.command != RecordHeader::SignerResult::FULL_CRL ) {
+ throw "Protocol violation";
+ }
+
+ writeFile( ca->path + std::string( "/ca.crl.bak" ), payload );
+ crl = std::shared_ptr<CRL>( new CRL( ca->path + std::string( "/ca.crl.bak" ) ) );
+
+ if( crl->verify( ca ) ) {
+ writeFile( ca->path + std::string( "/ca.crl" ), crl->toString() );
+ ( *log ) << "CRL is now valid" << std::endl;
+ } else {
+ ( *log ) << "CRL is still broken... Please, help me" << std::endl;
+ }
- default:
- throw "Invalid response command.";
}
- writeFile( ca->path + "/ca.crl", payload );
+ ( *log ) << "CRL: " << std::endl << crl->toString() << std::endl;
if( !SSL_shutdown( ssl.get() ) && !SSL_shutdown( ssl.get() ) ) { // need to close the connection twice
std::cout << "SSL shutdown failed" << std::endl;
}
- return std::shared_ptr<CRL>();
+ return std::pair<std::shared_ptr<CRL>, std::string>( crl, date );
}
void RemoteSigner::setLog( std::shared_ptr<std::ostream> target ) {