--- a/third_party/heimdal/lib/hx509/crypto-ec.c 2025-01-30 13:57:45.000000000 +0000 +++ b/third_party/heimdal/lib/hx509/crypto-ec.c 2026-09-01 23:21:32.000000000 +0000 @@ -785,6 +785,30 @@ 48 }; +/* + * Windows/CNG places the KEY algorithm OID (id-ecPublicKey) in the CMS + * SignerInfo.signatureAlgorithm field, where RFC 5652 expects the SIGNATURE + * algorithm OID (ecdsa-with-SHA384). Accept it and verify as ECDSA/SHA-384 so + * that Windows PKINIT smart-card logon interoperates. + * + * NOTE: the digest is fixed at SHA-384 here, which is only correct for P-384 + * clients. A general fix should derive the digest from SignerInfo.digestAlgorithm. + */ +const struct signature_alg ecdsa_ecpubkey_sha384_alg = { + "ecdsa-ecpublickey-sha384", + ASN1_OID_ID_ECPUBLICKEY, + &_hx509_signature_ecPublicKey, + ASN1_OID_ID_ECPUBLICKEY, + &_hx509_signature_sha384_data, + PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO| + SIG_PUBLIC_SIG|SELF_SIGNED_OK, + 0, + NULL, + ecdsa_verify_signature, + ecdsa_create_signature, + 48 +}; + const struct signature_alg ecdsa_with_sha256_alg = { "ecdsa-with-sha256", ASN1_OID_ID_ECDSA_WITH_SHA256, --- a/third_party/heimdal/lib/hx509/crypto.c 2025-01-30 13:57:45.000000000 +0000 +++ b/third_party/heimdal/lib/hx509/crypto.c 2026-09-01 23:21:32.000000000 +0000 @@ -760,6 +760,7 @@ #ifdef HAVE_HCRYPTO_W_OPENSSL extern const struct signature_alg ecdsa_with_sha512_alg; extern const struct signature_alg ecdsa_with_sha384_alg; +extern const struct signature_alg ecdsa_ecpubkey_sha384_alg; extern const struct signature_alg ecdsa_with_sha256_alg; extern const struct signature_alg ecdsa_with_sha1_alg; #endif @@ -968,6 +969,7 @@ static const struct signature_alg *sig_algs[] = { #ifdef HAVE_HCRYPTO_W_OPENSSL &ecdsa_with_sha512_alg, + &ecdsa_ecpubkey_sha384_alg, &ecdsa_with_sha384_alg, &ecdsa_with_sha256_alg, &ecdsa_with_sha1_alg,