diff options
author | Theo Buehler <tb@cvs.openbsd.org> | 2024-02-18 16:32:30 +0000 |
---|---|---|
committer | Theo Buehler <tb@cvs.openbsd.org> | 2024-02-18 16:32:30 +0000 |
commit | 2db14dff622f371559158cfc8b8f780ef4c0481b (patch) | |
tree | d35432ddfe90f75a8a9db09d8627eb9e543489c2 /regress/lib | |
parent | b2b920df317cc8a271d18b4429a14bbf4c53db91 (diff) |
Add regress coverage for the new API
This exercises the new API, in particular with respect to overflow behavior
around the years 0/9999, which are special for GeneralizedTime/X.509.
Diffstat (limited to 'regress/lib')
-rw-r--r-- | regress/lib/libcrypto/asn1/Makefile | 3 | ||||
-rw-r--r-- | regress/lib/libcrypto/asn1/asn1time.c | 196 |
2 files changed, 197 insertions, 2 deletions
diff --git a/regress/lib/libcrypto/asn1/Makefile b/regress/lib/libcrypto/asn1/Makefile index 173a51f4423..16a84c19bb8 100644 --- a/regress/lib/libcrypto/asn1/Makefile +++ b/regress/lib/libcrypto/asn1/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.26 2023/12/15 22:24:15 tb Exp $ +# $OpenBSD: Makefile,v 1.27 2024/02/18 16:32:29 tb Exp $ PROGS = \ asn1api \ @@ -24,5 +24,6 @@ CFLAGS+= -I${.CURDIR}/../../../../lib/libcrypto/bytestring LDADD_asn1basic = ${CRYPTO_INT} LDADD_asn1object = ${CRYPTO_INT} +LDADD_asn1time = ${CRYPTO_INT} .include <bsd.regress.mk> diff --git a/regress/lib/libcrypto/asn1/asn1time.c b/regress/lib/libcrypto/asn1/asn1time.c index 10533d62e9b..b3418c46165 100644 --- a/regress/lib/libcrypto/asn1/asn1time.c +++ b/regress/lib/libcrypto/asn1/asn1time.c @@ -1,6 +1,7 @@ -/* $OpenBSD: asn1time.c,v 1.21 2023/10/05 07:59:41 tb Exp $ */ +/* $OpenBSD: asn1time.c,v 1.22 2024/02/18 16:32:29 tb Exp $ */ /* * Copyright (c) 2015 Joel Sing <jsing@openbsd.org> + * Copyright (c) 2024 Google Inc. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -16,11 +17,15 @@ */ #include <openssl/asn1.h> +#include <openssl/posix_time.h> #include <err.h> +#include <limits.h> #include <stdio.h> #include <string.h> +#include "asn1_local.h" + int ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t); struct asn1_time_test { @@ -567,6 +572,192 @@ asn1_time_compare_test(void) return failed; } +static int +asn1_time_overflow(void) +{ + struct tm overflow_year = {0}, overflow_month = {0}; + struct tm copy, max_time = {0}, min_time = {0}; + int64_t valid_time_range = INT64_C(315569519999); + int64_t posix_u64; + time_t posix_time; + int days, secs; + int failed = 1; + + overflow_year.tm_year = INT_MAX - 1899; + overflow_year.tm_mday = 1; + + overflow_month.tm_mon = INT_MAX; + overflow_month.tm_mday = 1; + + if (OPENSSL_tm_to_posix(&overflow_year, &posix_u64)) { + fprintf(stderr, "FAIL: OPENSSL_tm_to_posix didn't fail on " + "overflow of years\n"); + goto err; + } + if (OPENSSL_tm_to_posix(&overflow_month, &posix_u64)) { + fprintf(stderr, "FAIL: OPENSSL_tm_to_posix didn't fail on " + "overflow of months\n"); + goto err; + } + if (OPENSSL_timegm(&overflow_year, &posix_time)) { + fprintf(stderr, "FAIL: OPENSSL_timegm didn't fail on " + "overflow of years\n"); + goto err; + } + if (OPENSSL_timegm(&overflow_month, &posix_time)) { + fprintf(stderr, "FAIL: OPENSSL_timegm didn't fail on " + "overflow of months\n"); + goto err; + } + if (OPENSSL_gmtime_adj(&overflow_year, 0, 0)) { + fprintf(stderr, "FAIL: OPENSSL_gmtime_adj didn't fail on " + "overflow of years\n"); + goto err; + } + if (OPENSSL_gmtime_adj(&overflow_month, 0, 0)) { + fprintf(stderr, "FAIL: OPENSSL_gmtime_adj didn't fail on " + "overflow of months\n"); + goto err; + } + if (OPENSSL_gmtime_diff(&days, &secs, &overflow_year, &overflow_year)) { + fprintf(stderr, "FAIL: OPENSSL_gmtime_diff didn't fail on " + "overflow of years\n"); + goto err; + } + if (OPENSSL_gmtime_diff(&days, &secs, &overflow_month, &overflow_month)) { + fprintf(stderr, "FAIL: OPENSSL_gmtime_diff didn't fail on " + "overflow of months\n"); + goto err; + } + + /* Input time is in range but adding one second puts it out of range. */ + max_time.tm_year = 9999 - 1900; + max_time.tm_mon = 12 - 1; + max_time.tm_mday = 31; + max_time.tm_hour = 23; + max_time.tm_min = 59; + max_time.tm_sec = 59; + + copy = max_time; + if (!OPENSSL_gmtime_adj(©, 0, 0)) { + fprintf(stderr, "FAIL: OPENSSL_gmtime_adj by 0 sec didn't " + "succeed for maximum time\n"); + goto err; + } + if (memcmp(©, &max_time, sizeof(max_time)) != 0) { + fprintf(stderr, "FAIL: OPENSSL_gmtime_adj by 0 sec didn't " + "leave copy of max_time unmodified\n"); + goto err; + } + if (OPENSSL_gmtime_adj(&max_time, 0, 1)) { + fprintf(stderr, "FAIL: OPENSSL_gmtime_adj by 1 sec didn't " + "fail for maximum time\n"); + goto err; + } + + min_time.tm_year = 0 - 1900; + min_time.tm_mon = 1 - 1; + min_time.tm_mday = 1; + min_time.tm_hour = 0; + min_time.tm_min = 0; + min_time.tm_sec = 0; + + copy = min_time; + if (!OPENSSL_gmtime_adj(©, 0, 0)) { + fprintf(stderr, "FAIL: OPENSSL_gmtime_adj by 0 sec didn't " + "succeed for minimum time\n"); + goto err; + } + if (memcmp(©, &min_time, sizeof(min_time)) != 0) { + fprintf(stderr, "FAIL: OPENSSL_gmtime_adj by 0 sec didn't " + "leave copy of min_time unmodified\n"); + goto err; + } + if (OPENSSL_gmtime_adj(&min_time, 0, -1)) { + fprintf(stderr, "FAIL: OPENSSL_gmtime_adj by 1 sec didn't " + "fail for minimum time\n"); + goto err; + } + + /* Test that we can offset by the valid minimum and maximum times. */ + if (!OPENSSL_gmtime_adj(©, 0, valid_time_range)) { + fprintf(stderr, "FAIL: OPENSSL_gmtime_adj by maximum range " + "failed\n"); + goto err; + } + if (memcmp(©, &max_time, sizeof(max_time)) != 0) { + fprintf(stderr, "FAIL: maximally adjusted copy didn't match" + "max_time\n"); + goto err; + } + if (!OPENSSL_gmtime_adj(©, 0, -valid_time_range)) { + fprintf(stderr, "FAIL: OPENSSL_gmtime_adj by maximum range " + "failed\n"); + goto err; + } + if (memcmp(©, &min_time, sizeof(min_time)) != 0) { + fprintf(stderr, "FAIL: maximally adjusted copy didn't match" + "min_time\n"); + goto err; + } + + /* + * The second offset may even exceed the valid_time_range if it is + * cancelled out by offset_day. + */ + if (!OPENSSL_gmtime_adj(©, -1, valid_time_range + 24 * 3600)) { + fprintf(stderr, "FAIL: OPENSSL_gmtime_adj by maximum range " + "failed\n"); + goto err; + } + if (memcmp(©, &max_time, sizeof(max_time)) != 0) { + fprintf(stderr, "FAIL: excess maximally adjusted copy didn't " + "match max_time\n"); + goto err; + } + if (!OPENSSL_gmtime_adj(©, 1, -valid_time_range - 24 * 3600)) { + fprintf(stderr, "FAIL: OPENSSL_gmtime_adj by maximum range " + "failed\n"); + goto err; + } + if (memcmp(©, &min_time, sizeof(min_time)) != 0) { + fprintf(stderr, "FAIL: excess maximally adjusted copy didn't " + "match min_time\n"); + goto err; + } + + copy = max_time; + if (OPENSSL_gmtime_adj(©, INT_MAX, INT64_MAX)) { + fprintf(stderr, "FAIL: maximal adjustments in OPENSSL_gmtime_adj" + "didn't fail\n"); + goto err; + } + copy = min_time; + if (OPENSSL_gmtime_adj(©, INT_MIN, INT64_MIN)) { + fprintf(stderr, "FAIL: minimal adjustments in OPENSSL_gmtime_adj" + "didn't fail\n"); + goto err; + } + + /* Test we can diff between maximum time and minimum time. */ + if (!OPENSSL_gmtime_diff(&days, &secs, &max_time, &min_time)) { + fprintf(stderr, "FAIL: OPENSSL_gmtime_diff between maximum and " + "minimum time failed\n"); + goto err; + } + if (!OPENSSL_gmtime_diff(&days, &secs, &min_time, &max_time)) { + fprintf(stderr, "FAIL: OPENSSL_gmtime_diff between minimum and " + "maximum time failed\n"); + goto err; + } + + + failed = 0; + + err: + return failed; +} + int main(int argc, char **argv) { @@ -614,5 +805,8 @@ main(int argc, char **argv) /* Check for a leak in ASN1_TIME_normalize(). */ failed |= ASN1_TIME_normalize(NULL) != 0; + fprintf(stderr, "Time overflow tests...\n"); + failed |= asn1_time_overflow(); + return (failed); } |