# Setting ssl\_ecdh\_curve to secp384r1 does not work

**URL:** <https://www.ruby-forum.com/t/setting-ssl-ecdh-curve-to-secp384r1-does-not-work/244901>\
**Category:** NGINX\
**Created:** [July 5, 2016, 2:00pm UTC](https://www.ruby-forum.com/t/setting-ssl-ecdh-curve-to-secp384r1-does-not-work/244901 "2016-07-05T14:00:42Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Sadaf\_N](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/858c86/32.png) [@Sadaf\_N](https://www.ruby-forum.com/u/Sadaf_N)\
**Post date:** [July 5, 2016, 2:00pm UTC](https://www.ruby-forum.com/t/setting-ssl-ecdh-curve-to-secp384r1-does-not-work/244901/1 "2016-07-05T14:00:42Z")

</div>

Hi all,

I was running nginx 1.9.12 on Ubuntu 14.04 built from the source tarball  
with these options: --with-ipv6 --with-http\_ssl\_module  
–with-http\_v2\_module --with-openssl=/openssl-1.0.2g

While switching to a new server, I also wanted to switch to the nginx  
Docker container using my existing nginx config.

First, I discovered an issue with missing ALPN support due to an old  
OpenSSL version in Debian Jessie (see  
[ALPN support for HTTP/2 · Issue #76 · nginxinc/docker-nginx · GitHub](https://github.com/nginxinc/docker-nginx/issues/76) ). Therefore, I  
switched to the Alpine image and discovered another issue.

The issue seems to be related to the ssl\_ecdh\_curve setting. In my  
config I set it to secp384r1. With this setting present clients won’t  
connect. This is what curl outputs:

curl -vvvv -k “[https://localhost](https://localhost)”

- Rebuilt URL to: [https://localhost/](https://localhost/)
- Trying ::1…
- connect to ::1 port 443 failed: Connection refused
- Trying 127.0.0.1…
- Connected to localhost (127.0.0.1) port 443 (#0)
- ALPN, offering h2
- ALPN, offering http/1.1
- Cipher selection:  
ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
- successfully set certificate verify locations:
- CAfile: /usr/local/etc/openssl/cert.pem  
CApath: none
- TLSv1.2 (OUT), TLS header, Certificate Status (22):
- TLSv1.2 (OUT), TLS handshake, Client hello (1):
- TLSv1.2 (IN), TLS header, Unknown (21):
- TLSv1.2 (IN), TLS alert, Server hello (2):
- error:14077410:SSL routines:SSL23\_GET\_SERVER\_HELLO:sslv3 alert  
handshake failure
- Closing connection 0  
curl: (35) error:14077410:SSL routines:SSL23\_GET\_SERVER\_HELLO:sslv3  
alert handshake failure

When I remove ssl\_ecdh\_curve from my config or set it to auto (which is  
the default) everything works fine.

To investigate this issue further I created a virtual machine running  
Ubuntu 16.04 and installed the latest nginx from the official package  
source: [nginx: Linux packages](http://nginx.org/en/linux_packages.html) I was able to reproduce  
the exact same issue in this virtual machine.

Do you have an idea what’s going on here? Please let me know if you need  
any additional information.

Thanks!  
Florian

---

<div class="post-metadata">

**Author:** ![Florian\_Reinhart](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/4491bb/32.png) [@Florian\_Reinhart](https://www.ruby-forum.com/u/Florian_Reinhart)\
**Post date:** [July 5, 2016, 3:20pm UTC](https://www.ruby-forum.com/t/setting-ssl-ecdh-curve-to-secp384r1-does-not-work/244901/2 "2016-07-05T15:20:44Z")

</div>

Hello!

On Tue, Jul 05, 2016 at 02:00:04PM +0200, Florian Reinhart wrote:

> curl -vvvv -k “[https://localhost](https://localhost)”  
> CApath: none
> 
> To investigate this issue further I created a virtual machine running Ubuntu  
> 16.04 and installed the latest nginx from the official package source:  
> [nginx: Linux packages](http://nginx.org/en/linux_packages.html) I was able to reproduce the exact same  
> issue in this virtual machine.
> 
> Do you have an idea what’s going on here? Please let me know if you need any  
> additional information.

It looks like the client doesn’t support the curve you’ve  
configured, and non-ECDH ciphers are disabled.

–  
Maxim D.

> **[nginx](http://nginx.org/)**

---

<div class="post-metadata">

**Author:** ![Florian\_Reinhart](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/4491bb/32.png) [@Florian\_Reinhart](https://www.ruby-forum.com/u/Florian_Reinhart)\
**Post date:** [July 5, 2016, 4:02pm UTC](https://www.ruby-forum.com/t/setting-ssl-ecdh-curve-to-secp384r1-does-not-work/244901/3 "2016-07-05T16:02:47Z")

</div>

Hi Maxim!

That’s what I thought. However, all clients can access the nginx server  
on the old Ubuntu 14.04 server, which uses the same config,

I tested the following clients on OS X 10.11.5, all failed to connect:

curl, installed from Homebrew: curl 7.49.1 (x86\_64-apple-darwin15.5.0)  
libcurl/7.49.1 OpenSSL/1.0.2h zlib/1.2.5 nghttp2/1.12.0  
Safari 9.1.1 (11601.6.17)  
Chrome 51.0.2704.106  
Firefox 47.0.1

That’s why I don’t think it is a client issue.

Best,  
Florian

---

<div class="post-metadata">

**Author:** ![Florian\_Reinhart](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/4491bb/32.png) [@Florian\_Reinhart](https://www.ruby-forum.com/u/Florian_Reinhart)\
**Post date:** [July 5, 2016, 4:40pm UTC](https://www.ruby-forum.com/t/setting-ssl-ecdh-curve-to-secp384r1-does-not-work/244901/4 "2016-07-05T16:40:11Z")

</div>

Hello!

On Tue, Jul 05, 2016 at 04:02:21PM +0200, Florian Reinhart wrote:

> That’s why I don’t think it is a client issue.

Yes, at least browsers are expected to support secp384r1, so it’s  
probably something different.

Which certificate do you use? Is it the same as on the old  
server? Such a situation can easily happen if the only  
certificate available is ECDSA one and uses, e.g., prime256v1 (not  
secp384r1), but only secp384r1 is enabled by the configuration.

Looking into nginx error logs might also somewhat help to diagnose  
what goes on here.

–  
Maxim D.

> **[nginx](http://nginx.org/)**

---

<div class="post-metadata">

**Author:** ![Florian\_Reinhart](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/4491bb/32.png) [@Florian\_Reinhart](https://www.ruby-forum.com/u/Florian_Reinhart)\
**Post date:** [July 5, 2016, 5:02pm UTC](https://www.ruby-forum.com/t/setting-ssl-ecdh-curve-to-secp384r1-does-not-work/244901/5 "2016-07-05T17:02:23Z")

</div>

Thanks a lot for your suggestions.

It is the same certificate on both servers and it is indeed a secp256r1  
aka prime256v1 certificate. So does this mean, I have to use prime256v1  
for ssl\_ecdh\_curve with this certificate? It’s still strange that it  
used to work before…

Here is what the error log says:  
2016/07/05 16:57:09 [info] 2525#2525: \*115 SSL\_do\_handshake() failed  
(SSL: error:1408A0C1:SSL routines:ssl3\_get\_client\_hello:no shared  
cipher) while SSL handshaking, client: 192.168.241.1, server:  
0.0.0.0:443

Thanks again!

---

<div class="post-metadata">

**Author:** ![Florian\_Reinhart](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/4491bb/32.png) [@Florian\_Reinhart](https://www.ruby-forum.com/u/Florian_Reinhart)\
**Post date:** [July 5, 2016, 8:16pm UTC](https://www.ruby-forum.com/t/setting-ssl-ecdh-curve-to-secp384r1-does-not-work/244901/6 "2016-07-05T20:16:55Z")

</div>

Hello!

On Tue, Jul 05, 2016 at 05:02:07PM +0200, Florian Reinhart wrote:

> It is the same certificate on both servers and it is indeed a  
> secp256r1 aka prime256v1 certificate. So does this mean, I have  
> to use prime256v1 for ssl\_ecdh\_curve with this certificate? It’s  
> still strange that it used to work before…

Since version 1.11.0 nginx uses the new SSL\_CTX\_set1\_curves\_list()  
interface if available to configure supported curves, instead of  
previously used EC\_KEY\_new\_by\_curve\_name()/SSL\_CTX\_set\_tmp\_ecdh().  
This new interface is generally better as it allows configuring  
multiple curves.

I’ve just tested, and it looks like this new interface is also  
more strict. With previous interface it was possible to use any  
certificate regardless of the ssl\_ecdh\_curve setting, and that’s  
why it worked for you in older versions. The new interface does  
not allow to use curves which are not listed at all, including  
certificates using these curves.

Solution would be to list all curves you want to use, including  
curves used by certificates, e.g.:

```
ssl_ecdh_curve secp384r1:prime256v1;

```

Or, better yet, just leave the default (“auto”), it will allow  
most common curves as supported by OpenSSL.

–  
Maxim D.

> **[nginx](http://nginx.org/)**

---

<div class="post-metadata">

**Author:** ![Florian\_Reinhart](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/4491bb/32.png) [@Florian\_Reinhart](https://www.ruby-forum.com/u/Florian_Reinhart)\
**Post date:** [July 6, 2016, 11:33am UTC](https://www.ruby-forum.com/t/setting-ssl-ecdh-curve-to-secp384r1-does-not-work/244901/7 "2016-07-06T11:33:36Z")

</div>

Hello,

The following are in auto:

secp256r1  
secp521r1  
brainpool512r1  
brainpoolP384r1  
secp384r1  
brainpoolP256r1  
secp256k1  
If not configured with OPENSSL\_NO\_EC2M  
sect571r1  
sect571k1  
sect409k1  
sect409r1  
sect283k1  
sect283r1  
#endif

From OpenSSL source:

> <https://github.com/openssl/openssl/blob/OpenSSL_1_0_2-stable/ssl/t1_lib.c#L266>

Kurt C.  
[https://www.x64architecture.com](https://www.x64architecture.com)

---

<div class="post-metadata">

**Author:** ![Florian\_Reinhart](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/4491bb/32.png) [@Florian\_Reinhart](https://www.ruby-forum.com/u/Florian_Reinhart)\
**Post date:** [July 6, 2016, 9:16am UTC](https://www.ruby-forum.com/t/setting-ssl-ecdh-curve-to-secp384r1-does-not-work/244901/8 "2016-07-06T09:16:19Z")

</div>

Hi Maxim!

Thanks for investigating this! I thought ssl\_ecdh\_curve was only used to  
specific curves for ECDHE.

Is there any way to know what curves “auto” will include on my system?

—Florian

---

<div class="post-metadata">

**Author:** ![Florian\_Reinhart](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/4491bb/32.png) [@Florian\_Reinhart](https://www.ruby-forum.com/u/Florian_Reinhart)\
**Post date:** [July 6, 2016, 6:08pm UTC](https://www.ruby-forum.com/t/setting-ssl-ecdh-curve-to-secp384r1-does-not-work/244901/9 "2016-07-06T18:08:30Z")

</div>

Hello!

On Wed, Jul 06, 2016 at 09:15:59AM +0200, Florian Reinhart wrote:

> Is there any way to know what curves “auto” will include on my  
> system?

This is not currently possible, AFAIK, and depends on the OpenSSL  
library used. Here is a short summary for varions OpenSSL version  
I’ve previously looked into:

- OpenSSL 1.0.2, 1.0.2a: all curves supported, strongest first.  
Full list is available via “openssl ecparam -list\_curves”.

- OpenSSL 1.0.2b … 1.0.2h: limited default list with at least  
256 bits, prime256v1 (aka P-256) first. List in OpenSSL 1.0.2g  
is as follows:

- Upcoming OpenSSL 1.1.0 uses X25519:P-256:P-521:P-384 (aka  
X25519:secp256r1:secp521r1:secp384r1).

–  
Maxim D.

> **[nginx](http://nginx.org/)**
