1 #include "recordHandler.h"
4 #include <sys/socket.h>
5 #include <netinet/in.h>
12 #include <openssl/ssl.h>
16 #include "opensslBIO.h"
17 #include "remoteSigner.h"
18 #include "simpleOpensslSigner.h"
22 extern std::vector<Profile> profiles;
24 class RecordHandlerSession {
27 uint32_t lastCommandCount;
29 std::shared_ptr<TBSCertificate> tbs;
30 std::shared_ptr<SignedCertificate> result;
32 std::shared_ptr<SSL> ssl;
34 std::shared_ptr<OpensslBIOWrapper> io;
35 DefaultRecordHandler* parent;
36 std::shared_ptr<Signer> signer;
38 RecordHandlerSession( DefaultRecordHandler* parent, std::shared_ptr<Signer> signer, std::shared_ptr<SSL_CTX> ctx, std::shared_ptr<BIO> output ) :
39 tbs( new TBSCertificate() ) {
40 this->parent = parent;
41 this->signer = signer;
43 ssl = std::shared_ptr<SSL>( SSL_new( ctx.get() ), SSL_free );
44 std::shared_ptr<BIO> bio(
45 BIO_new( BIO_f_ssl() ),
49 SSL_set_accept_state( ssl.get() );
50 SSL_set_bio( ssl.get(), output.get(), output.get() );
51 BIO_set_ssl( bio.get(), ssl.get(), BIO_NOCLOSE );
52 io = std::shared_ptr<OpensslBIOWrapper>( new OpensslBIOWrapper( bio ) );
55 void respondCommand( RecordHeader::SignerResult res, std::string payload ) {
57 rh.command = ( uint16_t ) res;
59 rh.command_count = 0; // TODO i++
60 rh.totalLength = payload.size();
61 sendCommand( rh, payload, io );
65 std::vector<char> buffer( 2048, 0 );
66 int res = io->read( buffer.data(), buffer.capacity() );
73 std::string content( buffer.data(), res );
77 std::string payload = parseCommand( head, content );
78 execute( head, payload );
79 } catch( const char* msg ) {
80 std::cout << msg << std::endl;
86 void execute( RecordHeader& head, std::string data ) {
87 if( head.totalLength != head.payloadLength || head.offset != 0 ) {
88 throw "Error, chunking not supported yet";
91 switch( ( RecordHeader::SignerCommand ) head.command ) {
92 case RecordHeader::SignerCommand::SET_CSR: // setCSR
93 tbs->csr_content = data;
94 tbs->csr_type = "CSR";
95 std::cout << "CSR read" << std::endl;
98 case RecordHeader::SignerCommand::SET_SIGNATURE_TYPE:
102 case RecordHeader::SignerCommand::SET_PROFILE:
107 case RecordHeader::SignerCommand::ADD_SAN: {
108 size_t pos = data.find( "," );
110 if( pos == std::string::npos ) {
112 std::shared_ptr<SAN> san( new SAN() );
113 san->type = data.substr( 0, pos );
114 san->content = data.substr( pos + 1 );
115 tbs->SANs.push_back( san );
120 case RecordHeader::SignerCommand::ADD_AVA: {
121 size_t pos = data.find( "," );
123 if( pos == std::string::npos ) {
126 std::shared_ptr<AVA> ava( new AVA() );
127 ava->name = data.substr( 0, pos );
128 ava->value = data.substr( pos + 1 );
129 tbs->AVAs.push_back( ava );
134 case RecordHeader::SignerCommand::ADD_PROOF_LINE:
137 case RecordHeader::SignerCommand::SIGN:
138 result = signer->sign( tbs );
139 std::cout << "res: " << result->certificate << std::endl;
140 result->log = "I am a dummy log.\nI signed that thing ;-) \n";
141 respondCommand( RecordHeader::SignerResult::SAVE_LOG, result->log );
144 case RecordHeader::SignerCommand::LOG_SAVED:
146 respondCommand( RecordHeader::SignerResult::CERTIFICATE, result->certificate );
149 if( !SSL_shutdown( ssl.get() ) && !SSL_shutdown( ssl.get() ) ) {
150 std::cout << "SSL close failed" << std::endl;
156 throw "Unimplemented";
161 DefaultRecordHandler::DefaultRecordHandler( std::shared_ptr<Signer> signer, std::shared_ptr<BIO> bio ) :
164 this->signer = signer;
166 ctx = generateSSLContext( true );
171 void DefaultRecordHandler::reset() {
172 currentSession = std::shared_ptr<RecordHandlerSession>();
175 void DefaultRecordHandler::handle() {
176 if( !currentSession ) {
177 std::cout << "session allocated" << std::endl;
178 currentSession = std::shared_ptr<RecordHandlerSession>( new RecordHandlerSession( this, signer, ctx, bio ) );
181 currentSession->work();