]> WPIA git - cassiopeia.git/blob - src/io/record.h
6c2df6590683d8f480fb286c95a715de90a63251
[cassiopeia.git] / src / io / record.h
1 #pragma once
2
3 #include <inttypes.h>
4
5 #include <memory>
6 #include <string>
7 #include <exception>
8 #include "bios.h"
9 #include "io/opensslBIO.h"
10
11 #define RECORD_HEADER_SIZE 17
12
13 class RecordHeader {
14 public:
15     enum class SignerCommand : uint16_t {
16         SET_CSR = 0x01,
17         SET_SPKAC = 0x02,
18         SET_SIGNATURE_TYPE = 0x10,
19         SET_PROFILE = 0x11,
20         SET_WISH_FROM = 0x12,
21         SET_WISH_TO = 0x13,
22         SET_OCSP_TARGET_CA = 0x14,
23         ADD_SAN = 0x18,
24         ADD_AVA = 0x19,
25         ADD_PROOF_LINE = 0x40,
26         SIGN = 0x80,
27         LOG_SAVED = 0x81,
28         REVOKE = 0x100,
29         GET_FULL_CRL = 0x101,
30         ADD_SERIAL = 0x102,
31         GET_TIMESTAMP = 0xC0,
32         GET_STATUS_REPORT = 0xD0
33     };
34
35     enum class SignerResult : uint16_t {
36         REVOKED = 0x100,
37         FULL_CRL = 0x101,
38         SAVE_LOG = 0x80,
39         CERTIFICATE = 0x81,
40         SIGNING_CA = 0x82,
41     };
42
43 public:
44     uint16_t command;
45     char flags;
46     uint32_t sessid;
47     uint16_t command_count;
48     uint32_t totalLength;
49     uint16_t offset;
50     uint16_t payloadLength;
51
52     RecordHeader() :
53         command( 0 ), flags( 0 ), sessid( 0 ), command_count( 0 ), totalLength( 0 ), offset( 0 ), payloadLength( 0 ) {
54     }
55
56     template <class T>
57     static void append( std::string& str, T val ) {
58         str.append( ( char * ) &val, sizeof( T ) );
59     }
60
61     template <class T>
62     static void read( std::string::const_iterator& it, T& val ) {
63         union typeConversion {
64             char buf[sizeof( T )];
65             T value;
66
67             typeConversion( const T& v ) : value( v ) {}
68         };
69
70         typeConversion data( 0 );
71
72         for( size_t i = 0; i < sizeof( T ); i++ ) {
73             data.buf[i] = *it++;
74         }
75
76         val = data.value;
77     }
78
79     std::string packToString() {
80         std::string res;
81         res.reserve( RECORD_HEADER_SIZE );
82         append( res, command );
83         append( res, flags );
84         append( res, sessid );
85         append( res, command_count );
86         append( res, totalLength );
87         append( res, offset );
88         append( res, payloadLength );
89         return res;
90     }
91
92     void unpackFromString( const std::string& str ) {
93         if( str.size() != RECORD_HEADER_SIZE ) {
94             throw std::runtime_error( "Invalid string length" );
95         }
96
97         auto it =  str.cbegin();
98         read( it, command );
99         read( it, flags );
100         read( it, sessid );
101         read( it, command_count );
102         read( it, totalLength );
103         read( it, offset );
104         read( it, payloadLength );
105     }
106     bool isFollowupOf( const RecordHeader& head ) {
107         return head.command == command && head.flags == flags && head.sessid == sessid && head.command_count == command_count && head.totalLength == totalLength && head.offset + 1 == offset;
108     }
109 };
110
111 std::string parseCommand( RecordHeader& head, const std::string& input );
112 std::string parseCommandChunked( RecordHeader& head, std::shared_ptr<OpensslBIOWrapper> conn );
113
114 void sendCommand( RecordHeader& head, const std::string& data, std::shared_ptr<OpensslBIO> bio );