erlang / otp

Erlang/OTP
http://erlang.org
Apache License 2.0
11.3k stars 2.94k forks source link

ERL-74: SSL crash #3302

Closed OTP-Maintainer closed 3 years ago

OTP-Maintainer commented 8 years ago

Original reporter: paul Affected version: OTP-18.0 Fixed in version: OTP-19.0 Component: ssl Migrated from: https://bugs.erlang.org/browse/ERL-74


CouchDB 1.6.1 whether installed via homebrew or via DMG, is using Erlang/OTP-18. A self-made certificate is fine for CouchDB, yet underneath it Erlang is choking on it presently. Crash report attached.

Earlier today I though this was a CouchDB issue: http://stackoverflow.com/questions/34690957/couchdb-ssl-handshake-error

But since finding the logs, I'm able to see that its an Erlang issue.
OTP-Maintainer commented 8 years ago

ingela said:

Have you verified your input using for instances openssl s_client/s_server? As the crash indicates that crypto thinks the key is somehow incorrect.
OTP-Maintainer commented 8 years ago

paul said:

Yup both are good. 

Verifying key:
{code}$ openssl rsa -in key.pem -check
    RSA key ok
    writing RSA key
    -----BEGIN RSA PRIVATE KEY-----
    .. snip ..
    -----END RSA PRIVATE KEY-----{code}

Verifying  Cert request:
{code}$ openssl req -text -noout -verify -in csr.pem 
    verify OK
    Certificate Request:
        Data:
            Version: 0 (0x0)
            Subject: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd
            Subject Public Key Info:
                Public Key Algorithm: rsaEncryption
                RSA Public Key: (2048 bit)
                    Modulus (2048 bit):
                        ... snip ....
                    Exponent: 65537 (0x10001)
            Attributes:
                a0:00
        Signature Algorithm: sha1WithRSAEncryption
            ... snip ...{code}
OTP-Maintainer commented 8 years ago

paul said:

Here's me checking Erlang SSL support:
{code:erlang}
1> ssl:versions().
[{ssl_app,"7.2"},
 {supported,['tlsv1.2','tlsv1.1',tlsv1]},
 {available,['tlsv1.2','tlsv1.1',tlsv1,sslv3]}]
{code}
OTP-Maintainer commented 8 years ago

paul said:

openssl s_client verification (as requested) - please excuse the lack of formatting below:

{code}$ openssl s_client -showcerts -connect 127.0.0.1:6984
CONNECTED(00000003)
92643:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake failure:/SourceCache/OpenSSL098/OpenSSL098-52.40.1/src/ssl/s23_lib.c:185:{code}

By contrast, a well known SSL service works fine:

{code}$ openssl s_client -showcerts -connect imap-mail.outlook.com:993
CONNECTED(00000003)
depth=1 /C=BE/O=GlobalSign nv-sa/CN=GlobalSign Organization Validation CA - SHA256 - G2
verify error:num=20:unable to get local issuer certificate
verify return:0
---
Certificate chain{code}
OTP-Maintainer commented 8 years ago

paul said:

Using an ad-hoc Python HTTPS server for the *same keys* handed to couchdb/erlang:

{code}import BaseHTTPServer, SimpleHTTPServer
import ssl
httpd = BaseHTTPServer.HTTPServer(('localhost', 4443), SimpleHTTPServer.SimpleHTTPRequestHandler)
httpd.socket = ssl.wrap_socket (httpd.socket, certfile="/path/to/couchdb.pem", server_side=True, keyfile="/path/to/privkey.pem")
httpd.serve_forever(){code}

Different terminal:

{code}$ openssl s_client -showcerts -connect localhost:4443
CONNECTED(00000003)
depth=0 /C=AU/ST=Some-State/O=Internet Widgits Pty Ltd
verify error:num=18:self signed certificate
verify return:1
depth=0 /C=AU/ST=Some-State/O=Internet Widgits Pty Ltd
verify return:1
---
Certificate chain
 0 s:/C=AU/ST=Some-State/O=Internet Widgits Pty Ltd
   i:/C=AU/ST=Some-State/O=Internet Widgits Pty Ltd
