http://bugs.winehq.org/show_bug.cgi?id=60486 Bug ID: 60486 Summary: crypt32: PFXExportCertStoreEx() and PFXImportCertStore() do not support ECDSA (CNG) keys Product: Wine Version: 11.19 Hardware: x86-64 OS: Linux Status: UNCONFIRMED Severity: normal Priority: P2 Component: crypt32 Assignee: wine-bugs@list.winehq.org Reporter: mailtomendoza@gmail.com Target Milestone: --- Distribution: --- Exporting or importing a PFX whose private key is an ECDSA key fails. 1. Export: X509Certificate2.Export(X509ContentType.Pfx) in .NET Framework 4.8 for a certificate with a CNG ECDSA P-256 key crashes. PFXExportCertStoreEx() always asks NCrypt for BCRYPT_RSAFULLPRIVATE_BLOB, which ends in bcrypt's RSA export code with an EC key (page fault inside the RSA key accessor). 2. Import: new X509Certificate2(pfxBytes, password, flags) with an EC key fails with CRYPT_E_BAD_ENCODE (0x80092002). The unix side (open_cert_store) rejects every key that is not GNUTLS_PK_RSA, and the PE side only knows how to import RSA keys into a CAPI provider. Steps (any .NET 4.8 program, 32- or 64-bit): var ec = ECDsa.Create(ECCurve.NamedCurves.nistP256); var req = new CertificateRequest("CN=test", ec, HashAlgorithmName.SHA256); var cert = req.CreateSelfSigned(DateTimeOffset.Now, DateTimeOffset.Now.AddYears(1)); var pfx = cert.Export(X509ContentType.Pfx, "pw"); // crash var back = new X509Certificate2(pfx, "pw", X509KeyStorageFlags.Exportable); // 0x80092002 (CreateSelfSigned itself needs the ncrypt changes from bug 60443.) A suggested patch is attached (tested on Wine 11.19, applies to master too): - PFXExportCertStoreEx(): read NCRYPT_ALGORITHM_GROUP_PROPERTY and export BCRYPT_ECCPRIVATE_BLOB for ECDSA/ECDH; unix export_cert_store builds the key with gnutls_x509_privkey_import_ecc_raw(GNUTLS_ECC_CURVE_SECP256R1). - open_cert_store accepts GNUTLS_PK_ECDSA; import returns a BCRYPT_ECCPRIVATE_BLOB built with gnutls_x509_privkey_export_ecc_raw(). - PFXImportCertStore(): ECC blobs are imported with NCryptOpenStorageProvider(MS_KEY_STORAGE_PROVIDER) + NCryptImportKey() and attached with CERT_NCRYPT_KEY_HANDLE_PROP_ID plus a CNG CERT_KEY_PROV_INFO, so HasPrivateKey is true and CryptAcquireCertificatePrivateKey() returns the NCrypt handle. RSA keeps the existing CAPI path. With it, export/import round trip and signing with the imported key work (32- and 64-bit); crypt32 conformance tests are unchanged. Limitations, why this is a suggestion rather than a finished patch: P-256 only; the CERT_KEY_PROV_INFO names a container that does not exist (Wine has no persisted NCrypt keys); PKCS12_ALWAYS_CNG_KSP is still ignored; no new tests yet. Possibly related: bug 59038. -- Do not reply to this email, post in Bugzilla using the above URL to reply. You are receiving this mail because: You are watching all bug changes.