aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/asn1/der_enc.cpp
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2018-05-22 11:04:15 -0400
committerJack Lloyd <[email protected]>2018-05-22 11:04:15 -0400
commit3789138906cecbcc5e33bb0d5784e6b576171080 (patch)
tree147c442020bec8ad6effe62727fdb6b300d0f7f7 /src/lib/asn1/der_enc.cpp
parentcd0bcd90817ece3e4fcba32e06a372580bbe3008 (diff)
DER improvements
Let DER_Encoder write to a user specified vector instead of only to an internal vector. This allows encoding to a std::vector without having to first write to a locked vector and then copying out the result. Add ASN1_Object::BER_encode convenience method. Replaces X509_Object::BER_encode which had the same logic but was restricted to a subtype. This replaces many cases where DER_Encoder was just used to encode a single object (X509_DN, AlgorithmIdentifier, etc).
Diffstat (limited to 'src/lib/asn1/der_enc.cpp')
-rw-r--r--src/lib/asn1/der_enc.cpp85
1 files changed, 58 insertions, 27 deletions
diff --git a/src/lib/asn1/der_enc.cpp b/src/lib/asn1/der_enc.cpp
index 461768180..c1ec010a0 100644
--- a/src/lib/asn1/der_enc.cpp
+++ b/src/lib/asn1/der_enc.cpp
@@ -66,6 +66,22 @@ void encode_length(std::vector<uint8_t>& encoded_length, size_t length)
}
+DER_Encoder::DER_Encoder(secure_vector<uint8_t>& vec)
+ {
+ m_append_output_fn = [&vec](const uint8_t b[], size_t l)
+ {
+ vec.insert(vec.end(), b, b + l);
+ };
+ }
+
+DER_Encoder::DER_Encoder(std::vector<uint8_t>& vec)
+ {
+ m_append_output_fn = [&vec](const uint8_t b[], size_t l)
+ {
+ vec.insert(vec.end(), b, b + l);
+ };
+ }
+
/*
* Push the encoded SEQUENCE/SET to the encoder stream
*/
@@ -138,8 +154,11 @@ secure_vector<uint8_t> DER_Encoder::get_contents()
if(m_subsequences.size() != 0)
throw Invalid_State("DER_Encoder: Sequence hasn't been marked done");
+ if(m_append_output_fn)
+ throw Invalid_State("DER_Encoder Cannot get contents when using output vector");
+
secure_vector<uint8_t> output;
- std::swap(output, m_contents);
+ std::swap(output, m_default_outbuf);
return output;
}
@@ -148,8 +167,11 @@ std::vector<uint8_t> DER_Encoder::get_contents_unlocked()
if(m_subsequences.size() != 0)
throw Invalid_State("DER_Encoder: Sequence hasn't been marked done");
- std::vector<uint8_t> output(m_contents.begin(), m_contents.end());
- m_contents.clear();
+ if(m_append_output_fn)
+ throw Invalid_State("DER_Encoder Cannot get contents when using output vector");
+
+ std::vector<uint8_t> output(m_default_outbuf.begin(), m_default_outbuf.end());
+ m_default_outbuf.clear();
return output;
}
@@ -209,9 +231,41 @@ DER_Encoder& DER_Encoder::raw_bytes(const uint8_t bytes[], size_t length)
{
m_subsequences[m_subsequences.size()-1].add_bytes(bytes, length);
}
+ else if(m_append_output_fn)
+ {
+ m_append_output_fn(bytes, length);
+ }
else
{
- m_contents += std::make_pair(bytes, length);
+ m_default_outbuf += std::make_pair(bytes, length);
+ }
+
+ return (*this);
+ }
+
+/*
+* Write the encoding of the byte(s)
+*/
+DER_Encoder& DER_Encoder::add_object(ASN1_Tag type_tag, ASN1_Tag class_tag,
+ const uint8_t rep[], size_t length)
+ {
+ std::vector<uint8_t> hdr;
+ encode_tag(hdr, type_tag, class_tag);
+ encode_length(hdr, length);
+
+ if(m_subsequences.size())
+ {
+ m_subsequences[m_subsequences.size()-1].add_bytes(hdr.data(), hdr.size(), rep, length);
+ }
+ else if(m_append_output_fn)
+ {
+ m_append_output_fn(hdr.data(), hdr.size());
+ m_append_output_fn(rep, length);
+ }
+ else
+ {
+ m_default_outbuf += hdr;
+ m_default_outbuf += std::make_pair(rep, length);
}
return (*this);
@@ -332,29 +386,6 @@ DER_Encoder& DER_Encoder::encode(const ASN1_Object& obj)
* Write the encoding of the byte(s)
*/
DER_Encoder& DER_Encoder::add_object(ASN1_Tag type_tag, ASN1_Tag class_tag,
- const uint8_t rep[], size_t length)
- {
- std::vector<uint8_t> hdr;
- encode_tag(hdr, type_tag, class_tag);
- encode_length(hdr, length);
-
- if(m_subsequences.size())
- {
- m_subsequences[m_subsequences.size()-1].add_bytes(hdr.data(), hdr.size(), rep, length);
- }
- else
- {
- m_contents += hdr;
- m_contents += std::make_pair(rep, length);
- }
-
- return (*this);
- }
-
-/*
-* Write the encoding of the byte(s)
-*/
-DER_Encoder& DER_Encoder::add_object(ASN1_Tag type_tag, ASN1_Tag class_tag,
const std::string& rep_str)
{
const uint8_t* rep = cast_char_ptr_to_uint8(rep_str.data());