diff options
Diffstat (limited to 'src/lib/libcrypto/x509/x509_vfy.c')
-rw-r--r-- | src/lib/libcrypto/x509/x509_vfy.c | 128 |
1 files changed, 36 insertions, 92 deletions
diff --git a/src/lib/libcrypto/x509/x509_vfy.c b/src/lib/libcrypto/x509/x509_vfy.c index 8d4d15668e..c48143f351 100644 --- a/src/lib/libcrypto/x509/x509_vfy.c +++ b/src/lib/libcrypto/x509/x509_vfy.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: x509_vfy.c,v 1.45 2015/09/14 16:13:39 jsing Exp $ */ | 1 | /* $OpenBSD: x509_vfy.c,v 1.46 2015/10/02 15:04:45 beck Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -1631,106 +1631,50 @@ X509_cmp_current_time(const ASN1_TIME *ctm) | |||
1631 | return X509_cmp_time(ctm, NULL); | 1631 | return X509_cmp_time(ctm, NULL); |
1632 | } | 1632 | } |
1633 | 1633 | ||
1634 | /* | ||
1635 | * Compare a possibly unvalidated ASN1_TIME string against a time_t | ||
1636 | * using RFC 5280 rules for the time string. If *cmp_time is NULL | ||
1637 | * the current system time is used. | ||
1638 | * | ||
1639 | * XXX NOTE that unlike what you expect a "cmp" function to do in C, | ||
1640 | * XXX this one is "special", and returns 0 for error. | ||
1641 | * | ||
1642 | * Returns: | ||
1643 | * -1 if the ASN1_time is earlier than OR the same as *cmp_time. | ||
1644 | * 1 if the ASN1_time is later than *cmp_time. | ||
1645 | * 0 on error. | ||
1646 | */ | ||
1634 | int | 1647 | int |
1635 | X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time) | 1648 | X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time) |
1636 | { | 1649 | { |
1637 | char *str; | 1650 | time_t time1, time2; |
1638 | ASN1_TIME atm; | 1651 | struct tm tm1; |
1639 | long offset; | 1652 | int ret = 0; |
1640 | char buff1[24], buff2[24], *p; | ||
1641 | int i, j; | ||
1642 | 1653 | ||
1643 | p = buff1; | 1654 | if (cmp_time == NULL) |
1644 | i = ctm->length; | 1655 | time2 = time(NULL); |
1645 | str = (char *)ctm->data; | 1656 | else |
1646 | if (ctm->type == V_ASN1_UTCTIME) { | 1657 | time2 = *cmp_time; |
1647 | if ((i < 11) || (i > 17)) | ||
1648 | return 0; | ||
1649 | memcpy(p, str, 10); | ||
1650 | p += 10; | ||
1651 | str += 10; | ||
1652 | i -= 10; | ||
1653 | } else { | ||
1654 | if (i < 13) | ||
1655 | return 0; | ||
1656 | memcpy(p, str, 12); | ||
1657 | p += 12; | ||
1658 | str += 12; | ||
1659 | i -= 12; | ||
1660 | } | ||
1661 | 1658 | ||
1662 | if (i < 1) | 1659 | memset(&tm1, 0, sizeof(tm1)); |
1663 | return 0; | ||
1664 | if ((*str == 'Z') || (*str == '-') || (*str == '+')) { | ||
1665 | *(p++) = '0'; | ||
1666 | *(p++) = '0'; | ||
1667 | } else { | ||
1668 | if (i < 2) | ||
1669 | return 0; | ||
1670 | *(p++) = *(str++); | ||
1671 | *(p++) = *(str++); | ||
1672 | i -= 2; | ||
1673 | if (i < 1) | ||
1674 | return 0; | ||
1675 | /* Skip any fractional seconds... */ | ||
1676 | if (*str == '.') { | ||
1677 | str++; | ||
1678 | i--; | ||
1679 | while (i > 1 && (*str >= '0') && (*str <= '9')) { | ||
1680 | str++; | ||
1681 | i--; | ||
1682 | } | ||
1683 | } | ||
1684 | } | ||
1685 | *(p++) = 'Z'; | ||
1686 | *(p++) = '\0'; | ||
1687 | 1660 | ||
1688 | if (i < 1) | 1661 | if (asn1_time_parse(ctm->data, ctm->length, &tm1, 0) == -1) |
1689 | return 0; | 1662 | goto out; /* invalid time */ |
1690 | if (*str == 'Z') { | ||
1691 | if (i != 1) | ||
1692 | return 0; | ||
1693 | offset = 0; | ||
1694 | } else { | ||
1695 | if (i != 5) | ||
1696 | return 0; | ||
1697 | if ((*str != '+') && (*str != '-')) | ||
1698 | return 0; | ||
1699 | if (str[1] < '0' || str[1] > '9' || | ||
1700 | str[2] < '0' || str[2] > '9' || | ||
1701 | str[3] < '0' || str[3] > '9' || | ||
1702 | str[4] < '0' || str[4] > '9') | ||
1703 | return 0; | ||
1704 | offset = ((str[1] - '0') * 10 + (str[2] - '0')) * 60; | ||
1705 | offset += (str[3] - '0') * 10 + (str[4] - '0'); | ||
1706 | if (*str == '-') | ||
1707 | offset = -offset; | ||
1708 | } | ||
1709 | atm.type = ctm->type; | ||
1710 | atm.flags = 0; | ||
1711 | atm.length = sizeof(buff2); | ||
1712 | atm.data = (unsigned char *)buff2; | ||
1713 | 1663 | ||
1714 | if (X509_time_adj(&atm, offset * 60, cmp_time) == NULL) | 1664 | /* |
1715 | return 0; | 1665 | * Defensively fail if the time string is not representable as |
1666 | * a time_t. A time_t must be sane if you care about times after | ||
1667 | * Jan 19 2038. | ||
1668 | */ | ||
1669 | if ((time1 = timegm(&tm1)) == -1) | ||
1670 | goto out; | ||
1716 | 1671 | ||
1717 | if (ctm->type == V_ASN1_UTCTIME) { | 1672 | if (time1 <= time2) |
1718 | i = (buff1[0] - '0') * 10 + (buff1[1] - '0'); | 1673 | ret = -1; |
1719 | if (i < 50) | ||
1720 | i += 100; /* cf. RFC 2459 */ | ||
1721 | j = (buff2[0] - '0') * 10 + (buff2[1] - '0'); | ||
1722 | if (j < 50) | ||
1723 | j += 100; | ||
1724 | if (i < j) | ||
1725 | return -1; | ||
1726 | if (i > j) | ||
1727 | return 1; | ||
1728 | } | ||
1729 | i = strcmp(buff1, buff2); | ||
1730 | if (i == 0) /* wait a second then return younger :-) */ | ||
1731 | return -1; | ||
1732 | else | 1674 | else |
1733 | return i; | 1675 | ret = 1; |
1676 | out: | ||
1677 | return (ret); | ||
1734 | } | 1678 | } |
1735 | 1679 | ||
1736 | ASN1_TIME * | 1680 | ASN1_TIME * |