Using OpenSSL with Windows cert store

Pawel Frankowski pwfran98 at wp.pl
Mon Apr 24 08:37:06 UTC 2023


Hi Michael,

  thanks a lot for your answer.
> "FIPS compliant" doesn't mean anything useful. I'm assuming you mean "I have a requirement to develop an application which uses cryptography, and the cryptography must have a FIPS 140 validation". Note that OpenSSL 1.0.2 is out of support unless you have a support contract for it. Also, I think OpenSSL 1.0.2's FIPS validation was moved to historic status, though as I recall there was some kerfuffle around this and perhaps it was restored to active.
>
> In any case, now that we have OpenSSL 3.0 and it has a FIPS 140-validated provider, why do you want to use 1.0.2?
I know "FIPS compliant" may not mean anything useful, but it may impose 
limitations, that is why I mention it.
Version 1.0.2 is required by the company I work for and yes, we have 
support contract for it.
Migration to 3.0 is possible in some future, but not yet.
>> I have requirement that it should get certificates, keys and
>> CRLs from Windows cert store, and it should use TLS 1.2 EC-based suites.
> Setting aside the matter of CRLs (because they're terrible and generally useless) this raises another question: if you're using the Windows cryptographic store, why not use Windows cryptography and set *that* to FIPS mode?
I could use Windows crypto but the whole TLS functionality must use 
OpenSSL version mentioned above.
>> Correct me if I am wrong, but as far as I know there are, at least in theory, 2 ways
>> of doing this:
>> 1) Get required cert/keys from Windows store using Windows API (Crypto API or CNG ?)
> CNG supersedes CAPI and is recommended for new applications. If you're not already using CAPI (e.g. because you're using OpenSSL prior to 3.0 and the CAPI Engine), use CNG.
OK, this is what I thought. More, it seems CAPI providers do not support 
EC (in contrary to CNG), so using OpenSSL with capi engine (my solution 
2)  is out of the question.
> You can only retrieve keys from the Windows store if they're marked as exportable. It's safer (under some threat models) and generally more sensible to let Windows perform the key-related operations, if you're using the Windows store.cert
Yes, I may mark keys as exportable.
>> Getting certificates from there programmatically using WinAPI is quite easy and works
>> CertFindCertificateInStore, etc.),
>> but is it possible to retrieve also corresponding private keys ?
> Only if the keys are marked as exportable, which is not the default. There is also the perennial problem of CAPI/CNG "providers" and incorrectly-labeled keys, which I'll go into below if I remember to.
>
>> Or perhaps it would b e easier to use CNG API to do it ?
> Regardless of whether it's easier, it would be better to use CNG. Or the equivalent .NET APIs if you're writing a CLR program.
>
>> 2) Using OpenSSL directly with CryptoAPI engine (capi).
>> Setting capi engine I was able to sign and verify signatures using RSA certs/keys,
>> but it seems that CryptoAPI (and capi engine using it) does not support EC.
> CAPI itself doesn't support anything. It's a framework API. Algorithms are provided by CAPI providers, and Microsoft has published CAPI ECC providers, but I have no idea offhand what's installed by default in current Windows versions. It's been several years since I had to muck around in this stuff.
>
> The OpenSSL 1.x CAPI Engine does not support ECC operations directly. (If you look at the source, you'll see it only implements RSA and DSA as far as algorithms go.) In principle you can use it to extract certificates with ECC public keys, and exportable private ECC keys, *if* you have an appropriate provider, and you tell the engine to use that provider when you go to extract those objects, and the keys were added to the Windows store correctly.
>
> On that last point, the problem I alluded to above rears its ugly head. Private keys in the Windows store are supposed to be labeled with the provider they use. Often they are not. (More specifically, there's both a provider name and a provider type, and braindead software such as Microsoft's certutil will set the provider name correctly, if you tell it to, but always have the provider type wrong.) I ended up tweaking capi_load_privkey in my fork of the OpenSSL CAPI Engine to silently fix the provider type when trying to load a key. Or, actually, looking at my code, in capi_get_key. Whatever.
>
> But, rather than go through the grief of using the OpenSSL CAPI Engine (with a fix similar to mine), or your own code, to extract private keys (which still must be exportable), why not Do The Right Thing and let Windows handle the cryptography, in FIPS mode? (Maybe you don't want to put Windows in FIPS mode, but then the question arises of why you need FIPS 140 validation for your application when the OS and other applications don't.) Either use OpenSSL 1.x and enhance the CAPI Engine to do ECC – it's just a matter of wrapping the relevant CAPI functions, along the same lines as for RSA and DSA – or move to OpenSSL 3.0 and either write or find a CNG Provider. Someone mentioned one on this list some time back.
>
> Having worked with CAPI and the OpenSSL 1.x CAPI Engine, I know I'd rather write a CNG Provider from scratch for 3.0 than go through that again. The OpenSSL CAPI engine isn't very complicated but CAPI itself is a mess with hard-to-diagnose issues like the provider-type problem, and using 1.x is a Bad Idea unless you have a support contract (and, arguably, even then, if you have any scope whatsoever for moving to 3.0). And if the OS vendor will provide FIPS-validated cryptography for you ... well, that's a whole hassle you're avoiding.
>
What do you mean exactly by "why not Do The Right Thing and let Windows 
handle the cryptography, in FIPS mode?" ? Could you please elaborate ?

As far as I can see I don't have access to ECC-capable CAPI provider, so 
simply using OpenSSL with capi engine will not work.
I don't think I can afford extending capi engine to do ECC and I cannot 
use OpenSSL 3.0 by now - we will see when company moves to 3.0.

So far I think I would use Windows API (CNG ?) to extract certificates 
and (exportable) keys from Windows store and load them into OpenSSL.
Are there any working examples of doing this ? Especially, accessing 
Personal/My store using CNG ?
Assuming private keys are exportable is it possible to export them in 
DER/PKCS8 or other format easily importable to OpenSSL ?


Best regards,
Pawel


More information about the openssl-users mailing list