New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Inconsistency in cert/key params, OpenSSL ENGINE / PKCS#11 issues #974
Comments
I note that the GnuTLS back end doesn't work with PKCS#12 files at all, and accepts PKCS#11 URIs whether you set the file type to PEM or DER. In fact, I'm not sure anything works with PKCS#12 files. PEM files... are odd. You need to specify the password for the key, in the And the above only actually works for OpenSSL and GnuTLS builds here; with NSS it still fails thus: |
Turns out the nss-pem module doesn't handle encrypted PKCS#8 PEM files at all. So the latter is at least not curl's fault. https://bugzilla.redhat.com/show_bug.cgi?id=1369251 |
I use curl's PKCS#11 capabilities in a different way: I'm listing private keys on card using command: To list certificates I use a command: Then I paste these IDs to the curl command or use them in CURLOPT_SSLCERT and CURLOPT_SSLKEY. My OpenSSL initialization function is as follows:
} |
One remark: I use old versions of engine_pkcs11.dll (0.1.8) and libp11 (0.2.8) compiled with mingw for production purposes because pkcs11-tool.exe 0.13.0 crashes on enumerating certificates with new version of engine pkcs#11. |
Thanks for the information. Without actually breaking your code above, my plan is to make most of it unnecessary. Especially the OpenSSL-specific horridness. You shouldn't need to use any of the All you need to do is set
You'd have just
Note that the latter already works when curl is built against GnuTLS, and I've got patches outstanding to NSS which mean that it'll work with NSS too. And now I'll fix curl's use of OpenSSL so it's all consistent. I am very interested in your comment about pkcs11-tool crashing. Note that it doesn't actually use the engine, or even libp11. It is, however, linked against its own version of OpenSC. What is the token you're using? Is it also OpenSC, and could it be a different version, so you have two different versions of the library being used at the same time? Could you file a separate ticket for that in the OpenSC repository please? |
Hmm. I probably mismatched versions of opensc.dll and pkcs11-tool.exe in my system. I repaired it and can't repeat this crash. |
For reference and building test cases, here are a bunch of ways you can generate/mangle a key, all of which should Just Work™ when you give the filename to curl. Without having to take any additional information from the user... PKCS#8 encrypted (PKCS#5 v2.0), HMAC-SHA1openssl pkcs8 -topk8 -in key.pem -out key-pkcs8-crypt.pem -v2 aes258 -v2prf hmacWithSHA1 PKCS#8 encrypted (PKCS#5 v2.0), HMAC-SHA256openssl pkcs8 -topk8 -in key.pem -out key-pkcs8-crypt.pem -v2 aes258 -v2prf hmacWithSHA256 PKCS#8 unencryptedopenssl pkcs8 -topk8 -in key.pem -nocrypt PKCS#1 unencryptedopenssl rsa -in key-pkcs8-crypt.pem -out key-pkcs1.pem PKCS#1 (OpenSSL encrypted)openssl rsa -in key-pkcs8-crypt.pem -out key-pkcs1-crypted.pem -aes128 openssl rsa -in ke2.pem -out ke3.pem PKCS#12openssl pkcs12 -export -out foo.p12 -inkey foo -in cert -certfile ca.cert -chain We can probably add a test which adds a |
Well, that quickly got silly. I accumulated some test cases, realised that my own project doesn't support them all, and went off to get my own house in order first... and also fixed some bugs in GnuTLS and OpenSSL which made it impossible to support them all. So now I have a nice set of torture tests at http://git.infradead.org/users/dwmw2/openconnect.git/blob/HEAD:/tests/Makefile.am which I assert that any well-behaved application capable of using client certificates SHOULD support. And a nascent Internet-Draft describing best practice to that effect: http://david.woodhou.se/draft-woodhouse-cert-best-practice.html Feedback very much welcome; I will be coming back to prod at curl with a pointy stick later... |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
Rather than continuing to pollute #964 I'll open a new ticket. This command line works when curl is built against GnuTLS or a suitably fixed NSS:
It doesn't work with OpenSSL, for a number of reasons.
One of the simple problems is that the curl command-line tool will automatically assume you want
CURLOPT_SSLENGINE_DEFAULT
if you pass--engine
. This seems wrong, and it makes the SSL connection fail because you really don't ever want that:@nased0 I'm assuming this isn't a problem for you because you're using libcurl and not setting
CURLOPT_SSLENGINE_DEFAULT
? I can't understand why anyone would want that option, although it's been present in curl(1) since the ENGINE support was first merged in commit af6c394. Can we just make the tool stop doing that?Next we have to specify the ENGINE explicitly by adding
--engine pkcs11
. We'll want to automatically infer that from the 'pkcs11:' at the beginning of the command line. Which brings me to theCURLOPT_SSLCERTTYPE
andCURLOPT_SSLKEYTYPE
options...I also need to pass
--certtype ENG
. OK, suboptimal but I can fix that (and let's fix it to automatically determine PKCS#12 vs. PEM files while we're at it, shall we? Just how much do we hate our users, to make them do that manually?).So now maybe with
--engine pkcs11 --cert-type ENG
it'll work...Oh, that's cute. We must really hate our users :)
We "assume" that the key identifier string (usually filename) is the same as the cert, but we don't assume that it's the same type? Really? OK, let's tell it that the key is the same type as the cert...
This is getting surreal now... if I specify the key type you forget what the key was. Finally, if I spell everything out (and patch out the
ENGINE_set_default()
call as discussed above), it does actually work:So... rants about hating users aside, what can we do about this? What part of this utter clusterf*ck do we need to preserve in the name of backward-compatibility, and what can we fix? :)
My suggestion would be to add a cert and key type of 'AUTO', which will be the default, and will work it out automatically. If it's a filename, then look in the file to see if it's PKCS#12 or PEM and act accordingly. And then only if your crypto library is insane enough to make you choose, rather than silently just doing the right thing with the filename you give it.
And if the string starts "pkcs11:" then it's fairly obviously a PKCS#11 URI so treat it as such. Which means setting the engine to 'pkcs11' in the OpenSSL case, but other libraries should cope automatically. Although that's partly because the NSS back end treats it as an NSS identifier even when the type is
PEM
... but OK, whatever.It's possible to fix this up in the tool, and have it inspect the
--cert
argument and manually set the type(s) accordingly... but I think it's much better off in the library.The text was updated successfully, but these errors were encountered: