static
-struct tm
+LocalTime
convert_time (ASN1_TIME const * time)
{
- struct tm t;
+ LocalTime t;
char const * s = (char const *) time->data;
if (time->type == V_ASN1_UTCTIME) {
- sscanf(s, "%2d%2d%2d%2d%2d%2d", &t.tm_year, &t.tm_mon, &t.tm_mday, &t.tm_hour, &t.tm_min, &t.tm_sec);
- if (t.tm_year < 70) {
- t.tm_year += 100;
- }
+ return LocalTime::from_asn1_utc_time (s);
} else if (time->type == V_ASN1_GENERALIZEDTIME) {
- sscanf(s, "%4d%2d%2d%2d%2d%2d", &t.tm_year, &t.tm_mon, &t.tm_mday, &t.tm_hour, &t.tm_min, &t.tm_sec);
- t.tm_year -= 1900;
+ return LocalTime::from_asn1_generalized_time (s);
}
- t.tm_mon--;
-
- return t;
+ DCP_ASSERT (false);
+ return {};
}
-struct tm
+LocalTime
Certificate::not_before () const
{
DCP_ASSERT (_certificate);
}
-struct tm
+LocalTime
Certificate::not_after () const
{
DCP_ASSERT (_certificate);
#define LIBDCP_CERTIFICATE_H
+#include "local_time.h"
#undef X509_NAME
#include <openssl/x509.h>
#include <boost/filesystem.hpp>
std::string subject_common_name () const;
std::string subject_organization_name () const;
std::string subject_organizational_unit_name () const;
- struct tm not_before () const;
- struct tm not_after () const;
+
+ LocalTime not_before () const;
+ LocalTime not_after () const;
X509* x509 () const {
return _certificate;
DCP_ASSERT (!_keys.empty ());
for (auto i: signer->leaf_to_root()) {
- if (day_greater_than_or_equal(dcp::LocalTime(i.not_before()), _not_valid_before)) {
+ if (day_greater_than_or_equal(i.not_before(), _not_valid_before)) {
throw BadKDMDateError (true);
- } else if (day_less_than_or_equal(dcp::LocalTime(i.not_after()), _not_valid_after)) {
+ } else if (day_less_than_or_equal(i.not_after(), _not_valid_after)) {
throw BadKDMDateError (false);
}
}
s << t.as_string ();
return s;
}
+
+
+LocalTime
+LocalTime::from_asn1_utc_time (string time)
+{
+ LocalTime t;
+ sscanf(time.c_str(), "%2d%2d%2d%2d%2d%2d", &t._year, &t._month, &t._day, &t._hour, &t._minute, &t._second);
+
+ if (t._year < 70) {
+ t._year += 100;
+ }
+ t._year += 1900;
+
+ t._tz_hour = t._tz_minute = t._millisecond = 0;
+
+ return t;
+}
+
+
+LocalTime
+LocalTime::from_asn1_generalized_time (string time)
+{
+ LocalTime t;
+ sscanf(time.c_str(), "%4d%2d%2d%2d%2d%2d", &t._year, &t._month, &t._day, &t._hour, &t._minute, &t._second);
+
+ t._tz_hour = t._tz_minute = t._millisecond = 0;
+
+ return t;
+}
+
+
return _year;
}
+ int hour () const {
+ return _hour;
+ }
+
+ int minute () const {
+ return _minute;
+ }
+
+ int second () const {
+ return _second;
+ }
+
void set_year (int y) {
_year = y;
}
void add_months (int a);
void add_minutes (int a);
+ static LocalTime from_asn1_utc_time (std::string time);
+ static LocalTime from_asn1_generalized_time (std::string time);
+
bool operator== (LocalTime const & other) const;
bool operator!= (LocalTime const & other) const;
bool operator< (LocalTime const & other) const;
BOOST_AUTO_TEST_CASE (certificate_not_before_after)
{
dcp::Certificate c (dcp::file_to_string("test/ref/crypt/ca.self-signed.pem"));
- struct tm not_before = c.not_before();
- BOOST_CHECK_EQUAL (not_before.tm_sec, 8);
- BOOST_CHECK_EQUAL (not_before.tm_min, 20);
- BOOST_CHECK_EQUAL (not_before.tm_hour, 13);
- BOOST_CHECK_EQUAL (not_before.tm_mday, 5);
- BOOST_CHECK_EQUAL (not_before.tm_mon, 5);
- BOOST_CHECK_EQUAL (not_before.tm_year, 115);
- struct tm not_after = c.not_after();
- BOOST_CHECK_EQUAL (not_after.tm_sec, 8);
- BOOST_CHECK_EQUAL (not_after.tm_min, 20);
- BOOST_CHECK_EQUAL (not_after.tm_hour, 13);
- BOOST_CHECK_EQUAL (not_after.tm_mday, 2);
- BOOST_CHECK_EQUAL (not_after.tm_mon, 5);
- BOOST_CHECK_EQUAL (not_after.tm_year, 125);
+ auto not_before = c.not_before();
+ BOOST_CHECK_EQUAL (not_before.second(), 8);
+ BOOST_CHECK_EQUAL (not_before.minute(), 20);
+ BOOST_CHECK_EQUAL (not_before.hour(), 13);
+ BOOST_CHECK_EQUAL (not_before.day(), 5);
+ BOOST_CHECK_EQUAL (not_before.month(), 6);
+ BOOST_CHECK_EQUAL (not_before.year(), 2015);
+ auto not_after = c.not_after();
+ BOOST_CHECK_EQUAL (not_after.second(), 8);
+ BOOST_CHECK_EQUAL (not_after.minute(), 20);
+ BOOST_CHECK_EQUAL (not_after.hour(), 13);
+ BOOST_CHECK_EQUAL (not_after.day(), 2);
+ BOOST_CHECK_EQUAL (not_after.month(), 6);
+ BOOST_CHECK_EQUAL (not_after.year(), 2025);
}
BOOST_CHECK_EQUAL (t.as_string(), "2018-02-28T11:00:00+01:00");
}
}
+
+
+BOOST_AUTO_TEST_CASE (local_time_from_asn1_utctime_test)
+{
+ BOOST_CHECK_EQUAL (dcp::LocalTime::from_asn1_utc_time("991231235952").as_string(), "1999-12-31T23:59:52+00:00");
+ BOOST_CHECK_EQUAL (dcp::LocalTime::from_asn1_utc_time("210215165952").as_string(), "2021-02-15T16:59:52+00:00");
+}
+
+
+BOOST_AUTO_TEST_CASE (local_time_from_asn1_generalized_time_test)
+{
+ BOOST_CHECK_EQUAL (dcp::LocalTime::from_asn1_generalized_time("19991231235952").as_string(), "1999-12-31T23:59:52+00:00");
+ BOOST_CHECK_EQUAL (dcp::LocalTime::from_asn1_generalized_time("20210215165952").as_string(), "2021-02-15T16:59:52+00:00");
+}
+
}
-static string
-tm_to_string (struct tm t)
-{
- char buffer[64];
- snprintf (buffer, 64, "%02d/%02d/%02d %02d:%02d:%02d", t.tm_mday, t.tm_mon + 1, t.tm_year + 1900, t.tm_hour, t.tm_min, t.tm_sec);
- return buffer;
-}
-
-
int
main (int argc, char* argv[])
try
cout << "\t\tSubject common name: " << i.subject_common_name() << "\n";
cout << "\t\tSubject organization name: " << i.subject_organization_name() << "\n";
cout << "\t\tSubject organizational unit name: " << i.subject_organizational_unit_name() << "\n";
- cout << "\t\tNot before: " << tm_to_string(i.not_before()) << "\n";
- cout << "\t\tNot after: " << tm_to_string(i.not_after()) << "\n";
+ cout << "\t\tNot before: " << i.not_before().as_string() << "\n";
+ cout << "\t\tNot after: " << i.not_after().as_string() << "\n";
if (i.has_utf8_strings()) {
cout << "\t\tUSES INCORRECT (UTF8) STRING ENCODING\n";
}