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

Certificates using mkcet fail handshake #250

Closed
mglaman opened this issue Sep 13, 2020 · 4 comments
Closed

Certificates using mkcet fail handshake #250

mglaman opened this issue Sep 13, 2020 · 4 comments

Comments

@mglaman
Copy link

mglaman commented Sep 13, 2020

I'm using DDEV to run a local API, which leverages mkcert (https://mkcert.org/) to allow valid localhost HTTPS certificates. cURL is happy with it

curl -I https://drupex.ddev.site/                                                                                                                                                  
HTTP/2 200
server: nginx/1.17.10
date: Sun, 13 Sep 2020 17:47:39 GMT
content-type: text/html; charset=UTF-8
vary: Accept-Encoding
cache-control: must-revalidate, no-cache, private
x-drupal-dynamic-cache: MISS
x-ua-compatible: IE=edge
content-language: en
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
expires: Sun, 19 Nov 1978 05:00:00 GMT
x-generator: Drupal 8 (https://www.drupal.org)
x-drupal-cache: HIT

But I'm getting the following error when trying to connect using react/http, and I tracked the error to StreamEncryption (or so)

Connection to drupex.ddev.site:443 failed during TLS handshake: Unable to complete TLS handshake: SSL operation failed with code 1. OpenSSL Error messages: error:1416F086:SSL routines:tls_process_server_certificate:certificate verify failed

It looks like the promise fails here

            if (\feof($socket) || $error === null) {
                // EOF or failed without error => connection closed during handshake
                $d->reject(new \UnexpectedValueException(
                    'Connection lost during TLS handshake',
                    \defined('SOCKET_ECONNRESET') ? \SOCKET_ECONNRESET : 0
                ));
            } else {
                // handshake failed with error message
                $d->reject(new \UnexpectedValueException(
                    'Unable to complete TLS handshake: ' . $error
                ));
            }

mkcert installs certificate so that they're valid in the system trust store

Using the local CA at "/Users/mglaman/Library/Application Support/mkcert" ✨
The local CA is already installed in the system trust store! 👍
The local CA is already installed in the Firefox trust store! 👍
@mglaman
Copy link
Author

mglaman commented Sep 13, 2020

Okay here's the root of the error:

return $promise = $encryption->enable($connection)->then(null, function ($error) use ($connection, $uri) {

            // try to enable encryption
            return $promise = $encryption->enable($connection)->then(null, function ($error) use ($connection, $uri) {
                // establishing encryption failed => close invalid connection and return error
                $connection->close();

                throw new \RuntimeException(
                    'Connection to ' . $uri . ' failed during TLS handshake: ' . $error->getMessage(),
                    $error->getCode()
                );
            });

@mglaman
Copy link
Author

mglaman commented Sep 13, 2020

I had to update openssl.capath to include the mkcert CAROOT

@mglaman mglaman closed this as completed Sep 13, 2020
@clue
Copy link
Member

clue commented Sep 14, 2020

@mglaman Happy to hear you've got this solved already!

In case somebody else stumbles upon the same problem, can you share a short snippet of how you've updated the "openssl.capath to include the mkcert CAROOT"?

@mglaman
Copy link
Author

mglaman commented Sep 14, 2020

Ah, yes! Forgot to post the fix here.

Here's the command I used for macOS, because Homebrew installs a second version of OpenSSL it's downloaded packages use

mkdir /usr/local/etc/[email protected]/certs
ln -s "$(mkcert -CAROOT)/rootCA.pem"  /usr/local/etc/[email protected]/certs

You just need to symlink the rootCA.pem to the capath.

I did a more lengthy write up here: https://mglaman.dev/blog/php-sockets-fix-unable-complete-tls-handshake-mkcert-local-development-certificates

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

2 participants