Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SSL certificate issue unable to get local issuer certificate

I'm trying to post data to a payment gateway API. It required post data in xml format. I have the following code:

<?php
$requestUrl = 'https://api.given.bypg'; //$block->getPaymentUrl();

$amount = 100; // $block->totalOrderAmount()*100; 

$approveUrl = $block->approveUrl();
$cancelUrl =  $block->cancelUrl();
$declineUrl = $block->declineUrl();


$merchant = 'mydomain.com'; 
//$amount = '100'; // in cents. 1$ = 100cents. 
$currency = '840'; // for dollar
$description = 'Happy customers is what we make.';
$merchantId = 'Nobel106513';
?>

<?php
echo $requestUrl;
$xml_data = '<TKKPG>
<Request>
<Operation>CreateOrder</Operation>
<Language>EN</Language>
<Order>
<OrderType>Purchase</OrderType>
<Merchant>'.$merchantId.'</Merchant>
<Amount>'.$amount.'</Amount>
<Currency>'.$currency.'</Currency>
<Description>'.$description.'</Description>
<ApproveURL>'.$approveUrl.'</ApproveURL>
<CancelURL>'.$cancelUrl.'</CancelURL>
<DeclineURL>'.$declineUrl.'</DeclineURL>
</Order>
</Request>
</TKKPG>';

$ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $requestUrl);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, 60000);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $xml_data);//My post data
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
        curl_setopt($ch, CURLOPT_CAPATH, "/etc/apache2/ssl/m4/mydomain.com.crt");
        curl_setopt($ch, CURLOPT_CAINFO, "/etc/apache2/ssl/m4/mydomain.com.crt");
        curl_setopt($ch, CURLOPT_CERTINFO, 1);

        $headers = [];
        array_push($headers, 'Content-Type: text/xml;charset=UTF-8');
        //array_push($headers, 'SoapAction: *');
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        $content = trim(curl_exec($ch));
        var_dump($content);
        var_dump(curl_getinfo($ch));
        var_dump(curl_errno($ch));
        var_dump(curl_error($ch));
        curl_close($ch);
  1. Output of var_dump($content); is empty ''.
  2. Output of var_dump(curl_getinfo($ch));.

    array (size=26)
    'url' => string 'https://api.given.bypg'
    'content_type' => null
    'http_code' => int 0
    'header_size' => int 0
    'request_size' => int 0
    'filetime' => int -1
    'ssl_verify_result' => int 1
    'redirect_count' => int 0
    'total_time' => float 0.488533
    'namelookup_time' => float 0.028558
    'connect_time' => float 0.256858
    'pretransfer_time' => float 0
    'size_upload' => float 0
    'size_download' => float 0
    'speed_download' => float 0
    'speed_upload' => float 0
    'download_content_length' => float -1
    'upload_content_length' => float -1
    'starttransfer_time' => float 0
    'redirect_time' => float 0
    'redirect_url' => string '' (length=0)
    'primary_ip' => string '91.227.244.57' (length=13)
    'certinfo' =>
    array (size=0)
    empty
    'primary_port' => int 8444
    'local_ip' => string '192.168.100.64' (length=14)
    'local_port' => int 53456

  3. Ouput of var_dump(curl_errno($ch)); : int 60

  4. Output of var_dump(curl_error($ch)); :

    string 'SSL certificate problem: unable to get local issuer certificate' (length=63) It seems like the API is returning no data as seen on curl_getinfo(). Please help me, I have seen almost every solution suggested in communities.

I have edited my php.ini file to give the path to the certificate downloaded from curl website. But this did not work as well.

like image 560
P S Avatar asked Oct 28 '22 20:10

P S


1 Answers

When you connect to the server to establish secure connection you as a client get server's certificate in the beginning of the conversation with it. This certificate and its private key are used to establish the secure connection. You client wants to ensure that the server's certificate is trusted and is not created by some man-in-the middle attacker. So your client need to have the CA certificate that signed the server certificate. The error above means that the client tried to find server's certificate issuer (or one of the issuers in the chain) and didn't find. The place it tries to find it is in the specified /etc/apache2/ssl/m4/mydomain.com.crt file. You have two options: either add CA certificate to the file or to disable server certificate verification (not secure) by setting CURLOPT_SSL_VERIFYPEER to false.

like image 126
Oleg Avatar answered Oct 31 '22 22:10

Oleg