Made to Order Software Corporation Logo

PHP e-Fax requires valid SSL certificates (failed with code 1)

As e-Fax is updating their systems further to be compliant with various security systems, some new problems may arise on your servers.

The main one is an SSL error that is quite unclear.

Warning: stream_socket_client(): SSL operation failed with code 1. OpenSSL Error messages: error:14090086:SSL routines:ssl3_get_server_certificate:certificate verify failed in /path-to-php-efax/http_request.php on line 294

As we can see, the error mentions a server certificate function and says it could not verify a certificate.

If your server is not 100% up to date with newest SSL versions or your web server / PHP does not have access to the the newest certificates, it may not be capable of finding the new versions required to connect with e-Fax servers.

What you want to do is make sure that your server is fully up to date and try again. You may have to restart your webserver or even the whole system to make sure the changes take. With Apache2 adding new certificates can be handled with a simple reload, but changing existing certificates most often require a full restart of Apache2 to make sure all the new files get reloaded and interact properly.

One way to test whether your system as a whole is up to date is to run the wget command as in:

prompt % wget
--2017-07-26 12:14:19--
Resolving (
Connecting to (||:443... connected.
HTTP request sent, awaiting response... 405 Method Not Allowed
2017-07-26 12:14:19 ERROR 405: Method Not Allowed.

Here we see a working connection. eFax tells us that we cannot access their server with a GET. However, it does not generate an SSL error. If your certificates are not properly installed, you would see an SSL error and no HTTP response (even if the response is a 4XX or 5XX answer.)

Another way to test and actually see a lot more details about the certificates is to use the openssl command line as in:

prompt % openssl s_client -connect -tls1_2

The -tls1_2 option can be used to make sure that the server supports TLS v1.2 (which is does.) To determine that it worked, you will notice that the commands "gets stuck". It is waiting for input data. That should last for a little while and then timeout.

You may also test other protocols with -ssl3, -tls1, -tls1_1. The -ssl2 command line option seems to have been disabled in my version, it may still work in yours. Note that the -ssl3 (and -ssl2) which generate an error. The prompt will come right back (no long timeout like the working encryptions.)

In the event you really cannot resolve the certificate problem you can use a totally unsecure method which says to use the encryption offered, but ignore the potential for the destination to be lying about its name. This is done by setting the following options to the stream context:

    $context_options = array(
        'ssl' => array(
            'verify_peer' => false,
            'verify_name' => false,

    $context = stream_context_create($context_options);

As we can see, the options are "verify_peer" and "verify_name". Both are true by default. By turning them to false, the connection remains encrypted but it ignores errors where the SSL certificate says A and the server is B. This is not a good idea unless you are testing with your own servers and a self signed certificate (which cannot be verified with the root.)

Although note that it is now possible to get a free certificate for any server and those are automatically working (they are registered in the root.) This means anyone can have encryption, not that their server is secure... On a Linux server, it is very easy to create a set of certificate for a website:

sudo certbot --apache certonly -d \
                               -d \
                               -d \
                               -d \

Make sure the first entry is the name you want to use (i.e. in most cases or You can enter up to 100 sub-domains in one go (one certificate covers all of these sub-domains). You may also create just one single certificate. Note that to be able to do a redirect from an encrypted connection (HTTPS) you must have a certificate. So to redirect to, you need both to be converted by a certificate. All the sub-domains defined in one certificate can be handled by by VirtualHost in an Apache2 setup, which is quite practical.

Note: you can test this with m2osw which supports no "www", "w", "ww", "wwww" as well but all redirect to our official "www" sub-domain.

I like to use the "--apache certonly" option because that way certbot does not change my Apache2 files at all. Then I can edit them and add exactly what I need where I need it. The first time, though, you may want to avoid that option and see what happens. Then you can copy/paste the necessary SSL options to your other domains.

Another option is to edit the stream_socket_client() function and change the protocol. Our current default is "tls://...". I can be changed to "ssl://..." to accept SSLv2 and SSLv3, which we do not recommend. It can also be changed to "tlsv1.2://..." to force the use of TLS v1.2. See the PHP OpenSSL documentation for more details about the protocol.

In the http_request.php file, you will find a line that looks like this:

$s = stream_socket_client('tls://' . $server['host'] . ':' . $server['port'], $errno, $errstr, 60, STREAM_CLIENT_CONNECT, $context);

This is where you can change the protocol to your liking.

Note that using SSL means that you will eventually connect using SSLv2 or SSLv3 which are considered insecure since Poodle. Later TLS v1.0 was found to have a similar insecure protocol.

Note that since the destination server does not support SSLv2 and SSLv3, you are safe changing this option. It may make things work better.


Post new comment

The content of this field is kept private and will not be shown publicly.
This question is for testing whether you are a human visitor and to prevent automated spam submissions.