AWS SSL security error : [curl] 60: SSL certificate prob...: unable to get local issuer certificate

amazon-s3, amazon-web-services, curl, php, ssl

Solution

As mentioned by Jeremy Lindblom in the comments, the solution for AWS SDK v2 is to set the `ssl.certificate_authority` option when instantiating the SDK:

$aws = Aws\Common\Aws::factory(array(
    'region' => 'us-west-2',
    'ssl.certificate_authority' => '/path/to/updated/cacert.pem'
));

http://docs.aws.amazon.com/aws-sdk-php/guide/latest/faq.html#what-do-i-do-about-a-curl-ssl-certificate-error

I'll add that this was changed in the AWS SDK v3, here is the new method:

$client = new DynamoDbClient([
    'region'  => 'us-west-2',
    'version' => 'latest',
    'http'    => [
        'verify' => '/path/to/my/cert.pem'
    ]
]);

http://docs.aws.amazon.com/aws-sdk-php/v3/guide/guide/configuration.html#verify

Problem

I am trying to connect Amazon's S3 files from my (localhost) Windows 8 machine running `AppServ 2.5.10` (which includes `Apache 2.2.8`, `php 5.2.6`, `mysql 5.0.51b` and `phpMyAdmin 2.10.3`) using `Amazon SDK` for php. In order to be compatible with `Amazon SDK's` namespace feature, I replaced php with version `5.3.28` by downloading its zipped file and unzipped it. My php code works fine to access `S3` file in `Amazon EC2` but it failed in my Windows local host. However when I run the php srcipt to read `Amazon S3` bucket file in Windows local host machine, I got SSL error as following: Fatal error: Uncaught exception 'Guzzle\Http\Exception\CurlException' with message '[curl] 60: SSL certificate problem: unable to get local issuer certificate [url] https://images-st.s3.amazonaws.com/us/123977_sale_red_car.png' in C:\AppServ\www\ecity\vendor\guzzle\guzzle\src\Guzzle\Http\Curl\CurlMulti.php:342 Stack trace: #0 C:\AppServ\www\ecity\vendor\guzzle\guzzle\src\Guzzle\Http\Curl\CurlMulti.php(283): Guzzle\Http\Curl\CurlMulti->isCurlException(Object(Guzzle\Http\Message\Request), Object(Guzzle\Http\Curl\CurlHandle), Array) #1 C:\AppServ\www\ecity\vendor\guzzle\guzzle\src\Guzzle\Http\Curl\CurlMulti.php(248): Guzzle\Http\Curl\CurlMulti->processResponse(Object(Guzzle\Http\Message\Request), Object(Guzzle\Http\Curl\CurlHandle), Array) #2 C:\AppServ\www\ecity\vendor\guzzle\guzzle\src\Guzzle\Http\Curl\CurlMulti.php(231): Guzzle\Http\Curl\CurlMulti->processMessages() #3 C:\AppServ\www\ecity\vendor\guzzle\guzzle\src\Guzzle\Http\Curl\CurlMulti.php(215): Guzzle\Http\Curl\CurlMulti->executeHandles() #4 C:\AppServ\www\ecity\ven in C:\AppServ\www\ecity\vendor\aws\aws-sdk-php\src\Aws\Common\Client\AbstractClient.php on line 288 I download the certifate from http://curl.haxx.se/ca/cacert.pem and define it in php.ini as following: ``` curl.cainfo = "C:\AppServ\cacert.pem" ``` but I still got the same error. It seems php doesn't honor the `curl.cainfo` defined in `php.ini`. My php version is `5.3.28` according to `localhost/phpinfo.php`. I also checked the `cainfo` parameter to be correct as `C:\AppServ\cacert.pem` using ``` echo ini_get( "curl.cainfo" ) ; ``` in the php script. Php version higher than `5.3` shall support `curl.cainfo` in `php.ini`. In Windows' command line, I check curl behavior and it seems work fine. ``` C:\Users\Jordan>curl https://s3-us-west-2.amazonaws.com/images-st/aaa.txt curl: (60) SSL certificate problem: unable to get local issuer certificate ...... C:\Users\Jordan>curl --cacert C:\AppServ\cacert.crt https://s3-us-west-2.amazonaws.com/images-st/aaa.txt This is aaa.txt file. Stored in Amazon S3 bucket. ``` Is it because I used Apache in Windows which doesn't match php `5.3.28` zip file I downloaded from http://windows.php.net/download/ VC9 x86 Thread Safe (2014-Jun-11 01:09:56) zip version. In my apache's httpd-ssl.conf file, I have the following setting even I use from local host in Windows 8. ``` <VirtualHost _default_:443> DocumentRoot "C:/AppServ/www" ServerName localhost:443 ServerAdmin webmaster@localhost.com ErrorLog "C:/AppServ/Apache2.2/logs/error.log" TransferLog "C:/AppServ/Apache2.2/logs/access.log" SSLEngine on SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL SSLCertificateFile "C:/AppServ/Apache2.2/conf/mydomain.cert" SSLCertificateKeyFile "C:/AppServ/Apache2.2/conf/mydomain.key" <FilesMatch "\.(cgi|shtml|phtml|php)$"> SSLOptions +StdEnvVars </FilesMatch> <Directory "C:/Apache2.2/cgi-bin"> SSLOptions +StdEnvVars </Directory> BrowserMatch ".*MSIE.*" \ nokeepalive ssl-unclean-shutdown \ downgrade-1.0 force-response-1.0 CustomLog "C:/AppServ/Apache2.2/logs/ssl_request.log" \ "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b" </VirtualHost> ``` Now I am wondering what is the problem and how to connect to `Amazon S3` bucket files and `RDS` database without producing these `curl` cannot get local issuer certificate problems from my Windows 8 local host. Any advice?

Original source