openssl / openssl

TLS/SSL and crypto library

Home Page:https://www.openssl.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

OpenSSL 1.1.0 s_server doesn't work with secp384r1 and secp521r1

mildas opened this issue · comments

As the title says, 1.1.0 s_server is not working with secp384r1 and secp521r1, but at 1.0.2a it is ok.
I tried OpenSSL 1.1.0 and OpenSSL 1.0.2a with curves from ecparam -list_curves and these 2 curves differs.

OpenSSL 1.0.2a s_client and s_server - both curves are ok

OpenSSL 1.1.0 s_server:

error:1417A0C1:SSL routines:tls_post_process_client_hello:no shared
cipher:ssl/statem/statem_srvr.c:1422

then OpenSSL 1.1.0 s_client:

error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake
failure:ssl/record/rec_layer_s3.c:1382:SSL alert number 40

Keys and certs generated by:

openssl ecparam -genkey -name prime256v1 -out ca.key
openssl req -x509 -batch -new -key ca.key -out ca.cert -subj '/CN=ca'

for t in server client; do
          openssl ecparam -genkey -name prime256v1 -out $t.key
          openssl req -batch -new -key $t.key -out $t.csr -subj "/CN=$t"
          openssl x509 -req -CAkey ca.key -CA ca.cert -CAcreateserial
-in $t.csr -out $t.cert
          rm -f $t.csr
done

s_server command:

openssl s_server -key server.key -cert server.cert -CAfile ca.cert
-sigalgs ECDSA+SHA384:ECDSA+SHA256 -Verify 1 -named_curve secp384r1

s_client command:

openssl s_client -connect localhost:4433 -cert client.cert -key
client.key -CAfile ca.cert -tls1_2 -sigalgs ECDSA+SHA384:ECDSA+SHA256

Yes, @vdukhovni independently discovered this same issue recently. The problem is that in 1.1.0 the supported curves affect both ECDHE and ECDSA. They should really be independent of each other. This means you can't use a different curve in your ECDSA certificate to the curve used for ECDHE.

Ping @vdukhovni and @snhenson, how do we progress this?

The correct approach is outlined in the TLS 1.3 draft. We need to choose a certificate that matches a client supported signature algorithm if possible, but otherwise go with some default certificate.

What this means for OpenSSL is that the server's ECDHE curve list SHOULD NOT be used to constrain the server's certificate. While we must choose the ECDHE curve based on the intersection of the server and client supported curves list, the server certificate need only appear on the client curve list, and the server curve list should be ignored in this context. In addition if the only EC certificate uses a curve that is not on the client's supported curves list, and we have no alternative (RSA or DSA) certificate to choose from, we just go with the certificate we have, and leave its ultimate suitability up to the client.

Actually the supported curves list affects ECDH and ECDSA in both 1.1.0 and 1.0.2. The difference is that the -named_curve option works by changing the list of server supported curves in 1.1.0: it didn't in 1.0.2.

Sure, so we may also need to fine-tune 1.0.2 at some point, with the 1.1.0 situation being a bit more "urgent" as it is not backwards-compatible. Are you willing to take this on, or will it have to wait for me to find the time?

I would like to use ECDHE with the secp384r1 curve to adhere to NSA's suite B, is there a workaround at the moment?

commented

Did you come up with a plan how to fix this issue? haproxy is a nice tool to trigger this issue.

@darix LibreSSL?

My focus area is chain verification, which is rather separate from SSL protocol cipher selection, ... I hope that @mattcaswell will take a look at this, and decouple the certificate from supported curves...

My focus area is chain verification, which is rather separate from SSL protocol cipher selection, ... I hope that @mattcaswell will take a look at this, and decouple the certificate from supported curves...

Such as PR #5601?

That only fixes master though. A different fix would probably be needed for 1.1.0. Do we want that?

I think official fix would be very welcome for distributions and other users that will remain on 1.1.0 branch for a while. Some cannot immediately move to 1.1.1

I still seem to be suffering from this issue when using a TLS openvpn server that uses ECDSA certs signed using the brainpoolP384r1 curve. The server, using openssl 1.1.0h, starts ok, but when a client, also using 1.1.0h, tries to connect the connection fails. A client using 1.0.2o connects fine. Using certs signed using secp384r1 means the client using 1.1.0h can then connect.

I still seem to be suffering from this issue when using a TLS openvpn server that uses ECDSA certs signed using the brainpoolP384r1 curve. The server, using openssl 1.1.0h, starts ok, but when a client, also using 1.1.0h, tries to connect the connection fails. A client using 1.0.2o connects fine. Using certs signed using secp384r1 means the client using 1.1.0h can then connect.

Sounds like a different issue. An OpenSSL client in 1.1.0 does not send the brainpool curves in its default supported groups list. It used to in OpenSSL 1.0.2. That's a deliberate policy change. You can customise that using SSL_CTX_set1_curves_list() or SSL_set1_curves_list() on the client side.

Oh ok, apologies if this is the wrong place. I was just following the chain of github issues with openvpn that seemed to lead here.

I did actually add SSL_CTX_set1_curves_list(ctx->ctx, "brainpoolP384r1"); to src/openvpn/ssl_openssl.c before compiling, as I had read that that would fix this issue, but that was on the server side. I'll try adding to client and see if that helps. Thanks

@eccgecko what you're experiencing sounds like #2237