Is my key really ignored in my PHP CURL SSL call?
There are several possibilities which would fit your description:
- the server does not require client certificates at all. In this case it does not matter what client certificate and key you give because it will not be used anyway.
- the real key is already contained in the PEM file you've given for the certificate
cURL requires CURLOPT_SSL_VERIFYPEER=FALSE
Thanks to Dave Chen's suggestions, I realized I must have misplaced my certificate. The problem is solved by this certificate which is provided by the cURL creator (extracted from Mozilla): https://curl.haxx.se/ca/cacert.pem
So after downloading this cacert.pem file into your project, in PHP you can now do this:
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, TRUE);
curl_setopt($ch, CURLOPT_CAINFO, "/path/to/cacert.pem");
Alternatively, this can be set globally by adding the following to your php.ini
curl.cainfo=/path/to/cacert.pem
Does turning off CURLOPT_SSL_VERIFYPEER in cURL make transmission insecure?
Yes it is insecure. If you don't check the certificate you can't be sure that the sender is truly the server you think you're talking to and it may be an impostor. A man in the middle.
Even impostors can run SSL and negotiate an encrypted connections with you. But they can (supposedly) not purchase a certificate for the forged site using the legitimate cert name.
If CURLOPT_SSL_VERIFYPEER is false, is the data transfer no longer secure?
The connection will still be SSL encrypted. You just won't be doing it on a link that uses validated-as-correct certificates. Anyone can create themselves an SSL certificate which will do perfectly acceptable encryption at whatever level your browser and the webserver support.
However, what you will get is many complaints about not being able to verify the certificate's authenticity. This is to prevent Joe M. Alicious from creating themselves a certificate claiming to be "microsoft.com" and setting up their own Windows Update host. The cert will say it's microsoft.com, but it cannot be authenticated as actually being microsoft.com, as Verisign (or whoever) did not actually issue that cert and put their own stamp of authenticity (signing the cert) on it.
_VERIFYHOST is there to check that the hostname of the URL you're connecting to (e.g. "microsoft.com") is listed within the SSL cert. With this option set to false, url/cert hostname mismatches will be ignored (say, you've got a development box at testbox.develhost.com, but are using your client's real valid 'example.com' cert).
_VERIFYPEER disables validating the entire certificate. This allows self-signed certs to work. Otherwise the SSL library will barf saying that the cert's issuer isn't valid.
But regardless of either setting, if you force through a connection, it WILL be ssl encrypted.
Is it ever safe to set CURLOPT_SSL_VERIFYPEER to FALSE? Even if you control both servers?
Is it safe to leave this set to false, because I control the traffic on both ends? In fact, do I even need an SSL cert? As long as it goes over HTTPS it's secure, right?
No. You are only safe if you not only control both ends but also everything in between. If you have a single cable between two computers and control both computers than you are probably safe. If there is any cabling, router etc which might be accessed by somebody else you are not safe anymore.
Am I in danger of a man-in-the-middle attack?
Yes, unless you can control everything in between you cannot prevent a man in the middle. And unless you validate the certificates you can neither detect nor prevent the attack.
in php, what will happen if CURLOPT_CAPATH is not set when CURLOPT_SSL_VERIFYPEER is set to true
From the documentation:
CURLOPT_CAINFO
This option is by default set to the system path where
libcurl's cacert bundle is assumed to be stored, as
established at build time.
So, if your system stores the cacert bundle in the default location, which is likely /etc/ssl/certs/, then it should find it.
Why we need CURLOPT_SSL_VERIFYPEER in windows
This cURL man page on SSL Certificates describes the process for Certificate Verification when connecting to SSL/TLS secured hosts.
The reason you are needing to set CURLOPT_SSL_VERIFYPEER
to false
on Windows is because the CA bundle it uses to verify the certificates is missing (or there is no default path compiled into cURL so you need to explicitly define it).
You can configure it in php.ini
using the curl.cainfo directive, or specify it at runtime using:
curl_setopt($curl, CURLOPT_CAFILE, 'C:/path/to/ca-bundle.crt');
If you don't have a copy, grab a recent one here.
While disabling peer verification is a workaround, this can be unsafe because you're disabling the very check that ensures you are securely communicating with the site you think you are.
Anyone can generate a self signed certificate to impersonate a domain, but browsers or clients (like cURL) will fail if the certificate can't be verified unless you ignore or bypass this check (i.e. CURLOPT_SSL_VERIFYPEER = false).
Related Topics
How to Generate Random Date Between Two Dates Using PHP
Post and Get at the Same Time in PHP
How to Concatenate Multiple Ternary Operator in PHP
Hide Shipping Methods for Specific Shipping Class in Woocommerce
Looping a Multidimensional Array in PHP
Laravel Recursive Relationships
Symfony2 and Date_Default_Timezone_Get() - It Is Not Safe to Rely on the System's Timezone Settings
Is There Garbage Collection in PHP
How Get Value for Unchecked Checkbox in Checkbox Elements When Form Posted
Generating Xml Document in PHP (Escape Characters)
PHP Memcached Fatal Error: Class 'Memcache' Not Found
How to Fetch All in Assoc Array from a Prepared Statement
How to Add a Delete Button to a PHP Form That Will Delete a Row from a MySQL Table
Selecting Multiple Array Elements
Converting Object to JSON and JSON to Object in PHP, (Library Like Gson for Java)