Search code examples
c#.netx509certificate.net-4.8x509certificate2

Clean up `X509Certificate2Collection`


In .NET Framework 4.8; X509Certificate2 implements Dispose, and we must either Dispose the instance or use it inside a using {} block.

What about X509Certificate2Collection? For example, say I load a .pfx file containing a certificate chain:

byte[] data = File.ReadAllBytes("path/to/my/chain.pfx");
X509Certificate2Collection chain = new X509Certificate2Collection();
chain.Import(data, "hunter2", X509KeyStorageFlags.Ephemeral);
// do some work with the certificates

Is it necessary to cleanup? For example, should I loop through the certificates in the chain and call Reset or Dispose?


Solution

  • The system doesn't make it easy for you to do so, but: yes, ideally you would dispose the certificates that were created by X509Certificate2Collection.Import.

    If you don't, the certificates will eventually get cleaned up by the Garbage Collector + Finalizer, but cleaning up the objects when you're done with them is better.

    You showed setting EphemeralKeySet here, but had you not specified either EphemeralKeySet or PersistedKeySet then the "temporary" key-on-disk's deletion is tied to when the certificate gets disposed (or finalized), and making that happen earlier is better (so that, for example, it doesn't get left behind if your process crashes or the computer loses power).

    Because one of the things that indirectly get tested in the .NET tests is that .NET doesn't create certificates and send them off to the finalizer, the X509Certificate(2) tests all need to do deterministic cleanup. They use a wrapper type that remembers what certs actually got imported, so that changes to the collection later don't change what does/doesn't get disposed. Most users of X509Certificate2Collection.Import are doing so with an empty collection, and never add to or remove from that collection, so just a foreach+Dispose is good enough. https://github.com/dotnet/runtime/blob/57608c3728279917a401a97ef80fa533c86b062f/src/libraries/System.Security.Cryptography/tests/X509Certificates/Cert.cs#L71-L76