]> WPIA git - cassiopeia.git/blob - src/remoteSigner.cpp
5d049034b5dc59e9511bb87596f9a2b1324a2f60
[cassiopeia.git] / src / remoteSigner.cpp
1 #include "remoteSigner.h"
2
3 #include <iostream>
4
5 RemoteSigner::RemoteSigner( std::shared_ptr<BIO> target, std::shared_ptr<SSL_CTX> ctx ) {
6     this->target = target;
7     this->ctx = ctx;
8 }
9 RemoteSigner::~RemoteSigner() {
10 }
11
12 void RemoteSigner::send( std::shared_ptr<OpensslBIOWrapper> bio, RecordHeader& head, RecordHeader::SignerCommand cmd, std::string data ) {
13     head.command = ( uint16_t ) cmd;
14     head.command_count++;
15     head.totalLength = data.size();
16     sendCommand( head, data, bio );
17
18 }
19
20 std::shared_ptr<SignedCertificate> RemoteSigner::sign( std::shared_ptr<TBSCertificate> cert ) {
21     std::shared_ptr<SSL> ssl( SSL_new( ctx.get() ), SSL_free );
22     std::shared_ptr<BIO> bio( BIO_new( BIO_f_ssl() ), BIO_free );
23     SSL_set_connect_state( ssl.get() );
24     SSL_set_bio( ssl.get(), target.get(), target.get() );
25     BIO_set_ssl( bio.get(), ssl.get(), BIO_NOCLOSE );
26     std::shared_ptr<OpensslBIOWrapper> conn( new OpensslBIOWrapper( bio ) );
27     RecordHeader head;
28     head.flags = 0;
29     head.sessid = 13;
30
31     if( cert->csr_type == "CSR" ) {
32         send( conn, head, RecordHeader::SignerCommand::SET_CSR, cert->csr_content );
33     } else {
34         std::cout << "Unknown csr_type: " << cert->csr_type;
35         return std::shared_ptr<SignedCertificate>();
36     }
37
38     send( conn, head, RecordHeader::SignerCommand::SET_SIGNATURE_TYPE, cert->md );
39     send( conn, head, RecordHeader::SignerCommand::SET_PROFILE, cert->profile );
40
41     for( auto ava : cert->AVAs ) {
42         if( ava->name.find( "," ) != std::string::npos ) {
43             // invalid ava
44             return std::shared_ptr<SignedCertificate>();
45         }
46
47         send( conn, head, RecordHeader::SignerCommand::ADD_AVA, ava->name + "," + ava->value );
48     }
49
50     for( auto san : cert->SANs ) {
51         if( san->type.find( "," ) != std::string::npos ) {
52             // invalid ava
53             return std::shared_ptr<SignedCertificate>();
54         }
55
56         send( conn, head, RecordHeader::SignerCommand::ADD_SAN, san->type + "," + san->content );
57     }
58
59     send( conn, head, RecordHeader::SignerCommand::SIGN, "" );
60     send( conn, head, RecordHeader::SignerCommand::LOG_SAVED, "" );
61     std::shared_ptr<SignedCertificate> result = std::shared_ptr<SignedCertificate>( new SignedCertificate() );
62     std::vector<char> buffer( 2048 * 4 );
63
64     for( int i = 0; i < 2; i++ ) {
65         try {
66             int length = conn->read( buffer.data(), buffer.size() );
67             RecordHeader head;
68             std::string payload = parseCommand( head, std::string( buffer.data(), length ) );
69
70             switch( ( RecordHeader::SignerResult ) head.command ) {
71             case RecordHeader::SignerResult::CERTIFICATE:
72                 result->certificate = payload;
73                 break;
74
75             case RecordHeader::SignerResult::SAVE_LOG:
76                 result->log = payload;
77                 break;
78             }
79         } catch( const char* msg ) {
80             std::cout << msg << std::endl;
81             return std::shared_ptr<SignedCertificate>();
82         }
83     }
84
85     return result;
86 }
87