I am implementing DTLS 1.2 protocol in C. While testing the client with openSSL, I observed that one of the frames sent by OpenSSL is not using the correct Dtls version (1.2) but an older version (1.0).
The client in C supports only DTLS1.2, and therefore reject the frame send by OpenSSL.
HelloClient sent by the C client:
Frame 2461: 109 bytes on wire (872 bits), 109 bytes captured (872 bits) on interface 0
Ethernet II, Src: Infineon_00:00:01 (00:03:19:00:00:01), Dst: Tp-LinkT_dc:4e:82 (50:3e:aa:dc:4e:82)
Internet Protocol Version 4, Src: 192.168.88.73, Dst: 192.168.88.77
User Datagram Protocol, Src Port: 50003, Dst Port: 60003
Datagram Transport Layer Security
DTLSv1.0 Record Layer: Handshake Protocol: Client Hello
Content Type: Handshake (22)
Version: DTLS 1.2 (0xfefd)
Epoch: 0
Sequence Number: 0
Length: 54
Handshake Protocol: Client Hello
Response from OpenSSL server:
Frame 2464: 90 bytes on wire (720 bits), 90 bytes captured (720 bits) on interface 0
Ethernet II, Src: Tp-LinkT_dc:4e:82 (50:3e:aa:dc:4e:82), Dst: Infineon_00:00:01 (00:03:19:00:00:01)
Internet Protocol Version 4, Src: 192.168.88.77, Dst: 192.168.88.73
User Datagram Protocol, Src Port: 60003, Dst Port: 50003
Datagram Transport Layer Security
DTLSv1.0 Record Layer: Handshake Protocol: Hello Verify Request
Content Type: Handshake (22)
Version: DTLS 1.0 (0xfeff)
Epoch: 0
Sequence Number: 0
Length: 35
Handshake Protocol: Hello Verify Request
I force OpenSSL to use the version 1.2 of DTLS running the following command: openssl.exe s_server -nocert -psk 01234567 -accept 443 -cipher PSK-AES128-GCM-SHA256 -dtls1_2
I saw in the RFC of TLS (https://www.rfc-editor.org/rfc/rfc5246#appendix-E)
TLS versions 1.0, 1.1, and 1.2, and SSL 3.0 are very similar, and use
compatible ClientHello messages; thus, supporting all of them is
relatively easy. Similarly, servers can easily handle clients trying
to use future versions of TLS as long as the ClientHello format
remains compatible, and the client supports the highest protocol
version available in the server.
Nothing is specified for HelloRequestVerify (rfc5246 or rfc6347), but does that means that any version between 1.0 and 1.2 should be accepted?
Or is that a bug in OpenSSL?
Note: If I continue the DTLS handshake, every further frame sent by OpenSSL are using the correct version of DTLS (1.2).
According RFC 6347, 4.2.1. Denial-of-Service Countermeasures
However, in order to avoid the requirement to do version negotiation in the initial handshake, DTLS 1.2 server implementations SHOULD use DTLS version 1.0 regardless of the version of TLS that is expected to be negotiated.
(That section contains some more information on that usage.)