-----BEGIN CERTIFICATE-----
... snip ...
-----END CERTIFICATE-----
---
Server certificate
subject=/C=AU/ST=Some-State/O=Internet Widgits Pty Ltd
issuer=/C=AU/ST=Some-State/O=Internet Widgits Pty Ltd
---
No client certificate CA names sent
---
SSL handshake has read 728 bytes and written 264 bytes
---
New, TLSv1/SSLv3, Cipher is AES256-SHA
Server public key is 512 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1
    Cipher    : AES256-SHA
    Session-ID: 842428520424BFF145C82F7AEFCDD263FA003D4FDDB891EAC54095D2EAA8580D
    Session-ID-ctx: 
    Master-Key: blahBlahBlah
    Key-Arg   : None
    Start Time: 1452649263
    Timeout   : 300 (sec)
    Verify return code: 18 (self signed certificate)
---{code}
OTP-Maintainer commented 8 years ago

ingela said:

Humm I still do not know what is wrong with the key, it is not obvious but I am trying to look into it.

Could you try using openssl s_server as server? Then the same code as Erlang is using via crypto should be called.
OTP-Maintainer commented 8 years ago

paul said:

Doesn't the Python code (above) prove the key is OK in server-mode ?

Will report back on a 'openssl s_server as server' test.
OTP-Maintainer commented 8 years ago

paul said:

h2. openssl s_server test:

{code}$ openssl s_server -key privkey.pem -cert couchdb.pem -accept 44330 -www
Using default temp DH parameters
Using default temp ECDH parameters
ACCEPT
14438:error:140780E5:SSL routines:SSL23_READ:ssl handshake failure:/SourceCache/OpenSSL098/OpenSSL098-52.40.1/src/ssl/s23_lib.c:139:
ACCEPT
14438:error:140780E5:SSL routines:SSL23_READ:ssl handshake failure:/SourceCache/OpenSSL098/OpenSSL098-52.40.1/src/ssl/s23_lib.c:139:
ACCEPT
14438:error:140780E5:SSL routines:SSL23_READ:ssl handshake failure:/SourceCache/OpenSSL098/OpenSSL098-52.40.1/src/ssl/s23_lib.c:139:
ACCEPT
14438:error:140780E5:SSL routines:SSL23_READ:ssl handshake failure:/SourceCache/OpenSSL098/OpenSSL098-52.40.1/src/ssl/s23_lib.c:139:
ACCEPT
14438:error:140780E5:SSL routines:SSL23_READ:ssl handshake failure:/SourceCache/OpenSSL098/OpenSSL098-52.40.1/src/ssl/s23_lib.c:139:
ACCEPT{code}

I was following this article - http://blog.jorisvisscher.com/2015/07/22/create-a-simple-https-server-with-openssl-s_server/ - but with the pre-existing keys.  Browser says:

!screenshot-1.png!

Note - The ERR_SSL_WEAK_SERVER_EPHEMERAL_DH_KEY detection by chrome is not helping the believability of ERL-74 as an issue, but it is a red herring.
OTP-Maintainer commented 8 years ago

paul said:

h2. Turns out this was an openssl key-gen problem all along

openssl version 0.9.8zg (14 July 2015) can make keys that cause Erlang to barf when serving up HTTPS
openssl version 1.0.2e (3 Dec 2015) works fine, for the same sequence of key-gen

h2. To recap, key-gen was:

{code}openssl genrsa > privkey.pem
openssl req -new -x509 -key privkey.pem -out couchdb.pem -days 1095{code}

h2. versions tested

0.9.8zg is what comes from Apple for 10.10.5
1.0.2e is installable from homebrew (but you have to follow it with a 'brew link --force openssl' sometimes)

If you can reproduce what I had, it may be best to suggest to the user to update their openssl before generating keys. I mean if the applicable exception is caught in the right spot. 
OTP-Maintainer commented 8 years ago

ingela said:

I will make this a feature request to provide a better error information if possible.
OTP-Maintainer commented 8 years ago

paul said:

Thank you.
OTP-Maintainer commented 8 years ago

ingela said:

Solution to this is included in our nightly builds, should show up on master in master later this week.
OTP-Maintainer commented 8 years ago

paul said:

This one - https://github.com/erlang/otp/commit/48085e18c31bd303f07d9d75cff282361e38ca8b it looks like :)
OTP-Maintainer commented 8 years ago

ingela said:

Um no. I am refering to a commit that catches the return from public_key:sign and gives a better error message if public_key or really crypto raises a badkey error. The commit above adds an option to customize or disable Rizzo/Duong Beast countermeasure, which is also useful.