diff options
-rw-r--r-- | checks/cvc_tests.cpp | 3 | ||||
-rw-r--r-- | src/asn1/asn1_obj.h | 3 | ||||
-rw-r--r-- | src/asn1/asn1_tm.cpp | 20 | ||||
-rw-r--r-- | src/cert/cvc/asn1_eac_tm.cpp | 53 | ||||
-rw-r--r-- | src/cert/cvc/cvc_self.cpp | 18 | ||||
-rw-r--r-- | src/cert/cvc/eac_asn_obj.h | 65 | ||||
-rw-r--r-- | src/cert/x509/crl_ent.cpp | 3 | ||||
-rw-r--r-- | src/cert/x509/x509_ca.cpp | 6 | ||||
-rw-r--r-- | src/cert/x509/x509opt.cpp | 6 | ||||
-rw-r--r-- | src/cert/x509/x509stor.cpp | 24 | ||||
-rw-r--r-- | src/cert/x509/x509stor.h | 2 | ||||
-rw-r--r-- | src/utils/time.cpp | 27 | ||||
-rw-r--r-- | src/utils/time.h | 22 |
13 files changed, 116 insertions, 136 deletions
diff --git a/checks/cvc_tests.cpp b/checks/cvc_tests.cpp index 4b2ffa9a6..7904a2700 100644 --- a/checks/cvc_tests.cpp +++ b/checks/cvc_tests.cpp @@ -350,8 +350,7 @@ void test_eac_time(RandomNumberGenerator&) { std::cout << "." << std::flush; - const u64bit current_time = system_time(); - EAC_Time time(current_time); + EAC_Time time(std::chrono::system_clock::now()); // std::cout << "time as std::string = " << time.as_string() << std::endl; EAC_Time sooner("", ASN1_Tag(99)); //X509_Time sooner("", ASN1_Tag(99)); diff --git a/src/asn1/asn1_obj.h b/src/asn1/asn1_obj.h index ea21c475f..a640f712b 100644 --- a/src/asn1/asn1_obj.h +++ b/src/asn1/asn1_obj.h @@ -14,6 +14,7 @@ #include <botan/alg_id.h> #include <vector> #include <map> +#include <chrono> namespace Botan { @@ -52,7 +53,7 @@ class BOTAN_DLL X509_Time : public ASN1_Object void set_to(const std::string&); void set_to(const std::string&, ASN1_Tag); - X509_Time(u64bit); + X509_Time(const std::chrono::system_clock::time_point& time); X509_Time(const std::string& = ""); X509_Time(const std::string&, ASN1_Tag); private: diff --git a/src/asn1/asn1_tm.cpp b/src/asn1/asn1_tm.cpp index 9df10f4a3..6e56bb8d1 100644 --- a/src/asn1/asn1_tm.cpp +++ b/src/asn1/asn1_tm.cpp @@ -23,18 +23,18 @@ X509_Time::X509_Time(const std::string& time_str) } /* -* Create an X509_Time +* Create a X509_Time from a time point */ -X509_Time::X509_Time(u64bit timer) +X509_Time::X509_Time(const std::chrono::system_clock::time_point& time) { - std::tm time_info = time_t_to_tm(timer); - - year = time_info.tm_year + 1900; - month = time_info.tm_mon + 1; - day = time_info.tm_mday; - hour = time_info.tm_hour; - minute = time_info.tm_min; - second = time_info.tm_sec; + calendar_point cal = calendar_value(time); + + year = cal.year; + month = cal.month; + day = cal.day; + hour = cal.hour; + minute = cal.minutes; + second = cal.seconds; if(year >= 2050) tag = GENERALIZED_TIME; diff --git a/src/cert/cvc/asn1_eac_tm.cpp b/src/cert/cvc/asn1_eac_tm.cpp index b0238ac4d..827710084 100644 --- a/src/cert/cvc/asn1_eac_tm.cpp +++ b/src/cert/cvc/asn1_eac_tm.cpp @@ -50,24 +50,24 @@ 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) { - std::tm time_info = time_t_to_tm(timer); + calendar_point cal = calendar_value(time); - year = time_info.tm_year + 1900; - month = time_info.tm_mon + 1; - day = time_info.tm_mday; + year = cal.year; + month = cal.month; + day = cal.day; } /* * Create an EAC_Time */ -EAC_Time::EAC_Time(const std::string& t_spec, ASN1_Tag t) - :tag(t) +EAC_Time::EAC_Time(const std::string& t_spec, ASN1_Tag t) : tag(t) { set_to(t_spec); } + /* * Create an EAC_Time */ @@ -280,19 +280,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 */ @@ -305,28 +292,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 98d90d0af..3b764644f 100644 --- a/src/cert/cvc/cvc_self.cpp +++ b/src/cert/cvc/cvc_self.cpp @@ -181,9 +181,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)); @@ -198,12 +197,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)) { @@ -278,8 +277,9 @@ EAC1_1_CVC sign_request(EAC1_1_CVC const& signer_cert, #endif 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 3e70f6b74..a6685a8ed 100644 --- a/src/cert/cvc/eac_asn_obj.h +++ b/src/cert/cvc/eac_asn_obj.h @@ -1,7 +1,7 @@ /* * EAC ASN.1 Objects * (C) 2007-2008 FlexSecure GmbH -* 2008 Jack Lloyd +* 2008-2009 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -12,6 +12,7 @@ #include <botan/asn1_obj.h> #include <vector> #include <map> +#include <chrono> namespace Botan { @@ -58,7 +59,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. @@ -76,24 +76,28 @@ class BOTAN_DLL EAC_Time : public ASN1_Object * Get the year value of this objects. * @return the year value */ - u32bit get_year() const; + u32bit get_year() const { return year; } /** * Get the month value of this objects. * @return the month value */ - u32bit get_month() const; + u32bit get_month() const { return month; } /** * Get the day value of this objects. * @return the 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: @@ -115,25 +119,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(std::string const& 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(EAC_Time const& 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. @@ -142,27 +146,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(std::string const& 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(EAC_Time const& other) : + EAC_Time(other.get_year(), other.get_month(), other.get_day(), + ASN1_Tag(36)) + {} }; /** diff --git a/src/cert/x509/crl_ent.cpp b/src/cert/x509/crl_ent.cpp index 42a742ebb..e7ce1a57a 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/x509_ca.cpp b/src/cert/x509/x509_ca.cpp index 80e808177..59a5bbaf8 100644 --- a/src/cert/x509/x509_ca.cpp +++ b/src/cert/x509/x509_ca.cpp @@ -14,7 +14,6 @@ #include <botan/lookup.h> #include <botan/look_pk.h> #include <botan/oids.h> -#include <botan/time.h> #include <memory> #include <set> @@ -197,7 +196,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( @@ -210,7 +210,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/x509/x509opt.cpp b/src/cert/x509/x509opt.cpp index c6421d9ca..a2547e30a 100644 --- a/src/cert/x509/x509opt.cpp +++ b/src/cert/x509/x509opt.cpp @@ -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 u32bit 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/x509stor.cpp b/src/cert/x509/x509stor.cpp index 323890f2d..336d155d3 100644 --- a/src/cert/x509/x509stor.cpp +++ b/src/cert/x509/x509stor.cpp @@ -22,13 +22,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, + u32bit slack) { const s32bit NOT_YET_VALID = -1, VALID_TIME = 0, EXPIRED = 1; - if(start.cmp(current_time + slack) > 0) + if(start.cmp(now + std::chrono::seconds(slack)) > 0) return NOT_YET_VALID; - if(end.cmp(current_time - slack) < 0) + if(end.cmp(now - std::chrono::seconds(slack)) < 0) return EXPIRED; return VALID_TIME; } @@ -212,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; @@ -563,8 +565,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; @@ -641,8 +645,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; } /* @@ -660,9 +664,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; } /* @@ -683,9 +687,9 @@ bool X509_Store::Cert_Info::is_verified(u32bit timeout) const 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 + std::chrono::seconds(timeout)) checked = false; return checked; diff --git a/src/cert/x509/x509stor.h b/src/cert/x509/x509stor.h index 958b6da0f..e55e36e7e 100644 --- a/src/cert/x509/x509stor.h +++ b/src/cert/x509/x509stor.h @@ -116,7 +116,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; }; u32bit find_cert(const X509_DN&, const MemoryRegion<byte>&) const; diff --git a/src/utils/time.cpp b/src/utils/time.cpp index 856b1c7be..1c64c820e 100644 --- a/src/utils/time.cpp +++ b/src/utils/time.cpp @@ -45,25 +45,30 @@ u64bit combine_timers(u32bit seconds, u32bit parts, u32bit parts_hz) } -/** -* Get the system clock -*/ -u64bit system_time() - { - return static_cast<u64bit>(std::time(0)); - } - /* * Convert a time_t to a struct tm */ -std::tm time_t_to_tm(u64bit timer) +calendar_point calendar_value( + const std::chrono::system_clock::time_point& time_point) { - std::time_t time_val = static_cast<std::time_t>(timer); + time_t time_val = std::chrono::system_clock::to_time_t(time_point); + + // Race condition: std::gmtime is not assured thread safe, + // and C++ does not include gmtime_r. Use a mutex here? std::tm* tm_p = std::gmtime(&time_val); if (tm_p == 0) throw Encoding_Error("time_t_to_tm could not convert"); - return (*tm_p); + + std::tm tm = *tm_p; + // Race is over here + + return calendar_point(tm.tm_year + 1900, + tm.tm_mon + 1, + tm.tm_mday, + tm.tm_hour, + tm.tm_min, + tm.tm_sec); } u64bit get_nanoseconds_clock() diff --git a/src/utils/time.h b/src/utils/time.h index c7f459096..28b777efe 100644 --- a/src/utils/time.h +++ b/src/utils/time.h @@ -9,16 +9,28 @@ #define BOTAN_TIME_H__ #include <botan/types.h> -#include <ctime> +#include <chrono> namespace Botan { /* -* Time Access/Conversion Functions +* Time Conversion Functions */ -BOTAN_DLL u64bit system_time(); - -BOTAN_DLL std::tm time_t_to_tm(u64bit); +struct BOTAN_DLL calendar_point + { + u32bit year; + byte month; + byte day; + byte hour; + byte minutes; + byte seconds; + + calendar_point(u32bit y, byte mon, byte d, byte h, byte min, byte sec) : + year(y), month(mon), day(d), hour(h), minutes(min), seconds(sec) {} + }; + +BOTAN_DLL calendar_point calendar_value( + const std::chrono::system_clock::time_point& time_point); /** @return nanoseconds resolution timestamp, unknown epoch |