summaryrefslogtreecommitdiff
path: root/test/asn1_time_test.c
diff options
context:
space:
mode:
authorTodd Short <tshort@akamai.com>2017-08-04 11:24:03 +1000
committerPauli <paul.dale@oracle.com>2017-08-04 11:24:03 +1000
commitcf37aaa335965902c6a022bc3c3e0162f59c0f3a (patch)
treeb00a60fd9a70836f4d97478432cd4d9ddaae73fa /test/asn1_time_test.c
parent2326bba0e5cbe98f4d00855a6909b1f14b6f5427 (diff)
downloadopenssl-new-cf37aaa335965902c6a022bc3c3e0162f59c0f3a.tar.gz
Consolidate to a single asn1_time_from_tm() function
Add missing ASN1_TIME functions Do some cleanup of the ASN1_TIME code. Add ASN1_TIME_normalize() to normalize ASN1_TIME structures. Add ASN1_TIME_compare() to compare two ASN1_TIME structures. Add ASN1_TIME_cmp_time_t() to compare an ASN1_TIME to time_t (generic version of ASN1_UTCTIME_cmp_time_t()). Replace '0' .. '9' compares with isdigit() Reviewed-by: Paul Dale <paul.dale@oracle.com> Reviewed-by: Rich Salz <rsalz@openssl.org> (Merged from https://github.com/openssl/openssl/pull/2753)
Diffstat (limited to 'test/asn1_time_test.c')
-rw-r--r--test/asn1_time_test.c296
1 files changed, 296 insertions, 0 deletions
diff --git a/test/asn1_time_test.c b/test/asn1_time_test.c
new file mode 100644
index 0000000000..184a18a5ad
--- /dev/null
+++ b/test/asn1_time_test.c
@@ -0,0 +1,296 @@
+/*
+ * Copyright 1999-2017 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+/* Time tests for the asn1 module */
+
+#include <stdio.h>
+#include <string.h>
+
+#include <openssl/asn1.h>
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include "testutil.h"
+#include "e_os.h"
+
+struct testdata {
+ char *data; /* TIME string value */
+ int type; /* GENERALIZED OR UTC */
+ int expected_type; /* expected type after set/set_string_gmt */
+ int check_result; /* check result */
+ time_t t; /* expected time_t*/
+ int cmp_result; /* compariston to baseline result */
+ int convert_result; /* convertion result */
+};
+
+static struct testdata tbl_testdata_pos[] = {
+ { "0", V_ASN1_GENERALIZEDTIME, V_ASN1_GENERALIZEDTIME, 0, 0, 0, 0, }, /* Bad time */
+ { "ABCD", V_ASN1_GENERALIZEDTIME, V_ASN1_GENERALIZEDTIME, 0, 0, 0, 0, },
+ { "0ABCD", V_ASN1_GENERALIZEDTIME, V_ASN1_GENERALIZEDTIME, 0, 0, 0, 0, },
+ { "1-700101000000Z", V_ASN1_GENERALIZEDTIME, V_ASN1_GENERALIZEDTIME, 0, 0, 0, 0, },
+ { "`9700101000000Z", V_ASN1_GENERALIZEDTIME, V_ASN1_GENERALIZEDTIME, 0, 0, 0, 0, },
+ { "19700101000000Z", V_ASN1_UTCTIME, V_ASN1_UTCTIME, 0, 0, 0, 0, },
+ { "A00101000000Z", V_ASN1_UTCTIME, V_ASN1_UTCTIME, 0, 0, 0, 0, },
+ { "A9700101000000Z", V_ASN1_GENERALIZEDTIME, V_ASN1_GENERALIZEDTIME, 0, 0, 0, 0, },
+ { "1A700101000000Z", V_ASN1_GENERALIZEDTIME, V_ASN1_GENERALIZEDTIME, 0, 0, 0, 0, },
+ { "19A00101000000Z", V_ASN1_GENERALIZEDTIME, V_ASN1_GENERALIZEDTIME, 0, 0, 0, 0, },
+ { "197A0101000000Z", V_ASN1_GENERALIZEDTIME, V_ASN1_GENERALIZEDTIME, 0, 0, 0, 0, },
+ { "1970A101000000Z", V_ASN1_GENERALIZEDTIME, V_ASN1_GENERALIZEDTIME, 0, 0, 0, 0, },
+ { "19700A01000000Z", V_ASN1_GENERALIZEDTIME, V_ASN1_GENERALIZEDTIME, 0, 0, 0, 0, },
+ { "197001A1000000Z", V_ASN1_GENERALIZEDTIME, V_ASN1_GENERALIZEDTIME, 0, 0, 0, 0, },
+ { "1970010A000000Z", V_ASN1_GENERALIZEDTIME, V_ASN1_GENERALIZEDTIME, 0, 0, 0, 0, },
+ { "19700101A00000Z", V_ASN1_GENERALIZEDTIME, V_ASN1_GENERALIZEDTIME, 0, 0, 0, 0, },
+ { "197001010A0000Z", V_ASN1_GENERALIZEDTIME, V_ASN1_GENERALIZEDTIME, 0, 0, 0, 0, },
+ { "1970010100A000Z", V_ASN1_GENERALIZEDTIME, V_ASN1_GENERALIZEDTIME, 0, 0, 0, 0, },
+ { "19700101000A00Z", V_ASN1_GENERALIZEDTIME, V_ASN1_GENERALIZEDTIME, 0, 0, 0, 0, },
+ { "197001010000A0Z", V_ASN1_GENERALIZEDTIME, V_ASN1_GENERALIZEDTIME, 0, 0, 0, 0, },
+ { "1970010100000AZ", V_ASN1_GENERALIZEDTIME, V_ASN1_GENERALIZEDTIME, 0, 0, 0, 0, },
+ { "700101000000X", V_ASN1_UTCTIME, V_ASN1_UTCTIME, 0, 0, 0, 0, },
+ { "19700101000000X", V_ASN1_GENERALIZEDTIME, V_ASN1_GENERALIZEDTIME, 0, 0, 0, 0, },
+ { "19700101000000Z", V_ASN1_GENERALIZEDTIME, V_ASN1_UTCTIME, 1, 0, -1, 1, }, /* Epoch begins */
+ { "700101000000Z", V_ASN1_UTCTIME, V_ASN1_UTCTIME, 1, 0, -1, 1, }, /* ditto */
+ { "20380119031407Z", V_ASN1_GENERALIZEDTIME, V_ASN1_UTCTIME, 1, 0x7FFFFFFF, 1, 1, }, /* Max 32bit time_t */
+ { "380119031407Z", V_ASN1_UTCTIME, V_ASN1_UTCTIME, 1, 0x7FFFFFFF, 1, 1, },
+ { "20371231235959Z", V_ASN1_GENERALIZEDTIME, V_ASN1_UTCTIME, 1, 2145916799, 1, 1, }, /* Just before 2038 */
+ { "20371231235959Z", V_ASN1_UTCTIME, V_ASN1_UTCTIME, 0, 0, 0, 1, }, /* Bad UTC time */
+ { "371231235959Z", V_ASN1_UTCTIME, V_ASN1_UTCTIME, 1, 2145916799, 1, 1, },
+ { "19701006121456Z", V_ASN1_GENERALIZEDTIME, V_ASN1_UTCTIME, 1, 24063296, -1, 1, },
+ { "701006121456Z", V_ASN1_UTCTIME, V_ASN1_UTCTIME, 1, 24063296, -1, 1, },
+ { "19991231000000Z", V_ASN1_GENERALIZEDTIME, V_ASN1_UTCTIME, 1, 946598400, 0, 1, }, /* Match baseline */
+ { "199912310000Z", V_ASN1_GENERALIZEDTIME, V_ASN1_UTCTIME, 1, 946598400, 0, 1, }, /* In various flavors */
+ { "991231000000Z", V_ASN1_UTCTIME, V_ASN1_UTCTIME, 1, 946598400, 0, 1, },
+ { "9912310000Z", V_ASN1_UTCTIME, V_ASN1_UTCTIME, 1, 946598400, 0, 1, },
+ { "9912310000+0000", V_ASN1_UTCTIME, V_ASN1_UTCTIME, 1, 946598400, 0, 1, },
+ { "199912310000+0000", V_ASN1_GENERALIZEDTIME, V_ASN1_UTCTIME, 1, 946598400, 0, 1, },
+ { "9912310000-0000", V_ASN1_UTCTIME, V_ASN1_UTCTIME, 1, 946598400, 0, 1, },
+ { "199912310000-0000", V_ASN1_GENERALIZEDTIME, V_ASN1_UTCTIME, 1, 946598400, 0, 1, },
+ { "199912310100+0100", V_ASN1_GENERALIZEDTIME, V_ASN1_UTCTIME, 1, 946598400, 0, 1, },
+ { "199912302300-0100", V_ASN1_GENERALIZEDTIME, V_ASN1_UTCTIME, 1, 946598400, 0, 1, },
+ { "199912302300-A000", V_ASN1_GENERALIZEDTIME, V_ASN1_UTCTIME, 0, 946598400, 0, 1, },
+ { "199912302300-0A00", V_ASN1_GENERALIZEDTIME, V_ASN1_UTCTIME, 0, 946598400, 0, 1, },
+ { "9912310100+0100", V_ASN1_UTCTIME, V_ASN1_UTCTIME, 1, 946598400, 0, 1, },
+ { "9912302300-0100", V_ASN1_UTCTIME, V_ASN1_UTCTIME, 1, 946598400, 0, 1, },
+};
+
+/* ASSUMES SIGNED TIME_T */
+static struct testdata tbl_testdata_neg[] = {
+ { "19011213204552Z", V_ASN1_GENERALIZEDTIME, V_ASN1_GENERALIZEDTIME, 1, -2147483648, -1, 0, },
+ { "691006121456Z", V_ASN1_UTCTIME, V_ASN1_UTCTIME, 1, -7472704, -1, 1, },
+ { "19691006121456Z", V_ASN1_GENERALIZEDTIME, V_ASN1_UTCTIME, 1, -7472704, -1, 1, },
+};
+
+static struct testdata tbl_testdata_pos_64bit[] = {
+ { "20380119031408Z", V_ASN1_GENERALIZEDTIME, V_ASN1_UTCTIME, 1, 0x80000000, 1, 1, },
+ { "20380119031409Z", V_ASN1_GENERALIZEDTIME, V_ASN1_UTCTIME, 1, 0x80000001, 1, 1, },
+ { "380119031408Z", V_ASN1_UTCTIME, V_ASN1_UTCTIME, 1, 0x80000000, 1, 1, },
+ { "20500101120000Z", V_ASN1_GENERALIZEDTIME, V_ASN1_GENERALIZEDTIME, 1, 2524651200, 1, 0, },
+};
+
+/* ASSUMES SIGNED TIME_T */
+static struct testdata tbl_testdata_neg_64bit[] = {
+ { "19011213204551Z", V_ASN1_GENERALIZEDTIME, V_ASN1_GENERALIZEDTIME, 1, -2147483649, -1, 0, },
+ { "19000101120000Z", V_ASN1_GENERALIZEDTIME, V_ASN1_GENERALIZEDTIME, 1, -2208945600, -1, 0, },
+};
+
+/* A baseline time to compare to */
+static ASN1_TIME gtime = {
+ 15,
+ V_ASN1_GENERALIZEDTIME,
+ (unsigned char*)"19991231000000Z",
+ 0
+};
+static time_t gtime_t = 946598400;
+
+static int test_table(struct testdata *tbl, int idx)
+{
+ int error = 0;
+ ASN1_TIME atime;
+ ASN1_TIME *ptime;
+ struct testdata *td = &tbl[idx];
+ int day, sec;
+
+ atime.data = (unsigned char*)td->data;
+ atime.length = strlen((char*)atime.data);
+ atime.type = td->type;
+ atime.flags = 0;
+
+ if (!TEST_int_eq(ASN1_TIME_check(&atime), td->check_result)) {
+ TEST_info("ASN1_TIME_check(%s) unexpected result", atime.data);
+ error = 1;
+ }
+ if (td->check_result == 0)
+ return 1;
+
+ if (!TEST_int_eq(ASN1_TIME_cmp_time_t(&atime, td->t), 0)) {
+ TEST_info("ASN1_TIME_cmp_time_t(%s vs %ld) compare failed", atime.data, (long)td->t);
+ error = 1;
+ }
+
+ if (!TEST_true(ASN1_TIME_diff(&day, &sec, &atime, &atime))) {
+ TEST_info("ASN1_TIME_diff(%s) to self failed", atime.data);
+ error = 1;
+ }
+ if (!TEST_int_eq(day, 0) || !TEST_int_eq(sec, 0)) {
+ TEST_info("ASN1_TIME_diff(%s) to self not equal", atime.data);
+ error = 1;
+ }
+
+ if (!TEST_true(ASN1_TIME_diff(&day, &sec, &gtime, &atime))) {
+ TEST_info("ASN1_TIME_diff(%s) to baseline failed", atime.data);
+ error = 1;
+ } else if (!((td->cmp_result == 0 && TEST_true((day == 0 && sec == 0))) ||
+ (td->cmp_result == -1 && TEST_true((day < 0 || sec < 0))) ||
+ (td->cmp_result == 1 && TEST_true((day > 0 || sec > 0))))) {
+ TEST_info("ASN1_TIME_diff(%s) to baseline bad comparison", atime.data);
+ error = 1;
+ }
+
+ if (!TEST_int_eq(ASN1_TIME_cmp_time_t(&atime, gtime_t), td->cmp_result)) {
+ TEST_info("ASN1_TIME_cmp_time_t(%s) to baseline bad comparison", atime.data);
+ error = 1;
+ }
+
+ ptime = ASN1_TIME_set(NULL, td->t);
+ if (!TEST_ptr(ptime)) {
+ TEST_info("ASN1_TIME_set(%ld) failed", (long)td->t);
+ error = 1;
+ } else {
+ int local_error = 0;
+ if (!TEST_int_eq(ASN1_TIME_cmp_time_t(ptime, td->t), 0)) {
+ TEST_info("ASN1_TIME_set(%ld) compare failed (%s->%s)",
+ (long)td->t, td->data, ptime->data);
+ local_error = error = 1;
+ }
+ if (!TEST_int_eq(ptime->type, td->expected_type)) {
+ TEST_info("ASN1_TIME_set(%ld) unexpected type", (long)td->t);
+ local_error = error = 1;
+ }
+ if (local_error)
+ TEST_info("ASN1_TIME_set() = %*s", ptime->length, ptime->data);
+ ASN1_TIME_free(ptime);
+ }
+
+ ptime = ASN1_TIME_new();
+ if (!TEST_ptr(ptime)) {
+ TEST_info("ASN1_TIME_new() failed");
+ error = 1;
+ } else {
+ int local_error = 0;
+ if (!TEST_int_eq(ASN1_TIME_set_string(ptime, td->data), td->check_result)) {
+ TEST_info("ASN1_TIME_set_string_gmt(%s) failed", td->data);
+ local_error = error = 1;
+ }
+ if (!TEST_int_eq(ASN1_TIME_normalize(ptime), td->check_result)) {
+ TEST_info("ASN1_TIME_normalize(%s) failed", td->data);
+ local_error = error = 1;
+ }
+ if (!TEST_int_eq(ptime->type, td->expected_type)) {
+ TEST_info("ASN1_TIME_set_string_gmt(%s) unexpected type", td->data);
+ local_error = error = 1;
+ }
+ day = sec = 0;
+ if (!TEST_true(ASN1_TIME_diff(&day, &sec, ptime, &atime)) || !TEST_int_eq(day, 0) || !TEST_int_eq(sec, 0)) {
+ TEST_info("ASN1_TIME_diff(day=%d, sec=%d, %s) after ASN1_TIME_set_string_gmt() failed", day, sec, td->data);
+ local_error = error = 1;
+ }
+ if (!TEST_int_eq(ASN1_TIME_cmp_time_t(ptime, gtime_t), td->cmp_result)) {
+ TEST_info("ASN1_TIME_cmp_time_t(%s) after ASN1_TIME_set_string_gnt() to baseline bad comparison", td->data);
+ local_error = error = 1;
+ }
+ if (local_error)
+ TEST_info("ASN1_TIME_set_string_gmt() = %*s", ptime->length, ptime->data);
+ ASN1_TIME_free(ptime);
+ }
+
+ ptime = ASN1_TIME_new();
+ if (!TEST_ptr(ptime)) {
+ TEST_info("ASN1_TIME_new() failed");
+ error = 1;
+ } else {
+ int local_error = 0;
+ if (!TEST_int_eq(ASN1_TIME_set_string(ptime, td->data), td->check_result)) {
+ TEST_info("ASN1_TIME_set_string(%s) failed", td->data);
+ local_error = error = 1;
+ }
+ day = sec = 0;
+ if (!TEST_true(ASN1_TIME_diff(&day, &sec, ptime, &atime)) || !TEST_int_eq(day, 0) || !TEST_int_eq(sec, 0)) {
+ TEST_info("ASN1_TIME_diff(day=%d, sec=%d, %s) after ASN1_TIME_set_string() failed", day, sec, td->data);
+ local_error = error = 1;
+ }
+ if (!TEST_int_eq(ASN1_TIME_cmp_time_t(ptime, gtime_t), td->cmp_result)) {
+ TEST_info("ASN1_TIME_cmp_time_t(%s) after ASN1_TIME_set_string() to baseline bad comparison", td->data);
+ local_error = error = 1;
+ }
+ if (local_error)
+ TEST_info("ASN1_TIME_set_string() = %*s", ptime->length, ptime->data);
+ ASN1_TIME_free(ptime);
+ }
+
+ if (td->type == V_ASN1_UTCTIME) {
+ ptime = ASN1_TIME_to_generalizedtime(&atime, NULL);
+ if (td->convert_result == 1 && !TEST_ptr(ptime)) {
+ TEST_info("ASN1_TIME_to_generalizedtime(%s) failed", atime.data);
+ error = 1;
+ } else if (td->convert_result == 0 && !TEST_ptr_null(ptime)) {
+ TEST_info("ASN1_TIME_to_generalizedtime(%s) should have failed", atime.data);
+ error = 1;
+ }
+ if (ptime != NULL && !TEST_int_eq(ASN1_TIME_cmp_time_t(ptime, td->t), 0)) {
+ TEST_info("ASN1_TIME_to_generalizedtime(%s->%s) bad result", atime.data, ptime->data);
+ error = 1;
+ }
+ ASN1_TIME_free(ptime);
+ }
+ /* else cannot simply convert GENERALIZEDTIME to UTCTIME */
+
+ if (error)
+ TEST_error("atime=%s", atime.data);
+
+ return !error;
+}
+
+static int test_table_pos(int idx)
+{
+ return test_table(tbl_testdata_pos, idx);
+}
+
+static int test_table_neg(int idx)
+{
+ return test_table(tbl_testdata_neg, idx);
+}
+
+static int test_table_pos_64bit(int idx)
+{
+ return test_table(tbl_testdata_pos_64bit, idx);
+}
+
+static int test_table_neg_64bit(int idx)
+{
+ return test_table(tbl_testdata_neg_64bit, idx);
+}
+
+int setup_tests(void)
+{
+ time_t t = -1;
+ struct tm *ptm = localtime(&t);
+
+ ADD_ALL_TESTS(test_table_pos, OSSL_NELEM(tbl_testdata_pos));
+ if (ptm != NULL) {
+ TEST_info("Adding negative-sign time_t tests");
+ ADD_ALL_TESTS(test_table_neg, OSSL_NELEM(tbl_testdata_neg));
+ }
+ if (sizeof(time_t) > sizeof(uint32_t)) {
+ TEST_info("Adding 64-bit time_t tests");
+ ADD_ALL_TESTS(test_table_pos_64bit, OSSL_NELEM(tbl_testdata_pos_64bit));
+ if (ptm != NULL) {
+ TEST_info("Adding negative-sign 64-bit time_t tests");
+ ADD_ALL_TESTS(test_table_neg_64bit, OSSL_NELEM(tbl_testdata_neg_64bit));
+ }
+ }
+ return 1;
+}