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");
20 if( ! BN_hex2bn( &serBN, serial.c_str() ) ) {
21 throw std::runtime_error("hex2bn malloc fail");
24 std::shared_ptr<BIGNUM> serBNP( serBN, BN_free );
25 std::shared_ptr<ASN1_INTEGER> ser( BN_to_ASN1_INTEGER( serBN, NULL ), ASN1_INTEGER_free );
28 throw std::runtime_error("BN Malloc fail");
31 logger::note("building current time");
32 std::shared_ptr<ASN1_TIME> tmptm( ASN1_TIME_new(), ASN1_TIME_free );
35 throw std::runtime_error("ASN1-Time Malloc fail");
38 X509_gmtime_adj( tmptm.get(), 0 );
40 logger::note("creating entry");
41 X509_REVOKED* rev = X509_REVOKED_new();
42 X509_REVOKED_set_serialNumber( rev, ser.get() );
45 ASN1_TIME_set_string( tmptm.get(), time.data() );
47 X509_REVOKED_set_revocationDate( rev, tmptm.get() );
49 X509_CRL_add0_revoked( crl.get(), rev );
51 int len = i2d_ASN1_TIME( tmptm.get(), NULL );
52 unsigned char* buffer = ( unsigned char* ) OPENSSL_malloc( len );
53 unsigned char* pos = buffer;
54 i2d_ASN1_TIME( tmptm.get(), &pos );
55 std::string rettime = std::string( ( char* ) buffer, len );
56 OPENSSL_free( buffer );
60 void CRL::sign( std::shared_ptr<CAConfig> ca ) {
61 // Updating necessary CRL props
62 std::shared_ptr<ASN1_TIME> tmptm( ASN1_TIME_new(), ASN1_TIME_free );
65 throw std::runtime_error("ASN1-Time Malloc fail");
68 X509_gmtime_adj( tmptm.get(), 0 );
70 logger::note("setting issuer");
71 if( !X509_CRL_set_issuer_name( crl.get(), X509_get_subject_name( ca->ca.get() ) ) ) {
72 throw std::runtime_error("Setting issuer failed");
75 logger::note("setting update");
76 X509_CRL_set_lastUpdate( crl.get(), tmptm.get() );
78 if( !X509_time_adj_ex( tmptm.get(), 1, 10, NULL ) ) {
79 throw std::runtime_error("Updating time failed");
82 logger::note("setting next update");
83 X509_CRL_set_nextUpdate( crl.get(), tmptm.get() );
85 logger::note("sorting");
86 // Sorting and signing
87 X509_CRL_sort( crl.get() );
88 logger::note("signing");
89 X509_CRL_sign( crl.get(), ca->caKey.get(), EVP_sha256() );
92 bool CRL::verify( std::shared_ptr<CAConfig> ca ) {
93 std::shared_ptr<EVP_PKEY> pk( X509_get_pubkey( ca->ca.get() ), EVP_PKEY_free );
94 return X509_CRL_verify( crl.get(), pk.get() ) > 0;
97 std::string CRL::toString() {
98 // Write out the new CRL
99 std::shared_ptr<BIO> mem( BIO_new( BIO_s_mem() ), BIO_free );
100 PEM_write_bio_X509_CRL( mem.get(), crl.get() );
102 BIO_get_mem_ptr( mem.get(), &bptr );
103 std::string newCRL( bptr->data, bptr->length );
107 std::string CRL::getSignature() {
108 const X509_ALGOR *palg;
109 const ASN1_BIT_STRING *psig;
111 X509_CRL_get0_signature(crl.get(), &psig, &palg);
112 int len = i2d_X509_ALGOR( const_cast<X509_ALGOR*>(palg), NULL );
113 len += i2d_ASN1_BIT_STRING( const_cast<ASN1_BIT_STRING*>(psig), NULL );
114 len += i2d_ASN1_TIME( const_cast<ASN1_TIME*>(X509_CRL_get0_lastUpdate(crl.get())), NULL );
115 len += i2d_ASN1_TIME( const_cast<ASN1_TIME*>(X509_CRL_get0_nextUpdate(crl.get())), NULL );
117 unsigned char* buffer = ( unsigned char* ) OPENSSL_malloc( len );
118 unsigned char* pos = buffer;
119 i2d_X509_ALGOR( const_cast<X509_ALGOR*>(palg), &pos );
120 i2d_ASN1_BIT_STRING( const_cast<ASN1_BIT_STRING*>(psig), &pos );
121 i2d_ASN1_TIME( const_cast<ASN1_TIME*>(X509_CRL_get0_lastUpdate(crl.get())), &pos );
122 i2d_ASN1_TIME( const_cast<ASN1_TIME*>(X509_CRL_get0_nextUpdate(crl.get())), &pos );
123 std::string res = std::string( ( char* ) buffer, len );
124 OPENSSL_free( buffer );
129 void CRL::setSignature( std::string signature ) {
130 X509_CRL_sort( crl.get() );
132 ASN1_BIT_STRING *psig;
133 // this is not intended use of the OPENSSL-API but API-limitations leave us with no other options.
134 X509_CRL_get0_signature(crl.get(), const_cast<const ASN1_BIT_STRING **>(&psig), const_cast<const X509_ALGOR**>(&palg));
136 const unsigned char* data = ( unsigned char* )( signature.data() );
137 const unsigned char* buffer = data;
138 X509_ALGOR *alg = d2i_X509_ALGOR( NULL, &buffer, signature.size() );
139 ASN1_BIT_STRING *sig = d2i_ASN1_BIT_STRING( NULL, &buffer, signature.size() + data - buffer );
140 ASN1_TIME *a1 = d2i_ASN1_TIME( NULL, &buffer, signature.size() + data - buffer );
141 ASN1_TIME *a2 = d2i_ASN1_TIME( NULL, &buffer, signature.size() + data - buffer );
142 std::swap(*palg, *alg);
143 std::swap(*psig, *sig);
144 X509_CRL_set1_lastUpdate( crl.get(), a1);
145 X509_CRL_set1_nextUpdate( crl.get(), a2);
147 X509_ALGOR_free(alg);
148 ASN1_BIT_STRING_free(sig);
153 bool CRL::needsResign() {
156 current += 60 * 60;// 1 hour
157 auto time = X509_CRL_get0_nextUpdate( crl.get() );
163 int cmp = X509_cmp_time( time, ¤t );