3 #include <openssl/ssl.h>
4 #include <log/logger.hpp>
7 CRL::CRL( std::string path ) {
8 std::shared_ptr<BIO> bio( BIO_new_file( path.c_str(), "r" ), BIO_free );
9 crl = std::shared_ptr<X509_CRL>( PEM_read_bio_X509_CRL( bio.get(), 0, NULL, 0 ), X509_CRL_free );
12 crl = std::shared_ptr<X509_CRL>( X509_CRL_new(), X509_CRL_free );
16 std::string CRL::revoke( std::string serial, std::string time ) {
19 logger::note( "parsing serial" );
21 if( ! BN_hex2bn( &serBN, serial.c_str() ) ) {
22 throw std::runtime_error( "hex2bn malloc fail" );
25 std::shared_ptr<BIGNUM> serBNP( serBN, BN_free );
26 std::shared_ptr<ASN1_INTEGER> ser( BN_to_ASN1_INTEGER( serBN, NULL ), ASN1_INTEGER_free );
29 throw std::runtime_error( "BN Malloc fail" );
32 logger::note( "building current time" );
33 std::shared_ptr<ASN1_TIME> tmptm( ASN1_TIME_new(), ASN1_TIME_free );
36 throw std::runtime_error( "ASN1-Time Malloc fail" );
39 X509_gmtime_adj( tmptm.get(), 0 );
41 logger::note( "creating entry" );
42 X509_REVOKED* rev = X509_REVOKED_new();
43 X509_REVOKED_set_serialNumber( rev, ser.get() );
46 ASN1_TIME_set_string( tmptm.get(), time.data() );
49 X509_REVOKED_set_revocationDate( rev, tmptm.get() );
51 X509_CRL_add0_revoked( crl.get(), rev );
53 int len = i2d_ASN1_TIME( tmptm.get(), NULL );
54 unsigned char* buffer = ( unsigned char* ) OPENSSL_malloc( len );
55 unsigned char* pos = buffer;
56 i2d_ASN1_TIME( tmptm.get(), &pos );
57 std::string rettime = std::string( ( char* ) buffer, len );
58 OPENSSL_free( buffer );
62 void CRL::sign( std::shared_ptr<CAConfig> ca ) {
64 throw new std::invalid_argument( "Cannot sign CRL with CA " + ca->name + " because it has no private key." );
67 // Updating necessary CRL props
68 std::shared_ptr<ASN1_TIME> tmptm( ASN1_TIME_new(), ASN1_TIME_free );
71 throw std::runtime_error( "ASN1-Time Malloc fail" );
74 X509_gmtime_adj( tmptm.get(), 0 );
76 logger::note( "setting issuer" );
78 if( !X509_CRL_set_issuer_name( crl.get(), X509_get_subject_name( ca->ca.get() ) ) ) {
79 throw std::runtime_error( "Setting issuer failed" );
82 logger::note( "setting update" );
83 X509_CRL_set_lastUpdate( crl.get(), tmptm.get() );
85 if( !X509_time_adj_ex( tmptm.get(), 1, 10, NULL ) ) {
86 throw std::runtime_error( "Updating time failed" );
89 logger::note( "setting next update" );
90 X509_CRL_set_nextUpdate( crl.get(), tmptm.get() );
92 logger::note( "sorting" );
93 // Sorting and signing
94 X509_CRL_sort( crl.get() );
95 logger::note( "signing" );
96 X509_CRL_sign( crl.get(), ca->caKey.get(), EVP_sha256() );
99 bool CRL::verify( std::shared_ptr<CAConfig> ca ) {
100 std::shared_ptr<EVP_PKEY> pk( X509_get_pubkey( ca->ca.get() ), EVP_PKEY_free );
101 return X509_CRL_verify( crl.get(), pk.get() ) > 0;
104 std::string CRL::toString() {
105 // Write out the new CRL
106 std::shared_ptr<BIO> mem( BIO_new( BIO_s_mem() ), BIO_free );
107 PEM_write_bio_X509_CRL( mem.get(), crl.get() );
109 BIO_get_mem_ptr( mem.get(), &bptr );
110 std::string newCRL( bptr->data, bptr->length );
114 std::string CRL::getSignature() {
115 const X509_ALGOR *palg;
116 const ASN1_BIT_STRING *psig;
118 X509_CRL_get0_signature( crl.get(), &psig, &palg );
119 int len = i2d_X509_ALGOR( const_cast<X509_ALGOR*>( palg ), NULL );
120 len += i2d_ASN1_BIT_STRING( const_cast<ASN1_BIT_STRING*>( psig ), NULL );
121 len += i2d_ASN1_TIME( const_cast<ASN1_TIME*>( X509_CRL_get0_lastUpdate( crl.get() ) ), NULL );
122 len += i2d_ASN1_TIME( const_cast<ASN1_TIME*>( X509_CRL_get0_nextUpdate( crl.get() ) ), NULL );
124 unsigned char* buffer = ( unsigned char* ) OPENSSL_malloc( len );
125 unsigned char* pos = buffer;
126 i2d_X509_ALGOR( const_cast<X509_ALGOR*>( palg ), &pos );
127 i2d_ASN1_BIT_STRING( const_cast<ASN1_BIT_STRING*>( psig ), &pos );
128 i2d_ASN1_TIME( const_cast<ASN1_TIME*>( X509_CRL_get0_lastUpdate( crl.get() ) ), &pos );
129 i2d_ASN1_TIME( const_cast<ASN1_TIME*>( X509_CRL_get0_nextUpdate( crl.get() ) ), &pos );
130 std::string res = std::string( ( char* ) buffer, len );
131 OPENSSL_free( buffer );
136 void CRL::setSignature( std::string signature ) {
137 X509_CRL_sort( crl.get() );
139 ASN1_BIT_STRING *psig;
140 // this is not intended use of the OPENSSL-API but API-limitations leave us with no other options.
141 X509_CRL_get0_signature(crl.get(), const_cast<const ASN1_BIT_STRING **>(&psig), const_cast<const X509_ALGOR**>(&palg));
143 const unsigned char* data = ( unsigned char* )( signature.data() );
144 const unsigned char* buffer = data;
145 X509_ALGOR *alg = d2i_X509_ALGOR( NULL, &buffer, signature.size() );
146 ASN1_BIT_STRING *sig = d2i_ASN1_BIT_STRING( NULL, &buffer, signature.size() + data - buffer );
147 ASN1_TIME *a1 = d2i_ASN1_TIME( NULL, &buffer, signature.size() + data - buffer );
148 ASN1_TIME *a2 = d2i_ASN1_TIME( NULL, &buffer, signature.size() + data - buffer );
149 std::swap(*palg, *alg);
150 std::swap(*psig, *sig);
151 X509_CRL_set1_lastUpdate( crl.get(), a1);
152 X509_CRL_set1_nextUpdate( crl.get(), a2);
154 X509_ALGOR_free(alg);
155 ASN1_BIT_STRING_free(sig);
160 bool CRL::needsResign() {
163 current += 60 * 60;// 1 hour
164 auto time = X509_CRL_get0_nextUpdate( crl.get() );
170 int cmp = X509_cmp_time( time, ¤t );