8#include <botan/der_enc.h>
9#include <botan/asn1_obj.h>
10#include <botan/bigint.h>
11#include <botan/loadstor.h>
12#include <botan/internal/bit_ops.h>
22void encode_tag(std::vector<uint8_t>& encoded_tag,
25 if((class_tag | 0xE0) != 0xE0)
26 throw Encoding_Error(
"DER_Encoder: Invalid class tag " +
31 encoded_tag.push_back(
static_cast<uint8_t
>(type_tag | class_tag));
35 size_t blocks =
high_bit(
static_cast<uint32_t
>(type_tag)) + 6;
36 blocks = (blocks - (blocks % 7)) / 7;
40 encoded_tag.push_back(
static_cast<uint8_t
>(class_tag | 0x1F));
41 for(
size_t i = 0; i != blocks - 1; ++i)
42 encoded_tag.push_back(0x80 | ((type_tag >> 7*(blocks-i-1)) & 0x7F));
43 encoded_tag.push_back(type_tag & 0x7F);
50void encode_length(std::vector<uint8_t>& encoded_length,
size_t length)
54 encoded_length.push_back(
static_cast<uint8_t
>(length));
60 encoded_length.push_back(
static_cast<uint8_t
>(0x80 | bytes_needed));
62 for(
size_t i =
sizeof(length) - bytes_needed; i <
sizeof(length); ++i)
63 encoded_length.push_back(
get_byte(i, length));
71 m_append_output = [&vec](
const uint8_t b[],
size_t l)
73 vec.insert(vec.end(), b, b + l);
79 m_append_output = [&vec](
const uint8_t b[],
size_t l)
81 vec.insert(vec.end(), b, b + l);
88void DER_Encoder::DER_Sequence::push_contents(
DER_Encoder& der)
94 std::sort(m_set_contents.begin(), m_set_contents.end());
95 for(
size_t i = 0; i != m_set_contents.size(); ++i)
96 m_contents += m_set_contents[i];
97 m_set_contents.clear();
100 der.
add_object(m_type_tag, real_class_tag, m_contents.data(), m_contents.size());
107void DER_Encoder::DER_Sequence::add_bytes(
const uint8_t data[],
size_t length)
109 if(m_type_tag ==
SET)
110 m_set_contents.push_back(secure_vector<uint8_t>(data, data + length));
112 m_contents += std::make_pair(data, length);
115void DER_Encoder::DER_Sequence::add_bytes(
const uint8_t hdr[],
size_t hdr_len,
116 const uint8_t val[],
size_t val_len)
118 if(m_type_tag ==
SET)
120 secure_vector<uint8_t> m;
121 m.reserve(hdr_len + val_len);
122 m += std::make_pair(hdr, hdr_len);
123 m += std::make_pair(val, val_len);
124 m_set_contents.push_back(std::move(m));
128 m_contents += std::make_pair(hdr, hdr_len);
129 m_contents += std::make_pair(val, val_len);
136ASN1_Tag DER_Encoder::DER_Sequence::tag_of()
const
138 return ASN1_Tag(m_type_tag | m_class_tag);
145 m_type_tag(t1), m_class_tag(t2)
154 if(m_subsequences.size() != 0)
155 throw Invalid_State(
"DER_Encoder: Sequence hasn't been marked done");
158 throw Invalid_State(
"DER_Encoder Cannot get contents when using output vector");
161 std::swap(output, m_default_outbuf);
167 if(m_subsequences.size() != 0)
168 throw Invalid_State(
"DER_Encoder: Sequence hasn't been marked done");
171 throw Invalid_State(
"DER_Encoder Cannot get contents when using output vector");
173 std::vector<uint8_t> output(m_default_outbuf.begin(), m_default_outbuf.end());
174 m_default_outbuf.clear();
184 m_subsequences.push_back(DER_Sequence(type_tag, class_tag));
193 if(m_subsequences.empty())
194 throw Invalid_State(
"DER_Encoder::end_cons: No such sequence");
196 DER_Sequence last_seq = std::move(m_subsequences[m_subsequences.size()-1]);
197 m_subsequences.pop_back();
198 last_seq.push_contents(*
this);
212 throw Internal_Error(
"DER_Encoder.start_explicit(SET) not supported");
230 if(m_subsequences.size())
232 m_subsequences[m_subsequences.size()-1].add_bytes(bytes, length);
234 else if(m_append_output)
236 m_append_output(bytes, length);
240 m_default_outbuf += std::make_pair(bytes, length);
250 const uint8_t rep[],
size_t length)
252 std::vector<uint8_t> hdr;
253 encode_tag(hdr, type_tag, class_tag);
254 encode_length(hdr, length);
256 if(m_subsequences.size())
258 m_subsequences[m_subsequences.size()-1].add_bytes(hdr.data(), hdr.size(), rep, length);
260 else if(m_append_output)
262 m_append_output(hdr.data(), hdr.size());
263 m_append_output(rep, length);
267 m_default_outbuf += hdr;
268 m_default_outbuf += std::make_pair(rep, length);
321 uint8_t val = is_true ? 0xFF : 0x00;
322 return add_object(type_tag, class_tag, &val, 1);
343 const size_t extra_zero = (n.
bits() % 8 == 0) ? 1 : 0;
348 for(
size_t i = 0; i != contents.size(); ++i)
349 contents[i] = ~contents[i];
350 for(
size_t i = contents.size(); i > 0; --i)
355 return add_object(type_tag, class_tag, contents);
371 encoded.push_back(0);
372 encoded += std::make_pair(bytes, length);
373 return add_object(type_tag, class_tag, encoded);
376 return add_object(type_tag, class_tag, bytes, length);
389 const std::string& rep_str)
392 const size_t rep_len = rep_str.size();
393 return add_object(type_tag, class_tag, rep, rep_len);
402 return add_object(type_tag, class_tag, &rep, 1);
#define BOTAN_ASSERT_NOMSG(expr)
virtual void encode_into(DER_Encoder &to) const =0
void binary_encode(uint8_t buf[]) const
secure_vector< uint8_t > get_contents()
DER_Encoder & end_explicit()
DER_Encoder & add_object(ASN1_Tag type_tag, ASN1_Tag class_tag, const uint8_t rep[], size_t length)
DER_Encoder & start_explicit(uint16_t type_tag)
DER_Encoder & start_cons(ASN1_Tag type_tag, ASN1_Tag class_tag=UNIVERSAL)
DER_Encoder & raw_bytes(const uint8_t val[], size_t len)
DER_Encoder & encode_null()
std::vector< uint8_t > get_contents_unlocked()
DER_Encoder & encode(bool b)
std::string to_string(const BER_Object &obj)
size_t significant_bytes(T n)
constexpr uint8_t get_byte(size_t byte_num, T input)
std::vector< T, secure_allocator< T > > secure_vector
const uint8_t * cast_char_ptr_to_uint8(const char *s)