]> WPIA git - cassiopeia.git/blob - src/crypto/CRL.cpp
chg: Replace ASN1_UTCTIME by ASN1_TIME
[cassiopeia.git] / src / crypto / CRL.cpp
1 #include "CRL.h"
2
3 #include <openssl/ssl.h>
4
5 CRL::CRL( std::string path ) {
6     std::shared_ptr<BIO> bio( BIO_new_file( path.c_str(), "r" ), free );
7     crl = std::shared_ptr<X509_CRL>( PEM_read_bio_X509_CRL( bio.get(), 0, NULL, 0 ), X509_CRL_free );
8
9     if( !crl ) {
10         crl = std::shared_ptr<X509_CRL>( X509_CRL_new(), X509_CRL_free );
11     }
12 }
13
14 std::string CRL::revoke( std::string serial, std::string time ) {
15     BIGNUM* serBN = 0;
16
17     if( ! BN_hex2bn( &serBN, serial.c_str() ) ) {
18         throw "hex2bn malloc fail";
19     }
20
21     std::shared_ptr<BIGNUM> serBNP( serBN, BN_free );
22     std::shared_ptr<ASN1_INTEGER> ser( BN_to_ASN1_INTEGER( serBN, NULL ), ASN1_INTEGER_free );
23
24     if( !ser ) {
25         throw "BN Malloc fail";
26     }
27
28     std::shared_ptr<ASN1_TIME> tmptm( ASN1_TIME_new(), ASN1_TIME_free );
29
30     if( !tmptm ) {
31         throw "ASN1-Time Malloc fail";
32     }
33
34     X509_gmtime_adj( tmptm.get(), 0 );
35
36     X509_REVOKED* rev = X509_REVOKED_new();
37     X509_REVOKED_set_serialNumber( rev, ser.get() );
38
39     if( time != "" ) {
40         const unsigned char* data = ( unsigned char* )( time.data() );
41         d2i_ASN1_TIME( &rev->revocationDate, &data, time.size() );
42     } else {
43         X509_REVOKED_set_revocationDate( rev, tmptm.get() );
44     }
45
46     X509_CRL_add0_revoked( crl.get(), rev );
47
48     int len = i2d_ASN1_TIME( tmptm.get(), NULL );
49     unsigned char* buffer = ( unsigned char* ) OPENSSL_malloc( len );
50     unsigned char* pos = buffer;
51     i2d_ASN1_TIME( tmptm.get(), &pos );
52     std::string rettime = std::string( ( char* ) buffer, len );
53     OPENSSL_free( buffer );
54     return rettime;
55 }
56
57 void CRL::sign( std::shared_ptr<CAConfig> ca ) {
58     // Updating necessary CRL props
59     std::shared_ptr<ASN1_TIME> tmptm( ASN1_TIME_new(), ASN1_TIME_free );
60
61     if( !tmptm ) {
62         throw "ASN1-Time Malloc fail";
63     }
64
65     X509_gmtime_adj( tmptm.get(), 0 );
66
67     if( !X509_CRL_set_issuer_name( crl.get(), X509_get_subject_name( ca->ca.get() ) ) ) {
68         throw "Setting issuer failed";
69     }
70
71     X509_CRL_set_lastUpdate( crl.get(), tmptm.get() );
72
73     if( !X509_time_adj_ex( tmptm.get(), 1, 10, NULL ) ) {
74         throw "Updating time failed";
75     }
76
77     X509_CRL_set_nextUpdate( crl.get(), tmptm.get() );
78
79     // Sorting and signing
80     X509_CRL_sort( crl.get() );
81     X509_CRL_sign( crl.get(), ca->caKey.get(), EVP_sha256() );
82 }
83
84 bool CRL::verify( std::shared_ptr<CAConfig> ca ) {
85     std::shared_ptr<EVP_PKEY> pk( X509_get_pubkey( ca->ca.get() ), EVP_PKEY_free );
86     return X509_CRL_verify( crl.get(), pk.get() ) > 0;
87 }
88
89 std::string CRL::toString() {
90     // Write out the new CRL
91     std::shared_ptr<BIO> mem( BIO_new( BIO_s_mem() ), BIO_free );
92     PEM_write_bio_X509_CRL( mem.get(), crl.get() );
93     BUF_MEM* bptr;
94     BIO_get_mem_ptr( mem.get(), &bptr );
95     std::string newCRL( bptr->data, bptr->length );
96     return newCRL;
97 }
98
99 std::string CRL::getSignature() {
100     int len = i2d_X509_ALGOR( crl->sig_alg, NULL );
101     len += i2d_ASN1_BIT_STRING( crl->signature, NULL );
102     len += i2d_ASN1_TIME( crl->crl->lastUpdate, NULL );
103     len += i2d_ASN1_TIME( crl->crl->nextUpdate, NULL );
104
105     unsigned char* buffer = ( unsigned char* ) OPENSSL_malloc( len );
106     unsigned char* pos = buffer;
107     i2d_X509_ALGOR( crl->sig_alg, &pos );
108     i2d_ASN1_BIT_STRING( crl->signature, &pos );
109     i2d_ASN1_TIME( crl->crl->lastUpdate, &pos );
110     i2d_ASN1_TIME( crl->crl->nextUpdate, &pos );
111     std::string res = std::string( ( char* ) buffer, len );
112     OPENSSL_free( buffer );
113
114     return res;
115 }
116
117 void CRL::setSignature( std::string signature ) {
118     const unsigned char* data = ( unsigned char* )( signature.data() );
119     const unsigned char* buffer = data;
120     d2i_X509_ALGOR( &crl->sig_alg, &buffer, signature.size() );
121     d2i_ASN1_BIT_STRING( &crl->signature, &buffer, signature.size() + data - buffer );
122     d2i_ASN1_TIME( &crl->crl->lastUpdate, &buffer, signature.size() + data - buffer );
123     d2i_ASN1_TIME( &crl->crl->nextUpdate, &buffer, signature.size() + data - buffer );
124 }