How to specify empty password for PKCS#12 client certificate? #1308

Closed
justinclift opened this Issue Mar 4, 2017 · 19 comments

Projects

None yet

3 participants

@justinclift
justinclift commented Mar 4, 2017 edited

The problem situation

Attempting to use curl (for testing purposes) on OSX.

When connecting to the (internal development) HTTPS server, curl complains the PKCS#12 file needs a password. Which is bizarre, as there is no password set on the file. 😉

$ curl -v --cert ./cert.pfx https://dev2.dbhub.io:5550/foo
*   Trying 127.0.0.1...
* Connected to dev2.dbhub.io (127.0.0.1) port 5550 (#0)
* WARNING: SSL: Certificate type not set, assuming PKCS#12 format.
* SSL The certificate "./cert.pfx" requires a password.
* Closing connection 0
curl: (58) SSL The certificate "./cert.pfx" requires a password.

Is there a way to specify "empty password", so that it works? I've tried a few obvious variations, and no joy so far:

$ curl -v --cert ./cert.pfx https://dev2.dbhub.io:5550/foo:
*   Trying 127.0.0.1...
* Connected to dev2.dbhub.io (127.0.0.1) port 5550 (#0)
* WARNING: SSL: Certificate type not set, assuming PKCS#12 format.
* SSL The certificate "./cert.pfx" requires a password.
* Closing connection 0
curl: (58) SSL The certificate "./cert.pfx" requires a password.
$ curl -v --cert ./cert.pfx https://dev2.dbhub.io:5550/foo:''
*   Trying 127.0.0.1...
* Connected to dev2.dbhub.io (127.0.0.1) port 5550 (#0)
* WARNING: SSL: Certificate type not set, assuming PKCS#12 format.
* SSL The certificate "./cert.pfx" requires a password.
* Closing connection 0
curl: (58) SSL The certificate "./cert.pfx" requires a password.
$ curl -v --cert ./cert.pfx https://dev2.dbhub.io:5550/foo:""
*   Trying 127.0.0.1...
* Connected to dev2.dbhub.io (127.0.0.1) port 5550 (#0)
* WARNING: SSL: Certificate type not set, assuming PKCS#12 format.
* SSL The certificate "./cert.pfx" requires a password.
* Closing connection 0
curl: (58) SSL The certificate "./cert.pfx" requires a password.
$ curl -v --cert ./cert.pfx https://dev2.dbhub.io:5550/foo:\"\"
*   Trying 127.0.0.1...
* Connected to dev2.dbhub.io (127.0.0.1) port 5550 (#0)
* WARNING: SSL: Certificate type not set, assuming PKCS#12 format.
* SSL The certificate "./cert.pfx" requires a password.
* Closing connection 0
curl: (58) SSL The certificate "./cert.pfx" requires a password.

I expected the following

Successful connection to the remote server.

If I manually add a password to the PKCS file using openssl, then it works. eg adding :password to the end of the file argument. The trouble I'm hitting is only where there's no password set in the file.

$ curl -v --cert ./cert.pfx:password https://dev2.dbhub.io:5550/foo
*   Trying 127.0.0.1...
* Connected to dev2.dbhub.io (127.0.0.1) port 5550 (#0)
* WARNING: SSL: Certificate type not set, assuming PKCS#12 format.
* Client certificate: dev2.dbhub.io
* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
* Server certificate: dev2.dbhub.io
* Server certificate: DBHub.io DEVELOPMENT Intermediate CA
* Server certificate: DBHub.io DEVELOPMENT Root CA
> GET /foo HTTP/1.1
> Host: dev2.dbhub.io:5550
> User-Agent: curl/7.43.0
> Accept: */*
> 
< HTTP/1.1 200 OK
< Date: Sat, 04 Mar 2017 19:37:58 GMT
< Content-Length: 929
< Content-Type: text/plain; charset=utf-8
< 
[...]

curl/libcurl version

Using curl installed through Homebrew. eg it's using "Secure"Transport

$ curl -V
curl 7.53.1 (x86_64-apple-darwin15.6.0) libcurl/7.53.1 SecureTransport zlib/1.2.5
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtsp smb smbs smtp smtps telnet tftp 
Features: IPv6 Largefile NTLM NTLM_WB SSL libz UnixSockets 

The problem also shows up when using the system curl provided by OSX:

$ /usr/bin/curl -V
curl 7.43.0 (x86_64-apple-darwin15.0) libcurl/7.43.0 SecureTransport zlib/1.2.5
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtsp smb smbs smtp smtps telnet tftp 
Features: AsynchDNS IPv6 Largefile GSS-API Kerberos SPNEGO NTLM NTLM_WB SSL libz UnixSockets

operating system

OSX 10.11.6

Collaborator
nickzman commented Mar 4, 2017

Try using the --key option with an empty string and see if that solves the problem, like this: --key ""

If not, then one other thing you can try is importing the PKCS#12 data into your Keychain, and then using --cert with the identity name as it appears in Keychain Access.

@nickzman Thanks. 😄

Trying with --key, along with various options to mean empty string, doesn't seem to work either. 😦

$ curl -v --cert ./cert.pfx --key "" https://dev2.dbhub.io:5550/foo
*   Trying 127.0.0.1...
* Connected to dev2.dbhub.io (127.0.0.1) port 5550 (#0)
* WARNING: SSL: CURLOPT_SSLKEY is ignored by Secure Transport. The private key must be in the Keychain.
* WARNING: SSL: Certificate type not set, assuming PKCS#12 format.
* SSL The certificate "./cert.pfx" requires a password.
* Closing connection 0
curl: (58) SSL The certificate "./cert.pfx" requires a password.
$ curl -v --cert ./cert.pfx --key '' https://dev2.dbhub.io:5550/foo
*   Trying 127.0.0.1...
* Connected to dev2.dbhub.io (127.0.0.1) port 5550 (#0)
* WARNING: SSL: CURLOPT_SSLKEY is ignored by Secure Transport. The private key must be in the Keychain.
* WARNING: SSL: Certificate type not set, assuming PKCS#12 format.
* SSL The certificate "./cert.pfx" requires a password.
* Closing connection 0
curl: (58) SSL The certificate "./cert.pfx" requires a password.
$ curl -v --cert ./cert.pfx --key https://dev2.dbhub.io:5550/foo
curl: no URL specified!
curl: try 'curl --help' or 'curl --manual' for more information
$ curl -v --cert ./cert.pfx --key \"\" https://dev2.dbhub.io:5550/foo
*   Trying 127.0.0.1...
* Connected to dev2.dbhub.io (127.0.0.1) port 5550 (#0)
* WARNING: SSL: CURLOPT_SSLKEY is ignored by Secure Transport. The private key must be in the Keychain.
* WARNING: SSL: Certificate type not set, assuming PKCS#12 format.
* SSL The certificate "./cert.pfx" requires a password.
* Closing connection 0
curl: (58) SSL The certificate "./cert.pfx" requires a password.
$ curl -v --cert ./cert.pfx --key \\"\\" https://dev2.dbhub.io:5550/foo
*   Trying 127.0.0.1...
* Connected to dev2.dbhub.io (127.0.0.1) port 5550 (#0)
* WARNING: SSL: CURLOPT_SSLKEY is ignored by Secure Transport. The private key must be in the Keychain.
* WARNING: SSL: Certificate type not set, assuming PKCS#12 format.
* SSL The certificate "./cert.pfx" requires a password.
* Closing connection 0
curl: (58) SSL The certificate "./cert.pfx" requires a password.

Importing into the keychain, though it might work, probably isn't going to be feasible. Aiming for something scriptable, that can be used with bulk keys for testing.

Should this be considered a bug in curl not picking up the empty string?

Collaborator
nickzman commented Mar 4, 2017

Can you even import it into the Keychain? I must say, it's quite unusual for a PKCS#12 file to have an empty password. If Keychain Access can't understand it, then the problem is with Apple's Security framework, not libcurl, since on macOS, libcurl uses Apple's PKCS#12 import function.

Owner
jay commented Mar 4, 2017

Recall for --cert that it expects a file with both the client certificate and private key. It is typical pfx contains both objects but check. I wonder if maybe you don't have both or it has a password even though you think it doesn't?

Should this be considered a bug in curl not picking up the empty string?

hm. Is a blank password the same as no password? That password error only happens on errSecPassphraseRequired. so if there is an empty password I guess it could be seen that way since parse_cert_parameter doesn't return an empty string as a password, instead it returns NULL (ie no password). OpenSSL PKCS12_parse for example seems to be ok with this.

CopyIdentityFromPKCS12File in darwinssl.c relevant area:

    const void *cKeys[] = {kSecImportExportPassphrase};
    const void *cValues[] = {password};
    CFDictionaryRef options = CFDictionaryCreate(NULL, cKeys, cValues,
      password ? 1L : 0L, NULL, NULL);
    CFArrayRef items = NULL;

    /* Here we go: */
    status = SecPKCS12Import(pkcs_data, options, &items);

I assume password is NULL based on my read of the code but cannot confirm this at runtime since I don't use mac. So 0 is set for numValues param for CFDictionaryCreate. In other words based on my read it seems no password is being set. And so again this makes me wonder is a blank password the same as no password.

@jay jay added the SSL/TLS label Mar 4, 2017
justinclift commented Mar 5, 2017 edited

@nickzman Thanks, that's interesting. You're right, KeyChain Access gets it wrong as well, also refusing to import it with no password.

When trying the import, it first pops up a dialog asking for a password:
screen shot 2017-03-04 at 23 54 30
Clicking the OK button, without entering any password then pops up a message about it being wrong, prompting again:
screen shot 2017-03-04 at 23 54 34
After a few further clicks on OK to see what happens, instead it pops up an error message about the import:

screen shot 2017-03-04 at 23 54 51

Conversely, trying the exact same certificate file with Firefox imports it fine. Firefox also asks for a password:
screen shot 2017-03-05 at 00 01 33
Then confirms it was imported fine:
screen shot 2017-03-05 at 00 04 35
And displays it in the list:
screen shot 2017-03-05 at 00 05 29
Firefox is then able to auth correctly to the remote server.

So it seems there's something wrong with Apples' import code then. ☹️

As a data point, the way I created the PKCS#12 cert file was by converting the PEM cert and it's key:

$ openssl pkcs12 -export -out cert.pfx -inkey cert.key.pem -in cert.pem
Enter Export Password:
Verifying - Enter Export Password:

For both of those password lines with the OpenSSL command, I just pressed enter. No other input.

Hmmm, I guess it's not going to be feasible to get a blank password passed in for PKCS#12 certs at this stage. Might need to turn to curl with the OpenSSL backend instead of Apple's "Secure"Transport, and use PEM format certs. Will test it tomorrow. 😄

@jay Yeah, not sure. My present thinking is it might be useful to file a bug with Apple. I've never personally seen Apple ever take an interest, so no idea if it's worth putting time into. What do you reckon?

justinclift commented Mar 5, 2017 edited

If it's useful, I can provide the PKCS#12 file, cert (PEM format), PEM cert key, ca chain, etc. They're all dev-only ones I generated earlier today, for a client-server thing I'm working on. (https://dbhub.io)

It's no real stress to generate new ones again tomorrow. 😉

Owner
jay commented Mar 5, 2017

You probably should but first if you are capable of compiling the source here are two things you can try. First it's possible that options if the password is NULL should really be a NULL pointer itself, so try changing that and see what happens, like pass options param as password ? options : NULL just to see what happens. And if that's not it then add this patch to try again with an empty password:

diff --git a/lib/vtls/darwinssl.c b/lib/vtls/darwinssl.c
index 25a8ab8..7795aa6 100644
--- a/lib/vtls/darwinssl.c
+++ b/lib/vtls/darwinssl.c
@@ -1003,6 +1003,15 @@ static OSStatus CopyIdentityFromPKCS12File(const char *cPath,
 
     /* Here we go: */
     status = SecPKCS12Import(pkcs_data, options, &items);
+    /* If auth fails and there is no password then try again with an empty
+       password. Apparently Apple treats those two things differently? */
+    if((status == errSecAuthFailed || status == errSecPassphraseRequired) &&
+       !cValues[0]) {
+      CFRelease(options);
+      cValues[0] = "";
+      options = CFDictionaryCreate(NULL, cKeys, cValues, 1L, NULL, NULL);
+      status = SecPKCS12Import(pkcs_data, options, &items);
+    }
     if(status == errSecSuccess && items && CFArrayGetCount(items)) {
       CFDictionaryRef identity_and_trust = CFArrayGetValueAtIndex(items, 0L);
       const void *temp_identity = CFDictionaryGetValue(identity_and_trust,
justinclift commented Mar 6, 2017 edited

@jay Thanks. It's been ages since I did C dev work, so wasn't sure where to attempt the password ? options : NULL change.

With your patch though, that was simple to apply then test. But still no luck with the certificate working. 😉 The error message changed, and now is:

curl: (58) SSL: Can't load the certificate "./cert.pfx" and its private key: OSStatus -50

For reference, the commands I tried with the patched version are:

$ /tmp/curl/bin/curl -v --cert ./cert.pfx: https://dev2.dbhub.io:5550/foo
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to dev2.dbhub.io (127.0.0.1) port 5550 (#0)
* WARNING: SSL: Certificate type not set, assuming PKCS#12 format.
* SSL: Can't load the certificate "./cert.pfx" and its private key: OSStatus -50
* Closing connection 0
curl: (58) SSL: Can't load the certificate "./cert.pfx" and its private key: OSStatus -50
$ /tmp/curl/bin/curl -v --cert ./cert.pfx https://dev2.dbhub.io:5550/foo
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to dev2.dbhub.io (127.0.0.1) port 5550 (#0)
* WARNING: SSL: Certificate type not set, assuming PKCS#12 format.
* SSL: Can't load the certificate "./cert.pfx" and its private key: OSStatus -50
* Closing connection 0
curl: (58) SSL: Can't load the certificate "./cert.pfx" and its private key: OSStatus -50
$ /tmp/curl/bin/curl -v --cert ./cert.pfx --key '' https://dev2.dbhub.io:5550/foo
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to dev2.dbhub.io (127.0.0.1) port 5550 (#0)
* WARNING: SSL: CURLOPT_SSLKEY is ignored by Secure Transport. The private key must be in the Keychain.
* WARNING: SSL: Certificate type not set, assuming PKCS#12 format.
* SSL: Can't load the certificate "./cert.pfx" and its private key: OSStatus -50
* Closing connection 0
curl: (58) SSL: Can't load the certificate "./cert.pfx" and its private key: OSStatus -50
$ /tmp/curl/bin/curl -v --cert ./cert.pfx --key "" https://dev2.dbhub.io:5550/foo
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to dev2.dbhub.io (127.0.0.1) port 5550 (#0)
* WARNING: SSL: CURLOPT_SSLKEY is ignored by Secure Transport. The private key must be in the Keychain.
* WARNING: SSL: Certificate type not set, assuming PKCS#12 format.
* SSL: Can't load the certificate "./cert.pfx" and its private key: OSStatus -50
* Closing connection 0
curl: (58) SSL: Can't load the certificate "./cert.pfx" and its private key: OSStatus -50

Should I still try to figure out the password ? options : NULL thing you were explaining?

Owner
jay commented Mar 6, 2017

Thanks. It's been ages since I did C dev work, so wasn't sure where to attempt the password ? options : NULL change.

I meant pass the second parameter as that. If you go to the doc for SecPKCS12Import it doesn't say whether or not that parameter is optional. So the two things I thought we could try are passing it a blank password (which doesn't work according to your error -50, which seems to mean invalid param list) or just passing it NULL for options.

Revert the earlier patch and then try this

diff --git a/lib/vtls/darwinssl.c b/lib/vtls/darwinssl.c
index 25a8ab8..dd9c3c1 100644
--- a/lib/vtls/darwinssl.c
+++ b/lib/vtls/darwinssl.c
@@ -1002,7 +1002,7 @@ static OSStatus CopyIdentityFromPKCS12File(const char *cPath,
     CFArrayRef items = NULL;
 
     /* Here we go: */
-    status = SecPKCS12Import(pkcs_data, options, &items);
+    status = SecPKCS12Import(pkcs_data, password ? options : NULL, &items);
     if(status == errSecSuccess && items && CFArrayGetCount(items)) {
       CFDictionaryRef identity_and_trust = CFArrayGetValueAtIndex(items, 0L);
       const void *temp_identity = CFDictionaryGetValue(identity_and_trust,
Owner
jay commented Mar 6, 2017

Here's another one you could try if that one gives you an error. Other than this I'm out of ideas

diff --git a/lib/vtls/darwinssl.c b/lib/vtls/darwinssl.c
index 25a8ab8..0bb0f66 100644
--- a/lib/vtls/darwinssl.c
+++ b/lib/vtls/darwinssl.c
@@ -998,7 +998,7 @@ static OSStatus CopyIdentityFromPKCS12File(const char *cPath,
     const void *cKeys[] = {kSecImportExportPassphrase};
     const void *cValues[] = {password};
     CFDictionaryRef options = CFDictionaryCreate(NULL, cKeys, cValues,
-      password ? 1L : 0L, NULL, NULL);
+      1L, NULL, NULL);
     CFArrayRef items = NULL;
 
     /* Here we go: */
Owner
jay commented Mar 6, 2017

I figured out why the first one returned bad parameter list, apparently I didn't implement it properly because CFStringRef must be passed instead of char *. So here's yet a third new patch for you to try similar to the failed one. Note all of these patches are mutually exclusive.

diff --git a/lib/vtls/darwinssl.c b/lib/vtls/darwinssl.c
index 25a8ab8..04f0322 100644
--- a/lib/vtls/darwinssl.c
+++ b/lib/vtls/darwinssl.c
@@ -1003,6 +1003,15 @@ static OSStatus CopyIdentityFromPKCS12File(const char *cPath,
 
     /* Here we go: */
     status = SecPKCS12Import(pkcs_data, options, &items);
+    /* If auth fails and there is no password then try again with an empty
+       password. Apparently Apple treats those two things differently? */
+    if((status == errSecAuthFailed || status == errSecPassphraseRequired) &&
+       !cValues[0]) {
+      CFRelease(options);
+      cValues[0] = CFStringCreateWithCString(NULL, "", kCFStringEncodingUTF8);
+      options = CFDictionaryCreate(NULL, cKeys, cValues, 1L, NULL, NULL);
+      status = SecPKCS12Import(pkcs_data, options, &items);
+    }
     if(status == errSecSuccess && items && CFArrayGetCount(items)) {
       CFDictionaryRef identity_and_trust = CFArrayGetValueAtIndex(items, 0L);
       const void *temp_identity = CFDictionaryGetValue(identity_and_trust,
justinclift commented Mar 6, 2017 edited

Thanks @jay, going through those now.

The first of the three is a no go:

$ /tmp/curl/bin/curl -v --cert ./cert.pfx https://dev2.dbhub.io:5550/foo
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to dev2.dbhub.io (127.0.0.1) port 5550 (#0)
* WARNING: SSL: Certificate type not set, assuming PKCS#12 format.
* SSL The certificate "./cert.pfx" requires a password.
* Closing connection 0
curl: (58) SSL The certificate "./cert.pfx" requires a password.
$ /tmp/curl/bin/curl -v --cert ./cert.pfx: https://dev2.dbhub.io:5550/foo
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to dev2.dbhub.io (127.0.0.1) port 5550 (#0)
* WARNING: SSL: Certificate type not set, assuming PKCS#12 format.
* SSL The certificate "./cert.pfx" requires a password.
* Closing connection 0
curl: (58) SSL The certificate "./cert.pfx" requires a password.
$ /tmp/curl/bin/curl -v --cert ./cert.pfx --key "" https://dev2.dbhub.io:5550/foo
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to dev2.dbhub.io (127.0.0.1) port 5550 (#0)
* WARNING: SSL: CURLOPT_SSLKEY is ignored by Secure Transport. The private key must be in the Keychain.
* WARNING: SSL: Certificate type not set, assuming PKCS#12 format.
* SSL The certificate "./cert.pfx" requires a password.
* Closing connection 0
curl: (58) SSL The certificate "./cert.pfx" requires a password.

And just for the heck of it, though it doesn't help either:

$ /tmp/curl/bin/curl -v --cert ./cert.pfx --pass "" https://dev2.dbhub.io:5550/foo
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to dev2.dbhub.io (127.0.0.1) port 5550 (#0)
* WARNING: SSL: Certificate type not set, assuming PKCS#12 format.
* SSL: Incorrect password for the certificate "./cert.pfx" and its private key.
* Closing connection 0
curl: (58) SSL: Incorrect password for the certificate "./cert.pfx" and its private key.

Will try the 2nd patch in a bit.

No luck with the 2nd either:

$ /tmp/curl/bin/curl -v --cert ./cert.pfx https://dev2.dbhub.io:5550/foo
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to dev2.dbhub.io (127.0.0.1) port 5550 (#0)
* WARNING: SSL: Certificate type not set, assuming PKCS#12 format.
* SSL The certificate "./cert.pfx" requires a password.
* Closing connection 0
curl: (58) SSL The certificate "./cert.pfx" requires a password.
$ /tmp/curl/bin/curl -v --cert ./cert.pfx: https://dev2.dbhub.io:5550/foo
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to dev2.dbhub.io (127.0.0.1) port 5550 (#0)
* WARNING: SSL: Certificate type not set, assuming PKCS#12 format.
* SSL The certificate "./cert.pfx" requires a password.
* Closing connection 0
curl: (58) SSL The certificate "./cert.pfx" requires a password.
$ /tmp/curl/bin/curl -v --cert ./cert.pfx --key "" https://dev2.dbhub.io:5550/foo
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to dev2.dbhub.io (127.0.0.1) port 5550 (#0)
* WARNING: SSL: CURLOPT_SSLKEY is ignored by Secure Transport. The private key must be in the Keychain.
* WARNING: SSL: Certificate type not set, assuming PKCS#12 format.
* SSL The certificate "./cert.pfx" requires a password.
* Closing connection 0
curl: (58) SSL The certificate "./cert.pfx" requires a password.
$ /tmp/curl/bin/curl -v --cert ./cert.pfx --key "abc" https://dev2.dbhub.io:5550/foo
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to dev2.dbhub.io (127.0.0.1) port 5550 (#0)
* WARNING: SSL: CURLOPT_SSLKEY is ignored by Secure Transport. The private key must be in the Keychain.
* WARNING: SSL: Certificate type not set, assuming PKCS#12 format.
* SSL The certificate "./cert.pfx" requires a password.
* Closing connection 0
curl: (58) SSL The certificate "./cert.pfx" requires a password.

Trying it with an incorrect password, just to see what happens:

$ /tmp/curl/bin/curl -v --cert ./cert.pfx:abc123 https://dev2.dbhub.io:5550/foo
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to dev2.dbhub.io (127.0.0.1) port 5550 (#0)
* WARNING: SSL: Certificate type not set, assuming PKCS#12 format.
* SSL: Incorrect password for the certificate "./cert.pfx" and its private key.
* Closing connection 0
curl: (58) SSL: Incorrect password for the certificate "./cert.pfx" and its private key.

Correct failure. 😉

And also:

$ /tmp/curl/bin/curl -v --cert ./cert.pfx --pass "" https://dev2.dbhub.io:5550/foo
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to dev2.dbhub.io (127.0.0.1) port 5550 (#0)
* WARNING: SSL: Certificate type not set, assuming PKCS#12 format.
* SSL: Incorrect password for the certificate "./cert.pfx" and its private key.
* Closing connection 0
curl: (58) SSL: Incorrect password for the certificate "./cert.pfx" and its private key.

Trying the 3rd patch next.

And no joy there either. 🤕

$ /tmp/curl/bin/curl -v --cert ./cert.pfx --pass "" https://dev2.dbhub.io:5550/foo
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to dev2.dbhub.io (127.0.0.1) port 5550 (#0)
* WARNING: SSL: Certificate type not set, assuming PKCS#12 format.
* SSL: Incorrect password for the certificate "./cert.pfx" and its private key.
* Closing connection 0
curl: (58) SSL: Incorrect password for the certificate "./cert.pfx" and its private key.
$ /tmp/curl/bin/curl -v --cert ./cert.pfx  https://dev2.dbhub.io:5550/foo
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to dev2.dbhub.io (127.0.0.1) port 5550 (#0)
* WARNING: SSL: Certificate type not set, assuming PKCS#12 format.
* SSL: Incorrect password for the certificate "./cert.pfx" and its private key.
* Closing connection 0
curl: (58) SSL: Incorrect password for the certificate "./cert.pfx" and its private key.
$ /tmp/curl/bin/curl -v --cert ./cert.pfx:  https://dev2.dbhub.io:5550/foo
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to dev2.dbhub.io (127.0.0.1) port 5550 (#0)
* WARNING: SSL: Certificate type not set, assuming PKCS#12 format.
* SSL: Incorrect password for the certificate "./cert.pfx" and its private key.
* Closing connection 0
curl: (58) SSL: Incorrect password for the certificate "./cert.pfx" and its private key.
$ /tmp/curl/bin/curl -v --cert ./cert.pfx --key ""  https://dev2.dbhub.io:5550/foo
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to dev2.dbhub.io (127.0.0.1) port 5550 (#0)
* WARNING: SSL: CURLOPT_SSLKEY is ignored by Secure Transport. The private key must be in the Keychain.
* WARNING: SSL: Certificate type not set, assuming PKCS#12 format.
* SSL: Incorrect password for the certificate "./cert.pfx" and its private key.
* Closing connection 0
curl: (58) SSL: Incorrect password for the certificate "./cert.pfx" and its private key.
$ /tmp/curl/bin/curl -v --cert ./cert.pfx:""  https://dev2.dbhub.io:5550/foo
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to dev2.dbhub.io (127.0.0.1) port 5550 (#0)
* WARNING: SSL: Certificate type not set, assuming PKCS#12 format.
* SSL: Incorrect password for the certificate "./cert.pfx" and its private key.
* Closing connection 0
curl: (58) SSL: Incorrect password for the certificate "./cert.pfx" and its private key.

I'll just use curl with OpenSSL compiled in, instead of Apple's (at present crappy) "Secure"Transport. That's been working fine earlier today with certs in PEM format instead. 😄

@jay Thank you very much for putting in this level of effort. It's hugely helpful to have people around doing that. 😄

justinclift commented Mar 6, 2017 edited

As a data point, looking through opensource.apple.com, the closest stuff I can find to being the "Secure"Transport code is this:

    https://opensource.apple.com/source/Security/Security-57740.31.2/

Anyone know if the "Secure"Transport code is open sourced (eg possible to peer review), or if it's relying on security by obscurity?

Owner
jay commented Mar 6, 2017

Thank you very much for putting in this level of effort.

No problem, thank you for testing.

Apparently this is a known issue. I found this:
SecPKCS12Import always fails with errSecPkcs12VerifyFailure if no password is set
http://www.openradar.me/22909471
Marked as a dupe of bug 12503102, but I don't have access to the rdar system to determine what is happening with that.

Interesting, thanks. 😄

Close this issue now, as it not really a curl problem.

@justinclift justinclift closed this Mar 6, 2017
Collaborator
nickzman commented Mar 6, 2017

I figured that had to be Apple's bug, not ours.

And yes, Secure Transport is open source and part of the Security framework on all Apple operating systems. That was how the infamous "goto fail" bug was found a while back.

justinclift commented Mar 7, 2017 edited

Thanks @nickzman.

As a data point for anyone interested, this seem to be the PKCS#12 importing code:

    https://opensource.apple.com/source/Security/Security-57740.31.2/SecurityTool/keychain_import.c.auto.html

@jay jay added a commit that referenced this issue Mar 7, 2017
@jay jay KNOWN_BUGS: Add DarwinSSL won't import PKCS#12 without a password
Bug: #1308
Reported-by: Justin Clift
f023f25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment