WIP: Add e_cng, a new engine that interfaces with MS CNG/Ncrypt and uses STORE#3481
WIP: Add e_cng, a new engine that interfaces with MS CNG/Ncrypt and uses STORE#3481levitte wants to merge 5 commits intoopenssl:masterfrom
Conversation
|
@snhenson, you might be interested in this |
|
Awesome! |
|
Maybe time to start reviewing the STORE project for real? (hint hint nudge nudge) ;-) |
Configurations/10-main.conf
Outdated
There was a problem hiding this comment.
It's tricky one. Formally there is no reason to link everything with ncrypt.lib. Well, of course in static build ncrypt.lib needs to be there for every .exe that pulls in e_cng.obj. But in shared build cng.dll would be the only one that needs to be linked with it. MSC has solution for that, and it's #pragma comment(lib,"ncrypt") that can be added directly to e_cng.c. And it's going to work out in both static and dynamic builds. [The pragma is tolerated by mingw compilers, but does nothing.] Another argument against adding it as above is that people still seem to be asking about compiling for legacy version, and there is no ncrypt.lib there. Even in such case above mentioned #pragma would do the trick, because it can be conditional...
There was a problem hiding this comment.
I think it can be argued that crypt32.lib shouldn't be there with the argument that only capi.dll needs it as well, no? I was pondering another variant, to add language in build.info to specify extra external libraries to be used with specific programs or shared libraries. Would it be worth it? Maybe. For now, though, I'll use the pragma, thanks for pointing it out.
There was a problem hiding this comment.
I think it can be argued that crypt32.lib shouldn't be there
I think so, yes. But there is difference. crypt32.lib is present in legacy SDKs, while ncrypt.lib is not. This is kind of the real concern. Having library on command line you don't link with has no side effects (on Windows), but lib-file needs to be present if you refer to in on command line irregardless. In other words it's availability of ncrypt.lib file in user's SDK that is concern.
engines/e_cng.c
Outdated
There was a problem hiding this comment.
MSDN says include ncrypt.h and I don't see no ncrypt.h. Well, nothing prevents wincrypt.h from including ncrypt.h, but then question would be if all SDKs do that... Maybe they all do, did you verify?
There was a problem hiding this comment.
I have verified that wincrypt.h includes ncrypt.h indeed. The reason I do this is the lines following, where I detect if ncrypt is present or not.
There was a problem hiding this comment.
I have verified that wincrypt.h includes ncrypt.h indeed.
Question was if all of them do. But of course one can always say that if wincrypt.h doesn't include ncrypt.h, then we don't compile it. It would be appropriate to mention this in more verbose comment...
engines/e_cng.c
Outdated
There was a problem hiding this comment.
I'd suggest a little bit more verbose comment...
engines/e_cng.c
Outdated
There was a problem hiding this comment.
I didn't follow the code thoroughly, but question is if CP_UTF8 would be more appropriate. Underlying question is if in can contain non-ASCII characters. Trouble is that CP_ACP can wipe some of them. I'd say that CP_UTF8 should be always preferred unless there is recognized reason to use CP_ACP.
There was a problem hiding this comment.
I used CP_ACP because e_capi.c does so. I was wondering, though, if that was the right choice. What can we expect from the command prompt these days?
There was a problem hiding this comment.
I used CP_ACP because e_capi.c does so.
It doesn't mean that it's right :-) I mean it surely needs an overhaul too.
What can we expect from the command prompt these days?
Command line options are UTF8-ised, and so should be console input. I'll double-check... And I'll have a look at e_capi.c. One can also put it this way. Let's aim for CP_UTF8, because it's the only one that should work, and fix remaining code paths. As opposite to trying to see what happens to work right now... Just to clarify, go for CP_UTF8 :-)
3e2c984 to
0556a9b
Compare
|
From a STORE point of view, this is currently fairly complete. It enumerates key providers, cert stores, keys (I hope, I don't seem to have any) and certs (the last two given a provider or a store), and fetches keys (I hope) and certs (this I know for certain). On to the key calculations part... |
|
Also, fancier search capabilities will be added in not too long (I know @snhenson's wondering about that part) |
d7d841c to
a34fd58
Compare
e6c67b6 to
8338528
Compare
|
Any idea when store changes and the cng engine this will be merged? |
8338528 to
25ddb80
Compare
Not really. Our major focus for 3.0 is replumbing and the FIPS module, so it's quite possible that this gets pushed to a later version, like 3.1. |
| goto err; | ||
| } | ||
| if (NCryptExportKey(khandle, 0, BCRYPT_PUBLIC_KEY_BLOB, NULL, | ||
| (PBYTE)exported, size, NULL, 0) != ERROR_SUCCESS) { |
There was a problem hiding this comment.
Passing NULL to pcbResult at this point causes NCryptExportKey to fail with 0x800706F4 in my test case. Passing &size resolves that problem.
|
I had forgotten about this... right now, my thoughts are to throw it away and create a provider instead |
| return -1; | ||
| } | ||
|
|
||
| if (NCryptEncrypt(ctx->khandle, (PBYTE)from, flen, NULL, to, flen, &len, |
There was a problem hiding this comment.
As far as I have seen, NCryptEncrypt will use the public key from the key handle instead of the private key, so NCryptDecrypt needs to be used here to perform the RSA operation with the private key.
NCryptDecrypt however probably can't be configured to add padding before the RSA operation with the private key as required here (RSA private enrypt) as it's designed to be used for decryption with the private key but not for signing/encryption and therefore removes the padding after the RSA operation (RSA private decrypt) instead of adding it before.
For that reason, NCryptDecrypt can only be used with RSA_NO_PADDING here, as with that RSA private encrypt and RSA private decrypt result in the same operation.
When OpenSSL uses RSA signing with PSS padding, this method is called with RSA_NO_PADDING as the padding has already be applied to the buffer before, so that is no problem in that case.
Client certificate authentication with TLS 1.2+ works in my test case, when NCryptDecrypt with RSA_NO_PADDING is used here (See #12859).
Please tell me if I am wrong.
There was a problem hiding this comment.
Yes, it is true that from my testing that when using TLSv1.3, the NCryptDecrypt should be used instead of NCryptEncrypt with the NCRYPT_NO_PADDING_FLAG as the padding of the buffer.
|
I was informed just now that someone else has made a CNG engine: https://github.com/rticommunity/openssl-cng-engine |
This PR doesn't build on its own for now, it needs to be merged #2688 to build.
Checklist