PKG_CHECK_MODULES(TEST_DEP
REQUIRED
libpcrecpp
+ openssl
)
SET(TEST_DIR ${CMAKE_CURRENT_SOURCE_DIR})
INCLUDE_DIRECTORIES(
SYSTEM
${TEST_DEP_INCLUDE_DIRS}
- ${PROJECT_SOURCE_DIR}/include
${PROJECT_SOURCE_DIR}/vcore
${TEST_DIR}/dpl/include
)
${CERT_SVC_VCORE_TESTS_DIR}/test-common.cpp
${CERT_SVC_VCORE_TESTS_DIR}/test-signature-validator.cpp
${CERT_SVC_VCORE_TESTS_DIR}/test-ocsp-check.cpp
+ ${CERT_SVC_VCORE_TESTS_DIR}/test-time-conversion.cpp
)
INCLUDE_DIRECTORIES(
- ${PROJECT_SOURCE_DIR}/vcore/src
${CERT_SVC_VCORE_TESTS_DIR}
)
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * @file test-time-conversion.cpp
+ * @author Kyungwook Tak (k.tak@samsung.com)
+ * @version 1.0
+ * @brief Internal class unit test : TimeConversion
+ */
+
+#include <cstring>
+#include <openssl/asn1.h>
+
+#include <dpl/test/test_runner.h>
+
+#include "test-common.h"
+
+#include <vcore/TimeConversion.h>
+
+static void UnitWrapper(const char *str, int type, int expected)
+{
+ ASN1_TIME asn1Time;
+
+ memset(&asn1Time, 0, sizeof(ASN1_TIME));
+
+ ASN1_STRING_set(&asn1Time, str, strlen(str));
+ asn1Time.type = type;
+
+ time_t t = 0;
+ int ret = ValidationCore::asn1TimeToTimeT(&asn1Time, &t);
+ RUNNER_ASSERT_MSG(ret == expected,
+ "ret: " << ret
+ << " expected: " << expected
+ << " time t: " << t);
+}
+
+RUNNER_TEST_GROUP_INIT(T0040_TIME_CONVERSION)
+
+RUNNER_TEST(T004101_utctime_positive_sec_and_Z_terminated)
+{
+ UnitWrapper("991231235959Z", V_ASN1_UTCTIME, 1);
+}
+
+RUNNER_TEST(T004102_utctime_positive_no_sec_and_Z_terminated)
+{
+ UnitWrapper("9912312359Z", V_ASN1_UTCTIME, 1);
+}
+
+RUNNER_TEST(T004103_utctime_positive_sec_and_plus)
+{
+ UnitWrapper("991231235959+1259", V_ASN1_UTCTIME, 1);
+}
+
+RUNNER_TEST(T004104_utctime_positive_sec_and_minus)
+{
+ UnitWrapper("991231235959-1259", V_ASN1_UTCTIME, 1);
+}
+
+RUNNER_TEST(T004105_utctime_positive_no_sec_and_plus)
+{
+ UnitWrapper("9912312359+1259", V_ASN1_UTCTIME, 1);
+}
+
+RUNNER_TEST(T004106_utctime_positive_no_sec_and_minus)
+{
+ UnitWrapper("9912312359-1259", V_ASN1_UTCTIME, 1);
+}
+
+
+
+RUNNER_TEST(T004201_utctime_negative_invalid_format_no_Z)
+{
+ UnitWrapper("9912312359", V_ASN1_UTCTIME, 0);
+}
+
+RUNNER_TEST(T004202_utctime_negative_invalid_format_no_minute)
+{
+ UnitWrapper("991231235Z", V_ASN1_UTCTIME, 0);
+}
+
+RUNNER_TEST(T004203_utctime_negative_invalid_format_too_long)
+{
+ UnitWrapper("9912312359+12590", V_ASN1_UTCTIME, 0);
+}
+
+
+
+RUNNER_TEST(T004301_gentime_positive_full_local_only)
+{
+ UnitWrapper("20001231235959.999", V_ASN1_GENERALIZEDTIME, 1);
+}
+
+RUNNER_TEST(T004302_gentime_positive_full_utc_only)
+{
+ UnitWrapper("20001231235959.999Z", V_ASN1_GENERALIZEDTIME, 1);
+}
+
+RUNNER_TEST(T004303_gentime_positive_full_local_and_utc_plus)
+{
+ UnitWrapper("20001231235959.999+1259", V_ASN1_GENERALIZEDTIME, 1);
+}
+
+RUNNER_TEST(T004304_gentime_positive_full_local_and_utc_minus)
+{
+ UnitWrapper("20001231235959.999-1259", V_ASN1_GENERALIZEDTIME, 1);
+}
+
+RUNNER_TEST(T004305_gentime_positive_no_fff_local_only)
+{
+ UnitWrapper("20001231235959", V_ASN1_GENERALIZEDTIME, 1);
+}
+
+RUNNER_TEST(T004306_gentime_positive_no_fff_utc_only)
+{
+ UnitWrapper("20001231235959Z", V_ASN1_GENERALIZEDTIME, 1);
+}
+
+RUNNER_TEST(T004307_gentime_positive_no_fff_local_and_utc_plus)
+{
+ UnitWrapper("20001231235959+1259", V_ASN1_GENERALIZEDTIME, 1);
+}
+
+RUNNER_TEST(T004308_gentime_positive_no_fff_local_and_utc_minus)
+{
+ UnitWrapper("20001231235959-1259", V_ASN1_GENERALIZEDTIME, 1);
+}
+
+RUNNER_TEST(T004309_gentime_positive_no_sec_utc_only)
+{
+ UnitWrapper("200012312359Z", V_ASN1_GENERALIZEDTIME, 1);
+}
+
+RUNNER_TEST(T004310_gentime_positive_no_sec_local_and_utc_plus)
+{
+ UnitWrapper("200012312359+1259", V_ASN1_GENERALIZEDTIME, 1);
+}
+
+RUNNER_TEST(T004311_gentime_positive_no_sec_local_and_utc_minus)
+{
+ UnitWrapper("200012312359-1259", V_ASN1_GENERALIZEDTIME, 1);
+}
+
+
+
+RUNNER_TEST(T004401_gentime_negative_invalid_format)
+{
+ UnitWrapper("200012312359599999", V_ASN1_GENERALIZEDTIME, 0);
+}
+
+RUNNER_TEST(T004402_gentime_negative_invalid_format)
+{
+ UnitWrapper("200012312359591", V_ASN1_GENERALIZEDTIME, 0);
+}
+
+RUNNER_TEST(T004403_gentime_negative_invalid_format)
+{
+ UnitWrapper("2000123123595A", V_ASN1_GENERALIZEDTIME, 0);
+}
+
+RUNNER_TEST(T004404_gentime_negative_invalid_format)
+{
+ UnitWrapper("20001231235959A", V_ASN1_GENERALIZEDTIME, 0);
+}
+
+RUNNER_TEST(T004405_gentime_negative_invalid_format)
+{
+ UnitWrapper("2000123123595", V_ASN1_GENERALIZEDTIME, 0);
+}
+
+RUNNER_TEST(T004406_gentime_negative_invalid_format)
+{
+ UnitWrapper("20001231235959+-", V_ASN1_GENERALIZEDTIME, 0);
+}
+
+RUNNER_TEST(T004407_gentime_negative_invalid_format)
+{
+ UnitWrapper("20001231235959+12599", V_ASN1_GENERALIZEDTIME, 0);
+}
+
+RUNNER_TEST(T004408_gentime_negative_invalid_format)
+{
+ UnitWrapper("20001231235959+1359", V_ASN1_GENERALIZEDTIME, 0);
+}
+
+RUNNER_TEST(T004409_gentime_negative_invalid_format)
+{
+ UnitWrapper("20000031235959", V_ASN1_GENERALIZEDTIME, 0);
+}
+
+/* k.tak : From openssl source, it's negative case for now */
+RUNNER_TEST(T004410_gentime_negative_no_sec_local_only)
+{
+ UnitWrapper("200012312359", V_ASN1_GENERALIZEDTIME, 0);
+}
+
"Reading Not After error.");
time_t output;
- if (asn1TimeToTimeT(time, &output))
+ if (asn1TimeToTimeT(time, &output) == 0)
VcoreThrowMsg(Certificate::Exception::OpensslInternalError,
"Converting ASN1_time to time_t error.");
"Reading Not Before error.");
time_t output;
- if (asn1TimeToTimeT(time, &output))
+ if (asn1TimeToTimeT(time, &output) == 0)
VcoreThrowMsg(Certificate::Exception::OpensslInternalError,
"Converting ASN1_time to time_t error.");
EXPIRED
};
-struct tm _ASN1_GetTimeT(ASN1_TIME *time)
+inline time_t _getMidTime(time_t lower, time_t upper)
{
- struct tm t;
- const char *str = (const char *)time->data;
- size_t i = 0;
-
- memset(&t, 0, sizeof(t));
-
- if (time->type == V_ASN1_UTCTIME) {
- /* two digit year */
- t.tm_year = (str[i] - '0') * 10 + (str[i + 1] - '0');
- i += 2;
- if (t.tm_year < 70)
- t.tm_year += 100;
- } else if (time->type == V_ASN1_GENERALIZEDTIME) {
- /* four digit year */
- t.tm_year =
- (str[i] - '0') * 1000
- + (str[i + 1] - '0') * 100
- + (str[i + 2] - '0') * 10
- + (str[i + 3] - '0');
- i += 4;
- t.tm_year -= 1900;
- }
-
- t.tm_mon = (str[i] - '0') * 10 + (str[i + 1] - '0') - 1; // -1 since January is 0 not 1.
- t.tm_mday = (str[i + 2] - '0') * 10 + (str[i + 3] - '0');
- t.tm_hour = (str[i + 4] - '0') * 10 + (str[i + 5] - '0');
- t.tm_min = (str[i + 6] - '0') * 10 + (str[i + 7] - '0');
- t.tm_sec = (str[i + 8] - '0') * 10 + (str[i + 9] - '0');
-
- /* Note: we did not adjust the time based on time zone information */
- return t;
+ return (lower >> 1) + (upper >> 1);
}
-struct tm getMidTime(const struct tm &tb, const struct tm &ta)
+inline CertTimeStatus _timeValidation(time_t lower, time_t upper, time_t current)
{
- struct tm tMid;
- memset(&tMid, 0, sizeof(tMid));
-
- LogDebug("Certificate's notBeforeTime : Year["
- << (tb.tm_year + 1900)
- << "] Month[" << (tb.tm_mon + 1)
- << "] Day[" << tb.tm_mday << "] ");
-
- LogDebug("Certificate's notAfterTime : Year["
- << (ta.tm_year + 1900)
- << "] Month[" << (ta.tm_mon + 1)
- << "] Day[" << ta.tm_mday << "] ");
-
- int year = (ta.tm_year - tb.tm_year) / 4;
-
- if (year == 0) {
- tMid.tm_year = tb.tm_year;
- tMid.tm_mon = tb.tm_mon + 1;
- tMid.tm_mday = tb.tm_mday;
-
- if (tMid.tm_mon == 12) {
- tMid.tm_year = ta.tm_year;
- tMid.tm_mon = ta.tm_mon - 1;
- tMid.tm_mday = ta.tm_mday;
-
- if (tMid.tm_mon < 0) {
- tMid.tm_year = ta.tm_year;
- tMid.tm_mon = ta.tm_mon;
- tMid.tm_mday = ta.tm_mday - 1;
-
- if (tMid.tm_mday == 0) {
- tMid.tm_year = tb.tm_year;
- tMid.tm_mon = tb.tm_mon;
- tMid.tm_mday = tb.tm_mday + 1;
- }
- }
- }
- } else {
- tMid.tm_year = tb.tm_year + year;
- tMid.tm_mon = (tb.tm_mon + ta.tm_mon) / 2;
- tMid.tm_mday = (tb.tm_mday + ta.tm_mday) / 2;
- }
-
- LogDebug("cmp cert with validation time. Year["
- << (tMid.tm_year + 1900)
- << "] Month[" << (tMid.tm_mon + 1)
- << "] Day[" << tMid.tm_mday << "] ");
-
- return tMid;
-}
-
-inline CertTimeStatus timeValidation(ASN1_TIME *min, ASN1_TIME *max, time_t *cur)
-{
- if (X509_cmp_time(min, cur) > 0)
+ if (current < lower)
return CertTimeStatus::NOT_YET;
- else if (X509_cmp_time(max, cur) < 0)
+ else if (current > upper)
return CertTimeStatus::EXPIRED;
else
return CertTimeStatus::VALID;
}
-inline bool isTimeStrict(const Set &stores)
+inline bool _isTimeStrict(const Set &stores)
{
return (stores.contains(TIZEN_TEST) || stores.contains(TIZEN_VERIFY))
? true : false;
m_context.certificatePtr = m_data.getCertList().back();
/* certificate time check */
- ASN1_TIME *notAfterTime = m_data.getEndEntityCertificatePtr()->getNotAfterTime();
- ASN1_TIME *notBeforeTime = m_data.getEndEntityCertificatePtr()->getNotBeforeTime();
-
- time_t nowTime = time(NULL);
+ time_t lower = m_data.getEndEntityCertificatePtr()->getNotBefore();
+ time_t upper = m_data.getEndEntityCertificatePtr()->getNotAfter();
+ time_t current = time(NULL);
+ CertTimeStatus status = _timeValidation(lower, upper, current);
- CertTimeStatus status = timeValidation(notBeforeTime, notAfterTime, &nowTime);
if (status != CertTimeStatus::VALID) {
- if (isTimeStrict(storeIdSet))
+ if (_isTimeStrict(storeIdSet))
return status == CertTimeStatus::EXPIRED
? E_SIG_CERT_EXPIRED : E_SIG_CERT_NOT_YET;
- struct tm tMid = getMidTime(
- _ASN1_GetTimeT(notBeforeTime),
- _ASN1_GetTimeT(notAfterTime));
-
- m_context.validationTime = mktime(&tMid);
+ time_t mid = _getMidTime(lower, upper);
+ LogInfo("Use middle notBeforeTime and notAfterTime."
+ " lower: " << lower
+ << " upper: " << upper
+ << " mid: " << mid
+ << " current: " << current);
+ m_context.validationTime = mid;
}
return E_SIG_NONE;
/*
- * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*/
#include <vcore/TimeConversion.h>
-#include <string.h>
+#include <cstring>
-#include <dpl/log/log.h>
-#include <dpl/assert.h>
+namespace {
-namespace ValidationCore {
+void _gmtime_adj(struct tm *tm, int offset)
+{
+ time_t t = mktime(tm);
+ t += offset;
-int asn1TimeToTimeT(ASN1_TIME *t, time_t *res)
+ memset(tm, 0, sizeof(struct tm));
+
+ gmtime_r(&t, tm);
+}
+
+/*
+ * from openssl/crypto/asn1/a_gentm.c, openssl version 1.0.2d
+ * return 1 on success, 0 on error
+ * 1. local time only : yyyymmddHHMMSS[.fff]
+ * 2. UTC time only : yyyymmddHHMM[SS[.fff]]Z
+ * 3. Difference between local and UTC times : yyyymmddHHMM[SS[.fff]](+|-)HHMM
+ */
+int asn1_generalizedtime_to_tm(struct tm *tm, const ASN1_GENERALIZEDTIME *d)
{
- struct tm tm;
- int offset;
+ static const int min[9] = { 0, 0, 1, 1, 0, 0, 0, 0, 0 };
+ static const int max[9] = { 99, 99, 12, 31, 23, 59, 59, 12, 59 };
+ char *a;
+ int n, i, l, o;
+
+ if (d->type != V_ASN1_GENERALIZEDTIME)
+ return (0);
+ l = d->length;
+ a = (char *)d->data;
+ o = 0;
+ /*
+ * GENERALIZEDTIME is similar to UTCTIME except the year is represented
+ * as YYYY. This stuff treats everything as a two digit field so make
+ * first two fields 00 to 99
+ */
+ if (l < 13)
+ goto err;
+ for (i = 0; i < 7; i++) {
+ if ((i == 6) && ((a[o] == 'Z') || (a[o] == '+') || (a[o] == '-'))) {
+ i++;
+ if (tm)
+ tm->tm_sec = 0;
+ break;
+ }
+ if ((a[o] < '0') || (a[o] > '9'))
+ goto err;
+ n = a[o] - '0';
+ if (++o > l)
+ goto err;
+
+ if ((a[o] < '0') || (a[o] > '9'))
+ goto err;
+ n = (n * 10) + a[o] - '0';
+ if (++o > l)
+ goto err;
- (*res) = 0;
- if (!ASN1_TIME_check(t)) {
- return -1;
+ if ((n < min[i]) || (n > max[i]))
+ goto err;
+ if (tm) {
+ switch (i) {
+ case 0:
+ tm->tm_year = n * 100 - 1900;
+ break;
+ case 1:
+ tm->tm_year += n;
+ break;
+ case 2:
+ tm->tm_mon = n - 1;
+ break;
+ case 3:
+ tm->tm_mday = n;
+ break;
+ case 4:
+ tm->tm_hour = n;
+ break;
+ case 5:
+ tm->tm_min = n;
+ break;
+ case 6:
+ tm->tm_sec = n;
+ break;
+ }
+ }
+ }
+ /*
+ * Optional fractional seconds: decimal point followed by one or more
+ * digits.
+ */
+ if (a[o] == '.') {
+ if (++o > l)
+ goto err;
+ i = o;
+ while ((a[o] >= '0') && (a[o] <= '9') && (o <= l))
+ o++;
+ /* Must have at least one digit after decimal point */
+ if (i == o)
+ goto err;
}
- memset(&tm, 0, sizeof(tm));
+ if (a[o] == 'Z')
+ o++;
+ else if ((a[o] == '+') || (a[o] == '-')) {
+ int offsign = a[o] == '-' ? -1 : 1, offset = 0;
+ o++;
+ if (o + 4 > l)
+ goto err;
+ for (i = 7; i < 9; i++) {
+ if ((a[o] < '0') || (a[o] > '9'))
+ goto err;
+ n = a[o] - '0';
+ o++;
+ if ((a[o] < '0') || (a[o] > '9'))
+ goto err;
+ n = (n * 10) + a[o] - '0';
+ if ((n < min[i]) || (n > max[i]))
+ goto err;
+ if (tm) {
+ if (i == 7)
+ offset = n * 3600;
+ else if (i == 8)
+ offset += n * 60;
+ }
+ o++;
+ }
+ if (offset)
+ _gmtime_adj(tm, offset * offsign);
+ } else if (a[o]) {
+ /* Missing time zone information. */
+ goto err;
+ }
+ return (o == l);
+ err:
+ return (0);
+}
+
+/*
+ * from openssl/crypto/asn1/a_utctm.c, openssl version 1.0.2d
+ * return 1 on success, 0 on error
+ * 1. yymmddHHMM[SS]Z
+ * 2. yymmddHHMM[SS](+|-)HHMM
+ */
+int asn1_utctime_to_tm(struct tm *tm, const ASN1_UTCTIME *d)
+{
+ static const int min[8] = { 0, 1, 1, 0, 0, 0, 0, 0 };
+ static const int max[8] = { 99, 12, 31, 23, 59, 59, 12, 59 };
+ char *a;
+ int n, i, l, o;
-#define g2(p) (((p)[0] - '0') * 10 + (p)[1] - '0')
- if (t->type == V_ASN1_UTCTIME) {
- Assert(t->length > 12);
+ if (d->type != V_ASN1_UTCTIME)
+ return (0);
+ l = d->length;
+ a = (char *)d->data;
+ o = 0;
- /* this code is copied from OpenSSL asn1/a_utctm.c file */
- tm.tm_year = g2(t->data);
- if (tm.tm_year < 50) {
- tm.tm_year += 100;
+ if (l < 11)
+ goto err;
+ for (i = 0; i < 6; i++) {
+ if ((i == 5) && ((a[o] == 'Z') || (a[o] == '+') || (a[o] == '-'))) {
+ i++;
+ if (tm)
+ tm->tm_sec = 0;
+ break;
}
- tm.tm_mon = g2(t->data + 2) - 1;
- tm.tm_mday = g2(t->data + 4);
- tm.tm_hour = g2(t->data + 6);
- tm.tm_min = g2(t->data + 8);
- tm.tm_sec = g2(t->data + 10);
- if (t->data[12] == 'Z') {
- offset = 0;
- } else {
- Assert(t->length > 16);
-
- offset = g2(t->data + 13) * 60 + g2(t->data + 15);
- if (t->data[12] == '-') {
- offset = -offset;
+ if ((a[o] < '0') || (a[o] > '9'))
+ goto err;
+ n = a[o] - '0';
+ if (++o > l)
+ goto err;
+
+ if ((a[o] < '0') || (a[o] > '9'))
+ goto err;
+ n = (n * 10) + a[o] - '0';
+ if (++o > l)
+ goto err;
+
+ if ((n < min[i]) || (n > max[i]))
+ goto err;
+ if (tm) {
+ switch (i) {
+ case 0:
+ tm->tm_year = n < 50 ? n + 100 : n;
+ break;
+ case 1:
+ tm->tm_mon = n - 1;
+ break;
+ case 2:
+ tm->tm_mday = n;
+ break;
+ case 3:
+ tm->tm_hour = n;
+ break;
+ case 4:
+ tm->tm_min = n;
+ break;
+ case 5:
+ tm->tm_sec = n;
+ break;
}
}
- tm.tm_isdst = -1;
- } else {
- Assert(t->length > 14);
-
- tm.tm_year = g2(t->data) * 100 + g2(t->data + 2);
- tm.tm_mon = g2(t->data + 4) - 1;
- tm.tm_mday = g2(t->data + 6);
- tm.tm_hour = g2(t->data + 8);
- tm.tm_min = g2(t->data + 10);
- tm.tm_sec = g2(t->data + 12);
- if (t->data[14] == 'Z') {
- offset = 0;
- } else {
- Assert(t->length > 18);
-
- offset = g2(t->data + 15) * 60 + g2(t->data + 17);
- if (t->data[14] == '-') {
- offset = -offset;
+ }
+ if (a[o] == 'Z')
+ o++;
+ else if ((a[o] == '+') || (a[o] == '-')) {
+ int offsign = a[o] == '-' ? -1 : 1, offset = 0;
+ o++;
+ if (o + 4 > l)
+ goto err;
+ for (i = 6; i < 8; i++) {
+ if ((a[o] < '0') || (a[o] > '9'))
+ goto err;
+ n = a[o] - '0';
+ o++;
+ if ((a[o] < '0') || (a[o] > '9'))
+ goto err;
+ n = (n * 10) + a[o] - '0';
+ if ((n < min[i]) || (n > max[i]))
+ goto err;
+ if (tm) {
+ if (i == 6)
+ offset = n * 3600;
+ else if (i == 7)
+ offset += n * 60;
}
+ o++;
}
- tm.tm_isdst = -1;
+ if (offset)
+ _gmtime_adj(tm, offset * offsign);
}
-#undef g2
- (*res) = timegm(&tm) - offset * 60;
+ return o == l;
+ err:
return 0;
}
-int asn1GeneralizedTimeToTimeT(ASN1_GENERALIZEDTIME *tm, time_t *res)
-{
- /*
- * This code is based on following assumption:
- * from openssl/a_gentm.c:
- * GENERALIZEDTIME is similar to UTCTIME except the year is
- * represented as YYYY. This stuff treats everything as a two digit
- * field so make first two fields 00 to 99
- */
- const int DATE_BUFFER_LENGTH = 15; // YYYYMMDDHHMMSSZ
+} // namespace anonymous
- if (NULL == res || NULL == tm) {
- LogError("NULL pointer");
- return -1;
- }
+namespace ValidationCore {
- if (DATE_BUFFER_LENGTH != tm->length || NULL == tm->data) {
- LogError("Invalid ASN1_GENERALIZEDTIME");
- return -1;
- }
+int asn1TimeToTimeT(ASN1_TIME *t, time_t *res)
+{
+ if (res == NULL)
+ return 0;
- struct tm time_s;
- if (sscanf ((char*)tm->data,
- "%4d%2d%2d%2d%2d%2d",
- &time_s.tm_year,
- &time_s.tm_mon,
- &time_s.tm_mday,
- &time_s.tm_hour,
- &time_s.tm_min,
- &time_s.tm_sec) < 6)
- {
- LogError("Could not extract time data from ASN1_GENERALIZEDTIME");
- return -1;
- }
+ int ret = 0;
+ struct tm tm;
- time_s.tm_year -= 1900;
- time_s.tm_mon -= 1;
- time_s.tm_isdst = 0; // UTC
- time_s.tm_gmtoff = 0; // UTC
- time_s.tm_zone = NULL; // UTC
+ memset(&tm, 0, sizeof(tm));
- *res = mktime(&time_s);
+ if (t->type == V_ASN1_UTCTIME)
+ ret = asn1_utctime_to_tm(&tm, t);
+ else if (t->type == V_ASN1_GENERALIZEDTIME)
+ ret = asn1_generalizedtime_to_tm(&tm, t);
+ else
+ ret = 0;
- return 0;
+ if (ret == 0)
+ return 0;
+
+ *res = mktime(&tm);
+ return 1;
}
} // namespace ValidationCore
#include <openssl/asn1.h>
namespace ValidationCore {
-// from OpenSSL asn1/a_utctm.c code
+
+/*
+ * openssl/crypto/asn1/a_time.c based version 1.0.2d
+ * return 1 on success, 0 on error
+ */
int asn1TimeToTimeT(ASN1_TIME *t, time_t *res);
-int asn1GeneralizedTimeToTimeT(ASN1_GENERALIZEDTIME *tm,
- time_t *res);
} // namespace ValidationCore
#endif // _VALIDATION_CORE_TIMECONVERSION_H_
-