From MSDN, this class is "not guaranteed to be thread safe."
From common sense, look at this class: there is a Handle property. This means that this class is just a wrapper for some lower level, perhaps a direct wrapper for CAPI services, and I actually do not think this is really unsafe.
I managed to find this one discussion: http://marc.info/?l=ms-cryptoapi&m=103430170033615 , pointing to some "discussions@microsoft.com", but it is controversial as a source of information.
Looking at X509Certificate and X509Cert2 with TypeDescriptor, it looks like it makes heavy use of lower levels, and even getters are not cached and polling all values directly from CAPI. If you are only reading, the X509 object does not seem to do much harm, but, of course, since MSDN says that it is “not guaranteed to be thread safe,” I cannot guarantee it either.
Some important points:
- The X509 object is just a manager wrapper in a CAPI context and processes
- The X509 object does not seem to cache anything, but the CAPI can do this based on TRANSFER.
- X509 obj does some error checking (even in getters) on the .Net side and throws exceptions if CAPI considers the request to be invalid.
- CAPI is almost certainly thread safe in terms of READing certificates.
- CAPI will almost certainly return errors when a certificate is deleted or something similar happens evil, but you do not control it, because the user can, for example, delete this certificate manually, and this makes me even more confident that CAPI is fully internally strengthened against multithreading.
However, I am sure that even if the x509 shell is damaged, the CAPI will not crash and will not damage the certificate database. I think the worst that could be the exception on the .Net side
You may also find this question interesting: Mitigating RsaCryptoServiceProvider security problems on a web server
Now lean back from this optimistic point of view.
You are talking about an error and a memory leak. Where was it? Was it in the .Net crypto class library or inside the CAPI? It was in CAPI, and if you cannot apply corrections on this machine, then you know, I would rather advise a little bit paranoid with this. If you open the same file with two X509 objects, and therefore two handles caused a leak, then I would really empirically ensure that reusing the same descriptor from many threads does not leak either. Errors like going into swarms and a “pen” are more fragile than a “file name”.
In addition, let me completely distract from the question;) - a known memory leak with known preconditions is usually not dangerous and can be circumvented in various ways.
Of course, if you created new X509 objects on the fly with every service request, you would run into memory problems, as each object would add a new leak. But a leak can easily be kept and closed to a constant value even without sharing objects. For example, you can pre-construct 10/100/1000 identical x509 objects, drop them into any thread safe collection and create a small manager class (a few lines of code, really) that will provide access to them upon acquisition / release. Thus, you will use the cost of memory 10/100/1000 times the leak, but it will be known and constant and will not grow further. Of course, this will mean that only 10/100/1000 simultaneous tasks related to certificates can be performed at a given time.