From: Felix Dörre Date: Sat, 20 Dec 2014 00:15:18 +0000 (+0100) Subject: add: Implement SSL for serial connection X-Git-Url: https://code.wpia.club/?a=commitdiff_plain;h=2e64f805b7d03578897b4d8d2a3d3f270b6288c2;p=cassiopeia.git add: Implement SSL for serial connection --- diff --git a/src/record.h b/src/record.h index 7b8f887..03746ed 100644 --- a/src/record.h +++ b/src/record.h @@ -52,7 +52,7 @@ public: void read( std::string::iterator& it, T& val ) { char* data = ( char* ) &val; - for( int i = 0; i < sizeof( T ); i++ ) { + for( size_t i = 0; i < sizeof( T ); i++ ) { data[i] = *it; it++; } diff --git a/src/recordHandler.cpp b/src/recordHandler.cpp index 9edd683..b1c5ac4 100644 --- a/src/recordHandler.cpp +++ b/src/recordHandler.cpp @@ -1,11 +1,11 @@ #include "recordHandler.h" -#include -#include #include #include #include #include +#include +#include #include @@ -17,6 +17,62 @@ #include "simpleOpensslSigner.h" #include "slipBio.h" +int gencb( int a, int b, BN_GENCB* g ) { + ( void ) a; + ( void ) b; + ( void ) g; + + std::cout << ( a == 0 ? "." : "+" ) << std::flush; + + return 1; +} + +static std::shared_ptr dh_param; + +std::shared_ptr generateSSLContext( bool server ) { + std::shared_ptr ctx = std::shared_ptr( SSL_CTX_new( TLSv1_2_method() ), SSL_CTX_free ); + + if( !SSL_CTX_set_cipher_list( ctx.get(), "HIGH:+CAMELLIA256:!eNull:!aNULL:!ADH:!MD5:-RSA+AES+SHA1:!RC4:!DES:!3DES:!SEED:!EXP:!AES128:!CAMELLIA128" ) ) { + throw "Cannot set cipher list. Your source is broken."; + } + + if( server ) { + if( !dh_param ) { + FILE* paramfile = fopen( "dh_param.pem", "r" ); + + if( paramfile ) { + dh_param = std::shared_ptr( PEM_read_DHparams( paramfile, NULL, NULL, NULL ), DH_free ); + fclose( paramfile ); + } else { + dh_param = std::shared_ptr( DH_new(), DH_free ); + std::cout << "Generating DH params" << std::endl; + BN_GENCB cb; + cb.ver = 2; + cb.arg = 0; + cb.cb.cb_2 = gencb; + + if( !DH_generate_parameters_ex( dh_param.get(), 2048, 5, &cb ) ) { + throw "DH generation failed"; + } + + std::cout << std::endl; + paramfile = fopen( "dh_param.pem", "w" ); + + if( paramfile ) { + PEM_write_DHparams( paramfile, dh_param.get() ); + fclose( paramfile ); + } + } + } + + if( !SSL_CTX_set_tmp_dh( ctx.get(), dh_param.get() ) ) { + throw "Cannot set tmp dh."; + } + } + + return ctx; +} + class RecordHandlerSession { public: uint32_t sessid; @@ -37,10 +93,10 @@ public: this->signer = signer; ssl = SSL_new( ctx.get() ); - BIO* bio = output;//BIO_new( BIO_f_ssl() ); - //SSL_set_accept_state( ssl ); - //SSL_set_bio( ssl, output, output ); - //BIO_set_ssl( bio, ssl, BIO_NOCLOSE ); + BIO* bio = BIO_new( BIO_f_ssl() ); + SSL_set_accept_state( ssl ); + SSL_set_bio( ssl, output, output ); + BIO_set_ssl( bio, ssl, BIO_NOCLOSE ); io = std::shared_ptr( new OpensslBIOWrapper( bio ) ); } @@ -151,7 +207,8 @@ DefaultRecordHandler::DefaultRecordHandler( std::shared_ptr signer, BIO* this->signer = signer; - ctx = std::shared_ptr( SSL_CTX_new( TLSv1_method() ), SSL_CTX_free ); + ctx = generateSSLContext( true ); + SSL_CTX_use_certificate_file( ctx.get(), "testdata/server.crt", SSL_FILETYPE_PEM ); SSL_CTX_use_PrivateKey_file( ctx.get(), "testdata/server.key", SSL_FILETYPE_PEM ); @@ -172,6 +229,7 @@ void DefaultRecordHandler::handle() { } int count = 0; + void send( std::shared_ptr bio, RecordHeader& head, RecordHeader::SignerCommand cmd, std::string data ) { head.command = ( uint16_t ) cmd; head.command_count++; @@ -232,7 +290,14 @@ int handlermain( int argc, const char* argv[] ) { BIO* b = BIO_new_fd( fileno( f ), 0 ); BIO* slip1 = BIO_new( toBio() ); ( ( SlipBIO* )slip1->ptr )->setTarget( std::shared_ptr( new OpensslBIOWrapper( b ) ) ); - std::shared_ptr conn( new OpensslBIOWrapper( slip1 ) ); + std::cout << "Initing tlsv1_2" << std::endl; + std::shared_ptr ctx = generateSSLContext( false ); + SSL* ssl = SSL_new( ctx.get() ); + BIO* bio = BIO_new( BIO_f_ssl() ); + SSL_set_connect_state( ssl ); + SSL_set_bio( ssl, slip1, slip1 ); + BIO_set_ssl( bio, ssl, BIO_NOCLOSE ); + std::shared_ptr conn( new OpensslBIOWrapper( bio ) ); send( conn, head, RecordHeader::SignerCommand::SET_CSR, data ); send( conn, head, RecordHeader::SignerCommand::SET_SIGNATURE_TYPE, "sha256" ); send( conn, head, RecordHeader::SignerCommand::SET_PROFILE, "1" ); @@ -244,7 +309,7 @@ int handlermain( int argc, const char* argv[] ) { for( int i = 0; i < 2; i++ ) { try { - int length = BIO_read( slip1, buffer.data(), buffer.size() ); + int length = conn->read( buffer.data(), buffer.size() ); RecordHeader head; std::string payload = parseCommand( head, std::string( buffer.data(), length ) ); std::cout << "Data: " << std::endl << payload << std::endl; @@ -271,9 +336,10 @@ int handlermain( int argc, const char* argv[] ) { BIO* conn = BIO_new_fd( fileno( f ), 0 ); BIO* slip1 = BIO_new( toBio() ); ( ( SlipBIO* )slip1->ptr )->setTarget( std::shared_ptr( new OpensslBIOWrapper( conn ) ) ); - DefaultRecordHandler* dh = new DefaultRecordHandler( std::shared_ptr( new SimpleOpensslSigner() ), slip1 ); try { + DefaultRecordHandler* dh = new DefaultRecordHandler( std::shared_ptr( new SimpleOpensslSigner() ), slip1 ); + while( true ) { dh->handle(); } diff --git a/src/slipBio.cpp b/src/slipBio.cpp index 5baae77..725e837 100644 --- a/src/slipBio.cpp +++ b/src/slipBio.cpp @@ -21,20 +21,15 @@ char hexDigit( char c ) { } std::string toHex( const char* buf, int len ) { - char* c = ( char* ) malloc( len * 2 ); - - if( !c ) { - return ""; - } - - std::shared_ptr mem = std::shared_ptr( c, free ); + std::string data = "000000"; for( int i = 0; i < len; i++ ) { - c[i * 2] = hexDigit( ( buf[i] >> 4 ) & 0xF ); - c[i * 2 + 1] = hexDigit( buf[i] & 0xF ); + data.append( 1, ' ' ); + data.append( 1, hexDigit( ( buf[i] >> 4 ) & 0xF ) ); + data.append( 1, hexDigit( buf[i] & 0xF ) ); } - return std::string( mem.get(), len * 2 ); + return data; } SlipBIO::SlipBIO() { diff --git a/test/src/main.cpp b/test/src/main.cpp index 313b620..32f58ca 100644 --- a/test/src/main.cpp +++ b/test/src/main.cpp @@ -1,4 +1,10 @@ #define BOOST_TEST_DYN_LINK #define BOOST_TEST_MODULE Cassiopeia +#include + #include + +#include "database.h" + +std::vector profiles;