aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/x509
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/x509
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/x509')
-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
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;