]> WPIA git - cassiopeia.git/commitdiff
add: implement command chunking especially for FULL_CRL-commands
authorFelix Dörre <felix@dogcraft.de>
Tue, 26 Jan 2016 15:34:47 +0000 (16:34 +0100)
committerFelix Dörre <felix@dogcraft.de>
Tue, 26 Jan 2016 15:34:47 +0000 (16:34 +0100)
src/crypto/remoteSigner.cpp
src/io/record.cpp
src/io/record.h
src/io/recordHandler.cpp

index 6c003c38023fc2ca2986cbf6d53e6a7cfe153a04..4b1e630ad21e511a1229bce1b78b61c3c8b918a2 100644 (file)
@@ -73,7 +73,7 @@ std::shared_ptr<SignedCertificate> RemoteSigner::sign( std::shared_ptr<TBSCertif
     for( int i = 0; i < 3; i++ ) {
         try {
             RecordHeader head;
-            std::string payload = parseCommand( head, conn->readLine() );
+            std::string payload = parseCommandChunked( head, conn );
 
             switch( static_cast<RecordHeader::SignerResult>( head.command )) {
             case RecordHeader::SignerResult::CERTIFICATE:
@@ -162,7 +162,7 @@ std::pair<std::shared_ptr<CRL>, std::string> RemoteSigner::revoke( std::shared_p
     std::string payload = ca->name;
     send( conn, head, RecordHeader::SignerCommand::REVOKE, payload );
 
-    payload = parseCommand( head, conn->readLine() );
+    payload = parseCommandChunked( head, conn );
 
     std::string tgtName = ca->path + std::string( "/ca.crl" );
     auto crl = std::make_shared<CRL>( tgtName );
@@ -193,7 +193,7 @@ std::pair<std::shared_ptr<CRL>, std::string> RemoteSigner::revoke( std::shared_p
         logger::warn( "CRL is broken, trying to recover" );
         send( conn, head, RecordHeader::SignerCommand::GET_FULL_CRL, ca->name );
 
-        payload = parseCommand( head, conn->readLine() );
+        payload = parseCommandChunked( head, conn );
 
         if( static_cast<RecordHeader::SignerResult>( head.command ) != RecordHeader::SignerResult::FULL_CRL ) {
             throw "Protocol violation";
index 97e601549428b26a4de512e3deba1e7d711a2926..422244e0021e2d06216df0f31e2ea7f626ee914b 100644 (file)
@@ -28,19 +28,26 @@ void sendCommand( RecordHeader& head, const std::string& data, std::shared_ptr<O
     std::stringstream ss;
     ss << data.size();
     logger::debugf( "Record payload length: %s", ss.str() ); 
-    if(data.size() > 0xFFFF){
-        logger::warn( "Data too big, need chunking" );
-    }
-    head.payloadLength = data.size();
-    std::string s;
-    s += head.packToString();
-    s += data;
+    size_t pos = 0;
+    head.offset = 0;
+    head.totalLength = data.size();
+    while(pos < data.size()){
+        size_t toTransfer = std::min(static_cast<size_t>(0xF000), data.size() - pos);
+        head.payloadLength = toTransfer;
+
+        std::string s;
+        s += head.packToString();
+        s += data.substr(pos, toTransfer);
 
-    std::string res = toHexAndChecksum( s );
+        std::string res = toHexAndChecksum( s );
 
-    logger::debug( "FINE: RECORD output: ", res );
+        logger::debug( "FINE: RECORD output: ", res );
 
-    bio->write( res.data(), res.size() );
+        bio->write( res.data(), res.size() );
+
+        pos += toTransfer;
+        head.offset += 1;
+    }
 }
 
 int32_t fromHexDigit( char c ) {
@@ -99,31 +106,20 @@ std::string parseCommand( RecordHeader& head, const std::string& input) {
 
     return data;
 }
-
-/*
-int main( int argc, char* argv[] ) {
-    OpensslBIOWrapper *bio = new OpensslBIOWrapper(BIO_new_fd(0, 0));
-    std::string data = "halloPayload";
-    RecordHeader head;
-    head.command = 0x7;
-    head.flags = 1;
-    head.sessid = 13;
-    head.command_count = 0xA0B;
-    head.totalLength = 9;
-    sendCommand( head, data, std::shared_ptr<OpensslBIO>(bio) );
-    head.command = 0x8;
-
-    try {
-        std::string c = parseCommand( head, ":0700010D0000000B0A0900000000000C0068616C6C6F5061796C6F6164E6\n" );
-
-        std::cout << "res: " << std::endl;
-        std::cout << head.payloadLength << std::endl;
-        std::cout << c << std::endl;
-    } catch( char const* c ) {
-        std::cout << "err: " << c << std::endl;
+std::string parseCommandChunked( RecordHeader& head, std::shared_ptr<OpensslBIOWrapper> io){
+    logger::note("reading");
+    std::string payload = parseCommand( head, io->readLine() );
+    std::string all(head.totalLength, ' ');
+    auto target = all.begin();
+    size_t pos = 0;
+    while(true) {
+        pos += head.payloadLength;
+        target = std::copy ( payload.begin(), payload.end(), target);
+        if(pos >= head.totalLength) {
+            break;
+        }
+        logger::note("chunk digested, reading next one");
+        payload = parseCommand( head, io->readLine() );
     }
-
-
-    return 0;
+    return all;
 }
-*/
index 28a9b1e710da79be26bbff034207328bf7fd86aa..d56708aa9a768f84d453200f6c390e670c25c078 100644 (file)
@@ -6,6 +6,7 @@
 #include <string>
 
 #include "bios.h"
+#include "io/opensslBIO.h"
 
 #define RECORD_HEADER_SIZE 17
 
@@ -105,5 +106,6 @@ public:
 };
 
 std::string parseCommand( RecordHeader& head, const std::string& input );
+std::string parseCommandChunked( RecordHeader& head, std::shared_ptr<OpensslBIOWrapper> conn);
 
 void sendCommand( RecordHeader& head, const std::string& data, std::shared_ptr<OpensslBIO> bio );
index 2d58be0b7d1e195e62350ebaadd4cc9191074b4f..551b2c495144e04c4660bc95c45dacaef885bbb3 100644 (file)
@@ -67,17 +67,14 @@ public:
         rh.command = static_cast<uint16_t>( res );
         rh.flags = 0;
         rh.command_count = 0; // TODO i++
-        rh.totalLength = payload.size();
         sendCommand( rh, payload, io );
     }
 
     void work() {
-        std::string content = io->readLine();
-
         try {
             RecordHeader head;
-            std::string payload = parseCommand( head, content );
-            execute( head, payload );
+            std::string all = parseCommandChunked( head, io );
+            execute( static_cast<RecordHeader::SignerCommand>( head.command ), all );
         } catch( const char* msg ) {
             logger::error( "ERROR: ", msg );
             parent->reset();
@@ -85,12 +82,8 @@ public:
         }
     }
 
-    void execute( RecordHeader& head, std::string data ) {
-        if( head.totalLength != head.payloadLength || head.offset != 0 ) {
-            throw "Error, chunking not supported yet";
-        }
-
-        switch( static_cast<RecordHeader::SignerCommand>( head.command )) {
+    void execute( RecordHeader::SignerCommand command, std::string data ) {
+        switch( command ) {
         case RecordHeader::SignerCommand::SET_CSR:
             tbs->csr_content = data;
             tbs->csr_type = "CSR";