]> WPIA git - cassiopeia.git/blob - src/simpleOpensslSigner.cpp
fmt: Reorganizing includes
[cassiopeia.git] / src / simpleOpensslSigner.cpp
1 #include "simpleOpensslSigner.h"
2
3 #include <iostream>
4
5 #include <openssl/ssl.h>
6 #include <openssl/err.h>
7 #include <openssl/bio.h>
8 #include <openssl/bn.h>
9 #include <openssl/engine.h>
10 #include <openssl/x509v3.h>
11
12 #include "X509.h"
13
14 extern std::vector<Profile> profiles;
15
16 std::shared_ptr<int> SimpleOpensslSigner::lib_ref(
17     new int( SSL_library_init() ),
18     []( int* ref ) {
19         delete ref;
20
21         EVP_cleanup();
22         CRYPTO_cleanup_all_ex_data();
23     } );
24
25 std::shared_ptr<X509> loadX509FromFile( std::string filename ) {
26     FILE* f = fopen( filename.c_str(), "r" );
27
28     if( !f ) {
29         return std::shared_ptr<X509>();
30     }
31
32     X509* key = PEM_read_X509( f, NULL, NULL, 0 );
33     fclose( f );
34
35     if( !key ) {
36         return std::shared_ptr<X509>();
37     }
38
39     return std::shared_ptr<X509>(
40         key,
41         []( X509 * ref ) {
42             X509_free( ref );
43         } );
44 }
45
46 std::shared_ptr<EVP_PKEY> loadPkeyFromFile( std::string filename ) {
47     FILE* f = fopen( filename.c_str(), "r" );
48
49     if( !f ) {
50         return std::shared_ptr<EVP_PKEY>();
51     }
52
53     EVP_PKEY* key = PEM_read_PrivateKey( f, NULL, NULL, 0 );
54     fclose( f );
55
56     if( !key ) {
57         return std::shared_ptr<EVP_PKEY>();
58     }
59
60     return std::shared_ptr<EVP_PKEY>(
61         key,
62         []( EVP_PKEY * ref ) {
63             EVP_PKEY_free( ref );
64         } );
65 }
66
67 SimpleOpensslSigner::SimpleOpensslSigner() {
68     caCert = loadX509FromFile( profiles[0].cert );
69     caKey = loadPkeyFromFile( profiles[0].key );
70 }
71
72 int serial = 10;
73
74 std::shared_ptr<SignedCertificate> SimpleOpensslSigner::sign( std::shared_ptr<TBSCertificate> cert ) {
75     if( !caKey ) {
76         throw "CA-key not found";
77     }
78
79     std::shared_ptr<X509Req> req;
80
81     if( cert->csr_type == "SPKAC" ) {
82         req = X509Req::parseSPKAC( cert->csr_content );
83     } else if( cert->csr_type == "CSR" ) {
84         req = X509Req::parse( cert->csr_content );
85     } else {
86         throw "Error, unknown REQ rype " + ( cert->csr_type );
87     }
88
89     int i = req->verify();
90
91     if( i < 0 ) {
92         throw "Signature problems ... ";
93     } else if( i == 0 ) {
94         throw "Signature did not match";
95     } else {
96         std::cerr << "Signature ok" << std::endl;
97     }
98
99     // Construct the Certificate
100     X509Cert c = X509Cert();
101     std::shared_ptr<X509> retsh = std::shared_ptr<X509>( X509_new(), X509_free );
102     X509* ret = retsh.get();
103
104     if( !ret ) {
105         throw "Creating X509 failed.";
106     }
107
108     c.setIssuerNameFrom( caCert );
109     c.setPubkeyFrom( req );
110     c.setSerialNumber( serial++ );
111     c.setTimes( 0, 60 * 60 * 24 * 10 );
112     c.setExtensions( caCert, cert->SANs );
113
114     std::shared_ptr<SignedCertificate> output = c.sign( caKey );
115
116     return output;
117 }