dotnet / docs

This repository contains .NET Documentation.
https://learn.microsoft.com/dotnet
Creative Commons Attribution 4.0 International
4.18k stars 5.85k forks source link

[Breaking change]: X509Certificate2, X509Certificate constructors and X509Certificate2Collection.Import are obsolete for binary and file content #41662

Open vcsjones opened 2 weeks ago

vcsjones commented 2 weeks ago

Description

The constructors on X509Certificate and X509Certificate2 that accept content as a byte[], ReadOnlySpan<byte>, or a string file path have been marked obsolete.

The Import method and all overloads on X509Certificate2Collection have also been marked obsolete.

Version

.NET 9 Preview 7

Previous behavior

Developers could use those APIs without an obsolete warning.

New behavior

Affected APIs will receive an obsolete compilation warning with SYSLIB0057.

Type of breaking change

Reason for change

The affected APIs supported loading certificates in multiple formats. For example, new X509Certificate2(data) would load a certificate from a byte[] called data. This data could be one of any supported format, including X.509, PKCS7, or PKCS12/PFX.

While this was easy to use, it created issues where user-supplied data is passed with a different format than intended. This may allow loading PKCS12 where only X.509 content was intended to be loaded, or create interoperability issues from handling the data in different ways.

Recommended action

Developers should use a different API to load certificate content, depending on the intended content type.

A new class called X509CertificateLoader can be used to load X.509 or PKCS12 content.

If you are uncertain about the content type you are loading, X509Certificate2.GetCertContentType can be used to determine the content type and call the appropriate API.

You may also suppress the obsoletion using #pragma warning disable SYSLIB0057 and #pragma warning restore SYSLIB0057 around the affected code to continue using the legacy certificate loading APIs.

The Microsoft.Bcl.Cryptography package supplies X509CertificateLoader for .NET Framework and .NET Standard.

Feature area

Cryptography

Affected APIs

Affected Doc IDs:




vcsjones commented 2 weeks ago

The content and messaging of this should get sign-off from @bartonjs first.

bartonjs commented 2 weeks ago

I tweaked the message a little bit, LGTM.

akoeplinger commented 2 weeks ago

@bartonjs reading https://github.com/dotnet/runtime/issues/91763 it looks like the Authenticode pieces were cut, is the intention for those to keep using X509Certificate2 ctor and suppress the warning?

Here's code from the SDK where we use this and I had to suppress: https://github.com/dotnet/sdk/blob/70479edb89ef1820051e951c4977f5fdb153f8e1/src/Cli/dotnet/Installer/Windows/Security/Signature.cs#L32-L35

akoeplinger commented 2 weeks ago

Also there's quite a lot of code that uses the approach shown in https://stackoverflow.com/questions/72096812/loading-x509certificate2-from-pem-file-results-in-no-credentials-are-available/72101855#72101855 to export+import a cert to workaround some Windows issue, is that contuing to work with export+X509CertificateLoader.LoadCertificate ?

bartonjs commented 2 weeks ago

reading https://github.com/dotnet/runtime/issues/91763 it looks like the Authenticode pieces were cut, is the intention for those to keep using X509Certificate2 ctor and suppress the warning?

More or less. For anyone still using that ctor, but expecting a certain content type, the recommendation is to do something like

if (X509Certificate2.GetCertContentType(input) != X509ContentType.TheOneIExpect)
{
    throw new CryptographicException();
}

#pragma warning disable SYSLIB0057
X509Certificate2 cert = new(input);
#pragma warning restore
bartonjs commented 2 weeks ago

export+import a cert to workaround some Windows issue, is that contuing to work with export+X509CertificateLoader.LoadCertificate

Yeah, just now it's X509CertificateLoader.LoadPkcs12(cert.Export(X509ContentType.Pkcs12, null))

akoeplinger commented 2 weeks ago

Ok. It's a bit sad that we have to suppress the warning for the Authenticode case but so be it :) Probably good to mention this in the doc somewhere.

ScotMac commented 1 week ago

export+import a cert to workaround some Windows issue, is that contuing to work with export+X509CertificateLoader.LoadCertificate

Yeah, just now it's X509CertificateLoader.LoadPkcs12(cert.Export(X509ContentType.Pkcs12, null))

@bartonjs HI Jeremy, i believe that question you quoted was in reference to PEM files. How do we get an x509Certificate2Collection for a PEM file with multiple certs/keys that has been read in and is now in a byte[]?

Thanks.

bartonjs commented 1 week ago

@ScotMac If you actually mean PEM when you say PEM, then that's X509Certificate2Collection.ImportFromPem, which is not being marked as obsolete.

If you meant PFX when you said PEM, that's X509CertificateLoader.LoadPkcs12Collection.

bartonjs commented 1 week ago

Oh, I slightly lied. The Collection ImportFromPem won't import private keys. There's no API for loading multiple certificates and multiple private keys from PEM. Only PFX supports multiple private keys.

ScotMac commented 1 week ago

@bartonjs Thanks Jeremy.

Yes, it appears that API will only read in public key certs. Is there no .NET API for parsing PEM data that contains at least one private key, and possibly multiple public key certs? Thus providing a way to get the key/certs necessary to estabish an mTLS connection (including the validation of the server cert), without using MCS (cert stores).

ScotMac commented 1 week ago

And yes, i meant PEM.

But thanks for that p12 load function, since we are currently using x509Certificate2Collection.Import() for p12, which appears to be obsoleted by this notice.