http://bugs.winehq.org/show_bug.cgi?id=27168
--- Comment #25 from Juan Lang juan_lang@yahoo.com 2011-09-18 12:23:51 CDT --- (In reply to comment #23)
Trying to do it... And finding all the certificate store stuff is a bit overcomplicated. Duplicating, freeing, duplicating again... Seems quite a mess really.
The design is partially imposed by the Crypto API. Of course, if it there was a simpler way to do it that I didn't see, that's my fault ;)
I've wrote a simple app (https://gist.github.com/a0531270636f407b4a1d) that queries certificate from a google (and it also brings an intermediate certificate) then frees the certificate explicitly using CertFreeCertificateContext. The temporary store is freed (on windows). I'm trying to implement the same in wine but that's where the problem is - removing a certificate from store calls the same CertFreeCertificateContext. What's worse - enumerating certificates in store calls CertFreeCertificateContext.
The last statement is due to how CertEnumCertificatesInStore works. From MSDN: "The returned pointer is freed when passed as the pPrevCertContext parameter on a subsequent call. Otherwise, the pointer must be freed by calling CertFreeCertificateContext."
But let's have a look at your test:
printf("Got the certificate %p, store = %p\n", cert, store = cert->hCertStore);
Don't assign to store in a print statement, it's easy to miss. Also, it would be preferable to assign store using CertDuplicateStore, i.e.:
store = CertDupicateStore(cert->hCertStore);
Otherwise, it's possible that the last remaining store reference is closed when you call CertEnumCertificatesInStore for the last cert in the store, implicitly closing the store and freeing it.