diff options
Diffstat (limited to 'src/usr.bin/openssl/ca.c')
| -rw-r--r-- | src/usr.bin/openssl/ca.c | 101 |
1 files changed, 74 insertions, 27 deletions
diff --git a/src/usr.bin/openssl/ca.c b/src/usr.bin/openssl/ca.c index b644b746b9..a2e8a68368 100644 --- a/src/usr.bin/openssl/ca.c +++ b/src/usr.bin/openssl/ca.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: ca.c,v 1.62 2025/04/14 08:39:27 tb Exp $ */ | 1 | /* $OpenBSD: ca.c,v 1.64 2025/12/21 07:14:47 tb 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 | * |
| @@ -69,6 +69,7 @@ | |||
| 69 | 69 | ||
| 70 | #include "apps.h" | 70 | #include "apps.h" |
| 71 | 71 | ||
| 72 | #include <openssl/asn1.h> | ||
| 72 | #include <openssl/bio.h> | 73 | #include <openssl/bio.h> |
| 73 | #include <openssl/bn.h> | 74 | #include <openssl/bn.h> |
| 74 | #include <openssl/conf.h> | 75 | #include <openssl/conf.h> |
| @@ -1652,6 +1653,54 @@ certify_cert(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509, | |||
| 1652 | } | 1653 | } |
| 1653 | 1654 | ||
| 1654 | static int | 1655 | static int |
| 1656 | is_printablestring_octet(const uint8_t u8) | ||
| 1657 | { | ||
| 1658 | /* | ||
| 1659 | * X.680, 41.4, Table 10 lists the allowed characters in this order. | ||
| 1660 | */ | ||
| 1661 | |||
| 1662 | if (u8 >= 'A' && u8 <= 'Z') | ||
| 1663 | return 1; | ||
| 1664 | if (u8 >= 'a' && u8 <= 'z') | ||
| 1665 | return 1; | ||
| 1666 | if (u8 >= '0' && u8 <= '9') | ||
| 1667 | return 1; | ||
| 1668 | |||
| 1669 | return u8 == ' ' || u8 == '\'' || u8 == '(' || u8 == ')' || u8 == '+' || | ||
| 1670 | u8 == ',' || u8 == '-' || u8 == '.' || u8 == '/' || u8 == ':' || | ||
| 1671 | u8 == '=' || u8 == '?'; | ||
| 1672 | } | ||
| 1673 | |||
| 1674 | /* | ||
| 1675 | * Allows the high bit to be set only for UTF8, BMP and T61 strings, and | ||
| 1676 | * checks that a PrintableString only contains the specified characters. | ||
| 1677 | */ | ||
| 1678 | static int | ||
| 1679 | validate_octets(const ASN1_STRING *astr) | ||
| 1680 | { | ||
| 1681 | const uint8_t *buf = ASN1_STRING_get0_data(astr); | ||
| 1682 | int type = ASN1_STRING_type(astr); | ||
| 1683 | int i; | ||
| 1684 | |||
| 1685 | if (type == V_ASN1_BMPSTRING || type == V_ASN1_UTF8STRING || | ||
| 1686 | type == V_ASN1_T61STRING) | ||
| 1687 | return 1; | ||
| 1688 | |||
| 1689 | for (i = 0; i < ASN1_STRING_length(astr); i++) { | ||
| 1690 | if (is_printablestring_octet(buf[i])) | ||
| 1691 | continue; | ||
| 1692 | |||
| 1693 | if (type == V_ASN1_PRINTABLESTRING) | ||
| 1694 | return 0; | ||
| 1695 | |||
| 1696 | if ((buf[i] & 0x80) != 0) | ||
| 1697 | return 0; | ||
| 1698 | } | ||
| 1699 | |||
| 1700 | return 1; | ||
| 1701 | } | ||
| 1702 | |||
| 1703 | static int | ||
| 1655 | do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst, | 1704 | do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst, |
| 1656 | STACK_OF(OPENSSL_STRING) *sigopts, STACK_OF(CONF_VALUE) *policy, | 1705 | STACK_OF(OPENSSL_STRING) *sigopts, STACK_OF(CONF_VALUE) *policy, |
| 1657 | CA_DB *db, BIGNUM *serial, char *subj, unsigned long chtype, int multirdn, | 1706 | CA_DB *db, BIGNUM *serial, char *subj, unsigned long chtype, int multirdn, |
| @@ -1717,22 +1766,17 @@ do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst, | |||
| 1717 | 1766 | ||
| 1718 | /* check some things */ | 1767 | /* check some things */ |
| 1719 | if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) && | 1768 | if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) && |
| 1720 | (str->type != V_ASN1_IA5STRING)) { | 1769 | (ASN1_STRING_type(str) != V_ASN1_IA5STRING)) { |
| 1721 | BIO_printf(bio_err, | 1770 | BIO_printf(bio_err, |
| 1722 | "\nemailAddress type needs to be of type IA5STRING\n"); | 1771 | "\nemailAddress type needs to be of type IA5STRING\n"); |
| 1723 | goto err; | 1772 | goto err; |
| 1724 | } | 1773 | } |
| 1725 | if ((str->type != V_ASN1_BMPSTRING) && | 1774 | |
| 1726 | (str->type != V_ASN1_UTF8STRING)) { | 1775 | if (!validate_octets(str)) { |
| 1727 | j = ASN1_PRINTABLE_type(str->data, str->length); | 1776 | BIO_printf(bio_err, |
| 1728 | if (((j == V_ASN1_T61STRING) && | 1777 | "\nThe string contains characters that are illegal " |
| 1729 | (str->type != V_ASN1_T61STRING)) || | 1778 | "for the ASN.1 type\n"); |
| 1730 | ((j == V_ASN1_IA5STRING) && | 1779 | goto err; |
| 1731 | (str->type == V_ASN1_PRINTABLESTRING))) { | ||
| 1732 | BIO_printf(bio_err, | ||
| 1733 | "\nThe string contains characters that are illegal for the ASN.1 type\n"); | ||
| 1734 | goto err; | ||
| 1735 | } | ||
| 1736 | } | 1780 | } |
| 1737 | if (default_op) | 1781 | if (default_op) |
| 1738 | old_entry_print(bio_err, obj, str); | 1782 | old_entry_print(bio_err, obj, str); |
| @@ -1830,9 +1874,9 @@ do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst, | |||
| 1830 | BIO_printf(bio_err, | 1874 | BIO_printf(bio_err, |
| 1831 | "The %s field needed to be the same in the\nCA certificate (%s) and the request (%s)\n", | 1875 | "The %s field needed to be the same in the\nCA certificate (%s) and the request (%s)\n", |
| 1832 | cv->name, ((str2 == NULL) ? | 1876 | cv->name, ((str2 == NULL) ? |
| 1833 | "NULL" : (char *) str2->data), | 1877 | "NULL" : (const char *) ASN1_STRING_get0_data(str2)), |
| 1834 | ((str == NULL) ? | 1878 | ((str == NULL) ? |
| 1835 | "NULL" : (char *) str->data)); | 1879 | "NULL" : (const char *) ASN1_STRING_get0_data(str))); |
| 1836 | goto err; | 1880 | goto err; |
| 1837 | } | 1881 | } |
| 1838 | } else { | 1882 | } else { |
| @@ -2153,7 +2197,8 @@ do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst, | |||
| 2153 | 2197 | ||
| 2154 | if ((tm = X509_get_notAfter(ret)) == NULL) | 2198 | if ((tm = X509_get_notAfter(ret)) == NULL) |
| 2155 | goto err; | 2199 | goto err; |
| 2156 | row[DB_exp_date] = strndup(tm->data, tm->length); | 2200 | row[DB_exp_date] = strndup(ASN1_STRING_get0_data(tm), |
| 2201 | ASN1_STRING_length(tm)); | ||
| 2157 | if (row[DB_type] == NULL || row[DB_exp_date] == NULL) { | 2202 | if (row[DB_type] == NULL || row[DB_exp_date] == NULL) { |
| 2158 | BIO_printf(bio_err, "Memory allocation failure\n"); | 2203 | BIO_printf(bio_err, "Memory allocation failure\n"); |
| 2159 | goto err; | 2204 | goto err; |
| @@ -2280,7 +2325,8 @@ do_revoke(X509 *x509, CA_DB *db, int type, char *value) | |||
| 2280 | 2325 | ||
| 2281 | if ((tm = X509_get_notAfter(x509)) == NULL) | 2326 | if ((tm = X509_get_notAfter(x509)) == NULL) |
| 2282 | goto err; | 2327 | goto err; |
| 2283 | row[DB_exp_date] = strndup(tm->data, tm->length); | 2328 | row[DB_exp_date] = strndup(ASN1_STRING_get0_data(tm), |
| 2329 | ASN1_STRING_length(tm)); | ||
| 2284 | if (row[DB_type] == NULL || row[DB_exp_date] == NULL) { | 2330 | if (row[DB_type] == NULL || row[DB_exp_date] == NULL) { |
| 2285 | BIO_printf(bio_err, "Memory allocation failure\n"); | 2331 | BIO_printf(bio_err, "Memory allocation failure\n"); |
| 2286 | goto err; | 2332 | goto err; |
| @@ -2443,7 +2489,7 @@ do_updatedb(CA_DB *db) | |||
| 2443 | cnt = -1; | 2489 | cnt = -1; |
| 2444 | goto err; | 2490 | goto err; |
| 2445 | } | 2491 | } |
| 2446 | a_tm_s = strndup(a_tm->data, a_tm->length); | 2492 | a_tm_s = strndup(ASN1_STRING_get0_data(a_tm), ASN1_STRING_length(a_tm)); |
| 2447 | if (a_tm_s == NULL) { | 2493 | if (a_tm_s == NULL) { |
| 2448 | cnt = -1; | 2494 | cnt = -1; |
| 2449 | goto err; | 2495 | goto err; |
| @@ -2579,7 +2625,7 @@ make_revocation_str(int rev_type, char *rev_arg) | |||
| 2579 | if (revtm == NULL) | 2625 | if (revtm == NULL) |
| 2580 | return NULL; | 2626 | return NULL; |
| 2581 | 2627 | ||
| 2582 | if (asprintf(&str, "%s%s%s%s%s", revtm->data, | 2628 | if (asprintf(&str, "%s%s%s%s%s", ASN1_STRING_get0_data(revtm), |
| 2583 | reason ? "," : "", reason ? reason : "", | 2629 | reason ? "," : "", reason ? reason : "", |
| 2584 | other ? "," : "", other ? other : "") == -1) | 2630 | other ? "," : "", other ? other : "") == -1) |
| 2585 | str = NULL; | 2631 | str = NULL; |
| @@ -2652,7 +2698,8 @@ make_revoked(X509_REVOKED *rev, const char *str) | |||
| 2652 | int | 2698 | int |
| 2653 | old_entry_print(BIO *bp, ASN1_OBJECT *obj, ASN1_STRING *str) | 2699 | old_entry_print(BIO *bp, ASN1_OBJECT *obj, ASN1_STRING *str) |
| 2654 | { | 2700 | { |
| 2655 | char buf[25], *pbuf, *p; | 2701 | const char *p; |
| 2702 | char buf[25], *pbuf; | ||
| 2656 | int j; | 2703 | int j; |
| 2657 | 2704 | ||
| 2658 | j = i2a_ASN1_OBJECT(bp, obj); | 2705 | j = i2a_ASN1_OBJECT(bp, obj); |
| @@ -2663,19 +2710,19 @@ old_entry_print(BIO *bp, ASN1_OBJECT *obj, ASN1_STRING *str) | |||
| 2663 | *(pbuf++) = '\0'; | 2710 | *(pbuf++) = '\0'; |
| 2664 | BIO_puts(bp, buf); | 2711 | BIO_puts(bp, buf); |
| 2665 | 2712 | ||
| 2666 | if (str->type == V_ASN1_PRINTABLESTRING) | 2713 | if (ASN1_STRING_type(str) == V_ASN1_PRINTABLESTRING) |
| 2667 | BIO_printf(bp, "PRINTABLE:'"); | 2714 | BIO_printf(bp, "PRINTABLE:'"); |
| 2668 | else if (str->type == V_ASN1_T61STRING) | 2715 | else if (ASN1_STRING_type(str) == V_ASN1_T61STRING) |
| 2669 | BIO_printf(bp, "T61STRING:'"); | 2716 | BIO_printf(bp, "T61STRING:'"); |
| 2670 | else if (str->type == V_ASN1_IA5STRING) | 2717 | else if (ASN1_STRING_type(str) == V_ASN1_IA5STRING) |
| 2671 | BIO_printf(bp, "IA5STRING:'"); | 2718 | BIO_printf(bp, "IA5STRING:'"); |
| 2672 | else if (str->type == V_ASN1_UNIVERSALSTRING) | 2719 | else if (ASN1_STRING_type(str) == V_ASN1_UNIVERSALSTRING) |
| 2673 | BIO_printf(bp, "UNIVERSALSTRING:'"); | 2720 | BIO_printf(bp, "UNIVERSALSTRING:'"); |
| 2674 | else | 2721 | else |
| 2675 | BIO_printf(bp, "ASN.1 %2d:'", str->type); | 2722 | BIO_printf(bp, "ASN.1 %2d:'", ASN1_STRING_type(str)); |
| 2676 | 2723 | ||
| 2677 | p = (char *) str->data; | 2724 | p = (const char *) ASN1_STRING_get0_data(str); |
| 2678 | for (j = str->length; j > 0; j--) { | 2725 | for (j = ASN1_STRING_length(str); j > 0; j--) { |
| 2679 | if ((*p >= ' ') && (*p <= '~')) | 2726 | if ((*p >= ' ') && (*p <= '~')) |
| 2680 | BIO_printf(bp, "%c", *p); | 2727 | BIO_printf(bp, "%c", *p); |
| 2681 | else if (*p & 0x80) | 2728 | else if (*p & 0x80) |
