Unable to use libcurl to access a site requiring client authentication - authentication

I’m using the below snipped for setting the certificate and key for client authentication.
curl_easy_setopt(curl,CURLOPT_SSLCERT,"clientCert.pem");
curl_easy_setopt(curl,CURLOPT_SSLCERTPASSWD,"changeit");
curl_easy_setopt(curl,CURLOPT_SSLCERTTYPE,"PEM");
curl_easy_setopt(curl,CURLOPT_SSLKEY,"privateKey.pem");
curl_easy_setopt(curl,CURLOPT_SSLKEYPASSWD,"changeit");
curl_easy_setopt(curl,CURLOPT_SSLKEYTYPE,"PEM");
The certificate doesn’t have a password, I don’t know why on earth the option SSLCERTPASSWD exists, I just provided a dummy value.
When I run the program on Linux I get an error code of 58 and an error message
unable to set private key file: 'privateKey.pem' type PEM
On Windows however I get
unable to use client certificate (no key found or wrong pass phrase?)
It seems to suggest the certificate and the key don’t match but I don’t know how. I have extracted both the cert and the key from a p12 file using openssl commands.
The command I used to extract the key is
openssl.exe pkcs12 -in client.p12 -nocerts -out privateKey.pem
and the command used to extract the cert is
openssl.exe pkcs12 -in client.p12 -nokeys -out clientCert.pem
The p12 file has been successfully used in a browser to access the client authentication url.
Please help before I shoot myself.
Edit:
Here is proof that the private key and the certificate correspond to each other:
[debugbld#nagara ~/curlm]$ openssl x509 -noout -modulus -in clientCert.pem | openssl md5
d7207cf82b771251471672dd54c59927
[debugbld#nagara ~/curlm]$ openssl rsa -noout -modulus -in privateKey.pem | openssl md5
Enter pass phrase for privateKey.pem:
d7207cf82b771251471672dd54c59927
So why can’t it work?

Using the command line curl, I've got the same error using a .pem file that was also obtained with openssl from a p12 file, The p12 was also able to working properly doing client authentication when imported in a browser. Just like you described, I think.
My problem was caused because the .pem file was not listing the certificates in the proper order: seems that each certificate in the file has to be followed by its issuer certificate. I edited the file and changed the order of the sections and curl was happy.
For the record, my original .p12 file was obtained by backing up a certificate from Firefox.
Also note that in my case, I was not getting prompted for the password and was getting the
curl: (58) unable to set private key file: 'alice.pem' type PEM
before the password prompt

I was facing similar issues, I found out the problem was related to file permissions of the certificate and private key files. The process running PHP did not have read access to those files.
One thing you can try (and that helped me figuring this out) is to run the following code:
$result=openssl_get_privatekey('file://path/to/private/key.pem','password');
and check if the returned value is not false and there are no errors. I was getting:
file_get_contents(/path/to/private/key.pem): failed to open stream: Permission denied

Thanks Hugh for the thread and raugfer for the openssl hint. The later: both helpful and misleading. ;-)
Actually, I solved the problem by making sure that the path of the key file is correct. And here is why the openssl hint was misleading, dispite helping me to check if my PEM file was ok:
cURL needs the complete path, but without 'file://' prefix. While fopen is happy with a relative path, cURL is not. So, all my tests to open the key file had been successful, while cURL was not.
Btw.:
curl_easy_setopt(curl,CURLOPT_SSLCERTPASSWD,"changeit");
curl_easy_setopt(curl,CURLOPT_SSLCERTTYPE,"PEM");
curl_easy_setopt(curl,CURLOPT_SSLKEYTYPE,"PEM");
are not needed, as the password is only used to decrypt the private key and PEM is the default.

Related

Enabling SSL for an MQ queue manager on the HP Nonstop

I have an existing MQ MQI connection (Server-Connection) between an HP Nonstop and a Windows server. I am working on configuring the queue manager for SSL on the Nonstop.
I have followed a couple sources available on net closely but am still confused about a few things.
The Stash.sth file, I have not gotten the following command to work:
openssl pkcs12 -export -in cert.pem -inkey server_key.pem -out personal_cert.p12 -passin pass:certkey -password pass:certkey -chain -CAfile trust.pem
I get an "Error unable to get local issuer certificate chain."
The SSLUpdate.pdf document that is delivered with MQ mentions creating the Stash.sth file using:
amqrsslc -s cert (cert being the trusted certificate store), and this DOES work for me.
However, it also says "The amqrsslc command will prompt for the private key pass phrase used when creating the certificate/key pair and will write a masked copy of that pass phrase to the Stash.sth file"
If I should have specified the same pass phrase earlier, where should I have done that?
When I created the private key? Should I have specified a -passin or -passout parameter? All I used was openssl genrsa -out privatekey.pem 2048 -sha256
Or, when I generated the certificate request? There is a prompt to enter an optional password.
Or neither? Is the pass phrase used when creating the Stash.sth file completely arbitrary?
Thanks for any help!
The error usually means the list of trusted certificates is not complete.
I think you need to be sure you certificate chain is complete.
Here is from the technote:
If the certificate request is signed by an intermediate certificate, the
certificate chain for the signed personal certificate will need to be
added to the trust.pem file. You need to add the root certificate and
the intermediate to the trust.pem file. Review create_trust_file.sh
script for the syntax.
I also think this presentation document may be helpful to you.
http://www-01.ibm.com/support/docview.wss?uid=swg27023472&aid=1

OpenSSL X509 Verify Signature with CA

I have a root certificate which I created based on a previously provided keypair (private & public). The certificate is called Root CA in file rootca.crt.
I've now been tasked with verifying a given signature with the Root CA.
I'm fairly sure this needs to be done through X509 but I'm not familiar with the command? The signature which I need to verify was supplied in Base64 and I've decoded it and converted to binary, so I believe the final step I'm missing is an OpenSSL X509 verify command, but that doesn't seem to exist?
Any advice would be appreciated, cheers.
Use the openssl verify command.
openssl verify -CAfile rootca.crt certificate
See also the verify(1) man page.

Security Certificates

I've currently encountered a unique issue. To help understand the predicament I'll provide some background. Our company hired a third-party to develop an application, apart of this web application package was the purchase of an SSL Certificate.
After they purchased the SSL they exported it into a Personal Information Exchange (.pfx).
The issue now occurs here...
Our company web-server utilizes the Plesk Panel 11. Which complicates matters for two reasons.
The first is that if I directly install the certificate Plesk will
not recgonize the certificate and will eventually overwrite the
contents in our Microsoft Certificate Store within the Windows
Server MMC Certificate Snap-In.
The second issue is sheer bad luck, Plesk doesn't recognize the .pfx extension. It apparently only understands the following:
Private Key (.key)
Certificate (.crt)
CA Certificate (-ca.crt)
So my original thought was to simply convert the file into a valid format, which resulted in an error. The second attempt was to follow a command line control to export the file format to the valid extension. The results are still disappointing:
Error: Invalid Certificate Format
Since the file installed was a .pfx it does not allow me to convert it to anything else. Unfortunately when utilizing Open SSL it only converted to a .pem. Which to my dismay is also unsupported-
Any assistance would be terrific.
Update:
I attempted to follow this question on Stack Overflow. Unfortunately Windows Server 2012 doesn't appear to do the conversion as well. It does convert it into a valid format, but then the Private Key can't be found.
In order to solve this issue I followed this blog here.
So I attempted to utilize Open SSL again, with these steps:
// Extract Private Key
openssl pkcs12 -in [yourfile.pfx] -nocerts -out [keyfile-encrypted.key]
// Extract Certificate
openssl pkcs12 -in [yourfile.pfx] -clcerts -nokeys -out [certificate.crt]
// Encrypted Private Key
openssl rsa -in [keyfile-encrypted.key] -out [keyfile-decrypted.key]
Again you need to enter an import password. This time you need to enter the new password that you created in step 1. After that you’re done. You decrypted your private key. In the folder you ran OpenSSL from you’ll find the certifcate (.crt) and the two private keys (encrypted and unencrypted).
That is how I solved my question.

C# WCF client error "The private key is not present in the X.509 certificate"

I'm am trying to create a very simple WCF client application which will send SOAP messages to a 3rd party service. All the messages must be digitally signed. It's really a proof of concept before I add the code to a larger application.
I have a .cer file containing the certificate and a .pem file containing the private key. What I have been trying to do is load the certificate using the .cer file then fire off a message. But I get the following error "The private key is not present in the X.509 certificate".
The problem, well one of the problems, is that I really know almost nothing about WCF, digital certificates, private keys and all that guff. I've done some reading, I've Googled till I'm blue in the face and I've not got anywhere.
If I open the .cert file there is a section labelled "BEGIN ENCRYPTED PRIVATE KEY" which suggests that the private key is included in the certificate. So, why am I getting a message saying that it is not present? Also, if the private key does need to be added to the certificate how do I do it?
Here basically what I'm doing. It's not my actual code, but it includes all the relevant stuff:
MyWSClient c = new MyWSClient();
c.ClientCredentials.ClientCertificate.Certificate = new X509Certificate2(#"pathToFile.cer");
c.SomeValidCall();
How are you creating this cert / key pair? You can combine them into a PKCS#12 certificate using openssl:
openssl pkcs12 -export -in yourcert.crt -inkey yourprivkey.key -out newcert.p12
You may need to play with the input format to get it to work with a .pem private key.
My colleague has found a solution. I don't know why but using a .der file rather than a .cer file solves the problem. This is the command he used to generate the .der file using a certificate, private key and root certificate as.pem files:
openssl pkcs12 -export -in cert.pem -inkey private_key.pem -certfile root_cert.cer -out pkcs12.der

"Public key certificate and private key doesn't match" when using Godaddy issued certificate [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 6 years ago.
Improve this question
I'm trying to install a GoDaddy SSL certificate on a new load balancer I'm setting up on Amazon AWS. I originally created the certificate at Godaddy using the keytool program for direct installation on a Glassfish 3.1 server (Amazon linux ami). I had no problems getting that setup directly on the server. I now need to move the certificate from the web server to the new load balancer. Amazon requires the private key and certs to be in PEM format, so I used the "rekey" tool at GoDaddy to create new certs. When I load those in the load balancer setup screen on AWS Mgmt Console, I get the error message: "Public Key Certificate and Private Key doesn't match."
Here is how I'm creating the keys:
$ openssl genrsa -des3 -out private.key 2048
$ openssl req -new -key private.key -out apps.mydomain.com.csr
I then submit the .csr file to GoDaddy during the "rekey" process. Once the rekey is complete, I download the 2 newly created certs (apps.mydomain.com.crt & gd_bundle.crt). I download them selecting (Apache) as the type of server (I've also tried "other" and "Cpanel" but the all look to be the same).
At this point, I remove the encryption from the private.key file by using the following command:
$ openssl rsa -in private.key -out private.pem
At this point, I go back into the AWS Mgmt console, create the load balancer, add the secure server redirect and put the contents of the following files in the respective fields on the screen where it asks to setup the ssl certificate:
private.pem --> Private Key
apps.mydomain.com.crt --> Public Key Certificate
gd_bundle.crt --> Certificate Chain
When I click the "continue button" I get the error "Error: Public Key Certificate and Private Key doesn't match."
-Is there a way that I can test that I'm getting a valid error message from Amazon? It seems odd to me that the keys wouldn't match when I'm following GoDaddy's instructions pretty closely.
I've tried creating the private.key file without RSA encryption prior to creating the .csr and that doesn't seem to make any difference.
I'm also assuming that the .crt files I'm downloading from GoDaddy are in .PEM format, but I'm not sure how to verify this.
Any ideas?
For me, it was an easy two-step:
Convert the private key to PEM:
openssl rsa -in yourdomain.key -outform PEM
Convert the certificate and certificate bundle to PEM:
openssl x509 -inform PEM -in yourdomain.crt
openssl x509 -inform PEM -in bundle.crt
Just for the record and anyone else who is trying to figure it out:
yourdomain.key
-> terminal command: sudo openssl rsa -in yourdomain.key -outform PEM -out yourdomain.pem
-> private key
yourdomain.crt
-> public key
gd_bundle.crt
-> certificate chain
and you're good to go :)
Looks like the issue was the way in which I was copying the contents of the key and certs into the AWS Management console. I was using an Ubuntu desktop running in Virtual Box on a Windows 7 desktop; copy and pasting the values from a gedit screen into the browser running on the Windows box. Once I opened the key and cert files on the same box as the web browser (Windows in this case) the certs went through just fine. I'm guessing some parts of the file aren't making it over correctly when using the shared clip board between Virtual Box client and host. Case closed.
We found an alternate solution to this problem. We were having the same symptoms with the same error.
Then we tried reentering the pem codes one more time, but this time we made sure to hit enter one time and make sure the cursor was on a blank line at the end of each window. Then we saved it.
IT WORKED.
This solved our problem, so it might solve it for others.
One little gotcha. I'm using a Windows box (Win 7 Pro) and when I used the windows port of OpenSSL, the outputted files had Unix style end-of-line characters (LF).
I had to convert the file to Windows style (CRLF) for the uploading of the private key.
I can suggest you with an alternative solution and an information to you folks.
Generally all certificates are of PEM file format. You can just open a notepad or any text editor and drag the files which you received in .crt file format. Which is normally called as .PEM file.If the certificate loaded in your keytool you can export the certificate as a pfx file from keytool. Then you can separate the pfx file from the private key from the pfx file. Because the pfx file is the combination of your certificate and the private key.So you can get separately the private key file and use it on your amazon aws.
I suspect there may be another way to install the certificate. May be you can contact the certificate authority and is there any way to get your certificate to be reissued.