From 04e62715db684d83bffac53793ff4cfac51e047a Mon Sep 17 00:00:00 2001 From: Rich Salz Date: Sun, 11 Jun 2017 16:36:07 -0400 Subject: Introduce ASN1_TIME_set_string_X509 API Make funcs to deal with non-null-term'd string in both asn1_generalizedtime_to_tm() and asn1_utctime_to_tm(). Fixes issue #3444. This one is used to enforce strict format (RFC 5280) check and to convert GeneralizedTime to UTCTime. apps/ca has been changed to use the new API. Test cases and documentation are updated/added Signed-off-by: Paul Yang Reviewed-by: Kurt Roeckx Reviewed-by: Rich Salz (Merged from https://github.com/openssl/openssl/pull/3566) --- test/x509_time_test.c | 143 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) (limited to 'test/x509_time_test.c') diff --git a/test/x509_time_test.c b/test/x509_time_test.c index b73e6554b9..6812805847 100644 --- a/test/x509_time_test.c +++ b/test/x509_time_test.c @@ -25,6 +25,99 @@ typedef struct { int expected; } TESTDATA; +typedef struct { + const char *data; + /* 0 for check-only mode, 1 for set-string mode */ + int set_string; + /* 0 for error, 1 if succeed */ + int expected; + /* + * The following 2 fields are ignored if set_string field is set to '0' + * (in check only mode). + * + * But they can still be ignored explicitly in set-string mode by: + * setting -1 to expected_type and setting NULL to expected_string. + * + * It's useful in a case of set-string mode but the expected result + * is a 'parsing error'. + */ + int expected_type; + const char *expected_string; +} TESTDATA_FORMAT; + +/* + * Actually, the "loose" mode has been tested in + * those time-compare-cases, so we may not test it again. + */ +static TESTDATA_FORMAT x509_format_tests[] = { + /* GeneralizedTime */ + { + /* good format, check only */ + "20170217180105Z", 0, 1, -1, NULL, + }, + { + /* SS is missing, check only */ + "201702171801Z", 0, 0, -1, NULL, + }, + { + /* fractional seconds, check only */ + "20170217180105.001Z", 0, 0, -1, NULL, + }, + { + /* time zone, check only */ + "20170217180105+0800", 0, 0, -1, NULL, + }, + { + /* SS is missing, set string */ + "201702171801Z", 1, 0, -1, NULL, + }, + { + /* fractional seconds, set string */ + "20170217180105.001Z", 1, 0, -1, NULL, + }, + { + /* time zone, set string */ + "20170217180105+0800", 1, 0, -1, NULL, + }, + { + /* good format, check returned 'turned' string */ + "20170217180154Z", 1, 1, V_ASN1_UTCTIME, "170217180154Z", + }, + { + /* good format, check returned string */ + "20510217180154Z", 1, 1, V_ASN1_GENERALIZEDTIME, "20510217180154Z", + }, + { + /* good format but out of UTC range, check returned string */ + "19230419180154Z", 1, 1, V_ASN1_GENERALIZEDTIME, "19230419180154Z", + }, + /* UTC */ + { + /* SS is missing, check only */ + "1702171801Z", 0, 0, -1, NULL, + }, + { + /* time zone, check only */ + "170217180154+0800", 0, 0, -1, NULL, + }, + { + /* SS is missing, set string */ + "1702171801Z", 1, 0, -1, NULL, + }, + { + /* time zone, set string */ + "170217180154+0800", 1, 0, -1, NULL, + }, + { + /* 2017, good format, check returned string */ + "170217180154Z", 1, 1, V_ASN1_UTCTIME, "170217180154Z", + }, + { + /* 1998, good format, check returned string */ + "981223180154Z", 1, 1, V_ASN1_UTCTIME, "981223180154Z", + }, +}; + static TESTDATA x509_cmp_tests[] = { { "20170217180154Z", V_ASN1_GENERALIZEDTIME, @@ -153,6 +246,7 @@ static int test_x509_cmp_time(int idx) t.type = x509_cmp_tests[idx].type; t.data = (unsigned char*)(x509_cmp_tests[idx].data); t.length = strlen(x509_cmp_tests[idx].data); + t.flags = 0; result = X509_cmp_time(&t, &x509_cmp_tests[idx].cmp_time); if (!TEST_int_eq(result, x509_cmp_tests[idx].expected)) { @@ -187,8 +281,57 @@ static int test_x509_cmp_time_current() return failed == 0; } +static int test_x509_time(int idx) +{ + ASN1_TIME *t = NULL; + int result, rv = 0; + + if (x509_format_tests[idx].set_string) { + /* set-string mode */ + t = ASN1_TIME_new(); + if (t == NULL) { + TEST_info("test_x509_time(%d) failed: internal error\n", idx); + return 0; + } + } + + result = ASN1_TIME_set_string_X509(t, x509_format_tests[idx].data); + /* time string parsing result is always checked against what's expected */ + if (!TEST_int_eq(result, x509_format_tests[idx].expected)) { + TEST_info("test_x509_time(%d) failed: expected %d, got %d\n", + idx, x509_format_tests[idx].expected, result); + goto out; + } + + /* if t is not NULL but expected_type is ignored(-1), it is an 'OK' case */ + if (t != NULL && x509_format_tests[idx].expected_type != -1) { + if (!TEST_int_eq(t->type, x509_format_tests[idx].expected_type)) { + TEST_info("test_x509_time(%d) failed: expected_type %d, got %d\n", + idx, x509_format_tests[idx].expected_type, t->type); + goto out; + } + } + + /* if t is not NULL but expected_string is NULL, it is an 'OK' case too */ + if (t != NULL && x509_format_tests[idx].expected_string) { + if (!TEST_str_eq((const char *)t->data, + x509_format_tests[idx].expected_string)) { + TEST_info("test_x509_time(%d) failed: expected_string %s, got %s\n", + idx, x509_format_tests[idx].expected_string, t->data); + goto out; + } + } + + rv = 1; +out: + if (t != NULL) + ASN1_TIME_free(t); + return rv; +} + void register_tests() { ADD_TEST(test_x509_cmp_time_current); ADD_ALL_TESTS(test_x509_cmp_time, OSSL_NELEM(x509_cmp_tests)); + ADD_ALL_TESTS(test_x509_time, OSSL_NELEM(x509_format_tests)); } -- cgit v1.2.1