It has been that situation again when I have spent a whole day trying to research and figure out the solution to a problem that has bugged me. Hopefully this will save researching time for people having the same issue.
If you, like me, are trying to get cURL, or rather, plugin such as WordPress OpenID (which uses PHP libcurl) to work with HTTPS sites that use self-signed certificates but do not wish to compromise the security by disabling CURLOPT_SSL_VERIFYPEER and/or CURLOPT_SSL_VERIFYHOST option in the code, the following might be the answer for you.
You can skip this part actually. But if you are interested in some technical details, you can continue reading. This post is written on the assumption that Ubuntu Linux is used. It should apply to other distros as well with minor differences.
When we are using cURL to retrieve a HTTPS site that is not using a CA-signed certificate, the following problem occurs. Of course, this can simply be overcome by using the -k option.
However, in the case of applications such as WordPress OpenID plugin, we have to amend the code to disable both CURLOPT_SSL_VERIFYPEER and/or CURLOPT_SSL_VERIFYHOST. Not a very good idea as this will disable verification for authentic sites as well. If we know example.selfip.com, in this case is one of our own trusted test servers, we can add its certificate to the trusted list.
Now that we know what to do, we have to find out how to do it. It took me quite a while to look for the solution as I was looking in the wrong places. WordPress OpenID and cURL documentations/forums did not point me in the right direction. I decided to take a look at the source code in cURL and discover that ultimately, the responsibility of the verification lies with OpenSSL.
Arm with this and some right keyword searching, it has led me to this HOWTO, which provided some insight on how OpenSSL recognizes certificate authorities, and an important program. Right now, we are all set to add the new certificate so that our OpenSSL can recognize the HTTPS server.
Identify which directory your OpenSSL installation uses.
List the directory contents. You should see a directory called “certs”.
drwxr-xr-x  4 root root  4096 2009-04-24 14:37 .
drwxr-xr-x 50 root root 12288 2009-04-24 17:56 ..
List the directory contents. You should see from the symlinks that the certificates are actually stored in “/usr/share/ca-certificates”.
drwxr-xr-x 2 root root  16384 2009-06-24 12:32 .
drwxr-xr-x 4 root root   4096 2009-04-24 14:39 ..
List the directory contents. As you can see, I have added “example.selfip.com.crt” here.
drwxr-xr-x 11 root root  4096 2009-06-24 15:02 .
drwxr-xr-x 98 root root  4096 2009-04-24 17:51 ..
Change to “/etc” directory and edit the file “ca-certificates.conf”.
Add “example.selfip.com.crt” to the file and save it.
# update-ca-certificates(8) will update /etc/ssl/certs by reading this file.
# This is autogenerated by dpkg-reconfigure ca-certificates.
# and files with extension '.crt' is recognized as available certs.
# line begins with # is comment.
# line begins with ! is certificate filename to be deselected.
Execute the program “update-ca-certificates –fresh”.
Note: You might like to backup /etc/ssl/certs before executing the command.
Test with curl on your target HTTPS site and it should work now.
hi, on redhat where the ca-certificates.conf file is? and wich command shall i use to update-ca-certificates -refresh?
Actually when someone doesn’t understand then its up to other viewers that they will help, so here it takes place.
how to add the support for fedora 9?
Unfortunately, I do not have Fedora installed to test it out. But the concept shouldn’t be too far apart between Ubuntu and Fedora. Probably someone in the community could help you out.
Got the same problem. Now I’m just using a different certificate instead.
Good post. Got same error while accessing the https url with curl. I used the domains certificate and it again gave same error … At last I downloaded the intermediate CA certificate and followed your instructions and it fixed the issue.
Great ! Helps a lot !
Excellent! This is not just for cURL, but if you use a self-signed certificate for any site that uploads files with flash (aaargh!!), then you need this too! I needed it for Magento stores to upload file in the administration interface.
This works for imap connection with php and a self signed certificate.
In fact it will not, as distros all use different systems for maintaining their trust stores. The system you describe is Debian’s system, which Ubuntu uses. Other Debian derivatives mostly use the same system, but non-Debian derived distros mostly do not.
On OpenSUSE – https://github.com/openSUSE/ca-certificates – I believe (going by the source) you will want to add the certificate to /etc/pki/trust/anchors and run update-ca-certificates (which, despite the identical name, is not the same as Debian’s update-ca-certificates).
On Fedora, RHEL, Arch, and derivatives / compatible distros, you will want to add the certificate to /etc/pki/ca-trust/source/anchors and run update-ca-trust (see ‘man update-ca-trust’).
Thanks for sharing. It will benefit people using other distros.
This tutorial is great, thanks.
I am really in need for support.
You should be adding the domain, and its relevant cert, you want to connect to, not example.selfip.com.
I am trying to connect https://api.royalmail.com/tracking — Should i have to use full url or simple https://api.royalmail.com ?
I believe i have to put this in my ca-certificates.conf instead of example.selfip.com.crt right?
will it become like api.royalmail.com.crt ? Please suggest.