aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/asn1/asn1_obj.cpp17
-rw-r--r--src/lib/asn1/asn1_obj.h9
-rw-r--r--src/lib/asn1/asn1_print.cpp5
-rw-r--r--src/lib/asn1/der_enc.cpp85
-rw-r--r--src/lib/asn1/der_enc.h23
-rw-r--r--src/lib/kdf/prf_x942/prf_x942.cpp5
-rw-r--r--src/lib/pk_pad/emsa_pssr/pssr.cpp28
-rw-r--r--src/lib/pubkey/dl_algo/dl_algo.cpp4
-rw-r--r--src/lib/pubkey/dl_group/dl_group.cpp25
-rw-r--r--src/lib/pubkey/ec_group/ec_group.cpp20
-rw-r--r--src/lib/pubkey/gost_3410/gost_3410.cpp13
-rw-r--r--src/lib/pubkey/mce/mceliece_key.cpp7
-rw-r--r--src/lib/pubkey/pbes2/pbes2.cpp35
-rw-r--r--src/lib/pubkey/pk_keys.cpp14
-rw-r--r--src/lib/pubkey/pkcs8.cpp43
-rw-r--r--src/lib/pubkey/pubkey.cpp7
-rw-r--r--src/lib/pubkey/rsa/rsa.cpp10
-rw-r--r--src/lib/x509/certstor_sql/certstor_sql.cpp37
-rw-r--r--src/lib/x509/ocsp.cpp7
-rw-r--r--src/lib/x509/x509_ext.cpp60
-rw-r--r--src/lib/x509/x509_obj.cpp28
-rw-r--r--src/lib/x509/x509_obj.h5
22 files changed, 287 insertions, 200 deletions
diff --git a/src/lib/asn1/asn1_obj.cpp b/src/lib/asn1/asn1_obj.cpp
index bbe469f5c..98f44d407 100644
--- a/src/lib/asn1/asn1_obj.cpp
+++ b/src/lib/asn1/asn1_obj.cpp
@@ -1,6 +1,6 @@
/*
* ASN.1 Internals
-* (C) 1999-2007 Jack Lloyd
+* (C) 1999-2007,2018 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
@@ -12,6 +12,14 @@
namespace Botan {
+std::vector<uint8_t> ASN1_Object::BER_encode() const
+ {
+ std::vector<uint8_t> output;
+ DER_Encoder der(output);
+ this->encode_into(der);
+ return output;
+ }
+
/*
* Check a type invariant on BER data
*/
@@ -132,11 +140,12 @@ std::vector<uint8_t> put_in_sequence(const std::vector<uint8_t>& contents)
std::vector<uint8_t> put_in_sequence(const uint8_t bits[], size_t len)
{
- return DER_Encoder()
+ std::vector<uint8_t> output;
+ DER_Encoder(output)
.start_cons(SEQUENCE)
.raw_bytes(bits, len)
- .end_cons()
- .get_contents_unlocked();
+ .end_cons();
+ return output;
}
/*
diff --git a/src/lib/asn1/asn1_obj.h b/src/lib/asn1/asn1_obj.h
index 2c2a3097a..b9477da09 100644
--- a/src/lib/asn1/asn1_obj.h
+++ b/src/lib/asn1/asn1_obj.h
@@ -1,6 +1,6 @@
/*
* ASN.1 Internals
-* (C) 1999-2007 Jack Lloyd
+* (C) 1999-2007,2018 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
@@ -76,6 +76,13 @@ class BOTAN_PUBLIC_API(2,0) ASN1_Object
*/
virtual void decode_from(BER_Decoder& from) = 0;
+ /**
+ * Return the encoding of this object. This is a convenience
+ * method when just one object needs to be serialized. Use
+ * DER_Encoder for complicated encodings.
+ */
+ std::vector<uint8_t> BER_encode() const;
+
ASN1_Object() = default;
ASN1_Object(const ASN1_Object&) = default;
ASN1_Object & operator=(const ASN1_Object&) = default;
diff --git a/src/lib/asn1/asn1_print.cpp b/src/lib/asn1/asn1_print.cpp
index cb223e130..1f9178266 100644
--- a/src/lib/asn1/asn1_print.cpp
+++ b/src/lib/asn1/asn1_print.cpp
@@ -87,9 +87,8 @@ void ASN1_Formatter::decode(std::ostream& output,
/* hack to insert the tag+length back in front of the stuff now
that we've gotten the type info */
- DER_Encoder encoder;
- encoder.add_object(type_tag, class_tag, obj.bits(), obj.length());
- const std::vector<uint8_t> bits = encoder.get_contents_unlocked();
+ std::vector<uint8_t> bits;
+ DER_Encoder(bits).add_object(type_tag, class_tag, obj.bits(), obj.length());
BER_Decoder data(bits);
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());
diff --git a/src/lib/asn1/der_enc.h b/src/lib/asn1/der_enc.h
index ebca73d33..f351817f9 100644
--- a/src/lib/asn1/der_enc.h
+++ b/src/lib/asn1/der_enc.h
@@ -10,6 +10,7 @@
#include <botan/asn1_obj.h>
#include <vector>
+#include <functional>
namespace Botan {
@@ -22,6 +23,25 @@ class ASN1_Object;
class BOTAN_PUBLIC_API(2,0) DER_Encoder final
{
public:
+ /**
+ * DER encode, writing to an internal buffer
+ * Use get_contents or get_contents_unlocked to read the results
+ * after all encoding is completed.
+ */
+ DER_Encoder() = default;
+
+ /**
+ * DER encode, writing to @param vec
+ * If this constructor is used, get_contents* may not be called.
+ */
+ DER_Encoder(secure_vector<uint8_t>& vec);
+
+ /**
+ * DER encode, writing to @param vec
+ * If this constructor is used, get_contents* may not be called.
+ */
+ DER_Encoder(std::vector<uint8_t>& vec);
+
secure_vector<uint8_t> get_contents();
std::vector<uint8_t> get_contents_unlocked();
@@ -183,7 +203,8 @@ class BOTAN_PUBLIC_API(2,0) DER_Encoder final
std::vector< secure_vector<uint8_t> > m_set_contents;
};
- secure_vector<uint8_t> m_contents;
+ std::function<void (const uint8_t[], size_t)> m_append_output_fn;
+ secure_vector<uint8_t> m_default_outbuf;
std::vector<DER_Sequence> m_subsequences;
};
diff --git a/src/lib/kdf/prf_x942/prf_x942.cpp b/src/lib/kdf/prf_x942/prf_x942.cpp
index 1abb4e77e..978892ef0 100644
--- a/src/lib/kdf/prf_x942/prf_x942.cpp
+++ b/src/lib/kdf/prf_x942/prf_x942.cpp
@@ -23,7 +23,10 @@ std::vector<uint8_t> encode_x942_int(uint32_t n)
{
uint8_t n_buf[4] = { 0 };
store_be(n, n_buf);
- return DER_Encoder().encode(n_buf, 4, OCTET_STRING).get_contents_unlocked();
+
+ std::vector<uint8_t> output;
+ DER_Encoder(output).encode(n_buf, 4, OCTET_STRING);
+ return output;
}
}
diff --git a/src/lib/pk_pad/emsa_pssr/pssr.cpp b/src/lib/pk_pad/emsa_pssr/pssr.cpp
index abe84f455..97b229be3 100644
--- a/src/lib/pk_pad/emsa_pssr/pssr.cpp
+++ b/src/lib/pk_pad/emsa_pssr/pssr.cpp
@@ -186,24 +186,16 @@ AlgorithmIdentifier PSSR::config_for_x509(const Private_Key& key,
// hardcoded as RSA is the only valid algorithm for EMSA4 at the moment
sig_algo.oid = OIDS::lookup( "RSA/EMSA4" );
- sig_algo.parameters = DER_Encoder()
- .start_cons( SEQUENCE )
- .start_cons( ASN1_Tag(0), CONTEXT_SPECIFIC )
- .encode( AlgorithmIdentifier( cert_hash_name, AlgorithmIdentifier::USE_NULL_PARAM ) )
- .end_cons()
- .start_cons( ASN1_Tag(1), CONTEXT_SPECIFIC )
- .encode( AlgorithmIdentifier( "MGF1", DER_Encoder()
- .encode( AlgorithmIdentifier( cert_hash_name, AlgorithmIdentifier::USE_NULL_PARAM ) )
- .get_contents_unlocked() ) )
- .end_cons()
- .start_cons( ASN1_Tag(2), CONTEXT_SPECIFIC )
- .encode( size_t( m_SALT_SIZE ) )
- .end_cons()
- .start_cons( ASN1_Tag(3), CONTEXT_SPECIFIC )
- .encode( size_t( 1 ) ) // trailer field
- .end_cons()
- .end_cons()
- .get_contents_unlocked();
+ const AlgorithmIdentifier hash_id(cert_hash_name, AlgorithmIdentifier::USE_NULL_PARAM);
+ const AlgorithmIdentifier mgf_id("MGF1", hash_id.BER_encode());
+
+ DER_Encoder(sig_algo.parameters)
+ .start_cons(SEQUENCE)
+ .start_cons(ASN1_Tag(0), CONTEXT_SPECIFIC).encode(hash_id).end_cons()
+ .start_cons(ASN1_Tag(1), CONTEXT_SPECIFIC).encode(mgf_id).end_cons()
+ .start_cons(ASN1_Tag(2), CONTEXT_SPECIFIC).encode(m_SALT_SIZE).end_cons()
+ .start_cons(ASN1_Tag(3), CONTEXT_SPECIFIC).encode(size_t(1)).end_cons() // trailer field
+ .end_cons();
return sig_algo;
}
diff --git a/src/lib/pubkey/dl_algo/dl_algo.cpp b/src/lib/pubkey/dl_algo/dl_algo.cpp
index f9d6178b0..15b0b175e 100644
--- a/src/lib/pubkey/dl_algo/dl_algo.cpp
+++ b/src/lib/pubkey/dl_algo/dl_algo.cpp
@@ -30,7 +30,9 @@ AlgorithmIdentifier DL_Scheme_PublicKey::algorithm_identifier() const
std::vector<uint8_t> DL_Scheme_PublicKey::public_key_bits() const
{
- return DER_Encoder().encode(m_y).get_contents_unlocked();
+ std::vector<uint8_t> output;
+ DER_Encoder(output).encode(m_y);
+ return output;
}
DL_Scheme_PublicKey::DL_Scheme_PublicKey(const DL_Group& group, const BigInt& y) :
diff --git a/src/lib/pubkey/dl_group/dl_group.cpp b/src/lib/pubkey/dl_group/dl_group.cpp
index 9bab123cb..6a2d21c8b 100644
--- a/src/lib/pubkey/dl_group/dl_group.cpp
+++ b/src/lib/pubkey/dl_group/dl_group.cpp
@@ -457,37 +457,36 @@ std::vector<uint8_t> DL_Group::DER_encode(Format format) const
if(get_q().is_zero() && (format == ANSI_X9_57 || format == ANSI_X9_42))
throw Encoding_Error("Cannot encode DL_Group in ANSI formats when q param is missing");
+ std::vector<uint8_t> output;
+ DER_Encoder der(output);
+
if(format == ANSI_X9_57)
{
- return DER_Encoder()
- .start_cons(SEQUENCE)
+ der.start_cons(SEQUENCE)
.encode(get_p())
.encode(get_q())
.encode(get_g())
- .end_cons()
- .get_contents_unlocked();
+ .end_cons();
}
else if(format == ANSI_X9_42)
{
- return DER_Encoder()
- .start_cons(SEQUENCE)
+ der.start_cons(SEQUENCE)
.encode(get_p())
.encode(get_g())
.encode(get_q())
- .end_cons()
- .get_contents_unlocked();
+ .end_cons();
}
else if(format == PKCS_3)
{
- return DER_Encoder()
- .start_cons(SEQUENCE)
+ der.start_cons(SEQUENCE)
.encode(get_p())
.encode(get_g())
- .end_cons()
- .get_contents_unlocked();
+ .end_cons();
}
+ else
+ throw Invalid_Argument("Unknown DL_Group encoding " + std::to_string(format));
- throw Invalid_Argument("Unknown DL_Group encoding " + std::to_string(format));
+ return output;
}
/*
diff --git a/src/lib/pubkey/ec_group/ec_group.cpp b/src/lib/pubkey/ec_group/ec_group.cpp
index ac23aa151..004708c7c 100644
--- a/src/lib/pubkey/ec_group/ec_group.cpp
+++ b/src/lib/pubkey/ec_group/ec_group.cpp
@@ -550,6 +550,10 @@ PointGFp EC_Group::zero_point() const
std::vector<uint8_t>
EC_Group::DER_encode(EC_Group_Encoding form) const
{
+ std::vector<uint8_t> output;
+
+ DER_Encoder der(output);
+
if(form == EC_DOMPAR_ENC_EXPLICIT)
{
const size_t ecpVers1 = 1;
@@ -557,8 +561,7 @@ EC_Group::DER_encode(EC_Group_Encoding form) const
const size_t p_bytes = get_p_bytes();
- return DER_Encoder()
- .start_cons(SEQUENCE)
+ der.start_cons(SEQUENCE)
.encode(ecpVers1)
.start_cons(SEQUENCE)
.encode(curve_type)
@@ -573,8 +576,7 @@ EC_Group::DER_encode(EC_Group_Encoding form) const
.encode(get_base_point().encode(PointGFp::UNCOMPRESSED), OCTET_STRING)
.encode(get_order())
.encode(get_cofactor())
- .end_cons()
- .get_contents_unlocked();
+ .end_cons();
}
else if(form == EC_DOMPAR_ENC_OID)
{
@@ -583,12 +585,18 @@ EC_Group::DER_encode(EC_Group_Encoding form) const
{
throw Encoding_Error("Cannot encode EC_Group as OID because OID not set");
}
- return DER_Encoder().encode(oid).get_contents_unlocked();
+ der.encode(oid);
}
else if(form == EC_DOMPAR_ENC_IMPLICITCA)
- return DER_Encoder().encode_null().get_contents_unlocked();
+ {
+ der.encode_null();
+ }
else
+ {
throw Internal_Error("EC_Group::DER_encode: Unknown encoding");
+ }
+
+ return output;
}
std::string EC_Group::PEM_encode() const
diff --git a/src/lib/pubkey/gost_3410/gost_3410.cpp b/src/lib/pubkey/gost_3410/gost_3410.cpp
index 1d1b0d75e..d6e8874ab 100644
--- a/src/lib/pubkey/gost_3410/gost_3410.cpp
+++ b/src/lib/pubkey/gost_3410/gost_3410.cpp
@@ -35,16 +35,19 @@ std::vector<uint8_t> GOST_3410_PublicKey::public_key_bits() const
std::swap(bits[part_size+i], bits[2*part_size-1-i]);
}
- return DER_Encoder().encode(bits, OCTET_STRING).get_contents_unlocked();
+ std::vector<uint8_t> output;
+ DER_Encoder(output).encode(bits, OCTET_STRING);
+ return output;
}
AlgorithmIdentifier GOST_3410_PublicKey::algorithm_identifier() const
{
- std::vector<uint8_t> params =
- DER_Encoder().start_cons(SEQUENCE)
+ std::vector<uint8_t> params;
+
+ DER_Encoder(params)
+ .start_cons(SEQUENCE)
.encode(domain().get_curve_oid())
- .end_cons()
- .get_contents_unlocked();
+ .end_cons();
return AlgorithmIdentifier(get_oid(), params);
}
diff --git a/src/lib/pubkey/mce/mceliece_key.cpp b/src/lib/pubkey/mce/mceliece_key.cpp
index 67ff8f635..4fe78d2a1 100644
--- a/src/lib/pubkey/mce/mceliece_key.cpp
+++ b/src/lib/pubkey/mce/mceliece_key.cpp
@@ -72,15 +72,16 @@ AlgorithmIdentifier McEliece_PublicKey::algorithm_identifier() const
std::vector<uint8_t> McEliece_PublicKey::public_key_bits() const
{
- return DER_Encoder()
+ std::vector<uint8_t> output;
+ DER_Encoder(output)
.start_cons(SEQUENCE)
.start_cons(SEQUENCE)
.encode(static_cast<size_t>(get_code_length()))
.encode(static_cast<size_t>(get_t()))
.end_cons()
.encode(m_public_matrix, OCTET_STRING)
- .end_cons()
- .get_contents_unlocked();
+ .end_cons();
+ return output;
}
size_t McEliece_PublicKey::key_length() const
diff --git a/src/lib/pubkey/pbes2/pbes2.cpp b/src/lib/pubkey/pbes2/pbes2.cpp
index e7bdf96ec..a6590938a 100644
--- a/src/lib/pubkey/pbes2/pbes2.cpp
+++ b/src/lib/pubkey/pbes2/pbes2.cpp
@@ -29,29 +29,30 @@ std::vector<uint8_t> encode_pbes2_params(const std::string& cipher,
size_t iterations,
size_t key_length)
{
- return DER_Encoder()
+ std::vector<uint8_t> output;
+
+ std::vector<uint8_t> pbkdf2_params;
+
+ DER_Encoder(pbkdf2_params)
.start_cons(SEQUENCE)
- .encode(
- AlgorithmIdentifier("PKCS5.PBKDF2",
- DER_Encoder()
- .start_cons(SEQUENCE)
- .encode(salt, OCTET_STRING)
- .encode(iterations)
- .encode(key_length)
- .encode_if(
- prf != "HMAC(SHA-160)",
- AlgorithmIdentifier(prf, AlgorithmIdentifier::USE_NULL_PARAM))
- .end_cons()
- .get_contents_unlocked()
- )
- )
+ .encode(salt, OCTET_STRING)
+ .encode(iterations)
+ .encode(key_length)
+ .encode_if(prf != "HMAC(SHA-160)",
+ AlgorithmIdentifier(prf, AlgorithmIdentifier::USE_NULL_PARAM))
+ .end_cons();
+
+ DER_Encoder(output)
+ .start_cons(SEQUENCE)
+ .encode(AlgorithmIdentifier("PKCS5.PBKDF2", pbkdf2_params))
.encode(
AlgorithmIdentifier(cipher,
DER_Encoder().encode(iv, OCTET_STRING).get_contents_unlocked()
)
)
- .end_cons()
- .get_contents_unlocked();
+ .end_cons();
+
+ return output;
}
/*
diff --git a/src/lib/pubkey/pk_keys.cpp b/src/lib/pubkey/pk_keys.cpp
index cdf8ae8ff..fbbc6f7dd 100644
--- a/src/lib/pubkey/pk_keys.cpp
+++ b/src/lib/pubkey/pk_keys.cpp
@@ -37,12 +37,14 @@ std::string create_hex_fingerprint(const uint8_t bits[],
std::vector<uint8_t> Public_Key::subject_public_key() const
{
- return DER_Encoder()
- .start_cons(SEQUENCE)
- .encode(algorithm_identifier())
- .encode(public_key_bits(), BIT_STRING)
- .end_cons()
- .get_contents_unlocked();
+ std::vector<uint8_t> output;
+
+ DER_Encoder(output).start_cons(SEQUENCE)
+ .encode(algorithm_identifier())
+ .encode(public_key_bits(), BIT_STRING)
+ .end_cons();
+
+ return output;
}
/*
diff --git a/src/lib/pubkey/pkcs8.cpp b/src/lib/pubkey/pkcs8.cpp
index bea3beec0..1034dfa99 100644
--- a/src/lib/pubkey/pkcs8.cpp
+++ b/src/lib/pubkey/pkcs8.cpp
@@ -192,12 +192,14 @@ std::vector<uint8_t> BER_encode(const Private_Key& key,
pbes2_encrypt_msec(PKCS8::BER_encode(key), pass, msec, nullptr,
pbe_params.first, pbe_params.second, rng);
- return DER_Encoder()
- .start_cons(SEQUENCE)
- .encode(pbe_info.first)
- .encode(pbe_info.second, OCTET_STRING)
- .end_cons()
- .get_contents_unlocked();
+ std::vector<uint8_t> output;
+ DER_Encoder der(output);
+ der.start_cons(SEQUENCE)
+ .encode(pbe_info.first)
+ .encode(pbe_info.second, OCTET_STRING)
+ .end_cons();
+
+ return output;
#else
BOTAN_UNUSED(key, rng, pass, msec, pbe_algo);
throw Encoding_Error("PKCS8::BER_encode cannot encrypt because PBES2 was disabled in build");
@@ -238,12 +240,15 @@ std::vector<uint8_t> BER_encode_encrypted_pbkdf_iter(const Private_Key& key,
pbkdf_hash.empty() ? "SHA-256" : pbkdf_hash,
rng);
- return DER_Encoder()
- .start_cons(SEQUENCE)
- .encode(pbe_info.first)
- .encode(pbe_info.second, OCTET_STRING)
- .end_cons()
- .get_contents_unlocked();
+ std::vector<uint8_t> output;
+ DER_Encoder der(output);
+ der.start_cons(SEQUENCE)
+ .encode(pbe_info.first)
+ .encode(pbe_info.second, OCTET_STRING)
+ .end_cons();
+
+ return output;
+
#else
BOTAN_UNUSED(key, rng, pass, pbkdf_iterations, cipher, pbkdf_hash);
throw Encoding_Error("PKCS8::BER_encode_encrypted_pbkdf_iter cannot encrypt because PBES2 disabled in build");
@@ -284,12 +289,14 @@ std::vector<uint8_t> BER_encode_encrypted_pbkdf_msec(const Private_Key& key,
pbkdf_hash.empty() ? "SHA-256" : pbkdf_hash,
rng);
- return DER_Encoder()
- .start_cons(SEQUENCE)
- .encode(pbe_info.first)
- .encode(pbe_info.second, OCTET_STRING)
- .end_cons()
- .get_contents_unlocked();
+ std::vector<uint8_t> output;
+ DER_Encoder(output)
+ .start_cons(SEQUENCE)
+ .encode(pbe_info.first)
+ .encode(pbe_info.second, OCTET_STRING)
+ .end_cons();
+
+ return output;
#else
BOTAN_UNUSED(key, rng, pass, pbkdf_msec, pbkdf_iterations, cipher, pbkdf_hash);
throw Encoding_Error("BER_encode_encrypted_pbkdf_msec cannot encrypt because PBES2 disabled in build");
diff --git a/src/lib/pubkey/pubkey.cpp b/src/lib/pubkey/pubkey.cpp
index d9b2cc8f6..bc476b30d 100644
--- a/src/lib/pubkey/pubkey.cpp
+++ b/src/lib/pubkey/pubkey.cpp
@@ -246,11 +246,12 @@ std::vector<uint8_t> PK_Signer::signature(RandomNumberGenerator& rng)
for(size_t i = 0; i != sig_parts.size(); ++i)
sig_parts[i].binary_decode(&sig[m_part_size*i], m_part_size);
- return DER_Encoder()
+ std::vector<uint8_t> output;
+ DER_Encoder(output)
.start_cons(SEQUENCE)
.encode_list(sig_parts)
- .end_cons()
- .get_contents_unlocked();
+ .end_cons();
+ return output;
}
else
throw Internal_Error("PK_Signer: Invalid signature format enum");
diff --git a/src/lib/pubkey/rsa/rsa.cpp b/src/lib/pubkey/rsa/rsa.cpp
index fdc5b63d0..b58724c63 100644
--- a/src/lib/pubkey/rsa/rsa.cpp
+++ b/src/lib/pubkey/rsa/rsa.cpp
@@ -45,12 +45,14 @@ AlgorithmIdentifier RSA_PublicKey::algorithm_identifier() const
std::vector<uint8_t> RSA_PublicKey::public_key_bits() const
{
- return DER_Encoder()
- .start_cons(SEQUENCE)
+ std::vector<uint8_t> output;
+ DER_Encoder der(output);
+ der.start_cons(SEQUENCE)
.encode(m_n)
.encode(m_e)
- .end_cons()
- .get_contents_unlocked();
+ .end_cons();
+
+ return output;
}
RSA_PublicKey::RSA_PublicKey(const AlgorithmIdentifier&,
diff --git a/src/lib/x509/certstor_sql/certstor_sql.cpp b/src/lib/x509/certstor_sql/certstor_sql.cpp
index d2991a019..1ffa2e8ca 100644
--- a/src/lib/x509/certstor_sql/certstor_sql.cpp
+++ b/src/lib/x509/certstor_sql/certstor_sql.cpp
@@ -1,6 +1,7 @@
/*
* Certificate Store in SQL
* (C) 2016 Kai Michaelis, Rohde & Schwarz Cybersecurity
+* (C) 2018 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
@@ -8,7 +9,6 @@
#include <botan/certstor_sql.h>
#include <botan/pk_keys.h>
#include <botan/ber_dec.h>
-#include <botan/der_enc.h>
#include <botan/pkcs8.h>
#include <botan/data_src.h>
@@ -46,21 +46,20 @@ Certificate_Store_In_SQL::Certificate_Store_In_SQL(std::shared_ptr<SQL_Database>
std::shared_ptr<const X509_Certificate>
Certificate_Store_In_SQL::find_cert(const X509_DN& subject_dn, const std::vector<uint8_t>& key_id) const
{
- DER_Encoder enc;
std::shared_ptr<SQL_Database::Statement> stmt;
- subject_dn.encode_into(enc);
+ const std::vector<uint8_t> dn_encoding = subject_dn.BER_encode();
if(key_id.empty())
{
stmt = m_database->new_statement("SELECT certificate FROM " + m_prefix + "certificates WHERE subject_dn == ?1");
- stmt->bind(1,enc.get_contents_unlocked());
+ stmt->bind(1, dn_encoding);
}
else
{
stmt = m_database->new_statement("SELECT certificate FROM " + m_prefix + "certificates WHERE\
subject_dn == ?1 AND (key_id == NULL OR key_id == ?2)");
- stmt->bind(1,enc.get_contents_unlocked());
+ stmt->bind(1, dn_encoding);
stmt->bind(2,key_id);
}
@@ -81,22 +80,21 @@ Certificate_Store_In_SQL::find_all_certs(const X509_DN& subject_dn, const std::v
{
std::vector<std::shared_ptr<const X509_Certificate>> certs;
- DER_Encoder enc;
std::shared_ptr<SQL_Database::Statement> stmt;
- subject_dn.encode_into(enc);
+ const std::vector<uint8_t> dn_encoding = subject_dn.BER_encode();
if(key_id.empty())
{
stmt = m_database->new_statement("SELECT certificate FROM " + m_prefix + "certificates WHERE subject_dn == ?1");
- stmt->bind(1,enc.get_contents_unlocked());
+ stmt->bind(1, dn_encoding);
}
else
{
stmt = m_database->new_statement("SELECT certificate FROM " + m_prefix + "certificates WHERE\
subject_dn == ?1 AND (key_id == NULL OR key_id == ?2)");
- stmt->bind(1,enc.get_contents_unlocked());
- stmt->bind(2,key_id);
+ stmt->bind(1, dn_encoding);
+ stmt->bind(2, key_id);
}
std::shared_ptr<const X509_Certificate> cert;
@@ -113,13 +111,13 @@ Certificate_Store_In_SQL::find_all_certs(const X509_DN& subject_dn, const std::v
std::shared_ptr<const X509_Certificate>
Certificate_Store_In_SQL::find_cert_by_pubkey_sha1(const std::vector<uint8_t>& /*key_hash*/) const
{
- throw Not_Implemented("TODO!");
+ throw Not_Implemented("Certificate_Store_In_SQL::find_cert_by_pubkey_sha1");
}
std::shared_ptr<const X509_Certificate>
Certificate_Store_In_SQL::find_cert_by_raw_subject_dn_sha256(const std::vector<uint8_t>& /*subject_hash*/) const
{
- throw Not_Implemented("TODO!");
+ throw Not_Implemented("Certificate_Store_In_SQL::find_cert_by_raw_subject_dn_sha256");
}
std::shared_ptr<const X509_CRL>
@@ -157,7 +155,9 @@ std::vector<X509_DN> Certificate_Store_In_SQL::all_subjects() const
bool Certificate_Store_In_SQL::insert_cert(const X509_Certificate& cert)
{
- DER_Encoder enc;
+ const std::vector<uint8_t> dn_encoding = cert.subject_dn().BER_encode();
+ const std::vector<uint8_t> cert_encoding = cert.BER_encode();
+
auto stmt = m_database->new_statement("INSERT OR REPLACE INTO " +
m_prefix + "certificates (\
fingerprint, \
@@ -168,13 +168,10 @@ bool Certificate_Store_In_SQL::insert_cert(const X509_Certificate& cert)
) VALUES ( ?1, ?2, ?3, ?4, ?5 )");
stmt->bind(1,cert.fingerprint("SHA-256"));
- cert.subject_dn().encode_into(enc);
- stmt->bind(2,enc.get_contents_unlocked());
+ stmt->bind(2,dn_encoding);
stmt->bind(3,cert.subject_key_id());
stmt->bind(4,std::vector<uint8_t>());
- enc = DER_Encoder();
- cert.encode_into(enc);
- stmt->bind(5,enc.get_contents_unlocked());
+ stmt->bind(5,cert_encoding);
stmt->spin();
return true;
@@ -281,9 +278,7 @@ void Certificate_Store_In_SQL::revoke_cert(const X509_Certificate& cert, CRL_Cod
if(time.time_is_set())
{
- DER_Encoder der;
- time.encode_into(der);
- stmt1->bind(3,der.get_contents_unlocked());
+ stmt1->bind(3, time.BER_encode());
}
else
{
diff --git a/src/lib/x509/ocsp.cpp b/src/lib/x509/ocsp.cpp
index 751f858a5..115c4117a 100644
--- a/src/lib/x509/ocsp.cpp
+++ b/src/lib/x509/ocsp.cpp
@@ -68,7 +68,8 @@ Request::Request(const X509_Certificate& issuer_cert,
std::vector<uint8_t> Request::BER_encode() const
{
- return DER_Encoder().start_cons(SEQUENCE)
+ std::vector<uint8_t> output;
+ DER_Encoder(output).start_cons(SEQUENCE)
.start_cons(SEQUENCE)
.start_explicit(0)
.encode(static_cast<size_t>(0)) // version #
@@ -79,7 +80,9 @@ std::vector<uint8_t> Request::BER_encode() const
.end_cons()
.end_cons()
.end_cons()
- .end_cons().get_contents_unlocked();
+ .end_cons();
+
+ return output;
}
std::string Request::base64_encode() const
diff --git a/src/lib/x509/x509_ext.cpp b/src/lib/x509/x509_ext.cpp
index 9686eacda..122be2885 100644
--- a/src/lib/x509/x509_ext.cpp
+++ b/src/lib/x509/x509_ext.cpp
@@ -300,15 +300,16 @@ size_t Basic_Constraints::get_path_limit() const
*/
std::vector<uint8_t> Basic_Constraints::encode_inner() const
{
- return DER_Encoder()
+ std::vector<uint8_t> output;
+ DER_Encoder(output)
.start_cons(SEQUENCE)
.encode_if(m_is_ca,
DER_Encoder()
.encode(m_is_ca)
.encode_optional(m_path_limit, NO_CERT_PATH_LIMIT)
)
- .end_cons()
- .get_contents_unlocked();
+ .end_cons();
+ return output;
}
/*
@@ -404,7 +405,9 @@ void Key_Usage::contents_to(Data_Store& subject, Data_Store&) const
*/
std::vector<uint8_t> Subject_Key_ID::encode_inner() const
{
- return DER_Encoder().encode(m_key_id, OCTET_STRING).get_contents_unlocked();
+ std::vector<uint8_t> output;
+ DER_Encoder(output).encode(m_key_id, OCTET_STRING);
+ return output;
}
/*
@@ -446,11 +449,12 @@ Subject_Key_ID::Subject_Key_ID(const std::vector<uint8_t>& pub_key, const std::s
*/
std::vector<uint8_t> Authority_Key_ID::encode_inner() const
{
- return DER_Encoder()
- .start_cons(SEQUENCE)
- .encode(m_key_id, OCTET_STRING, ASN1_Tag(0), CONTEXT_SPECIFIC)
- .end_cons()
- .get_contents_unlocked();
+ std::vector<uint8_t> output;
+ DER_Encoder(output)
+ .start_cons(SEQUENCE)
+ .encode(m_key_id, OCTET_STRING, ASN1_Tag(0), CONTEXT_SPECIFIC)
+ .end_cons();
+ return output;
}
/*
@@ -477,7 +481,9 @@ void Authority_Key_ID::contents_to(Data_Store&, Data_Store& issuer) const
*/
std::vector<uint8_t> Subject_Alternative_Name::encode_inner() const
{
- return DER_Encoder().encode(m_alt_name).get_contents_unlocked();
+ std::vector<uint8_t> output;
+ DER_Encoder(output).encode(m_alt_name);
+ return output;
}
/*
@@ -485,7 +491,9 @@ std::vector<uint8_t> Subject_Alternative_Name::encode_inner() const
*/
std::vector<uint8_t> Issuer_Alternative_Name::encode_inner() const
{
- return DER_Encoder().encode(m_alt_name).get_contents_unlocked();
+ std::vector<uint8_t> output;
+ DER_Encoder(output).encode(m_alt_name);
+ return output;
}
/*
@@ -526,11 +534,12 @@ void Issuer_Alternative_Name::contents_to(Data_Store&, Data_Store& issuer_info)
*/
std::vector<uint8_t> Extended_Key_Usage::encode_inner() const
{
- return DER_Encoder()
+ std::vector<uint8_t> output;
+ DER_Encoder(output)
.start_cons(SEQUENCE)
.encode_list(m_oids)
- .end_cons()
- .get_contents_unlocked();
+ .end_cons();
+ return output;
}
/*
@@ -724,11 +733,12 @@ std::vector<uint8_t> Certificate_Policies::encode_inner() const
for(size_t i = 0; i != m_oids.size(); ++i)
policies.push_back(Policy_Information(m_oids[i]));
- return DER_Encoder()
+ std::vector<uint8_t> output;
+ DER_Encoder(output)
.start_cons(SEQUENCE)
.encode_list(policies)
- .end_cons()
- .get_contents_unlocked();
+ .end_cons();
+ return output;
}
/*
@@ -771,13 +781,15 @@ std::vector<uint8_t> Authority_Information_Access::encode_inner() const
{
ASN1_String url(m_ocsp_responder, IA5_STRING);
- return DER_Encoder()
+ std::vector<uint8_t> output;
+ DER_Encoder(output)
.start_cons(SEQUENCE)
.start_cons(SEQUENCE)
.encode(OIDS::lookup("PKIX.OCSP"))
.add_object(ASN1_Tag(6), CONTEXT_SPECIFIC, url.value())
.end_cons()
- .end_cons().get_contents_unlocked();
+ .end_cons();
+ return output;
}
void Authority_Information_Access::decode_inner(const std::vector<uint8_t>& in)
@@ -847,7 +859,9 @@ CRL_Number* CRL_Number::copy() const
*/
std::vector<uint8_t> CRL_Number::encode_inner() const
{
- return DER_Encoder().encode(m_crl_number).get_contents_unlocked();
+ std::vector<uint8_t> output;
+ DER_Encoder(output).encode(m_crl_number);
+ return output;
}
/*
@@ -872,9 +886,9 @@ void CRL_Number::contents_to(Data_Store& info, Data_Store&) const
*/
std::vector<uint8_t> CRL_ReasonCode::encode_inner() const
{
- return DER_Encoder()
- .encode(static_cast<size_t>(m_reason), ENUMERATED, UNIVERSAL)
- .get_contents_unlocked();
+ std::vector<uint8_t> output;
+ DER_Encoder(output).encode(static_cast<size_t>(m_reason), ENUMERATED, UNIVERSAL);
+ return output;
}
/*
diff --git a/src/lib/x509/x509_obj.cpp b/src/lib/x509/x509_obj.cpp
index 41cf74acc..060453072 100644
--- a/src/lib/x509/x509_obj.cpp
+++ b/src/lib/x509/x509_obj.cpp
@@ -29,14 +29,14 @@ struct Pss_params
Pss_params decode_pss_params(const std::vector<uint8_t>& encoded_pss_params)
{
+ const AlgorithmIdentifier default_hash("SHA-160", AlgorithmIdentifier::USE_NULL_PARAM);
+ const AlgorithmIdentifier default_mgf("MGF1", default_hash.BER_encode());
+
Pss_params pss_parameter;
BER_Decoder(encoded_pss_params)
.start_cons(SEQUENCE)
- .decode_optional(pss_parameter.hash_algo, ASN1_Tag(0), PRIVATE, AlgorithmIdentifier("SHA-160",
- AlgorithmIdentifier::USE_NULL_PARAM))
- .decode_optional(pss_parameter.mask_gen_algo, ASN1_Tag(1), PRIVATE,
- AlgorithmIdentifier("MGF1", DER_Encoder().encode(AlgorithmIdentifier("SHA-160",
- AlgorithmIdentifier::USE_NULL_PARAM)).get_contents_unlocked()))
+ .decode_optional(pss_parameter.hash_algo, ASN1_Tag(0), PRIVATE, default_hash)
+ .decode_optional(pss_parameter.mask_gen_algo, ASN1_Tag(1), PRIVATE, default_mgf)
.decode_optional(pss_parameter.salt_len, ASN1_Tag(2), PRIVATE, size_t(20))
.decode_optional(pss_parameter.trailer_field, ASN1_Tag(3), PRIVATE, size_t(1))
.end_cons();
@@ -118,16 +118,6 @@ void X509_Object::decode_from(BER_Decoder& from)
}
/*
-* Return a BER encoded X.509 object
-*/
-std::vector<uint8_t> X509_Object::BER_encode() const
- {
- DER_Encoder der;
- encode_into(der);
- return der.get_contents_unlocked();
- }
-
-/*
* Return a PEM encoded X.509 object
*/
std::string X509_Object::PEM_encode() const
@@ -284,13 +274,15 @@ std::vector<uint8_t> X509_Object::make_signed(PK_Signer* signer,
{
const std::vector<uint8_t> signature = signer->sign_message(tbs_bits, rng);
- return DER_Encoder()
+ std::vector<uint8_t> output;
+ DER_Encoder(output)
.start_cons(SEQUENCE)
.raw_bytes(tbs_bits)
.encode(algo)
.encode(signature, BIT_STRING)
- .end_cons()
- .get_contents_unlocked();
+ .end_cons();
+
+ return output;
}
namespace {
diff --git a/src/lib/x509/x509_obj.h b/src/lib/x509/x509_obj.h
index 1e4abe00b..a0c8e5b39 100644
--- a/src/lib/x509/x509_obj.h
+++ b/src/lib/x509/x509_obj.h
@@ -102,11 +102,6 @@ class BOTAN_PUBLIC_API(2,0) X509_Object : public ASN1_Object
void decode_from(class BER_Decoder& from) override;
/**
- * @return BER encoding of this
- */
- std::vector<uint8_t> BER_encode() const;
-
- /**
* @return PEM encoding of this
*/
std::string PEM_encode() const;