diff options
author | tb <> | 2024-12-04 08:14:34 +0000 |
---|---|---|
committer | tb <> | 2024-12-04 08:14:34 +0000 |
commit | f14751780c164cac61e6f6763b1d8b4e8259080a (patch) | |
tree | c212ffd82d55194566861676aab463e3ff3a3af5 /src | |
parent | de658ff5e766edba762492289b6ff694e38322c5 (diff) | |
download | openbsd-f14751780c164cac61e6f6763b1d8b4e8259080a.tar.gz openbsd-f14751780c164cac61e6f6763b1d8b4e8259080a.tar.bz2 openbsd-f14751780c164cac61e6f6763b1d8b4e8259080a.zip |
Fix up authority and subject key identifiers in force pubkey mode
Upstream decided that this nonsense was worth an ABI break and added stuff
to the X509_CTX so they could hang the issuer's public key off it so that
they could adjust the key identifiers as needed. Let's avoid that and do
it the slightly less nasty way by updating the AKI and SKI as needed.
We only do this when force pubkey is in place so we don't change the
semantics of the batshit crazy config language that nobody understands.
ok job
Diffstat (limited to 'src')
-rw-r--r-- | src/usr.bin/openssl/x509.c | 141 |
1 files changed, 133 insertions, 8 deletions
diff --git a/src/usr.bin/openssl/x509.c b/src/usr.bin/openssl/x509.c index 1ebdfb005f..fc8a0daeb3 100644 --- a/src/usr.bin/openssl/x509.c +++ b/src/usr.bin/openssl/x509.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: x509.c,v 1.39 2024/05/27 16:12:55 tb Exp $ */ | 1 | /* $OpenBSD: x509.c,v 1.40 2024/12/04 08:14:34 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 | * |
@@ -1595,7 +1595,119 @@ callb(int ok, X509_STORE_CTX *ctx) | |||
1595 | } | 1595 | } |
1596 | } | 1596 | } |
1597 | 1597 | ||
1598 | /* self sign */ | 1598 | static int |
1599 | key_identifier_hash(EVP_PKEY *pkey, unsigned char *md, unsigned int *md_len) | ||
1600 | { | ||
1601 | X509_PUBKEY *x509_pubkey = NULL; | ||
1602 | const unsigned char *der; | ||
1603 | int der_len; | ||
1604 | int ret = 0; | ||
1605 | |||
1606 | if (*md_len < SHA_DIGEST_LENGTH) | ||
1607 | goto err; | ||
1608 | |||
1609 | if (!X509_PUBKEY_set(&x509_pubkey, pkey)) | ||
1610 | goto err; | ||
1611 | if (!X509_PUBKEY_get0_param(NULL, &der, &der_len, NULL, x509_pubkey)) | ||
1612 | goto err; | ||
1613 | if (!EVP_Digest(der, der_len, md, md_len, EVP_sha1(), NULL)) | ||
1614 | goto err; | ||
1615 | |||
1616 | ret = 1; | ||
1617 | |||
1618 | err: | ||
1619 | X509_PUBKEY_free(x509_pubkey); | ||
1620 | |||
1621 | return ret; | ||
1622 | } | ||
1623 | |||
1624 | static ASN1_OCTET_STRING * | ||
1625 | compute_key_identifier(EVP_PKEY *pkey) | ||
1626 | { | ||
1627 | ASN1_OCTET_STRING *ki = NULL; | ||
1628 | unsigned char md[EVP_MAX_MD_SIZE]; | ||
1629 | unsigned int md_len = EVP_MAX_MD_SIZE; | ||
1630 | |||
1631 | if (!key_identifier_hash(pkey, md, &md_len)) | ||
1632 | goto err; | ||
1633 | |||
1634 | if ((ki = ASN1_OCTET_STRING_new()) == NULL) | ||
1635 | goto err; | ||
1636 | if (!ASN1_STRING_set(ki, md, md_len)) | ||
1637 | goto err; | ||
1638 | |||
1639 | return ki; | ||
1640 | |||
1641 | err: | ||
1642 | ASN1_OCTET_STRING_free(ki); | ||
1643 | |||
1644 | return NULL; | ||
1645 | } | ||
1646 | |||
1647 | static ASN1_OCTET_STRING * | ||
1648 | compute_subject_key_identifier(EVP_PKEY *subject_key) | ||
1649 | { | ||
1650 | return compute_key_identifier(subject_key); | ||
1651 | } | ||
1652 | |||
1653 | static AUTHORITY_KEYID * | ||
1654 | compute_authority_key_identifier(EVP_PKEY *issuer_key) | ||
1655 | { | ||
1656 | AUTHORITY_KEYID *aki = NULL; | ||
1657 | |||
1658 | if ((aki = AUTHORITY_KEYID_new()) == NULL) | ||
1659 | goto err; | ||
1660 | if ((aki->keyid = compute_key_identifier(issuer_key)) == NULL) | ||
1661 | goto err; | ||
1662 | |||
1663 | return aki; | ||
1664 | |||
1665 | err: | ||
1666 | AUTHORITY_KEYID_free(aki); | ||
1667 | |||
1668 | return NULL; | ||
1669 | } | ||
1670 | |||
1671 | static int | ||
1672 | set_key_identifiers(X509 *cert, EVP_PKEY *issuer_key) | ||
1673 | { | ||
1674 | EVP_PKEY *subject_key; | ||
1675 | ASN1_OCTET_STRING *ski = NULL; | ||
1676 | AUTHORITY_KEYID *aki = NULL; | ||
1677 | int ret = 0; | ||
1678 | |||
1679 | if ((subject_key = X509_get0_pubkey(cert)) == NULL) | ||
1680 | goto err; | ||
1681 | |||
1682 | if ((ski = compute_subject_key_identifier(subject_key)) == NULL) | ||
1683 | goto err; | ||
1684 | if (!X509_add1_ext_i2d(cert, NID_subject_key_identifier, ski, 0, | ||
1685 | X509V3_ADD_REPLACE)) | ||
1686 | goto err; | ||
1687 | |||
1688 | /* | ||
1689 | * Historical OpenSSL behavior: don't set AKI if we're self-signing. | ||
1690 | * RFC 5280 says we MAY omit it, so this is ok. | ||
1691 | */ | ||
1692 | if (EVP_PKEY_cmp(subject_key, issuer_key) == 1) | ||
1693 | goto done; | ||
1694 | |||
1695 | if ((aki = compute_authority_key_identifier(issuer_key)) == NULL) | ||
1696 | goto err; | ||
1697 | if (!X509_add1_ext_i2d(cert, NID_authority_key_identifier, aki, 0, | ||
1698 | X509V3_ADD_REPLACE)) | ||
1699 | goto err; | ||
1700 | |||
1701 | done: | ||
1702 | ret = 1; | ||
1703 | |||
1704 | err: | ||
1705 | ASN1_OCTET_STRING_free(ski); | ||
1706 | AUTHORITY_KEYID_free(aki); | ||
1707 | |||
1708 | return ret; | ||
1709 | } | ||
1710 | |||
1599 | static int | 1711 | static int |
1600 | sign(X509 *x, EVP_PKEY *pkey, int days, int clrext, const EVP_MD *digest, | 1712 | sign(X509 *x, EVP_PKEY *pkey, int days, int clrext, const EVP_MD *digest, |
1601 | CONF *conf, char *section, X509_NAME *issuer, char *force_pubkey) | 1713 | CONF *conf, char *section, X509_NAME *issuer, char *force_pubkey) |
@@ -1617,12 +1729,7 @@ sign(X509 *x, EVP_PKEY *pkey, int days, int clrext, const EVP_MD *digest, | |||
1617 | if (X509_gmtime_adj(X509_get_notBefore(x), 0) == NULL) | 1729 | if (X509_gmtime_adj(X509_get_notBefore(x), 0) == NULL) |
1618 | goto err; | 1730 | goto err; |
1619 | 1731 | ||
1620 | /* Lets just make it 12:00am GMT, Jan 1 1970 */ | 1732 | if (X509_gmtime_adj(X509_get_notAfter(x), 60L * 60 * 24 * days) == NULL) |
1621 | /* memcpy(x->cert_info->validity->notBefore,"700101120000Z",13); */ | ||
1622 | /* 28 days to be certified */ | ||
1623 | |||
1624 | if (X509_gmtime_adj(X509_get_notAfter(x), | ||
1625 | (long) 60 * 60 * 24 * days) == NULL) | ||
1626 | goto err; | 1733 | goto err; |
1627 | 1734 | ||
1628 | if (force_pubkey == NULL) { | 1735 | if (force_pubkey == NULL) { |
@@ -1637,12 +1744,30 @@ sign(X509 *x, EVP_PKEY *pkey, int days, int clrext, const EVP_MD *digest, | |||
1637 | } | 1744 | } |
1638 | if (conf != NULL) { | 1745 | if (conf != NULL) { |
1639 | X509V3_CTX ctx; | 1746 | X509V3_CTX ctx; |
1747 | |||
1640 | if (!X509_set_version(x, 2)) /* version 3 certificate */ | 1748 | if (!X509_set_version(x, 2)) /* version 3 certificate */ |
1641 | goto err; | 1749 | goto err; |
1642 | X509V3_set_ctx(&ctx, x, x, NULL, NULL, 0); | 1750 | X509V3_set_ctx(&ctx, x, x, NULL, NULL, 0); |
1643 | X509V3_set_nconf(&ctx, conf); | 1751 | X509V3_set_nconf(&ctx, conf); |
1644 | if (!X509V3_EXT_add_nconf(conf, &ctx, section, x)) | 1752 | if (!X509V3_EXT_add_nconf(conf, &ctx, section, x)) |
1645 | goto err; | 1753 | goto err; |
1754 | if (force_pubkey != NULL) { | ||
1755 | /* | ||
1756 | * Set or fix up SKI and AKI. | ||
1757 | * | ||
1758 | * XXX - Doing this in a fully OpenSSL 3 compatible way | ||
1759 | * is extremely nasty: they hang an issuer_pubkey off | ||
1760 | * the X509V3_CTX and adjusted v2i_AUTHORITY_KEYID(). | ||
1761 | * Punt on this and make things work in the specific | ||
1762 | * situation we're interested in. Like OpenSSL, we only | ||
1763 | * support the keyid form of the AKI, which is what | ||
1764 | * RFC 5280 recommends, but unlike OpenSSL we replace | ||
1765 | * existing SKI and AKI rather than honoring the most | ||
1766 | * likely outdated ones already present in the cert. | ||
1767 | */ | ||
1768 | if (!set_key_identifiers(x, pkey)) | ||
1769 | goto err; | ||
1770 | } | ||
1646 | } | 1771 | } |
1647 | if (!X509_sign(x, pkey, digest)) | 1772 | if (!X509_sign(x, pkey, digest)) |
1648 | goto err; | 1773 | goto err; |