Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error OpenSSL Shutdown while in init - cURL - MSSQL #1512

Closed
AdrienHt opened this issue May 21, 2024 · 6 comments
Closed

Error OpenSSL Shutdown while in init - cURL - MSSQL #1512

AdrienHt opened this issue May 21, 2024 · 6 comments

Comments

@AdrienHt
Copy link

AdrienHt commented May 21, 2024

Environment

Php version: 8.2.19
PDO_SQLSRV: pdo_sqlsrv-5.12.0
Microsoft ODBC Driver version: 18.3.2.1-1
MS SQL Server version: 2022 lastest (docker image mcr.microsoft.com/mssql/server:2022-latest)
Ubuntu via Docker for Mac: Ubuntu 22.04.4 LTS (Jammy Jellyfish)
OpenSSL version: OpenSSL 1.1.1f 31 Mar 2020

Problem description

The following code:

<?php

$pdo = new \PDO('sqlsrv:server=tcp:' . getenv('SQL_HOST') . ',1433 ; Database = ' . getenv('SQL_DATABASE') . ';TrustServerCertificate=yes;', getenv('SQL_USERNAME'), getenv('SQL_PASSWORD'));

$pdo->beginTransaction();

$curlResource = curl_init();

$curlOptions = [
    CURLOPT_SSL_VERIFYPEER => true,
    CURLOPT_CAPATH => '/data/ca',
    CURLOPT_CAINFO => '/data/ca/serverCa.pem',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_URL => getenv('API_URL'),
];

foreach ($curlOptions as $option => $value) {
    curl_setopt($curlResource, $option, $value);
}

$responseContent = curl_exec($curlResource);
$errorNumber = curl_errno($curlResource);
$errorMessage = curl_error($curlResource);

curl_close($curlResource);

if ($errorNumber > 0) {
    echo 'Curl error: ' . $errorNumber . ' - ' . $errorMessage. "\n" ;
    $pdo->rollBack();
}

echo $responseContent;

Resulted in this output:

Curl error: 60 - SSL certificate problem: unable to get local issuer certificate

PHP Fatal error:  Uncaught PDOException: SQLSTATE[08S01]: [Microsoft][ODBC Driver 18 for SQL Server]SSL Provider: [error:140E0197:SSL routines:SSL_shutdown:shutdown while in init] in /data/test.php:30
Stack trace:
0 /data/test.php(30): PDO->rollBack()
1 {main}
  thrown in /data/test.php on line 30

But I expected no SQL error, only the cURL error :

Curl error: 60 - SSL certificate problem: unable to get local issuer certificate // no SQL error

The error only happens when the curl CA verification reports a certificate not allowed.
The error does not happen when I remove TrustServerCertificate=yes in the dsn.
The error does not happen when CURLOPT_SSL_VERIFYPEER is set to false.

It's seems that the Mssql driver call openssl function SSL_shutdown() while SSL_in_init() send true.

The SSL_in_init() seems to return true only when the curl CA verification reports a certificate not allowed.

I don't know if php curl implementation does not close the connection correctly or if the MSSQL driver should check if SSL_in_init() returns true before calling SSL_shutdown(), but there is something wrong here.
I opened an issue on PHP, but they suggested that I open an issue here (php/php-src#14230).

@v-makouz
Copy link
Contributor

It seems likely that curl also loads OpenSSL, just like the ODBC Driver and there is probably some interference there. I'm having a bit of trouble getting php-curl to work to verify, but the fact that error goes away when CURLOPT_SSL_VERIFYPEER is set to false, strongly suggests that curl's use of OpenSSL is involved. I will investigate further.

By the way, do you know which version of OpenSSL is used there?

@AdrienHt
Copy link
Author

thanks ! Yes we used OpenSSL 3.0.2 15 Mar 2022 (Library: OpenSSL 3.0.2 15 Mar 2022)

@v-makouz
Copy link
Contributor

Can you strace a successful run and the one with the error? Something like strace -o output.txt -f php file.php if it's run directly.

I can now run the repro code, but I don't get the same error, since I don't have the API URL setup that would return "certificate not allowed", if I understand the setup correctly.

@AdrienHt
Copy link
Author

The error is triggered before the API call. I got the error even when https://www.google.fr is set as the API URL. Are you sure you are using the same set up ?

@v-makouz
Copy link
Contributor

Great, thanks. I'll see what I can find in those

@absci
Copy link
Contributor

absci commented Jun 13, 2024

Hi, turns out this is a bug in libcurl. More details here. They have fixed it for curl>=8.3.0. After upgrade the driver no longer throw an error.

@absci absci closed this as completed Jun 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants