]> WPIA git - cassiopeia.git/blob - src/simpleOpensslSigner.cpp
chg: Split off X509-related API
[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 std::shared_ptr<int> SimpleOpensslSigner::lib_ref(
15     new int( SSL_library_init() ),
16     []( int* ref ) {
17         ( void ) ref;
18     } );
19
20 std::shared_ptr<X509> loadX509FromFile( std::string filename ) {
21     FILE* f = fopen( filename.c_str(), "r" );
22
23     if( !f ) {
24         return std::shared_ptr<X509>();
25     }
26
27     X509* key = PEM_read_X509( f, NULL, NULL, 0 );
28     fclose( f );
29
30     if( !key ) {
31         return std::shared_ptr<X509>();
32     }
33
34     return std::shared_ptr<X509>(
35         key,
36         []( X509 * ref ) {
37             X509_free( ref );
38         } );
39 }
40
41 std::shared_ptr<EVP_PKEY> loadPkeyFromFile( std::string filename ) {
42     FILE* f = fopen( filename.c_str(), "r" );
43
44     if( !f ) {
45         return std::shared_ptr<EVP_PKEY>();
46     }
47
48     EVP_PKEY* key = PEM_read_PrivateKey( f, NULL, NULL, 0 );
49     fclose( f );
50
51     if( !key ) {
52         return std::shared_ptr<EVP_PKEY>();
53     }
54
55     return std::shared_ptr<EVP_PKEY>(
56         key,
57         []( EVP_PKEY * ref ) {
58             EVP_PKEY_free( ref );
59         } );
60 }
61
62 std::shared_ptr<X509> SimpleOpensslSigner::caCert = loadX509FromFile( "assured.crt" );
63
64 std::shared_ptr<EVP_PKEY> SimpleOpensslSigner::caKey = loadPkeyFromFile( "assured.key" );
65
66 void SimpleOpensslSigner::sign( std::shared_ptr<TBSCertificate> cert ) {
67     if( !caKey ) {
68         throw "CA-key not found";
69     }
70
71     std::shared_ptr<X509Req> req = X509Req::parse( cert->csr_content );
72
73     int i = req->verify();
74
75     if( i < 0 ) {
76         throw "Signature problems ... ";
77     } else if( i == 0 ) {
78         throw "Signature did not match";
79     } else {
80         std::cerr << "Signature ok" << std::endl;
81     }
82
83     // Construct the Certificate
84     X509Cert c = X509Cert();
85     std::shared_ptr<X509> retsh = std::shared_ptr<X509>( X509_new(), X509_free );
86     X509* ret = retsh.get();
87
88     if( !ret ) {
89         throw "Creating X509 failed.";
90     }
91
92     c.setIssuerNameFrom( caCert );
93     c.setPubkeyFrom( req );
94     c.setSerialNumber( 4711 );
95     c.setTimes( 0, 1000 * 60 * 60 * 24 * 10 );
96     c.setExtensions( caCert );
97
98     std::string output = c.sign( caKey );
99
100     std::cout << "Certificate:" << std::endl << output << std::endl;
101 }