Search code examples
phpssl-certificatewebdav

PHP webDav client gives ClientException: SSL certificate problem: unable to get local issuer certificate


I want to upload files to NextCloud via PHP on Windows 11. I do not know PHP much but I managed to install sabre/dav via composer

Then I found on the internet simple code sample to list files.

<?php

// installed via - composer require sabre/dav

include 'vendor/autoload.php';
use Sabre\DAV\Client;

$settings = array(
    'baseUri' => 'https://cd.wedos.com/remote.php/dav/files/wedos-auth-xxxxxxxx',
    'userName' => '[email protected]',
    'password' => 'myPasssword'
);

$client = new Client($settings);

// Upload a file
//$upload_result = $client->request('PUT', 'test-upload.txt', 'This will be written to the txt file');

// List a folder's contents
$folder_content = $client->propFind('path/to/folder', array(
    '{DAV:}getlastmodified',
    '{DAV:}getcontenttype',
), 1);

But I am getting this error

PHP Fatal error:  Uncaught Sabre\HTTP\ClientException: SSL certificate problem: unable to get local issuer certificate in D:\data\projects\erp\php\vendor\sabre\http\lib\Client.php:327

I searched for the solution and it seems to me that I have two options

  • Disable Certificate Validation - which is not recommended for security reasons. But I have no ideal how to do it anyaway. I would like to actually try because I am going to use webDAV server and PHP client within the same company
  • install / import certificate
    • I have no idea what certificate - from cd.wedos.com ?
    • how and to where to save / import it?

Is there someone that could help me?

UPDATE1

I ran curl -v cd.wedos.com and got these results

* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Unknown (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384 / [blank] / UNDEF
* ALPN: server accepted h2
* Server certificate:
*  subject: CN=cd.wedos.com
*  start date: Jun  1 15:19:19 2024 GMT
*  expire date: Aug 30 15:19:18 2024 GMT
*  subjectAltName: host "cd.wedos.com" matched cert's "cd.wedos.com"
*  issuer: C=US; O=Let's Encrypt; CN=R3
*  SSL certificate verify ok.
*   Certificate level 0: Public key type ? (2048/112 Bits/secBits), signed using sha256WithRSAEncryption
*   Certificate level 1: Public key type ? (2048/112 Bits/secBits), signed using sha256WithRSAEncryption
*   Certificate level 2: Public key type ? (4096/128 Bits/secBits), signed using sha256WithRSAEncryption
* old SSL session ID is stale, removing

So I guess the issue is that PHP cannot see / is not using certificates


Solution

  • As explained in this PHP.Watch article, the issue is specific to Windows. On other OSes, curl uses the system list of root certificates:

    This error is uncommon on Linux, BSD, and macOS systems, but quite common on Windows because there is no designated file to obtain the root certificates, and the PHP does not ship a root certificate list on its own.

    To make it work on Windows, you can follow the instructions contained in the "Download and maintain a cacert.pem file" section:

    1. Download the cacert.pem file

    2. Move the file to a directory accessible by PHP and the web server. For example, to C:/php/cacert.pem.

    3. Edit the php.ini file and modify the curl.cainfo entry to point to the absolute path to the cacert.pem file.

    4. Optionally, restart the Web server (such as Apache) to reload the INI file.

    For your target system, which is Debian, it should work out of the box.