Coverage Report

Created: 2021-11-25 09:31

/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 <vector>
13
#include <functional>
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
   {
24
   public:
25
      typedef std::function<void (const uint8_t[], size_t)> append_fn;
26
27
      /**
28
      * DER encode, writing to an internal buffer
29
      * Use get_contents or get_contents_unlocked to read the results
30
      * after all encoding is completed.
31
      */
32
315
      DER_Encoder() = default;
33
34
      /**
35
      * DER encode, writing to @param vec
36
      * If this constructor is used, get_contents* may not be called.
37
      */
38
      DER_Encoder(secure_vector<uint8_t>& vec);
39
40
      /**
41
      * DER encode, writing to @param vec
42
      * If this constructor is used, get_contents* may not be called.
43
      */
44
      DER_Encoder(std::vector<uint8_t>& vec);
45
46
      /**
47
      * DER encode, calling append to write output
48
      * If this constructor is used, get_contents* may not be called.
49
      */
50
0
      DER_Encoder(append_fn append) : m_append_output(append) {}
51
52
      secure_vector<uint8_t> get_contents();
53
54
      /**
55
      * Return the encoded contents as a std::vector
56
      *
57
      * If using this function, instead pass a std::vector to the
58
      * contructor of DER_Encoder where the output will be placed. This
59
      * avoids several unecessary copies.
60
      */
61
      BOTAN_DEPRECATED("Use DER_Encoder(vector) instead")
62
      std::vector<uint8_t> get_contents_unlocked();
63
64
      DER_Encoder& start_cons(ASN1_Type type_tag, ASN1_Class class_tag);
65
66
      DER_Encoder& start_sequence()
67
88.1k
         {
68
88.1k
         return start_cons(ASN1_Type::Sequence, ASN1_Class::Universal);
69
88.1k
         }
70
71
      DER_Encoder& start_set()
72
0
         {
73
0
         return start_cons(ASN1_Type::Set, ASN1_Class::Universal);
74
0
         }
75
76
      DER_Encoder& start_context_specific(uint32_t tag)
77
0
         {
78
0
         return start_cons(ASN1_Type(tag), ASN1_Class::ContextSpecific);
79
0
         }
80
81
      DER_Encoder& start_explicit_context_specific(uint32_t tag)
82
0
         {
83
0
         return start_cons(ASN1_Type(tag), ASN1_Class::ExplicitContextSpecific);
84
0
         }
85
86
      DER_Encoder& end_cons();
87
88
      DER_Encoder& start_explicit(uint16_t type_tag);
89
      DER_Encoder& end_explicit();
90
91
      /**
92
      * Insert raw bytes directly into the output stream
93
      */
94
      DER_Encoder& raw_bytes(const uint8_t val[], size_t len);
95
96
      template<typename Alloc>
97
      DER_Encoder& raw_bytes(const std::vector<uint8_t, Alloc>& val)
98
24.7k
         {
99
24.7k
         return raw_bytes(val.data(), val.size());
100
24.7k
         }
Botan::DER_Encoder& Botan::DER_Encoder::raw_bytes<std::__1::allocator<unsigned char> >(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > const&)
Line
Count
Source
98
24.7k
         {
99
24.7k
         return raw_bytes(val.data(), val.size());
100
24.7k
         }
Unexecuted instantiation: Botan::DER_Encoder& Botan::DER_Encoder::raw_bytes<Botan::secure_allocator<unsigned char> >(std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> > const&)
101
102
      DER_Encoder& encode_null();
103
      DER_Encoder& encode(bool b);
104
      DER_Encoder& encode(size_t s);
105
      DER_Encoder& encode(const BigInt& n);
106
      DER_Encoder& encode(const uint8_t val[], size_t len, ASN1_Type real_type);
107
108
      template<typename Alloc>
109
      DER_Encoder& encode(const std::vector<uint8_t, Alloc>& vec, ASN1_Type real_type)
110
13.3k
         {
111
13.3k
         return encode(vec.data(), vec.size(), real_type);
112
13.3k
         }
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)
Line
Count
Source
110
12.9k
         {
111
12.9k
         return encode(vec.data(), vec.size(), real_type);
112
12.9k
         }
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)
Line
Count
Source
110
315
         {
111
315
         return encode(vec.data(), vec.size(), real_type);
112
315
         }
113
114
      DER_Encoder& encode(bool b,
115
                          ASN1_Type type_tag,
116
                          ASN1_Class class_tag = ASN1_Class::ContextSpecific);
117
118
      DER_Encoder& encode(size_t s,
119
                          ASN1_Type type_tag,
120
                          ASN1_Class class_tag = ASN1_Class::ContextSpecific);
121
122
      DER_Encoder& encode(const BigInt& n,
123
                          ASN1_Type type_tag,
124
                          ASN1_Class class_tag = ASN1_Class::ContextSpecific);
125
126
      DER_Encoder& encode(const uint8_t v[], size_t len,
127
                          ASN1_Type real_type,
128
                          ASN1_Type type_tag,
129
                          ASN1_Class class_tag = ASN1_Class::ContextSpecific);
130
131
      template<typename Alloc>
132
      DER_Encoder& encode(const std::vector<uint8_t, Alloc>& bytes,
133
                          ASN1_Type real_type,
134
                          ASN1_Type type_tag, ASN1_Class class_tag)
135
0
         {
136
0
         return encode(bytes.data(), bytes.size(),
137
0
                       real_type, type_tag, class_tag);
138
0
         }
