Coverage Report

Created: 2020-06-30 13:58

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