diff options
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/asn1/asn1_obj.cpp | 17 | ||||
-rw-r--r-- | src/lib/asn1/asn1_obj.h | 9 | ||||
-rw-r--r-- | src/lib/asn1/asn1_print.cpp | 5 | ||||
-rw-r--r-- | src/lib/asn1/der_enc.cpp | 85 | ||||
-rw-r--r-- | src/lib/asn1/der_enc.h | 23 | ||||
-rw-r--r-- | src/lib/kdf/prf_x942/prf_x942.cpp | 5 | ||||
-rw-r--r-- | src/lib/pk_pad/emsa_pssr/pssr.cpp | 28 | ||||
-rw-r--r-- | src/lib/pubkey/dl_algo/dl_algo.cpp | 4 | ||||
-rw-r--r-- | src/lib/pubkey/dl_group/dl_group.cpp | 25 | ||||
-rw-r--r-- | src/lib/pubkey/ec_group/ec_group.cpp | 20 | ||||
-rw-r--r-- | src/lib/pubkey/gost_3410/gost_3410.cpp | 13 | ||||
-rw-r--r-- | src/lib/pubkey/mce/mceliece_key.cpp | 7 | ||||
-rw-r--r-- | src/lib/pubkey/pbes2/pbes2.cpp | 35 | ||||
-rw-r--r-- | src/lib/pubkey/pk_keys.cpp | 14 | ||||
-rw-r--r-- | src/lib/pubkey/pkcs8.cpp | 43 | ||||
-rw-r--r-- | src/lib/pubkey/pubkey.cpp | 7 | ||||
-rw-r--r-- | src/lib/pubkey/rsa/rsa.cpp | 10 | ||||
-rw-r--r-- | src/lib/x509/certstor_sql/certstor_sql.cpp | 37 | ||||
-rw-r--r-- | src/lib/x509/ocsp.cpp | 7 | ||||
-rw-r--r-- | src/lib/x509/x509_ext.cpp | 60 | ||||
-rw-r--r-- | src/lib/x509/x509_obj.cpp | 28 | ||||
-rw-r--r-- | src/lib/x509/x509_obj.h | 5 |
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; |