Korvo
Korvo

Reputation: 9744

SSL not work in PHP5.6 on Windows

I tried:

$host = 'ssl://fbcdn-sphotos-c-a.akamaihd.net';
$port = 443;

$fp = fsockopen($host, $port, $errno, $errstr, 30);

if (!$fp) {
    var_dump($errno, $errstr);
} else {
    echo 'Connected';
}

And:

$host = 'ssl://fbcdn-sphotos-c-a.akamaihd.net:443';

$fp = stream_socket_client($host, $errno, $errstr, 30);

if (!$fp) {
    var_dump($errno, $errstr);
} else {
    echo 'Connected';
}

But both returns:

int(0)
string(0) ""

As if I had not been able to connect.

Note: Strangely in php5.4 works perfectly.

Is a bug in this version of PHP?

Details:

PHP 5.4.12

Registered Stream Socket Transports: tcp, udp, ssl, sslv3, sslv2, tls

Compiler: MSVC9 (Visual C++ 2008)

Architecture: x64

Configure Command (compile):

cscript /nologo configure.js "--enable-embed" "--enable-cli-win32" "--enable-apache2-2handler" "--enable-apache2-2filter" "--enable-apache2-4handler" "--with-mysql=shared" "--with-mysqli=shared" "--enable-pdo" "--with-pdo-mysql=shared" "--with-pgsql=shared" "--with-pdo-pgsql=shared" "--with-mcrypt=static" "--with-openssl=shared" "--enable-sockets=shared" "--enable-intl=shared" "--enable-mbstring=shared" "--enable-mbregex" "--enable-exif=shared" "--with-xmlrpc=shared" "--with-xsl=shared" "--enable-solr=shared" "--enable-solr-debug" "--with-curl=shared" "--with-tidy=shared" "--with-bz2=shared" "--enable-rar=shared" "--enable-fileinfo=shared" "--with-gettext=shared" "--with-mhash" "--with-ldap=shared" "--enable-com-dotnet=shared" "--enable-soap=shared" "--enable-shmop=shared" "--with-gmp=shared" "--with-interbase=shared" "--with-pdo-firebird=shared" "--with-sqlite3=shared" "--with-pdo-sqlite=shared" "--with-pdo-odbc=shared" "--enable-dbase=shared" "--with-pdo-oci=C:\php-sdk\oracle\x64\instantclient_10_2\sdk,shared" "--with-oci8=C:\php-sdk\oracle\x64\instantclient_10_2\sdk,shared" "--with-oci8-11g=C:\php-sdk\oracle\x64\instantclient_11_2\sdk,shared" "--with-sybase-ct=shared" "--enable-couchdb=shared" "--with-couchbase=shared" "--enable-mongo=shared" "--with-imap=shared" "--enable-mailparse=shared" "--enable-pop3=shared" "--with-smtp=shared" "--with-oauth=shared" "--with-ssh2=shared" "--with-snmp=shared" "--enable-uploadprogress=shared" "--enable-http=shared" "--with-imagick=shared" "--enable-discount=shared" "--with-pdflib=shared" "--with-haru=shared" "--with-excel=shared" "--with-enchant=shared" "--enable-printer=shared" "--with-geoip=shared" "--enable-timezonedb=shared" "--with-xdebug=shared" "--enable-suhosin=shared" "--disable-optimizer-plus" "--enable-pthreads=shared" "--enable-pthreads=shared" "--enable-win32service=shared" "--with-memcached=shared" "--enable-memcache=shared" "--enable-apc=shared" "--enable-apc-srwlock-native" "--enable-apc-debug" "--enable-xcache=shared" "--enable-xcache-optimizer" "--enable-xcache-coverager" "--enable-eaccelerator=shared" "--enable-varnish=shared" "--enable-ffmpeg=shared" "--disable-security-flags"

openssl

OpenSSL support: enabled

OpenSSL Library Version: OpenSSL 1.0.1c 10 May 2012

OpenSSL Header Version: OpenSSL 1.0.1e 11 Feb 2013

PHP 5.6.26

