diff options
author | lloyd <[email protected]> | 2012-05-25 22:52:00 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2012-05-25 22:52:00 +0000 |
commit | 12090a7148d9ee73572cc1a7268fc489504a8173 (patch) | |
tree | 51e50ce0852c56231e9e6dc13f168b10edd45d01 /src/cert | |
parent | 9594979caf775dc4062850044715b804d1fda60c (diff) | |
parent | 65cc04445f8d40497f02a14bd8cb97081790e54b (diff) |
propagate from branch 'net.randombit.botan.x509-path-validation' (head 63b5a20eab129ca13287fda33d2d02eec329708f)
to branch 'net.randombit.botan' (head 8b8150f09c55184f028f2929c4e7f7cd0d46d96e)
Diffstat (limited to 'src/cert')
36 files changed, 477 insertions, 425 deletions
diff --git a/src/cert/cvc/asn1_eac_tm.cpp b/src/cert/cvc/asn1_eac_tm.cpp index db5d2fbaf..a3a4d043d 100644 --- a/src/cert/cvc/asn1_eac_tm.cpp +++ b/src/cert/cvc/asn1_eac_tm.cpp @@ -1,7 +1,7 @@ /* * EAC Time Types * (C) 2007 FlexSecure GmbH -* 2008 Jack Lloyd +* 2008-2009 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -12,17 +12,17 @@ #include <botan/charset.h> #include <botan/parsing.h> #include <botan/internal/rounding.h> -#include <botan/time.h> +#include <botan/calendar.h> namespace Botan { namespace { -SecureVector<byte> enc_two_digit(u32bit in) +secure_vector<byte> enc_two_digit(u32bit in) { - SecureVector<byte> result; + secure_vector<byte> result; in %= 100; - if (in < 10) + if(in < 10) result.push_back(0x00); else { @@ -51,9 +51,10 @@ u32bit dec_two_digit(byte b1, byte b2) /* * Create an EAC_Time */ -EAC_Time::EAC_Time(u64bit timer, ASN1_Tag t) : tag(t) +EAC_Time::EAC_Time(const std::chrono::system_clock::time_point& time, + ASN1_Tag t) : tag(t) { - calendar_point cal = calendar_value(timer); + calendar_point cal = calendar_value(time); year = cal.year; month = cal.month; @@ -67,6 +68,7 @@ EAC_Time::EAC_Time(const std::string& t_spec, ASN1_Tag t) : tag(t) { set_to(t_spec); } + /* * Create an EAC_Time */ @@ -80,7 +82,7 @@ EAC_Time::EAC_Time(u32bit y, u32bit m, u32bit d, ASN1_Tag t) : */ void EAC_Time::set_to(const std::string& time_str) { - if (time_str == "") + if(time_str == "") { year = month = day = 0; return; @@ -89,28 +91,28 @@ void EAC_Time::set_to(const std::string& time_str) std::vector<std::string> params; std::string current; - for (u32bit j = 0; j != time_str.size(); ++j) + for(u32bit j = 0; j != time_str.size(); ++j) { - if (Charset::is_digit(time_str[j])) + if(Charset::is_digit(time_str[j])) current += time_str[j]; else { - if (current != "") + if(current != "") params.push_back(current); current.clear(); } } - if (current != "") + if(current != "") params.push_back(current); - if (params.size() != 3) + if(params.size() != 3) throw Invalid_Argument("Invalid time specification " + time_str); year = to_u32bit(params[0]); month = to_u32bit(params[1]); day = to_u32bit(params[2]); - if (!passes_sanity_check()) + if(!passes_sanity_check()) throw Invalid_Argument("Invalid time specification " + time_str); } @@ -129,15 +131,10 @@ void EAC_Time::encode_into(DER_Encoder& der) const */ std::string EAC_Time::as_string() const { - if (time_is_set() == false) + if(time_is_set() == false) throw Invalid_State("EAC_Time::as_string: No time set"); - std::string asn1rep; - asn1rep = to_string(year, 2); - - asn1rep += to_string(month, 2) + to_string(day, 2); - - return asn1rep; + return std::to_string(year * 10000 + month * 100 + day); } /* @@ -153,15 +150,14 @@ bool EAC_Time::time_is_set() const */ std::string EAC_Time::readable_string() const { - if (time_is_set() == false) + if(time_is_set() == false) throw Invalid_State("EAC_Time::readable_string: No time set"); - std::string readable; - readable += to_string(year, 2) + "/"; - readable += to_string(month, 2) + "/"; - readable += to_string(day, 2) + " "; + std::string output(11, 0); - return readable; + std::sprintf(&output[0], "%04d/%02d/%02d", year, month, day); + + return output; } /* @@ -169,11 +165,11 @@ std::string EAC_Time::readable_string() const */ bool EAC_Time::passes_sanity_check() const { - if (year < 2000 || year > 2099) + if(year < 2000 || year > 2099) return false; - if (month == 0 || month > 12) + if(month == 0 || month > 12) return false; - if (day == 0 || day > 31) + if(day == 0 || day > 31) return false; return true; @@ -182,11 +178,11 @@ bool EAC_Time::passes_sanity_check() const /* * modification functions */ - void EAC_Time::add_years(u32bit years) { year += years; } + void EAC_Time::add_months(u32bit months) { year += months/12; @@ -198,23 +194,22 @@ void EAC_Time::add_months(u32bit months) } } - /* * Compare this time against another */ s32bit EAC_Time::cmp(const EAC_Time& other) const { - if (time_is_set() == false) + if(time_is_set() == false) throw Invalid_State("EAC_Time::cmp: No time set"); const s32bit EARLIER = -1, LATER = 1, SAME_TIME = 0; - if (year < other.year) return EARLIER; - if (year > other.year) return LATER; - if (month < other.month) return EARLIER; - if (month > other.month) return LATER; - if (day < other.day) return EARLIER; - if (day > other.day) return LATER; + if(year < other.year) return EARLIER; + if(year > other.year) return LATER; + if(month < other.month) return EARLIER; + if(month > other.month) return LATER; + if(day < other.day) return EARLIER; + if(day > other.day) return LATER; return SAME_TIME; } @@ -283,61 +278,16 @@ void EAC_Time::decode_from(BER_Decoder& source) } -u32bit EAC_Time::get_year() const - { - return year; - } - -u32bit EAC_Time::get_month() const - { - return month; - } - -u32bit EAC_Time::get_day() const - { - return day; - } - /* * make the value an octet string for encoding */ -SecureVector<byte> EAC_Time::encoded_eac_time() const +secure_vector<byte> EAC_Time::encoded_eac_time() const { - SecureVector<byte> result; + secure_vector<byte> result; result += enc_two_digit(year); result += enc_two_digit(month); result += enc_two_digit(day); return result; } -ASN1_Ced::ASN1_Ced(std::string const& str) : - EAC_Time(str, ASN1_Tag(37)) - {} - -ASN1_Ced::ASN1_Ced(u64bit val) : - EAC_Time(val, ASN1_Tag(37)) - {} - -ASN1_Ced::ASN1_Ced(EAC_Time const& other) : - EAC_Time(other.get_year(), - other.get_month(), - other.get_day(), - ASN1_Tag(37)) - {} - -ASN1_Cex::ASN1_Cex(std::string const& str) : - EAC_Time(str, ASN1_Tag(36)) - {} - -ASN1_Cex::ASN1_Cex(u64bit val) : - EAC_Time(val, ASN1_Tag(36)) - {} - -ASN1_Cex::ASN1_Cex(EAC_Time const& other) : - EAC_Time(other.get_year(), - other.get_month(), - other.get_day(), - ASN1_Tag(36)) - {} - } diff --git a/src/cert/cvc/cvc_ado.cpp b/src/cert/cvc/cvc_ado.cpp index 38f51e8dc..f224d15b9 100644 --- a/src/cert/cvc/cvc_ado.cpp +++ b/src/cert/cvc/cvc_ado.cpp @@ -26,7 +26,7 @@ EAC1_1_ADO::EAC1_1_ADO(const std::string& in) void EAC1_1_ADO::force_decode() { - SecureVector<byte> inner_cert; + secure_vector<byte> inner_cert; BER_Decoder(tbs_bits) .start_cons(ASN1_Tag(33)) .raw_bytes(inner_cert) @@ -34,7 +34,7 @@ void EAC1_1_ADO::force_decode() .decode(m_car) .verify_end(); - SecureVector<byte> req_bits = DER_Encoder() + secure_vector<byte> req_bits = DER_Encoder() .start_cons(ASN1_Tag(33), APPLICATION) .raw_bytes(inner_cert) .end_cons() @@ -45,11 +45,11 @@ void EAC1_1_ADO::force_decode() sig_algo = m_req.sig_algo; } -MemoryVector<byte> EAC1_1_ADO::make_signed(PK_Signer& signer, - const MemoryRegion<byte>& tbs_bits, +std::vector<byte> EAC1_1_ADO::make_signed(PK_Signer& signer, + const secure_vector<byte>& tbs_bits, RandomNumberGenerator& rng) { - SecureVector<byte> concat_sig = signer.sign_message(tbs_bits, rng); + secure_vector<byte> concat_sig = signer.sign_message(tbs_bits, rng); return DER_Encoder() .start_cons(ASN1_Tag(7), APPLICATION) @@ -65,11 +65,11 @@ ASN1_Car EAC1_1_ADO::get_car() const } void EAC1_1_ADO::decode_info(DataSource& source, - SecureVector<byte> & res_tbs_bits, + secure_vector<byte> & res_tbs_bits, ECDSA_Signature & res_sig) { - SecureVector<byte> concat_sig; - SecureVector<byte> cert_inner_bits; + secure_vector<byte> concat_sig; + secure_vector<byte> cert_inner_bits; ASN1_Car car; BER_Decoder(source) @@ -81,7 +81,7 @@ void EAC1_1_ADO::decode_info(DataSource& source, .decode(concat_sig, OCTET_STRING, ASN1_Tag(55), APPLICATION) .end_cons(); - SecureVector<byte> enc_cert = DER_Encoder() + secure_vector<byte> enc_cert = DER_Encoder() .start_cons(ASN1_Tag(33), APPLICATION) .raw_bytes(cert_inner_bits) .end_cons() @@ -97,7 +97,7 @@ void EAC1_1_ADO::encode(Pipe& out, X509_Encoding encoding) const if(encoding == PEM) throw Invalid_Argument("EAC1_1_ADO::encode() cannot PEM encode an EAC object"); - SecureVector<byte> concat_sig( + secure_vector<byte> concat_sig( EAC1_1_obj<EAC1_1_ADO>::m_sig.get_concatenation()); out.write(DER_Encoder() @@ -108,7 +108,7 @@ void EAC1_1_ADO::encode(Pipe& out, X509_Encoding encoding) const .get_contents()); } -SecureVector<byte> EAC1_1_ADO::tbs_data() const +secure_vector<byte> EAC1_1_ADO::tbs_data() const { return tbs_bits; } diff --git a/src/cert/cvc/cvc_ado.h b/src/cert/cvc/cvc_ado.h index 65a39fd91..81b89ea00 100644 --- a/src/cert/cvc/cvc_ado.h +++ b/src/cert/cvc/cvc_ado.h @@ -43,9 +43,9 @@ class BOTAN_DLL EAC1_1_ADO : public EAC1_1_obj<EAC1_1_ADO> * @param tbs_bits the TBS data to sign * @param rng a random number generator */ - static MemoryVector<byte> make_signed( + static std::vector<byte> make_signed( PK_Signer& signer, - const MemoryRegion<byte>& tbs_bits, + const secure_vector<byte>& tbs_bits, RandomNumberGenerator& rng); /** @@ -73,7 +73,7 @@ class BOTAN_DLL EAC1_1_ADO : public EAC1_1_obj<EAC1_1_ADO> * Get the TBS data of this CVC ADO request. * @result the TBS data */ - SecureVector<byte> tbs_data() const; + secure_vector<byte> tbs_data() const; virtual ~EAC1_1_ADO() {} private: @@ -82,7 +82,7 @@ class BOTAN_DLL EAC1_1_ADO : public EAC1_1_obj<EAC1_1_ADO> void force_decode(); static void decode_info(DataSource& source, - SecureVector<byte> & res_tbs_bits, + secure_vector<byte> & res_tbs_bits, ECDSA_Signature & res_sig); }; diff --git a/src/cert/cvc/cvc_cert.cpp b/src/cert/cvc/cvc_cert.cpp index 54f72ecfc..12558bb80 100644 --- a/src/cert/cvc/cvc_cert.cpp +++ b/src/cert/cvc/cvc_cert.cpp @@ -33,8 +33,8 @@ u32bit EAC1_1_CVC::get_chat_value() const */ void EAC1_1_CVC::force_decode() { - SecureVector<byte> enc_pk; - SecureVector<byte> enc_chat_val; + secure_vector<byte> enc_pk; + secure_vector<byte> enc_chat_val; size_t cpi; BER_Decoder tbs_cert(tbs_bits); tbs_cert.decode(cpi, ASN1_Tag(41), APPLICATION) @@ -88,7 +88,7 @@ bool EAC1_1_CVC::operator==(EAC1_1_CVC const& rhs) const && get_concat_sig() == rhs.get_concat_sig()); } -ECDSA_PublicKey* decode_eac1_1_key(const MemoryRegion<byte>&, +ECDSA_PublicKey* decode_eac1_1_key(const secure_vector<byte>&, AlgorithmIdentifier&) { throw Internal_Error("decode_eac1_1_key: Unimplemented"); @@ -96,7 +96,7 @@ ECDSA_PublicKey* decode_eac1_1_key(const MemoryRegion<byte>&, } EAC1_1_CVC make_cvc_cert(PK_Signer& signer, - MemoryRegion<byte> const& public_key, + secure_vector<byte> const& public_key, ASN1_Car const& car, ASN1_Chr const& chr, byte holder_auth_templ, @@ -105,12 +105,12 @@ EAC1_1_CVC make_cvc_cert(PK_Signer& signer, RandomNumberGenerator& rng) { OID chat_oid(OIDS::lookup("CertificateHolderAuthorizationTemplate")); - MemoryVector<byte> enc_chat_val; + std::vector<byte> enc_chat_val; enc_chat_val.push_back(holder_auth_templ); - MemoryVector<byte> enc_cpi; + std::vector<byte> enc_cpi; enc_cpi.push_back(0x00); - MemoryVector<byte> tbs = DER_Encoder() + std::vector<byte> tbs = DER_Encoder() .encode(enc_cpi, OCTET_STRING, ASN1_Tag(41), APPLICATION) // cpi .encode(car) .raw_bytes(public_key) @@ -123,7 +123,7 @@ EAC1_1_CVC make_cvc_cert(PK_Signer& signer, .encode(cex) .get_contents(); - MemoryVector<byte> signed_cert = + std::vector<byte> signed_cert = EAC1_1_CVC::make_signed(signer, EAC1_1_CVC::build_cert_body(tbs), rng); diff --git a/src/cert/cvc/cvc_cert.h b/src/cert/cvc/cvc_cert.h index 69d0d824a..20370e64b 100644 --- a/src/cert/cvc/cvc_cert.h +++ b/src/cert/cvc/cvc_cert.h @@ -96,7 +96,7 @@ inline bool operator!=(EAC1_1_CVC const& lhs, EAC1_1_CVC const& rhs) * @param rng a random number generator */ EAC1_1_CVC BOTAN_DLL make_cvc_cert(PK_Signer& signer, - const MemoryRegion<byte>& public_key, + const secure_vector<byte>& public_key, ASN1_Car const& car, ASN1_Chr const& chr, byte holder_auth_templ, @@ -107,7 +107,7 @@ EAC1_1_CVC BOTAN_DLL make_cvc_cert(PK_Signer& signer, /** * Decode an EAC encoding ECDSA key */ -BOTAN_DLL ECDSA_PublicKey* decode_eac1_1_key(const MemoryRegion<byte>& enc_key, +BOTAN_DLL ECDSA_PublicKey* decode_eac1_1_key(const secure_vector<byte>& enc_key, AlgorithmIdentifier& sig_algo); } diff --git a/src/cert/cvc/cvc_gen_cert.h b/src/cert/cvc/cvc_gen_cert.h index ad61b85bf..a272e316f 100644 --- a/src/cert/cvc/cvc_gen_cert.h +++ b/src/cert/cvc/cvc_gen_cert.h @@ -56,14 +56,14 @@ class EAC1_1_gen_CVC : public EAC1_1_obj<Derived> // CRTP continuation from EAC1 * Get the to-be-signed (TBS) data of this object. * @result the TBS data of this object */ - SecureVector<byte> tbs_data() const; + secure_vector<byte> tbs_data() const; /** * Build the DER encoded certifcate body of an object * @param tbs the data to be signed * @result the correctly encoded body of the object */ - static SecureVector<byte> build_cert_body(MemoryRegion<byte> const& tbs); + static secure_vector<byte> build_cert_body(secure_vector<byte> const& tbs); /** * Create a signed generalized CVC object. @@ -72,9 +72,9 @@ class EAC1_1_gen_CVC : public EAC1_1_obj<Derived> // CRTP continuation from EAC1 * @param rng a random number generator * @result the DER encoded signed generalized CVC object */ - static MemoryVector<byte> make_signed( + static std::vector<byte> make_signed( PK_Signer& signer, - const MemoryRegion<byte>& tbs_bits, + const secure_vector<byte>& tbs_bits, RandomNumberGenerator& rng); EAC1_1_gen_CVC() { m_pk = 0; } @@ -88,7 +88,7 @@ class EAC1_1_gen_CVC : public EAC1_1_obj<Derived> // CRTP continuation from EAC1 bool self_signed; static void decode_info(DataSource& source, - SecureVector<byte> & res_tbs_bits, + secure_vector<byte> & res_tbs_bits, ECDSA_Signature & res_sig); }; @@ -104,12 +104,12 @@ template<typename Derived> bool EAC1_1_gen_CVC<Derived>::is_self_signed() const } template<typename Derived> -MemoryVector<byte> EAC1_1_gen_CVC<Derived>::make_signed( +std::vector<byte> EAC1_1_gen_CVC<Derived>::make_signed( PK_Signer& signer, - const MemoryRegion<byte>& tbs_bits, + const secure_vector<byte>& tbs_bits, RandomNumberGenerator& rng) // static { - SecureVector<byte> concat_sig = signer.sign_message(tbs_bits, rng); + secure_vector<byte> concat_sig = signer.sign_message(tbs_bits, rng); return DER_Encoder() .start_cons(ASN1_Tag(33), APPLICATION) @@ -125,7 +125,7 @@ Public_Key* EAC1_1_gen_CVC<Derived>::subject_public_key() const return new ECDSA_PublicKey(*m_pk); } -template<typename Derived> SecureVector<byte> EAC1_1_gen_CVC<Derived>::build_cert_body(MemoryRegion<byte> const& tbs) +template<typename Derived> secure_vector<byte> EAC1_1_gen_CVC<Derived>::build_cert_body(secure_vector<byte> const& tbs) { return DER_Encoder() .start_cons(ASN1_Tag(78), APPLICATION) @@ -133,15 +133,15 @@ template<typename Derived> SecureVector<byte> EAC1_1_gen_CVC<Derived>::build_cer .end_cons().get_contents(); } -template<typename Derived> SecureVector<byte> EAC1_1_gen_CVC<Derived>::tbs_data() const +template<typename Derived> secure_vector<byte> EAC1_1_gen_CVC<Derived>::tbs_data() const { return build_cert_body(EAC1_1_obj<Derived>::tbs_bits); } template<typename Derived> void EAC1_1_gen_CVC<Derived>::encode(Pipe& out, X509_Encoding encoding) const { - SecureVector<byte> concat_sig(EAC1_1_obj<Derived>::m_sig.get_concatenation()); - SecureVector<byte> der = DER_Encoder() + secure_vector<byte> concat_sig(EAC1_1_obj<Derived>::m_sig.get_concatenation()); + secure_vector<byte> der = DER_Encoder() .start_cons(ASN1_Tag(33), APPLICATION) .start_cons(ASN1_Tag(78), APPLICATION) .raw_bytes(EAC1_1_obj<Derived>::tbs_bits) @@ -159,10 +159,10 @@ template<typename Derived> void EAC1_1_gen_CVC<Derived>::encode(Pipe& out, X509_ template<typename Derived> void EAC1_1_gen_CVC<Derived>::decode_info( DataSource& source, - SecureVector<byte> & res_tbs_bits, + secure_vector<byte> & res_tbs_bits, ECDSA_Signature & res_sig) { - SecureVector<byte> concat_sig; + secure_vector<byte> concat_sig; BER_Decoder(source) .start_cons(ASN1_Tag(33)) .start_cons(ASN1_Tag(78)) diff --git a/src/cert/cvc/cvc_req.cpp b/src/cert/cvc/cvc_req.cpp index ad9e2f4ca..bd7dee3fa 100644 --- a/src/cert/cvc/cvc_req.cpp +++ b/src/cert/cvc/cvc_req.cpp @@ -19,7 +19,7 @@ bool EAC1_1_Req::operator==(EAC1_1_Req const& rhs) const void EAC1_1_Req::force_decode() { - SecureVector<byte> enc_pk; + secure_vector<byte> enc_pk; BER_Decoder tbs_cert(tbs_bits); size_t cpi; tbs_cert.decode(cpi, ASN1_Tag(41), APPLICATION) diff --git a/src/cert/cvc/cvc_req.h b/src/cert/cvc/cvc_req.h index 1e8cea7f8..ac4e22453 100644 --- a/src/cert/cvc/cvc_req.h +++ b/src/cert/cvc/cvc_req.h @@ -35,7 +35,7 @@ class BOTAN_DLL EAC1_1_Req : public EAC1_1_gen_CVC<EAC1_1_Req> EAC1_1_Req(DataSource& source); /** - * Construct a CVC request from a DER encoded CVC reqeust file. + * Construct a CVC request from a DER encoded CVC request file. * @param str the path to the DER encoded file */ EAC1_1_Req(const std::string& str); diff --git a/src/cert/cvc/cvc_self.cpp b/src/cert/cvc/cvc_self.cpp index 662a1d2be..e692bc9b8 100644 --- a/src/cert/cvc/cvc_self.cpp +++ b/src/cert/cvc/cvc_self.cpp @@ -8,7 +8,6 @@ #include <botan/cvc_self.h> #include <botan/ecc_key.h> #include <botan/point_gfp.h> -#include <botan/time.h> #include <botan/oids.h> #include <sstream> #include <memory> @@ -35,7 +34,7 @@ void encode_eac_bigint(DER_Encoder& der, const BigInt& x, ASN1_Tag tag) der.encode(BigInt::encode_1363(x, x.bytes()), OCTET_STRING, tag); } -MemoryVector<byte> eac_1_1_encoding(const EC_PublicKey* key, +std::vector<byte> eac_1_1_encoding(const EC_PublicKey* key, const OID& sig_algo) { if(key->domain_format() == EC_DOMPAR_ENC_OID) @@ -107,7 +106,7 @@ EAC1_1_CVC create_self_signed_cert(Private_Key const& key, PK_Signer signer(*priv_key, padding_and_hash); - MemoryVector<byte> enc_public_key = eac_1_1_encoding(priv_key, sig_algo.oid); + std::vector<byte> enc_public_key = eac_1_1_encoding(priv_key, sig_algo.oid); return make_cvc_cert(signer, enc_public_key, @@ -134,17 +133,17 @@ EAC1_1_Req create_cvc_req(Private_Key const& key, PK_Signer signer(*priv_key, padding_and_hash); - MemoryVector<byte> enc_public_key = eac_1_1_encoding(priv_key, sig_algo.oid); + std::vector<byte> enc_public_key = eac_1_1_encoding(priv_key, sig_algo.oid); - MemoryVector<byte> enc_cpi; + std::vector<byte> enc_cpi; enc_cpi.push_back(0x00); - MemoryVector<byte> tbs = DER_Encoder() + std::vector<byte> tbs = DER_Encoder() .encode(enc_cpi, OCTET_STRING, ASN1_Tag(41), APPLICATION) .raw_bytes(enc_public_key) .encode(chr) .get_contents(); - MemoryVector<byte> signed_cert = + std::vector<byte> signed_cert = EAC1_1_gen_CVC<EAC1_1_Req>::make_signed(signer, EAC1_1_gen_CVC<EAC1_1_Req>::build_cert_body(tbs), rng); @@ -164,12 +163,13 @@ EAC1_1_ADO create_ado_req(Private_Key const& key, { throw Invalid_Argument("CVC_EAC::create_self_signed_cert(): unsupported key type"); } + std::string padding_and_hash = padding_and_hash_from_oid(req.signature_algorithm().oid); PK_Signer signer(*priv_key, padding_and_hash); - SecureVector<byte> tbs_bits = req.BER_encode(); + secure_vector<byte> tbs_bits = req.BER_encode(); tbs_bits += DER_Encoder().encode(car).get_contents(); - MemoryVector<byte> signed_cert = + std::vector<byte> signed_cert = EAC1_1_ADO::make_signed(signer, tbs_bits, rng); DataSource_Memory source(signed_cert); @@ -193,9 +193,8 @@ EAC1_1_CVC create_cvca(Private_Key const& key, } EAC1_1_CVC_Options opts; opts.car = car; - const u64bit current_time = system_time(); - opts.ced = ASN1_Ced(current_time); + opts.ced = ASN1_Ced(std::chrono::system_clock::now()); opts.cex = ASN1_Cex(opts.ced); opts.cex.add_months(cvca_validity_months); opts.holder_auth_templ = (CVCA | (iris * IRIS) | (fingerpr * FINGERPRINT)); @@ -210,12 +209,12 @@ EAC1_1_CVC link_cvca(EAC1_1_CVC const& signer, EAC1_1_CVC const& signee, RandomNumberGenerator& rng) { - ECDSA_PrivateKey const* priv_key = dynamic_cast<ECDSA_PrivateKey const*>(&key); + const ECDSA_PrivateKey* priv_key = dynamic_cast<ECDSA_PrivateKey const*>(&key); + if (priv_key == 0) - { - throw Invalid_Argument("CVC_EAC::create_self_signed_cert(): unsupported key type"); - } - ASN1_Ced ced(system_time()); + throw Invalid_Argument("link_cvca(): unsupported key type"); + + ASN1_Ced ced(std::chrono::system_clock::now()); ASN1_Cex cex(signee.get_cex()); if (*static_cast<EAC_Time*>(&ced) > *static_cast<EAC_Time*>(&cex)) { @@ -232,11 +231,11 @@ EAC1_1_CVC link_cvca(EAC1_1_CVC const& signer, AlgorithmIdentifier sig_algo = signer.signature_algorithm(); std::string padding_and_hash = padding_and_hash_from_oid(sig_algo.oid); PK_Signer pk_signer(*priv_key, padding_and_hash); - std::auto_ptr<Public_Key> pk(signee.subject_public_key()); + std::unique_ptr<Public_Key> pk(signee.subject_public_key()); ECDSA_PublicKey* subj_pk = dynamic_cast<ECDSA_PublicKey*>(pk.get()); subj_pk->set_parameter_encoding(EC_DOMPAR_ENC_EXPLICIT); - MemoryVector<byte> enc_public_key = eac_1_1_encoding(priv_key, sig_algo.oid); + std::vector<byte> enc_public_key = eac_1_1_encoding(priv_key, sig_algo.oid); return make_cvc_cert(pk_signer, enc_public_key, signer.get_car(), @@ -262,13 +261,19 @@ EAC1_1_CVC sign_request(EAC1_1_CVC const& signer_cert, throw Invalid_Argument("CVC_EAC::create_self_signed_cert(): unsupported key type"); } std::string chr_str = signee.get_chr().value(); - chr_str += to_string(seqnr, seqnr_len); + + std::string seqnr_string = std::to_string(seqnr); + + while(seqnr_string.size() < seqnr_len) + seqnr_string = '0' + seqnr_string; + + chr_str += seqnr_string; ASN1_Chr chr(chr_str); std::string padding_and_hash = padding_and_hash_from_oid(signee.signature_algorithm().oid); PK_Signer pk_signer(*priv_key, padding_and_hash); - std::auto_ptr<Public_Key> pk(signee.subject_public_key()); + std::unique_ptr<Public_Key> pk(signee.subject_public_key()); ECDSA_PublicKey* subj_pk = dynamic_cast<ECDSA_PublicKey*>(pk.get()); - std::auto_ptr<Public_Key> signer_pk(signer_cert.subject_public_key()); + std::unique_ptr<Public_Key> signer_pk(signer_cert.subject_public_key()); // for the case that the domain parameters are not set... // (we use those from the signer because they must fit) @@ -277,8 +282,9 @@ EAC1_1_CVC sign_request(EAC1_1_CVC const& signer_cert, subj_pk->set_parameter_encoding(EC_DOMPAR_ENC_IMPLICITCA); AlgorithmIdentifier sig_algo(signer_cert.signature_algorithm()); - const u64bit current_time = system_time(); - ASN1_Ced ced(current_time); + + ASN1_Ced ced(std::chrono::system_clock::now()); + u32bit chat_val; u32bit chat_low = signer_cert.get_chat_value() & 0x3; // take the chat rights from signer ASN1_Cex cex(ced); @@ -303,7 +309,7 @@ EAC1_1_CVC sign_request(EAC1_1_CVC const& signer_cert, // (IS cannot sign certificates) } - MemoryVector<byte> enc_public_key = eac_1_1_encoding(priv_key, sig_algo.oid); + std::vector<byte> enc_public_key = eac_1_1_encoding(priv_key, sig_algo.oid); return make_cvc_cert(pk_signer, enc_public_key, ASN1_Car(signer_cert.get_chr().iso_8859()), diff --git a/src/cert/cvc/eac_asn_obj.h b/src/cert/cvc/eac_asn_obj.h index d0bab6fdd..9937abb01 100644 --- a/src/cert/cvc/eac_asn_obj.h +++ b/src/cert/cvc/eac_asn_obj.h @@ -56,7 +56,6 @@ class BOTAN_DLL EAC_Time : public ASN1_Object * e.g. "2007 08 01" */ void set_to(const std::string& str); - //void set_to(const std::string&, ASN1_Tag); /** * Add the specified number of years to this. @@ -74,28 +73,32 @@ class BOTAN_DLL EAC_Time : public ASN1_Object * Get the year value of this objects. * @return year value */ - u32bit get_year() const; + u32bit get_year() const { return year; } /** * Get the month value of this objects. * @return month value */ - u32bit get_month() const; + u32bit get_month() const { return month; } /** * Get the day value of this objects. * @return day value */ - u32bit get_day() const; + u32bit get_day() const { return day; } - EAC_Time(u64bit, ASN1_Tag t = ASN1_Tag(0)); - //EAC_Time(const std::string& = ""); - EAC_Time(const std::string&, ASN1_Tag = ASN1_Tag(0)); - EAC_Time(u32bit year, u32bit month, u32bit day, ASN1_Tag = ASN1_Tag(0)); + EAC_Time(const std::chrono::system_clock::time_point& time, + ASN1_Tag tag = ASN1_Tag(0)); + + EAC_Time(const std::string& yyyy_mm_dd, + ASN1_Tag tag = ASN1_Tag(0)); + + EAC_Time(u32bit year, u32bit month, u32bit day, + ASN1_Tag tag = ASN1_Tag(0)); virtual ~EAC_Time() {} private: - SecureVector<byte> encoded_eac_time() const; + secure_vector<byte> encoded_eac_time() const; bool passes_sanity_check() const; u32bit year, month, day; ASN1_Tag tag; @@ -113,25 +116,25 @@ class BOTAN_DLL ASN1_Ced : public EAC_Time * @param str a string in the format "yyyy mm dd", * e.g. "2007 08 01" */ - ASN1_Ced(std::string const& str = ""); + ASN1_Ced(const std::string& str = "") : + EAC_Time(str, ASN1_Tag(37)) {} /** - * Construct a CED from a timer value. - * @param time the number of seconds elapsed midnight, 1st - * January 1970 GMT (or 7pm, 31st December 1969 EST) up to the - * desired date + * Construct a CED from a time point */ - ASN1_Ced(u64bit time); + ASN1_Ced(const std::chrono::system_clock::time_point& time) : + EAC_Time(time, ASN1_Tag(37)) {} /** * Copy constructor (for general EAC_Time objects). * @param other the object to copy from */ - ASN1_Ced(EAC_Time const& other); - //ASN1_Ced(ASN1_Cex const& cex); + ASN1_Ced(const EAC_Time& other) : + EAC_Time(other.get_year(), other.get_month(), other.get_day(), + ASN1_Tag(37)) + {} }; - /** * This class represents CVC CEXs. Only limited sanity checks of * the inputted date value are performed. @@ -140,27 +143,20 @@ class BOTAN_DLL ASN1_Cex : public EAC_Time { public: /** - * Construct a CED from a string value. + * Construct a CEX from a string value. * @param str a string in the format "yyyy mm dd", * e.g. "2007 08 01" */ - ASN1_Cex(std::string const& str=""); + ASN1_Cex(const std::string& str = "") : + EAC_Time(str, ASN1_Tag(36)) {} - /** - * Construct a CED from a timer value. - * @param time the number of seconds elapsed - * midnight, 1st - * January 1970 GMT (or 7pm, 31st December 1969 EST) - * up to the desired date - */ - ASN1_Cex(u64bit time); + ASN1_Cex(const std::chrono::system_clock::time_point& time) : + EAC_Time(time, ASN1_Tag(36)) {} - /** - * Copy constructor (for general EAC_Time objects). - * @param other the object to copy from - */ - ASN1_Cex(EAC_Time const& other); - //ASN1_Cex(ASN1_Ced const& ced); + ASN1_Cex(const EAC_Time& other) : + EAC_Time(other.get_year(), other.get_month(), other.get_day(), + ASN1_Tag(36)) + {} }; /** diff --git a/src/cert/cvc/eac_obj.h b/src/cert/cvc/eac_obj.h index eb6db3369..39f34b874 100644 --- a/src/cert/cvc/eac_obj.h +++ b/src/cert/cvc/eac_obj.h @@ -24,7 +24,7 @@ class EAC1_1_obj : public EAC_Signed_Object * Return the signature as a concatenation of the encoded parts. * @result the concatenated signature */ - SecureVector<byte> get_concat_sig() const + secure_vector<byte> get_concat_sig() const { return m_sig.get_concatenation(); } bool check_signature(class Public_Key& key) const diff --git a/src/cert/cvc/ecdsa_sig.cpp b/src/cert/cvc/ecdsa_sig.cpp index e8fd7f051..91166ad79 100644 --- a/src/cert/cvc/ecdsa_sig.cpp +++ b/src/cert/cvc/ecdsa_sig.cpp @@ -10,7 +10,7 @@ namespace Botan { -ECDSA_Signature::ECDSA_Signature(const MemoryRegion<byte>& ber) +ECDSA_Signature::ECDSA_Signature(const secure_vector<byte>& ber) { BER_Decoder(ber) .start_cons(SEQUENCE) @@ -20,7 +20,7 @@ ECDSA_Signature::ECDSA_Signature(const MemoryRegion<byte>& ber) .verify_end(); } -MemoryVector<byte> ECDSA_Signature::DER_encode() const +std::vector<byte> ECDSA_Signature::DER_encode() const { return DER_Encoder() .start_cons(SEQUENCE) @@ -30,20 +30,20 @@ MemoryVector<byte> ECDSA_Signature::DER_encode() const .get_contents(); } -MemoryVector<byte> ECDSA_Signature::get_concatenation() const +std::vector<byte> ECDSA_Signature::get_concatenation() const { // use the larger const size_t enc_len = m_r > m_s ? m_r.bytes() : m_s.bytes(); - SecureVector<byte> sv_r = BigInt::encode_1363(m_r, enc_len); - SecureVector<byte> sv_s = BigInt::encode_1363(m_s, enc_len); + secure_vector<byte> sv_r = BigInt::encode_1363(m_r, enc_len); + secure_vector<byte> sv_s = BigInt::encode_1363(m_s, enc_len); - SecureVector<byte> result(sv_r); + secure_vector<byte> result(sv_r); result += sv_s; return result; } -ECDSA_Signature decode_concatenation(const MemoryRegion<byte>& concat) +ECDSA_Signature decode_concatenation(const secure_vector<byte>& concat) { if(concat.size() % 2 != 0) throw Invalid_Argument("Erroneous length of signature"); diff --git a/src/cert/cvc/ecdsa_sig.h b/src/cert/cvc/ecdsa_sig.h index a92052470..a92d5078c 100644 --- a/src/cert/cvc/ecdsa_sig.h +++ b/src/cert/cvc/ecdsa_sig.h @@ -27,7 +27,7 @@ class BOTAN_DLL ECDSA_Signature ECDSA_Signature(const BigInt& r, const BigInt& s) : m_r(r), m_s(s) {} - ECDSA_Signature(const MemoryRegion<byte>& ber); + ECDSA_Signature(const secure_vector<byte>& ber); const BigInt& get_r() const { return m_r; } const BigInt& get_s() const { return m_s; } @@ -35,9 +35,9 @@ class BOTAN_DLL ECDSA_Signature /** * return the r||s */ - MemoryVector<byte> get_concatenation() const; + std::vector<byte> get_concatenation() const; - MemoryVector<byte> DER_encode() const; + std::vector<byte> DER_encode() const; bool operator==(const ECDSA_Signature& other) const { @@ -54,7 +54,7 @@ inline bool operator!=(const ECDSA_Signature& lhs, const ECDSA_Signature& rhs) return !(lhs == rhs); } -ECDSA_Signature decode_concatenation(const MemoryRegion<byte>& concatenation); +ECDSA_Signature decode_concatenation(const secure_vector<byte>& concatenation); } diff --git a/src/cert/cvc/info.txt b/src/cert/cvc/info.txt index 33a872053..3cf759188 100644 --- a/src/cert/cvc/info.txt +++ b/src/cert/cvc/info.txt @@ -1,5 +1,4 @@ define CARD_VERIFIABLE_CERTIFICATES - load_on request <header:public> diff --git a/src/cert/cvc/signed_obj.cpp b/src/cert/cvc/signed_obj.cpp index d6aa2f02b..4f04cd72e 100644 --- a/src/cert/cvc/signed_obj.cpp +++ b/src/cert/cvc/signed_obj.cpp @@ -16,7 +16,7 @@ namespace Botan { /* * Return a BER encoded X.509 object */ -SecureVector<byte> EAC_Signed_Object::BER_encode() const +secure_vector<byte> EAC_Signed_Object::BER_encode() const { Pipe ber; ber.start_msg(); @@ -46,7 +46,7 @@ AlgorithmIdentifier EAC_Signed_Object::signature_algorithm() const } bool EAC_Signed_Object::check_signature(Public_Key& pub_key, - const MemoryRegion<byte>& sig) const + const secure_vector<byte>& sig) const { try { @@ -62,7 +62,7 @@ bool EAC_Signed_Object::check_signature(Public_Key& pub_key, Signature_Format format = (pub_key.message_parts() >= 2) ? DER_SEQUENCE : IEEE_1363; - SecureVector<byte> to_sign = tbs_data(); + secure_vector<byte> to_sign = tbs_data(); PK_Verifier verifier(pub_key, padding, format); return verifier.verify_message(to_sign, sig); diff --git a/src/cert/cvc/signed_obj.h b/src/cert/cvc/signed_obj.h index 20f0e7b14..45bd2858e 100644 --- a/src/cert/cvc/signed_obj.h +++ b/src/cert/cvc/signed_obj.h @@ -26,7 +26,7 @@ class BOTAN_DLL EAC_Signed_Object * Get the TBS (to-be-signed) data in this object. * @return DER encoded TBS data of this object */ - virtual SecureVector<byte> tbs_data() const = 0; + virtual secure_vector<byte> tbs_data() const = 0; /** * Get the signature of this object as a concatenation, i.e. if the @@ -39,7 +39,7 @@ class BOTAN_DLL EAC_Signed_Object NOTE: this is here only because abstract signature objects have not yet been introduced */ - virtual SecureVector<byte> get_concat_sig() const = 0; + virtual secure_vector<byte> get_concat_sig() const = 0; /** * Get the signature algorithm identifier used to sign this object. @@ -55,7 +55,7 @@ class BOTAN_DLL EAC_Signed_Object * associated with this public key */ bool check_signature(class Public_Key& key, - const MemoryRegion<byte>& sig) const; + const secure_vector<byte>& sig) const; /** * Write this object DER encoded into a specified pipe. @@ -69,7 +69,7 @@ class BOTAN_DLL EAC_Signed_Object * BER encode this object. * @return result containing the BER representation of this object. */ - SecureVector<byte> BER_encode() const; + secure_vector<byte> BER_encode() const; /** * PEM encode this object. @@ -83,7 +83,7 @@ class BOTAN_DLL EAC_Signed_Object EAC_Signed_Object() {} AlgorithmIdentifier sig_algo; - SecureVector<byte> tbs_bits; + secure_vector<byte> tbs_bits; std::string PEM_label_pref; std::vector<std::string> PEM_labels_allowed; private: diff --git a/src/cert/x509/certstor.cpp b/src/cert/x509/certstor.cpp index de27361ed..293072785 100644 --- a/src/cert/x509/certstor.cpp +++ b/src/cert/x509/certstor.cpp @@ -32,7 +32,7 @@ void Certificate_Store_In_Memory::add_certificate(const X509_Certificate& cert) std::vector<X509_Certificate> Certificate_Store_In_Memory::find_cert_by_subject_and_key_id( const X509_DN& subject_dn, - const MemoryRegion<byte>& key_id) const + const std::vector<byte>& key_id) const { std::vector<X509_Certificate> result; @@ -41,7 +41,7 @@ Certificate_Store_In_Memory::find_cert_by_subject_and_key_id( // Only compare key ids if set in both call and in the cert if(key_id.size()) { - MemoryVector<byte> skid = certs[i].subject_key_id(); + std::vector<byte> skid = certs[i].subject_key_id(); if(skid.size() && skid != key_id) // no match continue; @@ -76,7 +76,7 @@ void Certificate_Store_In_Memory::add_crl(const X509_CRL& crl) std::vector<X509_CRL> Certificate_Store_In_Memory::find_crl_by_issuer_and_key_id( const X509_DN& issuer_dn, - const MemoryRegion<byte>& key_id) const + const std::vector<byte>& key_id) const { std::vector<X509_CRL> result; @@ -85,7 +85,7 @@ Certificate_Store_In_Memory::find_crl_by_issuer_and_key_id( // Only compare key ids if set in both call and in the CRL if(key_id.size()) { - MemoryVector<byte> akid = crls[i].authority_key_id(); + std::vector<byte> akid = crls[i].authority_key_id(); if(akid.size() && akid != key_id) // no match continue; diff --git a/src/cert/x509/certstor.h b/src/cert/x509/certstor.h index e2727c569..584259f8c 100644 --- a/src/cert/x509/certstor.h +++ b/src/cert/x509/certstor.h @@ -39,7 +39,7 @@ class BOTAN_DLL Certificate_Store virtual std::vector<X509_Certificate> find_cert_by_subject_and_key_id( const X509_DN& subject_dn, - const MemoryRegion<byte>& key_id) const = 0; + const std::vector<byte>& key_id) const = 0; /** * Find CRLs by the DN and key id of the issuer @@ -47,7 +47,7 @@ class BOTAN_DLL Certificate_Store virtual std::vector<X509_CRL> find_crl_by_issuer_and_key_id( const X509_DN& issuer_dn, - const MemoryRegion<byte>& key_id) const = 0; + const std::vector<byte>& key_id) const = 0; }; /** @@ -62,11 +62,11 @@ class BOTAN_DLL Certificate_Store_In_Memory : public Certificate_Store std::vector<X509_Certificate> find_cert_by_subject_and_key_id( const X509_DN& subject_dn, - const MemoryRegion<byte>& key_id) const; + const std::vector<byte>& key_id) const; std::vector<X509_CRL> find_crl_by_issuer_and_key_id( const X509_DN& issuer_dn, - const MemoryRegion<byte>& key_id) const; + const std::vector<byte>& key_id) const; Certificate_Store_In_Memory() {} private: diff --git a/src/cert/x509/crl_ent.cpp b/src/cert/x509/crl_ent.cpp index d566637f6..a5663e6bb 100644 --- a/src/cert/x509/crl_ent.cpp +++ b/src/cert/x509/crl_ent.cpp @@ -11,7 +11,6 @@ #include <botan/ber_dec.h> #include <botan/bigint.h> #include <botan/oids.h> -#include <botan/time.h> namespace Botan { @@ -31,7 +30,7 @@ CRL_Entry::CRL_Entry(const X509_Certificate& cert, CRL_Code why) : throw_on_unknown_critical(false) { serial = cert.serial_number(); - time = X509_Time(system_time()); + time = X509_Time(std::chrono::system_clock::now()); reason = why; } diff --git a/src/cert/x509/crl_ent.h b/src/cert/x509/crl_ent.h index ae9535484..769519f78 100644 --- a/src/cert/x509/crl_ent.h +++ b/src/cert/x509/crl_ent.h @@ -45,7 +45,7 @@ class BOTAN_DLL CRL_Entry : public ASN1_Object * Get the serial number of the certificate associated with this entry. * @return certificate's serial number */ - MemoryVector<byte> serial_number() const { return serial; } + std::vector<byte> serial_number() const { return serial; } /** * Get the revocation date of the certificate associated with this entry @@ -74,7 +74,7 @@ class BOTAN_DLL CRL_Entry : public ASN1_Object private: bool throw_on_unknown_critical; - MemoryVector<byte> serial; + std::vector<byte> serial; X509_Time time; CRL_Code reason; }; diff --git a/src/cert/x509/pkcs10.cpp b/src/cert/x509/pkcs10.cpp index 784318d3d..c67f74142 100644 --- a/src/cert/x509/pkcs10.cpp +++ b/src/cert/x509/pkcs10.cpp @@ -35,6 +35,15 @@ PKCS10_Request::PKCS10_Request(const std::string& in) : } /* +* PKCS10_Request Constructor +*/ +PKCS10_Request::PKCS10_Request(const std::vector<byte>& in) : + X509_Object(in, "CERTIFICATE REQUEST/NEW CERTIFICATE REQUEST") + { + do_decode(); + } + +/* * Deocde the CertificateRequestInfo */ void PKCS10_Request::force_decode() @@ -45,7 +54,7 @@ void PKCS10_Request::force_decode() cert_req_info.decode(version); if(version != 0) throw Decoding_Error("Unknown version code in PKCS #10 request: " + - to_string(version)); + std::to_string(version)); X509_DN dn_subject; cert_req_info.decode(dn_subject); @@ -59,7 +68,7 @@ void PKCS10_Request::force_decode() info.add("X509.Certificate.public_key", PEM_Code::encode( - ASN1::put_in_sequence(public_key.value), + ASN1::put_in_sequence(unlock(public_key.value)), "PUBLIC KEY" ) ); @@ -136,10 +145,10 @@ X509_DN PKCS10_Request::subject_dn() const /* * Return the public key of the requestor */ -MemoryVector<byte> PKCS10_Request::raw_public_key() const +std::vector<byte> PKCS10_Request::raw_public_key() const { DataSource_Memory source(info.get1("X509.Certificate.public_key")); - return PEM_Code::decode_check_label(source, "PUBLIC KEY"); + return unlock(PEM_Code::decode_check_label(source, "PUBLIC KEY")); } /* diff --git a/src/cert/x509/pkcs10.h b/src/cert/x509/pkcs10.h index 065dfbdc0..974ea0070 100644 --- a/src/cert/x509/pkcs10.h +++ b/src/cert/x509/pkcs10.h @@ -33,7 +33,7 @@ class BOTAN_DLL PKCS10_Request : public X509_Object * Get the raw DER encoded public key. * @return raw DER encoded public key */ - MemoryVector<byte> raw_public_key() const; + std::vector<byte> raw_public_key() const; /** * Get the subject DN. @@ -91,6 +91,12 @@ class BOTAN_DLL PKCS10_Request : public X509_Object * encoded request file */ PKCS10_Request(const std::string& filename); + + /** + * Create a PKCS#10 Request from binary data. + * @param vec a std::vector containing the DER value + */ + PKCS10_Request(const std::vector<byte>& vec); private: void force_decode(); void handle_attribute(const Attribute&); diff --git a/src/cert/x509/x509_ca.cpp b/src/cert/x509/x509_ca.cpp index 77e066533..9633d1466 100644 --- a/src/cert/x509/x509_ca.cpp +++ b/src/cert/x509/x509_ca.cpp @@ -57,8 +57,8 @@ X509_Certificate X509_CA::sign_request(const PKCS10_Request& req, constraints = Key_Constraints(KEY_CERT_SIGN | CRL_SIGN); else { - std::auto_ptr<Public_Key> key(req.subject_public_key()); - constraints = find_constraints(*key, req.constraints()); + std::unique_ptr<Public_Key> key(req.subject_public_key()); + constraints = X509::find_constraints(*key, req.constraints()); } Extensions extensions; @@ -91,7 +91,7 @@ X509_Certificate X509_CA::sign_request(const PKCS10_Request& req, X509_Certificate X509_CA::make_cert(PK_Signer* signer, RandomNumberGenerator& rng, const AlgorithmIdentifier& sig_algo, - const MemoryRegion<byte>& pub_key, + const std::vector<byte>& pub_key, const X509_Time& not_before, const X509_Time& not_after, const X509_DN& issuer_dn, @@ -103,35 +103,35 @@ X509_Certificate X509_CA::make_cert(PK_Signer* signer, BigInt serial_no(rng, SERIAL_BITS); - DataSource_Memory source(X509_Object::make_signed(signer, rng, sig_algo, - DER_Encoder().start_cons(SEQUENCE) - .start_explicit(0) - .encode(X509_CERT_VERSION-1) - .end_explicit() + const std::vector<byte> cert = X509_Object::make_signed( + signer, rng, sig_algo, + DER_Encoder().start_cons(SEQUENCE) + .start_explicit(0) + .encode(X509_CERT_VERSION-1) + .end_explicit() - .encode(serial_no) + .encode(serial_no) - .encode(sig_algo) - .encode(issuer_dn) + .encode(sig_algo) + .encode(issuer_dn) - .start_cons(SEQUENCE) - .encode(not_before) - .encode(not_after) - .end_cons() + .start_cons(SEQUENCE) + .encode(not_before) + .encode(not_after) + .end_cons() - .encode(subject_dn) - .raw_bytes(pub_key) + .encode(subject_dn) + .raw_bytes(pub_key) - .start_explicit(3) - .start_cons(SEQUENCE) - .encode(extensions) - .end_cons() - .end_explicit() - .end_cons() - .get_contents() - )); + .start_explicit(3) + .start_cons(SEQUENCE) + .encode(extensions) + .end_cons() + .end_explicit() + .end_cons() + .get_contents()); - return X509_Certificate(source); + return X509_Certificate(cert); } /* @@ -173,36 +173,37 @@ X509_CRL X509_CA::make_crl(const std::vector<CRL_Entry>& revoked, next_update = timespec_to_u32bit("7d"); // Totally stupid: ties encoding logic to the return of std::time!! - const u64bit current_time = system_time(); + auto current_time = std::chrono::system_clock::now(); + auto expire_time = current_time + std::chrono::seconds(next_update); Extensions extensions; extensions.add( new Cert_Extension::Authority_Key_ID(cert.subject_key_id())); extensions.add(new Cert_Extension::CRL_Number(crl_number)); - DataSource_Memory source(X509_Object::make_signed(signer, rng, ca_sig_algo, - DER_Encoder().start_cons(SEQUENCE) - .encode(X509_CRL_VERSION-1) - .encode(ca_sig_algo) - .encode(cert.issuer_dn()) - .encode(X509_Time(current_time)) - .encode(X509_Time(current_time + next_update)) - .encode_if(revoked.size() > 0, - DER_Encoder() - .start_cons(SEQUENCE) - .encode_list(revoked) - .end_cons() - ) - .start_explicit(0) - .start_cons(SEQUENCE) - .encode(extensions) - .end_cons() - .end_explicit() - .end_cons() - .get_contents() - )); + const std::vector<byte> crl = X509_Object::make_signed( + signer, rng, ca_sig_algo, + DER_Encoder().start_cons(SEQUENCE) + .encode(X509_CRL_VERSION-1) + .encode(ca_sig_algo) + .encode(cert.issuer_dn()) + .encode(X509_Time(current_time)) + .encode(X509_Time(expire_time)) + .encode_if(revoked.size() > 0, + DER_Encoder() + .start_cons(SEQUENCE) + .encode_list(revoked) + .end_cons() + ) + .start_explicit(0) + .start_cons(SEQUENCE) + .encode(extensions) + .end_cons() + .end_explicit() + .end_cons() + .get_contents()); - return X509_CRL(source); + return X509_CRL(crl); } /* diff --git a/src/cert/x509/x509_ca.h b/src/cert/x509/x509_ca.h index 97be6a415..d37b02eaf 100644 --- a/src/cert/x509/x509_ca.h +++ b/src/cert/x509/x509_ca.h @@ -82,7 +82,7 @@ class BOTAN_DLL X509_CA static X509_Certificate make_cert(PK_Signer* signer, RandomNumberGenerator& rng, const AlgorithmIdentifier& sig_algo, - const MemoryRegion<byte>& pub_key, + const std::vector<byte>& pub_key, const X509_Time& not_before, const X509_Time& not_after, const X509_DN& issuer_dn, @@ -99,11 +99,11 @@ class BOTAN_DLL X509_CA const Private_Key& key, const std::string& hash_fn); + X509_CA(const X509_CA&) = delete; + X509_CA& operator=(const X509_CA&) = delete; + ~X509_CA(); private: - X509_CA(const X509_CA&) {} - X509_CA& operator=(const X509_CA&) { return (*this); } - X509_CRL make_crl(const std::vector<CRL_Entry>& entries, u32bit crl_number, u32bit next_update, RandomNumberGenerator& rng) const; diff --git a/src/cert/x509/x509_crl.cpp b/src/cert/x509/x509_crl.cpp index 9c6b891c7..1d6393470 100644 --- a/src/cert/x509/x509_crl.cpp +++ b/src/cert/x509/x509_crl.cpp @@ -33,6 +33,12 @@ X509_CRL::X509_CRL(const std::string& in, bool touc) : do_decode(); } +X509_CRL::X509_CRL(const std::vector<byte>& in, bool touc) : + X509_Object(in, "CRL/X509 CRL"), throw_on_unknown_critical(touc) + { + do_decode(); + } + /** * Check if this particular certificate is listed in the CRL */ @@ -82,7 +88,7 @@ void X509_CRL::force_decode() if(version != 0 && version != 1) throw X509_CRL_Error("Unknown X.509 CRL version " + - to_string(version+1)); + std::to_string(version+1)); AlgorithmIdentifier sig_algo_inner; tbs_crl.decode(sig_algo_inner); @@ -153,7 +159,7 @@ X509_DN X509_CRL::issuer_dn() const /* * Return the key identifier of the issuer */ -MemoryVector<byte> X509_CRL::authority_key_id() const +std::vector<byte> X509_CRL::authority_key_id() const { return info.get1_memvec("X509v3.AuthorityKeyIdentifier"); } diff --git a/src/cert/x509/x509_crl.h b/src/cert/x509/x509_crl.h index 55eb8424b..3e45df121 100644 --- a/src/cert/x509/x509_crl.h +++ b/src/cert/x509/x509_crl.h @@ -52,7 +52,7 @@ class BOTAN_DLL X509_CRL : public X509_Object * Get the AuthorityKeyIdentifier of this CRL. * @return this CRLs AuthorityKeyIdentifier */ - MemoryVector<byte> authority_key_id() const; + std::vector<byte> authority_key_id() const; /** * Get the serial number of this CRL. @@ -88,6 +88,16 @@ class BOTAN_DLL X509_CRL : public X509_Object */ X509_CRL(const std::string& filename, bool throw_on_unknown_critical = false); + + /** + * Construct a CRL from a binary vector + * @param vec the binary (DER) representation of the CRL + * @param throw_on_unknown_critical should we throw an exception + * if an unknown CRL extension marked as critical is encountered. + */ + X509_CRL(const std::vector<byte>& vec, + bool throw_on_unknown_critical = false); + private: void force_decode(); diff --git a/src/cert/x509/x509_ext.cpp b/src/cert/x509/x509_ext.cpp index 6e0befaf3..919fb790a 100644 --- a/src/cert/x509/x509_ext.cpp +++ b/src/cert/x509/x509_ext.cpp @@ -36,7 +36,7 @@ Certificate_Extension* Extensions::get_extension(const OID& oid) X509_EXTENSION("X509v3.CertificatePolicies", Certificate_Policies); X509_EXTENSION("X509v3.ReasonCode", CRL_ReasonCode); - return 0; + return nullptr; } /* @@ -114,7 +114,7 @@ void Extensions::decode_from(BER_Decoder& from_source) while(sequence.more_items()) { OID oid; - MemoryVector<byte> value; + std::vector<byte> value; bool critical; sequence.start_cons(SEQUENCE) @@ -176,7 +176,7 @@ size_t Basic_Constraints::get_path_limit() const /* * Encode the extension */ -MemoryVector<byte> Basic_Constraints::encode_inner() const +std::vector<byte> Basic_Constraints::encode_inner() const { return DER_Encoder() .start_cons(SEQUENCE) @@ -186,13 +186,13 @@ MemoryVector<byte> Basic_Constraints::encode_inner() const .encode_optional(path_limit, NO_CERT_PATH_LIMIT) ) .end_cons() - .get_contents(); + .get_contents_unlocked(); } /* * Decode the extension */ -void Basic_Constraints::decode_inner(const MemoryRegion<byte>& in) +void Basic_Constraints::decode_inner(const std::vector<byte>& in) { BER_Decoder(in) .start_cons(SEQUENCE) @@ -217,14 +217,14 @@ void Basic_Constraints::contents_to(Data_Store& subject, Data_Store&) const /* * Encode the extension */ -MemoryVector<byte> Key_Usage::encode_inner() const +std::vector<byte> Key_Usage::encode_inner() const { if(constraints == NO_CONSTRAINTS) throw Encoding_Error("Cannot encode zero usage constraints"); const size_t unused_bits = low_bit(constraints) - 1; - MemoryVector<byte> der; + std::vector<byte> der; der.push_back(BIT_STRING); der.push_back(2 + ((unused_bits < 8) ? 1 : 0)); der.push_back(unused_bits % 8); @@ -238,7 +238,7 @@ MemoryVector<byte> Key_Usage::encode_inner() const /* * Decode the extension */ -void Key_Usage::decode_inner(const MemoryRegion<byte>& in) +void Key_Usage::decode_inner(const std::vector<byte>& in) { BER_Decoder ber(in); @@ -274,15 +274,15 @@ void Key_Usage::contents_to(Data_Store& subject, Data_Store&) const /* * Encode the extension */ -MemoryVector<byte> Subject_Key_ID::encode_inner() const +std::vector<byte> Subject_Key_ID::encode_inner() const { - return DER_Encoder().encode(key_id, OCTET_STRING).get_contents(); + return DER_Encoder().encode(key_id, OCTET_STRING).get_contents_unlocked(); } /* * Decode the extension */ -void Subject_Key_ID::decode_inner(const MemoryRegion<byte>& in) +void Subject_Key_ID::decode_inner(const std::vector<byte>& in) { BER_Decoder(in).decode(key_id, OCTET_STRING).verify_end(); } @@ -298,28 +298,28 @@ void Subject_Key_ID::contents_to(Data_Store& subject, Data_Store&) const /* * Subject_Key_ID Constructor */ -Subject_Key_ID::Subject_Key_ID(const MemoryRegion<byte>& pub_key) +Subject_Key_ID::Subject_Key_ID(const std::vector<byte>& pub_key) { SHA_160 hash; - key_id = hash.process(pub_key); + key_id = unlock(hash.process(pub_key)); } /* * Encode the extension */ -MemoryVector<byte> Authority_Key_ID::encode_inner() const +std::vector<byte> Authority_Key_ID::encode_inner() const { return DER_Encoder() .start_cons(SEQUENCE) .encode(key_id, OCTET_STRING, ASN1_Tag(0), CONTEXT_SPECIFIC) .end_cons() - .get_contents(); + .get_contents_unlocked(); } /* * Decode the extension */ -void Authority_Key_ID::decode_inner(const MemoryRegion<byte>& in) +void Authority_Key_ID::decode_inner(const std::vector<byte>& in) { BER_Decoder(in) .start_cons(SEQUENCE) @@ -338,15 +338,15 @@ void Authority_Key_ID::contents_to(Data_Store&, Data_Store& issuer) const /* * Encode the extension */ -MemoryVector<byte> Alternative_Name::encode_inner() const +std::vector<byte> Alternative_Name::encode_inner() const { - return DER_Encoder().encode(alt_name).get_contents(); + return DER_Encoder().encode(alt_name).get_contents_unlocked(); } /* * Decode the extension */ -void Alternative_Name::decode_inner(const MemoryRegion<byte>& in) +void Alternative_Name::decode_inner(const std::vector<byte>& in) { BER_Decoder(in).decode(alt_name); } @@ -404,19 +404,19 @@ Issuer_Alternative_Name::Issuer_Alternative_Name(const AlternativeName& name) : /* * Encode the extension */ -MemoryVector<byte> Extended_Key_Usage::encode_inner() const +std::vector<byte> Extended_Key_Usage::encode_inner() const { return DER_Encoder() .start_cons(SEQUENCE) .encode_list(oids) .end_cons() - .get_contents(); + .get_contents_unlocked(); } /* * Decode the extension */ -void Extended_Key_Usage::decode_inner(const MemoryRegion<byte>& in) +void Extended_Key_Usage::decode_inner(const std::vector<byte>& in) { BER_Decoder(in) .start_cons(SEQUENCE) @@ -467,7 +467,7 @@ class Policy_Information : public ASN1_Object /* * Encode the extension */ -MemoryVector<byte> Certificate_Policies::encode_inner() const +std::vector<byte> Certificate_Policies::encode_inner() const { std::vector<Policy_Information> policies; @@ -478,13 +478,13 @@ MemoryVector<byte> Certificate_Policies::encode_inner() const .start_cons(SEQUENCE) .encode_list(policies) .end_cons() - .get_contents(); + .get_contents_unlocked(); } /* * Decode the extension */ -void Certificate_Policies::decode_inner(const MemoryRegion<byte>& in) +void Certificate_Policies::decode_inner(const std::vector<byte>& in) { std::vector<Policy_Information> policies; @@ -530,15 +530,15 @@ CRL_Number* CRL_Number::copy() const /* * Encode the extension */ -MemoryVector<byte> CRL_Number::encode_inner() const +std::vector<byte> CRL_Number::encode_inner() const { - return DER_Encoder().encode(crl_number).get_contents(); + return DER_Encoder().encode(crl_number).get_contents_unlocked(); } /* * Decode the extension */ -void CRL_Number::decode_inner(const MemoryRegion<byte>& in) +void CRL_Number::decode_inner(const std::vector<byte>& in) { BER_Decoder(in).decode(crl_number); } @@ -554,17 +554,17 @@ void CRL_Number::contents_to(Data_Store& info, Data_Store&) const /* * Encode the extension */ -MemoryVector<byte> CRL_ReasonCode::encode_inner() const +std::vector<byte> CRL_ReasonCode::encode_inner() const { return DER_Encoder() .encode(static_cast<size_t>(reason), ENUMERATED, UNIVERSAL) - .get_contents(); + .get_contents_unlocked(); } /* * Decode the extension */ -void CRL_ReasonCode::decode_inner(const MemoryRegion<byte>& in) +void CRL_ReasonCode::decode_inner(const std::vector<byte>& in) { size_t reason_code = 0; BER_Decoder(in).decode(reason_code, ENUMERATED, UNIVERSAL); diff --git a/src/cert/x509/x509_ext.h b/src/cert/x509/x509_ext.h index 714e29562..1e5d1adbb 100644 --- a/src/cert/x509/x509_ext.h +++ b/src/cert/x509/x509_ext.h @@ -56,8 +56,8 @@ class BOTAN_DLL Certificate_Extension protected: friend class Extensions; virtual bool should_encode() const { return true; } - virtual MemoryVector<byte> encode_inner() const = 0; - virtual void decode_inner(const MemoryRegion<byte>&) = 0; + virtual std::vector<byte> encode_inner() const = 0; + virtual void decode_inner(const std::vector<byte>&) = 0; }; /** @@ -107,8 +107,8 @@ class BOTAN_DLL Basic_Constraints : public Certificate_Extension std::string config_id() const { return "basic_constraints"; } std::string oid_name() const { return "X509v3.BasicConstraints"; } - MemoryVector<byte> encode_inner() const; - void decode_inner(const MemoryRegion<byte>&); + std::vector<byte> encode_inner() const; + void decode_inner(const std::vector<byte>&); void contents_to(Data_Store&, Data_Store&) const; bool is_ca; @@ -131,8 +131,8 @@ class BOTAN_DLL Key_Usage : public Certificate_Extension std::string oid_name() const { return "X509v3.KeyUsage"; } bool should_encode() const { return (constraints != NO_CONSTRAINTS); } - MemoryVector<byte> encode_inner() const; - void decode_inner(const MemoryRegion<byte>&); + std::vector<byte> encode_inner() const; + void decode_inner(const std::vector<byte>&); void contents_to(Data_Store&, Data_Store&) const; Key_Constraints constraints; @@ -147,19 +147,19 @@ class BOTAN_DLL Subject_Key_ID : public Certificate_Extension Subject_Key_ID* copy() const { return new Subject_Key_ID(key_id); } Subject_Key_ID() {} - Subject_Key_ID(const MemoryRegion<byte>&); + Subject_Key_ID(const std::vector<byte>&); - MemoryVector<byte> get_key_id() const { return key_id; } + std::vector<byte> get_key_id() const { return key_id; } private: std::string config_id() const { return "subject_key_id"; } std::string oid_name() const { return "X509v3.SubjectKeyIdentifier"; } bool should_encode() const { return (key_id.size() > 0); } - MemoryVector<byte> encode_inner() const; - void decode_inner(const MemoryRegion<byte>&); + std::vector<byte> encode_inner() const; + void decode_inner(const std::vector<byte>&); void contents_to(Data_Store&, Data_Store&) const; - MemoryVector<byte> key_id; + std::vector<byte> key_id; }; /** @@ -171,19 +171,19 @@ class BOTAN_DLL Authority_Key_ID : public Certificate_Extension Authority_Key_ID* copy() const { return new Authority_Key_ID(key_id); } Authority_Key_ID() {} - Authority_Key_ID(const MemoryRegion<byte>& k) : key_id(k) {} + Authority_Key_ID(const std::vector<byte>& k) : key_id(k) {} - MemoryVector<byte> get_key_id() const { return key_id; } + std::vector<byte> get_key_id() const { return key_id; } private: std::string config_id() const { return "authority_key_id"; } std::string oid_name() const { return "X509v3.AuthorityKeyIdentifier"; } bool should_encode() const { return (key_id.size() > 0); } - MemoryVector<byte> encode_inner() const; - void decode_inner(const MemoryRegion<byte>&); + std::vector<byte> encode_inner() const; + void decode_inner(const std::vector<byte>&); void contents_to(Data_Store&, Data_Store&) const; - MemoryVector<byte> key_id; + std::vector<byte> key_id; }; /** @@ -204,8 +204,8 @@ class BOTAN_DLL Alternative_Name : public Certificate_Extension std::string oid_name() const { return oid_name_str; } bool should_encode() const { return alt_name.has_items(); } - MemoryVector<byte> encode_inner() const; - void decode_inner(const MemoryRegion<byte>&); + std::vector<byte> encode_inner() const; + void decode_inner(const std::vector<byte>&); void contents_to(Data_Store&, Data_Store&) const; std::string config_name_str, oid_name_str; @@ -253,8 +253,8 @@ class BOTAN_DLL Extended_Key_Usage : public Certificate_Extension std::string oid_name() const { return "X509v3.ExtendedKeyUsage"; } bool should_encode() const { return (oids.size() > 0); } - MemoryVector<byte> encode_inner() const; - void decode_inner(const MemoryRegion<byte>&); + std::vector<byte> encode_inner() const; + void decode_inner(const std::vector<byte>&); void contents_to(Data_Store&, Data_Store&) const; std::vector<OID> oids; @@ -278,8 +278,8 @@ class BOTAN_DLL Certificate_Policies : public Certificate_Extension std::string oid_name() const { return "X509v3.CertificatePolicies"; } bool should_encode() const { return (oids.size() > 0); } - MemoryVector<byte> encode_inner() const; - void decode_inner(const MemoryRegion<byte>&); + std::vector<byte> encode_inner() const; + void decode_inner(const std::vector<byte>&); void contents_to(Data_Store&, Data_Store&) const; std::vector<OID> oids; @@ -302,8 +302,8 @@ class BOTAN_DLL CRL_Number : public Certificate_Extension std::string oid_name() const { return "X509v3.CRLNumber"; } bool should_encode() const { return has_value; } - MemoryVector<byte> encode_inner() const; - void decode_inner(const MemoryRegion<byte>&); + std::vector<byte> encode_inner() const; + void decode_inner(const std::vector<byte>&); void contents_to(Data_Store&, Data_Store&) const; bool has_value; @@ -326,8 +326,8 @@ class BOTAN_DLL CRL_ReasonCode : public Certificate_Extension std::string oid_name() const { return "X509v3.ReasonCode"; } bool should_encode() const { return (reason != UNSPECIFIED); } - MemoryVector<byte> encode_inner() const; - void decode_inner(const MemoryRegion<byte>&); + std::vector<byte> encode_inner() const; + void decode_inner(const std::vector<byte>&); void contents_to(Data_Store&, Data_Store&) const; CRL_Code reason; diff --git a/src/cert/x509/x509_obj.cpp b/src/cert/x509/x509_obj.cpp index 670bd8da6..af8be0384 100644 --- a/src/cert/x509/x509_obj.cpp +++ b/src/cert/x509/x509_obj.cpp @@ -16,8 +16,6 @@ #include <algorithm> #include <memory> -#include <stdio.h> - namespace Botan { /* @@ -29,7 +27,7 @@ X509_Object::X509_Object(DataSource& stream, const std::string& labels) } /* -* Createa a generic X.509 object +* Create a generic X.509 object */ X509_Object::X509_Object(const std::string& file, const std::string& labels) { @@ -38,6 +36,15 @@ X509_Object::X509_Object(const std::string& file, const std::string& labels) } /* +* Create a generic X.509 object +*/ +X509_Object::X509_Object(const std::vector<byte>& vec, const std::string& labels) + { + DataSource_Memory stream(&vec[0], vec.size()); + init(stream, labels); + } + +/* * Read a PEM or BER X.509 object */ void X509_Object::init(DataSource& in, const std::string& labels) @@ -99,7 +106,7 @@ void X509_Object::encode(Pipe& out, X509_Encoding encoding) const /* * Return a BER encoded X.509 object */ -MemoryVector<byte> X509_Object::BER_encode() const +std::vector<byte> X509_Object::BER_encode() const { return DER_Encoder() .start_cons(SEQUENCE) @@ -109,7 +116,7 @@ MemoryVector<byte> X509_Object::BER_encode() const .encode(sig_algo) .encode(sig, BIT_STRING) .end_cons() - .get_contents(); + .get_contents_unlocked(); } /* @@ -123,7 +130,7 @@ std::string X509_Object::PEM_encode() const /* * Return the TBS data */ -MemoryVector<byte> X509_Object::tbs_data() const +std::vector<byte> X509_Object::tbs_data() const { return ASN1::put_in_sequence(tbs_bits); } @@ -131,7 +138,7 @@ MemoryVector<byte> X509_Object::tbs_data() const /* * Return the signature of this object */ -MemoryVector<byte> X509_Object::signature() const +std::vector<byte> X509_Object::signature() const { return sig; } @@ -170,7 +177,7 @@ std::string X509_Object::hash_used_for_signature() const */ bool X509_Object::check_signature(const Public_Key* pub_key) const { - std::auto_ptr<const Public_Key> key(pub_key); + std::unique_ptr<Public_Key> key(pub_key); return check_signature(*key); } @@ -196,7 +203,6 @@ bool X509_Object::check_signature(const Public_Key& pub_key) const } catch(std::exception& e) { - printf("Failure during validation %s\n", e.what()); return false; } } @@ -204,10 +210,10 @@ bool X509_Object::check_signature(const Public_Key& pub_key) const /* * Apply the X.509 SIGNED macro */ -MemoryVector<byte> X509_Object::make_signed(PK_Signer* signer, +std::vector<byte> X509_Object::make_signed(PK_Signer* signer, RandomNumberGenerator& rng, const AlgorithmIdentifier& algo, - const MemoryRegion<byte>& tbs_bits) + const secure_vector<byte>& tbs_bits) { return DER_Encoder() .start_cons(SEQUENCE) @@ -215,7 +221,7 @@ MemoryVector<byte> X509_Object::make_signed(PK_Signer* signer, .encode(algo) .encode(signer->sign_message(tbs_bits, rng), BIT_STRING) .end_cons() - .get_contents(); + .get_contents_unlocked(); } /* diff --git a/src/cert/x509/x509_obj.h b/src/cert/x509/x509_obj.h index e46e72ce3..e91389acf 100644 --- a/src/cert/x509/x509_obj.h +++ b/src/cert/x509/x509_obj.h @@ -27,12 +27,12 @@ class BOTAN_DLL X509_Object * The underlying data that is to be or was signed * @return data that is or was signed */ - MemoryVector<byte> tbs_data() const; + std::vector<byte> tbs_data() const; /** * @return signature on tbs_data() */ - MemoryVector<byte> signature() const; + std::vector<byte> signature() const; /** * @return signature algorithm that was used to generate signature @@ -52,10 +52,10 @@ class BOTAN_DLL X509_Object * @param tbs the tbs bits to be signed * @return signed X509 object */ - static MemoryVector<byte> make_signed(class PK_Signer* signer, - RandomNumberGenerator& rng, - const AlgorithmIdentifier& alg_id, - const MemoryRegion<byte>& tbs); + static std::vector<byte> make_signed(class PK_Signer* signer, + RandomNumberGenerator& rng, + const AlgorithmIdentifier& alg_id, + const secure_vector<byte>& tbs); /** * Check the signature on this data @@ -75,7 +75,7 @@ class BOTAN_DLL X509_Object /** * @return BER encoding of this */ - MemoryVector<byte> BER_encode() const; + std::vector<byte> BER_encode() const; /** * @return PEM encoding of this @@ -95,15 +95,17 @@ class BOTAN_DLL X509_Object protected: X509_Object(DataSource& src, const std::string& pem_labels); X509_Object(const std::string& file, const std::string& pem_labels); + X509_Object(const std::vector<byte>& vec, const std::string& labels); void do_decode(); X509_Object() {} AlgorithmIdentifier sig_algo; - MemoryVector<byte> tbs_bits, sig; + std::vector<byte> tbs_bits, sig; private: virtual void force_decode() = 0; void init(DataSource&, const std::string&); void decode_info(DataSource&); + std::vector<std::string> PEM_labels_allowed; std::string PEM_label_pref; }; diff --git a/src/cert/x509/x509cert.cpp b/src/cert/x509/x509cert.cpp index 52115a1a8..d757c2b58 100644 --- a/src/cert/x509/x509cert.cpp +++ b/src/cert/x509/x509cert.cpp @@ -30,12 +30,8 @@ std::vector<std::string> lookup_oids(const std::vector<std::string>& in) { std::vector<std::string> out; - std::vector<std::string>::const_iterator i = in.begin(); - while(i != in.end()) - { + for(auto i = in.begin(); i != in.end(); ++i) out.push_back(OIDS::lookup(OID(*i))); - ++i; - } return out; } @@ -62,6 +58,16 @@ X509_Certificate::X509_Certificate(const std::string& in) : } /* +* X509_Certificate Constructor +*/ +X509_Certificate::X509_Certificate(const std::vector<byte>& in) : + X509_Object(in, "CERTIFICATE/X509 CERTIFICATE") + { + self_signed = false; + do_decode(); + } + +/* * Decode the TBSCertificate data */ void X509_Certificate::force_decode() @@ -87,7 +93,7 @@ void X509_Certificate::force_decode() .decode(dn_subject); if(version > 2) - throw Decoding_Error("Unknown X.509 cert version " + Botan::to_string(version)); + throw Decoding_Error("Unknown X.509 cert version " + std::to_string(version)); if(sig_algo != sig_algo_inner) throw Decoding_Error("Algorithm identifier mismatch"); @@ -101,7 +107,7 @@ void X509_Certificate::force_decode() throw BER_Bad_Tag("X509_Certificate: Unexpected tag for public key", public_key.type_tag, public_key.class_tag); - MemoryVector<byte> v2_issuer_key_id, v2_subject_key_id; + std::vector<byte> v2_issuer_key_id, v2_subject_key_id; tbs_cert.decode_optional_string(v2_issuer_key_id, BIT_STRING, 1); tbs_cert.decode_optional_string(v2_subject_key_id, BIT_STRING, 2); @@ -133,7 +139,7 @@ void X509_Certificate::force_decode() subject.add("X509.Certificate.public_key", PEM_Code::encode( - ASN1::put_in_sequence(public_key.value), + ASN1::put_in_sequence(unlock(public_key.value)), "PUBLIC KEY" ) ); @@ -253,7 +259,7 @@ std::vector<std::string> X509_Certificate::policies() const /* * Return the authority key id */ -MemoryVector<byte> X509_Certificate::authority_key_id() const +std::vector<byte> X509_Certificate::authority_key_id() const { return issuer.get1_memvec("X509v3.AuthorityKeyIdentifier"); } @@ -261,7 +267,7 @@ MemoryVector<byte> X509_Certificate::authority_key_id() const /* * Return the subject key id */ -MemoryVector<byte> X509_Certificate::subject_key_id() const +std::vector<byte> X509_Certificate::subject_key_id() const { return subject.get1_memvec("X509v3.SubjectKeyIdentifier"); } @@ -269,7 +275,7 @@ MemoryVector<byte> X509_Certificate::subject_key_id() const /* * Return the certificate serial number */ -MemoryVector<byte> X509_Certificate::serial_number() const +std::vector<byte> X509_Certificate::serial_number() const { return subject.get1_memvec("X509.Certificate.serial"); } @@ -290,6 +296,50 @@ X509_DN X509_Certificate::subject_dn() const return create_dn(subject); } +namespace { + +bool cert_subject_dns_match(const std::string& name, + const std::vector<std::string>& cert_names) + { + for(size_t i = 0; i != cert_names.size(); ++i) + { + const std::string cn = cert_names[i]; + + if(cn == name) + return true; + + /* + * Possible wildcard match. We only support the most basic form of + * cert wildcarding ala RFC 2595 + */ + if(cn.size() > 2 && cn[0] == '*' && cn[1] == '.' && name.size() > cn.size()) + { + const std::string base = cn.substr(1, std::string::npos); + + if(name.compare(name.size() - base.size(), base.size(), base) == 0) + return true; + } + } + + return false; + } + +} + +bool X509_Certificate::matches_dns_name(const std::string& name) const + { + if(name == "") + return false; + + if(cert_subject_dns_match(name, subject_info("DNS"))) + return true; + + if(cert_subject_dns_match(name, subject_info("Name"))) + return true; + + return false; + } + /* * Compare two certificates for equality */ @@ -302,6 +352,24 @@ bool X509_Certificate::operator==(const X509_Certificate& other) const subject == other.subject); } +bool X509_Certificate::operator<(const X509_Certificate& other) const + { + /* If signature values are not equal, sort by lexicographic ordering of that */ + if(sig != other.sig) + { + if(sig < other.sig) + return true; + return false; + } + + /* + * same signatures, highly unlikely case, revert to compare + * of entire contents + */ + + return to_string() < other.to_string(); + } + /* * X.509 Certificate Comparison */ @@ -323,7 +391,7 @@ std::string X509_Certificate::to_string() const "DNS", "URI", "PKIX.XMPPAddr", - 0 }; + nullptr }; std::ostringstream out; @@ -419,24 +487,15 @@ std::string X509_Certificate::to_string() const */ X509_DN create_dn(const Data_Store& info) { - class DN_Matcher : public Data_Store::Matcher + auto names = info.search_for( + [](const std::string& key, const std::string&) { - public: - bool operator()(const std::string& key, const std::string&) const - { - if(key.find("X520.") != std::string::npos) - return true; - return false; - } - }; - - std::multimap<std::string, std::string> names = - info.search_with(DN_Matcher()); + return (key.find("X520.") != std::string::npos); + }); X509_DN dn; - std::multimap<std::string, std::string>::iterator i; - for(i = names.begin(); i != names.end(); ++i) + for(auto i = names.begin(); i != names.end(); ++i) dn.add_attribute(i->first, i->second); return dn; @@ -447,32 +506,18 @@ X509_DN create_dn(const Data_Store& info) */ AlternativeName create_alt_name(const Data_Store& info) { - class AltName_Matcher : public Data_Store::Matcher + auto names = info.search_for( + [](const std::string& key, const std::string&) { - public: - bool operator()(const std::string& key, const std::string&) const - { - for(size_t i = 0; i != matches.size(); ++i) - if(key.compare(matches[i]) == 0) - return true; - return false; - } - - AltName_Matcher(const std::string& match_any_of) - { - matches = split_on(match_any_of, '/'); - } - private: - std::vector<std::string> matches; - }; - - std::multimap<std::string, std::string> names = - info.search_with(AltName_Matcher("RFC822/DNS/URI/IP")); + return (key == "RFC822" || + key == "DNS" || + key == "URI" || + key == "IP"); + }); AlternativeName alt_name; - std::multimap<std::string, std::string>::iterator i; - for(i = names.begin(); i != names.end(); ++i) + for(auto i = names.begin(); i != names.end(); ++i) alt_name.add_attribute(i->first, i->second); return alt_name; diff --git a/src/cert/x509/x509cert.h b/src/cert/x509/x509cert.h index 6a4fd6959..e204fb274 100644 --- a/src/cert/x509/x509cert.h +++ b/src/cert/x509/x509cert.h @@ -85,19 +85,19 @@ class BOTAN_DLL X509_Certificate : public X509_Object * Get the serial number of this certificate. * @return certificates serial number */ - MemoryVector<byte> serial_number() const; + std::vector<byte> serial_number() const; /** * Get the DER encoded AuthorityKeyIdentifier of this certificate. * @return DER encoded AuthorityKeyIdentifier */ - MemoryVector<byte> authority_key_id() const; + std::vector<byte> authority_key_id() const; /** * Get the DER encoded SubjectKeyIdentifier of this certificate. * @return DER encoded SubjectKeyIdentifier */ - MemoryVector<byte> subject_key_id() const; + std::vector<byte> subject_key_id() const; /** * Check whether this certificate is self signed. @@ -148,12 +148,24 @@ class BOTAN_DLL X509_Certificate : public X509_Object std::string to_string() const; /** + * Check if a certain DNS name matches up with the information in + * the cert + */ + bool matches_dns_name(const std::string& name) const; + + /** * Check to certificates for equality. * @return true both certificates are (binary) equal */ bool operator==(const X509_Certificate& other) const; /** + * Impose an arbitrary (but consistent) ordering + * @return true if this is less than other by some unspecified criteria + */ + bool operator<(const X509_Certificate& other) const; + + /** * Create a certificate from a data source providing the DER or * PEM encoded certificate. * @param source the data source @@ -166,6 +178,9 @@ class BOTAN_DLL X509_Certificate : public X509_Object * @param filename the name of the certificate file */ X509_Certificate(const std::string& filename); + + X509_Certificate(const std::vector<byte>& in); + private: void force_decode(); friend class X509_CA; diff --git a/src/cert/x509/x509opt.cpp b/src/cert/x509/x509opt.cpp index 345df1fe0..8a27fdbde 100644 --- a/src/cert/x509/x509opt.cpp +++ b/src/cert/x509/x509opt.cpp @@ -8,7 +8,7 @@ #include <botan/x509self.h> #include <botan/oids.h> #include <botan/parsing.h> -#include <botan/time.h> +#include <chrono> namespace Botan { @@ -78,16 +78,16 @@ void X509_Cert_Options::sanity_check() const * Initialize the certificate options */ X509_Cert_Options::X509_Cert_Options(const std::string& initial_opts, - u32bit expiration_time_in_seconds) + u32bit expiration_time) { is_CA = false; path_limit = 0; constraints = NO_CONSTRAINTS; - const u64bit now = system_time(); + auto now = std::chrono::system_clock::now(); start = X509_Time(now); - end = X509_Time(now + expiration_time_in_seconds); + end = X509_Time(now + std::chrono::seconds(expiration_time)); if(initial_opts == "") return; diff --git a/src/cert/x509/x509path.cpp b/src/cert/x509/x509path.cpp index fcf27841d..1d0667f85 100644 --- a/src/cert/x509/x509path.cpp +++ b/src/cert/x509/x509path.cpp @@ -9,8 +9,8 @@ #include <botan/parsing.h> #include <botan/pubkey.h> #include <botan/oids.h> -#include <botan/time.h> #include <algorithm> +#include <chrono> #include <memory> namespace Botan { diff --git a/src/cert/x509/x509path.h b/src/cert/x509/x509path.h index 18129a236..fc784d429 100644 --- a/src/cert/x509/x509path.h +++ b/src/cert/x509/x509path.h @@ -10,7 +10,12 @@ #include <botan/x509cert.h> #include <botan/certstor.h> +<<<<<<< variant A #include <set> +>>>>>>> variant B +#include <functional> +####### Ancestor +======= end namespace Botan { diff --git a/src/cert/x509/x509self.cpp b/src/cert/x509/x509self.cpp index a2f89159f..c13772382 100644 --- a/src/cert/x509/x509self.cpp +++ b/src/cert/x509/x509self.cpp @@ -53,8 +53,8 @@ X509_Certificate create_self_signed_cert(const X509_Cert_Options& opts, opts.sanity_check(); - MemoryVector<byte> pub_key = X509::BER_encode(key); - std::auto_ptr<PK_Signer> signer(choose_sig_format(key, hash_fn, sig_algo)); + std::vector<byte> pub_key = X509::BER_encode(key); + std::unique_ptr<PK_Signer> signer(choose_sig_format(key, hash_fn, sig_algo)); load_info(opts, subject_dn, subject_alt); Key_Constraints constraints; @@ -99,8 +99,8 @@ PKCS10_Request create_cert_req(const X509_Cert_Options& opts, opts.sanity_check(); - MemoryVector<byte> pub_key = X509::BER_encode(key); - std::auto_ptr<PK_Signer> signer(choose_sig_format(key, hash_fn, sig_algo)); + std::vector<byte> pub_key = X509::BER_encode(key); + std::unique_ptr<PK_Signer> signer(choose_sig_format(key, hash_fn, sig_algo)); load_info(opts, subject_dn, subject_alt); const size_t PKCS10_VERSION = 0; @@ -134,7 +134,7 @@ PKCS10_Request create_cert_req(const X509_Cert_Options& opts, tbs_req.encode( Attribute("PKCS9.ChallengePassword", - DER_Encoder().encode(challenge).get_contents() + DER_Encoder().encode(challenge).get_contents_unlocked() ) ); } @@ -145,20 +145,17 @@ PKCS10_Request create_cert_req(const X509_Cert_Options& opts, .start_cons(SEQUENCE) .encode(extensions) .end_cons() - .get_contents() + .get_contents_unlocked() ) ) .end_explicit() .end_cons(); - DataSource_Memory source( - X509_Object::make_signed(signer.get(), - rng, - sig_algo, - tbs_req.get_contents()) - ); + const std::vector<byte> req = + X509_Object::make_signed(signer.get(), rng, sig_algo, + tbs_req.get_contents()); - return PKCS10_Request(source); + return PKCS10_Request(req); } } |