diff options
| author | tb <> | 2024-02-18 16:32:29 +0000 |
|---|---|---|
| committer | tb <> | 2024-02-18 16:32:29 +0000 |
| commit | 4be46aff4053b553813a657c12a4aba90dcf4eed (patch) | |
| tree | 35b0cdf8d8e976f274d7b54df553c369c2d889eb /src | |
| parent | e6f7b0b1226a54f33775814024ebcb3dc28a6c32 (diff) | |
| download | openbsd-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.
Diffstat (limited to '')
| -rw-r--r-- | src/regress/lib/libcrypto/asn1/Makefile | 3 | ||||
| -rw-r--r-- | src/regress/lib/libcrypto/asn1/asn1time.c | 196 |
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 | ||
| 3 | PROGS = \ | 3 | PROGS = \ |
| 4 | asn1api \ | 4 | asn1api \ |
| @@ -24,5 +24,6 @@ CFLAGS+= -I${.CURDIR}/../../../../lib/libcrypto/bytestring | |||
| 24 | 24 | ||
| 25 | LDADD_asn1basic = ${CRYPTO_INT} | 25 | LDADD_asn1basic = ${CRYPTO_INT} |
| 26 | LDADD_asn1object = ${CRYPTO_INT} | 26 | LDADD_asn1object = ${CRYPTO_INT} |
| 27 | LDADD_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 | |||
| 24 | int ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t); | 29 | int ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t); |
| 25 | 30 | ||
| 26 | struct asn1_time_test { | 31 | struct asn1_time_test { |
| @@ -567,6 +572,192 @@ asn1_time_compare_test(void) | |||
| 567 | return failed; | 572 | return failed; |
| 568 | } | 573 | } |
| 569 | 574 | ||
| 575 | static int | ||
| 576 | asn1_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(©, 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(©, &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(©, 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(©, &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(©, 0, valid_time_range)) { | ||
| 684 | fprintf(stderr, "FAIL: OPENSSL_gmtime_adj by maximum range " | ||
| 685 | "failed\n"); | ||
| 686 | goto err; | ||
| 687 | } | ||
| 688 | if (memcmp(©, &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(©, 0, -valid_time_range)) { | ||
| 694 | fprintf(stderr, "FAIL: OPENSSL_gmtime_adj by maximum range " | ||
| 695 | "failed\n"); | ||
| 696 | goto err; | ||
| 697 | } | ||
| 698 | if (memcmp(©, &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(©, -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(©, &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(©, 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(©, &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(©, 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(©, 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 | |||
| 570 | int | 761 | int |
| 571 | main(int argc, char **argv) | 762 | main(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 | } |
