Paypal Access - SSL certificate: unable to get local issuer certificate - php

I'm working with cUrl and PHP to make a request to a server (for paypal access)
Paypal developer website does never mention that an SSL certificate is required to use PayPal access API, however the code that I use to request the token is the following:
$options = array(
CURLOPT_URL => $url,
CURLOPT_POST => 1,
CURLOPT_VERBOSE => 1,
CURLOPT_POSTFIELDS => $postvals,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_SSLVERSION => 3
);
curl_setopt_array($ch, $options);
$response = curl_exec($ch);
echo curl_error($ch);
This echo outputs the following error:
SSL certificate problem: unable to get local issuer certificate
My questions are:
1) do I need SSL to use paypal access if I need only to get the user email?
2) if I do not need SSL why this error occours?
PS: the endpoint is the following: https://www.sandbox.paypal.com/webapps/auth/protocol/openidconnect/v1/tokenservice

The correct solution is to fix your PHP setup.. setting CURLOPT_SSL_VERIFYPEER to false is a quick hack, but it's wrong as you disable the certificate validation by it's certificate authority. This exposes you to a man-in-the-middle attack.
It's easy to fix (php 5.3.7 or higher) -
Download a list file with an up-to-date certificate authorities, and add this setting to your php.ini
curl.cainfo=<path-to>cacert.pem
Restart your web server, and it'll work !

You may disable SSL verification (which is enabled by default as of cURL 7.10), by adding this:
CURLOPT_SSL_VERIFYPEER, false
to your $options, however the proper way is to keep validation enabled.
SECURITY NOTICE
If remote site uses certificate issued by known CA but validation still fails, then most likely certificate is incorrectly set up on the remote server (lack of intermediate certificates etc.). Alternatively your system got no idea about used Certificate Authority that signed target's certificate. In such case yo should use php.ini's curl.cainfo (documentation) to point to valid PEM file with all supported CAs - that would make your setup properly validate issuer chain.
Please be aware that by setting CURLOPT_SSL_VERIFYPEER to false you are NOT solving the issue! You are working it around. This is all about security so it's fine to do that for a while, but deploying that on production is not wise, politely speaking, as you will become open to Man In The Middle Attack. You have been warned.

