easysoft / phpmicro

micro sfx SAPI for php
Apache License 2.0
257 stars 30 forks source link

cURL error 60: SSL certificate problem #8

Open thibodelanghe opened 1 year ago

thibodelanghe commented 1 year ago

Hey! I've made an executable that does some API calls. When an endpoint is called, an error is thrown.

cURL error 60: SSL certificate problem: unable to get local issuer certificate (see https://curl.haxx.se/libcurl/c/libcurl  
  -errors.html) for .......

I suppose it has something to do with there being no ca-cert in the package. When fetching the ssl cert location for php with openssl_get_cert_locations() it states that the ssl dir is /ssl/certs but that does not exist.

[
  "default_cert_file" => "/ssl/cert.pem"
  "default_cert_file_env" => "SSL_CERT_FILE"
  "default_cert_dir" => "/ssl/certs"
  "default_cert_dir_env" => "SSL_CERT_DIR"
  "default_private_dir" => "/ssl/private"
  "default_default_cert_area" => "/ssl"
  "ini_cafile" => ""
  "ini_capath" => ""
]

Does anybody know how to add a ca cert so the bundle has it?

dixyes commented 1 year ago

You may set ini config openssl.capath to an exist ca path, see https://www.php.net/manual/en/openssl.configuration.php

or specify a ca cert used: https://stackoverflow.com/a/15362509/17803469

I think make a bundled ca cert load from memory is more safe and convenience, I will try to implement this when I have time.

dixyes commented 10 months ago

You may set ini config openssl.capath to an exist ca path, see https://www.php.net/manual/en/openssl.configuration.php

or specify a ca cert used: https://stackoverflow.com/a/15362509/17803469

I think make a bundled ca cert load from memory is more safe and convenience, I will try to implement this when I have time.

I have not made this yet, but I found that php supports load cafile from PHP stream for PHP stream (not for curl, but can do https request also), this will work for cli or micro:

Here's a demo:

<?php

// let's say you have a ca pem bundle (whatever it's self-signed or trusted) "cert.pem", you may use /etc/ssl/cert.pem for trusted

// makes a phar with the pem (run this with ini config "phar.readonly=0"

$phar = new Phar('test.phar', 0, 'test.phar');

$phar->startBuffering();
$phar->addFile("play.php");
$phar->addFile("cert.pem");
$phar->setStub($phar->createDefaultStub("play.php"));
$phar->stopBuffering();

what's in play.php :

<?php

// for php stream (like file_get_contents, fread things)
$ctx = stream_context_create(['ssl' => [
    // here we load the ca pem from the same dir, whether it's in phar or not
    'cafile' => __DIR__ . '/cert.pem'
]]);

file_get_contents("https://some.tls.site", context:$ctx);