Coverage Report

Created: 2025-04-11 06:34

/src/botan/build/include/public/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
0
      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(std::move(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") std::vector<uint8_t> get_contents_unlocked();
61
62
      DER_Encoder& start_cons(ASN1_Type type_tag, ASN1_Class class_tag);
63
64
254k
      DER_Encoder& start_sequence() { return start_cons(ASN1_Type::Sequence, ASN1_Class::Universal); }
65
66
0
      DER_Encoder& start_set() { return start_cons(ASN1_Type::Set, ASN1_Class::Universal); }
67
68
104k
      DER_Encoder& start_context_specific(uint32_t tag) {
69
104k
         return start_cons(ASN1_Type(tag), ASN1_Class::ContextSpecific);
70
104k
      }
71
72
0
      DER_Encoder& start_explicit_context_specific(uint32_t tag) {
73
0
         return start_cons(ASN1_Type(tag), ASN1_Class::ExplicitContextSpecific);
74
0
      }
75
76
      DER_Encoder& end_cons();
77
78
      DER_Encoder& start_explicit(uint16_t type_tag);
79
      DER_Encoder& end_explicit();
80
81
      /**
82
      * Insert raw bytes directly into the output stream
83
      */
84
      DER_Encoder& raw_bytes(const uint8_t val[], size_t len);
85
86
      template <typename Alloc>
87
138k
      DER_Encoder& raw_bytes(const std::vector<uint8_t, Alloc>& val) {
88
138k
         return raw_bytes(val.data(), val.size());
89
138k
      }
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
87
138k
      DER_Encoder& raw_bytes(const std::vector<uint8_t, Alloc>& val) {
88
138k
         return raw_bytes(val.data(), val.size());
89
138k
      }
90
91
      DER_Encoder& encode_null();
92
      DER_Encoder& encode(bool b);
93
      DER_Encoder& encode(size_t s);
94
      DER_Encoder& encode(const BigInt& n);
95
      DER_Encoder& encode(const uint8_t val[], size_t len, ASN1_Type real_type);
96
97
      template <typename Alloc>
98
17.3k
      DER_Encoder& encode(const std::vector<uint8_t, Alloc>& vec, ASN1_Type real_type) {
99
17.3k
         return encode(vec.data(), vec.size(), real_type);
100
17.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
98
17.3k
      DER_Encoder& encode(const std::vector<uint8_t, Alloc>& vec, ASN1_Type real_type) {
99
17.3k
         return encode(vec.data(), vec.size(), real_type);
100
17.3k
      }
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)
101
102
      DER_Encoder& encode(bool b, ASN1_Type type_tag, ASN1_Class class_tag = ASN1_Class::ContextSpecific);
103
104
      DER_Encoder& encode(size_t s, ASN1_Type type_tag, ASN1_Class class_tag = ASN1_Class::ContextSpecific);
105
106
      DER_Encoder& encode(const BigInt& n, ASN1_Type type_tag, ASN1_Class class_tag = ASN1_Class::ContextSpecific);
107
108
      DER_Encoder& encode(const uint8_t v[],
109
                          size_t len,
110
                          ASN1_Type real_type,
111
                          ASN1_Type type_tag,
112
                          ASN1_Class class_tag = ASN1_Class::ContextSpecific);
113
114
      template <typename Alloc>
115
      DER_Encoder& encode(const std::vector<uint8_t, Alloc>& bytes,
116
                          ASN1_Type real_type,
117
                          ASN1_Type type_tag,
118
0
                          ASN1_Class class_tag) {
119
0
         return encode(bytes.data(), bytes.size(), real_type, type_tag, class_tag);
120
0
      }
121
122
      template <typename T>
123
0
      DER_Encoder& encode_optional(const T& value, const T& default_value) {
124
0
         if(value != default_value) {
125
0
            encode(value);
126
0
         }
127
0
         return (*this);
128
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&)
129
130
      template <typename T>
131
537
      DER_Encoder& encode_list(const std::vector<T>& values) {
132
1.61k
         for(size_t i = 0; i != values.size(); ++i) {
133
1.07k
            encode(values[i]);
134
1.07k
         }
135
537
         return (*this);
136
537
      }
Botan::DER_Encoder& Botan::DER_Encoder::encode_list<Botan::BigInt>(std::__1::vector<Botan::BigInt, std::__1::allocator<Botan::BigInt> > const&)
Line
Count
Source
131
537
      DER_Encoder& encode_list(const std::vector<T>& values) {
132
1.61k
         for(size_t i = 0; i != values.size(); ++i) {
133
1.07k
            encode(values[i]);
134
1.07k
         }
135
537
         return (*this);
136
537
      }
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&)
Unexecuted instantiation: Botan::DER_Encoder& Botan::DER_Encoder::encode_list<Botan::Cert_Extension::CRL_Distribution_Points::Distribution_Point>(std::__1::vector<Botan::Cert_Extension::CRL_Distribution_Points::Distribution_Point, std::__1::allocator<Botan::Cert_Extension::CRL_Distribution_Points::Distribution_Point> > const&)
Unexecuted instantiation: Botan::DER_Encoder& Botan::DER_Encoder::encode_list<Botan::X509_Certificate>(std::__1::vector<Botan::X509_Certificate, std::__1::allocator<Botan::X509_Certificate> > const&)
137
138
      /*
139
      * Request for an object to encode itself to this stream
140
      */
141
      DER_Encoder& encode(const ASN1_Object& obj);
142
143
      /*
144
      * Conditionally write some values to the stream
145
      */
146
0
      DER_Encoder& encode_if(bool pred, DER_Encoder& enc) {
147
0
         if(pred) {
148
0
            return raw_bytes(enc.get_contents());
149
0
         }
150
0
         return (*this);
151
0
      }
152
153
0
      DER_Encoder& encode_if(bool pred, const ASN1_Object& obj) {
154
0
         if(pred) {
155
0
            encode(obj);
156
0
         }
157
0
         return (*this);
158
0
      }
159
160
0
      DER_Encoder& encode_if(bool pred, size_t num) {
161
0
         if(pred) {
162
0
            encode(num);
163
0
         }
164
0
         return (*this);
165
0
      }
166
167
      DER_Encoder& add_object(ASN1_Type type_tag, ASN1_Class class_tag, const uint8_t rep[], size_t length);
168
169
158k
      DER_Encoder& add_object(ASN1_Type type_tag, ASN1_Class class_tag, const std::vector<uint8_t>& rep) {
170
158k
         return add_object(type_tag, class_tag, rep.data(), rep.size());
171
158k
      }
172
173
17.3k
      DER_Encoder& add_object(ASN1_Type type_tag, ASN1_Class class_tag, const secure_vector<uint8_t>& rep) {
174
17.3k
         return add_object(type_tag, class_tag, rep.data(), rep.size());
175
17.3k
      }
176
177
      DER_Encoder& add_object(ASN1_Type type_tag, ASN1_Class class_tag, std::string_view str);
178
179
      DER_Encoder& add_object(ASN1_Type type_tag, ASN1_Class class_tag, uint8_t val);
180
181
   private:
182
      class DER_Sequence final {
183
         public:
184
            uint32_t tag_of() const;
185
186
            void push_contents(DER_Encoder& der);
187
188
            void add_bytes(const uint8_t val[], size_t len);
189
190
            void add_bytes(const uint8_t hdr[], size_t hdr_len, const uint8_t val[], size_t val_len);
191
192
            DER_Sequence(ASN1_Type, ASN1_Class);
193
194
            DER_Sequence(DER_Sequence&& seq) noexcept :
195
838k
                  m_type_tag(std::move(seq.m_type_tag)),
196
838k
                  m_class_tag(std::move(seq.m_class_tag)),
197
838k
                  m_contents(std::move(seq.m_contents)),
198
838k
                  m_set_contents(std::move(seq.m_set_contents)) {}
199
200
0
            DER_Sequence& operator=(DER_Sequence&& seq) noexcept {
201
0
               std::swap(m_type_tag, seq.m_type_tag);
202
0
               std::swap(m_class_tag, seq.m_class_tag);
203
0
               std::swap(m_contents, seq.m_contents);
204
0
               std::swap(m_set_contents, seq.m_set_contents);
205
0
               return (*this);
206
0
            }
207
208
            DER_Sequence(const DER_Sequence& seq) = default;
209
210
            DER_Sequence& operator=(const DER_Sequence& seq) = default;
211
212
         private:
213
            ASN1_Type m_type_tag;
214
            ASN1_Class m_class_tag;
215
            secure_vector<uint8_t> m_contents;
216
            std::vector<secure_vector<uint8_t>> m_set_contents;
217
      };
218
219
      append_fn m_append_output;
220
      secure_vector<uint8_t> m_default_outbuf;
221
      std::vector<DER_Sequence> m_subsequences;
222
};
223
224
}  // namespace Botan
225
226
#endif