diff options
author | Jack Lloyd <[email protected]> | 2018-05-22 11:04:15 -0400 |
---|---|---|
committer | Jack Lloyd <[email protected]> | 2018-05-22 11:04:15 -0400 |
commit | 3789138906cecbcc5e33bb0d5784e6b576171080 (patch) | |
tree | 147c442020bec8ad6effe62727fdb6b300d0f7f7 /src/lib/x509 | |
parent | cd0bcd90817ece3e4fcba32e06a372580bbe3008 (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/x509')
-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 |
5 files changed, 68 insertions, 69 deletions
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; |