Coverage Report

Created: 2025-07-11 06:15

/src/Botan-3.4.0/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")
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
      }
Unexecuted instantiation: Botan::DER_Encoder& Botan::DER_Encoder::raw_bytes<std::__1::allocator<unsigned char> >(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > const&)
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&)
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
         }
128
         return (*this);
129
      }
130
131
      template <typename T>
132
0
      DER_Encoder& encode_list(const std::vector<T>& values) {
133
0
         for(size_t i = 0; i != values.size(); ++i) {
134
0
            encode(values[i]);
135
0
         }
136
0
         return (*this);
137
0
      }
138
139
      /*
140
      * Request for an object to encode itself to this stream
141
      */
142
      DER_Encoder& encode(const ASN1_Object& obj);
143
144
      /*
145
      * Conditionally write some values to the stream
146
      */
147
0
      DER_Encoder& encode_if(bool pred, DER_Encoder& enc) {
148
0
         if(pred) {
149
0
            return raw_bytes(enc.get_contents());
150
0
         }
151
0
         return (*this);
152
0
      }
153
154
0
      DER_Encoder& encode_if(bool pred, const ASN1_Object& obj) {
155
0
         if(pred) {
156
0
            encode(obj);
157
0
         }
158
0
         return (*this);
159
0
      }
160
161
      DER_Encoder& add_object(ASN1_Type type_tag, ASN1_Class class_tag, const uint8_t rep[], size_t length);
162
163
0
      DER_Encoder& add_object(ASN1_Type type_tag, ASN1_Class class_tag, const std::vector<uint8_t>& rep) {
164
0
         return add_object(type_tag, class_tag, rep.data(), rep.size());
165
0
      }
166
167
0
      DER_Encoder& add_object(ASN1_Type type_tag, ASN1_Class class_tag, const secure_vector<uint8_t>& rep) {
168
0
         return add_object(type_tag, class_tag, rep.data(), rep.size());
169
0
      }
170
171
      DER_Encoder& add_object(ASN1_Type type_tag, ASN1_Class class_tag, std::string_view str);
172
173
      DER_Encoder& add_object(ASN1_Type type_tag, ASN1_Class class_tag, uint8_t val);
174
175
   private:
176
      class DER_Sequence final {
177
         public:
178
            uint32_t tag_of() const;
179
180
            void push_contents(DER_Encoder& der);
181
182
            void add_bytes(const uint8_t val[], size_t len);
183
184
            void add_bytes(const uint8_t hdr[], size_t hdr_len, const uint8_t val[], size_t val_len);
185
186
            DER_Sequence(ASN1_Type, ASN1_Class);
187
188
            DER_Sequence(DER_Sequence&& seq) noexcept :
189
0
                  m_type_tag(std::move(seq.m_type_tag)),
190
0
                  m_class_tag(std::move(seq.m_class_tag)),
191
0
                  m_contents(std::move(seq.m_contents)),
192
0
                  m_set_contents(std::move(seq.m_set_contents)) {}
193
194
0
            DER_Sequence& operator=(DER_Sequence&& seq) noexcept {
195
0
               std::swap(m_type_tag, seq.m_type_tag);
196
0
               std::swap(m_class_tag, seq.m_class_tag);
197
0
               std::swap(m_contents, seq.m_contents);
198
0
               std::swap(m_set_contents, seq.m_set_contents);
199
0
               return (*this);
200
0
            }
201
202
            DER_Sequence(const DER_Sequence& seq) = default;
203
204
            DER_Sequence& operator=(const DER_Sequence& seq) = default;
205
206
         private:
207
            ASN1_Type m_type_tag;
208
            ASN1_Class m_class_tag;
209
            secure_vector<uint8_t> m_contents;
210
            std::vector<secure_vector<uint8_t>> m_set_contents;
211
      };
212
213
      append_fn m_append_output;
214
      secure_vector<uint8_t> m_default_outbuf;
215
      std::vector<DER_Sequence> m_subsequences;
216
};
217
218
}  // namespace Botan
219
220
#endif