diff options
author | Jack Lloyd <[email protected]> | 2017-11-14 09:20:09 -0500 |
---|---|---|
committer | Jack Lloyd <[email protected]> | 2017-11-14 16:19:44 -0500 |
commit | 9f8e50700367bc7775f5cb1fee9dab787316411f (patch) | |
tree | f378429e2e5937c6a7d7b53a377b477c166c5b06 | |
parent | af1158dd7707d09bcaf47fa78868d0cedf99c0e1 (diff) |
Store PKCS10 request data in structure
-rw-r--r-- | src/lib/x509/pkcs10.cpp | 133 | ||||
-rw-r--r-- | src/lib/x509/pkcs10.h | 17 |
2 files changed, 85 insertions, 65 deletions
diff --git a/src/lib/x509/pkcs10.cpp b/src/lib/x509/pkcs10.cpp index 911d6958c..cdcb5e985 100644 --- a/src/lib/x509/pkcs10.cpp +++ b/src/lib/x509/pkcs10.cpp @@ -1,6 +1,6 @@ /* * PKCS #10 -* (C) 1999-2007 Jack Lloyd +* (C) 1999-2007,2017 Jack Lloyd * * Botan is released under the Simplified BSD License (see license.txt) */ @@ -14,6 +14,15 @@ namespace Botan { +struct PKCS10_Data + { + X509_DN m_subject_dn; + std::vector<uint8_t> m_public_key_bits; + AlternativeName m_alt_name; + std::string m_challenge; + Extensions m_extensions; + }; + /* * PKCS10_Request Constructor */ @@ -46,9 +55,13 @@ PKCS10_Request::PKCS10_Request(const std::vector<uint8_t>& in) : /* * Decode the CertificateRequestInfo */ -void PKCS10_Request::force_decode() +namespace { + +std::unique_ptr<PKCS10_Data> decode_pkcs10(const std::vector<uint8_t>& body) { - BER_Decoder cert_req_info(signed_body()); + std::unique_ptr<PKCS10_Data> data(new PKCS10_Data); + + BER_Decoder cert_req_info(body); size_t version; cert_req_info.decode(version); @@ -56,22 +69,14 @@ void PKCS10_Request::force_decode() throw Decoding_Error("Unknown version code in PKCS #10 request: " + std::to_string(version)); - X509_DN dn_subject; - cert_req_info.decode(dn_subject); - - m_info.add(dn_subject.contents()); + cert_req_info.decode(data->m_subject_dn); BER_Object public_key = cert_req_info.get_next_object(); if(public_key.type_tag != SEQUENCE || public_key.class_tag != CONSTRUCTED) throw BER_Bad_Tag("PKCS10_Request: Unexpected tag for public key", public_key.type_tag, public_key.class_tag); - m_info.add("X509.Certificate.public_key", - PEM_Code::encode( - ASN1::put_in_sequence(unlock(public_key.value)), - "PUBLIC KEY" - ) - ); + data->m_public_key_bits = ASN1::put_in_sequence(unlock(public_key.value)); BER_Object attr_bits = cert_req_info.get_next_object(); @@ -83,7 +88,24 @@ void PKCS10_Request::force_decode() { Attribute attr; attributes.decode(attr); - handle_attribute(attr); + BER_Decoder value(attr.parameters); + + if(attr.oid == OIDS::lookup("PKCS9.EmailAddress")) + { + ASN1_String email; + value.decode(email); + data->m_alt_name.add_attribute("RFC822", email.value()); + } + else if(attr.oid == OIDS::lookup("PKCS9.ChallengePassword")) + { + ASN1_String challenge_password; + value.decode(challenge_password); + data->m_challenge = challenge_password.value(); + } + else if(attr.oid == OIDS::lookup("PKCS9.ExtensionRequest")) + { + value.decode(data->m_extensions).verify_end(); + } } attributes.verify_end(); } @@ -93,33 +115,31 @@ void PKCS10_Request::force_decode() cert_req_info.verify_end(); + // TODO pull AlternativeName out of extensions and merge with m_alt_name + + + return data; + } + +} + +void PKCS10_Request::force_decode() + { + m_data.reset(); + + std::unique_ptr<PKCS10_Data> data = decode_pkcs10(signed_body()); + + m_data.reset(data.release()); + if(!this->check_signature(subject_public_key())) throw Decoding_Error("PKCS #10 request: Bad signature detected"); } -/* -* Handle attributes in a PKCS #10 request -*/ -void PKCS10_Request::handle_attribute(const Attribute& attr) +const PKCS10_Data& PKCS10_Request::data() const { - BER_Decoder value(attr.parameters); - - if(attr.oid == OIDS::lookup("PKCS9.EmailAddress")) - { - ASN1_String email; - value.decode(email); - m_info.add("RFC822", email.value()); - } - else if(attr.oid == OIDS::lookup("PKCS9.ChallengePassword")) - { - ASN1_String challenge_password; - value.decode(challenge_password); - m_info.add("PKCS9.ChallengePassword", challenge_password.value()); - } - else if(attr.oid == OIDS::lookup("PKCS9.ExtensionRequest")) - { - value.decode(m_extensions).verify_end(); - } + if(m_data == nullptr) + throw Decoding_Error("PKCS10_Request decoding failed"); + return *m_data.get(); } /* @@ -127,24 +147,23 @@ void PKCS10_Request::handle_attribute(const Attribute& attr) */ std::string PKCS10_Request::challenge_password() const { - return m_info.get1("PKCS9.ChallengePassword"); + return data().m_challenge; } /* * Return the name of the requestor */ -X509_DN PKCS10_Request::subject_dn() const +const X509_DN& PKCS10_Request::subject_dn() const { - return create_dn(m_info); + return data().m_subject_dn; } /* * Return the public key of the requestor */ -std::vector<uint8_t> PKCS10_Request::raw_public_key() const +const std::vector<uint8_t>& PKCS10_Request::raw_public_key() const { - DataSource_Memory source(m_info.get1("X509.Certificate.public_key")); - return unlock(PEM_Code::decode_check_label(source, "PUBLIC KEY")); + return data().m_public_key_bits; } /* @@ -152,16 +171,24 @@ std::vector<uint8_t> PKCS10_Request::raw_public_key() const */ Public_Key* PKCS10_Request::subject_public_key() const { - DataSource_Memory source(m_info.get1("X509.Certificate.public_key")); + DataSource_Memory source(raw_public_key()); return X509::load_key(source); } /* * Return the alternative names of the requestor */ -AlternativeName PKCS10_Request::subject_alt_name() const +const AlternativeName& PKCS10_Request::subject_alt_name() const + { + return data().m_alt_name; + } + +/* +* Return the X509v3 extensions +*/ +const Extensions& PKCS10_Request::extensions() const { - return create_alt_name(m_info); + return data().m_extensions; } /* @@ -169,7 +196,7 @@ AlternativeName PKCS10_Request::subject_alt_name() const */ Key_Constraints PKCS10_Request::constraints() const { - if(auto ext = m_extensions.get(OIDS::lookup("X509v3.KeyUsage"))) + if(auto ext = extensions().get(OIDS::lookup("X509v3.KeyUsage"))) { return dynamic_cast<Cert_Extension::Key_Usage&>(*ext).get_constraints(); } @@ -182,7 +209,7 @@ Key_Constraints PKCS10_Request::constraints() const */ std::vector<OID> PKCS10_Request::ex_constraints() const { - if(auto ext = m_extensions.get(OIDS::lookup("X509v3.ExtendedKeyUsage"))) + if(auto ext = extensions().get(OIDS::lookup("X509v3.ExtendedKeyUsage"))) { return dynamic_cast<Cert_Extension::Extended_Key_Usage&>(*ext).get_oids(); } @@ -195,7 +222,7 @@ std::vector<OID> PKCS10_Request::ex_constraints() const */ bool PKCS10_Request::is_CA() const { - if(auto ext = m_extensions.get(OIDS::lookup("X509v3.BasicConstraints"))) + if(auto ext = extensions().get(OIDS::lookup("X509v3.BasicConstraints"))) { return dynamic_cast<Cert_Extension::Basic_Constraints&>(*ext).get_is_ca(); } @@ -208,7 +235,7 @@ bool PKCS10_Request::is_CA() const */ size_t PKCS10_Request::path_limit() const { - if(auto ext = m_extensions.get(OIDS::lookup("X509v3.BasicConstraints"))) + if(auto ext = extensions().get(OIDS::lookup("X509v3.BasicConstraints"))) { Cert_Extension::Basic_Constraints& basic_constraints = dynamic_cast<Cert_Extension::Basic_Constraints&>(*ext); if(basic_constraints.get_is_ca()) @@ -220,12 +247,4 @@ size_t PKCS10_Request::path_limit() const return 0; } -/* -* Return the X509v3 extensions -*/ -Extensions PKCS10_Request::extensions() const - { - return m_extensions; - } - } diff --git a/src/lib/x509/pkcs10.h b/src/lib/x509/pkcs10.h index 973b91b8a..abed5fa75 100644 --- a/src/lib/x509/pkcs10.h +++ b/src/lib/x509/pkcs10.h @@ -12,7 +12,6 @@ #include <botan/x509_obj.h> #include <botan/x509_dn.h> #include <botan/x509_ext.h> -#include <botan/datastor.h> #include <botan/key_constraint.h> #include <botan/asn1_attribute.h> #include <botan/asn1_alt_name.h> @@ -20,6 +19,8 @@ namespace Botan { +struct PKCS10_Data; + /** * PKCS #10 Certificate Request. */ @@ -36,19 +37,19 @@ class BOTAN_PUBLIC_API(2,0) PKCS10_Request final : public X509_Object * Get the raw DER encoded public key. * @return raw DER encoded public key */ - std::vector<uint8_t> raw_public_key() const; + const std::vector<uint8_t>& raw_public_key() const; /** * Get the subject DN. * @return subject DN */ - X509_DN subject_dn() const; + const X509_DN& subject_dn() const; /** * Get the subject alternative name. * @return subject alternative name. */ - AlternativeName subject_alt_name() const; + const AlternativeName& subject_alt_name() const; /** * Get the key constraints for the key associated with this @@ -86,7 +87,7 @@ class BOTAN_PUBLIC_API(2,0) PKCS10_Request final : public X509_Object * Get the X509v3 extensions. * @return X509v3 extensions */ - Extensions extensions() const; + const Extensions& extensions() const; /** * Create a PKCS#10 Request from a data source. @@ -110,10 +111,10 @@ class BOTAN_PUBLIC_API(2,0) PKCS10_Request final : public X509_Object explicit PKCS10_Request(const std::vector<uint8_t>& vec); private: void force_decode() override; - void handle_attribute(const Attribute&); - Data_Store m_info; - Extensions m_extensions; + const PKCS10_Data& data() const; + + std::shared_ptr<PKCS10_Data> m_data; }; } |