]> WPIA git - cassiopeia.git/blob - src/sslUtil.cpp
add: Plug things together so we can have TBSCertificates from the database
[cassiopeia.git] / src / sslUtil.cpp
1 #include "sslUtil.h"
2
3 #include <sys/types.h>
4 #include <termios.h>
5 #include <unistd.h>
6 #include <iostream>
7
8 std::shared_ptr<int> ssl_lib_ref(
9     new int( SSL_library_init() ),
10     []( int* ref ) {
11         delete ref;
12
13         EVP_cleanup();
14         CRYPTO_cleanup_all_ex_data();
15     } );
16
17 int gencb( int a, int b, BN_GENCB* g ) {
18     ( void ) a;
19     ( void ) b;
20     ( void ) g;
21     std::cout << ( a == 0 ? "." : "+" ) << std::flush;
22     return 1;
23 }
24
25 static int verify_callback( int preverify_ok, X509_STORE_CTX* ctx ) {
26     if( !preverify_ok ) {
27         //auto cert = X509_STORE_CTX_get_current_cert(ctx);
28         //BIO *o = BIO_new_fp(stdout,BIO_NOCLOSE);
29         //X509_print_ex(o, cert, XN_FLAG_COMPAT, X509_FLAG_COMPAT);
30         //BIO_free(o);
31
32         std::cout << "Verification failed: " << preverify_ok << " because " << X509_STORE_CTX_get_error( ctx ) << std::endl;
33     }
34
35     return preverify_ok;
36 }
37
38 static std::shared_ptr<DH> dh_param;
39
40 std::shared_ptr<SSL_CTX> generateSSLContext( bool server ) {
41     std::shared_ptr<SSL_CTX> ctx = std::shared_ptr<SSL_CTX>( SSL_CTX_new( TLSv1_2_method() ), []( SSL_CTX * p ) {
42         SSL_CTX_free( p );
43     } );
44
45     if( !SSL_CTX_set_cipher_list( ctx.get(), "HIGH:+CAMELLIA256:!eNull:!aNULL:!ADH:!MD5:-RSA+AES+SHA1:!RC4:!DES:!3DES:!SEED:!EXP:!AES128:!CAMELLIA128" ) ) {
46         throw "Cannot set cipher list. Your source is broken.";
47     }
48
49     SSL_CTX_set_verify( ctx.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, verify_callback );
50     SSL_CTX_use_certificate_file( ctx.get(), server ? "keys/signer_server.crt" : "keys/signer_client.crt", SSL_FILETYPE_PEM );
51     SSL_CTX_use_PrivateKey_file( ctx.get(), server ? "keys/signer_server.key" : "keys/signer_client.key", SSL_FILETYPE_PEM );
52     SSL_CTX_load_verify_locations( ctx.get(), "keys/ca.crt", 0 );
53
54     if( server ) {
55         STACK_OF( X509_NAME ) *names = SSL_load_client_CA_file( "keys/env.crt" );
56
57         if( names ) {
58             SSL_CTX_set_client_CA_list( ctx.get(), names );
59         } else {
60             // error
61         }
62
63         if( !dh_param ) {
64             FILE* paramfile = fopen( "dh_param.pem", "r" );
65
66             if( paramfile ) {
67                 dh_param = std::shared_ptr<DH>( PEM_read_DHparams( paramfile, NULL, NULL, NULL ), DH_free );
68                 fclose( paramfile );
69             } else {
70                 dh_param = std::shared_ptr<DH>( DH_new(), DH_free );
71                 std::cout << "Generating DH params" << std::endl;
72                 BN_GENCB cb;
73                 cb.ver = 2;
74                 cb.arg = 0;
75                 cb.cb.cb_2 = gencb;
76
77                 if( !DH_generate_parameters_ex( dh_param.get(), 2048, 5, &cb ) ) {
78                     throw "DH generation failed";
79                 }
80
81                 std::cout << std::endl;
82                 paramfile = fopen( "dh_param.pem", "w" );
83
84                 if( paramfile ) {
85                     PEM_write_DHparams( paramfile, dh_param.get() );
86                     fclose( paramfile );
87                 }
88             }
89         }
90
91         if( !SSL_CTX_set_tmp_dh( ctx.get(), dh_param.get() ) ) {
92             throw "Cannot set tmp dh.";
93         }
94     }
95
96     return ctx;
97 }
98
99 void setupSerial( FILE* f ) {
100     struct termios attr;
101
102     if( tcgetattr( fileno( f ), &attr ) ) {
103         throw "failed to get attrs";
104     }
105
106     attr.c_iflag &= ~( IGNBRK | BRKINT | PARMRK | ISTRIP
107                        | INLCR | IGNCR | ICRNL | IXON );
108     attr.c_oflag &= ~OPOST;
109     attr.c_lflag &= ~( ECHO | ECHONL | ICANON | ISIG | IEXTEN );
110     attr.c_cflag &= ~( CSIZE | PARENB );
111     attr.c_cflag |= CS8;
112
113     cfsetispeed( &attr, B115200 );
114     cfsetospeed( &attr, B115200 );
115
116     if( tcsetattr( fileno( f ), TCSANOW, &attr ) ) {
117         throw "failed to get attrs";
118     }
119 }
120
121 std::shared_ptr<BIO> openSerial( const char* name ) {
122     FILE* f = fopen( name, "r+" );
123
124     if( !f ) {
125         std::cout << "Opening serial device failed" << std::endl;
126         return std::shared_ptr<BIO>();
127     }
128
129     setupSerial( f );
130
131     std::shared_ptr<BIO> b( BIO_new_fd( fileno( f ), 0 ), BIO_free );
132     return b;
133 }