]> WPIA git - cassiopeia.git/blob - src/record.cpp
add: Initial code to implement revocation
[cassiopeia.git] / src / record.cpp
1 #include "record.h"
2
3 #include <iomanip>
4 #include <iostream>
5 #include <memory>
6 #include <sstream>
7
8 #include "bios.h"
9 #include "opensslBIO.h"
10
11 std::string toHexAndChecksum( const std::string& src ) {
12     char checksum = 0;
13     std::stringstream ss;
14     ss << ':' << std::hex << std::setfill( '0' ) << std::uppercase;
15
16     for( auto c : src ) {
17         ss << std::setw( 2 ) << ( ( ( uint32_t ) c ) & 0xFF );
18         checksum += c;
19     }
20
21     ss << std::setw( 2 ) << ( ( ( uint32_t )( ~checksum ) ) & 0xFF );
22     ss << '\n';
23     return ss.str();
24 }
25
26 void sendCommand( RecordHeader& head, const std::string& data, std::shared_ptr<OpensslBIO> bio, std::shared_ptr<std::ostream> log ) {
27     head.payloadLength = data.size();
28     std::string s;
29     s += head.packToString();
30     s += data;
31
32     std::string res = toHexAndChecksum( s );
33
34     if( log ) {
35         ( *log.get() ) << "FINE: RECORD output: " << res << std::endl;
36     }
37
38     bio->write( res.data(), res.size() );
39 }
40
41 int32_t fromHexDigit( char c ) {
42     int32_t res = -1;
43
44     if( c >= '0' && c <= '9' ) {
45         res = c - '0';
46     }
47
48     if( c >= 'A' && c <= 'F' ) {
49         res = c - 'A' + 10;
50     }
51
52     return res;
53 }
54
55 std::string parseCommand( RecordHeader& head, const std::string input, std::shared_ptr<std::ostream> log ) {
56     if( log ) {
57         ( *log.get() ) << "FINE: RECORD input: " << input << std::endl;
58     }
59
60     int32_t dlen = ( input.size() - 2 ) / 2;
61     char checksum = 0;
62     bool error = false;
63
64     std::string str( std::max( dlen, RECORD_HEADER_SIZE ), 0 );
65     str.append( 0, dlen );
66
67     for( int i = 0; i < dlen; i++ ) {
68         int32_t digit;
69         int32_t accum;
70         digit = fromHexDigit( input[i * 2 + 1] );
71         error |= digit == -1;
72         accum = digit;
73         accum <<= 4;
74         digit = fromHexDigit( input[i * 2 + 2] );
75         error |= digit == -1;
76         accum += digit;
77         str[i] = accum;
78         checksum += str[i];
79     }
80
81     head.unpackFromString( str.substr( 0, RECORD_HEADER_SIZE ) );
82     uint32_t len = head.payloadLength;
83     uint32_t expectedTotalLength = ( RECORD_HEADER_SIZE + len + 1 /*checksum*/ ) * 2 + 2;
84     std::string data = str.substr( RECORD_HEADER_SIZE, str.size() - RECORD_HEADER_SIZE );
85
86     if( checksum != -1 || expectedTotalLength != input.size() || error || dlen < RECORD_HEADER_SIZE ) {
87         throw "Error, invalid checksum";
88     }
89
90     data.pop_back();
91
92     return data;
93 }
94
95 /*
96 int main( int argc, char* argv[] ) {
97     OpensslBIOWrapper *bio = new OpensslBIOWrapper(BIO_new_fd(0, 0));
98     std::string data = "halloPayload";
99     RecordHeader head;
100     head.command = 0x7;
101     head.flags = 1;
102     head.sessid = 13;
103     head.command_count = 0xA0B;
104     head.totalLength = 9;
105     sendCommand( head, data, std::shared_ptr<OpensslBIO>(bio) );
106     head.command = 0x8;
107
108     try {
109         std::string c = parseCommand( head, ":0700010D0000000B0A0900000000000C0068616C6C6F5061796C6F6164E6\n" );
110
111         std::cout << "res: " << std::endl;
112         std::cout << head.payloadLength << std::endl;
113         std::cout << c << std::endl;
114     } catch( char const* c ) {
115         std::cout << "err: " << c << std::endl;
116     }
117
118
119     return 0;
120 }
121 */