Sometimes, we are facing an issue with the error “cURL error 60: SSL certificate problem (unable to get local issuer certificate)” during curl call to third party services / websites.
This error occurs because the curl verifies and makes a secure connection request using self-signed certificate. When it does not find the valid certificate, it throws an error.
To fix this error, follow the steps below:
1. Disable CURLOPT_SSL_VERIFYPEER (verify the peer’s SSL certificate)
This option determines whether curl verifies the authenticity of the peer’s certificate. A value of 1 means curl verifies; 0 (zero) means it doesn’t.
When negotiating a TLS or SSL connection, the server sends a certificate indicating its identity. Curl verifies whether the certificate is authentic, i.e. that you can trust that the server is who the certificate says it is. This trust is based on a chain of digital signatures, rooted in certification authority (CA) certificates you supply. curl uses a default bundle of CA certificates (the path for that is determined at build time) and you can specify alternate certificates with the CURLOPT_CAINFO option or the CURLOPT_CAPATH option.
When CURLOPT_SSL_VERIFYPEER is enabled, and the verification fails to prove that the certificate is authentic, the connection fails. When the option is zero, the peer certificate verification succeeds regardless.
Authenticating the certificate is not enough to be sure about the server. You typically also want to ensure that the server is the server you mean to be talking to. Use CURLOPT_SSL_VERIFYHOST for that. The check that the host name in the certificate is valid for the host name you’re connecting to is done independently of the CURLOPT_SSL_VERIFYPEER option.
curl_setopt(CURL *handle, CURLOPT_SSL_VERIFYPEER, long verify);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
2. Disable CURLOPT_SSL_VERIFYHOST (verify the certificate’s name against host)
This option determines whether libcurl verifies that the server cert is for the server it is known as.
When negotiating TLS and SSL connections, the server sends a certificate indicating its identity.
When CURLOPT_SSL_VERIFYHOST is 2, that certificate must indicate that the server is the server to which you meant to connect, or the connection fails. Simply put, it means it has to have the same name in the certificate as is in the URL you operate against.
Curl considers the server the intended one when the Common Name field or a Subject Alternate Name field in the certificate matches the host name in the URL to which you told Curl to connect.
If verify value is set to 1:
In curl version 7.28.0 and earlier: treated as a debug option of some sorts, not supported anymore due to frequently leading to programmer mistakes.
From curl version 7.28.1 to curl version 7.65.3: setting it to 1 made curl_easy_setopt() return an error and leaving the flag untouched.
From curl version 7.66.0: treats 1 and 2 the same.
When the verify value is 0, the connection succeeds regardless of the names in the certificate. Use that ability with caution!
The default value for this option is 2.
curl_setopt(CURL *handle, CURLOPT_SSL_VERIFYHOST, long verify);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);