diff options
Diffstat (limited to 'src/cert')
-rw-r--r-- | src/cert/cvc/asn1_eac_tm.cpp | 114 | ||||
-rw-r--r-- | src/cert/cvc/cvc_self.cpp | 34 | ||||
-rw-r--r-- | src/cert/cvc/eac_asn_obj.h | 62 | ||||
-rw-r--r-- | src/cert/cvc/info.txt | 1 | ||||
-rw-r--r-- | src/cert/pkcs10/pkcs10.cpp | 2 | ||||
-rw-r--r-- | src/cert/x509ca/x509_ca.cpp | 11 | ||||
-rw-r--r-- | src/cert/x509ca/x509_ca.h | 6 | ||||
-rw-r--r-- | src/cert/x509cert/x509_obj.cpp | 2 | ||||
-rw-r--r-- | src/cert/x509cert/x509cert.cpp | 119 | ||||
-rw-r--r-- | src/cert/x509cert/x509cert.h | 12 | ||||
-rw-r--r-- | src/cert/x509crl/crl_ent.cpp | 3 | ||||
-rw-r--r-- | src/cert/x509crl/x509_crl.cpp | 2 | ||||
-rw-r--r-- | src/cert/x509self/x509opt.cpp | 8 | ||||
-rw-r--r-- | src/cert/x509self/x509self.cpp | 4 | ||||
-rw-r--r-- | src/cert/x509store/x509stor.cpp | 36 | ||||
-rw-r--r-- | src/cert/x509store/x509stor.h | 20 |
16 files changed, 220 insertions, 216 deletions
diff --git a/src/cert/cvc/asn1_eac_tm.cpp b/src/cert/cvc/asn1_eac_tm.cpp index db5d2fbaf..12221b582 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,7 +12,7 @@ #include <botan/charset.h> #include <botan/parsing.h> #include <botan/internal/rounding.h> -#include <botan/time.h> +#include <botan/calendar.h> namespace Botan { @@ -22,7 +22,7 @@ SecureVector<byte> enc_two_digit(u32bit in) { SecureVector<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,21 +278,6 @@ 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 */ @@ -310,34 +290,4 @@ SecureVector<byte> EAC_Time::encoded_eac_time() const 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_self.cpp b/src/cert/cvc/cvc_self.cpp index 662a1d2be..61a1e7b64 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> @@ -164,6 +163,7 @@ 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(); @@ -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,7 +231,7 @@ 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); @@ -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); diff --git a/src/cert/cvc/eac_asn_obj.h b/src/cert/cvc/eac_asn_obj.h index d0bab6fdd..54a9f1517 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,24 +73,28 @@ 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: @@ -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/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/pkcs10/pkcs10.cpp b/src/cert/pkcs10/pkcs10.cpp index 784318d3d..870a4d3a1 100644 --- a/src/cert/pkcs10/pkcs10.cpp +++ b/src/cert/pkcs10/pkcs10.cpp @@ -45,7 +45,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); diff --git a/src/cert/x509ca/x509_ca.cpp b/src/cert/x509ca/x509_ca.cpp index 40f2e3b3a..37b4f44b4 100644 --- a/src/cert/x509ca/x509_ca.cpp +++ b/src/cert/x509ca/x509_ca.cpp @@ -13,10 +13,6 @@ #include <botan/parsing.h> #include <botan/lookup.h> #include <botan/oids.h> -#include <botan/time.h> -#include <algorithm> -#include <typeinfo> -#include <iterator> #include <memory> #include <set> @@ -56,7 +52,7 @@ 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()); + std::unique_ptr<Public_Key> key(req.subject_public_key()); constraints = X509::find_constraints(*key, req.constraints()); } @@ -172,7 +168,8 @@ 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( @@ -185,7 +182,7 @@ X509_CRL X509_CA::make_crl(const std::vector<CRL_Entry>& revoked, .encode(ca_sig_algo) .encode(cert.issuer_dn()) .encode(X509_Time(current_time)) - .encode(X509_Time(current_time + next_update)) + .encode(X509_Time(expire_time)) .encode_if(revoked.size() > 0, DER_Encoder() .start_cons(SEQUENCE) diff --git a/src/cert/x509ca/x509_ca.h b/src/cert/x509ca/x509_ca.h index 97be6a415..7aca26d03 100644 --- a/src/cert/x509ca/x509_ca.h +++ b/src/cert/x509ca/x509_ca.h @@ -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/x509cert/x509_obj.cpp b/src/cert/x509cert/x509_obj.cpp index 13193f09c..eff8e2543 100644 --- a/src/cert/x509cert/x509_obj.cpp +++ b/src/cert/x509cert/x509_obj.cpp @@ -168,7 +168,7 @@ std::string X509_Object::hash_used_for_signature() const */ bool X509_Object::check_signature(Public_Key* pub_key) const { - std::auto_ptr<Public_Key> key(pub_key); + std::unique_ptr<Public_Key> key(pub_key); return check_signature(*key); } diff --git a/src/cert/x509cert/x509cert.cpp b/src/cert/x509cert/x509cert.cpp index 7d9370f2a..4cff28c39 100644 --- a/src/cert/x509cert/x509cert.cpp +++ b/src/cert/x509cert/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; } @@ -87,7 +83,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"); @@ -284,6 +280,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 */ @@ -296,6 +336,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 */ @@ -413,24 +471,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; @@ -441,32 +490,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/x509cert/x509cert.h b/src/cert/x509cert/x509cert.h index 8798ef1c2..26c57e524 100644 --- a/src/cert/x509cert/x509cert.h +++ b/src/cert/x509cert/x509cert.h @@ -146,12 +146,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 diff --git a/src/cert/x509crl/crl_ent.cpp b/src/cert/x509crl/crl_ent.cpp index d566637f6..a5663e6bb 100644 --- a/src/cert/x509crl/crl_ent.cpp +++ b/src/cert/x509crl/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/x509crl/x509_crl.cpp b/src/cert/x509crl/x509_crl.cpp index 01fce4c52..72da81fce 100644 --- a/src/cert/x509crl/x509_crl.cpp +++ b/src/cert/x509crl/x509_crl.cpp @@ -44,7 +44,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); diff --git a/src/cert/x509self/x509opt.cpp b/src/cert/x509self/x509opt.cpp index 345df1fe0..8a27fdbde 100644 --- a/src/cert/x509self/x509opt.cpp +++ b/src/cert/x509self/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/x509self/x509self.cpp b/src/cert/x509self/x509self.cpp index a2f89159f..c100ee825 100644 --- a/src/cert/x509self/x509self.cpp +++ b/src/cert/x509self/x509self.cpp @@ -54,7 +54,7 @@ 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::unique_ptr<PK_Signer> signer(choose_sig_format(key, hash_fn, sig_algo)); load_info(opts, subject_dn, subject_alt); Key_Constraints constraints; @@ -100,7 +100,7 @@ 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::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; diff --git a/src/cert/x509store/x509stor.cpp b/src/cert/x509store/x509stor.cpp index 3fe1adf62..a635b3930 100644 --- a/src/cert/x509store/x509stor.cpp +++ b/src/cert/x509store/x509stor.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 { @@ -21,13 +21,14 @@ namespace { * Do a validity check */ s32bit validity_check(const X509_Time& start, const X509_Time& end, - u64bit current_time, u32bit slack) + const std::chrono::system_clock::time_point& now, + std::chrono::seconds slack) { const s32bit NOT_YET_VALID = -1, VALID_TIME = 0, EXPIRED = 1; - if(start.cmp(current_time + slack) > 0) + if(start.cmp(now + slack) > 0) return NOT_YET_VALID; - if(end.cmp(current_time - slack) < 0) + if(end.cmp(now - slack) < 0) return EXPIRED; return VALID_TIME; } @@ -168,7 +169,8 @@ bool X509_Store::CRL_Data::operator<(const X509_Store::CRL_Data& other) const /* * X509_Store Constructor */ -X509_Store::X509_Store(u32bit slack, u32bit cache_timeout) +X509_Store::X509_Store(std::chrono::seconds slack, + std::chrono::seconds cache_timeout) { revoked_info_valid = true; @@ -211,10 +213,11 @@ X509_Code X509_Store::validate_cert(const X509_Certificate& cert, if(chaining_result != VERIFIED) return chaining_result; - const u64bit current_time = system_time(); + auto current_time = std::chrono::system_clock::now(); s32bit time_check = validity_check(cert.start_time(), cert.end_time(), current_time, time_slack); + if(time_check < 0) return CERT_NOT_YET_VALID; else if(time_check > 0) return CERT_HAS_EXPIRED; @@ -373,7 +376,7 @@ X509_Code X509_Store::check_sig(const Cert_Info& cert_info, */ X509_Code X509_Store::check_sig(const X509_Object& object, Public_Key* key) { - std::auto_ptr<Public_Key> pub_key(key); + std::unique_ptr<Public_Key> pub_key(key); try { std::vector<std::string> sig_info = @@ -528,8 +531,10 @@ void X509_Store::add_trusted_certs(DataSource& source) */ X509_Code X509_Store::add_crl(const X509_CRL& crl) { + auto current_time = std::chrono::system_clock::now(); + s32bit time_check = validity_check(crl.this_update(), crl.next_update(), - system_time(), time_slack); + current_time, time_slack); if(time_check < 0) return CRL_NOT_YET_VALID; else if(time_check > 0) return CRL_HAS_EXPIRED; @@ -568,8 +573,7 @@ X509_Code X509_Store::add_crl(const X509_CRL& crl) revoked_info.serial = revoked_certs[j].serial_number(); revoked_info.auth_key_id = crl.authority_key_id(); - std::vector<CRL_Data>::iterator p = - std::find(revoked.begin(), revoked.end(), revoked_info); + auto p = std::find(revoked.begin(), revoked.end(), revoked_info); if(revoked_certs[j].reason_code() == REMOVE_FROM_CRL) { @@ -607,8 +611,8 @@ X509_Store::Cert_Info::Cert_Info(const X509_Certificate& c, bool t) : cert(c), trusted(t) { checked = false; + last_checked = std::chrono::system_clock::time_point::min(); result = UNKNOWN_X509_ERROR; - last_checked = 0; } /* @@ -626,9 +630,9 @@ X509_Code X509_Store::Cert_Info::verify_result() const */ void X509_Store::Cert_Info::set_result(X509_Code code) const { - result = code; - last_checked = system_time(); checked = true; + last_checked = std::chrono::system_clock::now(); + result = code; } /* @@ -642,16 +646,16 @@ bool X509_Store::Cert_Info::is_trusted() const /* * Check if this certificate has been verified */ -bool X509_Store::Cert_Info::is_verified(u32bit timeout) const +bool X509_Store::Cert_Info::is_verified(std::chrono::seconds timeout) const { if(!checked) return false; if(result != VERIFIED && result != CERT_NOT_YET_VALID) return true; - const u64bit current_time = system_time(); + auto now = std::chrono::system_clock::now(); - if(current_time > last_checked + timeout) + if(now > last_checked + timeout) checked = false; return checked; diff --git a/src/cert/x509store/x509stor.h b/src/cert/x509store/x509stor.h index b4b50022c..532db6190 100644 --- a/src/cert/x509store/x509stor.h +++ b/src/cert/x509store/x509stor.h @@ -11,6 +11,7 @@ #include <botan/x509cert.h> #include <botan/x509_crl.h> #include <botan/certstor.h> +#include <functional> namespace Botan { @@ -70,14 +71,18 @@ class BOTAN_DLL X509_Store void add_new_certstore(Certificate_Store*); - X509_Store(u32bit time_slack = 24*60*60, - u32bit cache_results = 30*60); + X509_Store& operator=(const X509_Store&) = delete; + + /** + * @param slack the slack in checking validity times against current clock + * @param cache how long to cache validation results before rechecking + */ + X509_Store(std::chrono::seconds slack = std::chrono::seconds(24*60*60), + std::chrono::seconds cache = std::chrono::seconds(30*60)); X509_Store(const X509_Store&); ~X509_Store(); private: - X509_Store& operator=(const X509_Store&) { return (*this); } - class BOTAN_DLL CRL_Data { public: @@ -91,7 +96,7 @@ class BOTAN_DLL X509_Store class BOTAN_DLL Cert_Info { public: - bool is_verified(u32bit timeout) const; + bool is_verified(std::chrono::seconds cache_timeout) const; bool is_trusted() const; X509_Code verify_result() const; void set_result(X509_Code) const; @@ -102,7 +107,7 @@ class BOTAN_DLL X509_Store private: mutable bool checked; mutable X509_Code result; - mutable u64bit last_checked; + mutable std::chrono::system_clock::time_point last_checked; }; static X509_Code check_sig(const X509_Object&, Public_Key*); @@ -122,7 +127,8 @@ class BOTAN_DLL X509_Store std::vector<Cert_Info> certs; std::vector<CRL_Data> revoked; std::vector<Certificate_Store*> stores; - u32bit time_slack, validation_cache_timeout; + + std::chrono::seconds time_slack, validation_cache_timeout; mutable bool revoked_info_valid; }; |