Configuring cURL for SSL

Our site has recently switched from http to https. It has REST API calls caused by our clients, which now do not work:

cURL before SSL (works):

$ch = curl_init(); curl_setopt($ch,CURLOPT_URL,$api_call_url); curl_setopt($ch,CURLOPT_POST,1); curl_setopt($ch,CURLOPT_POSTFIELDS,$post_fields); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $result = curl_exec($ch); curl_close($ch); 

cURL after SSL (does not work):

 $ch = curl_init(); curl_setopt($ch,CURLOPT_URL,$api_call_url); curl_setopt($ch,CURLOPT_POST,1); curl_setopt($ch,CURLOPT_POSTFIELDS,$post_fields); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); curl_setopt($ch, CURLOPT_CAINFO, "/customers_path_on_their_server/to/our_cacert_they_exported_via_firefox.crt"); //X.509 Certificate $result = curl_exec($ch); curl_close($ch); 

Do I need to configure anything on our server, except to ask the client to add CURLOPT_SSL_VERIFYPEER, CURLOPT_SSL_VERIFYHOST, CURLOPT_CAINFO to my REST integration code?

I am really new to https and I don’t know what exactly is the term that I need to search, look for cURL SSL for several hours now ...

By the way, our site uses amazon ec2 hosting, if this information is important ...

Here is the cURL error returned:

  error:SSL certificate problem, verify that the CA cert is OK. Details: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed 

cURL version: 7.21.6

SSL Version: OpenSSL / 1.0.0e

+5
source share
3 answers

Do not turn off peer-to-peer testing and host checking, as others often suggest. This is an unsafe workaround to a real problem. These functions exist for a good reason: so that you can trust, through a third-party manufacturer, that the system you are connecting to is the one you expect.

First, find out if your OS contains a certificate directory. Certificate Authorities will often be included. For example, on Ubuntu it is often located in the /etc/ssl/certs , while Red Hat distributions will include it in /etc/pki/tls/certs . If this directory exists, set the CA path parameter:

 curl_setopt($ch, CURLOPT_CAPATH, '/etc/ssl/certs'); 

Alternatively, you can reference a single CA certificate file. Include the cacert.pem file in your project or install it on your server. Download from a trusted source, such as cacert.org. For a single file, do not install CAPATH, but instead install only CAINFO:

 curl_setopt($ch, CURLOPT_CAINFO, '/path/to/cacert.pem'); 
+7
source

To expand Matt's answer, the two settings cURL CURLOPT_CAPATH and CURLOPT_CAINFO perform different functions and behave completely differently.

CURLOPT_CAINFO refers to a single file, or to CURLOPT_CAINFO certificates, or, less commonly, to a single certificate. This value can (and should) be set permanently in php.ini with the curl.cainfo directive curl.cainfo .

A certificate package is simply a collection of certificates combined with an indication of which CA issues will be trusted. If you do not have it, most likely your OS provides a package that you can install. On RHEL, this can be done with yum install ca-certificates , while Debian / Ubuntu uses apt install ca-certificates . If your OS does not provide a package, cURL creators provide a link to download the package created by Mozilla.

CURLOPT_CAPATH refers to a directory containing individual certificates. The certificate in this directory can be used by cURL if the host name of your request matches the common name of the certificate. However, it is important to note that this will not happen automatically . If you set the path to CA, you must make sure that all certificates that you want to use in this directory have corresponding symbolic links (see below).


So, putting everything together, we get the following typical setup.

Point cURL to the system package constantly, using something like the following in php.ini :

 [curl] ; for RHEL curl.cainfo=/etc/pki/tls/certs/ca-bundle.crt ; for Debian/Ubuntu curl.cainfo=/etc/ssl/certs/ca-certificates.crt 

This is all you need to do to connect to public servers with certificates issued by trusted certificate authorities, that is, almost everything on the Internet. If that’s all you need, you’ve done.

In other cases, for example, when connecting to a device using a certificate issued by your company’s certification authority, make sure that you copy the corresponding certificate to the directory and correctly configure the symbolic link names:

 #!/bin/bash cd /path/to/my/certs/ for c in *.crt; do ln -s "$c" "$(openssl x509 -hash -noout -in "$c").0"; done 

Then use this cURL option to set the CA path in your code:

 <?php $ch = curl_init("https://some.device.internal"); curl_setopt($ch, CURLOPT_CAPATH, "/path/to/my/certs/"); $result = curl_init($ch); 
0
source

You need to set CURLOPT_SSL_VERIFYPEER and CURLOPT_SSL_VERIFYHOST for faslse or 0.

curl_setopt ($ ch, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt ($ ch, CURLOPT_SSL_VERIFYHOST, FALSE);

In addition, you need to make sure yu set CURLOPT_URL to 'https: // ...'

Charles

-1
source

Source: https://habr.com/ru/post/1447143/


All Articles