Registered Stream Socket Transports: tcp, udp, ssl, sslv3, tls, tlsv1.0, tlsv1.1, tlsv1.2

Compiler: MSVC11 (Visual C++ 2012)

Architecture: x64

Configure Command (compile):

cscript /nologo configure.js "--enable-snapshot-build" "--disable-isapi" "--enable-debug-pack" "--without-mssql" "--without-pdo-mssql" "--without-pi3web" "--with-pdo-oci=c:\php-sdk\oracle\x64\instantclient_12_1\sdk,shared" "--with-oci8-12c=c:\php-sdk\oracle\x64\instantclient_12_1\sdk,shared" "--enable-object-out-dir=../obj/" "--enable-com-dotnet=shared" "--with-mcrypt=static" "--without-analyzer" "--with-pgo"

openssl

OpenSSL support: enabled

OpenSSL Library Version: OpenSSL 1.0.1c 10 May 2012

OpenSSL Header Version: OpenSSL 1.0.1t 3 May 2016

Openssl default config: c:/openssl-1.0.1c-X64/ssl/openssl.cnf

openssl.cafile: no value

openssl.capath: no value

Upvotes: 1

Views: 5831

Answers (2)

Korvo
Korvo

Reputation: 9744

Even PHP5.5 certificates works in a way in PHP, but after the PHP5.6 that has changed, as described in: http://php.net/manual/en/migration56.openssl.php

All encrypted client streams now enable peer verification by default. By default, this will use OpenSSL's default CA bundle to verify the peer certificate. In most cases, no changes will need to be made to communicate with servers with valid SSL certificates, as distributors generally configure OpenSSL to use known good CA bundles.

The default CA bundle may be overridden on a global basis by setting either the openssl.cafile or openssl.capath configuration setting, or on a per request basis by using the cafile or capath context options.

While not recommended in general, it is possible to disable peer certificate verification for a request by setting the verify_peer context option to FALSE, and to disable peer name validation by setting the verify_peer_name context option to FALSE.

The fsockopen try resolve connection using cafile, if php.ini is not configured, this show error 0. You can try two solutions:

  1. Configure php.ini:

    You can download https://curl.haxx.se/ca/cacert.pem and configure php.ini like this:

    openssl.cafile= "‪C:\openssl\cert\cacert.pem"
    

    Maybe you need restart Apache/Ngnix

  2. Setup in execution time:

    Setup fsockopen is possible, but you can use fopen+stream_context_create, or use stream_socket_client.

    Note: sometimes the servers block functions like fopen and file_get_contents of access urls

    Example:

    <?php
    
    $opts = array(
        'ssl' => array(
            'verify_peer'   => true,
            'cafile'        => 'C:/openssl/cert/cacert.pem',
            'verify_depth'  => 5,
            'CN_match'      => 'fbcdn-sphotos-c-a.akamaihd.net'
        )
    );
    
    $context = stream_context_create($opts);
    
    $host = 'ssl://fbcdn-sphotos-c-a.akamaihd.net:443';
    
    $fp = stream_socket_client($host, $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $context);
    
    if (!$fp) {
        var_dump($errno, $errstr);
    } else {
        echo 'Connected';
    }
    

    If you decide you need to disable checking for any reason, you can simply do this:

    <?php
    
    $host = 'ssl://fbcdn-sphotos-c-a.akamaihd.net';
    $port = '443';
    
    $opts = array(
        'ssl' => array(
            'verify_peer' => false
        )
    );
    
    $context = stream_context_create($opts);
    
    $host = 'ssl://fbcdn-sphotos-c-a.akamaihd.net:443';
    
    $fp = stream_socket_client($host, $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $context);
    
    if (!$fp) {
        var_dump($errno, $errstr);
    } else {
        echo 'Connected';
    }
    

Upvotes: 7

ceejayoz
ceejayoz

Reputation: 180055

http://php.net/stream_socket_client

If the value returned in errno is 0 and the function returned FALSE, it is an indication that the error occurred before the [system-level] connect() call. This is most likely due to a problem initializing the socket.

Upvotes: 0

Related Questions