--- a/third_party/heimdal/kdc/pkinit-ec.c 2025-01-30 13:57:45.000000000 +0000 +++ b/third_party/heimdal/kdc/pkinit-ec.c 2026-09-01 23:21:32.000000000 +0000 @@ -314,11 +314,13 @@ groupnid); if (ret == 0 && (curve_sn_dup = strdup(curve_sn)) == NULL) ret = krb5_enomem(context); - if (ret == 0) { - if (der_heim_oid_cmp(&ecp.u.namedCurve, &asn1_oid_id_ec_group_secp256r1) != 0) - krb5_set_error_message(context, ret = KRB5_BADMSGTYPE, - "PKINIT client used an unsupported curve"); - } + /* + * The hardcoded secp256r1 check that used to live here rejected every + * other curve, even though _hx509_ossl_oid2nid() already resolves + * P-256/384/521 and the code below is curve-generic. Windows selects its + * ephemeral ECDH curve to match the logon certificate, so a P-384 + * certificate was always rejected. Restriction removed. + */ if (ret == 0) { /* * Apparently there's no error checking to be done here? Why does @@ -396,8 +398,22 @@ goto out; } + /* + * This path accepted ONLY secp256r1, so a Windows client using a P-384 + * logon certificate (which makes Windows choose a P-384 ephemeral ECDH + * key) was rejected with KRB5_BADMSGTYPE. Accept the other NIST curves + * that OpenSSL and hx509's oid2nid[] already support. + */ if (der_heim_oid_cmp(&ecp.u.namedCurve, &asn1_oid_id_ec_group_secp256r1) == 0) nid = NID_X9_62_prime256v1; +#ifdef NID_secp384r1 + else if (der_heim_oid_cmp(&ecp.u.namedCurve, &asn1_oid_id_ec_group_secp384r1) == 0) + nid = NID_secp384r1; +#endif +#ifdef NID_secp521r1 + else if (der_heim_oid_cmp(&ecp.u.namedCurve, &asn1_oid_id_ec_group_secp521r1) == 0) + nid = NID_secp521r1; +#endif else { ret = KRB5_BADMSGTYPE; goto out;