I had the same exact problem
Can't connect to PayPal to validate IPN message: SSL certificate: unable to get local issuer certificate
I used the code samples generated on paypal's github found here (I used PHP): https://github.com/paypal/ipn-code-samples
I downloaded both certs and tried testing both from curl: http://curl.haxx.se/docs/caextract.html
After about 2 hours of testing (using paypal's ipn simulator) and googling, found that paypal ipn cannot be tested on localhost, so i pushed the code live and tried testing, but still got the same error (even with permissions set to 777).
When I set CURLOPT_SSL_VERIFYPEER, false, it worked but this would defeat the purpose of having an ssl certificate.
After snooping around on my server's files, I found a curl-ca-bundle.crt file in my PHP folder. I decided to hardcode the CURLOPT_CAINFO in my paypal ipn script to that path. It finally worked!
I noticed this older .crt file included some certificates that weren't on the latest .crt file from the curl website. It was a bunch of certificates from verisign class 1, verisign class 2, verisign class 3 and verisign class 4.
Here's the complete list of the certificate names I added to curl's .crt file:
Verisign Class 1 Public Primary Certification Authority
Verisign Class 1 Public Primary Certification Authority - G2
Verisign Class 1 Public Primary Certification Authority - G3
Verisign Class 2 Public Primary Certification Authority - G2
Verisign Class 2 Public Primary Certification Authority - G3
Verisign Class 3 Public Primary Certification Authority
Verisign Class 4 Public Primary Certification Authority - G2
This may have something to do with what #Andomar was saying - paypal's verisign certificate is not included in the default (by default I mean curl's default) list of safe certificates.
I didn't have the time to debug and figure out exactly which certificate is needed so I just included all of them.
For anyone who experiences this problem in the future, I would suggest to get the latest certs from curl and add one by one the certificates in the list above until the error is gone.
Here's a link for some of those verisign certificates (you may need to google for the others not listed): www.symantec.com/page.jsp?id=roots
Note*: To view paypal's current certificates you can run this command in terminal:
openssl s_client -connect paypal.com:443 -showcerts
If anyone has further insight to this issue, please comment as I spent hours to figure all of the above out.

SSL certificate problem: unable to get local issuer certificate
Means that cUrl doesn't trust Verisign, the certificate authority that vouches for PayPal. As Marc B comments, cUrl no longer ships with trust for any certificate authority.
You can bypass the certificate chain validation with the option:
CURLOPT_SSL_VERIFYPEER => 0
To read how to configure cUrl so that it trusts Verisign, read the cUrl documentation.

Related

Plugin WP CONTENT CRAWL - cURL error 60: SSL certificate problem: unable to get local issuer certificate

I'm trying to get the profile picture of this website but getting the error as below. I tried going to Plugins and replacing this code, but it didn't work
Link: https://vn.joboko.com/viec-lam-ky-su-he-thong-pacs-y-te-tai-ha-noi-xvi2125694
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
with
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
but still can't.
This is most likely related to the expired DST Root CA X3, which expired Sep 30 14:01:15 2021 GMT.
Libcurl is using VERIFYPEER and VERIFYHOST to ensure trust between client and server.
The DST CA Root X3 certificate is part of the "cacert-bundle".
As of today the "cacert-bundle" can be found here: https://curl.se/docs/caextract.html
as part of the bundle https://curl.se/ca/cacert.pem.
The expired certificate is:
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
44:af:b0:80:d6:a3:27:ba:89:30:39:86:2e:f8:40:6b
Signature Algorithm: sha1WithRSAEncryption
Issuer: O=Digital Signature Trust Co., CN=DST Root CA X3
Validity
Not Before: Sep 30 21:12:19 2000 GMT
Not After : Sep 30 14:01:15 2021 GMT
Subject: O=Digital Signature Trust Co., CN=DST Root CA X3
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Which is used to verify peer in libcurl calls to websites using Let's Encrypt issued certificates.
Here's a detailed solution to your problem: https://stackoverflow.com/a/69411107/1549092
Another solutions is to disable VERIFYHOST and VERIFYPEER in your curl calls using that WP code.
Before doing that there's something to be aware of:
Let's explain the comparing your SSL/TLS certificate to the verified CA Authorities and how does that affect Man-in-the-middle (MITM) attacks.
Your program could be misled into talking to another server instead. This can be achieved through several mechanisms like DNS or ARP poisoning.
The intruder can also self-sign a certificate with the same 'comon name' your program is expecting.
The communication would still be encrypted but you would be giving away your secrets to an impostor.
This kind of attack is called 'man-in-the-middle'.
Defeating the 'man-in-the-middle'
We need to verify the certificate being presented to us is good for real. We do this by comparing it against a certificate we reasonably trust.
If the remote resource is protected by a certificate issued by one of the main CA's like Verisign, GeoTrust etc., you can safely compare against Mozilla's CA certificate bundle, which you can get from http://curl.haxx.se/docs/caextract.html
CURLOPT_SSL_VERIFYHOST and CURLOPT_SSL_VERIFYPEER prevent MITM attacks
WARNING: Disabling this would prevent CURL from detecting Man-in-the-middle' attacks!
#param CURLOPT_SSL_VERIFYPEER
Check the existence of a common name in the SSL peer certificate.
Check the existence of a common name and also verify that it matches the hostname provided.
To disable set the value to false:
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
#param CURLOPT_SSL_VERIFYHOST
FALSE to stop CURL from verifying the peer's certificate.
Alternate certificates to verify against can be specified with the CURLOPT_CAINFO option or a certificate directory can be specified with the CURLOPT_CAPATH option.
CURLOPT_SSL_VERIFYHOST may also need to be TRUE or FALSE if CURLOPT_SSL_VERIFYPEER is disabled (it defaults to 2).
Setting CURLOPT_SSL_VERIFYHOST to 2 (This is the default value) will guarantee that the certificate being presented to you have a 'common name' matching the URN you are using to access the remote resource.
This is a healthy check but it doesn't guarantee your program is not being decieved.
To disable this set the value to false:
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
Doing this disables the most important part of the CURL SSL handshake for your website!
I would consider resolving this issue globally for your OS as explained here: https://stackoverflow.com/a/69411107/1549092
Check again your host/vps. I crawled it on my delicated server which in the image
Gallery Image URL Selectors
Exchange element attributes
The solution to this problem is described here in detail: https://wp-kama.com/note/error-making-request-wordpress

Transfer file from local machine to server using cURL [duplicate]

I'm working with cUrl and PHP to make a request to a server (for paypal access)
Paypal developer website does never mention that an SSL certificate is required to use PayPal access API, however the code that I use to request the token is the following:
$options = array(
CURLOPT_URL => $url,
CURLOPT_POST => 1,
CURLOPT_VERBOSE => 1,
CURLOPT_POSTFIELDS => $postvals,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_SSLVERSION => 3
);
curl_setopt_array($ch, $options);
$response = curl_exec($ch);
echo curl_error($ch);
This echo outputs the following error:
SSL certificate problem: unable to get local issuer certificate
My questions are:
1) do I need SSL to use paypal access if I need only to get the user email?
2) if I do not need SSL why this error occours?
PS: the endpoint is the following: https://www.sandbox.paypal.com/webapps/auth/protocol/openidconnect/v1/tokenservice
The correct solution is to fix your PHP setup.. setting CURLOPT_SSL_VERIFYPEER to false is a quick hack, but it's wrong as you disable the certificate validation by it's certificate authority. This exposes you to a man-in-the-middle attack.
It's easy to fix (php 5.3.7 or higher) -
Download a list file with an up-to-date certificate authorities, and add this setting to your php.ini
curl.cainfo=<path-to>cacert.pem
Restart your web server, and it'll work !
You may disable SSL verification (which is enabled by default as of cURL 7.10), by adding this:
CURLOPT_SSL_VERIFYPEER, false
to your $options, however the proper way is to keep validation enabled.
SECURITY NOTICE
If remote site uses certificate issued by known CA but validation still fails, then most likely certificate is incorrectly set up on the remote server (lack of intermediate certificates etc.). Alternatively your system got no idea about used Certificate Authority that signed target's certificate. In such case yo should use php.ini's curl.cainfo (documentation) to point to valid PEM file with all supported CAs - that would make your setup properly validate issuer chain.
Please be aware that by setting CURLOPT_SSL_VERIFYPEER to false you are NOT solving the issue! You are working it around. This is all about security so it's fine to do that for a while, but deploying that on production is not wise, politely speaking, as you will become open to Man In The Middle Attack. You have been warned.
I had the same exact problem
Can't connect to PayPal to validate IPN message: SSL certificate: unable to get local issuer certificate
I used the code samples generated on paypal's github found here (I used PHP): https://github.com/paypal/ipn-code-samples
I downloaded both certs and tried testing both from curl: http://curl.haxx.se/docs/caextract.html
After about 2 hours of testing (using paypal's ipn simulator) and googling, found that paypal ipn cannot be tested on localhost, so i pushed the code live and tried testing, but still got the same error (even with permissions set to 777).
When I set CURLOPT_SSL_VERIFYPEER, false, it worked but this would defeat the purpose of having an ssl certificate.
After snooping around on my server's files, I found a curl-ca-bundle.crt file in my PHP folder. I decided to hardcode the CURLOPT_CAINFO in my paypal ipn script to that path. It finally worked!
I noticed this older .crt file included some certificates that weren't on the latest .crt file from the curl website. It was a bunch of certificates from verisign class 1, verisign class 2, verisign class 3 and verisign class 4.
Here's the complete list of the certificate names I added to curl's .crt file:
Verisign Class 1 Public Primary Certification Authority
Verisign Class 1 Public Primary Certification Authority - G2
Verisign Class 1 Public Primary Certification Authority - G3
Verisign Class 2 Public Primary Certification Authority - G2
Verisign Class 2 Public Primary Certification Authority - G3
Verisign Class 3 Public Primary Certification Authority
Verisign Class 4 Public Primary Certification Authority - G2
This may have something to do with what #Andomar was saying - paypal's verisign certificate is not included in the default (by default I mean curl's default) list of safe certificates.
I didn't have the time to debug and figure out exactly which certificate is needed so I just included all of them.
For anyone who experiences this problem in the future, I would suggest to get the latest certs from curl and add one by one the certificates in the list above until the error is gone.
Here's a link for some of those verisign certificates (you may need to google for the others not listed): www.symantec.com/page.jsp?id=roots
Note*: To view paypal's current certificates you can run this command in terminal:
openssl s_client -connect paypal.com:443 -showcerts
If anyone has further insight to this issue, please comment as I spent hours to figure all of the above out.
SSL certificate problem: unable to get local issuer certificate
Means that cUrl doesn't trust Verisign, the certificate authority that vouches for PayPal. As Marc B comments, cUrl no longer ships with trust for any certificate authority.
You can bypass the certificate chain validation with the option:
CURLOPT_SSL_VERIFYPEER => 0
To read how to configure cUrl so that it trusts Verisign, read the cUrl documentation.

CURL: unable to get local issuer certificate [duplicate]

I'm working with cUrl and PHP to make a request to a server (for paypal access)
Paypal developer website does never mention that an SSL certificate is required to use PayPal access API, however the code that I use to request the token is the following:
$options = array(
CURLOPT_URL => $url,
CURLOPT_POST => 1,
CURLOPT_VERBOSE => 1,
CURLOPT_POSTFIELDS => $postvals,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_SSLVERSION => 3
);
curl_setopt_array($ch, $options);
$response = curl_exec($ch);
echo curl_error($ch);
This echo outputs the following error:
SSL certificate problem: unable to get local issuer certificate
My questions are:
1) do I need SSL to use paypal access if I need only to get the user email?
2) if I do not need SSL why this error occours?
PS: the endpoint is the following: https://www.sandbox.paypal.com/webapps/auth/protocol/openidconnect/v1/tokenservice
The correct solution is to fix your PHP setup.. setting CURLOPT_SSL_VERIFYPEER to false is a quick hack, but it's wrong as you disable the certificate validation by it's certificate authority. This exposes you to a man-in-the-middle attack.
It's easy to fix (php 5.3.7 or higher) -
Download a list file with an up-to-date certificate authorities, and add this setting to your php.ini
curl.cainfo=<path-to>cacert.pem
Restart your web server, and it'll work !
You may disable SSL verification (which is enabled by default as of cURL 7.10), by adding this:
CURLOPT_SSL_VERIFYPEER, false
to your $options, however the proper way is to keep validation enabled.
SECURITY NOTICE
If remote site uses certificate issued by known CA but validation still fails, then most likely certificate is incorrectly set up on the remote server (lack of intermediate certificates etc.). Alternatively your system got no idea about used Certificate Authority that signed target's certificate. In such case yo should use php.ini's curl.cainfo (documentation) to point to valid PEM file with all supported CAs - that would make your setup properly validate issuer chain.
Please be aware that by setting CURLOPT_SSL_VERIFYPEER to false you are NOT solving the issue! You are working it around. This is all about security so it's fine to do that for a while, but deploying that on production is not wise, politely speaking, as you will become open to Man In The Middle Attack. You have been warned.
I had the same exact problem
Can't connect to PayPal to validate IPN message: SSL certificate: unable to get local issuer certificate
I used the code samples generated on paypal's github found here (I used PHP): https://github.com/paypal/ipn-code-samples
I downloaded both certs and tried testing both from curl: http://curl.haxx.se/docs/caextract.html
After about 2 hours of testing (using paypal's ipn simulator) and googling, found that paypal ipn cannot be tested on localhost, so i pushed the code live and tried testing, but still got the same error (even with permissions set to 777).
When I set CURLOPT_SSL_VERIFYPEER, false, it worked but this would defeat the purpose of having an ssl certificate.
After snooping around on my server's files, I found a curl-ca-bundle.crt file in my PHP folder. I decided to hardcode the CURLOPT_CAINFO in my paypal ipn script to that path. It finally worked!
I noticed this older .crt file included some certificates that weren't on the latest .crt file from the curl website. It was a bunch of certificates from verisign class 1, verisign class 2, verisign class 3 and verisign class 4.
Here's the complete list of the certificate names I added to curl's .crt file:
Verisign Class 1 Public Primary Certification Authority
Verisign Class 1 Public Primary Certification Authority - G2
Verisign Class 1 Public Primary Certification Authority - G3
Verisign Class 2 Public Primary Certification Authority - G2
Verisign Class 2 Public Primary Certification Authority - G3
Verisign Class 3 Public Primary Certification Authority
Verisign Class 4 Public Primary Certification Authority - G2
This may have something to do with what #Andomar was saying - paypal's verisign certificate is not included in the default (by default I mean curl's default) list of safe certificates.
I didn't have the time to debug and figure out exactly which certificate is needed so I just included all of them.
For anyone who experiences this problem in the future, I would suggest to get the latest certs from curl and add one by one the certificates in the list above until the error is gone.
Here's a link for some of those verisign certificates (you may need to google for the others not listed): www.symantec.com/page.jsp?id=roots
Note*: To view paypal's current certificates you can run this command in terminal:
openssl s_client -connect paypal.com:443 -showcerts
If anyone has further insight to this issue, please comment as I spent hours to figure all of the above out.
SSL certificate problem: unable to get local issuer certificate
Means that cUrl doesn't trust Verisign, the certificate authority that vouches for PayPal. As Marc B comments, cUrl no longer ships with trust for any certificate authority.
You can bypass the certificate chain validation with the option:
CURLOPT_SSL_VERIFYPEER => 0
To read how to configure cUrl so that it trusts Verisign, read the cUrl documentation.

php curl post to site returns nothing [duplicate]

I'm working with cUrl and PHP to make a request to a server (for paypal access)
Paypal developer website does never mention that an SSL certificate is required to use PayPal access API, however the code that I use to request the token is the following:
$options = array(
CURLOPT_URL => $url,
CURLOPT_POST => 1,
CURLOPT_VERBOSE => 1,
CURLOPT_POSTFIELDS => $postvals,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_SSLVERSION => 3
);
curl_setopt_array($ch, $options);
$response = curl_exec($ch);
echo curl_error($ch);
This echo outputs the following error:
SSL certificate problem: unable to get local issuer certificate
My questions are:
1) do I need SSL to use paypal access if I need only to get the user email?
2) if I do not need SSL why this error occours?
PS: the endpoint is the following: https://www.sandbox.paypal.com/webapps/auth/protocol/openidconnect/v1/tokenservice
The correct solution is to fix your PHP setup.. setting CURLOPT_SSL_VERIFYPEER to false is a quick hack, but it's wrong as you disable the certificate validation by it's certificate authority. This exposes you to a man-in-the-middle attack.
It's easy to fix (php 5.3.7 or higher) -
Download a list file with an up-to-date certificate authorities, and add this setting to your php.ini
curl.cainfo=<path-to>cacert.pem
Restart your web server, and it'll work !
You may disable SSL verification (which is enabled by default as of cURL 7.10), by adding this:
CURLOPT_SSL_VERIFYPEER, false
to your $options, however the proper way is to keep validation enabled.
SECURITY NOTICE
If remote site uses certificate issued by known CA but validation still fails, then most likely certificate is incorrectly set up on the remote server (lack of intermediate certificates etc.). Alternatively your system got no idea about used Certificate Authority that signed target's certificate. In such case yo should use php.ini's curl.cainfo (documentation) to point to valid PEM file with all supported CAs - that would make your setup properly validate issuer chain.
Please be aware that by setting CURLOPT_SSL_VERIFYPEER to false you are NOT solving the issue! You are working it around. This is all about security so it's fine to do that for a while, but deploying that on production is not wise, politely speaking, as you will become open to Man In The Middle Attack. You have been warned.
I had the same exact problem
Can't connect to PayPal to validate IPN message: SSL certificate: unable to get local issuer certificate
I used the code samples generated on paypal's github found here (I used PHP): https://github.com/paypal/ipn-code-samples
I downloaded both certs and tried testing both from curl: http://curl.haxx.se/docs/caextract.html
After about 2 hours of testing (using paypal's ipn simulator) and googling, found that paypal ipn cannot be tested on localhost, so i pushed the code live and tried testing, but still got the same error (even with permissions set to 777).
When I set CURLOPT_SSL_VERIFYPEER, false, it worked but this would defeat the purpose of having an ssl certificate.
After snooping around on my server's files, I found a curl-ca-bundle.crt file in my PHP folder. I decided to hardcode the CURLOPT_CAINFO in my paypal ipn script to that path. It finally worked!
I noticed this older .crt file included some certificates that weren't on the latest .crt file from the curl website. It was a bunch of certificates from verisign class 1, verisign class 2, verisign class 3 and verisign class 4.
Here's the complete list of the certificate names I added to curl's .crt file:
Verisign Class 1 Public Primary Certification Authority
Verisign Class 1 Public Primary Certification Authority - G2
Verisign Class 1 Public Primary Certification Authority - G3
Verisign Class 2 Public Primary Certification Authority - G2
Verisign Class 2 Public Primary Certification Authority - G3
Verisign Class 3 Public Primary Certification Authority
Verisign Class 4 Public Primary Certification Authority - G2
This may have something to do with what #Andomar was saying - paypal's verisign certificate is not included in the default (by default I mean curl's default) list of safe certificates.
I didn't have the time to debug and figure out exactly which certificate is needed so I just included all of them.
For anyone who experiences this problem in the future, I would suggest to get the latest certs from curl and add one by one the certificates in the list above until the error is gone.
Here's a link for some of those verisign certificates (you may need to google for the others not listed): www.symantec.com/page.jsp?id=roots
Note*: To view paypal's current certificates you can run this command in terminal:
openssl s_client -connect paypal.com:443 -showcerts
If anyone has further insight to this issue, please comment as I spent hours to figure all of the above out.
SSL certificate problem: unable to get local issuer certificate
Means that cUrl doesn't trust Verisign, the certificate authority that vouches for PayPal. As Marc B comments, cUrl no longer ships with trust for any certificate authority.
You can bypass the certificate chain validation with the option:
CURLOPT_SSL_VERIFYPEER => 0
To read how to configure cUrl so that it trusts Verisign, read the cUrl documentation.

Google PHP API Client: CA cert error

I'm attempting to interface with the Google PHP API client and I am having issues with the certificate provided by Google:
Google error:
SSL certificate problem, verify that the CA cert is OK.
Retrying with the CA cert bundle from google-api-php-client.
PHP cURL error:
SSL certificate problem: unable to get local issuer certificate
I had no problems whatsoever on a Linux box. These errors are occuring on a Windows box.
I've tried a couple of different solutions:
https://code.google.com/
http://richardwarrender.com/
but to no avail.
PS:
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
won't be acceptable ...
Courtesy of rmckay at webaware dot com dot au:
Please everyone, stop setting CURLOPT_SSL_VERIFYPEER to false or 0. If your PHP installation doesn't have an up-to-date CA root certificate bundle, download the one at the curl website and save it on your server:
http://curl.haxx.se/docs/caextract.html
Then set a path to it in your php.ini file, e.g. on Windows:
curl.cainfo=c:\php\cacert.pem
Turning off CURLOPT_SSL_VERIFYPEER allows man in the middle (MITM) attacks, which you don't want!
\Google_Client::$io->setOptions(array(CURLOPT_SSL_VERIFYPEER => FALSE));
#sKophek is correct and I appreciate the help as I was struggling with this. For those that prefer a touch more detail, here it is: (this is true, at least, for the 0.6.x version of the google-api-php-client)
1) \google-api-php-client\src\io\Google_CurlIO.php
2)
private $curlParams = array (
...
CURLOPT_SSL_VERIFYPEER => false,
... );

Categories