139
140
      template<typename T>
141
      DER_Encoder& encode_optional(const T& value, const T& default_value)
142
0
         {
143
0
         if(value != default_value)
144
0
            encode(value);
145
0
         return (*this);
146
0
         }
Unexecuted instantiation: Botan::DER_Encoder& Botan::DER_Encoder::encode_optional<bool>(bool const&, bool const&)
Unexecuted instantiation: Botan::DER_Encoder& Botan::DER_Encoder::encode_optional<unsigned long>(unsigned long const&, unsigned long const&)
147
148
      template<typename T>
149
      DER_Encoder& encode_list(const std::vector<T>& values)
150
446
         {
151
1.33k
         for(size_t i = 0; i != values.size(); ++i)
152
892
            encode(values[i]);
153
446
         return (*this);
154
446
         }
Unexecuted instantiation: Botan::DER_Encoder& Botan::DER_Encoder::encode_list<Botan::OID>(std::__1::vector<Botan::OID, std::__1::allocator<Botan::OID> > const&)
Unexecuted instantiation: x509_ext.cpp:Botan::DER_Encoder& Botan::DER_Encoder::encode_list<Botan::Cert_Extension::(anonymous namespace)::Policy_Information>(std::__1::vector<Botan::Cert_Extension::(anonymous namespace)::Policy_Information, std::__1::allocator<Botan::Cert_Extension::(anonymous namespace)::Policy_Information> > const&)
Botan::DER_Encoder& Botan::DER_Encoder::encode_list<Botan::BigInt>(std::__1::vector<Botan::BigInt, std::__1::allocator<Botan::BigInt> > const&)
Line
Count
Source
150
446
         {
151
1.33k
         for(size_t i = 0; i != values.size(); ++i)
152
892
            encode(values[i]);
153
446
         return (*this);
154
446
         }
155
156
      /*
157
      * Request for an object to encode itself to this stream
158
      */
159
      DER_Encoder& encode(const ASN1_Object& obj);
160
161
      /*
162
      * Conditionally write some values to the stream
163
      */
164
      DER_Encoder& encode_if(bool pred, DER_Encoder& enc)
165
0
         {
166
0
         if(pred)
167
0
            return raw_bytes(enc.get_contents());
168
0
         return (*this);
169
0
         }
170
171
      DER_Encoder& encode_if(bool pred, const ASN1_Object& obj)
172
0
         {
173
0
         if(pred)
174
0
            encode(obj);
175
0
         return (*this);
176
0
         }
177
178
      DER_Encoder& add_object(ASN1_Type type_tag, ASN1_Class class_tag,
179
                              const uint8_t rep[], size_t length);
180
181
      DER_Encoder& add_object(ASN1_Type type_tag, ASN1_Class class_tag,
182
                              const std::vector<uint8_t>& rep)
183
12.1k
         {
184
12.1k
         return add_object(type_tag, class_tag, rep.data(), rep.size());
185
12.1k
         }
186
187
      DER_Encoder& add_object(ASN1_Type type_tag, ASN1_Class class_tag,
188
                              const secure_vector<uint8_t>& rep)
189
14.8k
         {
190
14.8k
         return add_object(type_tag, class_tag, rep.data(), rep.size());
191
14.8k
         }
192
193
      DER_Encoder& add_object(ASN1_Type type_tag, ASN1_Class class_tag,
194
                              const std::string& str);
195
196
      DER_Encoder& add_object(ASN1_Type type_tag, ASN1_Class class_tag,
197
                              uint8_t val);
198
199
   private:
200
      class DER_Sequence final
201
         {
202
         public:
203
            uint32_t tag_of() const;
204
205
            void push_contents(DER_Encoder& der);
206
207
            void add_bytes(const uint8_t val[], size_t len);
208
209
            void add_bytes(const uint8_t hdr[], size_t hdr_len,
210
                           const uint8_t val[], size_t val_len);
211
212
            DER_Sequence(ASN1_Type, ASN1_Class);
213
214
            DER_Sequence(DER_Sequence&& seq)
215
175k
               {
216
175k
               std::swap(m_type_tag, seq.m_type_tag);
217
175k
               std::swap(m_class_tag, seq.m_class_tag);
218
175k
               std::swap(m_contents, seq.m_contents);
219
175k
               std::swap(m_set_contents, seq.m_set_contents);
220
175k
               }
221
222
            DER_Sequence& operator=(DER_Sequence&& seq)
223
0
               {
224
0
               std::swap(m_type_tag, seq.m_type_tag);
225
0
               std::swap(m_class_tag, seq.m_class_tag);
226
0
               std::swap(m_contents, seq.m_contents);
227
0
               std::swap(m_set_contents, seq.m_set_contents);
228
0
               return (*this);
229
0
               }
230
231
12.6k
            DER_Sequence(const DER_Sequence& seq) = default;
232
233
            DER_Sequence& operator=(const DER_Sequence& seq) = default;
234
235
         private:
236
             ASN1_Type m_type_tag;
237
             ASN1_Class m_class_tag;
238
            secure_vector<uint8_t> m_contents;
239
            std::vector< secure_vector<uint8_t> > m_set_contents;
240
         };
241
242
      append_fn m_append_output;
243
      secure_vector<uint8_t> m_default_outbuf;
244
      std::vector<DER_Sequence> m_subsequences;
245
   };
246
247
}
248
249
#endif