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:
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 );
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";
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 ) {
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;
}
-*/
#include <string>
#include "bios.h"
+#include "io/opensslBIO.h"
#define RECORD_HEADER_SIZE 17
};
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 );
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();
}
}
- 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";