Coverage Report

Created: 2023-06-07 07:00

/src/botan/build/include/botan/der_enc.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
* DER Encoder
3
* (C) 1999-2007,2018 Jack Lloyd
4
*
5
* Botan is released under the Simplified BSD License (see license.txt)
6
*/
7
8
#ifndef BOTAN_DER_ENCODER_H_
9
#define BOTAN_DER_ENCODER_H_
10
11
#include <botan/asn1_obj.h>
12
#include <functional>
13
#include <vector>
14
15
namespace Botan {
16
17
class BigInt;
18
19
/**
20
* General DER Encoding Object
21
*/
22
class BOTAN_PUBLIC_API(2, 0) DER_Encoder final {
23
   public:
24
      typedef std::function<void(const uint8_t[], size_t)> append_fn;
25
26
      /**
27
      * DER encode, writing to an internal buffer
28
      * Use get_contents or get_contents_unlocked to read the results
29
      * after all encoding is completed.
30
      */
31
      DER_Encoder() = default;
32
33
      /**
34
      * DER encode, writing to @param vec
35
      * If this constructor is used, get_contents* may not be called.
36
      */
37
      DER_Encoder(secure_vector<uint8_t>& vec);
38
39
      /**
40
      * DER encode, writing to @param vec
41
      * If this constructor is used, get_contents* may not be called.
42
      */
43
      DER_Encoder(std::vector<uint8_t>& vec);
44
45
      /**
46
      * DER encode, calling append to write output
47
      * If this constructor is used, get_contents* may not be called.
48
      */
49
0
      DER_Encoder(append_fn append) : m_append_output(append) {}
50
51
      secure_vector<uint8_t> get_contents();
52
53
      /**
54
      * Return the encoded contents as a std::vector
55
      *
56
      * If using this function, instead pass a std::vector to the
57
      * contructor of DER_Encoder where the output will be placed. This
58
      * avoids several unecessary copies.
59
      */
60
      BOTAN_DEPRECATED("Use DER_Encoder(vector) instead")
61
      std::vector<uint8_t> get_contents_unlocked();
62
63
      DER_Encoder& start_cons(ASN1_Type type_tag, ASN1_Class class_tag);
64
65
0
      DER_Encoder& start_sequence() { return start_cons(ASN1_Type::Sequence, ASN1_Class::Universal); }
66
67
0
      DER_Encoder& start_set() { return start_cons(ASN1_Type::Set, ASN1_Class::Universal); }
68
69
0
      DER_Encoder& start_context_specific(uint32_t tag) {
70
0
         return start_cons(ASN1_Type(tag), ASN1_Class::ContextSpecific);
71
0
      }
72
73
0
      DER_Encoder& start_explicit_context_specific(uint32_t tag) {
74
0
         return start_cons(ASN1_Type(tag), ASN1_Class::ExplicitContextSpecific);
75
0
      }
76
77
      DER_Encoder& end_cons();
78
79
      DER_Encoder& start_explicit(uint16_t type_tag);
80
      DER_Encoder& end_explicit();
81
82
      /**
83
      * Insert raw bytes directly into the output stream
84
      */
85
      DER_Encoder& raw_bytes(const uint8_t val[], size_t len);
86
87
      template <typename Alloc>
88
0
      DER_Encoder& raw_bytes(const std::vector<uint8_t, Alloc>& val) {
89
0
         return raw_bytes(val.data(), val.size());
90
0
      }
91
92
      DER_Encoder& encode_null();
93
      DER_Encoder& encode(bool b);
94
      DER_Encoder& encode(size_t s);
95
      DER_Encoder& encode(const BigInt& n);
96
      DER_Encoder& encode(const uint8_t val[], size_t len, ASN1_Type real_type);
97
98
      template <typename Alloc>
99
0
      DER_Encoder& encode(const std::vector<uint8_t, Alloc>& vec, ASN1_Type real_type) {
100
0
         return encode(vec.data(), vec.size(), real_type);
101
0
      }
Unexecuted instantiation: Botan::DER_Encoder& Botan::DER_Encoder::encode<Botan::secure_allocator<unsigned char> >(std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> > const&, Botan::ASN1_Type)
Unexecuted instantiation: Botan::DER_Encoder& Botan::DER_Encoder::encode<std::__1::allocator<unsigned char> >(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > const&, Botan::ASN1_Type)
102
103
      DER_Encoder& encode(bool b, ASN1_Type type_tag, ASN1_Class class_tag = ASN1_Class::ContextSpecific);
104
105
      DER_Encoder& encode(size_t s, ASN1_Type type_tag, ASN1_Class class_tag = ASN1_Class::ContextSpecific);
106
107
      DER_Encoder& encode(const BigInt& n, ASN1_Type type_tag, ASN1_Class class_tag = ASN1_Class::ContextSpecific);
108
109
      DER_Encoder& encode(const uint8_t v[],
110
                          size_t len,
111
                          ASN1_Type real_type,
112
                          ASN1_Type type_tag,
113
                          ASN1_Class class_tag = ASN1_Class::ContextSpecific);
114
115
      template <typename Alloc>
116
      DER_Encoder& encode(const std::vector<uint8_t, Alloc>& bytes,
117
                          ASN1_Type real_type,
118
                          ASN1_Type type_tag,
119
                          ASN1_Class class_tag) {
120
         return encode(bytes.data(), bytes.size(), real_type, type_tag, class_tag);
121
      }
122
123
      template <typename T>
124
      DER_Encoder& encode_optional(const T& value, const T& default_value) {
125
         if(value != default_value)
126
            encode(value);
127
         return (*this);
128
      }
129
130
      template <typename T>
131
      DER_Encoder& encode_list(const std::vector<T>& values) {
132
         for(size_t i = 0; i != values.size(); ++i)
133
            encode(values[i]);
134
         return (*this);
135
      }
136
137
      /*
138
      * Request for an object to encode itself to this stream
139
      */
140
      DER_Encoder& encode(const ASN1_Object& obj);
141
142
      /*
143
      * Conditionally write some values to the stream
144
      */
145
0
      DER_Encoder& encode_if(bool pred, DER_Encoder& enc) {
146
0
         if(pred)
147
0
            return raw_bytes(enc.get_contents());
148
0
         return (*this);
149
0
      }
150
151
0
      DER_Encoder& encode_if(bool pred, const ASN1_Object& obj) {
152
0
         if(pred)
153
0
            encode(obj);
154
0
         return (*this);
155
0
      }
156
157
      DER_Encoder& add_object(ASN1_Type type_tag, ASN1_Class class_tag, const uint8_t rep[], size_t length);
158
159
0
      DER_Encoder& add_object(ASN1_Type type_tag, ASN1_Class class_tag, const std::vector<uint8_t>& rep) {
160
0
         return add_object(type_tag, class_tag, rep.data(), rep.size());
161
0
      }
162
163
0
      DER_Encoder& add_object(ASN1_Type type_tag, ASN1_Class class_tag, const secure_vector<uint8_t>& rep) {
164
0
         return add_object(type_tag, class_tag, rep.data(), rep.size());
165
0
      }
166
167
      DER_Encoder& add_object(ASN1_Type type_tag, ASN1_Class class_tag, std::string_view str);
168
169
      DER_Encoder& add_object(ASN1_Type type_tag, ASN1_Class class_tag, uint8_t val);
170
171
   private:
172
      class DER_Sequence final {
173
         public:
174
            uint32_t tag_of() const;
175
176
            void push_contents(DER_Encoder& der);
177
178
            void add_bytes(const uint8_t val[], size_t len);
179
180
            void add_bytes(const uint8_t hdr[], size_t hdr_len, const uint8_t val[], size_t val_len);
181
182
            DER_Sequence(ASN1_Type, ASN1_Class);
183
184
            DER_Sequence(DER_Sequence&& seq) :
185
                  m_type_tag(std::move(seq.m_type_tag)),
186
                  m_class_tag(std::move(seq.m_class_tag)),
187
                  m_contents(std::move(seq.m_contents)),
188
0
                  m_set_contents(std::move(seq.m_set_contents)) {}
189
190
0
            DER_Sequence& operator=(DER_Sequence&& seq) {
191
0
               std::swap(m_type_tag, seq.m_type_tag);
192
0
               std::swap(m_class_tag, seq.m_class_tag);
193
0
               std::swap(m_contents, seq.m_contents);
194
0
               std::swap(m_set_contents, seq.m_set_contents);
195
0
               return (*this);
196
0
            }
197
198
0
            DER_Sequence(const DER_Sequence& seq) = default;
199
200
            DER_Sequence& operator=(const DER_Sequence& seq) = default;
201
202
         private:
203
            ASN1_Type m_type_tag;
204
            ASN1_Class m_class_tag;
205
            secure_vector<uint8_t> m_contents;
206
            std::vector<secure_vector<uint8_t>> m_set_contents;
207
      };
208
209
      append_fn m_append_output;
210
      secure_vector<uint8_t> m_default_outbuf;
211
      std::vector<DER_Sequence> m_subsequences;
212
};
213
214
}  // namespace Botan
215
216
#endif