summaryrefslogtreecommitdiff
path: root/regress/lib
diff options
context:
space:
mode:
authorTheo Buehler <tb@cvs.openbsd.org>2024-02-18 16:32:30 +0000
committerTheo Buehler <tb@cvs.openbsd.org>2024-02-18 16:32:30 +0000
commit2db14dff622f371559158cfc8b8f780ef4c0481b (patch)
treed35432ddfe90f75a8a9db09d8627eb9e543489c2 /regress/lib
parentb2b920df317cc8a271d18b4429a14bbf4c53db91 (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/Makefile3
-rw-r--r--regress/lib/libcrypto/asn1/asn1time.c196
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(&copy, 0, 0)) {
+ fprintf(stderr, "FAIL: OPENSSL_gmtime_adj by 0 sec didn't "
+ "succeed for maximum time\n");
+ goto err;
+ }
+ if (memcmp(&copy, &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(&copy, 0, 0)) {
+ fprintf(stderr, "FAIL: OPENSSL_gmtime_adj by 0 sec didn't "
+ "succeed for minimum time\n");
+ goto err;
+ }
+ if (memcmp(&copy, &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(&copy, 0, valid_time_range)) {
+ fprintf(stderr, "FAIL: OPENSSL_gmtime_adj by maximum range "
+ "failed\n");
+ goto err;
+ }
+ if (memcmp(&copy, &max_time, sizeof(max_time)) != 0) {
+ fprintf(stderr, "FAIL: maximally adjusted copy didn't match"
+ "max_time\n");
+ goto err;
+ }
+ if (!OPENSSL_gmtime_adj(&copy, 0, -valid_time_range)) {
+ fprintf(stderr, "FAIL: OPENSSL_gmtime_adj by maximum range "
+ "failed\n");
+ goto err;
+ }
+ if (memcmp(&copy, &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(&copy, -1, valid_time_range + 24 * 3600)) {
+ fprintf(stderr, "FAIL: OPENSSL_gmtime_adj by maximum range "
+ "failed\n");
+ goto err;
+ }
+ if (memcmp(&copy, &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(&copy, 1, -valid_time_range - 24 * 3600)) {
+ fprintf(stderr, "FAIL: OPENSSL_gmtime_adj by maximum range "
+ "failed\n");
+ goto err;
+ }
+ if (memcmp(&copy, &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(&copy, 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(&copy, 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);
}