7
votes
$\begingroup$

Using

openssl s_client -host myserver.net -port 443

I can see the cipher negotiated is indeed using ECDHE for session key exchange:

SSL handshake has read 5894 bytes and written 447 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES256-GCM-SHA384

Both the client and the server use exactly the same OpenSSL version "OpenSSL 1.0.1e 11 Feb 2013" and I can get the list of available, builtin curves using:

openssl ecparam -list_curves

However, how do I find out which elliptic curve is actually being used in the session?

For completeness, here are the TLS handshake messages relevant to curve negotiation from a real-world session (using the openssl command given by Thomas):

ClientHello:

>>> TLS 1.2 Handshake [length 013c], ClientHello
    01 00 01 38 03 03 52 6c 53 04 fb 32 94 d4 f4 91
    53 fe 59 5c d1 58 7f e0 67 e0 22 db da f4 8d ac
    dc 15 68 21 3d ec 00 00 a0 c0 30 c0 2c c0 28 c0
    24 c0 14 c0 0a c0 22 c0 21 00 a3 00 9f 00 6b 00
    6a 00 39 00 38 00 88 00 87 c0 32 c0 2e c0 2a c0
    26 c0 0f c0 05 00 9d 00 3d 00 35 00 84 c0 12 c0
    08 c0 1c c0 1b 00 16 00 13 c0 0d c0 03 00 0a c0
    2f c0 2b c0 27 c0 23 c0 13 c0 09 c0 1f c0 1e 00
    a2 00 9e 00 67 00 40 00 33 00 32 00 9a 00 99 00
    45 00 44 c0 31 c0 2d c0 29 c0 25 c0 0e c0 04 00
    9c 00 3c 00 2f 00 96 00 41 00 07 c0 11 c0 07 c0
    0c c0 02 00 05 00 04 00 15 00 12 00 09 00 14 00
    11 00 08 00 06 00 03 00 ff 01 00 00 6f 00 0b 00
    04 03 00 01 02[00 0a 00 34 00 32 00 0e 00 0d 00 [>>  ?
    19 00 0b 00 0c 00 18 00 09 00 0a 00 16 00 17 00
    08 00 06 00 07 00 14 00 15 00 04 00 05]00 12 00  <<] ?
    13 00 01 00 02 00 03 00 0f 00 10 00 11 00 23 00
    00 00 0d 00 22 00 20 06 01 06 02 06 03 05 01 05
    02 05 03 04 01 04 02 04 03 03 01 03 02 03 03 02
    01 02 02 02 03 01 01 00 0f 00 01 01

ServerKeyExchange:

<<< TLS 1.2 Handshake [length 014d], ServerKeyExchange
    0c 00 01 49 03 00 17 41 04 7e 74 d7 ed f4 7b 2f
    ...
$\endgroup$

2 Answers 2

9
votes
$\begingroup$

You can make OpenSSL print out the handshake messages with the -msg parameter:

openssl s_client -msg -connect myserver.net:443

Then look for the ServerKeyExchange message. Here is an example:

<<< TLS 1.2 Handshake [length 014d], ServerKeyExchange
    0c 00 01 49 03 00 17 41 04 6b d8 6e 14 1c 9b 12
    4d 58 29 20 e8 e2 1a 24 0d da 8f 38 1a 5d 85 2b
    2b 70 61 97 3b a7 5b fd b6 14 b3 5d f0 dd ea 7b
    68 d9 eb bc b2 59 32 52 9d 8e 9c 97 c0 d4 45 4c
    (...)

This can be analyzed, using RFC 5246 and RFC 4492 as references. In this case:

  • 0c: this is a ServerKeyExchange message (described in section 5.4 of RFC 4492)
  • 00 01 49: of length 0x000149 bytes (329 bytes)
  • 03: the curve type is "named_curve"
  • 00 17: the curve is secp256r1 (curve identifiers are in section 5.1.1, identifier 0x0017 is 23 in decimal).

secp256r1 is also known as P-256, one of the 15 curves standardized by NIST in FIPS 186-4. In fact this is the curve that almost everybody uses.

$\endgroup$
2
  • $\begingroup$ Fantastic! And yes, secp256r1 is also what I get: <<< TLS 1.2 Handshake [length 014d], ServerKeyExchange 0c 00 01 49 03 00 17 41 04 7e 74 d7 ed f4 7b 2f $\endgroup$
    – oberstet
    Commented Oct 26, 2013 at 23:43
  • $\begingroup$ Would you mind pointing out the relevant bits in the ClientHello (I've updated the question) where the client announces the curves it is willing to use? I am having a hard time wading through the RFCs as I am not at all experienced with TLS wire-level. Thank you very much! $\endgroup$
    – oberstet
    Commented Oct 27, 2013 at 0:09
8
votes
$\begingroup$

For what it's worth, in OpenSSL 1.0.2, s_client now displays the curve name:

$ openssl s_client -connect crypto.stackexchange.com:443
[...]
---
No client certificate CA names sent
Peer signing digest: SHA512
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 3436 bytes and written 443 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-ECDSA-AES128-GCM-SHA256
Server public key is 256 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-ECDSA-AES128-GCM-SHA256
[...]

The "Server Temp Key:" line quoted above gives the colloquial name, "P-256", for everybody's favorite NIST curve.

By the way, there's also a new -brief command line option, which also displays it:

$ openssl s_client -brief -connect crypto.stackexchange.com:443
CONNECTION ESTABLISHED
Protocol version: TLSv1.2
Ciphersuite: ECDHE-ECDSA-AES128-GCM-SHA256
Peer certificate: OU = Domain Control Validated, OU = PositiveSSL Multi-Domain, CN = ssl333133.cloudflaressl.com
Hash used: SHA512
Supported Elliptic Curve Point Formats: uncompressed:ansiX962_compressed_prime:ansiX962_compressed_char2
Server Temp Key: ECDH, P-256, 256 bits
^C
$\endgroup$
3
  • $\begingroup$ Awesome, thanks! If I get this right, I can now see the actual curve negotiated in the end, but not the curves announced by the client in the first place? $\endgroup$
    – oberstet
    Commented Dec 22, 2013 at 9:58
  • $\begingroup$ That's right, I'm afraid. $\endgroup$ Commented Dec 22, 2013 at 23:53
  • $\begingroup$ OpenSSL 1.0.2 is now available and -brief is apparently part of it, by the way. $\endgroup$ Commented Mar 7, 2015 at 9:16

Not the answer you're looking for? Browse other questions tagged or ask your own question.