Aktualizr
C++ SOTA Client
asn1-cerstream.h
1 #ifndef ASN1_CER_STREAM_H
2 #define ASN1_CER_STREAM_H
3 
4 #include "asn1/asn1-cer.h"
5 
6 #include <stack>
7 #include <utility>
8 
9 // tokens
10 namespace asn1 {
11 
12 class Token {
13  public:
14  enum TokType { seq_tok, endseq_tok, restseq_tok, expl_tok, peekexpl_tok, endexpl_tok, opt_tok, endopt_tok };
15  explicit Token(TokType t) { type = t; }
16  virtual ~Token() = default;
17  TokType type;
18 };
19 
20 class EndoptToken : public Token {
21  public:
22  explicit EndoptToken(bool* result = nullptr) : Token(endopt_tok), result_p(result) {}
23  ~EndoptToken() override = default;
24  bool* result_p;
25 };
26 
27 class ExplicitToken : public Token {
28  public:
29  explicit ExplicitToken(uint8_t token_tag, ASN1_Class token_tag_class = kAsn1Context)
30  : Token(expl_tok), tag(token_tag), tag_class(token_tag_class) {}
31  ~ExplicitToken() override = default;
32  uint8_t tag;
33  ASN1_Class tag_class;
34 };
35 
36 class PeekExplicitToken : public Token {
37  public:
38  explicit PeekExplicitToken(uint8_t* token_tag = nullptr, ASN1_Class* token_tag_class = nullptr)
39  : Token(peekexpl_tok), tag(token_tag), tag_class(token_tag_class) {}
40  ~PeekExplicitToken() override = default;
41  uint8_t* tag;
42  ASN1_Class* tag_class;
43 };
44 
45 const Token seq = Token(Token::seq_tok);
46 const Token endseq = Token(Token::endseq_tok);
47 const Token restseq = Token(Token::restseq_tok);
48 const Token endexpl = Token(Token::endexpl_tok);
49 const Token optional = Token(Token::opt_tok);
50 using endoptional = EndoptToken;
52 using expl = ExplicitToken;
53 
54 template <ASN1_UniversalTag Tag, typename = void>
55 class ImplicitC {};
56 
57 template <ASN1_UniversalTag Tag>
58 class ImplicitC<Tag, int32_t&> {
59  public:
60  int32_t& data;
61  explicit ImplicitC(int32_t& d) : data(d) {}
62 };
63 
64 template <ASN1_UniversalTag Tag>
65 class ImplicitC<Tag, const int32_t&> {
66  public:
67  const int32_t& data;
68  explicit ImplicitC(const int32_t& d) : data(d) {}
69 };
70 
71 template <ASN1_UniversalTag Tag>
72 class ImplicitC<Tag, bool&> {
73  public:
74  bool& data;
75  explicit ImplicitC(bool& d) : data(d) {}
76 };
77 
78 template <ASN1_UniversalTag Tag>
79 class ImplicitC<Tag, const bool&> {
80  public:
81  const bool& data;
82  explicit ImplicitC(const bool& d) : data(d) {}
83 };
84 
85 template <ASN1_UniversalTag Tag>
86 class ImplicitC<Tag, std::string&> {
87  public:
88  std::string& data;
89  explicit ImplicitC(std::string& d) : data(d) {}
90 };
91 
92 template <ASN1_UniversalTag Tag>
93 class ImplicitC<Tag, const std::string&> {
94  public:
95  const std::string& data;
96  explicit ImplicitC(const std::string& d) : data(d) {}
97 };
98 
99 template <ASN1_UniversalTag Tag, typename T>
100 ImplicitC<Tag, T&> implicit(T& data) {
101  return ImplicitC<Tag, T&>(data);
102 }
103 
104 class Serializer {
105  public:
106  const std::string& getResult() { return result; }
107 
108  Serializer& operator<<(int32_t val);
109  Serializer& operator<<(bool val);
110  Serializer& operator<<(const std::string& val);
111  Serializer& operator<<(ASN1_UniversalTag tag);
112  Serializer& operator<<(const Token& tok);
113 
114  private:
115  std::string result;
116  ASN1_UniversalTag last_type{kUnknown};
117 };
118 
119 template <ASN1_UniversalTag Tag, typename T>
120 Serializer& operator<<(Serializer& ser, ImplicitC<Tag, T> imp) {
121  ser << Tag << imp.data;
122  return ser;
123 }
124 
126  public:
127  explicit Deserializer(std::string d) : data(std::move(d)){};
128 
129  Deserializer& operator>>(int32_t& val);
130  Deserializer& operator>>(bool& val);
131  Deserializer& operator>>(std::string& val);
132  Deserializer& operator>>(ASN1_UniversalTag tag);
133  Deserializer& operator>>(const Token& tok);
134 
135  const std::string& getData() { return data; } // should only be used for testing
136 
137  private:
138  std::string data;
139  std::stack<int32_t> seq_lengths;
140  std::stack<int32_t> seq_consumed;
141  int32_t int_param{0};
142  std::string string_param;
143 
144  int32_t opt_count{0}; // counter of tested asn1::optional
145  bool opt_first{false};
146  bool opt_present{false};
147 };
148 
149 template <ASN1_UniversalTag Tag, typename T>
150 Deserializer& operator>>(Deserializer& des, ImplicitC<Tag, T> imp) {
151  des >> Tag >> imp.data;
152  return des;
153 }
154 } // namespace asn1
155 
156 #endif // ASN1_CER_STREAM_H
General data structures.
Definition: types.cc:44
STL namespace.