summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortb <>2024-02-18 16:32:29 +0000
committertb <>2024-02-18 16:32:29 +0000
commit4be46aff4053b553813a657c12a4aba90dcf4eed (patch)
tree35b0cdf8d8e976f274d7b54df553c369c2d889eb
parente6f7b0b1226a54f33775814024ebcb3dc28a6c32 (diff)
downloadopenbsd-4be46aff4053b553813a657c12a4aba90dcf4eed.tar.gz
openbsd-4be46aff4053b553813a657c12a4aba90dcf4eed.tar.bz2
openbsd-4be46aff4053b553813a657c12a4aba90dcf4eed.zip
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.
-rw-r--r--src/regress/lib/libcrypto/asn1/Makefile3
-rw-r--r--src/regress/lib/libcrypto/asn1/asn1time.c196
2 files changed, 197 insertions, 2 deletions
diff --git a/src/regress/lib/libcrypto/asn1/Makefile b/src/regress/lib/libcrypto/asn1/Makefile
index 173a51f442..16a84c19bb 100644
--- a/src/regress/lib/libcrypto/asn1/Makefile
+++ b/src/regress/lib/libcrypto/asn1/Makefile
@@ -1,4 +1,4 @@
1# $OpenBSD: Makefile,v 1.26 2023/12/15 22:24:15 tb Exp $ 1# $OpenBSD: Makefile,v 1.27 2024/02/18 16:32:29 tb Exp $
2 2
3PROGS = \ 3PROGS = \
4 asn1api \ 4 asn1api \
@@ -24,5 +24,6 @@ CFLAGS+= -I${.CURDIR}/../../../../lib/libcrypto/bytestring
24 24
25LDADD_asn1basic = ${CRYPTO_INT} 25LDADD_asn1basic = ${CRYPTO_INT}
26LDADD_asn1object = ${CRYPTO_INT} 26LDADD_asn1object = ${CRYPTO_INT}
27LDADD_asn1time = ${CRYPTO_INT}
27 28
28.include <bsd.regress.mk> 29.include <bsd.regress.mk>
diff --git a/src/regress/lib/libcrypto/asn1/asn1time.c b/src/regress/lib/libcrypto/asn1/asn1time.c
index 10533d62e9..b3418c4616 100644
--- a/src/regress/lib/libcrypto/asn1/asn1time.c
+++ b/src/regress/lib/libcrypto/asn1/asn1time.c
@@ -1,6 +1,7 @@
1/* $OpenBSD: asn1time.c,v 1.21 2023/10/05 07:59:41 tb Exp $ */ 1/* $OpenBSD: asn1time.c,v 1.22 2024/02/18 16:32:29 tb Exp $ */
2/* 2/*
3 * Copyright (c) 2015 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2015 Joel Sing <jsing@openbsd.org>
4 * Copyright (c) 2024 Google Inc.
4 * 5 *
5 * Permission to use, copy, modify, and distribute this software for any 6 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above 7 * purpose with or without fee is hereby granted, provided that the above
@@ -16,11 +17,15 @@
16 */ 17 */
17 18
18#include <openssl/asn1.h> 19#include <openssl/asn1.h>
20#include <openssl/posix_time.h>
19 21
20#include <err.h> 22#include <err.h>
23#include <limits.h>
21#include <stdio.h> 24#include <stdio.h>
22#include <string.h> 25#include <string.h>
23 26
27#include "asn1_local.h"
28
24int ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t); 29int ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t);
25 30
26struct asn1_time_test { 31struct asn1_time_test {
@@ -567,6 +572,192 @@ asn1_time_compare_test(void)
567 return failed; 572 return failed;
568} 573}
569 574
575static int
576asn1_time_overflow(void)
577{
578 struct tm overflow_year = {0}, overflow_month = {0};
579 struct tm copy, max_time = {0}, min_time = {0};
580 int64_t valid_time_range = INT64_C(315569519999);
581 int64_t posix_u64;
582 time_t posix_time;
583 int days, secs;
584 int failed = 1;
585
586 overflow_year.tm_year = INT_MAX - 1899;
587 overflow_year.tm_mday = 1;
588
589 overflow_month.tm_mon = INT_MAX;
590 overflow_month.tm_mday = 1;
591
592 if (OPENSSL_tm_to_posix(&overflow_year, &posix_u64)) {
593 fprintf(stderr, "FAIL: OPENSSL_tm_to_posix didn't fail on "
594 "overflow of years\n");
595 goto err;
596 }
597 if (OPENSSL_tm_to_posix(&overflow_month, &posix_u64)) {
598 fprintf(stderr, "FAIL: OPENSSL_tm_to_posix didn't fail on "
599 "overflow of months\n");
600 goto err;
601 }
602 if (OPENSSL_timegm(&overflow_year, &posix_time)) {
603 fprintf(stderr, "FAIL: OPENSSL_timegm didn't fail on "
604 "overflow of years\n");
605 goto err;
606 }
607 if (OPENSSL_timegm(&overflow_month, &posix_time)) {
608 fprintf(stderr, "FAIL: OPENSSL_timegm didn't fail on "
609 "overflow of months\n");
610 goto err;
611 }
612 if (OPENSSL_gmtime_adj(&overflow_year, 0, 0)) {
613 fprintf(stderr, "FAIL: OPENSSL_gmtime_adj didn't fail on "
614 "overflow of years\n");
615 goto err;
616 }
617 if (OPENSSL_gmtime_adj(&overflow_month, 0, 0)) {
618 fprintf(stderr, "FAIL: OPENSSL_gmtime_adj didn't fail on "
619 "overflow of months\n");
620 goto err;
621 }
622 if (OPENSSL_gmtime_diff(&days, &secs, &overflow_year, &overflow_year)) {
623 fprintf(stderr, "FAIL: OPENSSL_gmtime_diff didn't fail on "
624 "overflow of years\n");
625 goto err;
626 }
627 if (OPENSSL_gmtime_diff(&days, &secs, &overflow_month, &overflow_month)) {
628 fprintf(stderr, "FAIL: OPENSSL_gmtime_diff didn't fail on "
629 "overflow of months\n");
630 goto err;
631 }
632
633 /* Input time is in range but adding one second puts it out of range. */
634 max_time.tm_year = 9999 - 1900;
635 max_time.tm_mon = 12 - 1;
636 max_time.tm_mday = 31;
637 max_time.tm_hour = 23;
638 max_time.tm_min = 59;
639 max_time.tm_sec = 59;
640
641 copy = max_time;
642 if (!OPENSSL_gmtime_adj(&copy, 0, 0)) {
643 fprintf(stderr, "FAIL: OPENSSL_gmtime_adj by 0 sec didn't "
644 "succeed for maximum time\n");
645 goto err;
646 }
647 if (memcmp(&copy, &max_time, sizeof(max_time)) != 0) {
648 fprintf(stderr, "FAIL: OPENSSL_gmtime_adj by 0 sec didn't "
649 "leave copy of max_time unmodified\n");
650 goto err;
651 }
652 if (OPENSSL_gmtime_adj(&max_time, 0, 1)) {
653 fprintf(stderr, "FAIL: OPENSSL_gmtime_adj by 1 sec didn't "
654 "fail for maximum time\n");
655 goto err;
656 }
657
658 min_time.tm_year = 0 - 1900;
659 min_time.tm_mon = 1 - 1;
660 min_time.tm_mday = 1;
661 min_time.tm_hour = 0;
662 min_time.tm_min = 0;
663 min_time.tm_sec = 0;
664
665 copy = min_time;
666 if (!OPENSSL_gmtime_adj(&copy, 0, 0)) {
667 fprintf(stderr, "FAIL: OPENSSL_gmtime_adj by 0 sec didn't "
668 "succeed for minimum time\n");
669 goto err;
670 }
671 if (memcmp(&copy, &min_time, sizeof(min_time)) != 0) {
672 fprintf(stderr, "FAIL: OPENSSL_gmtime_adj by 0 sec didn't "
673 "leave copy of min_time unmodified\n");
674 goto err;
675 }
676 if (OPENSSL_gmtime_adj(&min_time, 0, -1)) {
677 fprintf(stderr, "FAIL: OPENSSL_gmtime_adj by 1 sec didn't "
678 "fail for minimum time\n");
679 goto err;
680 }
681
682 /* Test that we can offset by the valid minimum and maximum times. */
683 if (!OPENSSL_gmtime_adj(&copy, 0, valid_time_range)) {
684 fprintf(stderr, "FAIL: OPENSSL_gmtime_adj by maximum range "
685 "failed\n");
686 goto err;
687 }
688 if (memcmp(&copy, &max_time, sizeof(max_time)) != 0) {
689 fprintf(stderr, "FAIL: maximally adjusted copy didn't match"
690 "max_time\n");
691 goto err;
692 }
693 if (!OPENSSL_gmtime_adj(&copy, 0, -valid_time_range)) {
694 fprintf(stderr, "FAIL: OPENSSL_gmtime_adj by maximum range "
695 "failed\n");
696 goto err;
697 }
698 if (memcmp(&copy, &min_time, sizeof(min_time)) != 0) {
699 fprintf(stderr, "FAIL: maximally adjusted copy didn't match"
700 "min_time\n");
701 goto err;
702 }
703
704 /*
705 * The second offset may even exceed the valid_time_range if it is
706 * cancelled out by offset_day.
707 */
708 if (!OPENSSL_gmtime_adj(&copy, -1, valid_time_range + 24 * 3600)) {
709 fprintf(stderr, "FAIL: OPENSSL_gmtime_adj by maximum range "
710 "failed\n");
711 goto err;
712 }
713 if (memcmp(&copy, &max_time, sizeof(max_time)) != 0) {
714 fprintf(stderr, "FAIL: excess maximally adjusted copy didn't "
715 "match max_time\n");
716 goto err;
717 }
718 if (!OPENSSL_gmtime_adj(&copy, 1, -valid_time_range - 24 * 3600)) {
719 fprintf(stderr, "FAIL: OPENSSL_gmtime_adj by maximum range "
720 "failed\n");
721 goto err;
722 }
723 if (memcmp(&copy, &min_time, sizeof(min_time)) != 0) {
724 fprintf(stderr, "FAIL: excess maximally adjusted copy didn't "
725 "match min_time\n");
726 goto err;
727 }
728
729 copy = max_time;
730 if (OPENSSL_gmtime_adj(&copy, INT_MAX, INT64_MAX)) {
731 fprintf(stderr, "FAIL: maximal adjustments in OPENSSL_gmtime_adj"
732 "didn't fail\n");
733 goto err;
734 }
735 copy = min_time;
736 if (OPENSSL_gmtime_adj(&copy, INT_MIN, INT64_MIN)) {
737 fprintf(stderr, "FAIL: minimal adjustments in OPENSSL_gmtime_adj"
738 "didn't fail\n");
739 goto err;
740 }
741
742 /* Test we can diff between maximum time and minimum time. */
743 if (!OPENSSL_gmtime_diff(&days, &secs, &max_time, &min_time)) {
744 fprintf(stderr, "FAIL: OPENSSL_gmtime_diff between maximum and "
745 "minimum time failed\n");
746 goto err;
747 }
748 if (!OPENSSL_gmtime_diff(&days, &secs, &min_time, &max_time)) {
749 fprintf(stderr, "FAIL: OPENSSL_gmtime_diff between minimum and "
750 "maximum time failed\n");
751 goto err;
752 }
753
754
755 failed = 0;
756
757 err:
758 return failed;
759}
760
570int 761int
571main(int argc, char **argv) 762main(int argc, char **argv)
572{ 763{
@@ -614,5 +805,8 @@ main(int argc, char **argv)
614 /* Check for a leak in ASN1_TIME_normalize(). */ 805 /* Check for a leak in ASN1_TIME_normalize(). */
615 failed |= ASN1_TIME_normalize(NULL) != 0; 806 failed |= ASN1_TIME_normalize(NULL) != 0;
616 807
808 fprintf(stderr, "Time overflow tests...\n");
809 failed |= asn1_time_overflow();
810
617 return (failed); 811 return (failed);
618} 812}