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/parsing.h>
13 #include <botan/internal/bit_ops.h>
25 if((class_tag | 0xE0) != 0xE0)
26 throw Encoding_Error(
"DER_Encoder: Invalid class tag " +
29 secure_vector<uint8_t> encoded_tag;
31 encoded_tag.push_back(static_cast<uint8_t>(type_tag | class_tag));
34 size_t blocks =
high_bit(type_tag) + 6;
35 blocks = (blocks - (blocks % 7)) / 7;
39 encoded_tag.push_back(class_tag | 0x1F);
40 for(
size_t i = 0; i != blocks - 1; ++i)
41 encoded_tag.push_back(0x80 | ((type_tag >> 7*(blocks-i-1)) & 0x7F));
42 encoded_tag.push_back(type_tag & 0x7F);
51 secure_vector<uint8_t> encode_length(
size_t length)
53 secure_vector<uint8_t> encoded_length;
55 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));
65 return encoded_length;
73 secure_vector<uint8_t> DER_Encoder::DER_Sequence::get_contents()
79 std::sort(m_set_contents.begin(), m_set_contents.end());
80 for(
size_t i = 0; i != m_set_contents.size(); ++i)
81 m_contents += m_set_contents[i];
82 m_set_contents.clear();
85 secure_vector<uint8_t> result;
86 result += encode_tag(m_type_tag, real_class_tag);
87 result += encode_length(m_contents.size());
97 void DER_Encoder::DER_Sequence::add_bytes(
const uint8_t data[],
size_t length)
100 m_set_contents.push_back(secure_vector<uint8_t>(data, data + length));
102 m_contents += std::make_pair(data, length);
108 ASN1_Tag DER_Encoder::DER_Sequence::tag_of()
const
110 return ASN1_Tag(m_type_tag | m_class_tag);
117 m_type_tag(t1), m_class_tag(t2)
126 if(m_subsequences.size() != 0)
127 throw Invalid_State(
"DER_Encoder: Sequence hasn't been marked done");
130 std::swap(output, m_contents);
140 m_subsequences.push_back(DER_Sequence(type_tag, class_tag));
149 if(m_subsequences.empty())
150 throw Invalid_State(
"DER_Encoder::end_cons: No such sequence");
153 m_subsequences.pop_back();
166 throw Internal_Error(
"DER_Encoder.start_explicit(SET); cannot perform");
184 return raw_bytes(val.data(), val.size());
189 return raw_bytes(val.data(), val.size());
197 if(m_subsequences.size())
198 m_subsequences[m_subsequences.size()-1].add_bytes(bytes, length);
200 m_contents += std::make_pair(bytes, length);
243 return encode(bytes.data(), bytes.size(),
253 return encode(bytes.data(), bytes.size(),
272 uint8_t val = is_true ? 0xFF : 0x00;
273 return add_object(type_tag, class_tag, &val, 1);
294 bool extra_zero = (n.
bits() % 8 == 0);
299 for(
size_t i = 0; i != contents.size(); ++i)
300 contents[i] = ~contents[i];
301 for(
size_t i = contents.size(); i > 0; --i)
306 return add_object(type_tag, class_tag, contents);
316 return encode(bytes.data(), bytes.size(),
317 real_type, type_tag, class_tag);
327 return encode(bytes.data(), bytes.size(),
328 real_type, type_tag, class_tag);
344 encoded.push_back(0);
345 encoded += std::make_pair(bytes, length);
346 return add_object(type_tag, class_tag, encoded);
349 return add_object(type_tag, class_tag, bytes, length);
382 const uint8_t rep[],
size_t length)
385 buffer += encode_tag(type_tag, class_tag);
386 buffer += encode_length(length);
387 buffer += std::make_pair(rep, length);
396 const std::string& rep_str)
398 const uint8_t* rep =
reinterpret_cast<const uint8_t*
>(rep_str.data());
399 const size_t rep_len = rep_str.size();
400 return add_object(type_tag, class_tag, rep, rep_len);
409 return add_object(type_tag, class_tag, &rep, 1);
DER_Encoder & add_object(ASN1_Tag type_tag, ASN1_Tag class_tag, const uint8_t rep[], size_t length)
size_t significant_bytes(T n)
secure_vector< uint8_t > get_contents()
DER_Encoder & end_explicit()
std::string to_string(const BER_Object &obj)
DER_Encoder & raw_bytes(const uint8_t val[], size_t len)
#define BOTAN_ASSERT(expr, assertion_made)
DER_Encoder & encode(bool b)
std::vector< T, secure_allocator< T >> secure_vector
DER_Encoder & encode_null()
virtual void encode_into(DER_Encoder &to) const =0
DER_Encoder & encode_if(bool pred, DER_Encoder &enc)
DER_Encoder & start_cons(ASN1_Tag type_tag, ASN1_Tag class_tag=UNIVERSAL)
uint8_t get_byte(size_t byte_num, T input)
static std::vector< uint8_t > encode(const BigInt &n, Base base=Binary)
DER_Encoder & start_explicit(uint16_t type_tag)