]> WPIA git - cassiopeia.git/blob - src/io/record.h
fmt: run format script excluding lambdas
[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         ADD_SAN = 0x18,
23         ADD_AVA = 0x19,
24         ADD_PROOF_LINE = 0x40,
25         SIGN = 0x80,
26         LOG_SAVED = 0x81,
27         REVOKE = 0x100,
28         GET_FULL_CRL = 0x101,
29         ADD_SERIAL = 0x102,
30         GET_TIMESTAMP = 0xC0,
31         GET_STATUS_REPORT = 0xD0
32     };
33
34     enum class SignerResult : uint16_t {
35         REVOKED = 0x100,
36         FULL_CRL = 0x101,
37         SAVE_LOG = 0x80,
38         CERTIFICATE = 0x81,
39         SIGNING_CA = 0x82,
40     };
41
42 public:
43     uint16_t command;
44     char flags;
45     uint32_t sessid;
46     uint16_t command_count;
47     uint32_t totalLength;
48     uint16_t offset;
49     uint16_t payloadLength;
50
51     RecordHeader() :
52         command( 0 ), flags( 0 ), sessid( 0 ), command_count( 0 ), totalLength( 0 ), offset( 0 ), payloadLength( 0 ) {
53     }
54
55     template <class T>
56     static void append( std::string& str, T val ) {
57         str.append( ( char * ) &val, sizeof( T ) );
58     }
59
60     template <class T>
61     static void read( std::string::const_iterator& it, T& val ) {
62         union typeConversion {
63             char buf[sizeof( T )];
64             T value;
65
66             typeConversion( const T& v ) : value( v ) {}
67         };
68
69         typeConversion data( 0 );
70
71         for( size_t i = 0; i < sizeof( T ); i++ ) {
72             data.buf[i] = *it++;
73         }
74
75         val = data.value;
76     }
77
78     std::string packToString() {
79         std::string res;
80         res.reserve( RECORD_HEADER_SIZE );
81         append( res, command );
82         append( res, flags );
83         append( res, sessid );
84         append( res, command_count );
85         append( res, totalLength );
86         append( res, offset );
87         append( res, payloadLength );
88         return res;
89     }
90
91     void unpackFromString( const std::string& str ) {
92         if( str.size() != RECORD_HEADER_SIZE ) {
93             throw std::runtime_error( "Invalid string length" );
94         }
95
96         auto it =  str.cbegin();
97         read( it, command );
98         read( it, flags );
99         read( it, sessid );
100         read( it, command_count );
101         read( it, totalLength );
102         read( it, offset );
103         read( it, payloadLength );
104     }
105     bool isFollowupOf( const RecordHeader& head ) {
106         return head.command == command && head.flags == flags && head.sessid == sessid && head.command_count == command_count && head.totalLength == totalLength && head.offset + 1 == offset;
107     }
108 };
109
110 std::string parseCommand( RecordHeader& head, const std::string& input );
111 std::string parseCommandChunked( RecordHeader& head, std::shared_ptr<OpensslBIOWrapper> conn );
112
113 void sendCommand( RecordHeader& head, const std::string& data, std::shared_ptr<OpensslBIO> bio );