Compare commits

...
Sign in to create a new pull request.

74 commits

Author SHA1 Message Date
Frederik Wedel-Heinen
42d467380c Support DTLS 1.3 Unified Headers
Also set correct AAD for DTLS 1.3 message de-/encryption.

Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/25668)
2025-03-18 18:56:41 +01:00
Frederik Wedel-Heinen
374768c6cf Adds a workaround for false negative test results with TLSProxy
The server is not able to shut down correctly
when the client sends an alert in epoch 0 and the
server has sent its Finished message.
As a workaround we accept a bad exit code for a failing
DTLS test run.

Fixes #26915

Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/26922)
2025-02-27 07:12:37 +01:00
Frederik Wedel-Heinen
0c37be3a7c TLSProxy: Handle partial messages with DTLS
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/26532)
2025-02-26 15:03:59 +01:00
Frederik Wedel-Heinen
6a233c31de Reduce the number of mallocs in dtls1_new() by allocating message queues together with the d1 struct.
Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/26150)
2025-02-25 12:06:27 +01:00
Frederik Wedel-Heinen
718f5b4cfb This change fixes an issue where a DTLS 1.3 would calculate a wrong transcript hash.
A wrong transcript hash was calculated when the client received a HRR which caused interop failures with WolfSSL. This change also refactors the internal calls to ssl3_finish_mac() that no longer requires the "incl_hdr" argument.

Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/26465)
2025-02-19 12:08:12 +01:00
Frederik Wedel-Heinen
1ee54c646b Sequence number cipher context is NULL for TLS connections
Fix memory sanitizer report of use of uninitialized variable: be explicit
that sequence number cipher context is NULL for TLS connections when
calling ssl_set_new_record_layer().

Reviewed-by: Paul Dale <ppzgs1@gmail.com>
Reviewed-by: Hugo Landau <hlandau@devever.net>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/26401)
2025-01-15 15:31:03 +01:00
Frederik Wedel-Heinen
1465a55241 Check result of set_protocol_version() and use the version passed as argument
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/26226)
2025-01-09 18:08:57 +01:00
Frederik Wedel-Heinen
55c95848d1 Avoid mallocing unprocessed_rcds and processed_rcds in dtls record layer
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/26211)
2025-01-09 18:08:57 +01:00
Frederik Wedel-Heinen
acbb7f73f5 Fix DTLS 1.3 handshake transcript hash
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/26035)
2025-01-09 18:08:56 +01:00
Frederik Wedel-Heinen
919c71e2f5 DTLS 1.3 record number encryption
Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/23511)
2025-01-09 18:07:49 +01:00
Frederik Wedel-Heinen
344262cddf Support dtls 1.3 downgrade mechanism
Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/23320)
2025-01-09 18:07:48 +01:00
Frederik Wedel-Heinen
85aad3e553 Update epochs when changing key and cipher state for dtls 1.3
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/23229)
2025-01-09 18:06:57 +01:00
Frederik Wedel-Heinen
cb86ed419a Refactor handshake msg header parsing etc.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/24607)
2025-01-09 18:06:55 +01:00
Frederik Wedel-Heinen
6c75a12d87 Fix SCTP todo
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/24605)
2025-01-09 18:05:42 +01:00
Frederik Wedel-Heinen
bf9a4f8caa Run 70-test_tls13certcomp.t with dtls
Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/24525)
2025-01-09 18:05:42 +01:00
Frederik Wedel-Heinen
d4c8312a70 Run 70-test_tls13kexmodes.t with dtls
It is currently unsupported because of missing support in TLSProxy.

Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/24525)
2025-01-09 18:05:38 +01:00
Frederik Wedel-Heinen
c072b0e4ba Run 70-test_tls13messages.t with dtls
Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/24525)
2025-01-09 18:03:08 +01:00
Frederik Wedel-Heinen
df46d865e2 Add support for running 70-test_tls13psk.t with dtls
Has to be currently disabled because it fails.

Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/24525)
2025-01-09 17:53:42 +01:00
Frederik Wedel-Heinen
24bc207b02 Run 70-test_tls13hrr.t with dtls
Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/24525)
2025-01-09 17:53:40 +01:00
Frederik Wedel-Heinen
c8273a2a54 Run 70-test_tls13cookie.t with dtls
Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/24525)
2025-01-09 17:45:49 +01:00
Frederik Wedel-Heinen
99f00d917a Run 70-test_tls13alerts.t with dtls
Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/24525)
2025-01-09 17:45:49 +01:00
Frederik Wedel-Heinen
c979483a7b Fix an assertion failure which happens when a DTLS 1.3 client receives a HelloVerifyRequest.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/24509)
2025-01-09 17:45:49 +01:00
Frederik Wedel-Heinen
4bfc8b46d7 Use WPACKET in dtls1_do_write()
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/24426)
2025-01-09 17:45:49 +01:00
Frederik Wedel-Heinen
f964317a01 Place start of ClientHello correctly when calculating binder for DTLS 1.3
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/24426)
2025-01-09 17:45:47 +01:00
Frederik Wedel-Heinen
2e9a90704f Re-enable mtu assertion which previously failed for DTLS 1.3
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/24524)
2025-01-09 17:41:34 +01:00
Frederik Wedel-Heinen
554b56e969 Refactor code and fix a couple of missing DTLSv1.3 checks.
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/24345)
2025-01-09 17:41:31 +01:00
Frederik Wedel-Heinen
02146a0879 Add design document for DTLS 1.3 implementation
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/23041)
2025-01-09 17:06:56 +01:00
Frederik Wedel-Heinen
25ab23242f Run test_cookie() test with DTLS 1.3
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/24425)
2025-01-09 17:06:56 +01:00
Frederik Wedel-Heinen
6600141962 Adds DTLSv1.3 to protocol_version.pm for additional protocol version tests.
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/23242)
2025-01-09 17:06:56 +01:00
Frederik Wedel-Heinen
3df9414688 Continue processing cookieless client hellos for dtls1.3
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/22400)
2025-01-09 17:06:56 +01:00
Frederik Wedel-Heinen
e5e3c15523 Fix description of version field of ssl connection struct
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/22937)
2025-01-09 17:06:56 +01:00
Frederik Wedel-Heinen
f7553c08ca Updates SSL_CONF_cmd.pod to be explicit when features are for both TLS and DTLS
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/22363)
2025-01-09 17:04:14 +01:00
Frederik Wedel-Heinen
5ae9809930 Update documentation for DTLS1.3
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/22363)
2025-01-09 17:02:19 +01:00
Frederik Wedel-Heinen
7f4e2b3890 Correct traces for certificates in dtls13
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/22935)
2025-01-09 17:02:19 +01:00
Frederik Wedel-Heinen
a4461dba43 Clear old messages from queues in order to avoid leaks of record layer objects.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/22275)
2025-01-09 17:02:19 +01:00
Frederik Wedel-Heinen
fef3985424 Disable middlebox for dtls
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/22275)
2025-01-09 17:02:19 +01:00
Frederik Wedel-Heinen
36561a2aa0 Check that both tls1.3 and dtls1.3 is disabled before removing code from compilation path.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/22275)
2025-01-09 17:02:19 +01:00
Frederik Wedel-Heinen
d2526d8f35 Fix test_ssl_new tests
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/22275)
2025-01-09 17:02:19 +01:00
Frederik Wedel-Heinen
d888cb8646 Run some failing tests with DTLS1.2
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/22275)
2025-01-09 17:02:19 +01:00
Frederik Wedel-Heinen
86b4c0a05f Fix renegotiation check that was added in https://github.com/openssl/openssl/pull/24161
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/22275)
2025-01-09 17:02:19 +01:00
Frederik Wedel-Heinen
eda3b4b93a Fix version check to avoid unsupported protocol error in ssl_choose_server_version()
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/22275)
2025-01-09 17:02:19 +01:00
Frederik Wedel-Heinen
5fc85f277e Update DTLS version tests
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/22275)
2025-01-09 17:02:19 +01:00
Frederik Wedel-Heinen
bc86e5b81e Remove obsolete TODO and guards for post handshake authentication in DTLS 1.3
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/22275)
2025-01-09 17:02:19 +01:00
Frederik Wedel-Heinen
9ca8f6653c Update dtls max version
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/22275)
2025-01-09 17:02:19 +01:00
Frederik Wedel-Heinen
652e4506cf Fix sanity tests for ssl_version_cmp for dtls 1.3 branch
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/24293)
2025-01-09 17:02:19 +01:00
Frederik Wedel-Heinen
2af74c5a16 Sanity tests of inputs to ssl_version_cmp
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/24293)
2025-01-09 17:02:19 +01:00
Frederik Wedel-Heinen
34538ecc51 Fix ssl_lib functions for dtls 1.3
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/22378)
2025-01-09 17:02:19 +01:00
Frederik Wedel-Heinen
e41c916a22 tls_post_encryption_processing_default() and tls_validate_record_header()
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/22376)
2025-01-09 17:02:19 +01:00
Frederik Wedel-Heinen
6103993250 Fix session print for dtls1.3
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/22936)
2025-01-09 17:02:19 +01:00
Frederik Wedel-Heinen
73d1d24c0c Update session id and ticket logic for dtls13
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/22936)
2025-01-09 17:02:19 +01:00
Frederik Wedel-Heinen
30386820fb Removes an mtu assertion that fails
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/22401)
2025-01-09 17:02:19 +01:00
Frederik Wedel-Heinen
f29cf02239 Support TLS1.3 sigalg logic in DTLS1.3
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/22380)
2025-01-09 17:02:19 +01:00
Frederik Wedel-Heinen
8c90f9b8c2 Handle alerts similarly in dtls1_read_bytes() as done in ssl3_read_bytes()
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/22360)
2025-01-09 17:02:19 +01:00
Frederik Wedel-Heinen
b83a25638e Make similar changes to dtls1_do_write() for dtls1.3 as in ssl3_do_write() for tls1.3
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/22360)
2025-01-09 17:02:19 +01:00
Frederik Wedel-Heinen
c967dc7a5c Adds some more changes dtls specific functions to make them more in sync with their tls counterparts.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/22360)
2025-01-09 17:02:19 +01:00
Frederik Wedel-Heinen
50da738ed1 Make dtls1.3 changes to dtls1_read_bytes and do_dtls1_write which matches ssl3_read_bytes and ssl3_write_bytes
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/22360)
2025-01-09 17:02:19 +01:00
Frederik Wedel-Heinen
3165d63294 Don't allow renegotiation for DTLS 1.3
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/22362)
2025-01-09 17:02:19 +01:00
Frederik Wedel-Heinen
031697cf69 Adds dtls 1.3 support in TLS::Proxy
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/23375)
2025-01-09 17:02:19 +01:00
Frederik Wedel-Heinen
33c96b2dc6 Support TLS 1.3 kexs and groups with DTLS 1.3
SSL_CONNECTION_IS_VERSION13 macro is used where appropriate.

Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/22364)
2025-01-09 17:02:19 +01:00
Frederik Wedel-Heinen
44bfb6aa78 Fix wrong dtls 1 and 1.2 version check
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/22366)
2025-01-09 17:02:19 +01:00
Frederik Wedel-Heinen
1409fbeb8e Do DTLS13 and TLS13 connection version check in one macro
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/22366)
2025-01-09 17:02:17 +01:00
Frederik Wedel-Heinen
087bc64918 Fix sending session ids in DTLS-1.3
DTLS 1.3 session id must not be sent by client unless
it has a cached id. And DTLS 1.3 servers must not echo
a session id from a client.

Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/22366)
2025-01-09 17:01:30 +01:00
Frederik Wedel-Heinen
ceb9e33b3f Update tls state machine logic to support dtls1.3 alongside tls1.3
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/22366)

Updated the logic in ssl_cipher_list_to_bytes to take account of the changes
from PR#24161

Reviewed-by: Richard Levitte <levitte@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/24226)
2025-01-09 17:01:27 +01:00
Frederik Wedel-Heinen
7f95231e16 Fix protocol list for cmd_Protocol()
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/22273)
2025-01-09 16:58:39 +01:00
Frederik Wedel-Heinen
acec6d68c1 Add dtls1.3 to ssl_protocol_to_string()
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/22273)
2025-01-09 16:58:39 +01:00
Frederik Wedel-Heinen
719bf8d2eb Adds DTLS1.3 to ssl protocol to text structs
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/22273)
2025-01-09 16:58:39 +01:00
Frederik Wedel-Heinen
62458fac1c Determine which label prefix to use based on if the connection is dtls
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/22416)
2025-01-09 16:58:39 +01:00
Frederik Wedel-Heinen
0833bcf67d Use dtls1.3 cryptographic label prefix as dictated by RFC 9147 section 5.9
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/22416)
2025-01-09 16:58:39 +01:00
Frederik Wedel-Heinen
df6967ca3c Support TLS1.3 extensions with DTLS1.3
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/22261)
2025-01-09 16:58:38 +01:00
Frederik Wedel-Heinen
1daca57fd3 Print session ticket for dtls 1.3 as well.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/22260)
2025-01-09 16:57:24 +01:00
Frederik Wedel-Heinen
ef6533ad68 Adds DTLS 1.3 functionality to s_client and s_server documentation.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/22260)
2025-01-09 16:57:24 +01:00
Frederik Wedel-Heinen
62a0dfac46 Integrate dtls1.3 in s_client and s_server
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/22260)
2025-01-09 16:57:24 +01:00
Frederik Wedel-Heinen
21d0d5139f Remove compile guards for dtls1.3 method implementations
Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/22259)
2025-01-09 16:57:23 +01:00
Frederik Wedel-Heinen
557139f68f Adds initial dtls 1.3 structs and definitions
Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/22259)
2025-01-09 16:57:23 +01:00
106 changed files with 7470 additions and 3051 deletions

View file

@ -408,7 +408,7 @@ my $default_ranlib;
# Known TLS and DTLS protocols
my @tls = qw(ssl3 tls1 tls1_1 tls1_2 tls1_3);
my @dtls = qw(dtls1 dtls1_2);
my @dtls = qw(dtls1 dtls1_2 dtls1_3);
# Explicitly known options that are possible to disable. They can
# be regexps, and will be used like this: /^no-${option}$/
@ -549,7 +549,7 @@ my @disablables = (
foreach my $proto ((@tls, @dtls))
{
push(@disablables, $proto);
push(@disablables, "$proto-method") unless $proto eq "tls1_3";
push(@disablables, "$proto-method") unless $proto eq "tls1_3" || $proto eq "dtls1_3";
}
# Internal disablables, for aliasing purposes. They serve no special

View file

@ -216,12 +216,12 @@
"Groups to advertise (colon-separated list)" }, \
{"named_curve", OPT_S_NAMEDCURVE, 's', \
"Elliptic curve used for ECDHE (server-side only)" }, \
{"cipher", OPT_S_CIPHER, 's', "Specify TLSv1.2 and below cipher list to be used"}, \
{"ciphersuites", OPT_S_CIPHERSUITES, 's', "Specify TLSv1.3 ciphersuites to be used"}, \
{"cipher", OPT_S_CIPHER, 's', "Specify (D)TLSv1.2 and below cipher list to be used"}, \
{"ciphersuites", OPT_S_CIPHERSUITES, 's', "Specify (D)TLSv1.3 ciphersuites to be used"}, \
{"min_protocol", OPT_S_MINPROTO, 's', "Specify the minimum protocol version to be used"}, \
{"max_protocol", OPT_S_MAXPROTO, 's', "Specify the maximum protocol version to be used"}, \
{"record_padding", OPT_S_RECORD_PADDING, 's', \
"Block size to pad TLS 1.3 records to."}, \
"Block size to pad (D)TLS 1.3 records to."}, \
{"debug_broken_protocol", OPT_S_DEBUGBROKE, '-', \
"Perform all sorts of protocol violations for testing purposes"}, \
{"no_middlebox", OPT_S_NO_MIDDLEBOX, '-', \

View file

@ -16,7 +16,9 @@
#define PROTOCOL "tcp"
#define SSL_VERSION_ALLOWS_RENEGOTIATION(s) \
(SSL_is_dtls(s) || (SSL_version(s) < TLS1_3_VERSION))
((SSL_is_dtls(s) && (SSL_version(s) > DTLS1_3_VERSION \
|| SSL_version(s) == DTLS1_BAD_VER)) \
|| (!SSL_is_dtls(s) && SSL_version(s) < TLS1_3_VERSION))
typedef int (*do_server_cb)(int s, int stype, int prot, unsigned char *context);
void get_sock_info_address(int asock, char **hostname, char **service);

View file

@ -575,6 +575,8 @@ static STRINT_PAIR ssl_versions[] = {
{"TLS 1.2", TLS1_2_VERSION},
{"TLS 1.3", TLS1_3_VERSION},
{"DTLS 1.0", DTLS1_VERSION},
{"DTLS 1.2", DTLS1_2_VERSION},
{"DTLS 1.3", DTLS1_3_VERSION},
{"DTLS 1.0 (bad)", DTLS1_BAD_VER},
{NULL}
};
@ -657,7 +659,9 @@ void msg_cb(int write_p, int version, int content_type, const void *buf,
version == TLS1_1_VERSION ||
version == TLS1_2_VERSION ||
version == TLS1_3_VERSION ||
version == DTLS1_VERSION || version == DTLS1_BAD_VER) {
version == DTLS1_VERSION ||
version == DTLS1_2_VERSION ||
version == DTLS1_3_VERSION || version == DTLS1_BAD_VER) {
str_version = lookup(version, ssl_versions, "???");
switch (content_type) {
case SSL3_RT_CHANGE_CIPHER_SPEC:

View file

@ -206,6 +206,7 @@ static int psk_use_session_cb(SSL *s, const EVP_MD *md,
{
SSL_SESSION *usesess = NULL;
const SSL_CIPHER *cipher = NULL;
const int version1_3 = SSL_is_dtls(s) ? DTLS1_3_VERSION : TLS1_3_VERSION;
if (psksess != NULL) {
SSL_SESSION_up_ref(psksess);
@ -232,7 +233,7 @@ static int psk_use_session_cb(SSL *s, const EVP_MD *md,
if (usesess == NULL
|| !SSL_SESSION_set1_master_key(usesess, key, key_len)
|| !SSL_SESSION_set_cipher(usesess, cipher)
|| !SSL_SESSION_set_protocol_version(usesess, TLS1_3_VERSION)) {
|| !SSL_SESSION_set_protocol_version(usesess, version1_3)) {
OPENSSL_free(key);
goto err;
}
@ -491,9 +492,9 @@ typedef enum OPTION_choice {
#endif
OPT_SSL3, OPT_SSL_CONFIG,
OPT_TLS1_3, OPT_TLS1_2, OPT_TLS1_1, OPT_TLS1, OPT_DTLS, OPT_DTLS1,
OPT_DTLS1_2, OPT_QUIC, OPT_SCTP, OPT_TIMEOUT, OPT_MTU, OPT_KEYFORM,
OPT_PASS, OPT_CERT_CHAIN, OPT_KEY, OPT_RECONNECT, OPT_BUILD_CHAIN,
OPT_NEXTPROTONEG, OPT_ALPN,
OPT_DTLS1_2, OPT_DTLS1_3, OPT_QUIC, OPT_SCTP, OPT_TIMEOUT, OPT_MTU,
OPT_KEYFORM, OPT_PASS, OPT_CERT_CHAIN, OPT_KEY, OPT_RECONNECT,
OPT_BUILD_CHAIN, OPT_NEXTPROTONEG, OPT_ALPN,
OPT_CAPATH, OPT_NOCAPATH, OPT_CHAINCAPATH, OPT_VERIFYCAPATH,
OPT_CAFILE, OPT_NOCAFILE, OPT_CHAINCAFILE, OPT_VERIFYCAFILE,
OPT_CASTORE, OPT_NOCASTORE, OPT_CHAINCASTORE, OPT_VERIFYCASTORE,
@ -696,6 +697,9 @@ const OPTIONS s_client_options[] = {
#ifndef OPENSSL_NO_DTLS1_2
{"dtls1_2", OPT_DTLS1_2, '-', "Just use DTLSv1.2"},
#endif
#ifndef OPENSSL_NO_DTLS1_3
{"dtls1_3", OPT_DTLS1_3, '-', "Just use DTLSv1.3"},
#endif
#ifndef OPENSSL_NO_SCTP
{"sctp", OPT_SCTP, '-', "Use SCTP"},
{"sctp_label_bug", OPT_SCTP_LABEL_BUG, '-', "Enable SCTP label length bug"},
@ -798,7 +802,7 @@ static const OPT_PAIR services[] = {
#define IS_PROT_FLAG(o) \
(o == OPT_SSL3 || o == OPT_TLS1 || o == OPT_TLS1_1 || o == OPT_TLS1_2 \
|| o == OPT_TLS1_3 || o == OPT_DTLS || o == OPT_DTLS1 || o == OPT_DTLS1_2 \
|| o == OPT_QUIC)
|| o == OPT_DTLS1_3 || o == OPT_QUIC)
/* Free |*dest| and optionally set it to a copy of |source|. */
static void freeandcopy(char **dest, const char *source)
@ -811,6 +815,7 @@ static void freeandcopy(char **dest, const char *source)
static int new_session_cb(SSL *s, SSL_SESSION *sess)
{
const int version1_3 = SSL_is_dtls(s) ? DTLS1_3_VERSION : TLS1_3_VERSION;
if (sess_out != NULL) {
BIO *stmp = BIO_new_file(sess_out, "w");
@ -824,10 +829,10 @@ static int new_session_cb(SSL *s, SSL_SESSION *sess)
}
/*
* Session data gets dumped on connection for TLSv1.2 and below, and on
* arrival of the NewSessionTicket for TLSv1.3.
* Session data gets dumped on connection for (D)TLSv1.2 and below, and on
* arrival of the NewSessionTicket for (D)TLSv1.3.
*/
if (SSL_version(s) == TLS1_3_VERSION) {
if (SSL_version(s) == version1_3) {
BIO_printf(bio_c_out,
"---\nPost-Handshake New Session Ticket arrived:\n");
SSL_SESSION_print(bio_c_out, sess);
@ -929,6 +934,9 @@ int s_client_main(int argc, char **argv)
#ifndef OPENSSL_NO_CT
char *ctlog_file = NULL;
int ct_validation = 0;
#endif
#ifndef OPENSSL_NO_NEXTPROTONEG
int version1_3;
#endif
int min_version = 0, max_version = 0, prot_opt = 0, no_prot_opt = 0;
int async = 0;
@ -1350,6 +1358,18 @@ int s_client_main(int argc, char **argv)
socket_type = SOCK_DGRAM;
isdtls = 1;
isquic = 0;
#endif
break;
case OPT_DTLS1_3:
#ifndef OPENSSL_NO_DTLS1_3
meth = DTLS_client_method();
min_version = DTLS1_3_VERSION;
max_version = DTLS1_3_VERSION;
socket_type = SOCK_DGRAM;
isdtls = 1;
# ifndef OPENSS_NO_QUIC
isquic = 0;
# endif
#endif
break;
case OPT_QUIC:
@ -1575,6 +1595,10 @@ int s_client_main(int argc, char **argv)
}
}
#ifndef OPENSSL_NO_NEXTPROTONEG
version1_3 = isdtls ? DTLS1_3_VERSION : TLS1_3_VERSION;
#endif
/* Optional argument is connect string if -connect not used. */
if (opt_num_rest() == 1) {
/* Don't allow -connect and a separate argument. */
@ -1615,7 +1639,7 @@ int s_client_main(int argc, char **argv)
}
#ifndef OPENSSL_NO_NEXTPROTONEG
if (min_version == TLS1_3_VERSION && next_proto_neg_in != NULL) {
if (min_version == version1_3 && next_proto_neg_in != NULL) {
BIO_printf(bio_err, "Cannot supply -nextprotoneg with TLSv1.3\n");
goto opthelp;
}
@ -3366,7 +3390,8 @@ static void print_stuff(BIO *bio, SSL *s, int full)
STACK_OF(X509) *sk;
const SSL_CIPHER *c;
EVP_PKEY *public_key;
int i, istls13 = (SSL_version(s) == TLS1_3_VERSION);
const int version1_3 = SSL_is_dtls(s) ? DTLS1_3_VERSION : TLS1_3_VERSION;
int i;
long verify_result;
#ifndef OPENSSL_NO_COMP
const COMP_METHOD *comp, *expansion;
@ -3560,7 +3585,7 @@ static void print_stuff(BIO *bio, SSL *s, int full)
}
#endif
if (istls13) {
if (SSL_version(s) == version1_3) {
switch (SSL_get_early_data_status(s)) {
case SSL_EARLY_DATA_NOT_SENT:
BIO_printf(bio, "Early data was not sent\n");
@ -3821,6 +3846,8 @@ static int user_data_add(struct user_data_st *user_data, size_t i)
static int user_data_execute(struct user_data_st *user_data, int cmd, char *arg)
{
const int version1_3 = SSL_is_dtls(user_data->con) ? DTLS1_3_VERSION : TLS1_3_VERSION;
switch (cmd) {
case USER_COMMAND_HELP:
/* This only ever occurs in advanced mode, so just emit advanced help */
@ -3833,7 +3860,7 @@ static int user_data_execute(struct user_data_st *user_data, int cmd, char *arg)
BIO_printf(bio_err, " {reconnect}: Reconnect to the peer\n");
if (SSL_is_quic(user_data->con)) {
BIO_printf(bio_err, " {fin}: Send FIN on the stream. No further writing is possible\n");
} else if(SSL_version(user_data->con) == TLS1_3_VERSION) {
} else if(SSL_version(user_data->con) == version1_3) {
BIO_printf(bio_err, " {keyup:req|noreq}: Send a Key Update message\n");
BIO_printf(bio_err, " Arguments:\n");
BIO_printf(bio_err, " req = peer update requested (default)\n");
@ -3897,6 +3924,7 @@ static int user_data_process(struct user_data_st *user_data, size_t *len,
{
char *buf_start = user_data->buf + user_data->bufoff;
size_t outlen = user_data->buflen;
const int version1_3 = SSL_is_dtls(user_data->con) ? DTLS1_3_VERSION : TLS1_3_VERSION;
if (user_data->buflen == 0) {
*len = 0;
@ -3982,7 +4010,7 @@ static int user_data_process(struct user_data_st *user_data, size_t *len,
} else if(SSL_is_quic(user_data->con)) {
if (OPENSSL_strcasecmp(cmd_start, "fin") == 0)
cmd = USER_COMMAND_FIN;
} if (SSL_version(user_data->con) == TLS1_3_VERSION) {
} if (SSL_version(user_data->con) == version1_3) {
if (OPENSSL_strcasecmp(cmd_start, "keyup") == 0) {
cmd = USER_COMMAND_KEY_UPDATE;
if (arg_start == NULL)

View file

@ -57,6 +57,7 @@ typedef unsigned int u_int;
#include <openssl/ebcdic.h>
#endif
#include "internal/sockets.h"
#include "ssl/ssl_local.h"
static int not_resumable_sess_cb(SSL *s, int is_forward_secure);
static int sv_body(int s, int stype, int prot, unsigned char *context);
@ -133,16 +134,17 @@ static unsigned int psk_server_cb(SSL *ssl, const char *identity,
{
long key_len = 0;
unsigned char *key;
const int version1_3 = SSL_is_dtls(ssl) ? DTLS1_3_VERSION : TLS1_3_VERSION;
if (s_debug)
BIO_printf(bio_s_out, "psk_server_cb\n");
if (!SSL_is_dtls(ssl) && SSL_version(ssl) >= TLS1_3_VERSION) {
if (PROTOCOL_VERSION_CMP(SSL_is_dtls(ssl), SSL_version(ssl), version1_3) >= 0) {
/*
* This callback is designed for use in (D)TLSv1.2 (or below). It is
* possible to use a single callback for all protocol versions - but it
* is preferred to use a dedicated callback for TLSv1.3. For TLSv1.3 we
* have psk_find_session_cb.
* is preferred to use a dedicated callback for (D)TLSv1.3. For
* (D)TLSv1.3 we have psk_find_session_cb.
*/
return 0;
}
@ -733,8 +735,8 @@ typedef enum OPTION_choice {
OPT_UPPER_WWW, OPT_HTTP, OPT_ASYNC, OPT_SSL_CONFIG,
OPT_MAX_SEND_FRAG, OPT_SPLIT_SEND_FRAG, OPT_MAX_PIPELINES, OPT_READ_BUF,
OPT_SSL3, OPT_TLS1_3, OPT_TLS1_2, OPT_TLS1_1, OPT_TLS1, OPT_DTLS, OPT_DTLS1,
OPT_DTLS1_2, OPT_SCTP, OPT_TIMEOUT, OPT_MTU, OPT_LISTEN, OPT_STATELESS,
OPT_ID_PREFIX, OPT_SERVERNAME, OPT_SERVERNAME_FATAL,
OPT_DTLS1_2, OPT_DTLS1_3, OPT_SCTP, OPT_TIMEOUT, OPT_MTU, OPT_LISTEN,
OPT_STATELESS, OPT_ID_PREFIX, OPT_SERVERNAME, OPT_SERVERNAME_FATAL,
OPT_CERT2, OPT_KEY2, OPT_NEXTPROTONEG, OPT_ALPN, OPT_SENDFILE,
OPT_SRTP_PROFILES, OPT_KEYMATEXPORT, OPT_KEYMATEXPORTLEN,
OPT_KEYLOG_FILE, OPT_MAX_EARLY, OPT_RECV_MAX_EARLY, OPT_EARLY_DATA,
@ -942,7 +944,7 @@ const OPTIONS s_server_options[] = {
"The maximum number of bytes of early data (hard limit)"},
{"early_data", OPT_EARLY_DATA, '-', "Attempt to read early data"},
{"num_tickets", OPT_S_NUM_TICKETS, 'n',
"The number of TLSv1.3 session tickets that a server will automatically issue" },
"The number of (D)TLSv1.3 session tickets that a server will automatically issue" },
{"anti_replay", OPT_ANTI_REPLAY, '-', "Switch on anti-replay protection (default)"},
{"no_anti_replay", OPT_NO_ANTI_REPLAY, '-', "Switch off anti-replay protection"},
{"http_server_binmode", OPT_HTTP_SERVER_BINMODE, '-', "opening files in binary mode when acting as http server (-WWW and -HTTP)"},
@ -975,6 +977,9 @@ const OPTIONS s_server_options[] = {
#ifndef OPENSSL_NO_DTLS1_2
{"dtls1_2", OPT_DTLS1_2, '-', "Just talk DTLSv1.2"},
#endif
#ifndef OPENSSL_NO_DTLS1_3
{"dtls1_3", OPT_DTLS1_3, '-', "Just talk DTLSv1.3"},
#endif
#ifndef OPENSSL_NO_SCTP
{"sctp", OPT_SCTP, '-', "Use SCTP"},
{"sctp_label_bug", OPT_SCTP_LABEL_BUG, '-', "Enable SCTP label length bug"},
@ -1007,7 +1012,8 @@ const OPTIONS s_server_options[] = {
#define IS_PROT_FLAG(o) \
(o == OPT_SSL3 || o == OPT_TLS1 || o == OPT_TLS1_1 || o == OPT_TLS1_2 \
|| o == OPT_TLS1_3 || o == OPT_DTLS || o == OPT_DTLS1 || o == OPT_DTLS1_2)
|| o == OPT_TLS1_3 || o == OPT_DTLS || o == OPT_DTLS1 || o == OPT_DTLS1_2 \
|| o == OPT_DTLS1_3)
int s_server_main(int argc, char *argv[])
{
@ -1067,6 +1073,9 @@ int s_server_main(int argc, char *argv[])
#endif
#ifndef OPENSSL_NO_SRTP
char *srtp_profiles = NULL;
#endif
#if !(defined(OPENSSL_NO_NEXTPROTONEG) && defined(OPENSSL_NO_PSK))
int version1_3;
#endif
int min_version = 0, max_version = 0, prot_opt = 0, no_prot_opt = 0;
int s_server_verify = SSL_VERIFY_NONE;
@ -1557,6 +1566,14 @@ int s_server_main(int argc, char *argv[])
min_version = DTLS1_2_VERSION;
max_version = DTLS1_2_VERSION;
socket_type = SOCK_DGRAM;
#endif
break;
case OPT_DTLS1_3:
#ifndef OPENSSL_NO_DTLS
meth = DTLS_server_method();
min_version = DTLS1_3_VERSION;
max_version = DTLS1_3_VERSION;
socket_type = SOCK_DGRAM;
#endif
break;
case OPT_SCTP:
@ -1710,6 +1727,10 @@ int s_server_main(int argc, char *argv[])
}
}
#if !(defined(OPENSSL_NO_NEXTPROTONEG) && defined(OPENSSL_NO_PSK))
version1_3 = (socket_type == SOCK_DGRAM) ? DTLS1_3_VERSION : TLS1_3_VERSION;
#endif
/* No extra arguments. */
if (!opt_check_rest_arg(NULL))
goto opthelp;
@ -1718,7 +1739,7 @@ int s_server_main(int argc, char *argv[])
goto end;
#ifndef OPENSSL_NO_NEXTPROTONEG
if (min_version == TLS1_3_VERSION && next_proto_neg_in != NULL) {
if (min_version == version1_3 && next_proto_neg_in != NULL) {
BIO_printf(bio_err, "Cannot supply -nextprotoneg with TLSv1.3\n");
goto opthelp;
}
@ -2208,7 +2229,7 @@ int s_server_main(int argc, char *argv[])
}
if (psk_identity_hint != NULL) {
if (min_version == TLS1_3_VERSION) {
if (min_version == version1_3) {
BIO_printf(bio_s_out, "PSK warning: there is NO identity hint in TLSv1.3\n");
} else {
if (!SSL_CTX_use_psk_identity_hint(ctx, psk_identity_hint)) {

View file

@ -364,6 +364,12 @@ int WPACKET_finish(WPACKET *pkt)
}
int WPACKET_start_sub_packet_len__(WPACKET *pkt, size_t lenbytes)
{
return WPACKET_start_sub_packet_at_offset_len__(pkt, lenbytes, 0);
}
int WPACKET_start_sub_packet_at_offset_len__(WPACKET *pkt, size_t lenbytes,
size_t offset)
{
WPACKET_SUB *sub;
unsigned char *lenchars;
@ -381,7 +387,7 @@ int WPACKET_start_sub_packet_len__(WPACKET *pkt, size_t lenbytes)
sub->parent = pkt->subs;
pkt->subs = sub;
sub->pwritten = pkt->written + lenbytes;
sub->pwritten = pkt->written + lenbytes + offset;
sub->lenbytes = lenbytes;
if (lenbytes == 0) {
@ -391,7 +397,8 @@ int WPACKET_start_sub_packet_len__(WPACKET *pkt, size_t lenbytes)
sub->packet_len = pkt->written;
if (!WPACKET_allocate_bytes(pkt, lenbytes, &lenchars))
if (!WPACKET_allocate_bytes(pkt, lenbytes, &lenchars)
|| (offset > 0 && !WPACKET_allocate_bytes(pkt, offset, &lenchars)))
return 0;
return 1;

View file

@ -0,0 +1,249 @@
DTLSv1.3 Design
===============
This page presents an overview of the design rationale for the DTLSv1.3
(RFC 9147) implementation in OpenSSL.
Objectives
----------
* A user should be able to establish a DTLSv1.3 connection through the same
apis as previous versions of DTLS.
* MUSTs, SHALLs and REQUIREDs of RFC 9147 are implemented.
* Implementation details of OPTIONALs, SHOULDs and MAYs are documented in
this document.
Implementation details
----------------------
This section describes the implementation requirements of DTLSv1.3
(RFC 9147).
### DTLSv1.0 support
RFC 9147 recommends to drop DTLSv1.0 support but OpenSSL will continue to
support it for now.
### DTLSv1.3 unified header
A new feature for DTLSv1.3 is the unified header (unified_hdr) (RFC 9147
section 4) of the DTLSCiphertext. OpenSSL supports receiving a DTLSCiphertext
of any format but always formats the header of outgoing DTLSCiphertext's the
same way:
* The C-bit is set to 0. Refer to [DTLSv1.3 connection id](#dtlsv1.3-connection-id)
* The S-bit is set to 1 (sequence numbers are 16-bit)
* The L-bit is set to 1 (length field is present)
Configurability of the unified header fields requires a new api and is marked
as a feature request in issue ###########.
### DTLSv1.3 connection id
OpenSSL does not support Connection IDs (RFC 9146). Notably Openssl DTLSv1.3 clients
will not offer the "connection_id" extension even though RFC 9147 states:
> DTLS clients which do not want to receive a Connection ID SHOULD still offer
> the "connection_id" extension [RFC9146] unless there is an application
> profile to the contrary. This permits a server which wants to receive a CID
> to negotiate one.
### Clearing retransmission queue
When the session keys are updated the DTLSv1.3 implementation will clear the
messages waiting for retransmission that belongs to the key that is being updated.
#### TLS 1.3 "compatibility mode" is not enabled
Opposed to the TLS 1.3 implementation, the DTLSv1.3 implementation does not offer
the compatibility which is in consistency with RFC9147 section 5.
This is enforced by the macro `SSL_CONNECTION_MIDDLEBOX_IS_ENABLED(sc)`.
#### Cryptographic label prefix
The DTLSv1.3 implementation uses the label "dtls1.3" as described by RFC9147
section 5.9.
#### DTLS 1.3 Epoch
The DTLSv1.3 implementation modifies the epoch according to RFC9147 section 6.1
for DTLSv1.3 connections.
#### DTLS 1.3 Transcript Hash
The DTLSv1.3 implementation does not include the message sequence number,
fragment offset and fragment length as is the case with previous versions of DTLS.
Implementation progress
-----------------------
This section contains a summary of the work required to implement DTLSv1.3 for Openssl.
It is basically a condensed version of the RFC.
### Backlog of work items
A summary of larger work items that needs to be addressed.
Notice that some of the requirements mentioned in [List of DTLSv1.3 requirements](#list-of-dtls-13-requirements)
is not covered by these workitems and must be implemented separately.
| Summary | #PR |
|-----------------------------------------------------|--------|
| ACK messages | #25119 |
| Use HelloRetryRequest instead of HelloVerifyRequest | #22985 |
| EndOfEarlyData message | - |
| DTLSv1.3 Fuzzer | - |
### Changes from DTLS 1.2 and/or TLS 1.3
In general the implementation of DTLSv1.3 reuses much of the same functionality of
TLSv1.3 and DTLSv1.2. This part of the implementation can be considered a
separate work item.
Here follows a collection of changes that need to be implemented.
#### DTLSCipherText
DTLSCipherText differs from DTLS 1.2 and TLS 1.3:
> The DTLSCiphertext structure omits the superfluous version number and type fields
> ...
> The DTLSCiphertext structure has a variable-length header
> ...
> The entire header value shown in Figure 4 (but prior to record number encryption;
> see Section 4.2.3) is used as the additional data value for the AEAD function
> ...
> In DTLSv1.3 the 64-bit sequence_number is used as the sequence number for the
> AEAD computation; unlike DTLS 1.2, the epoch is not included.
Because of the encrypted sequence number and record number the implementation must
handle them as described in:
> 4.2.2. Reconstructing the Sequence Number and Epoch
And
> 4.2.3. Record Number Encryption
#### ClientHello
DTLS adds legacy_cookie which has a forced value. And there are changes to the
random value:
> random: Same as for TLS 1.3, except that the downgrade sentinels ... apply to
> DTLS 1.2 and DTLS 1.0, respectively.
#### EndOfEarlyData message
> the EndOfEarlyData message is omitted both from the wire and the handshake
> transcript
#### ACK messages
See section 7 and 8 of RFC 9147.
### List of DTLSv1.3 requirements
Here's a list of requirements from RFC 9147 together with their implementation status
and associated PR with the relevant implementation.
"TBD" indicates that the implementation is missing. Note there may exist a fix in a PR.
"Yes" indicates that the requirement is already implemented.
"No" indicates that the requirement will not be implemented. For example some requirements only
applies if the implementation supports Connection Id's.
"DTLS 1.2" indicates that the requirement is the same for DTLS 1.2 and is expected to already
have been implemented. "DTLS 1.2?" indicates that this is an optional requirement for DTLS 1.2.
"TLS 1.3" indicates that the requirement is the same for TLS 1.3 and is expected to already
have been implemented.
| Requirement description | Implemented? |
|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------|
| Plaintext records MUST NOT be sent with sequence numbers that would exceed 2^48-1 | TBD |
| [legacy_record_version] MUST be set to {254, 253} for all records other than the initial ClientHello | TBD |
| [legacy_record_version] MUST be ignored for all purposes | TBD |
| Omitting the length field MUST only be used for the last record in a datagram. | No |
| If a Connection ID is negotiated, then it MUST be contained in all datagrams | No |
| Sending implementations MUST NOT mix records from multiple DTLS associations in the same datagram | TBD |
| If the second or later record has a connection ID which does not correspond to the same association used for previous records, the rest of the datagram MUST be discarded | No |
| If the first byte is alert(21), handshake(22), or ack(proposed, 26), the record MUST be interpreted as a DTLSPlaintext record | TBD |
| If the first byte is any other value, then receivers MUST check to see if the leading bits of the first byte are 001 | TBD |
| If so, the implementation MUST process the record as DTLSCiphertext; the true content type will be inside the protected portion | TBD |
| Otherwise, the record MUST be rejected as if it had failed deprotection | TBD |
| Implementations MUST send retransmissions of lost messages using the same epoch and keying material as the original transmission | TBD |
| Implementations MUST either abandon an association or rekey prior to allowing the sequence number to wrap. | DTLS 1.2? |
| Implementations MUST NOT allow the epoch to wrap, but instead MUST establish a new association, terminating the old association. | DTLS 1.2 |
| Receivers MUST reject shorter records [Ciphertexts lengths less than 16 bytes] as if they had failed deprotection | TBD |
| Senders MUST pad short plaintexts out | TBD |
| cipher suites, which are not based on AES or ChaCha20, MUST define their own record sequence number encryption in order to be used with DTLS | N/A |
| Each DTLS record MUST fit within a single datagram | DTLS 1.2 |
| The first byte of the datagram payload MUST be the beginning of a record | DTLS 1.2 |
| Records MUST NOT span datagrams | DTLS 1.2 |
| [For DTLS over TCP or SCTP] the upper layer protocol MUST NOT write any record that exceeds the maximum record size of 2^14 bytes | DTLS 1.2 |
| [If there is a transport protocol indication that the PMTU was exceeded] then the DTLS record layer MUST inform the upper layer protocol of the error | DTLS 1.2 |
| The received record counter for an epoch MUST be initialized to zero when that epoch is first used. | TBD |
| For each received record, the receiver MUST verify that the record contains a sequence number that does not duplicate the sequence number of any other record | DTLS 1.2 |
| The window MUST NOT be updated due to a received record until that record has been deprotected successfully | DTLS 1.2 |
| Implementations which choose to generate an alert [for invalid records] instead MUST generate fatal alerts | TBD |
| Implementations MUST count the number of received packets that fail authentication with each key. | TBD |
| Therefore, TLS_AES_128_CCM_8_SHA256 MUST NOT be used in DTLS without additional safeguards against forgery. | No |
| Implementations MUST set usage limits for AEAD_AES_128_CCM_8 based on an understanding of any additional forgery protections that are used. | TBD |
| Any TLS cipher suite that is specified for use with DTLS MUST define limits on the use of the associated AEAD function | N/A |
| DTLS servers MUST NOT echo the "legacy_session_id" value from the client | TBD |
| endpoints MUST NOT send ChangeCipherSpec messages | TBD |
| The client MUST send a new ClientHello with the cookie added as an extension | TBD |
| the legacy_cookie field in the ClientHello message MUST be set to a zero-length vector | TBD |
| When responding to a HelloRetryRequest, the client MUST create a new ClientHello message following the description in Section 4.1.2 of [TLS13] | TBD |
| Clients MUST be prepared to do a cookie exchange with every handshake. | DTLS 1.2 |
| If a server receives a ClientHello with an invalid cookie, it MUST terminate the handshake with an "illegal_parameter" alert | TBD |
| clients MUST abort the handshake with an "unexpected_message" alert in response to any second HelloRetryRequest which was sent in the same connection | TLS 1.3 |
| If the sequence number is less than next_receive_seq, the message MUST be discarded | DTLS 1.2 |
| DTLSv1.3-compliant implementations MUST NOT use the HelloVerifyRequest to execute a return-routability check. | TBD |
| A dual-stack DTLS 1.2 / DTLSv1.3 client MUST, however, be prepared to interact with a DTLS 1.2 server | TBD |
| the legacy_version field MUST be set to {254, 253} | TBD |
| A client which has a cached session ID set by a pre-DTLSv1.3 server SHOULD set this field to that value. Otherwise, it MUST be set as a zero-length vector | TBD |
| A DTLSv1.3-only client MUST set the legacy_cookie field to zero length | TBD |
| If a DTLSv1.3 ClientHello is received with any other value in this field [ie. legacy_cookie], the server MUST abort the handshake with an "illegal_parameter" alert | TBD |
| When transmitting the handshake message, the sender divides the message into a series of N contiguous data ranges. The ranges MUST NOT overlap | DTLS 1.2? |
| Each handshake message fragment that is placed into a record MUST be delivered in a single UDP datagram | DTLS 1.2? |
| When a DTLS implementation receives a handshake message fragment corresponding to the next expected handshake message sequence number, it MUST process it | DTLS 1.2? |
| DTLS implementations MUST be able to handle overlapping fragment ranges | DTLS 1.2 |
| Senders MUST NOT change handshake message bytes upon retransmission | TBD |
| when in the FINISHED state, the server MUST respond to retransmission of the client's final flight with a retransmit of its ACK | TBD |
| Implementations MUST either discard or buffer all application data records for epoch 3 and above until they have received the Finished message from the peer | TBD |
| implementations MUST NOT send KeyUpdate, NewConnectionId, or RequestConnectionId messages if an earlier message of the same type has not yet been acknowledged | TBD |
| Any data received with an epoch/sequence number pair after that of a valid received closure alert MUST be ignored | TBD |
| [The server] MUST NOT destroy the existing association until the client has demonstrated reachability | DTLS 1.2 |
| After a correct Finished message is received, the server MUST abandon the previous association | DTLS 1.2 |
| If a DTLS implementation would need to wrap the epoch value, it MUST terminate the connection. | DTLS 1.2 |
| Implementations MUST NOT acknowledge records containing handshake messages or fragments which have not been processed or buffered | TBD |
| For post-handshake messages, ACKs SHOULD be sent once for each received and processed handshake record | TBD |
| During the handshake, ACK records MUST be sent with an epoch which is equal to or higher than the record which is being acknowledged | TBD |
| After the handshake, implementations MUST use the highest available sending epoch | TBD |
| flights MUST be ACKed unless they are implicitly acknowledged | TBD |
| ACKs MUST NOT be sent for records of any content type other than handshake or for records which cannot be deprotected | TBD |
| Once all the messages in a flight have been acknowledged, the implementation MUST cancel all retransmissions of that flight | TBD |
| Implementations MUST treat a record as having been acknowledged if it appears in any ACK | TBD |
| the receipt of any record responding to a given flight MUST be taken as an implicit acknowledgement for the entire flight to which it is responding. | TBD |
| KeyUpdates MUST be acknowledged | TBD |
| implementations MUST NOT send records with the new keys or send a new KeyUpdate until the previous KeyUpdate has been acknowledged | TBD |
| receivers MUST retain the pre-update keying material until receipt and successful decryption of a message using the new keys | TBD |
| sending implementations MUST NOT allow the epoch to exceed 2^48-1 | DTLS 1.2 |
| receiving implementations MUST NOT enforce this rule [i.e. epoch exceeding 2^48-1] | TBD |
| sending implementations MUST NOT send its own KeyUpdate if that would cause it to exceed these limits [i.e. epoch exceeding 2^48-1] | TBD |
| If usage is set to "cid_immediate", then one of the new CIDs MUST be used immediately for all future records. | No |
| Endpoints MUST NOT have more than one NewConnectionId message outstanding | No |
| Implementations which either did not negotiate the "connection_id" extension or which have negotiated receiving an empty CID MUST NOT send NewConnectionId | No |
| Implementations MUST NOT send RequestConnectionId when sending an empty Connection ID | No |
| Implementations which detect a violation of these rules MUST terminate the connection with an "unexpected_message" alert | TBD |
| Endpoints MUST NOT send a RequestConnectionId message when an existing request is still unfulfilled | No |
| Endpoints MUST NOT send either of these messages [i.e. NewConnectionId and RequestConnectionId] if they did not negotiate a CID. | No |
| If an implementation receives these messages [i.e. NewConnectionId, RequestConnectionId] when CIDs were not negotiated, it MUST abort the connection with an "unexpected_message" alert | TBD |
| If no CID is negotiated, then the receiver MUST reject any records it receives that contain a CID. | TBD |
| The cookie MUST depend on the client's address. | Yes |
| It MUST NOT be possible for anyone other than the issuing entity to generate cookies that are accepted as valid by that entity. | TBD |
| DTLS implementations MUST NOT update the address they send to in response to packets from a different address | TBD |

View file

@ -365,7 +365,7 @@ See L<ossl_store-file(7)> for more information on the C<file:> scheme.
A file containing a list of certificates whose subject names will be sent
to the server in the B<certificate_authorities> extension. Only supported
for TLS 1.3
for TLS 1.3 and DTLS 1.3
=item B<-dane_tlsa_domain> I<domain>
@ -554,13 +554,13 @@ This option must be provided in order to use a PSK cipher.
=item B<-psk_session> I<file>
Use the pem encoded SSL_SESSION data stored in I<file> as the basis of a PSK.
Note that this will only work if TLSv1.3 is negotiated.
Note that this will only work if (D)TLSv1.3 is negotiated.
=item B<-sctp>
Use SCTP for the transport protocol instead of UDP in DTLS. Must be used in
conjunction with B<-dtls>, B<-dtls1> or B<-dtls1_2>. This option is only
available where OpenSSL has support for SCTP enabled.
conjunction with B<-dtls>, B<-dtls1>, B<-dtls1_2> or B<-dtls1_3>. This option
is only available where OpenSSL has support for SCTP enabled.
=item B<-sctp_label_bug>
@ -630,11 +630,11 @@ option enables various workarounds.
=item B<-no_tx_cert_comp>
Disables support for sending TLSv1.3 compressed certificates.
Disables support for sending (D)TLSv1.3 compressed certificates.
=item B<-no_rx_cert_comp>
Disables support for receiving TLSv1.3 compressed certificate.
Disables support for receiving (D)TLSv1.3 compressed certificate.
=item B<-comp>
@ -763,7 +763,8 @@ for example "http/1.1" or "spdy/3".
An empty list of protocols is treated specially and will cause the
client to advertise support for the TLS extension but disconnect just
after receiving ServerHello with a list of server supported protocols.
The flag B<-nextprotoneg> cannot be specified if B<-tls1_3> is used.
The flag B<-nextprotoneg> cannot be specified if B<-tls1_3> or B<-dtls1_3> is
used.
=item B<-ct>, B<-noct>
@ -793,8 +794,8 @@ data and when the server accepts the early data.
=item B<-enable_pha>
For TLSv1.3 only, send the Post-Handshake Authentication extension. This will
happen whether or not a certificate has been provided via B<-cert>.
For (D)TLSv1.3 only, send the Post-Handshake Authentication extension. This
will happen whether or not a certificate has been provided via B<-cert>.
=item B<-use_srtp> I<value>
@ -905,7 +906,7 @@ End the current SSL connection and exit.
=item B<R>
Renegotiate the SSL session (TLSv1.2 and below only).
Renegotiate the SSL session ((D)TLSv1.2 and below only).
=item B<C>
@ -913,11 +914,11 @@ Attempt to reconnect to the server using a resumption handshake.
=item B<k>
Send a key update message to the server (TLSv1.3 only)
Send a key update message to the server ((D)TLSv1.3 only)
=item B<K>
Send a key update message to the server and request one back (TLSv1.3 only)
Send a key update message to the server and request one back ((D)TLSv1.3 only)
=back
@ -958,7 +959,7 @@ Reconnect to the peer and attempt a resumption handshake
=item B<keyup>
Send a Key Update message. TLSv1.3 only. This command takes an optional
Send a Key Update message. (D)TLSv1.3 only. This command takes an optional
argument. If the argument "req" is supplied then the peer is also requested to
update its keys. Otherwise if "noreq" is supplied the peer is not requested
to update its keys. The default is "req".

View file

@ -620,11 +620,11 @@ option enables various workarounds.
=item B<-no_tx_cert_comp>
Disables support for sending TLSv1.3 compressed certificates.
Disables support for sending (D)TLSv1.3 compressed certificates.
=item B<-no_rx_cert_comp>
Disables support for receiving TLSv1.3 compressed certificates.
Disables support for receiving (D)TLSv1.3 compressed certificates.
=item B<-no_comp>
@ -645,14 +645,14 @@ more information.
=item B<-no_ticket>
Disable RFC4507bis session ticket support. This option has no effect if TLSv1.3
is negotiated. See B<-num_tickets>.
Disable RFC4507bis session ticket support. This option has no effect if
(D)TLSv1.3 is negotiated. See B<-num_tickets>.
=item B<-num_tickets>
Control the number of tickets that will be sent to the client after a full
handshake in TLSv1.3. The default number of tickets is 2. This option does not
affect the number of tickets sent after a resumption handshake.
handshake in (D)TLSv1.3. The default number of tickets is 2. This option does
not affect the number of tickets sent after a resumption handshake.
=item B<-serverpref>
@ -766,8 +766,8 @@ connect to that peer and complete the handshake.
=item B<-sctp>
Use SCTP for the transport protocol instead of UDP in DTLS. Must be used in
conjunction with B<-dtls>, B<-dtls1> or B<-dtls1_2>. This option is only
available where OpenSSL has support for SCTP enabled.
conjunction with B<-dtls>, B<-dtls1>, B<-dtls1_2> or B<-dtls1_3>. This option
is only available where OpenSSL has support for SCTP enabled.
=item B<-sctp_label_bug>
@ -795,7 +795,8 @@ The I<val> list is a comma-separated list of supported protocol
names. The list should contain the most desirable protocols first.
Protocol names are printable ASCII strings, for example "http/1.1" or
"spdy/3".
The flag B<-nextprotoneg> cannot be specified if B<-tls1_3> is used.
The flag B<-nextprotoneg> cannot be specified if B<-tls1_3> or B<-dtls1_3>
is used.
=item B<-ktls>
@ -843,16 +844,16 @@ B<-WWW>, B<-HTTP> or B<-rev>.
=item B<-stateless>
Require TLSv1.3 cookies.
Require (D)TLSv1.3 cookies.
=item B<-anti_replay>, B<-no_anti_replay>
Switches replay protection on or off, respectively. Replay protection is on by
default unless overridden by a configuration file. When it is on, OpenSSL will
automatically detect if a session ticket has been used more than once, TLSv1.3
has been negotiated, and early data is enabled on the server. A full handshake
is forced if a session ticket is used a second or subsequent time. Any early
data that was sent will be rejected.
automatically detect if a session ticket has been used more than once,
(D)TLSv1.3 has been negotiated, and early data is enabled on the server. A full
handshake is forced if a session ticket is used a second or subsequent time.
Any early data that was sent will be rejected.
=item B<-tfo>
@ -928,12 +929,12 @@ End the current SSL connection and exit.
=item B<r>
Renegotiate the SSL session (TLSv1.2 and below only).
Renegotiate the SSL session ((D)TLSv1.2 and below only).
=item B<R>
Renegotiate the SSL session and request a client certificate (TLSv1.2 and below
only).
Renegotiate the SSL session and request a client certificate ((D)TLSv1.2 and
below only).
=item B<P>
@ -946,15 +947,15 @@ Print out some session cache status information.
=item B<k>
Send a key update message to the client (TLSv1.3 only)
Send a key update message to the client ((D)TLSv1.3 only).
=item B<K>
Send a key update message to the client and request one back (TLSv1.3 only)
Send a key update message to the client and request one back ((D)TLSv1.3 only).
=item B<c>
Send a certificate request to the client (TLSv1.3 only)
Send a certificate request to the client ((D)TLSv1.3 only).
=back

View file

@ -609,12 +609,12 @@ the B<no_> options.
The B<no_*> options do not work with B<s_time> and B<ciphers> commands but work with
B<s_client> and B<s_server> commands.
=item B<-dtls>, B<-dtls1>, B<-dtls1_2>
=item B<-dtls>, B<-dtls1>, B<-dtls1_2>, B<-dtls1_3>
These options specify to use DTLS instead of TLS.
With B<-dtls>, clients will negotiate any supported DTLS protocol version.
Use the B<-dtls1> or B<-dtls1_2> options to support only DTLS1.0 or DTLS1.2,
respectively.
Use the B<-dtls1>, B<-dtls1_2> or B<-dtls1_3> options to support only DTLS1.0,
DTLS1.2 or DTLS1.3 respectively.
=back

View file

@ -74,7 +74,7 @@ different to the digest used to calculate the MAC for encrypted records.
SSL_CIPHER_get_kx_nid() returns the key exchange NID corresponding to the method
used by B<c>. If there is no key exchange, then B<NID_undef> is returned.
If any appropriate key exchange algorithm can be used (as in the case of TLS 1.3
If any appropriate key exchange algorithm can be used (as in the case of (D)TLS 1.3
cipher suites) B<NID_kx_any> is returned. Examples (not comprehensive):
NID_kx_rsa
@ -85,7 +85,7 @@ cipher suites) B<NID_kx_any> is returned. Examples (not comprehensive):
SSL_CIPHER_get_auth_nid() returns the authentication NID corresponding to the method
used by B<c>. If there is no authentication, then B<NID_undef> is returned.
If any appropriate authentication algorithm can be used (as in the case of
TLS 1.3 cipher suites) B<NID_auth_any> is returned. Examples (not comprehensive):
(D)TLS 1.3 cipher suites) B<NID_auth_any> is returned. Examples (not comprehensive):
NID_auth_rsa
NID_auth_ecdsa

View file

@ -74,7 +74,7 @@ B<SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION>.
=item B<-no_renegotiation>
Disables all attempts at renegotiation in TLSv1.2 and earlier, same as setting
Disables all attempts at renegotiation in (D)TLSv1.2 and earlier, same as setting
B<SSL_OP_NO_RENEGOTIATION>.
=item B<-no_resumption_on_reneg>
@ -95,8 +95,8 @@ Only used by servers. Requires B<-serverpref>.
=item B<-allow_no_dhe_kex>
In TLSv1.3 allow a non-(ec)dhe based key exchange mode on resumption. This means
that there will be no forward secrecy for the resumed session.
In (D)TLSv1.3 allow a non-(ec)dhe based key exchange mode on resumption. This
means that there will be no forward secrecy for the resumed session.
=item B<-prefer_no_dhe_kex>
@ -111,7 +111,7 @@ B<SSL_CERT_FLAG_TLS_STRICT>.
=item B<-sigalgs> I<algs>
This sets the supported signature algorithms for TLSv1.2 and TLSv1.3.
This sets the supported signature algorithms for (D)TLSv1.2 and (D)TLSv1.3.
For clients this value is used directly for the supported signature
algorithms extension. For servers it is used to determine which signature
algorithms to support.
@ -123,7 +123,7 @@ B<algorithm> is one of B<RSA>, B<DSA> or B<ECDSA> and
B<hash> is a supported algorithm OID short name such as B<SHA1>, B<SHA224>,
B<SHA256>, B<SHA384> or B<SHA512>. Note: algorithm and hash names are case
sensitive. B<signature_scheme> is one of the signature schemes defined in
TLSv1.3, specified using the IETF name, e.g., B<ecdsa_secp256r1_sha256>,
(D)TLSv1.3, specified using the IETF name, e.g., B<ecdsa_secp256r1_sha256>,
B<ed25519>, or B<rsa_pss_pss_sha256>. Additional providers may make available
further algorithms via the TLS-SIGALG capability.
See L<provider-base(7)>.
@ -133,12 +133,12 @@ activated providers are permissible.
Note: algorithms which specify a PKCS#1 v1.5 signature scheme (either by
using B<RSA> as the B<algorithm> or by using one of the B<rsa_pkcs1_*>
identifiers) are ignored in TLSv1.3 and will not be negotiated.
identifiers) are ignored in (D)TLSv1.3 and will not be negotiated.
=item B<-client_sigalgs> I<algs>
This sets the supported signature algorithms associated with client
authentication for TLSv1.2 and TLSv1.3. For servers the B<algs> is used
authentication for (D)TLSv1.2 and (D)TLSv1.3. For servers the B<algs> is used
in the B<signature_algorithms> field of a B<CertificateRequest> message.
For clients it is used to determine which signature algorithm to use with
the client certificate. If a server does not request a certificate this
@ -151,9 +151,9 @@ value set for B<-sigalgs> will be used instead.
This sets the supported groups. For clients, the groups are sent using
the supported groups extension. For servers, it is used to determine which
group to use. This setting affects groups used for signatures (in TLSv1.2
group to use. This setting affects groups used for signatures (in (D)TLSv1.2
and earlier) and key exchange. The first group listed will also be used
for the B<key_share> sent by a client in a TLSv1.3 B<ClientHello>.
for the B<key_share> sent by a client in a (D)TLSv1.3 B<ClientHello>.
The B<groups> argument is a colon separated list of groups. The group can
be either the B<NIST> name (e.g. B<P-256>), some other commonly used name
@ -161,7 +161,7 @@ where applicable (e.g. B<X25519>, B<ffdhe2048>) or an OpenSSL OID name
(e.g. B<prime256v1>). Group names are case sensitive. The list should be
in order of preference with the most preferred group first.
Groups for B<TLSv1.3> in the default provider are B<P-256>, B<P-384>,
Groups for B<TLSv1.3> and B<DTLSv1.3> in the default provider are B<P-256>, B<P-384>,
B<P-521>, B<X25519>, B<X448>, B<ffdhe2048>, B<ffdhe3072>, B<ffdhe4096>,
B<ffdhe6144>, B<ffdhe8192>, B<brainpoolP256r1tls13>,
B<brainpoolP384r1tls13> and B<brainpoolP512r1tls13>.
@ -179,19 +179,19 @@ by servers.
=item B<-tx_cert_comp>
Enables support for sending TLSv1.3 compressed certificates.
Enables support for sending (D)TLSv1.3 compressed certificates.
=item B<-no_tx_cert_comp>
Disables support for sending TLSv1.3 compressed certificates.
Disables support for sending (D)TLSv1.3 compressed certificates.
=item B<-rx_cert_comp>
Enables support for receiving TLSv1.3 compressed certificates.
Enables support for receiving (D)TLSv1.3 compressed certificates.
=item B<-no_rx_cert_comp>
Disables support for receiving TLSv1.3 compressed certificates.
Disables support for receiving (D)TLSv1.3 compressed certificates.
=item B<-comp>
@ -202,24 +202,24 @@ curve can be either the B<NIST> name (e.g. B<P-256>) or an OpenSSL OID name
=item B<-cipher> I<ciphers>
Sets the TLSv1.2 and below ciphersuite list to B<ciphers>. This list will be
combined with any configured TLSv1.3 ciphersuites. Note: syntax checking
Sets the (D)TLSv1.2 and below ciphersuite list to B<ciphers>. This list will be
combined with any configured (D)TLSv1.3 ciphersuites. Note: syntax checking
of B<ciphers> is currently not performed unless a B<SSL> or B<SSL_CTX>
structure is associated with B<ctx>.
=item B<-ciphersuites> I<1.3ciphers>
Sets the available ciphersuites for TLSv1.3 to value. This is a
colon-separated list of TLSv1.3 ciphersuite names in order of preference. This
list will be combined any configured TLSv1.2 and below ciphersuites.
Sets the available ciphersuites for (D)TLSv1.3 to value. This is a
colon-separated list of (D)TLSv1.3 ciphersuite names in order of preference.
This list will be combined any configured (D)TLSv1.2 and below ciphersuites.
See L<openssl-ciphers(1)> for more information.
=item B<-min_protocol> I<minprot>, B<-max_protocol> I<maxprot>
Sets the minimum and maximum supported protocol.
Currently supported protocol values are B<SSLv3>, B<TLSv1>, B<TLSv1.1>,
B<TLSv1.2>, B<TLSv1.3> for TLS; B<DTLSv1>, B<DTLSv1.2> for DTLS, and B<None>
for no limit.
B<TLSv1.2>, B<TLSv1.3> for TLS; B<DTLSv1>, B<DTLSv1.2>, B<DTLSv1.3> for DTLS,
and B<None> for no limit.
If either the lower or upper bound is not specified then only the other bound
applies, if specified.
If your application supports both TLS and DTLS you can specify any of these
@ -230,15 +230,11 @@ deprecated alternative commands below.
=item B<-record_padding> I<padding>
Controls use of TLSv1.3 record layer padding. B<padding> is a string of the
form "number[,number]" where the (required) first number is the padding block
size (in octets) for application data, and the optional second number is the
padding block size for handshake and alert messages. If the optional second
number is omitted, the same padding will be applied to all messages.
Padding attempts to pad TLSv1.3 records so that they are a multiple of the set
length on send. A value of 0 or 1 turns off padding as relevant. Otherwise, the
values must be >1 or <=16384.
==== BASE ====
Attempts to pad TLSv1.3 records so that they are a multiple of B<padding>
in length on send. A B<padding> of 0 or 1 turns off padding. Otherwise,
the B<padding> must be >1 or <=16384.
==== BASE ====
=item B<-debug_broken_protocol>
@ -290,11 +286,11 @@ B<-max_protocol> instead.
Switches replay protection, on or off respectively. With replay protection on,
OpenSSL will automatically detect if a session ticket has been used more than
once, TLSv1.3 has been negotiated, and early data is enabled on the server. A
full handshake is forced if a session ticket is used a second or subsequent
once, (D)TLSv1.3 has been negotiated, and early data is enabled on the server.
A full handshake is forced if a session ticket is used a second or subsequent
time. Anti-Replay is on by default unless overridden by a configuration file and
is only used by servers. Anti-replay measures are required for compliance with
the TLSv1.3 specification. Some applications may be able to mitigate the replay
the (D)TLSv1.3 specification. Some applications may be able to mitigate the replay
risks in other ways and in such cases the built-in OpenSSL functionality is not
required. Switching off anti-replay is equivalent to B<SSL_OP_NO_ANTI_REPLAY>.
@ -314,16 +310,16 @@ Note: the command prefix (if set) alters the recognised B<option> values.
=item B<CipherString>
Sets the ciphersuite list for TLSv1.2 and below to B<value>. This list will be
combined with any configured TLSv1.3 ciphersuites. Note: syntax
Sets the ciphersuite list for (D)TLSv1.2 and below to B<value>. This list will
be combined with any configured (D)TLSv1.3 ciphersuites. Note: syntax
checking of B<value> is currently not performed unless an B<SSL> or B<SSL_CTX>
structure is associated with B<ctx>.
=item B<Ciphersuites>
Sets the available ciphersuites for TLSv1.3 to B<value>. This is a
colon-separated list of TLSv1.3 ciphersuite names in order of preference. This
list will be combined any configured TLSv1.2 and below ciphersuites.
Sets the available ciphersuites for (D)TLSv1.3 to B<value>. This is a
colon-separated list of (D)TLSv1.3 ciphersuite names in order of preference.
This list will be combined any configured (D)TLSv1.2 and below ciphersuites.
See L<openssl-ciphers(1)> for more information.
=item B<Certificate>
@ -351,7 +347,7 @@ if certificate operations are permitted.
This option indicates a file containing a set of certificates in PEM form.
The subject names of the certificates are sent to the peer in the
B<certificate_authorities> extension for TLS 1.3 (in ClientHello or
B<certificate_authorities> extension for (D)TLSv1.3 (in ClientHello or
CertificateRequest) or in a certificate request for previous versions or
TLS.
@ -368,19 +364,15 @@ operations are permitted.
=item B<RecordPadding>
Controls use of TLSv1.3 record layer padding. B<value> is a string of the form
"number[,number]" where the (required) first number is the padding block size
(in octets) for application data, and the optional second number is the padding
block size for handshake and alert messages. If the optional second number is
omitted, the same padding will be applied to all messages.
Padding attempts to pad TLSv1.3 records so that they are a multiple of the set
length on send. A value of 0 or 1 turns off padding as relevant. Otherwise, the
values must be >1 or <=16384.
==== BASE ====
Attempts to pad TLSv1.3 records so that they are a multiple of B<value> in
length on send. A B<value> of 0 or 1 turns off padding. Otherwise, the
B<value> must be >1 or <=16384.
==== BASE ====
=item B<SignatureAlgorithms>
This sets the supported signature algorithms for TLSv1.2 and TLSv1.3.
This sets the supported signature algorithms for (D)TLSv1.2 and (D)TLSv1.3.
For clients this
value is used directly for the supported signature algorithms extension. For
servers it is used to determine which signature algorithms to support.
@ -392,7 +384,7 @@ B<algorithm> is one of B<RSA>, B<DSA> or B<ECDSA> and B<hash> is a supported
algorithm OID short name such as B<SHA1>, B<SHA224>, B<SHA256>, B<SHA384>
or B<SHA512>.
Note: algorithm and hash names are case sensitive.
B<signature_scheme> is one of the signature schemes defined in TLSv1.3,
B<signature_scheme> is one of the signature schemes defined in (D)TLSv1.3,
specified using the IETF name, e.g., B<ecdsa_secp256r1_sha256>, B<ed25519>,
or B<rsa_pss_pss_sha256>.
Additional providers may make available further algorithms via the TLS_SIGALG
@ -403,12 +395,12 @@ activated providers are permissible.
Note: algorithms which specify a PKCS#1 v1.5 signature scheme (either by
using B<RSA> as the B<algorithm> or by using one of the B<rsa_pkcs1_*>
identifiers) are ignored in TLSv1.3 and will not be negotiated.
identifiers) are ignored in (D)TLSv1.3 and will not be negotiated.
=item B<ClientSignatureAlgorithms>
This sets the supported signature algorithms associated with client
authentication for TLSv1.2 and TLSv1.3.
authentication for (D)TLSv1.2 and (D)TLSv1.3.
For servers the value is used in the
B<signature_algorithms> field of a B<CertificateRequest> message.
For clients it is
@ -423,8 +415,8 @@ the value set for B<SignatureAlgorithms> will be used instead.
This sets the supported groups. For clients, the groups are
sent using the supported groups extension. For servers, it is used
to determine which group to use. This setting affects groups used for
signatures (in TLSv1.2 and earlier) and key exchange. The first group listed
will also be used for the B<key_share> sent by a client in a TLSv1.3
signatures (in (D)TLSv1.2 and earlier) and key exchange. The first group listed
will also be used for the B<key_share> sent by a client in a (D)TLSv1.3
B<ClientHello>.
The B<value> argument is a colon separated list of groups. The group can be
@ -433,9 +425,9 @@ applicable (e.g. B<X25519>, B<ffdhe2048>) or an OpenSSL OID name
(e.g. B<prime256v1>). Group names are case sensitive. The list should be in
order of preference with the most preferred group first.
Currently supported groups for B<TLSv1.3> are B<P-256>, B<P-384>, B<P-521>,
B<X25519>, B<X448>, B<ffdhe2048>, B<ffdhe3072>, B<ffdhe4096>, B<ffdhe6144>,
B<ffdhe8192>.
Currently supported groups for B<TLSv1.3> and B<DTLSv1.3> are B<P-256>,
B<P-384>, B<P-521>, B<X25519>, B<X448>, B<ffdhe2048>, B<ffdhe3072>,
B<ffdhe4096>, B<ffdhe6144>, B<ffdhe8192>.
=item B<Curves>
@ -446,7 +438,7 @@ This is a synonym for the "Groups" command.
This sets the minimum supported SSL, TLS or DTLS version.
Currently supported protocol values are B<SSLv3>, B<TLSv1>, B<TLSv1.1>,
B<TLSv1.2>, B<TLSv1.3>, B<DTLSv1> and B<DTLSv1.2>.
B<TLSv1.2>, B<TLSv1.3>, B<DTLSv1>, B<DTLSv1.2> and B<DTLSv1.3>.
The SSL and TLS bounds apply only to TLS-based contexts, while the DTLS bounds
apply only to DTLS-based contexts.
The command can be repeated with one instance setting a TLS bound, and the
@ -458,7 +450,7 @@ The value B<None> applies to both types of contexts and disables the limits.
This sets the maximum supported SSL, TLS or DTLS version.
Currently supported protocol values are B<SSLv3>, B<TLSv1>, B<TLSv1.1>,
B<TLSv1.2>, B<TLSv1.3>, B<DTLSv1> and B<DTLSv1.2>.
B<TLSv1.2>, B<TLSv1.3>, B<DTLSv1>, B<DTLSv1.2> and B<DTLSv1.3>.
The SSL and TLS bounds apply only to TLS-based contexts, while the DTLS bounds
apply only to DTLS-based contexts.
The command can be repeated with one instance setting a TLS bound, and the
@ -481,7 +473,7 @@ Only enabling some protocol versions does not disable the other protocol
versions.
Currently supported protocol values are B<SSLv3>, B<TLSv1>, B<TLSv1.1>,
B<TLSv1.2>, B<TLSv1.3>, B<DTLSv1> and B<DTLSv1.2>.
B<TLSv1.2>, B<TLSv1.3>, B<DTLSv1>, B<DTLSv1.2> and B<DTLSv1.3>.
The special value B<ALL> refers to all supported versions.
This can't enable protocols that are disabled using B<MinProtocol>
@ -536,7 +528,7 @@ Only used by servers.
B<NoResumptionOnRenegotiation>: set
B<SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION> flag. Only used by servers.
B<NoRenegotiation>: disables all attempts at renegotiation in TLSv1.2 and
B<NoRenegotiation>: disables all attempts at renegotiation in (D)TLSv1.2 and
earlier, same as setting B<SSL_OP_NO_RENEGOTIATION>.
B<UnsafeLegacyRenegotiation>: permits the use of unsafe legacy renegotiation.
@ -549,7 +541,7 @@ B<EncryptThenMac>: use encrypt-then-mac extension, enabled by
default. Inverse of B<SSL_OP_NO_ENCRYPT_THEN_MAC>: that is,
B<-EncryptThenMac> is the same as setting B<SSL_OP_NO_ENCRYPT_THEN_MAC>.
B<AllowNoDHEKEX>: In TLSv1.3 allow a non-(ec)dhe based key exchange mode on
B<AllowNoDHEKEX>: In (D)TLSv1.3 allow a non-(ec)dhe based key exchange mode on
resumption. This means that there will be no forward secrecy for the resumed
session. Equivalent to B<SSL_OP_ALLOW_NO_DHE_KEX>.
@ -565,10 +557,10 @@ option is set by default. A future version of OpenSSL may not set this by
default. Equivalent to B<SSL_OP_ENABLE_MIDDLEBOX_COMPAT>.
B<AntiReplay>: If set then OpenSSL will automatically detect if a session ticket
has been used more than once, TLSv1.3 has been negotiated, and early data is
has been used more than once, (D)TLSv1.3 has been negotiated, and early data is
enabled on the server. A full handshake is forced if a session ticket is used a
second or subsequent time. This option is set by default and is only used by
servers. Anti-replay measures are required to comply with the TLSv1.3
servers. Anti-replay measures are required to comply with the (D)TLSv1.3
specification. Some applications may be able to mitigate the replay risks in
other ways and in such cases the built-in OpenSSL functionality is not required.
Disabling anti-replay is equivalent to setting B<SSL_OP_NO_ANTI_REPLAY>.
@ -628,13 +620,13 @@ B<RequestPostHandshake> configures the connection to support requests but does
not require a certificate from the client post-handshake. A certificate will
not be requested during the initial handshake. The server application must
provide a mechanism to request a certificate post-handshake. Servers only.
TLSv1.3 only.
(D)TLSv1.3 only.
B<RequiresPostHandshake> configures the connection to support requests and
requires a certificate from the client post-handshake: an error occurs if the
client does not present a certificate. A certificate will not be requested
during the initial handshake. The server application must provide a mechanism
to request a certificate post-handshake. Servers only. TLSv1.3 only.
to request a certificate post-handshake. Servers only. (D)TLSv1.3 only.
=item B<ClientCAFile>, B<ClientCAPath>

View file

@ -47,7 +47,7 @@ server to the client when requesting a client certificate. So any list of CA
names set is never sent from client to server and the list of CA names retrieved
by SSL_get0_peer_CA_list() is always B<NULL>.
For TLS 1.3 the list of CA names is sent using the B<certificate_authorities>
For (D)TLS 1.3 the list of CA names is sent using the B<certificate_authorities>
extension and may be sent by a client (in the ClientHello message) or by
a server (when requesting a certificate).

View file

@ -32,7 +32,7 @@ SSL_CTX_set1_sigalgs_list() and SSL_set1_sigalgs_list() set the supported
signature algorithms for B<ctx> or B<ssl>. The B<str> parameter
must be a null terminated string consisting of a colon separated list of
elements, where each element is either a combination of a public key
algorithm and a digest separated by B<+>, or a TLS 1.3-style named
algorithm and a digest separated by B<+>, or a (D)TLS 1.3-style named
SignatureScheme such as rsa_pss_pss_sha256. If a list entry is preceded
with the C<?> character, it will be ignored if an implementation is missing.
@ -80,7 +80,7 @@ The short or long name values for digests can be used in a string (for
example "MD5", "SHA1", "SHA224", "SHA256", "SHA384", "SHA512") and
the public key algorithm strings "RSA", "RSA-PSS", "DSA" or "ECDSA".
The TLS 1.3 signature scheme names (such as "rsa_pss_pss_sha256") can also
The (D)TLS 1.3 signature scheme names (such as "rsa_pss_pss_sha256") can also
be used with the B<_list> forms of the API.
The use of MD5 as a digest is strongly discouraged due to security weaknesses.

View file

@ -40,7 +40,7 @@ automatically use the lowest or highest version supported by the library.
Currently supported versions are B<SSL3_VERSION>, B<TLS1_VERSION>,
B<TLS1_1_VERSION>, B<TLS1_2_VERSION>, B<TLS1_3_VERSION> for TLS and
B<DTLS1_VERSION>, B<DTLS1_2_VERSION> for DTLS.
B<DTLS1_VERSION>, B<DTLS1_2_VERSION>, B<DTLS1_3_VERSION> for DTLS.
In the current version of OpenSSL only QUICv1 is supported in conjunction with
TLSv1.3. Calling these functions on a QUIC object has no effect.

View file

@ -46,7 +46,7 @@ To issue tickets after other events (such as application-layer changes),
SSL_new_session_ticket() is used by a server application to request that a new
ticket be sent when it is safe to do so. New tickets are only allowed to be
sent in this manner after the initial handshake has completed, and only for
TLS 1.3 connections. By default, the ticket generation and transmission are
(D)TLS 1.3 connections. By default, the ticket generation and transmission are
delayed until the server is starting a new write operation, so that it is
bundled with other application data being written and properly aligned to a
record boundary. If the connection was at a record boundary when

View file

@ -296,10 +296,11 @@ When performing renegotiation as a server, always start a new session
handshake). This option is not needed for clients.
=item SSL_OP_NO_SSLv3, SSL_OP_NO_TLSv1, SSL_OP_NO_TLSv1_1,
SSL_OP_NO_TLSv1_2, SSL_OP_NO_TLSv1_3, SSL_OP_NO_DTLSv1, SSL_OP_NO_DTLSv1_2
SSL_OP_NO_TLSv1_2, SSL_OP_NO_TLSv1_3,
SSL_OP_NO_DTLSv1, SSL_OP_NO_DTLSv1_2, SSL_OP_NO_DTLSv1_3
These options turn off the SSLv3, TLSv1, TLSv1.1, TLSv1.2 or TLSv1.3 protocol
versions with TLS or the DTLSv1, DTLSv1.2 versions with DTLS,
versions with TLS or the DTLSv1, DTLSv1.2, DTLSv1.3 versions with DTLS,
respectively.
As of OpenSSL 1.1.0, these options are deprecated, use
L<SSL_CTX_set_min_proto_version(3)> and

View file

@ -72,8 +72,8 @@ The validity of a chain is determined by checking if it matches a supported
signature algorithm, supported curves and in the case of client authentication
certificate types and issuer names.
Since the supported signature algorithms extension is only used in TLS 1.2,
TLS 1.3 and DTLS 1.2 the results for earlier versions of TLS and DTLS may not
Since the supported signature algorithms extension is only used in (D)TLS 1.2
and (D)TLS 1.3 the results for earlier versions of TLS and DTLS may not
be very useful. Applications may wish to specify a different "legacy" chain
for earlier versions of TLS or DTLS.

View file

@ -31,7 +31,7 @@ accordance with RFC5705 (for TLSv1.2 and below) or RFC8446 (for TLSv1.3).
SSL_export_keying_material() derives keying material using
the F<exporter_master_secret> established in the handshake.
SSL_export_keying_material_early() is only usable with TLSv1.3, and derives
SSL_export_keying_material_early() is only usable with (D)TLSv1.3, and derives
keying material using the F<early_exporter_master_secret> (as defined in the
TLS 1.3 RFC). For the client, the F<early_exporter_master_secret> is only
available when the client attempts to send 0-RTT data. For the server, it is

View file

@ -54,7 +54,7 @@ signature algorithms: after a client hello (for servers) or a certificate
request (for clients). They can (for example) be called in the certificate
callback.
Only TLS 1.2, TLS 1.3 and DTLS 1.2 currently support signature algorithms.
Only (D)TLS 1.2 and (D)TLS 1.3 currently support signature algorithms.
If these
functions are called on an earlier version of TLS or DTLS zero is returned.

View file

@ -77,6 +77,10 @@ The connection uses the DTLSv1 protocol
The connection uses the DTLSv1.2 protocol
=item DTLSv1.3
The connection uses the DTLSv1.3 protocol
=item QUICv1
The connection uses the QUICv1 protocol.
@ -125,6 +129,10 @@ The connection uses the DTLSv1 protocol
The connection uses the DTLSv1.2 protocol
=item DTLS1_3_VERSION
The connection uses the DTLSv1.3 protocol
=item OSSL_QUIC1_VERSION
The connection uses the QUICv1 protocol.

View file

@ -162,11 +162,12 @@ $OpenSSL::safe::opt_version_synopsis = ""
. "$OpenSSL::safe::opt_versiontls_synopsis\n"
. "[B<-dtls>]\n"
. "[B<-dtls1>]\n"
. "[B<-dtls1_2>]";
. "[B<-dtls1_2>]\n"
. "[B<-dtls1_3>]";
$OpenSSL::safe::opt_version_item = "\n"
. "$OpenSSL::safe::opt_versiontls_item\n"
. "\n"
. "=item B<-dtls>, B<-dtls1>, B<-dtls1_2>\n"
. "=item B<-dtls>, B<-dtls1>, B<-dtls1_2>, B<-dtls1_3>\n"
. "\n"
. "These specify the use of DTLS instead of TLS.\n"
. "See L<openssl(1)/TLS Version Options>.";

View file

@ -72,6 +72,7 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len)
if (client == NULL)
goto end;
OPENSSL_assert(SSL_set_min_proto_version(client, 0) == 1);
OPENSSL_assert(SSL_set_max_proto_version(client, 0) == 1);
OPENSSL_assert(SSL_set_cipher_list(client, "ALL:eNULL:@SECLEVEL=0") == 1);
SSL_set_tlsext_host_name(client, "localhost");
in = BIO_new(BIO_s_mem());

View file

@ -180,9 +180,9 @@ __owur static ossl_inline int ossl_assert_int(int expr, const char *exprstr,
(((unsigned long)((c)[1]))<< 8)| \
(((unsigned long)((c)[2])) )),(c)+=3)
# define l2n3(l,c) (((c)[0]=(unsigned char)(((l)>>16)&0xff), \
(c)[1]=(unsigned char)(((l)>> 8)&0xff), \
(c)[2]=(unsigned char)(((l) )&0xff)),(c)+=3)
#define l3n2(c,l) (l =((uint64_t)(*((c)++)))<<16, \
l|=((uint64_t)(*((c)++)))<< 8, \
l|=((uint64_t)(*((c)++))))
static ossl_inline int ossl_ends_with_dirsep(const char *path)
{

View file

@ -764,6 +764,18 @@ int WPACKET_finish(WPACKET *pkt);
*/
int WPACKET_fill_lengths(WPACKET *pkt);
/*
* Initialise a new sub-packet. Additionally |lenbytes| of data is preallocated
* at the current position in |pkt| to store the sub-packets length once we know
* it. The sub-packet start is set at |offset| from current position in |pkt|
* Don't call this directly. Use the convenience macros below instead.
*/
int WPACKET_start_sub_packet_at_offset_len__(WPACKET *pkt, size_t lenbytes,
size_t offset);
#define WPACKET_start_sub_packet_u24_at_offset(pkt, offset) \
WPACKET_start_sub_packet_at_offset_len__((pkt), 3, (offset))
/*
* Initialise a new sub-packet. Additionally |lenbytes| of data is preallocated
* at the start of the sub-packet to store its length once we know it. Don't

View file

@ -126,12 +126,15 @@ struct ossl_record_method_st {
uint16_t epoch,
unsigned char *secret,
size_t secretlen,
unsigned char *snkey,
unsigned char *key,
size_t keylen,
unsigned char *iv,
size_t ivlen,
unsigned char *mackey,
size_t mackeylen,
const EVP_CIPHER *snciph,
size_t snoffs,
const EVP_CIPHER *ciph,
size_t taglen,
int mactype,

View file

@ -22,22 +22,24 @@
extern "C" {
#endif
#include <openssl/opensslconf.h>
# include <openssl/opensslconf.h>
/* DTLS*_VERSION constants are defined in prov_ssl.h */
# ifndef OPENSSL_NO_DEPRECATED_3_0
# define DTLS_MIN_VERSION DTLS1_VERSION
# define DTLS_MAX_VERSION DTLS1_2_VERSION
# define DTLS_MAX_VERSION DTLS1_3_VERSION
# endif
# define DTLS1_VERSION_MAJOR 0xFE
/* Special value for method supporting multiple versions */
# define DTLS_ANY_VERSION 0x1FFFF
/* lengths of messages */
/* DTLS records and messages lengths and offsets */
# define DTLS1_COOKIE_LENGTH 255
# define DTLS1_RT_HEADER_SEQ_OFFS 5
# define DTLS1_RT_HEADER_SEQ_LEN 6
# define DTLS1_RT_HEADER_LENGTH 13
# define DTLS1_HM_HEADER_LENGTH 12
@ -51,7 +53,19 @@ extern "C" {
# define DTLS1_TMO_ALERT_COUNT 12
#ifdef __cplusplus
/* DTLS 1.3 Unified header */
# define DTLS13_UNI_HDR_FIXED_LENGTH 5
# define DTLS13_UNI_HDR_FIX_BITS 0x20
# define DTLS13_UNI_HDR_CID_BIT 0x10
# define DTLS13_UNI_HDR_SEQ_BIT 0x08
# define DTLS13_UNI_HDR_SEQ_OFF 1
# define DTLS13_UNI_HDR_LEN_BIT 0x04
# define DTLS13_UNI_HDR_FIX_BITS_MASK 0xe0
# define DTLS13_UNI_HDR_EPOCH_BITS_MASK 0x03
# define DTLS13_CIPHERTEXT_MINSIZE 16
# ifdef __cplusplus
}
#endif
# endif
#endif

View file

@ -27,8 +27,11 @@ extern "C" {
# define TLS1_3_VERSION 0x0304
# define DTLS1_VERSION 0xFEFF
# define DTLS1_2_VERSION 0xFEFD
# define DTLS1_3_VERSION 0xFEFC
# define DTLS1_BAD_VER 0x0100
# define PROTO_VERSION_UNSET 0
/* QUIC uses a 4 byte unsigned version number */
# define OSSL_QUIC1_VERSION 0x0000001

View file

@ -404,6 +404,7 @@ typedef int (*SSL_async_callback_fn)(SSL *s, void *arg);
# define SSL_OP_NO_TLSv1_3 SSL_OP_BIT(29)
# define SSL_OP_NO_DTLSv1 SSL_OP_BIT(26)
# define SSL_OP_NO_DTLSv1_2 SSL_OP_BIT(27)
# define SSL_OP_NO_DTLSv1_3 SSL_OP_BIT(29)
/* Disallow all renegotiation */
# define SSL_OP_NO_RENEGOTIATION SSL_OP_BIT(30)
/*

View file

@ -86,15 +86,15 @@ static const TLS_GROUP_CONSTANTS group_list[] = {
DTLS1_VERSION, DTLS1_2_VERSION },
{ OSSL_TLS_GROUP_ID_x25519, 128, TLS1_VERSION, 0, DTLS1_VERSION, 0 },
{ OSSL_TLS_GROUP_ID_x448, 224, TLS1_VERSION, 0, DTLS1_VERSION, 0 },
{ OSSL_TLS_GROUP_ID_brainpoolP256r1_tls13, 128, TLS1_3_VERSION, 0, -1, -1 },
{ OSSL_TLS_GROUP_ID_brainpoolP384r1_tls13, 192, TLS1_3_VERSION, 0, -1, -1 },
{ OSSL_TLS_GROUP_ID_brainpoolP512r1_tls13, 256, TLS1_3_VERSION, 0, -1, -1 },
{ OSSL_TLS_GROUP_ID_brainpoolP256r1_tls13, 128, TLS1_3_VERSION, 0, DTLS1_3_VERSION, 0 },
{ OSSL_TLS_GROUP_ID_brainpoolP384r1_tls13, 192, TLS1_3_VERSION, 0, DTLS1_3_VERSION, 0 },
{ OSSL_TLS_GROUP_ID_brainpoolP512r1_tls13, 256, TLS1_3_VERSION, 0, DTLS1_3_VERSION, 0 },
/* Security bit values as given by BN_security_bits() */
{ OSSL_TLS_GROUP_ID_ffdhe2048, 112, TLS1_3_VERSION, 0, -1, -1 },
{ OSSL_TLS_GROUP_ID_ffdhe3072, 128, TLS1_3_VERSION, 0, -1, -1 },
{ OSSL_TLS_GROUP_ID_ffdhe4096, 128, TLS1_3_VERSION, 0, -1, -1 },
{ OSSL_TLS_GROUP_ID_ffdhe6144, 128, TLS1_3_VERSION, 0, -1, -1 },
{ OSSL_TLS_GROUP_ID_ffdhe8192, 192, TLS1_3_VERSION, 0, -1, -1 },
{ OSSL_TLS_GROUP_ID_ffdhe2048, 112, TLS1_3_VERSION, 0, DTLS1_3_VERSION, 0 },
{ OSSL_TLS_GROUP_ID_ffdhe3072, 128, TLS1_3_VERSION, 0, DTLS1_3_VERSION, 0 },
{ OSSL_TLS_GROUP_ID_ffdhe4096, 128, TLS1_3_VERSION, 0, DTLS1_3_VERSION, 0 },
{ OSSL_TLS_GROUP_ID_ffdhe6144, 128, TLS1_3_VERSION, 0, DTLS1_3_VERSION, 0 },
{ OSSL_TLS_GROUP_ID_ffdhe8192, 192, TLS1_3_VERSION, 0, DTLS1_3_VERSION, 0 },
};
#define TLS_GROUP_ENTRY(tlsname, realname, algorithm, idx) \

View file

@ -52,6 +52,21 @@ const SSL3_ENC_METHOD DTLSv1_2_enc_data = {
dtls1_handshake_write
};
const SSL3_ENC_METHOD DTLSv1_3_enc_data = {
tls13_setup_key_block,
tls13_generate_master_secret,
tls13_change_cipher_state,
tls13_final_finish_mac,
TLS_MD_CLIENT_FINISH_CONST, TLS_MD_CLIENT_FINISH_CONST_SIZE,
TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE,
tls13_alert_code,
tls13_export_keying_material,
SSL_ENC_FLAG_DTLS | SSL_ENC_FLAG_SIGALGS | SSL_ENC_FLAG_SHA256_PRF,
dtls1_set_handshake_header,
dtls1_close_construct_packet,
dtls1_handshake_write
};
OSSL_TIME dtls1_default_timeout(void)
{
/*
@ -80,23 +95,12 @@ int dtls1_new(SSL *ssl)
return 0;
}
d1->buffered_messages = pqueue_new();
d1->sent_messages = pqueue_new();
if (s->server) {
if (s->server)
d1->cookie_len = sizeof(s->d1->cookie);
}
d1->link_mtu = 0;
d1->mtu = 0;
if (d1->buffered_messages == NULL || d1->sent_messages == NULL) {
pqueue_free(d1->buffered_messages);
pqueue_free(d1->sent_messages);
OPENSSL_free(d1);
ssl3_free(ssl);
return 0;
}
d1->hello_verify_request = SSL_HVR_NONE;
s->d1 = d1;
@ -116,8 +120,9 @@ void dtls1_clear_received_buffer(SSL_CONNECTION *s)
{
pitem *item = NULL;
hm_fragment *frag = NULL;
pqueue *rcvd_messages = &s->d1->rcvd_messages;
while ((item = pqueue_pop(s->d1->buffered_messages)) != NULL) {
while ((item = pqueue_pop(rcvd_messages)) != NULL) {
frag = (hm_fragment *)item->data;
dtls1_hm_fragment_free(frag);
pitem_free(item);
@ -127,22 +132,22 @@ void dtls1_clear_received_buffer(SSL_CONNECTION *s)
void dtls1_clear_sent_buffer(SSL_CONNECTION *s)
{
pitem *item = NULL;
hm_fragment *frag = NULL;
pqueue *sent_messages = &s->d1->sent_messages;
while ((item = pqueue_pop(s->d1->sent_messages)) != NULL) {
frag = (hm_fragment *)item->data;
while ((item = pqueue_pop(sent_messages)) != NULL) {
dtls_sent_msg *sent_msg = (dtls_sent_msg *)item->data;
if (frag->msg_header.is_ccs
&& frag->msg_header.saved_retransmit_state.wrlmethod != NULL
&& s->rlayer.wrl != frag->msg_header.saved_retransmit_state.wrl) {
if (sent_msg->record_type == SSL3_RT_CHANGE_CIPHER_SPEC
&& sent_msg->saved_retransmit_state.wrlmethod != NULL
&& s->rlayer.wrl != sent_msg->saved_retransmit_state.wrl) {
/*
* If we're freeing the CCS then we're done with the old wrl and it
* can bee freed
*/
frag->msg_header.saved_retransmit_state.wrlmethod->free(frag->msg_header.saved_retransmit_state.wrl);
sent_msg->saved_retransmit_state.wrlmethod->free(sent_msg->saved_retransmit_state.wrl);
}
dtls1_hm_fragment_free(frag);
dtls1_sent_msg_free(sent_msg);
pitem_free(item);
}
}
@ -155,24 +160,17 @@ void dtls1_free(SSL *ssl)
if (s == NULL)
return;
if (s->d1 != NULL) {
if (s->d1 != NULL)
dtls1_clear_queues(s);
pqueue_free(s->d1->buffered_messages);
pqueue_free(s->d1->sent_messages);
}
DTLS_RECORD_LAYER_free(&s->rlayer);
ssl3_free(ssl);
OPENSSL_free(s->d1);
s->d1 = NULL;
}
int dtls1_clear(SSL *ssl)
{
pqueue *buffered_messages;
pqueue *sent_messages;
size_t mtu;
size_t link_mtu;
@ -186,8 +184,6 @@ int dtls1_clear(SSL *ssl)
if (s->d1) {
DTLS_timer_cb timer_cb = s->d1->timer_cb;
buffered_messages = s->d1->buffered_messages;
sent_messages = s->d1->sent_messages;
mtu = s->d1->mtu;
link_mtu = s->d1->link_mtu;
@ -206,9 +202,6 @@ int dtls1_clear(SSL *ssl)
s->d1->mtu = mtu;
s->d1->link_mtu = link_mtu;
}
s->d1->buffered_messages = buffered_messages;
s->d1->sent_messages = sent_messages;
}
if (!ssl3_clear(ssl))
@ -408,7 +401,7 @@ int dtls1_handle_timeout(SSL_CONNECTION *s)
dtls1_start_timer(s);
/* Calls SSLfatal() if required */
return dtls1_retransmit_buffered_messages(s);
return dtls1_retransmit_sent_messages(s);
}
#define LISTEN_SUCCESS 2
@ -830,12 +823,11 @@ int DTLSv1_listen(SSL *ssl, BIO_ADDR *client)
* Reset the record layer - but this time we can use the record we just
* buffered in s->rlayer.rrlnext
*/
if (!ssl_set_new_record_layer(s,
DTLS_ANY_VERSION,
if (!ssl_set_new_record_layer(s, DTLS_ANY_VERSION,
OSSL_RECORD_DIRECTION_READ,
OSSL_RECORD_PROTECTION_LEVEL_NONE, NULL, 0,
NULL, 0, NULL, 0, NULL, 0, NULL, 0,
NID_undef, NULL, NULL, NULL)) {
NULL, NULL, 0, NULL, 0, NULL, 0, NULL, 0, NULL,
0, NID_undef, NULL, NULL, NULL)) {
/* SSLfatal already called */
ret = -1;
goto end;
@ -931,7 +923,7 @@ size_t dtls1_min_mtu(SSL_CONNECTION *s)
size_t DTLS_get_data_mtu(const SSL *ssl)
{
size_t mac_overhead, int_overhead, blocksize, ext_overhead;
size_t mac_overhead, int_overhead, blocksize, ext_overhead, rechdrlen = 0;
const SSL_CIPHER *ciph = SSL_get_current_cipher(ssl);
size_t mtu;
const SSL_CONNECTION *s = SSL_CONNECTION_FROM_CONST_SSL_ONLY(ssl);
@ -953,10 +945,33 @@ size_t DTLS_get_data_mtu(const SSL *ssl)
else
int_overhead += mac_overhead;
if (SSL_version(ssl) == DTLS1_3_VERSION) {
switch (SSL_get_state(ssl)) {
case TLS_ST_BEFORE:
case DTLS_ST_CR_HELLO_VERIFY_REQUEST:
case TLS_ST_CR_SRVR_HELLO:
case TLS_ST_CW_CLNT_HELLO:
case TLS_ST_CW_COMP_CERT:
case TLS_ST_CW_KEY_EXCH:
case TLS_ST_SW_HELLO_REQ:
case TLS_ST_SR_CLNT_HELLO:
case DTLS_ST_SW_HELLO_VERIFY_REQUEST:
case TLS_ST_SW_SRVR_HELLO:
case TLS_ST_CR_HELLO_REQ:
rechdrlen = DTLS1_RT_HEADER_LENGTH;
break;
default:
rechdrlen = DTLS13_UNI_HDR_FIXED_LENGTH;
break;
}
} else {
rechdrlen = DTLS1_RT_HEADER_LENGTH;
}
/* Subtract external overhead (e.g. IV/nonce, separate MAC) */
if (ext_overhead + DTLS1_RT_HEADER_LENGTH >= mtu)
if (ext_overhead + rechdrlen >= mtu)
return 0;
mtu -= ext_overhead + DTLS1_RT_HEADER_LENGTH;
mtu -= ext_overhead + rechdrlen;
/* Round encrypted payload down to cipher block size (for CBC etc.)
* No check for overflow since 'mtu % blocksize' cannot exceed mtu. */

View file

@ -125,6 +125,10 @@ IMPLEMENT_dtls1_meth_func(DTLS1_2_VERSION, 0, SSL_OP_NO_DTLSv1_2,
ossl_statem_accept,
ossl_statem_connect, DTLSv1_2_enc_data)
#endif
IMPLEMENT_dtls1_meth_func(DTLS1_3_VERSION, 0, SSL_OP_NO_DTLSv1_3,
dtlsv1_3_method,
ossl_statem_accept,
ossl_statem_connect, DTLSv1_3_enc_data)
IMPLEMENT_dtls1_meth_func(DTLS_ANY_VERSION, 0, 0,
DTLS_method,
ossl_statem_accept,
@ -145,6 +149,10 @@ IMPLEMENT_dtls1_meth_func(DTLS1_2_VERSION, 0, SSL_OP_NO_DTLSv1_2,
ossl_statem_accept,
ssl_undefined_function, DTLSv1_2_enc_data)
#endif
IMPLEMENT_dtls1_meth_func(DTLS1_3_VERSION, 0, SSL_OP_NO_DTLSv1_3,
dtlsv1_3_server_method,
ossl_statem_accept,
ssl_undefined_function, DTLSv1_3_enc_data)
IMPLEMENT_dtls1_meth_func(DTLS_ANY_VERSION, 0, 0,
DTLS_server_method,
ossl_statem_accept,
@ -169,6 +177,10 @@ IMPLEMENT_dtls1_meth_func(DTLS1_2_VERSION, 0, SSL_OP_NO_DTLSv1_2,
ssl_undefined_function,
ossl_statem_connect, DTLSv1_2_enc_data)
#endif
IMPLEMENT_dtls1_meth_func(DTLS1_3_VERSION, 0, SSL_OP_NO_DTLSv1_3,
dtlsv1_3_client_method,
ssl_undefined_function,
ossl_statem_connect, DTLSv1_3_enc_data)
IMPLEMENT_dtls1_meth_func(DTLS_ANY_VERSION, 0, 0,
DTLS_client_method,
ssl_undefined_function,

View file

@ -10,11 +10,6 @@
#include "ssl_local.h"
#include <openssl/bn.h>
struct pqueue_st {
pitem *items;
int count;
};
pitem *pitem_new(unsigned char *prio64be, void *data)
{
pitem *item = OPENSSL_malloc(sizeof(*item));

View file

@ -91,8 +91,10 @@ static int
quic_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers,
int role, int direction, int level, uint16_t epoch,
unsigned char *secret, size_t secretlen,
unsigned char *key, size_t keylen, unsigned char *iv,
size_t ivlen, unsigned char *mackey, size_t mackeylen,
unsigned char *snkey, unsigned char *key, size_t keylen,
unsigned char *iv, size_t ivlen,
unsigned char *mackey, size_t mackeylen,
const EVP_CIPHER *snciph, size_t snoffs,
const EVP_CIPHER *ciph, size_t taglen,
int mactype,
const EVP_MD *md, COMP_METHOD *comp,

View file

@ -105,6 +105,24 @@ static void dtls_set_in_init(OSSL_RECORD_LAYER *rl, int in_init)
rl->in_init = in_init;
}
size_t dtls_get_rec_header_size(uint8_t hdr_first_byte)
{
size_t size = 0;
if (DTLS13_UNI_HDR_FIX_BITS_IS_SET(hdr_first_byte)
&& ossl_assert(!DTLS13_UNI_HDR_CID_BIT_IS_SET(hdr_first_byte))) {
/* DTLSv1.3 unified record header */
size = 1;
size += DTLS13_UNI_HDR_SEQ_BIT_IS_SET(hdr_first_byte) ? 2 : 1;
size += DTLS13_UNI_HDR_LEN_BIT_IS_SET(hdr_first_byte) ? 2 : 0;
} else {
/* DTLSv1.0, DTLSv1.2 or unencrypted DTLSv1.3 record header */
size = DTLS1_RT_HEADER_LENGTH;
}
return size;
}
static int dtls_process_record(OSSL_RECORD_LAYER *rl, DTLS_BITMAP *bitmap)
{
int i;
@ -112,6 +130,7 @@ static int dtls_process_record(OSSL_RECORD_LAYER *rl, DTLS_BITMAP *bitmap)
TLS_RL_RECORD *rr;
int imac_size;
size_t mac_size = 0;
size_t rechdrsize = dtls_get_rec_header_size(rl->packet[0]);
unsigned char md[EVP_MAX_MD_SIZE];
SSL_MAC_BUF macbuf = { NULL, 0 };
int ret = 0;
@ -119,10 +138,10 @@ static int dtls_process_record(OSSL_RECORD_LAYER *rl, DTLS_BITMAP *bitmap)
rr = &rl->rrec[0];
/*
* At this point, rl->packet_length == DTLS1_RT_HEADER_LENGTH + rr->length,
* At this point, rl->packet_length == rechdrsize + rr->length,
* and we have that many bytes in rl->packet
*/
rr->input = &(rl->packet[DTLS1_RT_HEADER_LENGTH]);
rr->input = rl->packet + rechdrsize;
/*
* ok, we can now read from 'rl->packet' data into 'rr'. rr->input
@ -342,7 +361,8 @@ static int dtls_copy_rlayer_record(OSSL_RECORD_LAYER *rl, pitem *item)
memcpy(&rl->rrec[0], &(rdata->rrec), sizeof(TLS_RL_RECORD));
/* Set proper sequence number for mac calculation */
memcpy(&(rl->sequence[2]), &(rdata->packet[5]), 6);
assert(sizeof(rl->sequence) == sizeof(rdata->rrec.seq_num));
memcpy(rl->sequence, rdata->rrec.seq_num, sizeof(rl->sequence));
return 1;
}
@ -365,6 +385,44 @@ static int dtls_retrieve_rlayer_buffered_record(OSSL_RECORD_LAYER *rl,
return 0;
}
/* rfc9147 section 4.2.3 */
int dtls_crypt_sequence_number(EVP_CIPHER_CTX *ctx, unsigned char *seq, size_t seqlen,
unsigned char *rec_data, size_t rec_data_offs)
{
unsigned char mask[16];
int outlen, inlen;
unsigned char *iv, *in;
size_t i;
if (ossl_assert(sizeof(mask) > rec_data_offs))
inlen = (int)(sizeof(mask) - rec_data_offs);
else
return 0;
iv = rec_data_offs == 0 ? NULL : rec_data;
in = rec_data + rec_data_offs;
memset(mask, 0, sizeof(mask));
if (!ossl_assert(inlen >= 0)
|| (size_t)inlen > sizeof(mask)
|| EVP_CipherInit_ex2(ctx, NULL, NULL, iv, 1, NULL) <= 0
|| EVP_CipherUpdate(ctx, mask, &outlen, in, inlen) <= 0
|| outlen != inlen
|| EVP_CipherFinal_ex(ctx, mask + outlen, &outlen) <= 0
|| outlen != 0)
return 0;
if (!ossl_assert(seqlen <= sizeof(mask)))
return 0;
for (i = 0; i < seqlen; i++)
seq[i] ^= mask[i];
OPENSSL_cleanse(mask, sizeof(mask));
return 1;
}
/*-
* Call this to get a new input record.
* It will return <= 0 if more data is needed, normally due to an error
@ -376,13 +434,17 @@ static int dtls_retrieve_rlayer_buffered_record(OSSL_RECORD_LAYER *rl,
*/
int dtls_get_more_records(OSSL_RECORD_LAYER *rl)
{
int ssl_major, ssl_minor;
int rret;
size_t more, n;
size_t more, nread = 0;
TLS_RL_RECORD *rr;
unsigned char *p = NULL;
DTLS_BITMAP *bitmap;
unsigned int is_next_epoch;
unsigned char recseqnum[6];
size_t recseqnumlen = 0;
size_t rechdrlen = 0;
size_t recseqnumoffs = 0;
memset(recseqnum, 0, sizeof(recseqnum));
rl->num_recs = 0;
rl->curr_rec = 0;
@ -399,7 +461,7 @@ int dtls_get_more_records(OSSL_RECORD_LAYER *rl)
again:
/* if we're renegotiating, then there may be buffered records */
if (dtls_retrieve_rlayer_buffered_record(rl, rl->processed_rcds)) {
if (dtls_retrieve_rlayer_buffered_record(rl, &rl->processed_rcds)) {
rl->num_recs = 1;
return OSSL_RECORD_RETURN_SUCCESS;
}
@ -407,10 +469,13 @@ int dtls_get_more_records(OSSL_RECORD_LAYER *rl)
/* get something from the wire */
/* check if we have the header */
if ((rl->rstate != SSL_ST_READ_BODY) ||
(rl->packet_length < DTLS1_RT_HEADER_LENGTH)) {
if (rl->rstate != SSL_ST_READ_BODY
|| rl->packet_length < DTLS1_RT_HEADER_LENGTH) {
PACKET dtlsrecord;
unsigned int record_type, record_version, epoch, length;
rret = rl->funcs->read_n(rl, DTLS1_RT_HEADER_LENGTH,
TLS_BUFFER_get_len(&rl->rbuf), 0, 1, &n);
TLS_BUFFER_get_len(&rl->rbuf), 0, 1, &nread);
/* read timeout is handled by dtls1_read_bytes */
if (rret < OSSL_RECORD_RETURN_SUCCESS) {
/* RLAYERfatal() already called if appropriate */
@ -425,31 +490,121 @@ int dtls_get_more_records(OSSL_RECORD_LAYER *rl)
rl->rstate = SSL_ST_READ_BODY;
p = rl->packet;
if (!PACKET_buf_init(&dtlsrecord, rl->packet, rl->packet_length)
|| !PACKET_get_1(&dtlsrecord, &record_type)) {
rl->packet_length = 0;
goto again;
}
/* Pull apart the header into the DTLS1_RECORD */
rr->type = *(p++);
ssl_major = *(p++);
ssl_minor = *(p++);
rr->rec_version = (ssl_major << 8) | ssl_minor;
rr->type = (int)record_type;
/* sequence number is 64 bits, with top 2 bytes = epoch */
n2s(p, rr->epoch);
/*-
* rfc9147:
* Implementations can demultiplex DTLS 1.3 records by examining the first
* byte as follows:
* * If the first byte is alert(21), handshake(22), or ack(proposed, 26),
* the record MUST be interpreted as a DTLSPlaintext record.
* * If the first byte is any other value, then receivers MUST check to
* see if the leading bits of the first byte are 001. If so, the implementation
* MUST process the record as DTLSCiphertext; the true content type
* will be inside the protected portion.
* * Otherwise, the record MUST be rejected as if it had failed deprotection,
* as described in Section 4.5.2.
*/
if (rl->version == DTLS1_3_VERSION
&& rr->type != SSL3_RT_ALERT
&& rr->type != SSL3_RT_HANDSHAKE
/* TODO(DTLSv1.3): && rr->type != SSL3_RT_ACK depends on acknowledge implementation */
&& !DTLS13_UNI_HDR_FIX_BITS_IS_SET(rr->type)) {
/* Silently discard */
rr->length = 0;
rl->packet_length = 0;
goto again;
}
memcpy(&(rl->sequence[2]), p, 6);
p += 6;
if (DTLS13_UNI_HDR_FIX_BITS_IS_SET(rr->type)) {
/*
* rfc9147:
* receivers MUST check to if the leading bits of the first byte are 001.
* If so, the implementation MUST process the record as DTLSCiphertext;
*/
int cbitisset = DTLS13_UNI_HDR_CID_BIT_IS_SET(rr->type);
int sbitisset = DTLS13_UNI_HDR_SEQ_BIT_IS_SET(rr->type);
int lbitisset = DTLS13_UNI_HDR_LEN_BIT_IS_SET(rr->type);
uint16_t eebits = rr->type & DTLS13_UNI_HDR_EPOCH_BITS_MASK;
n2s(p, rr->length);
record_version = DTLS1_2_VERSION;
epoch = rl->epoch;
recseqnumlen = sbitisset ? 2 : 1;
recseqnumoffs = sizeof(recseqnum) - recseqnumlen;
if (/* OpenSSL does not support connection IDs: silently discard */
cbitisset
/*
* Naive approach? We expect sequence number to be filled already
* and then override the last bytes of the sequence number.
*/
|| !PACKET_copy_bytes(&dtlsrecord, recseqnum + recseqnumoffs, recseqnumlen)) {
rr->length = 0;
rl->packet_length = 0;
goto again;
}
/*
* rfc9147:
* The length field MAY be omitted by clearing the L bit, which means
* that the record consumes the entire rest of the datagram in the
* lower level transport
*/
length = TLS_BUFFER_get_len(&rl->rbuf) - dtls_get_rec_header_size(rr->type);
if ((lbitisset && !PACKET_get_net_2(&dtlsrecord, &length))
|| length == 0) {
rr->length = 0;
rl->packet_length = 0;
goto again;
}
/*
* We should not be getting records from a previous epoch so
* choose the current epoch if the bits match or else choose the
* next epoch with matching bits
*/
while (eebits != (epoch & DTLS13_UNI_HDR_EPOCH_BITS_MASK))
epoch++;
} else {
if (!PACKET_get_net_2(&dtlsrecord, &record_version)
|| !PACKET_get_net_2(&dtlsrecord, &epoch)
|| !PACKET_copy_bytes(&dtlsrecord, recseqnum, 6)
|| !PACKET_get_net_2(&dtlsrecord, &length)) {
rr->length = 0;
rl->packet_length = 0;
goto again;
}
recseqnumoffs = 0;
recseqnumlen = 6;
}
rechdrlen = PACKET_data(&dtlsrecord) - rl->packet;
rr->rec_version = (int)record_version;
rr->epoch = epoch;
rr->length = length;
if (rl->msg_callback != NULL)
rl->msg_callback(0, rr->rec_version, SSL3_RT_HEADER, rl->packet, DTLS1_RT_HEADER_LENGTH,
rl->cbarg);
rl->msg_callback(0, rr->rec_version, SSL3_RT_HEADER, rl->packet,
rechdrlen, rl->cbarg);
/*
* Lets check the version. We tolerate alerts that don't have the exact
* version number (e.g. because of protocol version errors)
*/
if (!rl->is_first_record && rr->type != SSL3_RT_ALERT) {
if (!rl->is_first_record && rr->type != SSL3_RT_ALERT
/* DTLSv1.3 records sets the legacy version field to DTLSv1.2 */
&& !(rr->rec_version == DTLS1_2_VERSION
&& rl->version == DTLS1_3_VERSION)) {
if (rr->rec_version != rl->version) {
/* unexpected version, silently discard */
rr->length = 0;
@ -458,7 +613,7 @@ int dtls_get_more_records(OSSL_RECORD_LAYER *rl)
}
}
if (ssl_major !=
if (rr->rec_version >> 8 !=
(rl->version == DTLS_ANY_VERSION ? DTLS1_VERSION_MAJOR
: rl->version >> 8)) {
/* wrong version, silently discard record */
@ -492,10 +647,10 @@ int dtls_get_more_records(OSSL_RECORD_LAYER *rl)
if (rr->length > rl->packet_length - DTLS1_RT_HEADER_LENGTH) {
/* now rl->packet_length == DTLS1_RT_HEADER_LENGTH */
more = rr->length;
rret = rl->funcs->read_n(rl, more, more, 1, 1, &n);
more = rr->length - (nread - rechdrlen);
rret = rl->funcs->read_n(rl, more, more, 1, 1, &nread);
/* this packet contained a partial record, dump it */
if (rret < OSSL_RECORD_RETURN_SUCCESS || n != more) {
if (rret < OSSL_RECORD_RETURN_SUCCESS || nread != more) {
if (rl->alert != SSL_AD_NO_ALERT) {
/* read_n() called RLAYERfatal() */
return OSSL_RECORD_RETURN_FATAL;
@ -513,6 +668,30 @@ int dtls_get_more_records(OSSL_RECORD_LAYER *rl)
/* set state for later operations */
rl->rstate = SSL_ST_READ_HEADER;
/*
* rfc9147:
* This procedure requires the ciphertext length to be at least
* DTLS13_CIPHERTEXT_MINSIZE (16) bytes.
* Receivers MUST reject shorter records as if they had failed deprotection
*/
if (DTLS13_UNI_HDR_FIX_BITS_IS_SET(rr->type)
&& rl->version == DTLS1_3_VERSION
&& (!ossl_assert(rl->sn_enc_ctx != NULL)
|| !ossl_assert(rl->packet_length >= rechdrlen + DTLS13_CIPHERTEXT_MINSIZE)
|| !dtls_crypt_sequence_number(rl->sn_enc_ctx,
recseqnum + recseqnumoffs,
recseqnumlen,
rl->packet + rechdrlen,
rl->sn_enc_offs))) {
/* sequence number encryption failed dump record */
rr->length = 0;
rl->packet_length = 0;
goto again;
}
memset(rl->sequence, 0, sizeof(rl->sequence));
memcpy(rl->sequence + 2, recseqnum, sizeof(recseqnum));
/* match epochs. NULL means the packet is dropped on the floor */
bitmap = dtls_get_bitmap(rl, rr, &is_next_epoch);
if (bitmap == NULL) {
@ -545,7 +724,7 @@ int dtls_get_more_records(OSSL_RECORD_LAYER *rl)
*/
if (is_next_epoch) {
if (rl->in_init) {
if (dtls_rlayer_buffer_record(rl, rl->unprocessed_rcds,
if (dtls_rlayer_buffer_record(rl, &rl->unprocessed_rcds,
rr->seq_num) < 0) {
/* RLAYERfatal() already called */
return OSSL_RECORD_RETURN_FATAL;
@ -595,8 +774,7 @@ static int dtls_free(OSSL_RECORD_LAYER *rl)
rbuf->left = 0;
}
if (rl->unprocessed_rcds != NULL) {
while ((item = pqueue_pop(rl->unprocessed_rcds)) != NULL) {
while ((item = pqueue_pop(&rl->unprocessed_rcds)) != NULL) {
rdata = (DTLS_RLAYER_RECORD_DATA *)item->data;
/* Push to the next record layer */
ret &= BIO_write_ex(rl->next, rdata->packet, rdata->packet_length,
@ -605,18 +783,13 @@ static int dtls_free(OSSL_RECORD_LAYER *rl)
OPENSSL_free(item->data);
pitem_free(item);
}
pqueue_free(rl->unprocessed_rcds);
}
if (rl->processed_rcds!= NULL) {
while ((item = pqueue_pop(rl->processed_rcds)) != NULL) {
while ((item = pqueue_pop(&rl->processed_rcds)) != NULL) {
rdata = (DTLS_RLAYER_RECORD_DATA *)item->data;
OPENSSL_free(rdata->rbuf.buf);
OPENSSL_free(item->data);
pitem_free(item);
}
pqueue_free(rl->processed_rcds);
}
return tls_free(rl) && ret;
}
@ -625,8 +798,10 @@ static int
dtls_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers,
int role, int direction, int level, uint16_t epoch,
unsigned char *secret, size_t secretlen,
unsigned char *key, size_t keylen, unsigned char *iv,
size_t ivlen, unsigned char *mackey, size_t mackeylen,
unsigned char *snkey, unsigned char *key, size_t keylen,
unsigned char *iv, size_t ivlen,
unsigned char *mackey, size_t mackeylen,
const EVP_CIPHER *snciph, size_t snoffs,
const EVP_CIPHER *ciph, size_t taglen,
int mactype,
const EVP_MD *md, COMP_METHOD *comp,
@ -646,17 +821,6 @@ dtls_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers,
if (ret != OSSL_RECORD_RETURN_SUCCESS)
return ret;
(*retrl)->unprocessed_rcds = pqueue_new();
(*retrl)->processed_rcds = pqueue_new();
if ((*retrl)->unprocessed_rcds == NULL
|| (*retrl)->processed_rcds == NULL) {
dtls_free(*retrl);
*retrl = NULL;
ERR_raise(ERR_LIB_SSL, ERR_R_SSL_LIB);
return OSSL_RECORD_RETURN_FATAL;
}
(*retrl)->isdtls = 1;
(*retrl)->epoch = epoch;
(*retrl)->in_init = 1;
@ -665,6 +829,9 @@ dtls_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers,
case DTLS_ANY_VERSION:
(*retrl)->funcs = &dtls_any_funcs;
break;
case DTLS1_3_VERSION:
(*retrl)->funcs = &dtls_1_3_funcs;
break;
case DTLS1_2_VERSION:
case DTLS1_VERSION:
case DTLS1_BAD_VER:
@ -677,9 +844,10 @@ dtls_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers,
goto err;
}
ret = (*retrl)->funcs->set_crypto_state(*retrl, level, key, keylen, iv,
ivlen, mackey, mackeylen, ciph,
taglen, mactype, md, comp);
ret = (*retrl)->funcs->set_crypto_state(*retrl, level, snkey, key, keylen,
iv, ivlen, mackey, mackeylen,
snciph, snoffs, ciph, taglen, mactype, md,
comp);
err:
if (ret != OSSL_RECORD_RETURN_SUCCESS) {
@ -696,6 +864,7 @@ int dtls_prepare_record_header(OSSL_RECORD_LAYER *rl,
unsigned char **recdata)
{
size_t maxcomplen;
int unifiedheader = rl->version == DTLS1_3_VERSION && rl->epoch > 0;
*recdata = NULL;
@ -703,6 +872,25 @@ int dtls_prepare_record_header(OSSL_RECORD_LAYER *rl,
if (rl->compctx != NULL)
maxcomplen += SSL3_RT_MAX_COMPRESSED_OVERHEAD;
if (unifiedheader) {
uint8_t fixedbits = 0x20;
uint8_t cbit = 0;
uint8_t sbit = DTLS13_UNI_HDR_SEQ_BIT;
uint8_t lbit = DTLS13_UNI_HDR_LEN_BIT;
uint8_t ebits = rl->epoch & DTLS13_UNI_HDR_EPOCH_BITS_MASK;
uint8_t unifiedhdrbits = fixedbits | cbit | sbit | lbit | ebits;
if (!WPACKET_put_bytes_u8(thispkt, unifiedhdrbits)
|| !WPACKET_memcpy(thispkt, rl->sequence + 6, 2)
|| !WPACKET_start_sub_packet_u16(thispkt)
|| (rl->eivlen > 0
&& !WPACKET_allocate_bytes(thispkt, rl->eivlen, NULL))
|| (maxcomplen > 0
&& !WPACKET_reserve_bytes(thispkt, maxcomplen, recdata))) {
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return 0;
}
} else {
if (!WPACKET_put_bytes_u8(thispkt, rectype)
|| !WPACKET_put_bytes_u16(thispkt, templ->version)
|| !WPACKET_put_bytes_u16(thispkt, rl->epoch)
@ -711,11 +899,11 @@ int dtls_prepare_record_header(OSSL_RECORD_LAYER *rl,
|| (rl->eivlen > 0
&& !WPACKET_allocate_bytes(thispkt, rl->eivlen, NULL))
|| (maxcomplen > 0
&& !WPACKET_reserve_bytes(thispkt, maxcomplen,
recdata))) {
&& !WPACKET_reserve_bytes(thispkt, maxcomplen, recdata))) {
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return 0;
}
}
return 1;
}
@ -737,12 +925,17 @@ int dtls_post_encryption_processing(OSSL_RECORD_LAYER *rl,
static size_t dtls_get_max_record_overhead(OSSL_RECORD_LAYER *rl)
{
size_t blocksize = 0;
size_t blocksize = 0, contenttypelen = 0;
size_t rchdrlen = tls_get_record_header_len(rl);
if (rl->enc_ctx != NULL &&
(EVP_CIPHER_CTX_get_mode(rl->enc_ctx) == EVP_CIPH_CBC_MODE))
blocksize = EVP_CIPHER_CTX_get_block_size(rl->enc_ctx);
/* DTLSv1.3 adds an extra content type byte after payload data */
if (rl->version == DTLS1_3_VERSION)
contenttypelen = 1;
/*
* If we have a cipher in place then the tag is mandatory. If the cipher is
* CBC mode then an explicit IV is also mandatory. If we know the digest,
@ -765,7 +958,7 @@ static size_t dtls_get_max_record_overhead(OSSL_RECORD_LAYER *rl)
* MTU size - so isn't very helpful. We just ignore potential expansion
* due to compression.
*/
return DTLS1_RT_HEADER_LENGTH + rl->eivlen + blocksize + rl->taglen;
return rchdrlen + rl->eivlen + blocksize + rl->taglen + contenttypelen;
}
const OSSL_RECORD_METHOD ossl_dtls_record_method = {
@ -782,7 +975,7 @@ const OSSL_RECORD_METHOD ossl_dtls_record_method = {
tls_get_alert_code,
tls_set1_bio,
tls_set_protocol_version,
NULL,
tls_set_plain_alerts,
tls_set_first_handshake,
tls_set_max_pipelines,
dtls_set_in_init,

View file

@ -287,9 +287,11 @@ int ktls_configure_crypto(OSSL_LIB_CTX *libctx, int version, const EVP_CIPHER *c
#endif /* OPENSSL_SYS_LINUX */
static int ktls_set_crypto_state(OSSL_RECORD_LAYER *rl, int level,
unsigned char *snkey,
unsigned char *key, size_t keylen,
unsigned char *iv, size_t ivlen,
unsigned char *mackey, size_t mackeylen,
const EVP_CIPHER *snciph, size_t snoffs,
const EVP_CIPHER *ciph,
size_t taglen,
int mactype,
@ -403,8 +405,10 @@ static int
ktls_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers,
int role, int direction, int level, uint16_t epoch,
unsigned char *secret, size_t secretlen,
unsigned char *key, size_t keylen, unsigned char *iv,
size_t ivlen, unsigned char *mackey, size_t mackeylen,
unsigned char *snkey, unsigned char *key, size_t keylen,
unsigned char *iv, size_t ivlen,
unsigned char *mackey, size_t mackeylen,
const EVP_CIPHER *snciph, size_t snoffs,
const EVP_CIPHER *ciph, size_t taglen,
int mactype,
const EVP_MD *md, COMP_METHOD *comp,
@ -426,9 +430,10 @@ ktls_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers,
(*retrl)->funcs = &ossl_ktls_funcs;
ret = (*retrl)->funcs->set_crypto_state(*retrl, level, key, keylen, iv,
ivlen, mackey, mackeylen, ciph,
taglen, mactype, md, comp);
ret = (*retrl)->funcs->set_crypto_state(*retrl, level, snkey, key, keylen,
iv, ivlen, mackey, mackeylen,
snciph, snoffs, ciph, taglen, mactype, md,
comp);
if (ret != OSSL_RECORD_RETURN_SUCCESS) {
OPENSSL_free(*retrl);

View file

@ -98,9 +98,11 @@ struct record_functions_st {
* alternative record layer.
*/
int (*set_crypto_state)(OSSL_RECORD_LAYER *rl, int level,
unsigned char *snkey,
unsigned char *key, size_t keylen,
unsigned char *iv, size_t ivlen,
unsigned char *mackey, size_t mackeylen,
const EVP_CIPHER *snciph, size_t snoffs,
const EVP_CIPHER *ciph,
size_t taglen,
int mactype,
@ -292,6 +294,9 @@ struct ossl_record_layer_st {
/* cryptographic state */
EVP_CIPHER_CTX *enc_ctx;
/* cryptographic state for DTLS sequence numbers */
EVP_CIPHER_CTX *sn_enc_ctx;
size_t sn_enc_offs;
/* TLSv1.3 MAC ctx, only used with integrity-only cipher */
EVP_MAC_CTX *mac_ctx;
@ -346,8 +351,8 @@ struct ossl_record_layer_st {
size_t taglen;
/* DTLS received handshake records (processed and unprocessed) */
struct pqueue_st *unprocessed_rcds;
struct pqueue_st *processed_rcds;
pqueue unprocessed_rcds;
pqueue processed_rcds;
/* records being received in the current epoch */
DTLS_BITMAP bitmap;
@ -384,6 +389,7 @@ extern const struct record_functions_st tls_1_funcs;
extern const struct record_functions_st tls_1_3_funcs;
extern const struct record_functions_st tls_any_funcs;
extern const struct record_functions_st dtls_1_funcs;
extern const struct record_functions_st dtls_1_3_funcs;
extern const struct record_functions_st dtls_any_funcs;
void ossl_rlayer_fatal(OSSL_RECORD_LAYER *rl, int al, int reason,
@ -416,6 +422,26 @@ int tls_free_buffers(OSSL_RECORD_LAYER *rl);
int tls_default_read_n(OSSL_RECORD_LAYER *rl, size_t n, size_t max, int extend,
int clearold, size_t *readbytes);
int tls_get_more_records(OSSL_RECORD_LAYER *rl);
/* Returns true if the unified header fixed bits are set (rfc9147 section 4) */
#define DTLS13_UNI_HDR_FIX_BITS_IS_SET(byte) \
(((byte) & DTLS13_UNI_HDR_FIX_BITS_MASK) == DTLS13_UNI_HDR_FIX_BITS)
/* Returns true if the unified header connection id bit is set (rfc9147 section 4) */
#define DTLS13_UNI_HDR_CID_BIT_IS_SET(byte) \
(((byte) & DTLS13_UNI_HDR_CID_BIT) == DTLS13_UNI_HDR_CID_BIT)
/* Returns true if the unified header sequence number bit is set (rfc9147 section 4) */
#define DTLS13_UNI_HDR_SEQ_BIT_IS_SET(byte) \
(((byte) & DTLS13_UNI_HDR_SEQ_BIT) == DTLS13_UNI_HDR_SEQ_BIT)
/* Returns true if the unified header length bit is set (rfc9147 section 4) */
#define DTLS13_UNI_HDR_LEN_BIT_IS_SET(byte) \
(((byte) & DTLS13_UNI_HDR_LEN_BIT) == DTLS13_UNI_HDR_LEN_BIT)
size_t dtls_get_rec_header_size(uint8_t hdr_first_byte);
int dtls_crypt_sequence_number(EVP_CIPHER_CTX *ctx, unsigned char *seq, size_t seqlen,
unsigned char *rec_data, size_t rec_data_offs);
int dtls_get_more_records(OSSL_RECORD_LAYER *rl);
int dtls_prepare_record_header(OSSL_RECORD_LAYER *rl,
@ -431,6 +457,7 @@ int dtls_post_encryption_processing(OSSL_RECORD_LAYER *rl,
int tls_default_set_protocol_version(OSSL_RECORD_LAYER *rl, int version);
int tls_default_validate_record_header(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *re);
size_t tls_get_record_header_len(OSSL_RECORD_LAYER *rl);
int tls_do_compress(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *wr);
int tls_do_uncompress(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *rec);
int tls_default_post_process_record(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *rec);
@ -460,7 +487,6 @@ int tls_read_record(OSSL_RECORD_LAYER *rl, void **rechandle, int *rversion,
uint8_t *type, const unsigned char **data, size_t *datalen,
uint16_t *epoch, unsigned char *seq_num);
int tls_release_record(OSSL_RECORD_LAYER *rl, void *rechandle, size_t length);
int tls_default_set_protocol_version(OSSL_RECORD_LAYER *rl, int version);
int tls_set_protocol_version(OSSL_RECORD_LAYER *rl, int version);
void tls_set_plain_alerts(OSSL_RECORD_LAYER *rl, int allow);
void tls_set_first_handshake(OSSL_RECORD_LAYER *rl, int first);
@ -484,6 +510,8 @@ size_t tls_get_max_records_default(OSSL_RECORD_LAYER *rl, uint8_t type,
size_t tls_get_max_records_multiblock(OSSL_RECORD_LAYER *rl, uint8_t type,
size_t len, size_t maxfrag,
size_t *preffrag);
size_t tls_get_record_body_alignment_offset(OSSL_RECORD_LAYER *rl,
const unsigned char *rec);
int tls_allocate_write_buffers_default(OSSL_RECORD_LAYER *rl,
OSSL_RECORD_TEMPLATE *templates,
size_t numtempl, size_t *prefix);

View file

@ -15,9 +15,11 @@
#include "recmethod_local.h"
static int ssl3_set_crypto_state(OSSL_RECORD_LAYER *rl, int level,
unsigned char *snkey,
unsigned char *key, size_t keylen,
unsigned char *iv, size_t ivlen,
unsigned char *mackey, size_t mackeylen,
const EVP_CIPHER *snciph, size_t snoffs,
const EVP_CIPHER *ciph,
size_t taglen,
int mactype,

View file

@ -14,9 +14,11 @@
#include "recmethod_local.h"
static int tls13_set_crypto_state(OSSL_RECORD_LAYER *rl, int level,
unsigned char *snkey,
unsigned char *key, size_t keylen,
unsigned char *iv, size_t ivlen,
unsigned char *mackey, size_t mackeylen,
const EVP_CIPHER *snciph, size_t snoffs,
const EVP_CIPHER *ciph,
size_t taglen,
int mactype,
@ -78,6 +80,27 @@ static int tls13_set_crypto_state(OSSL_RECORD_LAYER *rl, int level,
ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR);
return OSSL_RECORD_RETURN_FATAL;
}
if (rl->isdtls && snciph != NULL) {
EVP_CIPHER_CTX *sn_ciph_ctx;
sn_ciph_ctx = rl->sn_enc_ctx = EVP_CIPHER_CTX_new();
if (sn_ciph_ctx == NULL) {
ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR);
return OSSL_RECORD_RETURN_FATAL;
}
rl->sn_enc_offs = snoffs;
if (EVP_CIPHER_CTX_set_padding(sn_ciph_ctx, 0)
|| EVP_CipherInit_ex(sn_ciph_ctx, snciph, NULL,
snkey, NULL, 1) <= 0) {
ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR);
return OSSL_RECORD_RETURN_FATAL;
}
}
end:
return OSSL_RECORD_RETURN_SUCCESS;
}
@ -89,7 +112,8 @@ static int tls13_cipher(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *recs,
EVP_CIPHER_CTX *enc_ctx;
unsigned char recheader[SSL3_RT_HEADER_LENGTH];
unsigned char tag[EVP_MAX_MD_SIZE];
size_t nonce_len, offset, loop, hdrlen, taglen;
size_t nonce_len, offset, loop, hdrlen, taglen, exphdrlen;
int isdtls, sbit = 0, addlen;
unsigned char *staticiv;
unsigned char *nonce;
unsigned char *seq = rl->sequence;
@ -109,6 +133,7 @@ static int tls13_cipher(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *recs,
enc_ctx = rl->enc_ctx; /* enc_ctx is ignored when rl->mac_ctx != NULL */
staticiv = rl->iv;
nonce = rl->nonce;
isdtls = rl->isdtls;
if (enc_ctx == NULL && rl->mac_ctx == NULL) {
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
@ -162,18 +187,46 @@ static int tls13_cipher(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *recs,
for (loop = 0; loop < SEQ_NUM_SIZE; loop++)
nonce[offset + loop] = staticiv[offset + loop] ^ seq[loop];
if (!tls_increment_sequence_ctr(rl)) {
if (!isdtls && !tls_increment_sequence_ctr(rl)) {
/* RLAYERfatal already called */
return 0;
}
/* Set up the AAD */
if (!WPACKET_init_static_len(&wpkt, recheader, sizeof(recheader), 0)
/*-
* Set up the additional data as described in rfc8446 section 5.2:
* "and the additional data input is the record header.
* I.e.,
* additional_data = TLSCiphertext.opaque_type ||
* TLSCiphertext.legacy_record_version ||
* TLSCiphertext.length"
* and in rfc1947 section 4:
* "The entire header value shown in Figure 4 (but prior to record number
* encryption; see Section 4.2.3) is used as the additional data value for
* the AEAD function. For instance, if the minimal variant is used, the
* Associated Data (AD) is 2 octets long."
*
* For DTLS: at this point rec->type is just the first byte of the variable
* header. So it is not an actual record type. The record type is set in
* tls13_post_process_record() for incoming records.
*/
if (isdtls) {
exphdrlen = dtls_get_rec_header_size(rec->type);
sbit = DTLS13_UNI_HDR_SEQ_BIT_IS_SET(rec->type);
addlen = DTLS13_UNI_HDR_LEN_BIT_IS_SET(rec->type);
} else {
exphdrlen = SSL3_RT_HEADER_LENGTH;
addlen = 1;
}
if ((isdtls && !ossl_assert(!DTLS13_UNI_HDR_CID_BIT_IS_SET(rec->type)))
|| !WPACKET_init_static_len(&wpkt, recheader, sizeof(recheader), 0)
|| !WPACKET_put_bytes_u8(&wpkt, rec->type)
|| !WPACKET_put_bytes_u16(&wpkt, rec->rec_version)
|| !WPACKET_put_bytes_u16(&wpkt, rec->length + rl->taglen)
|| (isdtls && (sbit ? !WPACKET_memcpy(&wpkt, rl->sequence + 6, 2)
: !WPACKET_memcpy(&wpkt, rl->sequence + 7, 1)))
|| (!isdtls && !WPACKET_put_bytes_u16(&wpkt, rec->rec_version))
|| (addlen && !WPACKET_put_bytes_u16(&wpkt, rec->length + rl->taglen))
|| !WPACKET_get_total_written(&wpkt, &hdrlen)
|| hdrlen != SSL3_RT_HEADER_LENGTH
|| hdrlen != exphdrlen
|| !WPACKET_finish(&wpkt)) {
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
WPACKET_cleanup(&wpkt);
@ -185,7 +238,7 @@ static int tls13_cipher(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *recs,
if ((mac_ctx = EVP_MAC_CTX_dup(rl->mac_ctx)) == NULL
|| !EVP_MAC_update(mac_ctx, nonce, nonce_len)
|| !EVP_MAC_update(mac_ctx, recheader, sizeof(recheader))
|| !EVP_MAC_update(mac_ctx, recheader, hdrlen)
|| !EVP_MAC_update(mac_ctx, rec->input, rec->length)
|| !EVP_MAC_final(mac_ctx, tag, &taglen, rl->taglen)) {
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
@ -225,12 +278,9 @@ static int tls13_cipher(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *recs,
* any AAD.
*/
if ((mode == EVP_CIPH_CCM_MODE
&& EVP_CipherUpdate(enc_ctx, NULL, &lenu, NULL,
(unsigned int)rec->length) <= 0)
|| EVP_CipherUpdate(enc_ctx, NULL, &lenu, recheader,
sizeof(recheader)) <= 0
|| EVP_CipherUpdate(enc_ctx, rec->data, &lenu, rec->input,
(unsigned int)rec->length) <= 0
&& EVP_CipherUpdate(enc_ctx, NULL, &lenu, NULL, (int)rec->length) <= 0)
|| EVP_CipherUpdate(enc_ctx, NULL, &lenu, recheader, (int)hdrlen) <= 0
|| EVP_CipherUpdate(enc_ctx, rec->data, &lenu, rec->input, (int)rec->length) <= 0
|| EVP_CipherFinal_ex(enc_ctx, rec->data + lenu, &lenf) <= 0
|| (size_t)(lenu + lenf) != rec->length) {
return 0;
@ -279,7 +329,8 @@ static int tls13_post_process_record(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *rec)
size_t end;
if (rec->length == 0
|| rec->type != SSL3_RT_APPLICATION_DATA) {
|| rl->isdtls ? !DTLS13_UNI_HDR_FIX_BITS_IS_SET(rec->type)
: rec->type != SSL3_RT_APPLICATION_DATA) {
RLAYERfatal(rl, SSL_AD_UNEXPECTED_MESSAGE,
SSL_R_BAD_RECORD_TYPE);
return 0;
@ -317,6 +368,15 @@ static uint8_t tls13_get_record_type(OSSL_RECORD_LAYER *rl,
* when encrypting in TLSv1.3. The "inner" record type encodes the "real"
* record type from the template.
*/
if (rl->isdtls) {
const unsigned char fixed = DTLS13_UNI_HDR_FIX_BITS;
const unsigned char sbit = DTLS13_UNI_HDR_SEQ_BIT;
const unsigned char lbit = DTLS13_UNI_HDR_LEN_BIT;
const unsigned char epochbits = DTLS13_UNI_HDR_EPOCH_BITS_MASK & rl->epoch;
return fixed | sbit | lbit | epochbits;
}
return SSL3_RT_APPLICATION_DATA;
}
@ -425,3 +485,24 @@ const struct record_functions_st tls_1_3_funcs = {
tls_post_encryption_processing_default,
NULL
};
const struct record_functions_st dtls_1_3_funcs = {
tls13_set_crypto_state,
tls13_cipher,
NULL,
tls_default_set_protocol_version,
tls_default_read_n,
dtls_get_more_records,
NULL,
tls13_post_process_record,
NULL,
tls_write_records_default,
tls_allocate_write_buffers_default,
tls_initialise_write_packets_default,
tls13_get_record_type,
dtls_prepare_record_header,
tls13_add_record_padding,
tls_prepare_for_encryption_default,
dtls_post_encryption_processing,
NULL
};

View file

@ -17,9 +17,11 @@
#include "recmethod_local.h"
static int tls1_set_crypto_state(OSSL_RECORD_LAYER *rl, int level,
unsigned char *snkey,
unsigned char *key, size_t keylen,
unsigned char *iv, size_t ivlen,
unsigned char *mackey, size_t mackeylen,
const EVP_CIPHER *snciph, size_t snoffs,
const EVP_CIPHER *ciph,
size_t taglen,
int mactype,
@ -624,12 +626,7 @@ int tls1_initialise_write_packets(OSSL_RECORD_LAYER *rl,
prefixtempl->type = SSL3_RT_APPLICATION_DATA;
wb = &bufs[0];
#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD != 0
align = (size_t)TLS_BUFFER_get_buf(wb) + SSL3_RT_HEADER_LENGTH;
align = SSL3_ALIGN_PAYLOAD - 1
- ((align - 1) % SSL3_ALIGN_PAYLOAD);
#endif
align = tls_get_record_body_alignment_offset(rl, TLS_BUFFER_get_buf(wb));
TLS_BUFFER_set_offset(wb, align);
if (!WPACKET_init_static_len(&pkt[0], TLS_BUFFER_get_buf(wb),

View file

@ -148,15 +148,13 @@ int tls_setup_write_buffer(OSSL_RECORD_LAYER *rl, size_t numwpipes,
size_t currpipe;
size_t defltlen = 0;
size_t contenttypelen = 0;
const int version1_3 = rl->isdtls ? DTLS1_3_VERSION : TLS1_3_VERSION;
if (firstlen == 0 || (numwpipes > 1 && nextlen == 0)) {
if (rl->isdtls)
headerlen = DTLS1_RT_HEADER_LENGTH + 1;
else
headerlen = SSL3_RT_HEADER_LENGTH;
headerlen = tls_get_record_header_len(rl);
/* TLSv1.3 adds an extra content type byte after payload data */
if (rl->version == TLS1_3_VERSION)
/* (D)TLSv1.3 adds an extra content type byte after payload data */
if (rl->version == version1_3)
contenttypelen = 1;
#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD != 0
@ -234,10 +232,7 @@ int tls_setup_read_buffer(OSSL_RECORD_LAYER *rl)
b = &rl->rbuf;
if (rl->isdtls)
headerlen = DTLS1_RT_HEADER_LENGTH;
else
headerlen = SSL3_RT_HEADER_LENGTH;
headerlen = tls_get_record_header_len(rl);
#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD != 0
maxalign = SSL3_ALIGN_PAYLOAD - 1;
@ -635,7 +630,7 @@ int tls_get_more_records(OSSL_RECORD_LAYER *rl)
|| !PACKET_get_net_2(&pkt, &version)
|| !PACKET_get_net_2_len(&pkt, &thisrr->length)) {
if (rl->msg_callback != NULL)
rl->msg_callback(0, 0, SSL3_RT_HEADER, p, 5, rl->cbarg);
rl->msg_callback(0, 0, SSL3_RT_HEADER, p, SSL3_RT_HEADER_LENGTH, rl->cbarg);
RLAYERfatal(rl, SSL_AD_DECODE_ERROR, ERR_R_INTERNAL_ERROR);
return OSSL_RECORD_RETURN_FATAL;
}
@ -655,7 +650,8 @@ int tls_get_more_records(OSSL_RECORD_LAYER *rl)
}
if (rl->msg_callback != NULL)
rl->msg_callback(0, version, SSL3_RT_HEADER, p, 5, rl->cbarg);
rl->msg_callback(0, version, SSL3_RT_HEADER, p,
SSL3_RT_HEADER_LENGTH, rl->cbarg);
if (thisrr->length >
TLS_BUFFER_get_len(rbuf) - SSL3_RT_HEADER_LENGTH) {
@ -1386,8 +1382,10 @@ static int
tls_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers,
int role, int direction, int level, uint16_t epoch,
unsigned char *secret, size_t secretlen,
unsigned char *key, size_t keylen, unsigned char *iv,
size_t ivlen, unsigned char *mackey, size_t mackeylen,
unsigned char *snkey, unsigned char *key, size_t keylen,
unsigned char *iv, size_t ivlen,
unsigned char *mackey, size_t mackeylen,
const EVP_CIPHER *snciph, size_t snoffs,
const EVP_CIPHER *ciph, size_t taglen,
int mactype,
const EVP_MD *md, COMP_METHOD *comp,
@ -1429,9 +1427,10 @@ tls_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers,
goto err;
}
ret = (*retrl)->funcs->set_crypto_state(*retrl, level, key, keylen, iv,
ivlen, mackey, mackeylen, ciph,
taglen, mactype, md, comp);
ret = (*retrl)->funcs->set_crypto_state(*retrl, level, snkey, key, keylen,
iv, ivlen, mackey, mackeylen,
snciph, snoffs, ciph, taglen, mactype, md,
comp);
err:
if (ret != OSSL_RECORD_RETURN_SUCCESS) {
@ -1451,6 +1450,7 @@ static void tls_int_free(OSSL_RECORD_LAYER *rl)
tls_release_write_buffer(rl);
EVP_CIPHER_CTX_free(rl->enc_ctx);
EVP_CIPHER_CTX_free(rl->sn_enc_ctx);
EVP_MAC_CTX_free(rl->mac_ctx);
EVP_MD_CTX_free(rl->md_ctx);
#ifndef OPENSSL_NO_COMP
@ -1557,6 +1557,21 @@ int tls_allocate_write_buffers_default(OSSL_RECORD_LAYER *rl,
return 1;
}
size_t tls_get_record_body_alignment_offset(OSSL_RECORD_LAYER *rl,
const unsigned char *rec)
{
size_t alignoffset = 0;
size_t headersize = tls_get_record_header_len(rl);
#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD != 0
alignoffset = (size_t)rec;
alignoffset += headersize;
alignoffset = SSL3_ALIGN_PAYLOAD - 1 - ((alignoffset - 1) % SSL3_ALIGN_PAYLOAD);
#endif
return alignoffset;
}
int tls_initialise_write_packets_default(OSSL_RECORD_LAYER *rl,
OSSL_RECORD_TEMPLATE *templates,
size_t numtempl,
@ -1574,13 +1589,7 @@ int tls_initialise_write_packets_default(OSSL_RECORD_LAYER *rl,
wb = &bufs[j];
wb->type = templates[j].type;
#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD != 0
align = (size_t)TLS_BUFFER_get_buf(wb);
align += rl->isdtls ? DTLS1_RT_HEADER_LENGTH : SSL3_RT_HEADER_LENGTH;
align = SSL3_ALIGN_PAYLOAD - 1
- ((align - 1) % SSL3_ALIGN_PAYLOAD);
#endif
align = tls_get_record_body_alignment_offset(rl, TLS_BUFFER_get_buf(wb));
TLS_BUFFER_set_offset(wb, align);
if (!WPACKET_init_static_len(thispkt, TLS_BUFFER_get_buf(wb),
@ -1684,8 +1693,9 @@ int tls_post_encryption_processing_default(OSSL_RECORD_LAYER *rl,
TLS_RL_RECORD *thiswr)
{
size_t origlen, len;
size_t headerlen = rl->isdtls ? DTLS1_RT_HEADER_LENGTH
: SSL3_RT_HEADER_LENGTH;
unsigned char *recordstart;
size_t rechdrlen;
size_t written;
/* Allocate bytes for the encryption overhead */
if (!WPACKET_get_length(thispkt, &origlen)
@ -1714,19 +1724,39 @@ int tls_post_encryption_processing_default(OSSL_RECORD_LAYER *rl,
}
if (!WPACKET_get_length(thispkt, &len)
|| !WPACKET_close(thispkt)) {
|| !WPACKET_close(thispkt)
|| !WPACKET_get_total_written(thispkt, &written)) {
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return 0;
}
recordstart = WPACKET_get_curr(thispkt) - written;
recordstart += tls_get_record_body_alignment_offset(rl, recordstart);
if (rl->isdtls)
rechdrlen = dtls_get_rec_header_size(*recordstart);
else
rechdrlen = SSL3_RT_HEADER_LENGTH;
if (rl->isdtls && DTLS13_UNI_HDR_FIX_BITS_IS_SET(*recordstart)) {
size_t seqnumlen = DTLS13_UNI_HDR_SEQ_BIT_IS_SET(*recordstart) ? 2 : 1;
if (!ossl_assert(DTLS13_UNI_HDR_SEQ_OFF + seqnumlen <= rechdrlen)
|| !dtls_crypt_sequence_number(rl->sn_enc_ctx, recordstart + DTLS13_UNI_HDR_SEQ_OFF,
seqnumlen, recordstart + rechdrlen,
rl->sn_enc_offs)) {
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return 0;
}
}
if (rl->msg_callback != NULL) {
unsigned char *recordstart;
const int version1_3 = rl->isdtls ? DTLS1_3_VERSION : TLS1_3_VERSION;
recordstart = WPACKET_get_curr(thispkt) - len - headerlen;
rl->msg_callback(1, thiswr->rec_version, SSL3_RT_HEADER, recordstart,
headerlen, rl->cbarg);
rechdrlen, rl->cbarg);
if (rl->version == TLS1_3_VERSION && rl->enc_ctx != NULL) {
if (rl->version == version1_3 && rl->enc_ctx != NULL) {
unsigned char ctype = thistempl->type;
rl->msg_callback(1, thiswr->rec_version, SSL3_RT_INNER_CONTENT_TYPE,
@ -1739,7 +1769,7 @@ int tls_post_encryption_processing_default(OSSL_RECORD_LAYER *rl,
return 0;
}
TLS_RL_RECORD_add_length(thiswr, headerlen);
TLS_RL_RECORD_add_length(thiswr, rechdrlen);
return 1;
}
@ -1998,6 +2028,22 @@ int tls_set1_bio(OSSL_RECORD_LAYER *rl, BIO *bio)
return 1;
}
size_t tls_get_record_header_len(OSSL_RECORD_LAYER *rl)
{
size_t headerlen;
if (rl->isdtls) {
if (rl->version == DTLS1_3_VERSION && rl->epoch > 0)
headerlen = DTLS13_UNI_HDR_FIXED_LENGTH;
else
headerlen = DTLS1_RT_HEADER_LENGTH;
} else {
headerlen = SSL3_RT_HEADER_LENGTH;
}
return headerlen;
}
/* Shared by most methods except tlsany_meth */
int tls_default_set_protocol_version(OSSL_RECORD_LAYER *rl, int version)
{

View file

@ -15,9 +15,11 @@
#define MIN_SSL2_RECORD_LEN 9
static int tls_any_set_crypto_state(OSSL_RECORD_LAYER *rl, int level,
unsigned char *snkey,
unsigned char *key, size_t keylen,
unsigned char *iv, size_t ivlen,
unsigned char *mackey, size_t mackeylen,
const EVP_CIPHER *snciph, size_t snoffs,
const EVP_CIPHER *ciph,
size_t taglen,
int mactype,
@ -54,6 +56,8 @@ static int tls_validate_record_header(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *rec)
return 0;
}
} else {
const int version1_3 = rl->isdtls ? DTLS1_3_VERSION : TLS1_3_VERSION;
if (rl->version == TLS_ANY_VERSION) {
if ((rec->rec_version >> 8) != SSL3_VERSION_MAJOR) {
if (rl->is_first_record) {
@ -86,7 +90,7 @@ static int tls_validate_record_header(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *rec)
return 0;
}
}
} else if (rl->version == TLS1_3_VERSION) {
} else if (rl->version == version1_3) {
/*
* In this case we know we are going to negotiate TLSv1.3, but we've
* had an HRR, so we haven't actually done so yet. In TLSv1.3 we

View file

@ -204,10 +204,13 @@ int dtls1_read_bytes(SSL *s, uint8_t type, uint8_t *recvd_type,
TLS_RECORD *rr;
void (*cb) (const SSL *ssl, int type2, int val) = NULL;
SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
int is_dtls13;
if (sc == NULL)
return -1;
is_dtls13 = SSL_CONNECTION_IS_DTLS13(sc);
if ((type && (type != SSL3_RT_APPLICATION_DATA) &&
(type != SSL3_RT_HANDSHAKE)) ||
(peek && (type != SSL3_RT_APPLICATION_DATA))) {
@ -312,7 +315,8 @@ int dtls1_read_bytes(SSL *s, uint8_t type, uint8_t *recvd_type,
if (type == rr->type
|| (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC
&& type == SSL3_RT_HANDSHAKE && recvd_type != NULL)) {
&& type == SSL3_RT_HANDSHAKE && recvd_type != NULL
&& !is_dtls13)) {
/*
* SSL3_RT_APPLICATION_DATA or
* SSL3_RT_HANDSHAKE or
@ -405,7 +409,8 @@ int dtls1_read_bytes(SSL *s, uint8_t type, uint8_t *recvd_type,
cb(s, SSL_CB_READ_ALERT, j);
}
if (alert_level == SSL3_AL_WARNING) {
if ((!is_dtls13 && alert_level == SSL3_AL_WARNING)
|| (is_dtls13 && alert_descr == SSL_AD_USER_CANCELLED)) {
sc->s3.warn_alert = alert_descr;
if (!ssl_release_record(sc, rr, 0))
return -1;
@ -416,8 +421,16 @@ int dtls1_read_bytes(SSL *s, uint8_t type, uint8_t *recvd_type,
SSL_R_TOO_MANY_WARN_ALERTS);
return -1;
}
}
if (alert_descr == SSL_AD_CLOSE_NOTIFY) {
/*
* Apart from close_notify the only other warning alert in DTLSv1.3
* is user_cancelled - which we just ignore.
*/
if (is_dtls13 && alert_descr == SSL_AD_USER_CANCELLED) {
goto start;
} else if (alert_descr == SSL_AD_CLOSE_NOTIFY
&& (is_dtls13 || alert_level == SSL3_AL_WARNING)) {
#ifndef OPENSSL_NO_SCTP
/*
* With SCTP and streams the socket may deliver app data
@ -435,8 +448,7 @@ int dtls1_read_bytes(SSL *s, uint8_t type, uint8_t *recvd_type,
#endif
sc->shutdown |= SSL_RECEIVED_SHUTDOWN;
return 0;
}
} else if (alert_level == SSL3_AL_FATAL) {
} else if (alert_level == SSL3_AL_FATAL || is_dtls13) {
sc->rwstate = SSL_NOTHING;
sc->s3.fatal_alert = alert_descr;
SSLfatal_data(sc, SSL_AD_NO_ALERT,
@ -447,12 +459,13 @@ int dtls1_read_bytes(SSL *s, uint8_t type, uint8_t *recvd_type,
return -1;
SSL_CTX_remove_session(sc->session_ctx, sc->session);
return 0;
} else {
SSLfatal(sc, SSL_AD_ILLEGAL_PARAMETER, SSL_R_UNKNOWN_ALERT_TYPE);
return -1;
} else if (alert_level == SSL3_AL_WARNING) {
/* We ignore any other warning alert in (D)TLSv1.2 and below */
goto start;
}
goto start;
SSLfatal(sc, SSL_AD_ILLEGAL_PARAMETER, SSL_R_UNKNOWN_ALERT_TYPE);
return -1;
}
if (sc->shutdown & SSL_SENT_SHUTDOWN) { /* but we have not received a
@ -477,32 +490,32 @@ int dtls1_read_bytes(SSL *s, uint8_t type, uint8_t *recvd_type,
* Unexpected handshake message (Client Hello, or protocol violation)
*/
if (rr->type == SSL3_RT_HANDSHAKE && !ossl_statem_get_in_handshake(sc)) {
struct hm_header_st msg_hdr;
unsigned char msg_type;
/*
* This may just be a stale retransmit. Also sanity check that we have
* at least enough record bytes for a message header
*/
if (rr->epoch != sc->rlayer.d->r_epoch
if (rr->epoch != dtls1_get_epoch(sc, SSL3_CC_READ)
|| rr->length < DTLS1_HM_HEADER_LENGTH) {
if (!ssl_release_record(sc, rr, 0))
return -1;
goto start;
}
dtls1_get_message_header(rr->data, &msg_hdr);
msg_type = *rr->data;
/*
* If we are server, we may have a repeated FINISHED of the client
* here, then retransmit our CCS and FINISHED.
*/
if (msg_hdr.type == SSL3_MT_FINISHED) {
if (msg_type == SSL3_MT_FINISHED) {
if (dtls1_check_timeout_num(sc) < 0) {
/* SSLfatal) already called */
return -1;
}
if (dtls1_retransmit_buffered_messages(sc) <= 0) {
if (dtls1_retransmit_sent_messages(sc) <= 0) {
/* Fail if we encountered a fatal error */
if (ossl_statem_in_error(sc))
return -1;
@ -643,12 +656,14 @@ int do_dtls1_write(SSL_CONNECTION *sc, uint8_t type, const unsigned char *buf,
}
tmpl.type = type;
if (sc->version == DTLS1_3_VERSION)
tmpl.version = DTLS1_2_VERSION;
/*
* Special case: for hello verify request, client version 1.0 and we
* haven't decided which version to use yet send back using version 1.0
* header: otherwise some clients will ignore it.
*/
if (s->method->version == DTLS_ANY_VERSION
else if (s->method->version == DTLS_ANY_VERSION
&& sc->max_proto_version != DTLS1_BAD_VER)
tmpl.version = DTLS1_VERSION;
else

View file

@ -81,16 +81,16 @@ int RECORD_LAYER_reset(RECORD_LAYER *rl)
? DTLS_ANY_VERSION : TLS_ANY_VERSION,
OSSL_RECORD_DIRECTION_READ,
OSSL_RECORD_PROTECTION_LEVEL_NONE, NULL, 0,
NULL, 0, NULL, 0, NULL, 0, NULL, 0,
NID_undef, NULL, NULL, NULL);
NULL, NULL, 0, NULL, 0, NULL, 0, NULL, 0, NULL,
0, NID_undef, NULL, NULL, NULL);
ret &= ssl_set_new_record_layer(rl->s,
SSL_CONNECTION_IS_DTLS(rl->s)
? DTLS_ANY_VERSION : TLS_ANY_VERSION,
OSSL_RECORD_DIRECTION_WRITE,
OSSL_RECORD_PROTECTION_LEVEL_NONE, NULL, 0,
NULL, 0, NULL, 0, NULL, 0, NULL, 0,
NID_undef, NULL, NULL, NULL);
NULL, NULL, 0, NULL, 0, NULL, 0, NULL, 0, NULL,
0, NID_undef, NULL, NULL, NULL);
/* SSLfatal already called in the event of failure */
return ret;
@ -1235,9 +1235,11 @@ static int ssl_post_record_layer_select(SSL_CONNECTION *s, int direction)
int ssl_set_new_record_layer(SSL_CONNECTION *s, int version,
int direction, int level,
unsigned char *secret, size_t secretlen,
unsigned char *snkey,
unsigned char *key, size_t keylen,
unsigned char *iv, size_t ivlen,
unsigned char *mackey, size_t mackeylen,
const EVP_CIPHER *snciph, size_t snoffs,
const EVP_CIPHER *ciph, size_t taglen,
int mactype, const EVP_MD *md,
const SSL_COMP *comp, const EVP_MD *kdfdigest)
@ -1413,9 +1415,11 @@ int ssl_set_new_record_layer(SSL_CONNECTION *s, int version,
rlret = meth->new_record_layer(sctx->libctx, sctx->propq, version,
s->server, direction, level, epoch,
secret, secretlen, key, keylen, iv,
ivlen, mackey, mackeylen, ciph, taglen,
mactype, md, compm, kdfdigest, prev,
secret, secretlen, snkey, key, keylen,
iv,
ivlen, mackey, mackeylen, snciph, snoffs, ciph,
taglen, mactype, md, compm, kdfdigest,
prev,
thisbio, next, NULL, NULL, settings,
options, rlayer_dispatch_tmp, s,
s->rlayer.rlarg, &newrl);
@ -1457,7 +1461,7 @@ int ssl_set_new_record_layer(SSL_CONNECTION *s, int version,
*/
if (!SSL_CONNECTION_IS_DTLS(s)
|| direction == OSSL_RECORD_DIRECTION_READ
|| pqueue_peek(s->d1->sent_messages) == NULL) {
|| pqueue_peek(&s->d1->sent_messages) == NULL) {
if (*thismethod != NULL && !(*thismethod)->free(*thisrl)) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return 0;
@ -1472,11 +1476,14 @@ int ssl_set_new_record_layer(SSL_CONNECTION *s, int version,
int ssl_set_record_protocol_version(SSL_CONNECTION *s, int vers)
{
if (!ossl_assert(s->rlayer.rrlmethod != NULL)
|| !ossl_assert(s->rlayer.wrlmethod != NULL))
if ((s->negotiated_version != PROTO_VERSION_UNSET && s->negotiated_version != vers)
|| !ossl_assert(s->rlayer.rrlmethod != NULL)
|| !ossl_assert(s->rlayer.wrlmethod != NULL)
|| !s->rlayer.rrlmethod->set_protocol_version(s->rlayer.rrl, vers)
|| !s->rlayer.wrlmethod->set_protocol_version(s->rlayer.wrl, vers))
return 0;
s->rlayer.rrlmethod->set_protocol_version(s->rlayer.rrl, s->version);
s->rlayer.wrlmethod->set_protocol_version(s->rlayer.wrl, s->version);
s->negotiated_version = vers;
return 1;
}

View file

@ -174,9 +174,11 @@ int ossl_tls_handle_rlayer_return(SSL_CONNECTION *s, int writing, int ret,
int ssl_set_new_record_layer(SSL_CONNECTION *s, int version,
int direction, int level,
unsigned char *secret, size_t secretlen,
unsigned char *snkey,
unsigned char *key, size_t keylen,
unsigned char *iv, size_t ivlen,
unsigned char *mackey, size_t mackeylen,
const EVP_CIPHER *snciph, size_t snoffs,
const EVP_CIPHER *ciph, size_t taglen,
int mactype, const EVP_MD *md,
const SSL_COMP *comp, const EVP_MD *kdfdigest);

View file

@ -144,11 +144,11 @@ int ssl3_change_cipher_state(SSL_CONNECTION *s, int which)
goto err;
}
if (!ssl_set_new_record_layer(s, SSL3_VERSION,
direction,
if (!ssl_set_new_record_layer(s, SSL3_VERSION, direction,
OSSL_RECORD_PROTECTION_LEVEL_APPLICATION,
NULL, 0, key, key_len, iv, iv_len, mac_secret,
md_len, ciph, 0, NID_undef, md, comp, NULL)) {
NULL, 0, NULL, key, key_len, iv, iv_len,
mac_secret, md_len, NULL, 0, ciph, 0, NID_undef,
md, comp, NULL)) {
/* SSLfatal already called */
goto err;
}
@ -170,8 +170,8 @@ int ssl3_setup_key_block(SSL_CONNECTION *s)
if (s->s3.tmp.key_block_length != 0)
return 1;
if (!ssl_cipher_get_evp(SSL_CONNECTION_GET_CTX(s), s->session, &c, &hash,
NULL, NULL, &comp, 0)) {
if (!ssl_cipher_get_evp(SSL_CONNECTION_GET_CTX(s), s->session, NULL, NULL, &c,
&hash, NULL, NULL, &comp, 0)) {
/* Error is already recorded */
SSLfatal_alert(s, SSL_AD_INTERNAL_ERROR);
return 0;
@ -260,11 +260,72 @@ int ssl3_finish_mac(SSL_CONNECTION *s, const unsigned char *buf, size_t len)
return 0;
}
} else {
ret = EVP_DigestUpdate(s->s3.handshake_dgst, buf, len);
if (!ret) {
/*
* rfc9147:
* In DTLS 1.3, the message transcript is computed over the
* original TLS 1.3-style Handshake messages without the
* message_seq, fragment_offset, and fragment_length values. Note
* that this is a change from DTLS 1.2 where those values were
* included in the transcript.
*
* So this means that we record the full handshake messages in
* s->s3.handshake_buffer while s->s3.handshake_dgst is not in use and then
* we calculate the digest when initiating s->s3.handshake_dgst at which
* point we know what the protocol version is.
*/
if (s->negotiated_version == DTLS1_3_VERSION) {
/*
* In DTLS 1.3 we need to parse the messages that are buffered to
* be able to remove message_sequence, fragment_size and fragment_offset
* from the Transcript Hash calculation.
*/
while (len > 0) {
PACKET hmhdr;
unsigned long hmbodylen;
unsigned int msgtype;
size_t hmhdrlen;
if (!ossl_assert(len >= SSL3_HM_HEADER_LENGTH)
|| !PACKET_buf_init(&hmhdr, buf, SSL3_HM_HEADER_LENGTH)
|| !PACKET_get_1(&hmhdr, &msgtype)
|| !PACKET_get_net_3(&hmhdr, &hmbodylen)) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return 0;
}
/*
* SSL3_MT_MESSAGE_HASH is a dummy message type only used when
* calculating the transcript hash of the synthetic message in
* (D)TLS 1.3.
*/
if (msgtype == SSL3_MT_MESSAGE_HASH)
hmhdrlen = SSL3_HM_HEADER_LENGTH;
else
hmhdrlen = DTLS1_HM_HEADER_LENGTH;
/*
* In DTLS 1.3 the transcript hash is calculated excluding the
* message_sequence, fragment_size and fragment_offset header
* fields which are carried in the last
* DTLS1_HM_HEADER_LENGTH - SSL3_HM_HEADER_LENGTH header bytes
* of the DTLS handshake message header.
*/
if (!ossl_assert(hmhdrlen + hmbodylen <= len)
|| !EVP_DigestUpdate(s->s3.handshake_dgst, buf, SSL3_HM_HEADER_LENGTH)
|| !EVP_DigestUpdate(s->s3.handshake_dgst, buf + hmhdrlen, hmbodylen)) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return 0;
}
buf += hmhdrlen + hmbodylen;
len -= hmhdrlen + hmbodylen;
}
} else {
if (!EVP_DigestUpdate(s->s3.handshake_dgst, buf, len)) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return 0;
}
}
}
return 1;
}
@ -294,11 +355,14 @@ int ssl3_digest_cached_records(SSL_CONNECTION *s, int keep)
SSL_R_NO_SUITABLE_DIGEST_ALGORITHM);
return 0;
}
if (!EVP_DigestInit_ex(s->s3.handshake_dgst, md, NULL)
|| !EVP_DigestUpdate(s->s3.handshake_dgst, hdata, hdatalen)) {
if (!EVP_DigestInit_ex(s->s3.handshake_dgst, md, NULL)) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return 0;
}
if (!ssl3_finish_mac(s, hdata, hdatalen)) {
/* SSLfatal() already called */
return 0;
}
}
if (keep == 0) {
BIO_free(s->s3.handshake_buffer);

View file

@ -26,7 +26,7 @@
#define SSL3_NUM_CIPHERS OSSL_NELEM(ssl3_ciphers)
#define SSL3_NUM_SCSVS OSSL_NELEM(ssl3_scsvs)
/* TLSv1.3 downgrade protection sentinel values */
/* TLSv1.3 downgrade protection sentinel values (rfc8446 4.1.3.) */
const unsigned char tls11downgrade[] = {
0x44, 0x4f, 0x57, 0x4e, 0x47, 0x52, 0x44, 0x00
};
@ -46,7 +46,7 @@ static SSL_CIPHER tls13_ciphers[] = {
SSL_AES128GCM,
SSL_AEAD,
TLS1_3_VERSION, TLS1_3_VERSION,
0, 0,
DTLS1_3_VERSION, DTLS1_3_VERSION,
SSL_HIGH,
SSL_HANDSHAKE_MAC_SHA256 | SSL_QUIC,
128,
@ -61,7 +61,7 @@ static SSL_CIPHER tls13_ciphers[] = {
SSL_AES256GCM,
SSL_AEAD,
TLS1_3_VERSION, TLS1_3_VERSION,
0, 0,
DTLS1_3_VERSION, DTLS1_3_VERSION,
SSL_HIGH,
SSL_HANDSHAKE_MAC_SHA384 | SSL_QUIC,
256,
@ -77,7 +77,7 @@ static SSL_CIPHER tls13_ciphers[] = {
SSL_CHACHA20POLY1305,
SSL_AEAD,
TLS1_3_VERSION, TLS1_3_VERSION,
0, 0,
DTLS1_3_VERSION, DTLS1_3_VERSION,
SSL_HIGH,
SSL_HANDSHAKE_MAC_SHA256 | SSL_QUIC,
256,
@ -93,7 +93,7 @@ static SSL_CIPHER tls13_ciphers[] = {
SSL_AES128CCM,
SSL_AEAD,
TLS1_3_VERSION, TLS1_3_VERSION,
0, 0,
DTLS1_3_VERSION, DTLS1_3_VERSION,
SSL_NOT_DEFAULT | SSL_HIGH,
SSL_HANDSHAKE_MAC_SHA256,
128,
@ -108,7 +108,7 @@ static SSL_CIPHER tls13_ciphers[] = {
SSL_AES128CCM8,
SSL_AEAD,
TLS1_3_VERSION, TLS1_3_VERSION,
0, 0,
DTLS1_3_VERSION, DTLS1_3_VERSION,
SSL_NOT_DEFAULT | SSL_MEDIUM,
SSL_HANDSHAKE_MAC_SHA256,
64, /* CCM8 uses a short tag, so we have a low security strength */
@ -3415,6 +3415,7 @@ void ssl3_free(SSL *s)
sc->s3.tmp.pkey = NULL;
ssl_evp_cipher_free(sc->s3.tmp.new_sym_enc);
ssl_evp_cipher_free(sc->s3.tmp.new_sym_enc_sn);
ssl_evp_md_free(sc->s3.tmp.new_hash);
OPENSSL_free(sc->s3.tmp.ctype);
@ -3731,7 +3732,7 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
{
unsigned int id;
if (SSL_CONNECTION_IS_TLS13(sc) && sc->s3.did_kex)
if (SSL_CONNECTION_IS_VERSION13(sc) && sc->s3.did_kex)
id = sc->s3.group_id;
else
id = sc->session->kex_group;
@ -4319,7 +4320,7 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL_CONNECTION *s, STACK_OF(SSL_CIPHER) *cl
allow = srvr;
}
if (SSL_CONNECTION_IS_TLS13(s)) {
if (SSL_CONNECTION_IS_VERSION13(s)) {
#ifndef OPENSSL_NO_PSK
size_t j;
@ -4351,7 +4352,8 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL_CONNECTION *s, STACK_OF(SSL_CIPHER) *cl
maxversion = SSL_CONNECTION_IS_DTLS(s) ? c->max_dtls : c->max_tls;
/* Skip ciphers not supported by the protocol version */
if (ssl_version_cmp(s, s->version, minversion) < 0
if (minversion <= 0 || maxversion <= 0
|| ssl_version_cmp(s, s->version, minversion) < 0
|| ssl_version_cmp(s, s->version, maxversion) > 0)
continue;
@ -4359,7 +4361,7 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL_CONNECTION *s, STACK_OF(SSL_CIPHER) *cl
* Since TLS 1.3 ciphersuites can be used with any auth or
* key exchange scheme skip tests.
*/
if (!SSL_CONNECTION_IS_TLS13(s)) {
if (!SSL_CONNECTION_IS_VERSION13(s)) {
mask_k = s->s3.tmp.mask_k;
mask_a = s->s3.tmp.mask_a;
#ifndef OPENSSL_NO_SRP
@ -4902,7 +4904,7 @@ int ssl_gensecret(SSL_CONNECTION *s, unsigned char *pms, size_t pmslen)
int rv = 0;
/* SSLfatal() called as appropriate in the below functions */
if (SSL_CONNECTION_IS_TLS13(s)) {
if (SSL_CONNECTION_IS_VERSION13(s)) {
/*
* If we are resuming then we already generated the early secret
* when we created the ClientHello, so don't recreate it.
@ -4945,7 +4947,7 @@ int ssl_derive(SSL_CONNECTION *s, EVP_PKEY *privkey, EVP_PKEY *pubkey, int gense
goto err;
}
if (SSL_CONNECTION_IS_TLS13(s) && EVP_PKEY_is_a(privkey, "DH"))
if (SSL_CONNECTION_IS_VERSION13(s) && EVP_PKEY_is_a(privkey, "DH"))
EVP_PKEY_CTX_set_dh_pad(pctx, 1);
pms = OPENSSL_malloc(pmslen);
@ -5097,7 +5099,7 @@ const char *SSL_get0_group_name(SSL *s)
if (sc == NULL)
return NULL;
if (SSL_CONNECTION_IS_TLS13(sc) && sc->s3.did_kex)
if (SSL_CONNECTION_IS_VERSION13(sc) && sc->s3.did_kex)
id = sc->s3.group_id;
else
id = sc->session->kex_group;

View file

@ -1208,8 +1208,10 @@ static int ssl_security_default_callback(const SSL *s, const SSL_CTX *ctx,
int op, int bits, int nid, void *other,
void *ex)
{
int level, minbits, pfs_mask;
int level, minbits, pfs_mask, minversion;
const SSL_CONNECTION *sc;
const int version1_3 = SSL_is_dtls(s) ? DTLS1_3_VERSION : TLS1_3_VERSION;
const int version1_2 = SSL_is_dtls(s) ? DTLS1_2_VERSION : TLS1_2_VERSION;
minbits = ssl_get_security_level_bits(s, ctx, &level);
@ -1240,9 +1242,12 @@ static int ssl_security_default_callback(const SSL *s, const SSL_CTX *ctx,
/* SHA1 HMAC is 160 bits of security */
if (minbits > 160 && c->algorithm_mac & SSL_SHA1)
return 0;
/* Level 3: forward secure ciphersuites only */
pfs_mask = SSL_kDHE | SSL_kECDHE | SSL_kDHEPSK | SSL_kECDHEPSK;
if (level >= 3 && c->min_tls != TLS1_3_VERSION &&
minversion = SSL_is_dtls(s) ? c->min_dtls : c->min_tls;
if (level >= 3 && minversion != version1_3 &&
!(c->algorithm_mkey & pfs_mask))
return 0;
break;
@ -1250,15 +1255,9 @@ static int ssl_security_default_callback(const SSL *s, const SSL_CTX *ctx,
case SSL_SECOP_VERSION:
if ((sc = SSL_CONNECTION_FROM_CONST_SSL(s)) == NULL)
return 0;
if (!SSL_CONNECTION_IS_DTLS(sc)) {
/* SSLv3, TLS v1.0 and TLS v1.1 only allowed at level 0 */
if (nid <= TLS1_1_VERSION && level > 0)
/* SSLv3, TLS v1.0 and TLS v1.1 and DTLS v1.0 only allowed at level 0 */
if (ssl_version_cmp(sc, nid, version1_2) < 0 && level > 0)
return 0;
} else {
/* DTLS v1.0 only allowed at level 0 */
if (DTLS_VERSION_LT(nid, DTLS1_2_VERSION) && level > 0)
return 0;
}
break;
case SSL_SECOP_COMPRESSION:

View file

@ -494,8 +494,51 @@ int ssl_cipher_get_evp_md_mac(SSL_CTX *ctx, const SSL_CIPHER *sslc,
return 1;
}
int ssl_cipher_get_evp_cipher_sn(SSL_CTX *ctx, const SSL_CIPHER *sslc,
const EVP_CIPHER **enc, size_t *inputoffs)
{
int i = ssl_cipher_info_lookup(ssl_cipher_table_cipher, sslc->algorithm_enc);
if (i == -1) {
*enc = NULL;
} else {
if (i == SSL_ENC_NULL_IDX) {
/*
* We assume we don't care about this coming from an ENGINE so
* just do a normal EVP_CIPHER_fetch instead of
* ssl_evp_cipher_fetch()
*/
*enc = EVP_CIPHER_fetch(ctx->libctx, "NULL", ctx->propq);
} else {
int ecbnid = NID_undef;
*enc = NULL;
if ((sslc->algorithm_enc & SSL_AES128_ANY) != 0) {
ecbnid = NID_aes_128_ecb;
*inputoffs = 0;
} else if ((sslc->algorithm_enc & SSL_AES256_ANY) != 0) {
ecbnid = NID_aes_256_ecb;
*inputoffs = 0;
} else if (ossl_assert((sslc->algorithm_enc & SSL_CHACHA20) != 0)) {
ecbnid = NID_chacha20;
*inputoffs = 4;
}
if (ecbnid != NID_undef)
*enc = ssl_evp_cipher_fetch(ctx->libctx, ecbnid, ctx->propq);
}
if (*enc == NULL)
return 0;
}
return 1;
}
int ssl_cipher_get_evp(SSL_CTX *ctx, const SSL_SESSION *s,
const EVP_CIPHER **enc, const EVP_MD **md,
const EVP_CIPHER **snenc, size_t *snencoffs,
const EVP_CIPHER **enc,
const EVP_MD **md,
int *mac_pkey_type, size_t *mac_secret_size,
SSL_COMP **comp, int use_etm)
{
@ -525,12 +568,18 @@ int ssl_cipher_get_evp(SSL_CTX *ctx, const SSL_SESSION *s,
if ((enc == NULL) || (md == NULL))
return 0;
if (!ssl_cipher_get_evp_cipher(ctx, c, enc))
if (!ssl_cipher_get_evp_cipher(ctx, c, enc)
|| (snenc != NULL
&& !ssl_cipher_get_evp_cipher_sn(ctx, c, snenc, snencoffs)))
return 0;
if (!ssl_cipher_get_evp_md_mac(ctx, c, md, mac_pkey_type,
mac_secret_size)) {
ssl_evp_cipher_free(*enc);
if (snenc != NULL)
ssl_evp_cipher_free(*snenc);
return 0;
}
@ -1354,15 +1403,23 @@ static int update_cipher_list(SSL_CTX *ctx,
return 0;
/*
* Delete any existing TLSv1.3 ciphersuites. These are always first in the
* Delete any existing (D)TLSv1.3 ciphersuites. These are always first in the
* list.
*/
while (sk_SSL_CIPHER_num(tmp_cipher_list) > 0
&& sk_SSL_CIPHER_value(tmp_cipher_list, 0)->min_tls
== TLS1_3_VERSION)
(void)sk_SSL_CIPHER_delete(tmp_cipher_list, 0);
/* Insert the new TLSv1.3 ciphersuites */
while (sk_SSL_CIPHER_num(tmp_cipher_list) > 0) {
const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(tmp_cipher_list, 0);
const int version1_3 = SSL_CTX_IS_DTLS(ctx) ? DTLS1_3_VERSION
: TLS1_3_VERSION;
const int minversion = SSL_CTX_IS_DTLS(ctx) ? cipher->min_dtls
: cipher->min_tls;
if (minversion != version1_3)
break;
(void)sk_SSL_CIPHER_delete(tmp_cipher_list, 0);
}
/* Insert the new (D)TLSv1.3 ciphersuites */
for (i = sk_SSL_CIPHER_num(tls13_ciphersuites) - 1; i >= 0; i--) {
const SSL_CIPHER *sslc = sk_SSL_CIPHER_value(tls13_ciphersuites, i);

View file

@ -287,7 +287,8 @@ static int cmd_Protocol(SSL_CONF_CTX *cctx, const char *value)
SSL_FLAG_TBL_INV("TLSv1.2", SSL_OP_NO_TLSv1_2),
SSL_FLAG_TBL_INV("TLSv1.3", SSL_OP_NO_TLSv1_3),
SSL_FLAG_TBL_INV("DTLSv1", SSL_OP_NO_DTLSv1),
SSL_FLAG_TBL_INV("DTLSv1.2", SSL_OP_NO_DTLSv1_2)
SSL_FLAG_TBL_INV("DTLSv1.2", SSL_OP_NO_DTLSv1_2),
SSL_FLAG_TBL_INV("DTLSv1.3", SSL_OP_NO_DTLSv1_3)
};
cctx->tbl = ssl_protocol_list;
cctx->ntbl = OSSL_NELEM(ssl_protocol_list);
@ -320,7 +321,8 @@ static int protocol_from_string(const char *value)
{"TLSv1.2", TLS1_2_VERSION},
{"TLSv1.3", TLS1_3_VERSION},
{"DTLSv1", DTLS1_VERSION},
{"DTLSv1.2", DTLS1_2_VERSION}
{"DTLSv1.2", DTLS1_2_VERSION},
{"DTLSv1.3", DTLS1_3_VERSION}
};
size_t i;
size_t n = OSSL_NELEM(versions);

View file

@ -472,7 +472,11 @@ static int ssl_check_allowed_versions(int min_version, int max_version)
/* Ignore DTLS1_BAD_VER */
min_version = DTLS1_VERSION;
if (max_version == 0)
max_version = DTLS1_3_VERSION;
#ifdef OPENSSL_NO_DTLS1_3
if (max_version == DTLS1_3_VERSION)
max_version = DTLS1_2_VERSION;
#endif
#ifdef OPENSSL_NO_DTLS1_2
if (max_version == DTLS1_2_VERSION)
max_version = DTLS1_VERSION;
@ -490,6 +494,10 @@ static int ssl_check_allowed_versions(int min_version, int max_version)
#ifdef OPENSSL_NO_DTLS1_2
|| (DTLS_VERSION_GE(min_version, DTLS1_2_VERSION)
&& DTLS_VERSION_GE(DTLS1_2_VERSION, max_version))
#endif
#ifdef OPENSSL_NO_DTLS1_3
|| (DTLS_VERSION_GE(min_version, DTLS1_3_VERSION)
&& DTLS_VERSION_GE(DTLS1_3_VERSION, max_version))
#endif
)
return 0;
@ -943,6 +951,9 @@ int SSL_is_dtls(const SSL *s)
{
SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
if (s == NULL)
return 0;
#ifndef OPENSSL_NO_QUIC
if (s->type == SSL_TYPE_QUIC_CONNECTION || s->type == SSL_TYPE_QUIC_XSO)
return 0;
@ -2785,7 +2796,7 @@ int SSL_key_update(SSL *s, int updatetype)
if (sc == NULL)
return 0;
if (!SSL_CONNECTION_IS_TLS13(sc)) {
if (!SSL_CONNECTION_IS_VERSION13(sc)) {
ERR_raise(ERR_LIB_SSL, SSL_R_WRONG_SSL_VERSION);
return 0;
}
@ -2832,7 +2843,7 @@ int SSL_get_key_update_type(const SSL *s)
*/
static int can_renegotiate(const SSL_CONNECTION *sc)
{
if (SSL_CONNECTION_IS_TLS13(sc)) {
if (SSL_CONNECTION_IS_VERSION13(sc)) {
ERR_raise(ERR_LIB_SSL, SSL_R_WRONG_SSL_VERSION);
return 0;
}
@ -2899,7 +2910,7 @@ int SSL_new_session_ticket(SSL *s)
/* If we are in init because we're sending tickets, okay to send more. */
if ((SSL_in_init(s) && sc->ext.extra_tickets_expected == 0)
|| SSL_IS_FIRST_HANDSHAKE(sc) || !sc->server
|| !SSL_CONNECTION_IS_TLS13(sc))
|| !SSL_CONNECTION_IS_VERSION13(sc))
return 0;
sc->ext.extra_tickets_expected++;
if (!RECORD_LAYER_write_pending(&sc->rlayer) && !SSL_in_init(s))
@ -3315,16 +3326,21 @@ STACK_OF(SSL_CIPHER) *SSL_CTX_get_ciphers(const SSL_CTX *ctx)
* Distinguish between ciphers controlled by set_ciphersuite() and
* set_cipher_list() when counting.
*/
static int cipher_list_tls12_num(STACK_OF(SSL_CIPHER) *sk)
static int cipher_list_tls12_num(STACK_OF(SSL_CIPHER) *sk, int isdtls)
{
int i, num = 0;
const SSL_CIPHER *c;
const int version1_3 = isdtls ? DTLS1_3_VERSION : TLS1_3_VERSION;
if (sk == NULL)
return 0;
for (i = 0; i < sk_SSL_CIPHER_num(sk); ++i) {
int minversion;
c = sk_SSL_CIPHER_value(sk, i);
if (c->min_tls >= TLS1_3_VERSION)
minversion = isdtls ? c->min_dtls : c->min_tls;
if (PROTOCOL_VERSION_CMP(isdtls, minversion, version1_3) >= 0)
continue;
num++;
}
@ -3348,7 +3364,8 @@ int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str)
*/
if (sk == NULL)
return 0;
if (ctx->method->num_ciphers() > 0 && cipher_list_tls12_num(sk) == 0) {
if (ctx->method->num_ciphers() > 0
&& cipher_list_tls12_num(sk, SSL_CTX_IS_DTLS(ctx)) == 0) {
ERR_raise(ERR_LIB_SSL, SSL_R_NO_CIPHER_MATCH);
return 0;
}
@ -3372,7 +3389,8 @@ int SSL_set_cipher_list(SSL *s, const char *str)
/* see comment in SSL_CTX_set_cipher_list */
if (sk == NULL)
return 0;
if (ctx->method->num_ciphers() > 0 && cipher_list_tls12_num(sk) == 0) {
if (ctx->method->num_ciphers() > 0
&& cipher_list_tls12_num(sk, SSL_CONNECTION_IS_DTLS(sc)) == 0) {
ERR_raise(ERR_LIB_SSL, SSL_R_NO_CIPHER_MATCH);
return 0;
}
@ -3457,21 +3475,21 @@ const char *SSL_get_servername(const SSL *s, const int type)
if (server) {
/**
* Server side
* In TLSv1.3 on the server SNI is not associated with the session
* but in TLSv1.2 or below it is.
* In (D)TLSv1.3 on the server SNI is not associated with the session
* but in (D)TLSv1.2 or below it is.
*
* Before the handshake:
* - return NULL
*
* During/after the handshake (TLSv1.2 or below resumption occurred):
* During/after the handshake ((D)TLSv1.2 or below resumption occurred):
* - If a servername was accepted by the server in the original
* handshake then it will return that servername, or NULL otherwise.
*
* During/after the handshake (TLSv1.2 or below resumption did not occur):
* During/after the handshake ((D)TLSv1.2 or below resumption did not occur):
* - The function will return the servername requested by the client in
* this handshake or NULL if none was requested.
*/
if (sc->hit && !SSL_CONNECTION_IS_TLS13(sc))
if (sc->hit && !SSL_CONNECTION_IS_VERSION13(sc))
return sc->session->ext.hostname;
} else {
/**
@ -3480,29 +3498,32 @@ const char *SSL_get_servername(const SSL *s, const int type)
* Before the handshake:
* - If a servername has been set via a call to
* SSL_set_tlsext_host_name() then it will return that servername
* - If one has not been set, but a TLSv1.2 resumption is being
* - If one has not been set, but a (D)TLSv1.2 resumption is being
* attempted and the session from the original handshake had a
* servername accepted by the server then it will return that
* servername
* - Otherwise it returns NULL
*
* During/after the handshake (TLSv1.2 or below resumption occurred):
* During/after the handshake ((D)TLSv1.2 or below resumption occurred):
* - If the session from the original handshake had a servername accepted
* by the server then it will return that servername.
* - Otherwise it returns the servername set via
* SSL_set_tlsext_host_name() (or NULL if it was not called).
*
* During/after the handshake (TLSv1.2 or below resumption did not occur):
* During/after the handshake ((D)TLSv1.2 or below resumption did not occur):
* - It will return the servername set via SSL_set_tlsext_host_name()
* (or NULL if it was not called).
*/
if (SSL_in_before(s)) {
const int version1_3 = SSL_CONNECTION_IS_DTLS(sc) ? DTLS1_3_VERSION
: TLS1_3_VERSION;
if (sc->ext.hostname == NULL
&& sc->session != NULL
&& sc->session->ssl_version != TLS1_3_VERSION)
&& sc->session->ssl_version != version1_3)
return sc->session->ext.hostname;
} else {
if (!SSL_CONNECTION_IS_TLS13(sc) && sc->hit
if (!SSL_CONNECTION_IS_VERSION13(sc) && sc->hit
&& sc->session->ext.hostname != NULL)
return sc->session->ext.hostname;
}
@ -3807,12 +3828,15 @@ int SSL_export_keying_material_early(SSL *s, unsigned char *out, size_t olen,
const unsigned char *context,
size_t contextlen)
{
int version1_3;
SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
if (sc == NULL)
return -1;
if (sc->version != TLS1_3_VERSION)
version1_3 = SSL_CONNECTION_IS_DTLS(sc) ? DTLS1_3_VERSION : TLS1_3_VERSION;
if (sc->version != version1_3)
return 0;
return tls13_export_keying_material_early(sc, out, olen, label, llen,
@ -4649,7 +4673,7 @@ void ssl_update_cache(SSL_CONNECTION *s, int mode)
i = s->session_ctx->session_cache_mode;
if ((i & mode) != 0
&& (!s->hit || SSL_CONNECTION_IS_TLS13(s))) {
&& (!s->hit || SSL_CONNECTION_IS_VERSION13(s))) {
/*
* Add the session to the internal cache. In server side TLSv1.3 we
* normally don't do this because by default it's a full stateless ticket
@ -4662,7 +4686,7 @@ void ssl_update_cache(SSL_CONNECTION *s, int mode)
* - SSL_OP_NO_TICKET is set in which case it is a stateful ticket
*/
if ((i & SSL_SESS_CACHE_NO_INTERNAL_STORE) == 0
&& (!SSL_CONNECTION_IS_TLS13(s)
&& (!SSL_CONNECTION_IS_VERSION13(s)
|| !s->server
|| (s->max_early_data > 0
&& (s->options & SSL_OP_NO_ANTI_REPLAY) == 0)
@ -4970,6 +4994,9 @@ const char *ssl_protocol_to_string(int version)
case DTLS1_2_VERSION:
return "DTLSv1.2";
case DTLS1_3_VERSION:
return "DTLSv1.3";
default:
return "unknown";
}
@ -7272,7 +7299,7 @@ int SSL_verify_client_post_handshake(SSL *ssl)
if (sc == NULL)
return 0;
if (!SSL_CONNECTION_IS_TLS13(sc)) {
if (!SSL_CONNECTION_IS_VERSION13(sc)) {
ERR_raise(ERR_LIB_SSL, SSL_R_WRONG_SSL_VERSION);
return 0;
}

View file

@ -45,7 +45,7 @@
# endif
# define TLS_MAX_VERSION_INTERNAL TLS1_3_VERSION
# define DTLS_MAX_VERSION_INTERNAL DTLS1_2_VERSION
# define DTLS_MAX_VERSION_INTERNAL DTLS1_3_VERSION
/*
* DTLS version numbers are strange because they're inverted. Except for
@ -56,6 +56,42 @@
# define DTLS_VERSION_GE(v1, v2) (dtls_ver_ordinal(v1) <= dtls_ver_ordinal(v2))
# define DTLS_VERSION_LT(v1, v2) (dtls_ver_ordinal(v1) > dtls_ver_ordinal(v2))
# define DTLS_VERSION_LE(v1, v2) (dtls_ver_ordinal(v1) >= dtls_ver_ordinal(v2))
/*
* SSL/TLS version comparison
*
* Returns
* 0 if versiona is equal to versionb or if either are 0 or less
* 1 if versiona is greater than versionb
* -1 if versiona is less than versionb
*/
# define TLS_VERSION_CMP(versiona, versionb) \
((!ossl_assert((versiona) > 0) || !ossl_assert((versionb) > 0) \
|| (versiona) == (versionb)) ? 0 \
: ((versiona) < (versionb) ? -1 : 1))
/*
* DTLS version comparison
*
* Returns
* 0 if versiona is equal to versionb or if either are 0 or less
* 1 if versiona is greater than versionb
* -1 if versiona is less than versionb
*/
# define DTLS_VERSION_CMP(versiona, versionb) \
((!ossl_assert((versiona) > 0) || !ossl_assert((versionb) > 0) \
|| (versiona) == (versionb)) ? 0 \
: (DTLS_VERSION_LT((versiona), \
(versionb)) ? -1 : 1))
/*
* SSL/TLS/DTLS version comparison
*
* Returns
* 0 if versiona is equal to versionb or if either are 0 or less
* 1 if versiona is greater than versionb
* -1 if versiona is less than versionb
*/
# define PROTOCOL_VERSION_CMP(isdtls, versiona, versionb) \
((isdtls) ? DTLS_VERSION_CMP(versiona, versionb) \
: TLS_VERSION_CMP(versiona, versionb))
# define SSL_AD_NO_ALERT -1
@ -152,6 +188,10 @@
# define SSL_AESGCM (SSL_AES128GCM | SSL_AES256GCM)
# define SSL_AESCCM (SSL_AES128CCM | SSL_AES256CCM | SSL_AES128CCM8 | SSL_AES256CCM8)
# define SSL_AES (SSL_AES128|SSL_AES256|SSL_AESGCM|SSL_AESCCM)
# define SSL_AES128_ANY (SSL_AES128 | SSL_AES128CCM | SSL_AES128CCM8 \
| SSL_AES128GCM)
# define SSL_AES256_ANY (SSL_AES256 | SSL_AES256CCM | SSL_AES256CCM8 \
| SSL_AES256GCM)
# define SSL_CAMELLIA (SSL_CAMELLIA128|SSL_CAMELLIA256)
# define SSL_CHACHA20 (SSL_CHACHA20POLY1305)
# define SSL_ARIAGCM (SSL_ARIA128GCM | SSL_ARIA256GCM)
@ -254,13 +294,27 @@
# define SSL_CONNECTION_IS_DTLS(s) \
(SSL_CONNECTION_GET_SSL(s)->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_DTLS)
/* Check if an SSL structure is using DTLS */
# define SSL_CONNECTION_MIDDLEBOX_IS_ENABLED(s) \
((s->options & SSL_OP_ENABLE_MIDDLEBOX_COMPAT) != 0 \
&& !SSL_CONNECTION_IS_DTLS(s))
/* Check if we are using DTLSv1.3 */
# define SSL_CONNECTION_IS_DTLS13(s) (SSL_CONNECTION_IS_DTLS(s) \
&& DTLS_VERSION_GE(SSL_CONNECTION_GET_SSL(s)->method->version, DTLS1_3_VERSION) \
&& SSL_CONNECTION_GET_SSL(s)->method->version != DTLS_ANY_VERSION)
/* Check if we are using TLSv1.3 */
# define SSL_CONNECTION_IS_TLS13(s) (!SSL_CONNECTION_IS_DTLS(s) \
&& SSL_CONNECTION_GET_SSL(s)->method->version >= TLS1_3_VERSION \
&& SSL_CONNECTION_GET_SSL(s)->method->version != TLS_ANY_VERSION)
/* Check if we are using (D)TLSv1.3 */
# define SSL_CONNECTION_IS_VERSION13(s) \
(SSL_CONNECTION_IS_DTLS13(s) || SSL_CONNECTION_IS_TLS13(s))
# define SSL_CONNECTION_TREAT_AS_TLS13(s) \
(SSL_CONNECTION_IS_TLS13(s) \
(SSL_CONNECTION_IS_VERSION13(s) \
|| (s)->early_data_state == SSL_EARLY_DATA_CONNECTING \
|| (s)->early_data_state == SSL_EARLY_DATA_CONNECT_RETRY \
|| (s)->early_data_state == SSL_EARLY_DATA_WRITING \
@ -1186,6 +1240,9 @@ struct ssl_ctx_st {
# endif
};
# define SSL_CTX_IS_DTLS(ctx) \
(((ctx)->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_DTLS) != 0)
typedef struct cert_pkey_st CERT_PKEY;
#define SSL_TYPE_SSL_CONNECTION 0
@ -1214,10 +1271,18 @@ struct ssl_connection_st {
SSL *user_ssl;
/*
* protocol version (one of SSL2_VERSION, SSL3_VERSION, TLS1_VERSION,
* DTLS1_VERSION)
* protocol version (one of SSL3_VERSION, TLS1_VERSION, TLS1_1_VERSION,
* TLS1_2_VERSION, TLS1_3_VERSION, DTLS1_VERSION, DTLS1_2_VERSION,
* DTLS1_3_VERSION)
*/
int version;
/*
* The negotiated version for the connection. Initially PROTO_VERSION_UNSET.
* Set by ssl_set_negotiated_protocol_version().
*/
int negotiated_version;
/*
* There are 2 BIO's even though they are normally both the same. This
* is so data can be read and written to different handlers
@ -1325,6 +1390,8 @@ struct ssl_connection_st {
size_t key_block_length;
unsigned char *key_block;
const EVP_CIPHER *new_sym_enc;
const EVP_CIPHER *new_sym_enc_sn;
size_t new_sym_enc_sn_offs;
const EVP_MD *new_hash;
int new_mac_pkey_type;
size_t new_mac_secret_size;
@ -1866,6 +1933,12 @@ typedef struct sigalg_lookup_st {
int enabled;
} SIGALG_LOOKUP;
typedef enum downgrade_en {
DOWNGRADE_NONE,
DOWNGRADE_TO_1_2,
DOWNGRADE_TO_1_1
} DOWNGRADE;
/* DTLS structures */
# ifndef OPENSSL_NO_SCTP
@ -1886,8 +1959,6 @@ struct hm_header_st {
unsigned short seq;
size_t frag_off;
size_t frag_len;
unsigned int is_ccs;
struct dtls1_retransmit_state saved_retransmit_state;
};
typedef struct hm_fragment_st {
@ -1899,6 +1970,11 @@ typedef struct hm_fragment_st {
typedef struct pqueue_st pqueue;
typedef struct pitem_st pitem;
struct pqueue_st {
pitem *items;
int count;
};
struct pitem_st {
unsigned char priority[8]; /* 64-bit value in big-endian encoding */
void *data;
@ -1919,6 +1995,19 @@ pitem *pqueue_iterator(pqueue *pq);
pitem *pqueue_next(piterator *iter);
size_t pqueue_size(pqueue *pq);
typedef struct dtls_msg_info_st {
unsigned char msg_type;
size_t msg_body_len;
unsigned short msg_seq;
} dtls_msg_info;
typedef struct dtls_sent_msg_st {
dtls_msg_info msg_info;
int record_type;
unsigned char *msg_buf;
struct dtls1_retransmit_state saved_retransmit_state;
} dtls_sent_msg;
typedef struct dtls1_state_st {
unsigned char cookie[DTLS1_COOKIE_LENGTH];
size_t cookie_len;
@ -1927,14 +2016,17 @@ typedef struct dtls1_state_st {
unsigned short handshake_write_seq;
unsigned short next_handshake_write_seq;
unsigned short handshake_read_seq;
/* Buffered handshake messages */
pqueue *buffered_messages;
/* Buffered received handshake messages */
pqueue rcvd_messages;
/* Buffered (sent) handshake records */
pqueue *sent_messages;
pqueue sent_messages;
/* Flag to indicate current HelloVerifyRequest status */
enum {SSL_HVR_NONE = 0, SSL_HVR_RECEIVED, SSL_HVR_SENT} hello_verify_request;
DOWNGRADE downgrade_after_hvr; /* Only used by a stateful server */
size_t link_mtu; /* max on-the-wire DTLS packet size */
size_t mtu; /* max DTLS packet size */
struct hm_header_st w_msg_hdr;
struct hm_header_st r_msg_hdr;
dtls_msg_info w_msg;
unsigned short r_msg_seq;
/* Number of alerts received so far */
unsigned int timeout_num_alerts;
/*
@ -2159,12 +2251,6 @@ typedef struct ssl3_enc_method {
*/
# define SSL_ENC_FLAG_TLS1_2_CIPHERS 0x10
typedef enum downgrade_en {
DOWNGRADE_NONE,
DOWNGRADE_TO_1_2,
DOWNGRADE_TO_1_1
} DOWNGRADE;
/*
* Dummy status type for the status_type extension. Indicates no status type
* set
@ -2281,6 +2367,9 @@ __owur const SSL_METHOD *dtls_bad_ver_client_method(void);
__owur const SSL_METHOD *dtlsv1_2_method(void);
__owur const SSL_METHOD *dtlsv1_2_server_method(void);
__owur const SSL_METHOD *dtlsv1_2_client_method(void);
__owur const SSL_METHOD *dtlsv1_3_method(void);
__owur const SSL_METHOD *dtlsv1_3_server_method(void);
__owur const SSL_METHOD *dtlsv1_3_client_method(void);
extern const SSL3_ENC_METHOD TLSv1_enc_data;
extern const SSL3_ENC_METHOD TLSv1_1_enc_data;
@ -2289,6 +2378,7 @@ extern const SSL3_ENC_METHOD TLSv1_3_enc_data;
extern const SSL3_ENC_METHOD SSLv3_enc_data;
extern const SSL3_ENC_METHOD DTLSv1_enc_data;
extern const SSL3_ENC_METHOD DTLSv1_2_enc_data;
extern const SSL3_ENC_METHOD DTLSv1_3_enc_data;
/*
* Flags for SSL methods
@ -2521,11 +2611,15 @@ __owur int ossl_bytes_to_cipher_list(SSL_CONNECTION *s, PACKET *cipher_suites,
void ssl_update_cache(SSL_CONNECTION *s, int mode);
__owur int ssl_cipher_get_evp_cipher(SSL_CTX *ctx, const SSL_CIPHER *sslc,
const EVP_CIPHER **enc);
__owur int ssl_cipher_get_evp_cipher_sn(SSL_CTX *ctx, const SSL_CIPHER *sslc,
const EVP_CIPHER **enc, size_t *inputoffs);
__owur int ssl_cipher_get_evp_md_mac(SSL_CTX *ctx, const SSL_CIPHER *sslc,
const EVP_MD **md,
int *mac_pkey_type, size_t *mac_secret_size);
__owur int ssl_cipher_get_evp(SSL_CTX *ctxc, const SSL_SESSION *s,
const EVP_CIPHER **enc, const EVP_MD **md,
__owur int ssl_cipher_get_evp(SSL_CTX *ctx, const SSL_SESSION *s,
const EVP_CIPHER **snenc, size_t *snencoffs,
const EVP_CIPHER **enc,
const EVP_MD **md,
int *mac_pkey_type, size_t *mac_secret_size,
SSL_COMP **comp, int use_etm);
__owur int ssl_cipher_get_overhead(const SSL_CIPHER *c, size_t *mac_overhead,
@ -2671,25 +2765,19 @@ __owur int ssl_get_min_max_version(const SSL_CONNECTION *s, int *min_version,
int *max_version, int *real_max);
__owur OSSL_TIME tls1_default_timeout(void);
__owur int dtls1_do_write(SSL_CONNECTION *s, uint8_t type);
void dtls1_set_message_header(SSL_CONNECTION *s,
unsigned char mt,
size_t len,
size_t frag_off, size_t frag_len);
__owur int dtls1_do_write(SSL_CONNECTION *s, uint8_t recordtype);
int dtls1_write_app_data_bytes(SSL *s, uint8_t type, const void *buf_,
size_t len, size_t *written);
__owur int dtls1_read_failed(SSL_CONNECTION *s, int code);
__owur int dtls1_buffer_message(SSL_CONNECTION *s, int ccs);
__owur int dtls1_buffer_sent_message(SSL_CONNECTION *s, int record_type);
__owur int dtls1_retransmit_message(SSL_CONNECTION *s, unsigned short seq,
int *found);
__owur int dtls1_get_queue_priority(unsigned short seq, int is_ccs);
int dtls1_retransmit_buffered_messages(SSL_CONNECTION *s);
int dtls1_retransmit_sent_messages(SSL_CONNECTION *s);
void dtls1_clear_received_buffer(SSL_CONNECTION *s);
void dtls1_clear_sent_buffer(SSL_CONNECTION *s);
void dtls1_get_message_header(const unsigned char *data,
struct hm_header_st *msg_hdr);
__owur OSSL_TIME dtls1_default_timeout(void);
__owur int dtls1_get_timeout(const SSL_CONNECTION *s, OSSL_TIME *timeleft);
__owur int dtls1_check_timeout_num(SSL_CONNECTION *s);
@ -2701,6 +2789,7 @@ __owur int dtls_raw_hello_verify_request(WPACKET *pkt, unsigned char *cookie,
size_t cookie_len);
__owur size_t dtls1_min_mtu(SSL_CONNECTION *s);
void dtls1_hm_fragment_free(hm_fragment *frag);
void dtls1_sent_msg_free(dtls_sent_msg *msg);
__owur int dtls1_query_mtu(SSL_CONNECTION *s);
__owur int tls1_new(SSL *s);

View file

@ -362,6 +362,7 @@ int ssl_generate_session_id(SSL_CONNECTION *s, SSL_SESSION *ss)
case DTLS1_BAD_VER:
case DTLS1_VERSION:
case DTLS1_2_VERSION:
case DTLS1_3_VERSION:
ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH;
break;
default:
@ -456,7 +457,7 @@ int ssl_get_new_session(SSL_CONNECTION *s, int session)
s->session = NULL;
if (session) {
if (SSL_CONNECTION_IS_TLS13(s)) {
if (SSL_CONNECTION_IS_VERSION13(s)) {
/*
* We generate the session id while constructing the
* NewSessionTicket in TLSv1.3.
@ -590,7 +591,7 @@ int ssl_get_prev_session(SSL_CONNECTION *s, CLIENTHELLO_MSG *hello)
int try_session_cache = 0;
SSL_TICKET_STATUS r;
if (SSL_CONNECTION_IS_TLS13(s)) {
if (SSL_CONNECTION_IS_VERSION13(s)) {
/*
* By default we will send a new ticket. This can be overridden in the
* ticket processing.
@ -685,8 +686,8 @@ int ssl_get_prev_session(SSL_CONNECTION *s, CLIENTHELLO_MSG *hello)
goto err;
}
if (!SSL_CONNECTION_IS_TLS13(s)) {
/* We already did this for TLS1.3 */
if (!SSL_CONNECTION_IS_VERSION13(s)) {
/* We already did this for (D)TLS1.3 */
SSL_SESSION_free(s->session);
s->session = ret;
}
@ -698,8 +699,8 @@ int ssl_get_prev_session(SSL_CONNECTION *s, CLIENTHELLO_MSG *hello)
err:
if (ret != NULL) {
SSL_SESSION_free(ret);
/* In TLSv1.3 s->session was already set to ret, so we NULL it out */
if (SSL_CONNECTION_IS_TLS13(s))
/* In (D)TLSv1.3 s->session was already set to ret, so we NULL it out */
if (SSL_CONNECTION_IS_VERSION13(s))
s->session = NULL;
if (!try_session_cache) {

View file

@ -35,11 +35,12 @@ int SSL_SESSION_print(BIO *bp, const SSL_SESSION *x)
{
size_t i;
const char *s;
int istls13;
int isversion13;
if (x == NULL)
goto err;
istls13 = (x->ssl_version == TLS1_3_VERSION);
isversion13 = (x->ssl_version == TLS1_3_VERSION)
|| (x->ssl_version == DTLS1_3_VERSION);
if (BIO_puts(bp, "SSL-Session:\n") <= 0)
goto err;
s = ssl_protocol_to_string(x->ssl_version);
@ -74,7 +75,7 @@ int SSL_SESSION_print(BIO *bp, const SSL_SESSION *x)
if (BIO_printf(bp, "%02X", x->sid_ctx[i]) <= 0)
goto err;
}
if (istls13) {
if (isversion13) {
if (BIO_puts(bp, "\n Resumption PSK: ") <= 0)
goto err;
} else if (BIO_puts(bp, "\n Master-Key: ") <= 0)
@ -118,7 +119,7 @@ int SSL_SESSION_print(BIO *bp, const SSL_SESSION *x)
if (x->compress_meth != 0) {
SSL_COMP *comp = NULL;
if (!ssl_cipher_get_evp(NULL, x, NULL, NULL, NULL, NULL, &comp, 0))
if (!ssl_cipher_get_evp(NULL, x, NULL, NULL, NULL, NULL, NULL, NULL, &comp, 0))
goto err;
if (comp == NULL) {
if (BIO_printf(bp, "\n Compression: %d", x->compress_meth) <= 0)
@ -153,7 +154,7 @@ int SSL_SESSION_print(BIO *bp, const SSL_SESSION *x)
x->flags & SSL_SESS_FLAG_EXTMS ? "yes" : "no") <= 0)
goto err;
if (istls13) {
if (isversion13) {
if (BIO_printf(bp, " Max Early Data: %u\n",
(unsigned int)x->ext.max_early_data) <= 0)
goto err;

View file

@ -190,7 +190,7 @@ static const EXTENSION_DEFINITION ext_defs[] = {
* to indicate to the client the complete list of groups supported
* by the server, with the server instead just indicating the
* selected group for this connection in the ServerKeyExchange
* message. TLS 1.3 adds a scheme for the server to indicate
* message. (D)TLS 1.3 adds a scheme for the server to indicate
* to the client its list of supported groups in the
* EncryptedExtensions message, but none of the relevant
* specifications permit sending supported_groups in the ServerHello.
@ -200,7 +200,7 @@ static const EXTENSION_DEFINITION ext_defs[] = {
* ServerHello anyway. Up to and including the 1.1.0 release,
* we did not check for the presence of nonpermitted extensions,
* so to avoid a regression, we must permit this extension in the
* TLS 1.2 ServerHello as well.
* (D)TLS 1.2 ServerHello as well.
*
* Note that there is no tls_parse_stoc_supported_groups function,
* so we do not perform any additional parsing, validation, or
@ -341,7 +341,7 @@ static const EXTENSION_DEFINITION ext_defs[] = {
{
TLSEXT_TYPE_supported_versions,
SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS1_3_SERVER_HELLO
| SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST | SSL_EXT_TLS_IMPLEMENTATION_ONLY,
| SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST,
NULL,
/* Processed inline as part of version selection */
NULL, tls_parse_stoc_supported_versions,
@ -350,8 +350,7 @@ static const EXTENSION_DEFINITION ext_defs[] = {
},
{
TLSEXT_TYPE_psk_kex_modes,
SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS_IMPLEMENTATION_ONLY
| SSL_EXT_TLS1_3_ONLY,
SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS1_3_ONLY,
init_psk_kex_modes, tls_parse_ctos_psk_kex_modes, NULL, NULL,
tls_construct_ctos_psk_kex_modes, NULL
},
@ -362,7 +361,7 @@ static const EXTENSION_DEFINITION ext_defs[] = {
*/
TLSEXT_TYPE_key_share,
SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS1_3_SERVER_HELLO
| SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST | SSL_EXT_TLS_IMPLEMENTATION_ONLY
| SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST
| SSL_EXT_TLS1_3_ONLY,
NULL, tls_parse_ctos_key_share, tls_parse_stoc_key_share,
tls_construct_stoc_key_share, tls_construct_ctos_key_share,
@ -372,7 +371,7 @@ static const EXTENSION_DEFINITION ext_defs[] = {
/* Must be after key_share */
TLSEXT_TYPE_cookie,
SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST
| SSL_EXT_TLS_IMPLEMENTATION_ONLY | SSL_EXT_TLS1_3_ONLY,
| SSL_EXT_TLS1_3_ONLY,
NULL, tls_parse_ctos_cookie, tls_parse_stoc_cookie,
tls_construct_stoc_cookie, tls_construct_ctos_cookie, NULL
},
@ -390,7 +389,7 @@ static const EXTENSION_DEFINITION ext_defs[] = {
{
TLSEXT_TYPE_compress_certificate,
SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS1_3_CERTIFICATE_REQUEST
| SSL_EXT_TLS_IMPLEMENTATION_ONLY | SSL_EXT_TLS1_3_ONLY,
| SSL_EXT_TLS1_3_ONLY,
tls_init_compress_certificate,
tls_parse_compress_certificate, tls_parse_compress_certificate,
tls_construct_compress_certificate, tls_construct_compress_certificate,
@ -422,10 +421,10 @@ static const EXTENSION_DEFINITION ext_defs[] = {
NULL, NULL, NULL, tls_construct_ctos_padding, NULL
},
{
/* Required by the TLSv1.3 spec to always be the last extension */
/* Required by the (D)TLSv1.3 spec to always be the last extension */
TLSEXT_TYPE_psk,
SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS1_3_SERVER_HELLO
| SSL_EXT_TLS_IMPLEMENTATION_ONLY | SSL_EXT_TLS1_3_ONLY,
| SSL_EXT_TLS1_3_ONLY,
NULL, tls_parse_ctos_psk, tls_parse_stoc_psk, tls_construct_stoc_psk,
tls_construct_ctos_psk, final_psk
}
@ -556,33 +555,33 @@ static int verify_extension(SSL_CONNECTION *s, unsigned int context,
int extension_is_relevant(SSL_CONNECTION *s, unsigned int extctx,
unsigned int thisctx)
{
int is_tls13;
int is_version13;
/*
* For HRR we haven't selected the version yet but we know it will be
* TLSv1.3
* (D)TLSv1.3
*/
if ((thisctx & SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST) != 0)
is_tls13 = 1;
is_version13 = 1;
else
is_tls13 = SSL_CONNECTION_IS_TLS13(s);
is_version13 = SSL_CONNECTION_IS_VERSION13(s);
if ((SSL_CONNECTION_IS_DTLS(s)
&& (extctx & SSL_EXT_TLS_IMPLEMENTATION_ONLY) != 0)
|| (s->version == SSL3_VERSION
&& (extctx & SSL_EXT_SSL3_ALLOWED) == 0)
/*
* Note that SSL_IS_TLS13() means "TLS 1.3 has been negotiated",
* Note that is_version13 means "(D)TLS 1.3 has been negotiated",
* which is never true when generating the ClientHello.
* However, version negotiation *has* occurred by the time the
* ClientHello extensions are being parsed.
* Be careful to allow TLS 1.3-only extensions when generating
* Be careful to allow (D)TLS 1.3-only extensions when generating
* the ClientHello.
*/
|| (is_tls13 && (extctx & SSL_EXT_TLS1_2_AND_BELOW_ONLY) != 0)
|| (!is_tls13 && (extctx & SSL_EXT_TLS1_3_ONLY) != 0
|| (is_version13 && (extctx & SSL_EXT_TLS1_2_AND_BELOW_ONLY) != 0)
|| (!is_version13 && (extctx & SSL_EXT_TLS1_3_ONLY) != 0
&& (thisctx & SSL_EXT_CLIENT_HELLO) == 0)
|| (s->server && !is_tls13 && (extctx & SSL_EXT_TLS1_3_ONLY) != 0)
|| (s->server && !is_version13 && (extctx & SSL_EXT_TLS1_3_ONLY) != 0)
|| (s->hit && (extctx & SSL_EXT_IGNORE_ON_RESUMPTION) != 0))
return 0;
return 1;
@ -825,6 +824,8 @@ int tls_parse_all_extensions(SSL_CONNECTION *s, int context,
int should_add_extension(SSL_CONNECTION *s, unsigned int extctx,
unsigned int thisctx, int max_version)
{
const int version1_3 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION : TLS1_3_VERSION;
/* Skip if not relevant for our context */
if ((extctx & thisctx) == 0)
return 0;
@ -833,7 +834,7 @@ int should_add_extension(SSL_CONNECTION *s, unsigned int extctx,
if (!extension_is_relevant(s, extctx, thisctx)
|| ((extctx & SSL_EXT_TLS1_3_ONLY) != 0
&& (thisctx & SSL_EXT_CLIENT_HELLO) != 0
&& (SSL_CONNECTION_IS_DTLS(s) || max_version < TLS1_3_VERSION)))
&& ssl_version_cmp(s, max_version, version1_3) < 0))
return 0;
return 1;
@ -860,7 +861,7 @@ int tls_construct_extensions(SSL_CONNECTION *s, WPACKET *pkt,
/*
* If extensions are of zero length then we don't even add the
* extensions length bytes to a ClientHello/ServerHello
* (for non-TLSv1.3).
* (for non-(D)TLSv1.3).
*/
|| ((context &
(SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS1_2_SERVER_HELLO)) != 0
@ -1072,8 +1073,8 @@ static int final_server_name(SSL_CONNECTION *s, unsigned int context, int sent)
return 0;
case SSL_TLSEXT_ERR_ALERT_WARNING:
/* TLSv1.3 doesn't have warning alerts so we suppress this */
if (!SSL_CONNECTION_IS_TLS13(s))
/* (D)TLSv1.3 doesn't have warning alerts so we suppress this */
if (!SSL_CONNECTION_IS_VERSION13(s))
ssl3_send_alert(s, SSL3_AL_WARNING, altmp);
s->servername_done = 0;
return 1;
@ -1180,15 +1181,15 @@ static int final_alpn(SSL_CONNECTION *s, unsigned int context, int sent)
if (!s->server && !sent && s->session->ext.alpn_selected != NULL)
s->ext.early_data_ok = 0;
if (!s->server || !SSL_CONNECTION_IS_TLS13(s))
if (!s->server || !SSL_CONNECTION_IS_VERSION13(s))
return 1;
/*
* Call alpn_select callback if needed. Has to be done after SNI and
* cipher negotiation (HTTP/2 restricts permitted ciphers). In TLSv1.3
* cipher negotiation (HTTP/2 restricts permitted ciphers). In (D)TLSv1.3
* we also have to do this before we decide whether to accept early_data.
* In TLSv1.3 we've already negotiated our cipher so we do this call now.
* For < TLSv1.3 we defer it until after cipher negotiation.
* In (D)TLSv1.3 we've already negotiated our cipher so we do this call now.
* For < (D)TLSv1.3 we defer it until after cipher negotiation.
*
* On failure SSLfatal() already called.
*/
@ -1340,7 +1341,7 @@ static int init_srtp(SSL_CONNECTION *s, unsigned int context)
static int final_sig_algs(SSL_CONNECTION *s, unsigned int context, int sent)
{
if (!sent && SSL_CONNECTION_IS_TLS13(s) && !s->hit) {
if (!sent && SSL_CONNECTION_IS_VERSION13(s) && !s->hit) {
SSLfatal(s, TLS13_AD_MISSING_EXTENSION,
SSL_R_MISSING_SIGALGS_EXTENSION);
return 0;
@ -1363,8 +1364,8 @@ static int final_supported_versions(SSL_CONNECTION *s, unsigned int context,
static int final_key_share(SSL_CONNECTION *s, unsigned int context, int sent)
{
#if !defined(OPENSSL_NO_TLS1_3)
if (!SSL_CONNECTION_IS_TLS13(s))
#if !(defined(OPENSSL_NO_TLS1_3) && defined(OPENSSL_NO_DTLS1_3))
if (!SSL_CONNECTION_IS_VERSION13(s))
return 1;
/* Nothing to do for key_share in an HRR */
@ -1464,14 +1465,17 @@ static int final_key_share(SSL_CONNECTION *s, unsigned int context, int sent)
* Find the first group we allow that is also in client's list
*/
for (i = 0; i < num_groups; i++) {
const int version1_3 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION
: TLS1_3_VERSION;
group_id = pgroups[i];
if (check_in_list(s, group_id, clntgroups, clnt_num_groups,
1)
&& tls_group_allowed(s, group_id,
SSL_SECOP_CURVE_SUPPORTED)
&& tls_valid_group(s, group_id, TLS1_3_VERSION,
TLS1_3_VERSION, 0, NULL))
&& tls_valid_group(s, group_id, version1_3,
version1_3, 0, NULL))
break;
}
@ -1524,7 +1528,7 @@ static int final_key_share(SSL_CONNECTION *s, unsigned int context, int sent)
return 0;
}
}
#endif /* !defined(OPENSSL_NO_TLS1_3) */
#endif /* !defined(OPENSSL_NO_TLS1_3) && !defined(OPENSSL_NO_DTLS1_3) */
return 1;
}
@ -1549,8 +1553,8 @@ int tls_psk_do_binder(SSL_CONNECTION *s, const EVP_MD *md,
static const unsigned char resumption_label[] = "\x72\x65\x73\x20\x62\x69\x6E\x64\x65\x72";
/* ASCII: "ext binder", in hex for EBCDIC compatibility */
static const unsigned char external_label[] = "\x65\x78\x74\x20\x62\x69\x6E\x64\x65\x72";
const unsigned char *label;
size_t bindersize, labelsize, hashsize;
const unsigned char *label, *msgbodystart;
size_t bindersize, labelsize, hashsize, msgbodylen;
int hashsizei = EVP_MD_get_size(md);
int ret = -1;
int usepskfored = 0;
@ -1668,7 +1672,23 @@ int tls_psk_do_binder(SSL_CONNECTION *s, const EVP_MD *md,
}
}
if (EVP_DigestUpdate(mctx, msgstart, binderoffset) <= 0
if (SSL_CONNECTION_IS_DTLS(s)) {
msgbodystart = msgstart + DTLS1_HM_HEADER_LENGTH;
msgbodylen = binderoffset - DTLS1_HM_HEADER_LENGTH;
} else {
msgbodystart = msgstart + SSL3_HM_HEADER_LENGTH;
msgbodylen = binderoffset - SSL3_HM_HEADER_LENGTH;
}
/*
* RFC9147 (DTLSv1.3)
* The transcript consists of complete TLS Handshake messages
* (reassembled as necessary). Note that this requires removing the
* message_seq, fragment_offset, and fragment_length fields to create
* the Handshake structure.
*/
if (EVP_DigestUpdate(mctx, msgstart, SSL3_HM_HEADER_LENGTH) <= 0
|| EVP_DigestUpdate(mctx, msgbodystart, msgbodylen) <= 0
|| EVP_DigestFinal_ex(mctx, hash, NULL) <= 0) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
goto err;

View file

@ -17,16 +17,15 @@ EXT_RETURN tls_construct_ctos_renegotiate(SSL_CONNECTION *s, WPACKET *pkt,
size_t chainidx)
{
if (!s->renegotiate) {
const int version1_3 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION
: TLS1_3_VERSION;
/* If not renegotiating, send an empty RI extension to indicate support */
#if DTLS_MAX_VERSION_INTERNAL != DTLS1_2_VERSION
# error Internal DTLS version error
#endif
if (!SSL_CONNECTION_IS_DTLS(s)
&& (s->min_proto_version >= TLS1_3_VERSION
|| (ssl_security(s, SSL_SECOP_VERSION, 0, TLS1_VERSION, NULL)
&& s->min_proto_version <= TLS1_VERSION))) {
if ((s->min_proto_version != 0
&& ssl_version_cmp(s, s->min_proto_version, version1_3) >= 0)
|| (!SSL_CONNECTION_IS_DTLS(s)
&& ssl_security(s, SSL_SECOP_VERSION, 0, TLS1_VERSION, NULL)
&& s->min_proto_version <= TLS1_VERSION)) {
/*
* For TLS <= 1.0 SCSV is used instead, and for TLS 1.3 this
* extension isn't used at all.
@ -144,6 +143,7 @@ static int use_ecc(SSL_CONNECTION *s, int min_version, int max_version)
const uint16_t *pgroups = NULL;
size_t num_groups, j;
SSL *ssl = SSL_CONNECTION_GET_SSL(s);
const int version1_3 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION : TLS1_3_VERSION;
/* See if we support any ECC ciphersuites */
if (s->version == SSL3_VERSION)
@ -153,12 +153,14 @@ static int use_ecc(SSL_CONNECTION *s, int min_version, int max_version)
end = sk_SSL_CIPHER_num(cipher_stack);
for (i = 0; i < end; i++) {
const SSL_CIPHER *c = sk_SSL_CIPHER_value(cipher_stack, i);
const int cipher_minversion = SSL_CONNECTION_IS_DTLS(s) ? c->min_dtls
: c->min_tls;
alg_k = c->algorithm_mkey;
alg_a = c->algorithm_auth;
if ((alg_k & (SSL_kECDHE | SSL_kECDHEPSK))
|| (alg_a & SSL_aECDSA)
|| c->min_tls >= TLS1_3_VERSION) {
|| ssl_version_cmp(s, cipher_minversion, version1_3) >= 0) {
ret = 1;
break;
}
@ -218,6 +220,7 @@ EXT_RETURN tls_construct_ctos_supported_groups(SSL_CONNECTION *s, WPACKET *pkt,
const uint16_t *pgroups = NULL;
size_t num_groups = 0, i, tls13added = 0, added = 0;
int min_version, max_version, reason;
const int version1_3 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION : TLS1_3_VERSION;
reason = ssl_get_min_max_version(s, &min_version, &max_version, NULL);
if (reason != 0) {
@ -226,11 +229,11 @@ EXT_RETURN tls_construct_ctos_supported_groups(SSL_CONNECTION *s, WPACKET *pkt,
}
/*
* We only support EC groups in TLSv1.2 or below, and in DTLS. Therefore
* We only support EC groups in (D)TLSv1.2 or below, and in DTLS. Therefore
* if we don't have EC support then we don't send this extension.
*/
if (!use_ecc(s, min_version, max_version)
&& (SSL_CONNECTION_IS_DTLS(s) || max_version < TLS1_3_VERSION))
if (!use_ecc(s, min_version, max_version))
if (ssl_version_cmp(s, max_version, version1_3) < 0)
return EXT_RETURN_NOT_SENT;
/*
@ -257,7 +260,7 @@ EXT_RETURN tls_construct_ctos_supported_groups(SSL_CONNECTION *s, WPACKET *pkt,
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return EXT_RETURN_FAIL;
}
if (okfortls13 && max_version == TLS1_3_VERSION)
if (okfortls13 && max_version == version1_3)
tls13added++;
added++;
}
@ -271,7 +274,7 @@ EXT_RETURN tls_construct_ctos_supported_groups(SSL_CONNECTION *s, WPACKET *pkt,
return EXT_RETURN_FAIL;
}
if (tls13added == 0 && max_version == TLS1_3_VERSION) {
if (tls13added == 0 && max_version == version1_3) {
SSLfatal_data(s, SSL_AD_INTERNAL_ERROR, SSL_R_NO_SUITABLE_GROUPS,
"No groups enabled for max supported SSL/TLS version");
return EXT_RETURN_FAIL;
@ -285,13 +288,14 @@ EXT_RETURN tls_construct_ctos_session_ticket(SSL_CONNECTION *s, WPACKET *pkt,
size_t chainidx)
{
size_t ticklen;
const int version1_3 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION : TLS1_3_VERSION;
if (!tls_use_ticket(s))
return EXT_RETURN_NOT_SENT;
if (!s->new_session && s->session != NULL
&& s->session->ext.tick != NULL
&& s->session->ssl_version != TLS1_3_VERSION) {
&& s->session->ssl_version != version1_3) {
ticklen = s->session->ext.ticklen;
} else if (s->session && s->ext.session_ticket != NULL
&& s->ext.session_ticket->data != NULL) {
@ -561,6 +565,8 @@ EXT_RETURN tls_construct_ctos_supported_versions(SSL_CONNECTION *s, WPACKET *pkt
size_t chainidx)
{
int currv, min_version, max_version, reason;
const int isdtls = SSL_CONNECTION_IS_DTLS(s);
const int version1_3 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION : TLS1_3_VERSION;
reason = ssl_get_min_max_version(s, &min_version, &max_version, NULL);
if (reason != 0) {
@ -569,10 +575,9 @@ EXT_RETURN tls_construct_ctos_supported_versions(SSL_CONNECTION *s, WPACKET *pkt
}
/*
* Don't include this if we can't negotiate TLSv1.3. We can do a straight
* comparison here because we will never be called in DTLS.
* Don't include this if we can't negotiate (D)TLSv1.3.
*/
if (max_version < TLS1_3_VERSION)
if (ssl_version_cmp(s, max_version, version1_3) < 0)
return EXT_RETURN_NOT_SENT;
if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_supported_versions)
@ -582,7 +587,8 @@ EXT_RETURN tls_construct_ctos_supported_versions(SSL_CONNECTION *s, WPACKET *pkt
return EXT_RETURN_FAIL;
}
for (currv = max_version; currv >= min_version; currv--) {
for (currv = max_version; ssl_version_cmp(s, currv, min_version) >= 0;
isdtls ? currv++ : currv--) {
if (!WPACKET_put_bytes_u16(pkt, currv)) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return EXT_RETURN_FAIL;
@ -603,7 +609,7 @@ EXT_RETURN tls_construct_ctos_psk_kex_modes(SSL_CONNECTION *s, WPACKET *pkt,
unsigned int context, X509 *x,
size_t chainidx)
{
#ifndef OPENSSL_NO_TLS1_3
#if !(defined(OPENSSL_NO_TLS1_3) && defined(OPENSSL_NO_DTLS1_3))
int nodhe = s->options & SSL_OP_ALLOW_NO_DHE_KEX;
if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_psk_kex_modes)
@ -625,7 +631,7 @@ EXT_RETURN tls_construct_ctos_psk_kex_modes(SSL_CONNECTION *s, WPACKET *pkt,
return EXT_RETURN_SENT;
}
#ifndef OPENSSL_NO_TLS1_3
#if !(defined(OPENSSL_NO_TLS1_3) && defined(OPENSSL_NO_DTLS1_3))
static int add_key_share(SSL_CONNECTION *s, WPACKET *pkt, unsigned int curve_id)
{
unsigned char *encoded_point = NULL;
@ -633,12 +639,14 @@ static int add_key_share(SSL_CONNECTION *s, WPACKET *pkt, unsigned int curve_id)
size_t encodedlen;
if (s->s3.tmp.pkey != NULL) {
if (!ossl_assert(s->hello_retry_request == SSL_HRR_PENDING)) {
if (!ossl_assert(s->hello_retry_request == SSL_HRR_PENDING
|| s->d1->hello_verify_request == SSL_HVR_RECEIVED)) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return 0;
}
/*
* Could happen if we got an HRR that wasn't requesting a new key_share
* Could happen if we got a HRR that wasn't requesting a new key_share
* or if we got a HelloVerifyRequest
*/
key_share_key = s->s3.tmp.pkey;
} else {
@ -686,7 +694,7 @@ EXT_RETURN tls_construct_ctos_key_share(SSL_CONNECTION *s, WPACKET *pkt,
unsigned int context, X509 *x,
size_t chainidx)
{
#ifndef OPENSSL_NO_TLS1_3
#if !(defined(OPENSSL_NO_TLS1_3) && defined(OPENSSL_NO_DTLS1_3))
size_t i, num_groups = 0;
const uint16_t *pgroups = NULL;
uint16_t curve_id = 0;
@ -711,10 +719,13 @@ EXT_RETURN tls_construct_ctos_key_share(SSL_CONNECTION *s, WPACKET *pkt,
curve_id = s->s3.group_id;
} else {
for (i = 0; i < num_groups; i++) {
const int version1_3 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION
: TLS1_3_VERSION;
if (!tls_group_allowed(s, pgroups[i], SSL_SECOP_CURVE_SUPPORTED))
continue;
if (!tls_valid_group(s, pgroups[i], TLS1_3_VERSION, TLS1_3_VERSION,
if (!tls_valid_group(s, pgroups[i], version1_3, version1_3,
0, NULL))
continue;
@ -785,14 +796,14 @@ EXT_RETURN tls_construct_ctos_early_data(SSL_CONNECTION *s, WPACKET *pkt,
SSL_SESSION *edsess = NULL;
const EVP_MD *handmd = NULL;
SSL *ussl = SSL_CONNECTION_GET_USER_SSL(s);
const int version1_3 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION : TLS1_3_VERSION;
if (s->hello_retry_request == SSL_HRR_PENDING)
handmd = ssl_handshake_md(s);
if (s->psk_use_session_cb != NULL
&& (!s->psk_use_session_cb(ussl, handmd, &id, &idlen, &psksess)
|| (psksess != NULL
&& psksess->ssl_version != TLS1_3_VERSION))) {
|| (psksess != NULL && psksess->ssl_version != version1_3))) {
SSL_SESSION_free(psksess);
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_BAD_PSK);
return EXT_RETURN_FAIL;
@ -824,7 +835,7 @@ EXT_RETURN tls_construct_ctos_early_data(SSL_CONNECTION *s, WPACKET *pkt,
/*
* We found a PSK using an old style callback. We don't know
* the digest so we default to SHA256 as per the TLSv1.3 spec
* the digest so we default to SHA256 as per the (D)TLSv1.3 spec
*/
cipher = SSL_CIPHER_find(SSL_CONNECTION_GET_SSL(s),
tls13_aes128gcmsha256_id);
@ -834,10 +845,11 @@ EXT_RETURN tls_construct_ctos_early_data(SSL_CONNECTION *s, WPACKET *pkt,
}
psksess = SSL_SESSION_new();
if (psksess == NULL
|| !SSL_SESSION_set1_master_key(psksess, psk, psklen)
|| !SSL_SESSION_set_cipher(psksess, cipher)
|| !SSL_SESSION_set_protocol_version(psksess, TLS1_3_VERSION)) {
|| !SSL_SESSION_set_protocol_version(psksess, version1_3)) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
OPENSSL_cleanse(psk, psklen);
return EXT_RETURN_FAIL;
@ -950,6 +962,7 @@ EXT_RETURN tls_construct_ctos_padding(SSL_CONNECTION *s, WPACKET *pkt,
{
unsigned char *padbytes;
size_t hlen;
const int version1_3 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION : TLS1_3_VERSION;
if ((s->options & SSL_OP_TLSEXT_PADDING) == 0)
return EXT_RETURN_NOT_SENT;
@ -969,7 +982,7 @@ EXT_RETURN tls_construct_ctos_padding(SSL_CONNECTION *s, WPACKET *pkt,
* If we're going to send a PSK then that will be written out after this
* extension, so we need to calculate how long it is going to be.
*/
if (s->session->ssl_version == TLS1_3_VERSION
if (s->session->ssl_version == version1_3
&& s->session->ext.ticklen != 0
&& s->session->cipher != NULL) {
const EVP_MD *md = ssl_md(SSL_CONNECTION_GET_CTX(s),
@ -1022,7 +1035,7 @@ EXT_RETURN tls_construct_ctos_psk(SSL_CONNECTION *s, WPACKET *pkt,
unsigned int context,
X509 *x, size_t chainidx)
{
#ifndef OPENSSL_NO_TLS1_3
#if !(defined(OPENSSL_NO_TLS1_3) && defined(OPENSSL_NO_DTLS1_3))
uint32_t agesec, agems = 0;
size_t binderoffset, msglen;
int reshashsize = 0, pskhashsize = 0;
@ -1031,6 +1044,7 @@ EXT_RETURN tls_construct_ctos_psk(SSL_CONNECTION *s, WPACKET *pkt,
int dores = 0;
SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s);
OSSL_TIME t;
const int version1_3 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION : TLS1_3_VERSION;
s->ext.tick_identity = 0;
@ -1044,7 +1058,7 @@ EXT_RETURN tls_construct_ctos_psk(SSL_CONNECTION *s, WPACKET *pkt,
* If this is an incompatible or new session then we have nothing to resume
* so don't add this extension.
*/
if (s->session->ssl_version != TLS1_3_VERSION
if (s->session->ssl_version != version1_3
|| (s->session->ext.ticklen == 0 && s->psksession == NULL))
return EXT_RETURN_NOT_SENT;
@ -1206,8 +1220,7 @@ EXT_RETURN tls_construct_ctos_psk(SSL_CONNECTION *s, WPACKET *pkt,
msgstart = WPACKET_get_curr(pkt) - msglen;
if (dores
&& tls_psk_do_binder(s, mdres, msgstart, binderoffset, NULL,
if (dores && tls_psk_do_binder(s, mdres, msgstart, binderoffset, NULL,
resbinder, s->session, 1, 0) != 1) {
/* SSLfatal() already called */
return EXT_RETURN_FAIL;
@ -1231,7 +1244,7 @@ EXT_RETURN tls_construct_ctos_post_handshake_auth(SSL_CONNECTION *s, WPACKET *pk
ossl_unused X509 *x,
ossl_unused size_t chainidx)
{
#ifndef OPENSSL_NO_TLS1_3
#if !(defined(OPENSSL_NO_TLS1_3) && defined(OPENSSL_NO_DTLS1_3))
if (!s->pha_enabled)
return EXT_RETURN_NOT_SENT;
@ -1458,18 +1471,18 @@ int tls_parse_stoc_status_request(SSL_CONNECTION *s, PACKET *pkt,
/*
* MUST only be sent if we've requested a status
* request message. In TLS <= 1.2 it must also be empty.
* request message. In (D)TLS <= 1.2 it must also be empty.
*/
if (s->ext.status_type != TLSEXT_STATUSTYPE_ocsp) {
SSLfatal(s, SSL_AD_UNSUPPORTED_EXTENSION, SSL_R_BAD_EXTENSION);
return 0;
}
if (!SSL_CONNECTION_IS_TLS13(s) && PACKET_remaining(pkt) > 0) {
if (!SSL_CONNECTION_IS_VERSION13(s) && PACKET_remaining(pkt) > 0) {
SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION);
return 0;
}
if (SSL_CONNECTION_IS_TLS13(s)) {
if (SSL_CONNECTION_IS_VERSION13(s)) {
/* We only know how to handle this if it's for the first Certificate in
* the chain. We ignore any other responses.
*/
@ -1796,6 +1809,7 @@ int tls_parse_stoc_supported_versions(SSL_CONNECTION *s, PACKET *pkt,
X509 *x, size_t chainidx)
{
unsigned int version;
const int version1_3 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION : TLS1_3_VERSION;
if (!PACKET_get_net_2(pkt, &version)
|| PACKET_remaining(pkt) != 0) {
@ -1805,9 +1819,9 @@ int tls_parse_stoc_supported_versions(SSL_CONNECTION *s, PACKET *pkt,
/*
* The only protocol version we support which is valid in this extension in
* a ServerHello is TLSv1.3 therefore we shouldn't be getting anything else.
* a ServerHello is (D)TLSv1.3 therefore we shouldn't be getting anything else.
*/
if (version != TLS1_3_VERSION) {
if ((int)version != version1_3) {
SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER,
SSL_R_BAD_PROTOCOL_VERSION_NUMBER);
return 0;
@ -1831,7 +1845,7 @@ int tls_parse_stoc_key_share(SSL_CONNECTION *s, PACKET *pkt,
unsigned int context, X509 *x,
size_t chainidx)
{
#ifndef OPENSSL_NO_TLS1_3
#if !(defined(OPENSSL_NO_TLS1_3) && defined(OPENSSL_NO_DTLS1_3))
unsigned int group_id;
PACKET encoded_pt;
EVP_PKEY *ckey = s->s3.tmp.pkey, *skey = NULL;
@ -1851,6 +1865,8 @@ int tls_parse_stoc_key_share(SSL_CONNECTION *s, PACKET *pkt,
if ((context & SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST) != 0) {
const uint16_t *pgroups = NULL;
size_t i, num_groups;
const int version1_3 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION
: TLS1_3_VERSION;
if (PACKET_remaining(pkt) != 0) {
SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH);
@ -1872,10 +1888,10 @@ int tls_parse_stoc_key_share(SSL_CONNECTION *s, PACKET *pkt,
if (group_id == pgroups[i])
break;
}
if (i >= num_groups
|| !tls_group_allowed(s, group_id, SSL_SECOP_CURVE_SUPPORTED)
|| !tls_valid_group(s, group_id, TLS1_3_VERSION, TLS1_3_VERSION,
0, NULL)) {
|| !tls_valid_group(s, group_id, version1_3, version1_3, 0, NULL)) {
SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_KEY_SHARE);
return 0;
}
@ -2041,7 +2057,7 @@ int tls_parse_stoc_psk(SSL_CONNECTION *s, PACKET *pkt,
unsigned int context, X509 *x,
size_t chainidx)
{
#ifndef OPENSSL_NO_TLS1_3
#if !(defined(OPENSSL_NO_TLS1_3) && defined(OPENSSL_NO_DTLS1_3))
unsigned int identity;
if (!PACKET_get_net_2(pkt, &identity) || PACKET_remaining(pkt) != 0) {

View file

@ -31,7 +31,7 @@
* + 2 bytes for extension block length + 6 bytes for key_share extension
* + 4 bytes for cookie extension header + the number of bytes in the cookie
*/
#define MAX_HRR_SIZE (SSL3_HM_HEADER_LENGTH + 2 + SSL3_RANDOM_SIZE + 1 \
#define MAX_HRR_SIZE (DTLS1_HM_HEADER_LENGTH + 2 + SSL3_RANDOM_SIZE + 1 \
+ SSL_MAX_SSL_SESSION_ID_LENGTH + 2 + 1 + 2 + 6 + 4 \
+ MAX_COOKIE_SIZE)
@ -133,10 +133,10 @@ int tls_parse_ctos_server_name(SSL_CONNECTION *s, PACKET *pkt,
}
/*
* In TLSv1.2 and below the SNI is associated with the session. In TLSv1.3
* In (D)TLSv1.2 and below the SNI is associated with the session. In (D)TLSv1.3
* we always use the SNI value from the handshake.
*/
if (!s->hit || SSL_CONNECTION_IS_TLS13(s)) {
if (!s->hit || SSL_CONNECTION_IS_VERSION13(s)) {
if (PACKET_remaining(&hostname) > TLSEXT_MAXLEN_host_name) {
SSLfatal(s, SSL_AD_UNRECOGNIZED_NAME, SSL_R_BAD_EXTENSION);
return 0;
@ -161,9 +161,9 @@ int tls_parse_ctos_server_name(SSL_CONNECTION *s, PACKET *pkt,
s->servername_done = 1;
} else {
/*
* In TLSv1.2 and below we should check if the SNI is consistent between
* the initial handshake and the resumption. In TLSv1.3 SNI is not
* associated with the session.
* In (D)TLSv1.2 and below we should check if the SNI is consistent
* between the initial handshake and the resumption. In (D)TLSv1.3 SNI
* is not associated with the session.
*/
s->servername_done = (s->session->ext.hostname != NULL)
&& PACKET_equal(&hostname, s->session->ext.hostname,
@ -561,7 +561,7 @@ int tls_parse_ctos_psk_kex_modes(SSL_CONNECTION *s, PACKET *pkt,
unsigned int context,
X509 *x, size_t chainidx)
{
#ifndef OPENSSL_NO_TLS1_3
#if !(defined(OPENSSL_NO_TLS1_3) && defined(OPENSSL_NO_DTLS1_3))
PACKET psk_kex_modes;
unsigned int mode;
@ -605,7 +605,7 @@ int tls_parse_ctos_psk_kex_modes(SSL_CONNECTION *s, PACKET *pkt,
int tls_parse_ctos_key_share(SSL_CONNECTION *s, PACKET *pkt,
unsigned int context, X509 *x, size_t chainidx)
{
#ifndef OPENSSL_NO_TLS1_3
#if !(defined(OPENSSL_NO_TLS1_3) && defined(OPENSSL_NO_DTLS1_3))
unsigned int group_id;
PACKET key_share_list, encoded_pt;
const uint16_t *clntgroups, *srvrgroups;
@ -652,6 +652,9 @@ int tls_parse_ctos_key_share(SSL_CONNECTION *s, PACKET *pkt,
}
while (PACKET_remaining(&key_share_list) > 0) {
const int version1_3 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION
: TLS1_3_VERSION;
if (!PACKET_get_net_2(&key_share_list, &group_id)
|| !PACKET_get_length_prefixed_2(&key_share_list, &encoded_pt)
|| PACKET_remaining(&encoded_pt) == 0) {
@ -688,9 +691,9 @@ int tls_parse_ctos_key_share(SSL_CONNECTION *s, PACKET *pkt,
|| !tls_group_allowed(s, group_id, SSL_SECOP_CURVE_SUPPORTED)
/*
* We tolerate but ignore a group id that we don't think is
* suitable for TLSv1.3
* suitable for (D)TLSv1.3
*/
|| !tls_valid_group(s, group_id, TLS1_3_VERSION, TLS1_3_VERSION,
|| !tls_valid_group(s, group_id, version1_3, version1_3,
0, NULL)) {
/* Share not suitable */
continue;
@ -723,7 +726,7 @@ int tls_parse_ctos_key_share(SSL_CONNECTION *s, PACKET *pkt,
int tls_parse_ctos_cookie(SSL_CONNECTION *s, PACKET *pkt, unsigned int context,
X509 *x, size_t chainidx)
{
#ifndef OPENSSL_NO_TLS1_3
#if !(defined(OPENSSL_NO_TLS1_3) && defined(OPENSSL_NO_DTLS1_3))
unsigned int format, version, key_share, group_id;
EVP_MD_CTX *hctx;
EVP_PKEY *pkey;
@ -736,6 +739,11 @@ int tls_parse_ctos_cookie(SSL_CONNECTION *s, PACKET *pkt, unsigned int context,
uint64_t tm, now;
SSL *ssl = SSL_CONNECTION_GET_SSL(s);
SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s);
const int version1_2 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_2_VERSION : TLS1_2_VERSION;
const int version1_3 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION : TLS1_3_VERSION;
size_t msgbody_offs = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_HM_HEADER_LENGTH
- SSL3_HM_HEADER_LENGTH
: 0;
/* Ignore any cookie if we're not set up to verify it */
if (sctx->verify_stateless_cookie_cb == NULL
@ -808,7 +816,7 @@ int tls_parse_ctos_cookie(SSL_CONNECTION *s, PACKET *pkt, unsigned int context,
SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH);
return 0;
}
if (version != TLS1_3_VERSION) {
if ((int)version != version1_3) {
SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER,
SSL_R_BAD_PROTOCOL_VERSION_NUMBER);
return 0;
@ -869,8 +877,15 @@ int tls_parse_ctos_cookie(SSL_CONNECTION *s, PACKET *pkt, unsigned int context,
return 0;
}
if (!WPACKET_put_bytes_u8(&hrrpkt, SSL3_MT_SERVER_HELLO)
|| !WPACKET_start_sub_packet_u24(&hrrpkt)
|| !WPACKET_put_bytes_u16(&hrrpkt, TLS1_2_VERSION)
|| !WPACKET_start_sub_packet_u24_at_offset(&hrrpkt, msgbody_offs)
/*
* We are reconstructing the HRR to be able to calculate the
* transcript hash.
* Since HRR is only allowed for (D)TLSv1.3 and transcript hash does
* not include the values of message_seq, fragment_offset and
* fragment_length, setting these values is not required.
*/
|| !WPACKET_put_bytes_u16(&hrrpkt, version1_2)
|| !WPACKET_memcpy(&hrrpkt, hrrrandom, SSL3_RANDOM_SIZE)
|| !WPACKET_sub_memcpy_u8(&hrrpkt, s->tmp_session_id,
s->tmp_session_id_len)
@ -944,7 +959,7 @@ int tls_parse_ctos_supported_groups(SSL_CONNECTION *s, PACKET *pkt,
return 0;
}
if (!s->hit || SSL_CONNECTION_IS_TLS13(s)) {
if (!s->hit || SSL_CONNECTION_IS_VERSION13(s)) {
OPENSSL_free(s->ext.peer_supportedgroups);
s->ext.peer_supportedgroups = NULL;
s->ext.peer_supportedgroups_len = 0;
@ -1087,10 +1102,12 @@ int tls_parse_ctos_psk(SSL_CONNECTION *s, PACKET *pkt, unsigned int context,
} else if (pskdatalen > 0) {
const SSL_CIPHER *cipher;
const unsigned char tls13_aes128gcmsha256_id[] = { 0x13, 0x01 };
const int version1_3 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION
: TLS1_3_VERSION;
/*
* We found a PSK using an old style callback. We don't know
* the digest so we default to SHA256 as per the TLSv1.3 spec
* the digest so we default to SHA256 as per the (D)TLSv1.3 spec
*/
cipher = SSL_CIPHER_find(SSL_CONNECTION_GET_SSL(s),
tls13_aes128gcmsha256_id);
@ -1101,12 +1118,12 @@ int tls_parse_ctos_psk(SSL_CONNECTION *s, PACKET *pkt, unsigned int context,
}
sess = SSL_SESSION_new();
if (sess == NULL
|| !SSL_SESSION_set1_master_key(sess, pskdata,
pskdatalen)
|| !SSL_SESSION_set_cipher(sess, cipher)
|| !SSL_SESSION_set_protocol_version(sess,
TLS1_3_VERSION)) {
|| !SSL_SESSION_set_protocol_version(sess, version1_3)) {
OPENSSL_cleanse(pskdata, pskdatalen);
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
goto err;
@ -1315,10 +1332,10 @@ EXT_RETURN tls_construct_stoc_server_name(SSL_CONNECTION *s, WPACKET *pkt,
return EXT_RETURN_NOT_SENT;
/*
* Prior to TLSv1.3 we ignore any SNI in the current handshake if resuming.
* Prior to (D)TLSv1.3 we ignore any SNI in the current handshake if resuming.
* We just use the servername from the initial handshake.
*/
if (s->hit && !SSL_CONNECTION_IS_TLS13(s))
if (s->hit && !SSL_CONNECTION_IS_VERSION13(s))
return EXT_RETURN_NOT_SENT;
if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_server_name)
@ -1469,7 +1486,7 @@ EXT_RETURN tls_construct_stoc_status_request(SSL_CONNECTION *s, WPACKET *pkt,
if (!s->ext.status_expected)
return EXT_RETURN_NOT_SENT;
if (SSL_CONNECTION_IS_TLS13(s) && chainidx != 0)
if (SSL_CONNECTION_IS_VERSION13(s) && chainidx != 0)
return EXT_RETURN_NOT_SENT;
if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_status_request)
@ -1479,11 +1496,12 @@ EXT_RETURN tls_construct_stoc_status_request(SSL_CONNECTION *s, WPACKET *pkt,
}
/*
* In TLSv1.3 we include the certificate status itself. In <= TLSv1.2 we
* In (D)TLSv1.3 we include the certificate status itself. In <= (D)TLSv1.2 we
* send back an empty extension, with the certificate status appearing as a
* separate message
*/
if (SSL_CONNECTION_IS_TLS13(s) && !tls_construct_cert_status_body(s, pkt)) {
if (SSL_CONNECTION_IS_VERSION13(s)
&& !tls_construct_cert_status_body(s, pkt)) {
/* SSLfatal() already called */
return EXT_RETURN_FAIL;
}
@ -1620,7 +1638,7 @@ EXT_RETURN tls_construct_stoc_supported_versions(SSL_CONNECTION *s, WPACKET *pkt
unsigned int context, X509 *x,
size_t chainidx)
{
if (!ossl_assert(SSL_CONNECTION_IS_TLS13(s))) {
if (!ossl_assert(SSL_CONNECTION_IS_VERSION13(s))) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return EXT_RETURN_FAIL;
}
@ -1640,7 +1658,7 @@ EXT_RETURN tls_construct_stoc_key_share(SSL_CONNECTION *s, WPACKET *pkt,
unsigned int context, X509 *x,
size_t chainidx)
{
#ifndef OPENSSL_NO_TLS1_3
#if !(defined(OPENSSL_NO_TLS1_3) && defined(OPENSSL_NO_DTLS1_3))
unsigned char *encodedPoint;
size_t encoded_pt_len = 0;
EVP_PKEY *ckey = s->s3.peer_tmp, *skey = NULL;
@ -1768,6 +1786,7 @@ EXT_RETURN tls_construct_stoc_key_share(SSL_CONNECTION *s, WPACKET *pkt,
s->s3.did_kex = 1;
return EXT_RETURN_SENT;
#else
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return EXT_RETURN_FAIL;
#endif
}
@ -1776,7 +1795,7 @@ EXT_RETURN tls_construct_stoc_cookie(SSL_CONNECTION *s, WPACKET *pkt,
unsigned int context,
X509 *x, size_t chainidx)
{
#ifndef OPENSSL_NO_TLS1_3
#if !(defined(OPENSSL_NO_TLS1_3) && defined(OPENSSL_NO_DTLS1_3))
unsigned char *hashval1, *hashval2, *appcookie1, *appcookie2, *cookie;
unsigned char *hmac, *hmac2;
size_t startlen, ciphlen, totcookielen, hashlen, hmaclen, appcookielen;
@ -1786,6 +1805,7 @@ EXT_RETURN tls_construct_stoc_cookie(SSL_CONNECTION *s, WPACKET *pkt,
SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s);
SSL *ssl = SSL_CONNECTION_GET_SSL(s);
SSL *ussl = SSL_CONNECTION_GET_USER_SSL(s);
const int version = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION : TLS1_3_VERSION;
if ((s->s3.flags & TLS1_FLAGS_STATELESS) == 0)
return EXT_RETURN_NOT_SENT;
@ -1801,7 +1821,7 @@ EXT_RETURN tls_construct_stoc_cookie(SSL_CONNECTION *s, WPACKET *pkt,
|| !WPACKET_get_total_written(pkt, &startlen)
|| !WPACKET_reserve_bytes(pkt, MAX_COOKIE_SIZE, &cookie)
|| !WPACKET_put_bytes_u16(pkt, COOKIE_STATE_FORMAT_VERSION)
|| !WPACKET_put_bytes_u16(pkt, TLS1_3_VERSION)
|| !WPACKET_put_bytes_u16(pkt, version)
|| !WPACKET_put_bytes_u16(pkt, s->s3.group_id)
|| !ssl->method->put_cipher_by_char(s->s3.tmp.new_cipher, pkt,
&ciphlen)
@ -1897,6 +1917,7 @@ EXT_RETURN tls_construct_stoc_cookie(SSL_CONNECTION *s, WPACKET *pkt,
EVP_PKEY_free(pkey);
return ret;
#else
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return EXT_RETURN_FAIL;
#endif
}
@ -1997,7 +2018,7 @@ EXT_RETURN tls_construct_stoc_client_cert_type(SSL_CONNECTION *sc, WPACKET *pkt,
/*
* Note: only supposed to send this if we are going to do a cert request,
* but TLSv1.3 could do a PHA request if the client supports it
* but (D)TLSv1.3 could do a PHA request if the client supports it
*/
if ((!send_certificate_request(sc) && sc->post_handshake_auth != SSL_PHA_EXT_RECEIVED)
|| sc->ext.client_cert_type_ctos != OSSL_CERT_TYPE_CTOS_GOOD

View file

@ -401,7 +401,7 @@ static int state_machine(SSL_CONNECTION *s, int server)
s->server = server;
if (cb != NULL) {
if (SSL_IS_FIRST_HANDSHAKE(s) || !SSL_CONNECTION_IS_TLS13(s))
if (SSL_IS_FIRST_HANDSHAKE(s) || !SSL_CONNECTION_IS_VERSION13(s))
cb(ussl, SSL_CB_HANDSHAKE_START, 1);
}

View file

@ -190,19 +190,8 @@ static int ossl_statem_client13_read_transition(SSL_CONNECTION *s, int mt)
return 1;
}
if (mt == SSL3_MT_CERTIFICATE_REQUEST) {
#if DTLS_MAX_VERSION_INTERNAL != DTLS1_2_VERSION
/* Restore digest for PHA before adding message.*/
# error Internal DTLS version error
#endif
if (!SSL_CONNECTION_IS_DTLS(s)
&& s->post_handshake_auth == SSL_PHA_EXT_SENT) {
if (s->post_handshake_auth == SSL_PHA_EXT_SENT) {
s->post_handshake_auth = SSL_PHA_REQUESTED;
/*
* In TLS, this is called before the message is added to the
* digest. In DTLS, this is expected to be called after adding
* to the digest. Either move the digest restore, or add the
* message here after the swap, or do it after the clientFinished?
*/
if (!tls13_restore_handshake_digest_for_pha(s)) {
/* SSLfatal() already called */
return 0;
@ -236,7 +225,7 @@ int ossl_statem_client_read_transition(SSL_CONNECTION *s, int mt)
* Note that after writing the first ClientHello we don't know what version
* we are going to negotiate yet, so we don't take this branch until later.
*/
if (SSL_CONNECTION_IS_TLS13(s)) {
if (SSL_CONNECTION_IS_VERSION13(s)) {
if (!ossl_statem_client13_read_transition(s, mt))
goto err;
return 1;
@ -476,7 +465,7 @@ static WRITE_TRAN ossl_statem_client13_write_transition(SSL_CONNECTION *s)
if (s->early_data_state == SSL_EARLY_DATA_WRITE_RETRY
|| s->early_data_state == SSL_EARLY_DATA_FINISHED_WRITING)
st->hand_state = TLS_ST_PENDING_EARLY_DATA_END;
else if ((s->options & SSL_OP_ENABLE_MIDDLEBOX_COMPAT) != 0
else if (SSL_CONNECTION_MIDDLEBOX_IS_ENABLED(s)
&& s->hello_retry_request == SSL_HRR_NONE)
st->hand_state = TLS_ST_CW_CHANGE;
else if (s->s3.tmp.cert_req == 0)
@ -548,7 +537,7 @@ WRITE_TRAN ossl_statem_client_write_transition(SSL_CONNECTION *s)
* version we are going to negotiate yet, so we don't take this branch until
* later
*/
if (SSL_CONNECTION_IS_TLS13(s))
if (SSL_CONNECTION_IS_VERSION13(s))
return ossl_statem_client13_write_transition(s);
switch (st->hand_state) {
@ -574,10 +563,10 @@ WRITE_TRAN ossl_statem_client_write_transition(SSL_CONNECTION *s)
case TLS_ST_CW_CLNT_HELLO:
if (s->early_data_state == SSL_EARLY_DATA_CONNECTING) {
/*
* We are assuming this is a TLSv1.3 connection, although we haven't
* We are assuming this is a (D)TLSv1.3 connection, although we haven't
* actually selected a version yet.
*/
if ((s->options & SSL_OP_ENABLE_MIDDLEBOX_COMPAT) != 0)
if (SSL_CONNECTION_MIDDLEBOX_IS_ENABLED(s))
st->hand_state = TLS_ST_CW_CHANGE;
else
st->hand_state = TLS_ST_EARLY_DATA;
@ -592,11 +581,11 @@ WRITE_TRAN ossl_statem_client_write_transition(SSL_CONNECTION *s)
case TLS_ST_CR_SRVR_HELLO:
/*
* We only get here in TLSv1.3. We just received an HRR, so issue a
* We only get here in (D)TLSv1.3. We just received an HRR, so issue a
* CCS unless middlebox compat mode is off, or we already issued one
* because we did early data.
*/
if ((s->options & SSL_OP_ENABLE_MIDDLEBOX_COMPAT) != 0
if (SSL_CONNECTION_MIDDLEBOX_IS_ENABLED(s)
&& s->early_data_state != SSL_EARLY_DATA_FINISHED_WRITING)
st->hand_state = TLS_ST_CW_CHANGE;
else
@ -721,7 +710,7 @@ WORK_STATE ossl_statem_client_pre_work(SSL_CONNECTION *s, WORK_STATE wst)
case TLS_ST_CW_CLNT_HELLO:
s->shutdown = 0;
if (SSL_CONNECTION_IS_DTLS(s)) {
if (SSL_CONNECTION_IS_DTLS(s) && s->hello_retry_request != SSL_HRR_PENDING) {
/* every DTLS ClientHello resets Finished MAC */
if (!ssl3_init_finished_mac(s)) {
/* SSLfatal() already called */
@ -738,9 +727,9 @@ WORK_STATE ossl_statem_client_pre_work(SSL_CONNECTION *s, WORK_STATE wst)
TLS_ANY_VERSION,
OSSL_RECORD_DIRECTION_WRITE,
OSSL_RECORD_PROTECTION_LEVEL_NONE,
NULL, 0, NULL, 0, NULL, 0, NULL, 0,
NULL, 0, NID_undef, NULL, NULL,
NULL)) {
NULL, 0, NULL, NULL, 0, NULL, 0,
NULL, 0, NULL, 0, NULL, 0, NID_undef,
NULL, NULL, NULL)) {
/* SSLfatal already called */
return WORK_ERROR;
}
@ -807,11 +796,11 @@ WORK_STATE ossl_statem_client_post_work(SSL_CONNECTION *s, WORK_STATE wst)
if (s->early_data_state == SSL_EARLY_DATA_CONNECTING
&& s->max_early_data > 0) {
/*
* We haven't selected TLSv1.3 yet so we don't call the change
* We haven't selected (D)TLSv1.3 yet so we don't call the change
* cipher state function associated with the SSL_METHOD. Instead
* we call tls13_change_cipher_state() directly.
*/
if ((s->options & SSL_OP_ENABLE_MIDDLEBOX_COMPAT) == 0) {
if (!SSL_CONNECTION_MIDDLEBOX_IS_ENABLED(s)) {
if (!tls13_change_cipher_state(s,
SSL3_CC_EARLY | SSL3_CHANGE_CIPHER_CLIENT_WRITE)) {
/* SSLfatal() already called */
@ -837,13 +826,13 @@ WORK_STATE ossl_statem_client_post_work(SSL_CONNECTION *s, WORK_STATE wst)
break;
case TLS_ST_CW_CHANGE:
if (SSL_CONNECTION_IS_TLS13(s)
if (SSL_CONNECTION_IS_VERSION13(s)
|| s->hello_retry_request == SSL_HRR_PENDING)
break;
if (s->early_data_state == SSL_EARLY_DATA_CONNECTING
&& s->max_early_data > 0) {
/*
* We haven't selected TLSv1.3 yet so we don't call the change
* We haven't selected (D)TLSv1.3 yet so we don't call the change
* cipher state function associated with the SSL_METHOD. Instead
* we call tls13_change_cipher_state() directly.
*/
@ -898,7 +887,7 @@ WORK_STATE ossl_statem_client_post_work(SSL_CONNECTION *s, WORK_STATE wst)
if (statem_flush(s) != 1)
return WORK_MORE_B;
if (SSL_CONNECTION_IS_TLS13(s)) {
if (SSL_CONNECTION_IS_VERSION13(s)) {
if (!tls13_save_handshake_digest_for_pha(s)) {
/* SSLfatal() already called */
return WORK_ERROR;
@ -1059,7 +1048,7 @@ size_t ossl_statem_client_max_message_size(SSL_CONNECTION *s)
return CCS_MAX_LENGTH;
case TLS_ST_CR_SESSION_TICKET:
return (SSL_CONNECTION_IS_TLS13(s)) ? SESSION_TICKET_MAX_LENGTH_TLS13
return SSL_CONNECTION_IS_VERSION13(s) ? SESSION_TICKET_MAX_LENGTH_TLS13
: SESSION_TICKET_MAX_LENGTH_TLS12;
case TLS_ST_CR_FINISHED:
@ -1166,6 +1155,7 @@ CON_FUNC_RETURN tls_construct_client_hello(SSL_CONNECTION *s, WPACKET *pkt)
unsigned char *p;
size_t sess_id_len;
int i, protverr;
const int version1_3 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION : TLS1_3_VERSION;
#ifndef OPENSSL_NO_COMP
SSL_COMP *comp;
#endif
@ -1198,6 +1188,7 @@ CON_FUNC_RETURN tls_construct_client_hello(SSL_CONNECTION *s, WPACKET *pkt)
* required to use same upon reply to HelloVerify
*/
if (SSL_CONNECTION_IS_DTLS(s)) {
/* TODO(DTLS-1.3): Check this bit for HRR */
size_t idx;
i = 1;
for (idx = 0; idx < sizeof(s->s3.client_random); idx++) {
@ -1257,9 +1248,9 @@ CON_FUNC_RETURN tls_construct_client_hello(SSL_CONNECTION *s, WPACKET *pkt)
/* Session ID */
session_id = s->session->session_id;
if (s->new_session || s->session->ssl_version == TLS1_3_VERSION) {
if (s->new_session || s->session->ssl_version == version1_3) {
if (s->version == TLS1_3_VERSION
&& (s->options & SSL_OP_ENABLE_MIDDLEBOX_COMPAT) != 0) {
&& SSL_CONNECTION_MIDDLEBOX_IS_ENABLED(s)) {
sess_id_len = sizeof(s->tmp_session_id);
s->tmp_session_id_len = sess_id_len;
session_id = s->tmp_session_id;
@ -1275,7 +1266,7 @@ CON_FUNC_RETURN tls_construct_client_hello(SSL_CONNECTION *s, WPACKET *pkt)
} else {
assert(s->session->session_id_length <= sizeof(s->session->session_id));
sess_id_len = s->session->session_id_length;
if (s->version == TLS1_3_VERSION) {
if (s->version == version1_3) {
s->tmp_session_id_len = sess_id_len;
memcpy(s->tmp_session_id, s->session->session_id, sess_id_len);
}
@ -1322,8 +1313,7 @@ CON_FUNC_RETURN tls_construct_client_hello(SSL_CONNECTION *s, WPACKET *pkt)
#ifndef OPENSSL_NO_COMP
if (ssl_allow_compression(s)
&& sctx->comp_methods
&& (SSL_CONNECTION_IS_DTLS(s)
|| s->s3.tmp.max_ver < TLS1_3_VERSION)) {
&& ssl_version_cmp(s, s->s3.tmp.max_ver, version1_3) < 0) {
int compnum = sk_SSL_COMP_num(sctx->comp_methods);
for (i = 0; i < compnum; i++) {
comp = sk_SSL_COMP_value(sctx->comp_methods, i);
@ -1353,6 +1343,8 @@ MSG_PROCESS_RETURN dtls_process_hello_verify(SSL_CONNECTION *s, PACKET *pkt)
{
size_t cookie_len;
PACKET cookiepkt;
int min_version;
SSL *ssl = SSL_CONNECTION_GET_SSL(s);
if (!PACKET_forward(pkt, 2)
|| !PACKET_get_length_prefixed_1(pkt, &cookiepkt)) {
@ -1372,6 +1364,25 @@ MSG_PROCESS_RETURN dtls_process_hello_verify(SSL_CONNECTION *s, PACKET *pkt)
}
s->d1->cookie_len = cookie_len;
if (ssl == NULL) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return MSG_PROCESS_ERROR;
}
min_version = SSL_get_min_proto_version(ssl);
/*
* Server responds with a HelloVerify which means we cannot negotiate a
* higher version than DTLSv1.2.
*/
if (min_version != 0
&& ssl_version_cmp(s, min_version, DTLS1_2_VERSION) > 0) {
SSLfatal(s, SSL_AD_PROTOCOL_VERSION, SSL_R_UNSUPPORTED_PROTOCOL);
return MSG_PROCESS_ERROR;
}
s->d1->hello_verify_request = SSL_HVR_RECEIVED;
return MSG_PROCESS_FINISHED_READING;
}
@ -1406,7 +1417,7 @@ static int set_client_ciphersuite(SSL_CONNECTION *s,
return 0;
}
if (SSL_CONNECTION_IS_TLS13(s) && s->s3.tmp.new_cipher != NULL
if (SSL_CONNECTION_IS_VERSION13(s) && s->s3.tmp.new_cipher != NULL
&& s->s3.tmp.new_cipher->id != c->id) {
/* ServerHello selected a different ciphersuite to that in the HRR */
SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_WRONG_CIPHER_RETURNED);
@ -1421,7 +1432,7 @@ static int set_client_ciphersuite(SSL_CONNECTION *s,
if (s->session->cipher != NULL)
s->session->cipher_id = s->session->cipher->id;
if (s->hit && (s->session->cipher_id != c->id)) {
if (SSL_CONNECTION_IS_TLS13(s)) {
if (SSL_CONNECTION_IS_VERSION13(s)) {
const EVP_MD *md = ssl_md(sctx, c->algorithm2);
if (!ossl_assert(s->session->cipher != NULL)) {
@ -1463,6 +1474,9 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL_CONNECTION *s, PACKET *pkt)
unsigned int sversion;
unsigned int context;
RAW_EXTENSION *extensions = NULL;
const int version1_3 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION : TLS1_3_VERSION;
const unsigned int version1_2 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_2_VERSION
: TLS1_2_VERSION;
SSL *ssl = SSL_CONNECTION_GET_SSL(s);
SSL *ussl = SSL_CONNECTION_GET_USER_SSL(s);
#ifndef OPENSSL_NO_COMP
@ -1475,8 +1489,7 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL_CONNECTION *s, PACKET *pkt)
}
/* load the server random */
if (s->version == TLS1_3_VERSION
&& sversion == TLS1_2_VERSION
if (s->version == version1_3 && sversion == version1_2
&& PACKET_remaining(pkt) >= SSL3_RANDOM_SIZE
&& memcmp(hrrrandom, PACKET_data(pkt), SSL3_RANDOM_SIZE) == 0) {
if (s->hello_retry_request != SSL_HRR_NONE) {
@ -1547,7 +1560,7 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL_CONNECTION *s, PACKET *pkt)
}
}
if (SSL_CONNECTION_IS_TLS13(s) || hrr) {
if (SSL_CONNECTION_IS_VERSION13(s) || hrr) {
if (compression != 0) {
SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER,
SSL_R_INVALID_COMPRESSION_ALGORITHM);
@ -1575,7 +1588,7 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL_CONNECTION *s, PACKET *pkt)
* Now we have chosen the version we need to check again that the extensions
* are appropriate for this version.
*/
context = SSL_CONNECTION_IS_TLS13(s) ? SSL_EXT_TLS1_3_SERVER_HELLO
context = SSL_CONNECTION_IS_VERSION13(s) ? SSL_EXT_TLS1_3_SERVER_HELLO
: SSL_EXT_TLS1_2_SERVER_HELLO;
if (!tls_validate_all_contexts(s, context, extensions)) {
SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_EXTENSION);
@ -1584,7 +1597,7 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL_CONNECTION *s, PACKET *pkt)
s->hit = 0;
if (SSL_CONNECTION_IS_TLS13(s)) {
if (SSL_CONNECTION_IS_VERSION13(s)) {
/*
* In TLSv1.3 a ServerHello message signals a key change so the end of
* the message must be on a record boundary.
@ -1677,7 +1690,7 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL_CONNECTION *s, PACKET *pkt)
* echo of what we originally sent in the ClientHello and should not be
* used for resumption.
*/
if (!SSL_CONNECTION_IS_TLS13(s)) {
if (!SSL_CONNECTION_IS_VERSION13(s)) {
s->session->session_id_length = session_id_len;
/* session_id_len could be 0 */
if (session_id_len > 0)
@ -1749,7 +1762,12 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL_CONNECTION *s, PACKET *pkt)
}
#ifndef OPENSSL_NO_SCTP
if (SSL_CONNECTION_IS_DTLS(s) && s->hit) {
/*
* Before exporting the SCTP auth key we check if DTLSv1.3 has been negotiated
* which is not supported.
* Refer to draft-tuexen-tsvwg-rfc6083-bis-04 for more info.
*/
if (SSL_CONNECTION_IS_DTLS(s) && !SSL_CONNECTION_IS_DTLS13(s) && s->hit) {
unsigned char sctpauthkey[64];
char labelbuffer[sizeof(DTLS1_SCTP_AUTH_LABEL)];
size_t labellen;
@ -1784,7 +1802,7 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL_CONNECTION *s, PACKET *pkt)
* In TLSv1.3 we have some post-processing to change cipher state, otherwise
* we're done with this message
*/
if (SSL_CONNECTION_IS_TLS13(s)) {
if (SSL_CONNECTION_IS_VERSION13(s)) {
if (!ssl->method->ssl3_enc->setup_key_block(s)
|| !ssl->method->ssl3_enc->change_cipher_state(s,
SSL3_CC_HANDSHAKE | SSL3_CHANGE_CIPHER_CLIENT_READ)) {
@ -1801,7 +1819,7 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL_CONNECTION *s, PACKET *pkt)
* compat this doesn't cause a problem.
*/
if (s->early_data_state == SSL_EARLY_DATA_NONE
&& (s->options & SSL_OP_ENABLE_MIDDLEBOX_COMPAT) == 0
&& !SSL_CONNECTION_MIDDLEBOX_IS_ENABLED(s)
&& !ssl->method->ssl3_enc->change_cipher_state(s,
SSL3_CC_HANDSHAKE | SSL3_CHANGE_CIPHER_CLIENT_WRITE)) {
/* SSLfatal() already called */
@ -1820,23 +1838,31 @@ static MSG_PROCESS_RETURN tls_process_as_hello_retry_request(SSL_CONNECTION *s,
PACKET *extpkt)
{
RAW_EXTENSION *extensions = NULL;
const int version1_3 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION : TLS1_3_VERSION;
const int versionany = SSL_CONNECTION_IS_DTLS(s) ? DTLS_ANY_VERSION : TLS_ANY_VERSION;
const size_t msghdrlen = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_HM_HEADER_LENGTH
: SSL3_HM_HEADER_LENGTH;
/*
* If we were sending early_data then any alerts should not be sent using
* the old wrlmethod.
*/
if (s->early_data_state == SSL_EARLY_DATA_FINISHED_WRITING
&& !ssl_set_new_record_layer(s,
TLS_ANY_VERSION,
&& !ssl_set_new_record_layer(s, versionany,
OSSL_RECORD_DIRECTION_WRITE,
OSSL_RECORD_PROTECTION_LEVEL_NONE,
NULL, 0, NULL, 0, NULL, 0, NULL, 0,
NULL, 0, NID_undef, NULL, NULL, NULL)) {
NULL, 0, NULL, NULL, 0, NULL, 0, NULL,
0, NULL, 0, NULL, 0, NID_undef, NULL,
NULL, NULL)) {
/* SSLfatal already called */
goto err;
}
/* We are definitely going to be using TLSv1.3 */
s->rlayer.wrlmethod->set_protocol_version(s->rlayer.wrl, TLS1_3_VERSION);
/* We are definitely going to be using (D)TLSv1.3 */
if (!s->rlayer.wrlmethod->set_protocol_version(s->rlayer.wrl, version1_3)) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
goto err;
}
if (!tls_collect_extensions(s, extpkt, SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST,
&extensions, NULL, 1)
@ -1874,7 +1900,7 @@ static MSG_PROCESS_RETURN tls_process_as_hello_retry_request(SSL_CONNECTION *s,
* for HRR messages.
*/
if (!ssl3_finish_mac(s, (unsigned char *)s->init_buf->data,
s->init_num + SSL3_HM_HEADER_LENGTH)) {
s->init_num + msghdrlen)) {
/* SSLfatal() already called */
goto err;
}
@ -1934,7 +1960,7 @@ static WORK_STATE tls_post_process_server_rpk(SSL_CONNECTION *sc,
* skip check since TLS 1.3 ciphersuites can be used with any certificate
* type.
*/
if (!SSL_CONNECTION_IS_TLS13(sc)) {
if (!SSL_CONNECTION_IS_VERSION13(sc)) {
if ((clu->amask & sc->s3.tmp.new_cipher->algorithm_auth) == 0) {
SSLfatal(sc, SSL_AD_ILLEGAL_PARAMETER, SSL_R_WRONG_RPK_TYPE);
return WORK_ERROR;
@ -1949,7 +1975,7 @@ static WORK_STATE tls_post_process_server_rpk(SSL_CONNECTION *sc,
sc->session->verify_result = sc->verify_result;
/* Save the current hash state for when we receive the CertificateVerify */
if (SSL_CONNECTION_IS_TLS13(sc)
if (SSL_CONNECTION_IS_VERSION13(sc)
&& !ssl_handshake_hash(sc, sc->cert_verify_hash,
sizeof(sc->cert_verify_hash),
&sc->cert_verify_hash_len)) {
@ -1984,7 +2010,7 @@ MSG_PROCESS_RETURN tls_process_server_certificate(SSL_CONNECTION *s,
goto err;
}
if ((SSL_CONNECTION_IS_TLS13(s) && !PACKET_get_1(pkt, &context))
if ((SSL_CONNECTION_IS_VERSION13(s) && !PACKET_get_1(pkt, &context))
|| context != 0
|| !PACKET_get_net_3(pkt, &cert_list_len)
|| PACKET_remaining(pkt) != cert_list_len
@ -2016,7 +2042,7 @@ MSG_PROCESS_RETURN tls_process_server_certificate(SSL_CONNECTION *s,
goto err;
}
if (SSL_CONNECTION_IS_TLS13(s)) {
if (SSL_CONNECTION_IS_VERSION13(s)) {
RAW_EXTENSION *rawexts = NULL;
PACKET extensions;
@ -2120,7 +2146,7 @@ WORK_STATE tls_post_process_server_certificate(SSL_CONNECTION *s,
* skip check since TLS 1.3 ciphersuites can be used with any certificate
* type.
*/
if (!SSL_CONNECTION_IS_TLS13(s)) {
if (!SSL_CONNECTION_IS_VERSION13(s)) {
if ((clu->amask & s->s3.tmp.new_cipher->algorithm_auth) == 0) {
SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_WRONG_CERTIFICATE_TYPE);
return WORK_ERROR;
@ -2136,7 +2162,7 @@ WORK_STATE tls_post_process_server_certificate(SSL_CONNECTION *s,
s->session->peer_rpk = NULL;
/* Save the current hash state for when we receive the CertificateVerify */
if (SSL_CONNECTION_IS_TLS13(s)
if (SSL_CONNECTION_IS_VERSION13(s)
&& !ssl_handshake_hash(s, s->cert_verify_hash,
sizeof(s->cert_verify_hash),
&s->cert_verify_hash_len)) {
@ -2570,7 +2596,7 @@ MSG_PROCESS_RETURN tls_process_certificate_request(SSL_CONNECTION *s,
if (s->s3.tmp.valid_flags == NULL)
return 0;
if (SSL_CONNECTION_IS_TLS13(s)) {
if (SSL_CONNECTION_IS_VERSION13(s)) {
PACKET reqctx, extensions;
RAW_EXTENSION *rawexts = NULL;
@ -2675,7 +2701,7 @@ MSG_PROCESS_RETURN tls_process_certificate_request(SSL_CONNECTION *s,
* SSL_get1_peer_certificate() returns something sensible in
* client_cert_cb.
*/
if (SSL_CONNECTION_IS_TLS13(s)
if (SSL_CONNECTION_IS_VERSION13(s)
&& s->post_handshake_auth != SSL_PHA_REQUESTED)
return MSG_PROCESS_CONTINUE_READING;
@ -2696,11 +2722,11 @@ MSG_PROCESS_RETURN tls_process_new_session_ticket(SSL_CONNECTION *s,
PACKET_null_init(&nonce);
if (!PACKET_get_net_4(pkt, &ticket_lifetime_hint)
|| (SSL_CONNECTION_IS_TLS13(s)
|| (SSL_CONNECTION_IS_VERSION13(s)
&& (!PACKET_get_net_4(pkt, &age_add)
|| !PACKET_get_length_prefixed_1(pkt, &nonce)))
|| !PACKET_get_net_2(pkt, &ticklen)
|| (SSL_CONNECTION_IS_TLS13(s) ? (ticklen == 0
|| (SSL_CONNECTION_IS_VERSION13(s) ? (ticklen == 0
|| PACKET_remaining(pkt) < ticklen)
: PACKET_remaining(pkt) != ticklen)) {
SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH);
@ -2723,7 +2749,7 @@ MSG_PROCESS_RETURN tls_process_new_session_ticket(SSL_CONNECTION *s,
* post-handshake and the session may have already gone into the session
* cache.
*/
if (SSL_CONNECTION_IS_TLS13(s) || s->session->session_id_length > 0) {
if (SSL_CONNECTION_IS_VERSION13(s) || s->session->session_id_length > 0) {
SSL_SESSION *new_sess;
/*
@ -2736,7 +2762,7 @@ MSG_PROCESS_RETURN tls_process_new_session_ticket(SSL_CONNECTION *s,
}
if ((s->session_ctx->session_cache_mode & SSL_SESS_CACHE_CLIENT) != 0
&& !SSL_CONNECTION_IS_TLS13(s)) {
&& !SSL_CONNECTION_IS_VERSION13(s)) {
/*
* In TLSv1.2 and below the arrival of a new tickets signals that
* any old ticket we were using is now out of date, so we remove the
@ -2770,7 +2796,7 @@ MSG_PROCESS_RETURN tls_process_new_session_ticket(SSL_CONNECTION *s,
s->session->ext.tick_age_add = age_add;
s->session->ext.ticklen = ticklen;
if (SSL_CONNECTION_IS_TLS13(s)) {
if (SSL_CONNECTION_IS_VERSION13(s)) {
PACKET extpkt;
if (!PACKET_as_length_prefixed_2(pkt, &extpkt)
@ -2823,7 +2849,7 @@ MSG_PROCESS_RETURN tls_process_new_session_ticket(SSL_CONNECTION *s,
s->session->not_resumable = 0;
/* This is a standalone message in TLSv1.3, so there is no more to read */
if (SSL_CONNECTION_IS_TLS13(s)) {
if (SSL_CONNECTION_IS_VERSION13(s)) {
const EVP_MD *md = ssl_handshake_md(s);
int hashleni = EVP_MD_get_size(md);
size_t hashlen;
@ -3609,7 +3635,12 @@ int tls_client_key_exchange_post_work(SSL_CONNECTION *s)
pmslen = 0;
#ifndef OPENSSL_NO_SCTP
if (SSL_CONNECTION_IS_DTLS(s)) {
/*
* Before exporting the SCTP auth key we check if DTLSv1.3 has been negotiated
* which is not supported.
* Refer to draft-tuexen-tsvwg-rfc6083-bis-04 for more info.
*/
if (SSL_CONNECTION_IS_DTLS(s) && !SSL_CONNECTION_IS_DTLS13(s)) {
unsigned char sctpauthkey[64];
char labelbuffer[sizeof(DTLS1_SCTP_AUTH_LABEL)];
size_t labellen;
@ -3739,7 +3770,7 @@ WORK_STATE tls_prepare_client_certificate(SSL_CONNECTION *s, WORK_STATE wst)
}
}
if (!SSL_CONNECTION_IS_TLS13(s)
if (!SSL_CONNECTION_IS_VERSION13(s)
|| (s->options & SSL_OP_NO_TX_CERTIFICATE_COMPRESSION) != 0)
s->ext.compress_certificate_from_peer[0] = TLSEXT_comp_cert_none;
@ -3759,7 +3790,7 @@ CON_FUNC_RETURN tls_construct_client_certificate(SSL_CONNECTION *s,
CERT_PKEY *cpk = NULL;
SSL *ssl = SSL_CONNECTION_GET_SSL(s);
if (SSL_CONNECTION_IS_TLS13(s)) {
if (SSL_CONNECTION_IS_VERSION13(s)) {
if (s->pha_context == NULL) {
/* no context available, add 0-length context */
if (!WPACKET_put_bytes_u8(pkt, 0)) {
@ -3796,10 +3827,10 @@ CON_FUNC_RETURN tls_construct_client_certificate(SSL_CONNECTION *s,
* then we deferred changing the handshake write keys to the last possible
* moment. We need to do it now.
*/
if (SSL_CONNECTION_IS_TLS13(s)
if (SSL_CONNECTION_IS_VERSION13(s)
&& SSL_IS_FIRST_HANDSHAKE(s)
&& (s->early_data_state != SSL_EARLY_DATA_NONE
|| (s->options & SSL_OP_ENABLE_MIDDLEBOX_COMPAT) != 0)
|| SSL_CONNECTION_MIDDLEBOX_IS_ENABLED(s))
&& (!ssl->method->ssl3_enc->change_cipher_state(s,
SSL3_CC_HANDSHAKE | SSL3_CHANGE_CIPHER_CLIENT_WRITE))) {
/*
@ -4121,7 +4152,8 @@ int ssl_cipher_list_to_bytes(SSL_CONNECTION *s, STACK_OF(SSL_CIPHER) *sk,
int minproto = SSL_CONNECTION_IS_DTLS(s) ? c->min_dtls : c->min_tls;
int maxproto = SSL_CONNECTION_IS_DTLS(s) ? c->max_dtls : c->max_tls;
if (ssl_version_cmp(s, maxproto, s->s3.tmp.max_ver) >= 0
if (maxproto > 0 && minproto > 0
&& ssl_version_cmp(s, maxproto, s->s3.tmp.max_ver) >= 0
&& ssl_version_cmp(s, minproto, s->s3.tmp.max_ver) <= 0)
maxverok = 1;
}

File diff suppressed because it is too large Load diff

View file

@ -130,7 +130,7 @@ int tls_close_construct_packet(SSL_CONNECTION *s, WPACKET *pkt, int htype)
|| !WPACKET_get_length(pkt, &msglen)
|| msglen > INT_MAX)
return 0;
s->init_num = (int)msglen;
s->init_num = msglen;
s->init_off = 0;
return 1;
@ -157,12 +157,13 @@ int tls_setup_handshake(SSL_CONNECTION *s)
/* Sanity check that we have MD5-SHA1 if we need it */
if (sctx->ssl_digest_methods[SSL_MD_MD5_SHA1_IDX] == NULL) {
int negotiated_minversion;
int md5sha1_needed_maxversion = SSL_CONNECTION_IS_DTLS(s)
? DTLS1_VERSION : TLS1_1_VERSION;
const int version1_2 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_2_VERSION
: TLS1_2_VERSION;
const int version1_1 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_VERSION
: TLS1_1_VERSION;
/* We don't have MD5-SHA1 - do we need it? */
if (ssl_version_cmp(s, ver_max, md5sha1_needed_maxversion) <= 0) {
if (ssl_version_cmp(s, ver_max, version1_1) <= 0) {
SSLfatal_data(s, SSL_AD_HANDSHAKE_FAILURE,
SSL_R_NO_SUITABLE_DIGEST_ALGORITHM,
"The max supported SSL/TLS version needs the"
@ -175,10 +176,8 @@ int tls_setup_handshake(SSL_CONNECTION *s)
ok = 1;
/* Don't allow TLSv1.1 or below to be negotiated */
negotiated_minversion = SSL_CONNECTION_IS_DTLS(s) ?
DTLS1_2_VERSION : TLS1_2_VERSION;
if (ssl_version_cmp(s, ver_min, negotiated_minversion) < 0)
ok = SSL_set_min_proto_version(ssl, negotiated_minversion);
if (ssl_version_cmp(s, ver_min, version1_2) < 0)
ok = SSL_set_min_proto_version(ssl, version1_2);
if (!ok) {
/* Shouldn't happen */
SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, ERR_R_INTERNAL_ERROR);
@ -203,7 +202,8 @@ int tls_setup_handshake(SSL_CONNECTION *s)
int cipher_maxprotover = SSL_CONNECTION_IS_DTLS(s)
? c->max_dtls : c->max_tls;
if (ssl_version_cmp(s, ver_max, cipher_minprotover) >= 0
if (cipher_minprotover > 0 && cipher_maxprotover > 0
&& ssl_version_cmp(s, ver_max, cipher_minprotover) >= 0
&& ssl_version_cmp(s, ver_max, cipher_maxprotover) <= 0) {
ok = 1;
break;
@ -262,7 +262,7 @@ static int get_cert_verify_tbs_data(SSL_CONNECTION *s, unsigned char *tls13tbs,
static const char clientcontext[] = "\x54\x4c\x53\x20\x31\x2e\x33\x2c\x20\x63\x6c\x69"
"\x65\x6e\x74\x20\x43\x65\x72\x74\x69\x66\x69\x63\x61\x74\x65\x56\x65\x72\x69\x66\x79";
if (SSL_CONNECTION_IS_TLS13(s)) {
if (SSL_CONNECTION_IS_VERSION13(s)) {
size_t hashlen;
/* Set the first 64 bytes of to-be-signed data to octet 32 */
@ -585,14 +585,14 @@ MSG_PROCESS_RETURN tls_process_cert_verify(SSL_CONNECTION *s, PACKET *pkt)
}
/*
* In TLSv1.3 on the client side we make sure we prepare the client
* In (D)TLSv1.3 on the client side we make sure we prepare the client
* certificate after the CertVerify instead of when we get the
* CertificateRequest. This is because in TLSv1.3 the CertificateRequest
* comes *before* the Certificate message. In TLSv1.2 it comes after. We
* CertificateRequest. This is because in (D)TLSv1.3 the CertificateRequest
* comes *before* the Certificate message. In (D)TLSv1.2 it comes after. We
* want to make sure that SSL_get1_peer_certificate() will return the actual
* server certificate from the client_cert_cb callback.
*/
if (!s->server && SSL_CONNECTION_IS_TLS13(s) && s->s3.tmp.cert_req == 1)
if (!s->server && SSL_CONNECTION_IS_VERSION13(s) && s->s3.tmp.cert_req == 1)
ret = MSG_PROCESS_CONTINUE_PROCESSING;
else
ret = MSG_PROCESS_CONTINUE_READING;
@ -623,10 +623,10 @@ CON_FUNC_RETURN tls_construct_finished(SSL_CONNECTION *s, WPACKET *pkt)
* moment. If we didn't already do this when we sent the client certificate
* then we need to do it now.
*/
if (SSL_CONNECTION_IS_TLS13(s)
if (SSL_CONNECTION_IS_VERSION13(s)
&& !s->server
&& (s->early_data_state != SSL_EARLY_DATA_NONE
|| (s->options & SSL_OP_ENABLE_MIDDLEBOX_COMPAT) != 0)
|| SSL_CONNECTION_MIDDLEBOX_IS_ENABLED(s))
&& s->s3.tmp.cert_req == 0
&& (!ssl->method->ssl3_enc->change_cipher_state(s,
SSL3_CC_HANDSHAKE | SSL3_CHANGE_CIPHER_CLIENT_WRITE))) {;
@ -659,9 +659,9 @@ CON_FUNC_RETURN tls_construct_finished(SSL_CONNECTION *s, WPACKET *pkt)
/*
* Log the master secret, if logging is enabled. We don't log it for
* TLSv1.3: there's a different key schedule for that.
* (D)TLSv1.3: there's a different key schedule for that.
*/
if (!SSL_CONNECTION_IS_TLS13(s)
if (!SSL_CONNECTION_IS_VERSION13(s)
&& !ssl_log_secret(s, MASTER_SECRET_LABEL, s->session->master_key,
s->session->master_key_length)) {
/* SSLfatal() already called */
@ -843,13 +843,13 @@ MSG_PROCESS_RETURN tls_process_finished(SSL_CONNECTION *s, PACKET *pkt)
/*
* To get this far we must have read encrypted data from the client. We
* no longer tolerate unencrypted alerts. This is ignored if less than
* TLSv1.3
* (D)TLSv1.3
*/
if (s->rlayer.rrlmethod->set_plain_alerts != NULL)
s->rlayer.rrlmethod->set_plain_alerts(s->rlayer.rrl, 0);
if (s->post_handshake_auth != SSL_PHA_REQUESTED)
s->statem.cleanuphand = 1;
if (SSL_CONNECTION_IS_TLS13(s)
if (SSL_CONNECTION_IS_VERSION13(s)
&& !tls13_save_handshake_digest_for_pha(s)) {
/* SSLfatal() already called */
return MSG_PROCESS_ERROR;
@ -860,14 +860,14 @@ MSG_PROCESS_RETURN tls_process_finished(SSL_CONNECTION *s, PACKET *pkt)
* In TLSv1.3 a Finished message signals a key change so the end of the
* message must be on a record boundary.
*/
if (SSL_CONNECTION_IS_TLS13(s)
if (SSL_CONNECTION_IS_VERSION13(s)
&& RECORD_LAYER_processed_read_pending(&s->rlayer)) {
SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_NOT_ON_RECORD_BOUNDARY);
return MSG_PROCESS_ERROR;
}
/* If this occurs, we have missed a message */
if (!SSL_CONNECTION_IS_TLS13(s) && !s->s3.change_cipher_spec) {
if (!SSL_CONNECTION_IS_VERSION13(s) && !s->s3.change_cipher_spec) {
SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_GOT_A_FIN_BEFORE_A_CCS);
return MSG_PROCESS_ERROR;
}
@ -915,7 +915,7 @@ MSG_PROCESS_RETURN tls_process_finished(SSL_CONNECTION *s, PACKET *pkt)
* In TLS1.3 we also have to change cipher state and do any final processing
* of the initial server flight (if we are a client)
*/
if (SSL_CONNECTION_IS_TLS13(s)) {
if (SSL_CONNECTION_IS_VERSION13(s)) {
if (s->server) {
if (s->post_handshake_auth != SSL_PHA_REQUESTED &&
!ssl->method->ssl3_enc->change_cipher_state(s,
@ -924,7 +924,7 @@ MSG_PROCESS_RETURN tls_process_finished(SSL_CONNECTION *s, PACKET *pkt)
return MSG_PROCESS_ERROR;
}
} else {
/* TLS 1.3 gets the secret size from the handshake md */
/* (D)TLS 1.3 gets the secret size from the handshake md */
size_t dummy;
if (!ssl->method->ssl3_enc->generate_master_secret(s,
s->master_secret, s->handshake_secret, 0,
@ -986,7 +986,7 @@ static int ssl_add_cert_to_wpacket(SSL_CONNECTION *s, WPACKET *pkt,
return 0;
}
if ((SSL_CONNECTION_IS_TLS13(s) || for_comp)
if ((SSL_CONNECTION_IS_VERSION13(s) || for_comp)
&& !tls_construct_extensions(s, pkt, context, x, chain)) {
/* SSLfatal() already called */
return 0;
@ -1118,7 +1118,7 @@ int tls_process_rpk(SSL_CONNECTION *sc, PACKET *pkt, EVP_PKEY **peer_rpk)
/*-
* ----------------------------
* TLS 1.3 Certificate message:
* (D)TLS 1.3 Certificate message:
* ----------------------------
* https://datatracker.ietf.org/doc/html/rfc8446#section-4.4.2
*
@ -1178,21 +1178,21 @@ int tls_process_rpk(SSL_CONNECTION *sc, PACKET *pkt, EVP_PKEY **peer_rpk)
* -------------
* Consequently:
* -------------
* After the (TLS 1.3 only) context octet string (1 byte length + data) the
* After the ((D)TLS 1.3 only) context octet string (1 byte length + data) the
* Certificate message has a 3-byte length that is zero in the client to
* server message when the client has no RPK to send. In that case, there
* are no (TLS 1.3 only) per-certificate extensions either, because the
* are no ((D)TLS 1.3 only) per-certificate extensions either, because the
* [CertificateEntry] list is empty.
*
* In the server to client direction, or when the client had an RPK to send,
* the TLS 1.3 message just prepends the length of the RPK+extensions,
* the (D)TLS 1.3 message just prepends the length of the RPK+extensions,
* while TLS <= 1.2 sends just the RPK (octet-string).
*
* The context must be zero-length in the server to client direction, and
* must match the value recorded in the certificate request in the client
* to server direction.
*/
if (SSL_CONNECTION_IS_TLS13(sc)) {
if (SSL_CONNECTION_IS_VERSION13(sc)) {
if (!PACKET_get_length_prefixed_1(pkt, &context)) {
SSLfatal(sc, SSL_AD_DECODE_ERROR, SSL_R_INVALID_CONTEXT);
goto err;
@ -1234,7 +1234,7 @@ int tls_process_rpk(SSL_CONNECTION *sc, PACKET *pkt, EVP_PKEY **peer_rpk)
if (cert_len == 0)
return 1;
if (SSL_CONNECTION_IS_TLS13(sc)) {
if (SSL_CONNECTION_IS_VERSION13(sc)) {
/*
* With TLS 1.3, a non-empty explicit-length RPK octet-string followed
* by a possibly empty extension block.
@ -1269,7 +1269,7 @@ int tls_process_rpk(SSL_CONNECTION *sc, PACKET *pkt, EVP_PKEY **peer_rpk)
}
/* Process the Extensions block */
if (SSL_CONNECTION_IS_TLS13(sc)) {
if (SSL_CONNECTION_IS_VERSION13(sc)) {
if (PACKET_remaining(pkt) != (cert_len - 3 - spki_len)) {
SSLfatal(sc, SSL_AD_DECODE_ERROR, SSL_R_BAD_LENGTH);
goto err;
@ -1346,7 +1346,7 @@ unsigned long tls_output_rpk(SSL_CONNECTION *sc, WPACKET *pkt, CERT_PKEY *cpk)
* TLSv1.2 is _just_ the raw public key
* TLSv1.3 includes extensions, so there's a length wrapper
*/
if (SSL_CONNECTION_IS_TLS13(sc)) {
if (SSL_CONNECTION_IS_VERSION13(sc)) {
if (!WPACKET_start_sub_packet_u24(pkt)) {
SSLfatal(sc, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
goto err;
@ -1358,7 +1358,7 @@ unsigned long tls_output_rpk(SSL_CONNECTION *sc, WPACKET *pkt, CERT_PKEY *cpk)
goto err;
}
if (SSL_CONNECTION_IS_TLS13(sc)) {
if (SSL_CONNECTION_IS_VERSION13(sc)) {
/*
* Only send extensions relevant to raw public keys. Until such
* extensions are defined, this will be an empty set of extensions.
@ -1442,7 +1442,7 @@ WORK_STATE tls_finish_handshake(SSL_CONNECTION *s, ossl_unused WORK_STATE wst,
s->init_num = 0;
}
if (SSL_CONNECTION_IS_TLS13(s) && !s->server
if (SSL_CONNECTION_IS_VERSION13(s) && !s->server
&& s->post_handshake_auth == SSL_PHA_REQUESTED)
s->post_handshake_auth = SSL_PHA_EXT_SENT;
@ -1464,14 +1464,14 @@ WORK_STATE tls_finish_handshake(SSL_CONNECTION *s, ossl_unused WORK_STATE wst,
* In TLSv1.3 we update the cache as part of constructing the
* NewSessionTicket
*/
if (!SSL_CONNECTION_IS_TLS13(s))
if (!SSL_CONNECTION_IS_VERSION13(s))
ssl_update_cache(s, SSL_SESS_CACHE_SERVER);
/* N.B. s->ctx may not equal s->session_ctx */
ssl_tsan_counter(sctx, &sctx->stats.sess_accept_good);
s->handshake_func = ossl_statem_accept;
} else {
if (SSL_CONNECTION_IS_TLS13(s)) {
if (SSL_CONNECTION_IS_VERSION13(s)) {
/*
* We encourage applications to only use TLSv1.3 tickets once,
* so we remove this one from the cache.
@ -1514,7 +1514,7 @@ WORK_STATE tls_finish_handshake(SSL_CONNECTION *s, ossl_unused WORK_STATE wst,
if (cb != NULL) {
if (cleanuphand
|| !SSL_CONNECTION_IS_TLS13(s)
|| !SSL_CONNECTION_IS_VERSION13(s)
|| SSL_IS_FIRST_HANDSHAKE(s))
cb(ssl, SSL_CB_HANDSHAKE_DONE, 1);
}
@ -1639,6 +1639,55 @@ int tls_get_message_header(SSL_CONNECTION *s, int *mt)
return 1;
}
int tls_common_finish_mac(SSL_CONNECTION *s) {
unsigned char *msg = (unsigned char *)s->init_buf->data;
size_t msg_len = s->init_num;
size_t hdr_len = 0;
if (SSL_CONNECTION_IS_DTLS(s)) {
if (s->version != DTLS1_BAD_VER)
hdr_len = DTLS1_HM_HEADER_LENGTH;
else
msg += DTLS1_HM_HEADER_LENGTH;
} else if (!RECORD_LAYER_is_sslv2_record(&s->rlayer)) {
hdr_len = SSL3_HM_HEADER_LENGTH;
}
msg_len += hdr_len;
/* Feed this message into MAC computation. */
if (RECORD_LAYER_is_sslv2_record(&s->rlayer)
&& !ssl3_finish_mac(s, msg, msg_len)) {
/* SSLfatal() already called */
return 0;
} else {
/*
* We defer feeding in the HRR until later. We'll do it as part of
* the message processing.
* The (D)TLSv1.3 handshake transcript stops at the ClientFinished
* message.
*/
const size_t srvhellorandom_offs = hdr_len + 2;
/* KeyUpdate and NewSessionTicket do not need to be added */
if (!SSL_CONNECTION_IS_VERSION13(s)
|| (s->s3.tmp.message_type != SSL3_MT_NEWSESSION_TICKET
&& s->s3.tmp.message_type != SSL3_MT_KEY_UPDATE)) {
if (s->s3.tmp.message_type != SSL3_MT_SERVER_HELLO
|| s->init_num < srvhellorandom_offs + SSL3_RANDOM_SIZE
|| memcmp(hrrrandom,
s->init_buf->data + srvhellorandom_offs,
SSL3_RANDOM_SIZE) != 0) {
if (!ssl3_finish_mac(s, msg, msg_len))
/* SSLfatal() already called */
return 0;
}
}
}
return 1;
}
int tls_get_message_body(SSL_CONNECTION *s, size_t *len)
{
size_t n, readbytes;
@ -1677,45 +1726,20 @@ int tls_get_message_body(SSL_CONNECTION *s, size_t *len)
return 0;
}
/* Feed this message into MAC computation. */
if (RECORD_LAYER_is_sslv2_record(&s->rlayer)) {
if (!ssl3_finish_mac(s, (unsigned char *)s->init_buf->data,
s->init_num)) {
if (!tls_common_finish_mac(s)) {
/* SSLfatal() already called */
*len = 0;
return 0;
}
if (RECORD_LAYER_is_sslv2_record(&s->rlayer)) {
if (s->msg_callback)
s->msg_callback(0, SSL2_VERSION, 0, s->init_buf->data,
(size_t)s->init_num, ussl, s->msg_callback_arg);
s->init_num, ussl, s->msg_callback_arg);
} else {
/*
* We defer feeding in the HRR until later. We'll do it as part of
* processing the message
* The TLsv1.3 handshake transcript stops at the ClientFinished
* message.
*/
#define SERVER_HELLO_RANDOM_OFFSET (SSL3_HM_HEADER_LENGTH + 2)
/* KeyUpdate and NewSessionTicket do not need to be added */
if (!SSL_CONNECTION_IS_TLS13(s)
|| (s->s3.tmp.message_type != SSL3_MT_NEWSESSION_TICKET
&& s->s3.tmp.message_type != SSL3_MT_KEY_UPDATE)) {
if (s->s3.tmp.message_type != SSL3_MT_SERVER_HELLO
|| s->init_num < SERVER_HELLO_RANDOM_OFFSET + SSL3_RANDOM_SIZE
|| memcmp(hrrrandom,
s->init_buf->data + SERVER_HELLO_RANDOM_OFFSET,
SSL3_RANDOM_SIZE) != 0) {
if (!ssl3_finish_mac(s, (unsigned char *)s->init_buf->data,
s->init_num + SSL3_HM_HEADER_LENGTH)) {
/* SSLfatal() already called */
*len = 0;
return 0;
}
}
}
if (s->msg_callback)
s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, s->init_buf->data,
(size_t)s->init_num + SSL3_HM_HEADER_LENGTH, ussl,
s->init_num + SSL3_HM_HEADER_LENGTH, ussl,
s->msg_callback_arg);
}
@ -1798,11 +1822,7 @@ int ssl_version_cmp(const SSL_CONNECTION *s, int versiona, int versionb)
{
int dtls = SSL_CONNECTION_IS_DTLS(s);
if (versiona == versionb)
return 0;
if (!dtls)
return versiona < versionb ? -1 : 1;
return DTLS_VERSION_LT(versiona, versionb) ? -1 : 1;
return PROTOCOL_VERSION_CMP(dtls, versiona, versionb);
}
typedef struct {
@ -1845,12 +1865,13 @@ static const version_info tls_version_table[] = {
{0, NULL, NULL},
};
#if DTLS_MAX_VERSION_INTERNAL != DTLS1_2_VERSION
# error Code needs update for DTLS_method() support beyond DTLS1_2_VERSION.
#if DTLS_MAX_VERSION_INTERNAL != DTLS1_3_VERSION
# error Code needs update for DTLS_method() support beyond DTLS1_3_VERSION.
#endif
/* Must be in order high to low */
static const version_info dtls_version_table[] = {
{DTLS1_3_VERSION, dtlsv1_3_client_method, dtlsv1_3_server_method},
#ifndef OPENSSL_NO_DTLS1_2
{DTLS1_2_VERSION, dtlsv1_2_client_method, dtlsv1_2_server_method},
#else
@ -1991,7 +2012,7 @@ int ssl_version_supported(const SSL_CONNECTION *s, int version,
&& ssl_version_cmp(s, version, vent->version) == 0
&& ssl_method_error(s, thismeth()) == 0
&& (!s->server
|| version != TLS1_3_VERSION
|| (version != TLS1_3_VERSION && version != DTLS1_3_VERSION)
|| is_tls13_capable(s))) {
if (meth != NULL)
*meth = thismeth();
@ -2109,23 +2130,27 @@ int ssl_set_version_bound(int method_version, int version, int *bound)
static void check_for_downgrade(SSL_CONNECTION *s, int vers, DOWNGRADE *dgrd)
{
if (vers == TLS1_2_VERSION
&& ssl_version_supported(s, TLS1_3_VERSION, NULL)) {
int version12 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_2_VERSION : TLS1_2_VERSION;
int version13 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION : TLS1_3_VERSION;
if (vers == version12 && ssl_version_supported(s, version13, NULL)) {
*dgrd = DOWNGRADE_TO_1_2;
} else if (!SSL_CONNECTION_IS_DTLS(s)
&& vers < TLS1_2_VERSION
} else if (ssl_version_cmp(s, vers, version12) < 0
/*
* We need to ensure that a server that disables TLSv1.2
* (creating a hole between TLSv1.3 and TLSv1.1) can still
* complete handshakes with clients that support TLSv1.2 and
* below. Therefore we do not enable the sentinel if TLSv1.3 is
* enabled and TLSv1.2 is not.
* We need to ensure that a server that disables (D)TLSv1.2
* (creating a hole between (D)TLSv1.3 and (D)TLSv1.1) can still
* complete handshakes with clients that support (D)TLSv1.2 and
* below. Therefore we do not enable the sentinel if (D)TLSv1.3 is
* enabled and (D)TLSv1.2 is not.
*/
&& ssl_version_supported(s, TLS1_2_VERSION, NULL)) {
&& ssl_version_supported(s, version12, NULL)) {
*dgrd = DOWNGRADE_TO_1_1;
} else {
*dgrd = DOWNGRADE_NONE;
}
if (SSL_CONNECTION_IS_DTLS(s))
s->d1->downgrade_after_hvr = *dgrd;
}
/*
@ -2156,15 +2181,35 @@ int ssl_choose_server_version(SSL_CONNECTION *s, CLIENTHELLO_MSG *hello,
const version_info *table;
int disabled = 0;
RAW_EXTENSION *suppversions;
const int version1_3 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION
: TLS1_3_VERSION;
const int version1_2 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_2_VERSION
: TLS1_2_VERSION;
if (client_version <= 0)
return SSL_R_WRONG_SSL_VERSION;
s->client_version = client_version;
switch (server_version) {
default:
if (!SSL_CONNECTION_IS_TLS13(s)) {
if (!SSL_CONNECTION_IS_VERSION13(s)) {
if (ssl_version_cmp(s, client_version, s->version) < 0)
return SSL_R_WRONG_SSL_VERSION;
/*
* The downgrade sentinel is selected when parsing the first
* ClientHello. If this server has sent a HelloVerifyRequest, the
* sentinel is recovered while parsing the second ClientHello in
* order to apply it to the ServerHello random value.
*/
if (SSL_CONNECTION_IS_DTLS(s)
&& s->d1->hello_verify_request != SSL_HVR_NONE) {
*dgrd = s->d1->downgrade_after_hvr;
} else {
*dgrd = DOWNGRADE_NONE;
}
/*
* If this SSL handle is not from a version flexible method we don't
* (and never did) check min/max FIPS or Suite B constraints. Hope
@ -2193,9 +2238,11 @@ int ssl_choose_server_version(SSL_CONNECTION *s, CLIENTHELLO_MSG *hello,
if (!suppversions->present && s->hello_retry_request != SSL_HRR_NONE)
return SSL_R_UNSUPPORTED_PROTOCOL;
if (suppversions->present && !SSL_CONNECTION_IS_DTLS(s)) {
unsigned int candidate_vers = 0;
unsigned int best_vers = 0;
if (suppversions->present) {
int candidate_vers = 0;
const int best_vers_init = SSL_CONNECTION_IS_DTLS(s) ? INT_MAX
: 0;
int best_vers = best_vers_init;
const SSL_METHOD *best_method = NULL;
PACKET versionslist;
@ -2218,8 +2265,10 @@ int ssl_choose_server_version(SSL_CONNECTION *s, CLIENTHELLO_MSG *hello,
if (client_version <= SSL3_VERSION)
return SSL_R_BAD_LEGACY_VERSION;
while (PACKET_get_net_2(&versionslist, &candidate_vers)) {
if (ssl_version_cmp(s, candidate_vers, best_vers) <= 0)
while (PACKET_get_net_2(&versionslist, (unsigned int*)&candidate_vers)) {
if (candidate_vers <= 0
|| (best_vers != best_vers_init
&& ssl_version_cmp(s, candidate_vers, best_vers) <= 0))
continue;
if (ssl_version_supported(s, candidate_vers, &best_method))
best_vers = candidate_vers;
@ -2229,13 +2278,14 @@ int ssl_choose_server_version(SSL_CONNECTION *s, CLIENTHELLO_MSG *hello,
return SSL_R_LENGTH_MISMATCH;
}
if (best_vers > 0) {
/* Did best_vers change from the initial value? */
if (best_vers != best_vers_init) {
if (s->hello_retry_request != SSL_HRR_NONE) {
/*
* This is after a HelloRetryRequest so we better check that we
* negotiated TLSv1.3
* negotiated (D)TLSv1.3
*/
if (best_vers != TLS1_3_VERSION)
if (best_vers != version1_3)
return SSL_R_UNSUPPORTED_PROTOCOL;
return 0;
}
@ -2252,10 +2302,10 @@ int ssl_choose_server_version(SSL_CONNECTION *s, CLIENTHELLO_MSG *hello,
/*
* If the supported versions extension isn't present, then the highest
* version we can negotiate is TLSv1.2
* version we can negotiate is (D)TLSv1.2
*/
if (ssl_version_cmp(s, client_version, TLS1_3_VERSION) >= 0)
client_version = TLS1_2_VERSION;
if (ssl_version_cmp(s, client_version, version1_3) >= 0)
client_version = version1_2;
/*
* No supported versions extension, so we just use the version supplied in
@ -2299,7 +2349,11 @@ int ssl_choose_client_version(SSL_CONNECTION *s, int version,
const version_info *vent;
const version_info *table;
int ret, ver_min, ver_max, real_max, origv;
const int version12 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_2_VERSION
: TLS1_2_VERSION;
SSL *ssl = SSL_CONNECTION_GET_SSL(s);
const int version1_3 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION
: TLS1_3_VERSION;
origv = s->version;
s->version = version;
@ -2313,8 +2367,7 @@ int ssl_choose_client_version(SSL_CONNECTION *s, int version,
return 0;
}
if (s->hello_retry_request != SSL_HRR_NONE
&& s->version != TLS1_3_VERSION) {
if (s->hello_retry_request != SSL_HRR_NONE && s->version != version1_3) {
s->version = origv;
SSLfatal(s, SSL_AD_PROTOCOL_VERSION, SSL_R_WRONG_SSL_VERSION);
return 0;
@ -2364,8 +2417,9 @@ int ssl_choose_client_version(SSL_CONNECTION *s, int version,
real_max = ver_max;
/* Check for downgrades */
if (s->version == TLS1_2_VERSION && real_max > s->version) {
if (memcmp(tls12downgrade,
if (s->version == version12
&& ssl_version_cmp(s, real_max, s->version) > 0
&& memcmp(tls12downgrade,
s->s3.server_random + SSL3_RANDOM_SIZE
- sizeof(tls12downgrade),
sizeof(tls12downgrade)) == 0) {
@ -2373,11 +2427,9 @@ int ssl_choose_client_version(SSL_CONNECTION *s, int version,
SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER,
SSL_R_INAPPROPRIATE_FALLBACK);
return 0;
}
} else if (!SSL_CONNECTION_IS_DTLS(s)
&& s->version < TLS1_2_VERSION
&& real_max > s->version) {
if (memcmp(tls11downgrade,
} else if (ssl_version_cmp(s, s->version, version12) < 0
&& ssl_version_cmp(s, real_max, s->version) > 0
&& memcmp(tls11downgrade,
s->s3.server_random + SSL3_RANDOM_SIZE
- sizeof(tls11downgrade),
sizeof(tls11downgrade)) == 0) {
@ -2386,7 +2438,6 @@ int ssl_choose_client_version(SSL_CONNECTION *s, int version,
SSL_R_INAPPROPRIATE_FALLBACK);
return 0;
}
}
for (vent = table; vent->version != 0; ++vent) {
if (vent->cmeth == NULL || s->version != vent->version)
@ -2535,6 +2586,7 @@ int ssl_get_min_max_version(const SSL_CONNECTION *s, int *min_version,
int ssl_set_client_hello_version(SSL_CONNECTION *s)
{
int ver_min, ver_max, ret;
const int version1_2 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_2_VERSION : TLS1_2_VERSION;
/*
* In a renegotiation we always send the same client_version that we sent
@ -2550,8 +2602,7 @@ int ssl_set_client_hello_version(SSL_CONNECTION *s)
s->version = ver_max;
if (SSL_CONNECTION_IS_DTLS(s)) {
if (ver_max == DTLS1_BAD_VER) {
if (SSL_CONNECTION_IS_DTLS(s) && ver_max == DTLS1_BAD_VER) {
/*
* Even though this is technically before version negotiation,
* because we have asked for DTLS1_BAD_VER we will never negotiate
@ -2561,10 +2612,9 @@ int ssl_set_client_hello_version(SSL_CONNECTION *s)
*/
if (!ssl_set_record_protocol_version(s, ver_max))
return 0;
}
} else if (ver_max > TLS1_2_VERSION) {
/* TLS1.3 always uses TLS1.2 in the legacy_version field */
ver_max = TLS1_2_VERSION;
} else if (ssl_version_cmp(s, ver_max, version1_2) > 0) {
/* (D)TLS1.3 always uses (D)TLS1.2 in the legacy_version field */
ver_max = version1_2;
}
s->client_version = ver_max;
@ -2604,21 +2654,27 @@ int create_synthetic_message_hash(SSL_CONNECTION *s,
size_t hashlen, const unsigned char *hrr,
size_t hrrlen)
{
unsigned char hashvaltmp[EVP_MAX_MD_SIZE];
unsigned char msghdr[SSL3_HM_HEADER_LENGTH];
unsigned char *hashvaltmp;
unsigned char synmsg[SSL3_HM_HEADER_LENGTH + EVP_MAX_MD_SIZE];
size_t currmsghdr_len = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_HM_HEADER_LENGTH
: SSL3_HM_HEADER_LENGTH;
memset(msghdr, 0, sizeof(msghdr));
memset(synmsg, 0, SSL3_HM_HEADER_LENGTH);
hashvaltmp = synmsg + SSL3_HM_HEADER_LENGTH;
if (hashval == NULL) {
hashval = hashvaltmp;
hashlen = 0;
/* Get the hash of the initial ClientHello */
if (!ssl3_digest_cached_records(s, 0)
|| !ssl_handshake_hash(s, hashvaltmp, sizeof(hashvaltmp),
|| !ssl_handshake_hash(s, hashvaltmp, EVP_MAX_MD_SIZE,
&hashlen)) {
/* SSLfatal() already called */
return 0;
}
} else {
if (!ossl_assert(hashlen <= EVP_MAX_MD_SIZE))
return 0;
memcpy(hashvaltmp, hashval, hashlen);
}
/* Reinitialise the transcript hash */
@ -2628,10 +2684,9 @@ int create_synthetic_message_hash(SSL_CONNECTION *s,
}
/* Inject the synthetic message_hash message */
msghdr[0] = SSL3_MT_MESSAGE_HASH;
msghdr[SSL3_HM_HEADER_LENGTH - 1] = (unsigned char)hashlen;
if (!ssl3_finish_mac(s, msghdr, SSL3_HM_HEADER_LENGTH)
|| !ssl3_finish_mac(s, hashval, hashlen)) {
synmsg[0] = SSL3_MT_MESSAGE_HASH;
synmsg[SSL3_HM_HEADER_LENGTH - 1] = (unsigned char)hashlen;
if (!ssl3_finish_mac(s, synmsg, SSL3_HM_HEADER_LENGTH + hashlen)) {
/* SSLfatal() already called */
return 0;
}
@ -2644,8 +2699,7 @@ int create_synthetic_message_hash(SSL_CONNECTION *s,
if (hrr != NULL
&& (!ssl3_finish_mac(s, hrr, hrrlen)
|| !ssl3_finish_mac(s, (unsigned char *)s->init_buf->data,
s->s3.tmp.message_size
+ SSL3_HM_HEADER_LENGTH))) {
s->s3.tmp.message_size + currmsghdr_len))) {
/* SSLfatal() already called */
return 0;
}

View file

@ -113,6 +113,7 @@ __owur int tls_get_message_header(SSL_CONNECTION *s, int *mt);
__owur int tls_get_message_body(SSL_CONNECTION *s, size_t *len);
__owur int dtls_get_message(SSL_CONNECTION *s, int *mt);
__owur int dtls_get_message_body(SSL_CONNECTION *s, size_t *len);
__owur int tls_common_finish_mac(SSL_CONNECTION *s);
/* Message construction and processing functions */
__owur int tls_process_initial_server_flight(SSL_CONNECTION *s);

View file

@ -183,7 +183,7 @@ int ossl_statem_server_read_transition(SSL_CONNECTION *s, int mt)
{
OSSL_STATEM *st = &s->statem;
if (SSL_CONNECTION_IS_TLS13(s)) {
if (SSL_CONNECTION_IS_VERSION13(s)) {
if (!ossl_statem_server13_read_transition(s, mt))
goto err;
return 1;
@ -418,7 +418,7 @@ int send_certificate_request(SSL_CONNECTION *s)
* don't request if post-handshake-only unless doing
* post-handshake in TLSv1.3:
*/
&& (!SSL_CONNECTION_IS_TLS13(s)
&& (!SSL_CONNECTION_IS_VERSION13(s)
|| !(s->verify_mode & SSL_VERIFY_POST_HANDSHAKE)
|| s->post_handshake_auth == SSL_PHA_REQUEST_PENDING)
/*
@ -500,7 +500,7 @@ static WRITE_TRAN ossl_statem_server13_write_transition(SSL_CONNECTION *s)
return WRITE_TRAN_CONTINUE;
case TLS_ST_SW_SRVR_HELLO:
if ((s->options & SSL_OP_ENABLE_MIDDLEBOX_COMPAT) != 0
if (SSL_CONNECTION_MIDDLEBOX_IS_ENABLED(s)
&& s->hello_retry_request != SSL_HRR_COMPLETE)
st->hand_state = TLS_ST_SW_CHANGE;
else if (s->hello_retry_request == SSL_HRR_PENDING)
@ -612,7 +612,7 @@ WRITE_TRAN ossl_statem_server_write_transition(SSL_CONNECTION *s)
* to negotiate yet, so we don't take this branch until later
*/
if (SSL_CONNECTION_IS_TLS13(s))
if (SSL_CONNECTION_IS_VERSION13(s))
return ossl_statem_server13_write_transition(s);
switch (st->hand_state) {
@ -644,7 +644,7 @@ WRITE_TRAN ossl_statem_server_write_transition(SSL_CONNECTION *s)
return WRITE_TRAN_CONTINUE;
case TLS_ST_SR_CLNT_HELLO:
if (SSL_CONNECTION_IS_DTLS(s) && !s->d1->cookie_verified
if (SSL_CONNECTION_IS_DTLS(s) && !SSL_CONNECTION_IS_DTLS13(s) && !s->d1->cookie_verified
&& (SSL_get_options(SSL_CONNECTION_GET_SSL(s)) & SSL_OP_COOKIE_EXCHANGE)) {
st->hand_state = DTLS_ST_SW_HELLO_VERIFY_REQUEST;
} else if (s->renegotiate == 0 && !SSL_IS_FIRST_HANDSHAKE(s)) {
@ -788,7 +788,7 @@ WORK_STATE ossl_statem_server_pre_work(SSL_CONNECTION *s, WORK_STATE wst)
return WORK_FINISHED_CONTINUE;
case TLS_ST_SW_SESSION_TICKET:
if (SSL_CONNECTION_IS_TLS13(s) && s->sent_tickets == 0
if (SSL_CONNECTION_IS_VERSION13(s) && s->sent_tickets == 0
&& s->ext.extra_tickets_expected == 0) {
/*
* Actually this is the end of the handshake, but we're going
@ -809,7 +809,7 @@ WORK_STATE ossl_statem_server_pre_work(SSL_CONNECTION *s, WORK_STATE wst)
break;
case TLS_ST_SW_CHANGE:
if (SSL_CONNECTION_IS_TLS13(s))
if (SSL_CONNECTION_IS_VERSION13(s))
break;
/* Writes to s->session are only safe for initial handshakes */
if (s->session->cipher == NULL) {
@ -908,15 +908,20 @@ WORK_STATE ossl_statem_server_post_work(SSL_CONNECTION *s, WORK_STATE wst)
break;
case TLS_ST_SW_SRVR_HELLO:
if (SSL_CONNECTION_IS_TLS13(s)
if (SSL_CONNECTION_IS_VERSION13(s)
&& s->hello_retry_request == SSL_HRR_PENDING) {
if ((s->options & SSL_OP_ENABLE_MIDDLEBOX_COMPAT) == 0
if (!SSL_CONNECTION_MIDDLEBOX_IS_ENABLED(s)
&& statem_flush(s) != 1)
return WORK_MORE_A;
break;
}
#ifndef OPENSSL_NO_SCTP
if (SSL_CONNECTION_IS_DTLS(s) && s->hit) {
/*
* Before exporting the SCTP auth key we check if DTLSv1.3 has been negotiated
* which is not supported.
* Refer to draft-tuexen-tsvwg-rfc6083-bis-04 for more info.
*/
if (SSL_CONNECTION_IS_DTLS(s) && !SSL_CONNECTION_IS_DTLS13(s) && s->hit) {
unsigned char sctpauthkey[64];
char labelbuffer[sizeof(DTLS1_SCTP_AUTH_LABEL)];
size_t labellen;
@ -945,8 +950,8 @@ WORK_STATE ossl_statem_server_post_work(SSL_CONNECTION *s, WORK_STATE wst)
sizeof(sctpauthkey), sctpauthkey);
}
#endif
if (!SSL_CONNECTION_IS_TLS13(s)
|| ((s->options & SSL_OP_ENABLE_MIDDLEBOX_COMPAT) != 0
if (!SSL_CONNECTION_IS_VERSION13(s)
|| (SSL_CONNECTION_MIDDLEBOX_IS_ENABLED(s)
&& s->hello_retry_request != SSL_HRR_COMPLETE))
break;
/* Fall through */
@ -958,7 +963,7 @@ WORK_STATE ossl_statem_server_post_work(SSL_CONNECTION *s, WORK_STATE wst)
break;
}
if (SSL_CONNECTION_IS_TLS13(s)) {
if (SSL_CONNECTION_IS_VERSION13(s)) {
if (!ssl->method->ssl3_enc->setup_key_block(s)
|| !ssl->method->ssl3_enc->change_cipher_state(s,
SSL3_CC_HANDSHAKE | SSL3_CHANGE_CIPHER_SERVER_WRITE)) {
@ -1017,8 +1022,8 @@ WORK_STATE ossl_statem_server_post_work(SSL_CONNECTION *s, WORK_STATE wst)
0, NULL);
}
#endif
if (SSL_CONNECTION_IS_TLS13(s)) {
/* TLS 1.3 gets the secret size from the handshake md */
if (SSL_CONNECTION_IS_VERSION13(s)) {
/* (D)TLS 1.3 gets the secret size from the handshake md */
size_t dummy;
if (!ssl->method->ssl3_enc->generate_master_secret(s,
s->master_secret, s->handshake_secret, 0,
@ -1035,7 +1040,7 @@ WORK_STATE ossl_statem_server_post_work(SSL_CONNECTION *s, WORK_STATE wst)
if (statem_flush(s) != 1)
return WORK_MORE_A;
} else {
if (!SSL_CONNECTION_IS_TLS13(s)
if (!SSL_CONNECTION_IS_VERSION13(s)
|| (s->options & SSL_OP_NO_TX_CERTIFICATE_COMPRESSION) != 0)
s->ext.compress_certificate_from_peer[0] = TLSEXT_comp_cert_none;
}
@ -1043,7 +1048,7 @@ WORK_STATE ossl_statem_server_post_work(SSL_CONNECTION *s, WORK_STATE wst)
case TLS_ST_SW_ENCRYPTED_EXTENSIONS:
if (!s->hit && !send_certificate_request(s)) {
if (!SSL_CONNECTION_IS_TLS13(s)
if (!SSL_CONNECTION_IS_VERSION13(s)
|| (s->options & SSL_OP_NO_TX_CERTIFICATE_COMPRESSION) != 0)
s->ext.compress_certificate_from_peer[0] = TLSEXT_comp_cert_none;
}
@ -1060,7 +1065,7 @@ WORK_STATE ossl_statem_server_post_work(SSL_CONNECTION *s, WORK_STATE wst)
case TLS_ST_SW_SESSION_TICKET:
clear_sys_error();
if (SSL_CONNECTION_IS_TLS13(s) && statem_flush(s) != 1) {
if (SSL_CONNECTION_IS_VERSION13(s) && statem_flush(s) != 1) {
if (SSL_get_error(ssl, 0) == SSL_ERROR_SYSCALL
&& conn_is_closed()) {
/*
@ -1397,6 +1402,12 @@ CON_FUNC_RETURN dtls_construct_hello_verify_request(SSL_CONNECTION *s,
return CON_FUNC_ERROR;
}
/*
* Server must recover the downgrade sentinel in case it sends a
* HelloVerifyRequest.
*/
s->d1->hello_verify_request = SSL_HVR_SENT;
return CON_FUNC_SUCCESS;
}
@ -1477,7 +1488,7 @@ MSG_PROCESS_RETURN tls_process_client_hello(SSL_CONNECTION *s, PACKET *pkt)
/* Check if this is actually an unexpected renegotiation ClientHello */
if (s->renegotiate == 0 && !SSL_IS_FIRST_HANDSHAKE(s)) {
if (!ossl_assert(!SSL_CONNECTION_IS_TLS13(s))) {
if (!ossl_assert(!SSL_CONNECTION_IS_VERSION13(s))) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
goto err;
}
@ -1618,17 +1629,6 @@ MSG_PROCESS_RETURN tls_process_client_hello(SSL_CONNECTION *s, PACKET *pkt)
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
goto err;
}
/*
* If we require cookies and this ClientHello doesn't contain one,
* just return since we do not want to allocate any memory yet.
* So check cookie length...
*/
if (SSL_get_options(SSL_CONNECTION_GET_SSL(s)) & SSL_OP_COOKIE_EXCHANGE) {
if (clienthello->dtls_cookie_len == 0) {
OPENSSL_free(clienthello);
return MSG_PROCESS_FINISHED_READING;
}
}
}
if (!PACKET_get_length_prefixed_2(pkt, &clienthello->ciphersuites)) {
@ -1668,6 +1668,31 @@ MSG_PROCESS_RETURN tls_process_client_hello(SSL_CONNECTION *s, PACKET *pkt)
/* SSLfatal already been called */
goto err;
}
if (SSL_CONNECTION_IS_DTLS(s)) {
int minversion, maxversion;
/*
* If the connection supports DTLSv1.3 or if the ClientHello was sent
* with the SupportedVersions extension:
* We continue to process ClientHello's without cookies
*
* Otherwise, if we require cookies and this ClientHello doesn't
* contain one:
* Return since we do not want to allocate any memory yet
*/
if ((SSL_get_options(SSL_CONNECTION_GET_SSL(s)) & SSL_OP_COOKIE_EXCHANGE)
&& clienthello->dtls_cookie_len == 0
&& ossl_assert(ssl_get_min_max_version(s, &minversion,
&maxversion, NULL) == 0)
&& ssl_version_cmp(s, maxversion, DTLS1_3_VERSION) < 0
&& !clienthello->pre_proc_exts[TLSEXT_IDX_supported_versions].present) {
OPENSSL_free(clienthello->pre_proc_exts);
OPENSSL_free(clienthello);
return MSG_PROCESS_FINISHED_READING;
}
}
s->clienthello = clienthello;
return MSG_PROCESS_CONTINUE_PROCESSING;
@ -1748,15 +1773,13 @@ static int tls_early_post_process_client_hello(SSL_CONNECTION *s)
}
/* TLSv1.3 specifies that a ClientHello must end on a record boundary */
if (SSL_CONNECTION_IS_TLS13(s)
if (SSL_CONNECTION_IS_VERSION13(s)
&& RECORD_LAYER_processed_read_pending(&s->rlayer)) {
SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_NOT_ON_RECORD_BOUNDARY);
goto err;
}
if (SSL_CONNECTION_IS_DTLS(s)) {
/* Empty cookie was already handled above by returning early. */
if (SSL_get_options(ssl) & SSL_OP_COOKIE_EXCHANGE) {
if ((SSL_get_options(ssl) & SSL_OP_COOKIE_EXCHANGE) && clienthello->dtls_cookie_len != 0) {
if (sctx->app_verify_cookie_cb != NULL) {
if (sctx->app_verify_cookie_cb(ussl, clienthello->dtls_cookie,
clienthello->dtls_cookie_len) == 0) {
@ -1816,7 +1839,7 @@ static int tls_early_post_process_client_hello(SSL_CONNECTION *s)
}
/* For TLSv1.3 we must select the ciphersuite *before* session resumption */
if (SSL_CONNECTION_IS_TLS13(s)) {
if (SSL_CONNECTION_IS_VERSION13(s)) {
const SSL_CIPHER *cipher =
ssl3_choose_cipher(s, ciphers, SSL_get_ciphers(ssl));
@ -1885,7 +1908,7 @@ static int tls_early_post_process_client_hello(SSL_CONNECTION *s)
}
}
if (SSL_CONNECTION_IS_TLS13(s)) {
if (SSL_CONNECTION_IS_VERSION13(s)) {
memcpy(s->tmp_session_id, s->clienthello->session_id,
s->clienthello->session_id_len);
s->tmp_session_id_len = s->clienthello->session_id_len;
@ -1895,7 +1918,7 @@ static int tls_early_post_process_client_hello(SSL_CONNECTION *s)
* If it is a hit, check that the cipher is in the list. In TLSv1.3 we check
* ciphersuite compatibility with the session as part of resumption.
*/
if (!SSL_CONNECTION_IS_TLS13(s) && s->hit) {
if (!SSL_CONNECTION_IS_VERSION13(s) && s->hit) {
j = 0;
id = s->session->cipher->id;
@ -1971,7 +1994,7 @@ static int tls_early_post_process_client_hello(SSL_CONNECTION *s)
if (!s->hit
&& s->version >= TLS1_VERSION
&& !SSL_CONNECTION_IS_TLS13(s)
&& !SSL_CONNECTION_IS_VERSION13(s)
&& !SSL_CONNECTION_IS_DTLS(s)
&& s->ext.session_secret_cb != NULL) {
const SSL_CIPHER *pref_cipher = NULL;
@ -2017,7 +2040,7 @@ static int tls_early_post_process_client_hello(SSL_CONNECTION *s)
* algorithms from the client, starting at q.
*/
s->s3.tmp.new_compression = NULL;
if (SSL_CONNECTION_IS_TLS13(s)) {
if (SSL_CONNECTION_IS_VERSION13(s)) {
/*
* We already checked above that the NULL compression method appears in
* the list. Now we check there aren't any others (which is illegal in
@ -2104,7 +2127,7 @@ static int tls_early_post_process_client_hello(SSL_CONNECTION *s)
* Given s->peer_ciphers and SSL_get_ciphers, we must pick a cipher
*/
if (!s->hit || SSL_CONNECTION_IS_TLS13(s)) {
if (!s->hit || SSL_CONNECTION_IS_VERSION13(s)) {
sk_SSL_CIPHER_free(s->peer_ciphers);
s->peer_ciphers = ciphers;
if (ciphers == NULL) {
@ -2288,7 +2311,7 @@ WORK_STATE tls_post_process_client_hello(SSL_CONNECTION *s, WORK_STATE wst)
wst = WORK_MORE_B;
}
if (wst == WORK_MORE_B) {
if (!s->hit || SSL_CONNECTION_IS_TLS13(s)) {
if (!s->hit || SSL_CONNECTION_IS_VERSION13(s)) {
/* Let cert callback update server certificates if required */
if (!s->hit && s->cert->cert_cb != NULL) {
int rv = s->cert->cert_cb(ussl, s->cert->cert_cb_arg);
@ -2305,7 +2328,7 @@ WORK_STATE tls_post_process_client_hello(SSL_CONNECTION *s, WORK_STATE wst)
}
/* In TLSv1.3 we selected the ciphersuite before resumption */
if (!SSL_CONNECTION_IS_TLS13(s)) {
if (!SSL_CONNECTION_IS_VERSION13(s)) {
cipher =
ssl3_choose_cipher(s, s->peer_ciphers,
SSL_get_ciphers(ssl));
@ -2363,7 +2386,7 @@ WORK_STATE tls_post_process_client_hello(SSL_CONNECTION *s, WORK_STATE wst)
* we already did this because cipher negotiation happens earlier, and
* we must handle ALPN before we decide whether to accept early_data.
*/
if (!SSL_CONNECTION_IS_TLS13(s) && !tls_handle_alpn(s)) {
if (!SSL_CONNECTION_IS_VERSION13(s) && !tls_handle_alpn(s)) {
/* SSLfatal() already called */
goto err;
}
@ -2399,9 +2422,13 @@ CON_FUNC_RETURN tls_construct_server_hello(SSL_CONNECTION *s, WPACKET *pkt)
int version;
unsigned char *session_id;
int usetls13 = SSL_CONNECTION_IS_TLS13(s)
|| s->hello_retry_request == SSL_HRR_PENDING;
|| (!SSL_CONNECTION_IS_DTLS(s)
&& s->hello_retry_request == SSL_HRR_PENDING);
int usedtls13 = SSL_CONNECTION_IS_DTLS13(s)
|| (SSL_CONNECTION_IS_DTLS(s)
&& s->hello_retry_request == SSL_HRR_PENDING);
version = usetls13 ? TLS1_2_VERSION : s->version;
version = usetls13 ? TLS1_2_VERSION : (usedtls13 ? DTLS1_2_VERSION : s->version);
if (!WPACKET_put_bytes_u16(pkt, version)
/*
* Random stuff. Filling of the server_random takes place in
@ -2429,6 +2456,7 @@ CON_FUNC_RETURN tls_construct_server_hello(SSL_CONNECTION *s, WPACKET *pkt)
* we send back a 0-length session ID.
* - In TLSv1.3 we echo back the session id sent to us by the client
* regardless
* - In DTLSv1.3 we must not echo the session id sent by the client
* s->hit is non-zero in either case of session reuse,
* so the following won't overwrite an ID that we're supposed
* to send back.
@ -2440,6 +2468,9 @@ CON_FUNC_RETURN tls_construct_server_hello(SSL_CONNECTION *s, WPACKET *pkt)
if (usetls13) {
sl = s->tmp_session_id_len;
session_id = s->tmp_session_id;
} else if (usedtls13) {
sl = 0;
session_id = NULL;
} else {
sl = s->session->session_id_length;
session_id = s->session->session_id;
@ -2454,7 +2485,7 @@ CON_FUNC_RETURN tls_construct_server_hello(SSL_CONNECTION *s, WPACKET *pkt)
#ifdef OPENSSL_NO_COMP
compm = 0;
#else
if (usetls13 || s->s3.tmp.new_compression == NULL)
if (usetls13 || usedtls13 || s->s3.tmp.new_compression == NULL)
compm = 0;
else
compm = s->s3.tmp.new_compression->id;
@ -2471,7 +2502,7 @@ CON_FUNC_RETURN tls_construct_server_hello(SSL_CONNECTION *s, WPACKET *pkt)
if (!tls_construct_extensions(s, pkt,
s->hello_retry_request == SSL_HRR_PENDING
? SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST
: (SSL_CONNECTION_IS_TLS13(s)
: (SSL_CONNECTION_IS_VERSION13(s)
? SSL_EXT_TLS1_3_SERVER_HELLO
: SSL_EXT_TLS1_2_SERVER_HELLO),
NULL, 0)) {
@ -2827,7 +2858,7 @@ CON_FUNC_RETURN tls_construct_server_key_exchange(SSL_CONNECTION *s,
CON_FUNC_RETURN tls_construct_certificate_request(SSL_CONNECTION *s,
WPACKET *pkt)
{
if (SSL_CONNECTION_IS_TLS13(s)) {
if (SSL_CONNECTION_IS_VERSION13(s)) {
/* Send random context when doing post-handshake auth */
if (s->post_handshake_auth == SSL_PHA_REQUEST_PENDING) {
OPENSSL_free(s->pha_context);
@ -3454,7 +3485,12 @@ WORK_STATE tls_post_process_client_key_exchange(SSL_CONNECTION *s,
{
#ifndef OPENSSL_NO_SCTP
if (wst == WORK_MORE_A) {
if (SSL_CONNECTION_IS_DTLS(s)) {
/*
* Before exporting the SCTP auth key we check if DTLSv1.3 has been
* negotiated which is not supported.
* Refer to draft-tuexen-tsvwg-rfc6083-bis-04 for more info.
*/
if (SSL_CONNECTION_IS_DTLS(s) && !SSL_CONNECTION_IS_DTLS13(s)) {
unsigned char sctpauthkey[64];
char labelbuffer[sizeof(DTLS1_SCTP_AUTH_LABEL)];
size_t labellen;
@ -3573,7 +3609,7 @@ MSG_PROCESS_RETURN tls_process_client_rpk(SSL_CONNECTION *sc, PACKET *pkt)
* Freeze the handshake buffer. For <TLS1.3 we do this after the CKE
* message
*/
if (SSL_CONNECTION_IS_TLS13(sc)) {
if (SSL_CONNECTION_IS_VERSION13(sc)) {
if (!ssl3_digest_cached_records(sc, 1)) {
/* SSLfatal() already called */
goto err;
@ -3633,7 +3669,7 @@ MSG_PROCESS_RETURN tls_process_client_certificate(SSL_CONNECTION *s,
goto err;
}
if (SSL_CONNECTION_IS_TLS13(s)
if (SSL_CONNECTION_IS_VERSION13(s)
&& (!PACKET_get_length_prefixed_1(pkt, &context)
|| (s->pha_context == NULL && PACKET_remaining(&context) != 0)
|| (s->pha_context != NULL
@ -3672,7 +3708,7 @@ MSG_PROCESS_RETURN tls_process_client_certificate(SSL_CONNECTION *s,
goto err;
}
if (SSL_CONNECTION_IS_TLS13(s)) {
if (SSL_CONNECTION_IS_VERSION13(s)) {
RAW_EXTENSION *rawexts = NULL;
PACKET extensions;
@ -3767,7 +3803,7 @@ MSG_PROCESS_RETURN tls_process_client_certificate(SSL_CONNECTION *s,
* Freeze the handshake buffer. For <TLS1.3 we do this after the CKE
* message
*/
if (SSL_CONNECTION_IS_TLS13(s) && !ssl3_digest_cached_records(s, 1)) {
if (SSL_CONNECTION_IS_VERSION13(s) && !ssl3_digest_cached_records(s, 1)) {
/* SSLfatal() already called */
goto err;
}
@ -3778,7 +3814,7 @@ MSG_PROCESS_RETURN tls_process_client_certificate(SSL_CONNECTION *s,
*/
/* Save the current hash state for when we receive the CertificateVerify */
if (SSL_CONNECTION_IS_TLS13(s)) {
if (SSL_CONNECTION_IS_VERSION13(s)) {
if (!ssl_handshake_hash(s, s->cert_verify_hash,
sizeof(s->cert_verify_hash),
&s->cert_verify_hash_len)) {
@ -3826,7 +3862,7 @@ CON_FUNC_RETURN tls_construct_server_certificate(SSL_CONNECTION *s, WPACKET *pkt
* In TLSv1.3 the certificate chain is always preceded by a 0 length context
* for the server Certificate message
*/
if (SSL_CONNECTION_IS_TLS13(s) && !WPACKET_put_bytes_u8(pkt, 0)) {
if (SSL_CONNECTION_IS_VERSION13(s) && !WPACKET_put_bytes_u8(pkt, 0)) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return CON_FUNC_ERROR;
}
@ -3891,7 +3927,7 @@ static int create_ticket_prequel(SSL_CONNECTION *s, WPACKET *pkt,
*/
#define ONE_WEEK_SEC (7 * 24 * 60 * 60)
if (SSL_CONNECTION_IS_TLS13(s)) {
if (SSL_CONNECTION_IS_VERSION13(s)) {
if (ossl_time_compare(s->session->timeout,
ossl_seconds2time(ONE_WEEK_SEC)) > 0)
timeout = ONE_WEEK_SEC;
@ -3903,7 +3939,7 @@ static int create_ticket_prequel(SSL_CONNECTION *s, WPACKET *pkt,
return 0;
}
if (SSL_CONNECTION_IS_TLS13(s)) {
if (SSL_CONNECTION_IS_VERSION13(s)) {
if (!WPACKET_put_bytes_u32(pkt, age_add)
|| !WPACKET_sub_memcpy_u8(pkt, tick_nonce, TICKET_NONCE_SIZE)) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
@ -4030,7 +4066,7 @@ static CON_FUNC_RETURN construct_stateless_ticket(SSL_CONNECTION *s,
* length ticket is not allowed so we abort construction of the
* ticket
*/
if (SSL_CONNECTION_IS_TLS13(s)) {
if (SSL_CONNECTION_IS_VERSION13(s)) {
ok = CON_FUNC_DONT_SEND;
goto err;
}
@ -4173,7 +4209,7 @@ CON_FUNC_RETURN tls_construct_new_session_ticket(SSL_CONNECTION *s, WPACKET *pkt
age_add_u.age_add = 0;
if (SSL_CONNECTION_IS_TLS13(s)) {
if (SSL_CONNECTION_IS_VERSION13(s)) {
size_t i, hashlen;
uint64_t nonce;
static const unsigned char nonce_label[] = "resumption";
@ -4260,7 +4296,7 @@ CON_FUNC_RETURN tls_construct_new_session_ticket(SSL_CONNECTION *s, WPACKET *pkt
* SSL_OP_NO_TICKET is set - we are caching tickets anyway so there
* is no point in using full stateless tickets.
*/
if (SSL_CONNECTION_IS_TLS13(s)
if (SSL_CONNECTION_IS_VERSION13(s)
&& ((s->options & SSL_OP_NO_TICKET) != 0
|| (s->max_early_data > 0
&& (s->options & SSL_OP_NO_ANTI_REPLAY) == 0))) {
@ -4285,7 +4321,7 @@ CON_FUNC_RETURN tls_construct_new_session_ticket(SSL_CONNECTION *s, WPACKET *pkt
}
}
if (SSL_CONNECTION_IS_TLS13(s)) {
if (SSL_CONNECTION_IS_VERSION13(s)) {
if (!tls_construct_extensions(s, pkt,
SSL_EXT_TLS1_3_NEW_SESSION_TICKET,
NULL, 0)) {

View file

@ -233,9 +233,9 @@ int tls1_change_cipher_state(SSL_CONNECTION *s, int which)
if (!ssl_set_new_record_layer(s, s->version, direction,
OSSL_RECORD_PROTECTION_LEVEL_APPLICATION,
NULL, 0, key, cl, iv, (size_t)k, mac_secret,
mac_secret_size, c, taglen, mac_type,
m, comp, NULL)) {
NULL, 0, NULL, key, cl, iv, (size_t)k,
mac_secret, mac_secret_size, NULL, 0, c, taglen,
mac_type, m, comp, NULL)) {
/* SSLfatal already called */
goto err;
}
@ -266,8 +266,8 @@ int tls1_setup_key_block(SSL_CONNECTION *s)
if (s->s3.tmp.key_block_length != 0)
return 1;
if (!ssl_cipher_get_evp(SSL_CONNECTION_GET_CTX(s), s->session, &c, &hash,
&mac_type, &mac_secret_size, &comp,
if (!ssl_cipher_get_evp(SSL_CONNECTION_GET_CTX(s), s->session, NULL, NULL, &c,
&hash, &mac_type, &mac_secret_size, &comp,
s->ext.use_etm)) {
/* Error is already recorded */
SSLfatal_alert(s, SSL_AD_INTERNAL_ERROR);

View file

@ -582,8 +582,12 @@ static int add_provider_sigalgs(const OSSL_PARAM params[], void *data)
ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT);
goto err;
}
if ((sinf->mintls != 0) && (sinf->mintls != -1) &&
((sinf->mintls < TLS1_3_VERSION))) {
if ((sinf->mintls != 0) && (sinf->mintls != -1)
/*
* There are no discrepancies for signature algs between comparable
* versions of tls and dtls. Hence we check tls versions only.
*/
&& ((sinf->mintls < TLS1_3_VERSION))) {
/* ignore this sigalg as this OpenSSL doesn't know how to handle it */
ret = 1;
goto err;
@ -594,13 +598,21 @@ static int add_provider_sigalgs(const OSSL_PARAM params[], void *data)
ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT);
goto err;
}
if ((sinf->maxtls != 0) && (sinf->maxtls != -1) &&
((sinf->maxtls < sinf->mintls))) {
if ((sinf->maxtls != 0) && (sinf->maxtls != -1)
/*
* There are no discrepancies for signature algs between comparable
* versions of tls and dtls. Hence we check tls versions only.
*/
&& ((sinf->maxtls < sinf->mintls))) {
ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT);
goto err;
}
if ((sinf->maxtls != 0) && (sinf->maxtls != -1) &&
((sinf->maxtls < TLS1_3_VERSION))) {
if ((sinf->maxtls != 0) && (sinf->maxtls != -1)
/*
* There are no discrepancies for signature algs between comparable
* versions of tls and dtls. Hence we check tls versions only.
*/
&& ((sinf->maxtls < TLS1_3_VERSION))) {
/* ignore this sigalg as this OpenSSL doesn't know how to handle it */
ret = 1;
goto err;
@ -851,6 +863,7 @@ int tls_valid_group(SSL_CONNECTION *s, uint16_t group_id,
group_id);
int ret;
int group_minversion, group_maxversion;
const int version1_3 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION : TLS1_3_VERSION;
if (okfortls13 != NULL)
*okfortls13 = 0;
@ -870,11 +883,9 @@ int tls_valid_group(SSL_CONNECTION *s, uint16_t group_id,
if (group_minversion > 0)
ret &= (ssl_version_cmp(s, maxversion, group_minversion) >= 0);
if (!SSL_CONNECTION_IS_DTLS(s)) {
if (ret && okfortls13 != NULL && maxversion == TLS1_3_VERSION)
if (ret && okfortls13 != NULL && maxversion == version1_3)
*okfortls13 = (group_maxversion == 0)
|| (group_maxversion >= TLS1_3_VERSION);
}
|| (ssl_version_cmp(s, group_maxversion, maxversion) >= 0);
ret &= !isec
|| strcmp(ginfo->algorithm, "EC") == 0
|| strcmp(ginfo->algorithm, "X25519") == 0
@ -1276,7 +1287,7 @@ static int tls1_check_pkey_comp(SSL_CONNECTION *s, EVP_PKEY *pkey)
return 0;
if (point_conv == POINT_CONVERSION_UNCOMPRESSED) {
comp_id = TLSEXT_ECPOINTFORMAT_uncompressed;
} else if (SSL_CONNECTION_IS_TLS13(s)) {
} else if (SSL_CONNECTION_IS_VERSION13(s)) {
/*
* ec_point_formats extension is not used in TLSv1.3 so we ignore
* this check.
@ -2022,13 +2033,13 @@ int tls12_check_peer_sigalg(SSL_CONNECTION *s, uint16_t sig, EVP_PKEY *pkey)
pkeyid = EVP_PKEY_get_id(pkey);
if (SSL_CONNECTION_IS_TLS13(s)) {
/* Disallow DSA for TLS 1.3 */
if (SSL_CONNECTION_IS_VERSION13(s)) {
/* Disallow DSA for (D)TLS 1.3 */
if (pkeyid == EVP_PKEY_DSA) {
SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_WRONG_SIGNATURE_TYPE);
return 0;
}
/* Only allow PSS for TLS 1.3 */
/* Only allow PSS for (D)TLS 1.3 */
if (pkeyid == EVP_PKEY_RSA)
pkeyid = EVP_PKEY_RSA_PSS;
}
@ -2042,11 +2053,11 @@ int tls12_check_peer_sigalg(SSL_CONNECTION *s, uint16_t sig, EVP_PKEY *pkey)
return -1;
/*
* Check sigalgs is known. Disallow SHA1/SHA224 with TLS 1.3. Check key type
* Check sigalgs is known. Disallow SHA1/SHA224 with (D)TLS 1.3. Check key type
* is consistent with signature: RSA keys can be used for RSA-PSS
*/
if (lu == NULL
|| (SSL_CONNECTION_IS_TLS13(s)
|| (SSL_CONNECTION_IS_VERSION13(s)
&& (lu->hash == NID_sha1 || lu->hash == NID_sha224))
|| (pkeyid != lu->sig
&& (lu->sig != EVP_PKEY_RSA_PSS || pkeyid != EVP_PKEY_RSA))) {
@ -2071,8 +2082,8 @@ int tls12_check_peer_sigalg(SSL_CONNECTION *s, uint16_t sig, EVP_PKEY *pkey)
return 0;
}
/* For TLS 1.3 or Suite B check curve matches signature algorithm */
if (SSL_CONNECTION_IS_TLS13(s) || tls1_suiteb(s)) {
/* For (D)TLS 1.3 or Suite B check curve matches signature algorithm */
if (SSL_CONNECTION_IS_VERSION13(s) || tls1_suiteb(s)) {
int curve = ssl_get_EC_curve_nid(pkey);
if (lu->curve != NID_undef && curve != lu->curve) {
@ -2080,7 +2091,7 @@ int tls12_check_peer_sigalg(SSL_CONNECTION *s, uint16_t sig, EVP_PKEY *pkey)
return 0;
}
}
if (!SSL_CONNECTION_IS_TLS13(s)) {
if (!SSL_CONNECTION_IS_VERSION13(s)) {
/* Check curve matches extensions */
if (!tls1_check_group_id(s, tls1_get_group_id(pkey), 1)) {
SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_WRONG_CURVE);
@ -2237,7 +2248,8 @@ int ssl_cipher_disabled(const SSL_CONNECTION *s, const SSL_CIPHER *c,
&& (c->algorithm_mkey & (SSL_kECDHE | SSL_kECDHEPSK)) != 0)
minversion = SSL3_VERSION;
if (ssl_version_cmp(s, minversion, s->s3.tmp.max_ver) > 0
if (minversion <= 0 || maxversion <= 0
|| ssl_version_cmp(s, minversion, s->s3.tmp.max_ver) > 0
|| ssl_version_cmp(s, maxversion, s->s3.tmp.min_ver) < 0)
return 1;
@ -2324,7 +2336,7 @@ SSL_TICKET_STATUS tls_get_ticket_from_client(SSL_CONNECTION *s,
s->ext.ticket_expected = 0;
/*
* If tickets disabled or not supported by the protocol version
* If tickets are disabled or not supported by the protocol version
* (e.g. TLSv1.3) behave as if no ticket present to permit stateful
* resumption.
*/
@ -2390,7 +2402,7 @@ SSL_TICKET_STATUS tls_decrypt_ticket(SSL_CONNECTION *s,
ret = SSL_TICKET_EMPTY;
goto end;
}
if (!SSL_CONNECTION_IS_TLS13(s) && s->ext.session_secret_cb) {
if (!SSL_CONNECTION_IS_VERSION13(s) && s->ext.session_secret_cb) {
/*
* Indicate that the ticket couldn't be decrypted rather than
* generating the session from ticket now, trigger
@ -2475,7 +2487,7 @@ SSL_TICKET_STATUS tls_decrypt_ticket(SSL_CONNECTION *s,
goto end;
}
EVP_CIPHER_free(aes256cbc);
if (SSL_CONNECTION_IS_TLS13(s))
if (SSL_CONNECTION_IS_VERSION13(s))
renew_ticket = 1;
}
/*
@ -2621,7 +2633,7 @@ SSL_TICKET_STATUS tls_decrypt_ticket(SSL_CONNECTION *s,
}
}
if (s->ext.session_secret_cb == NULL || SSL_CONNECTION_IS_TLS13(s)) {
if (s->ext.session_secret_cb == NULL || SSL_CONNECTION_IS_VERSION13(s)) {
switch (ret) {
case SSL_TICKET_NO_DECRYPT:
case SSL_TICKET_SUCCESS_RENEW:
@ -2641,18 +2653,20 @@ static int tls12_sigalg_allowed(const SSL_CONNECTION *s, int op,
{
unsigned char sigalgstr[2];
int secbits;
const int version1_3 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION
: TLS1_3_VERSION;
if (lu == NULL || !lu->enabled)
return 0;
/* DSA is not allowed in TLS 1.3 */
if (SSL_CONNECTION_IS_TLS13(s) && lu->sig == EVP_PKEY_DSA)
/* DSA is not allowed in (D)TLSv1.3 */
if (SSL_CONNECTION_IS_VERSION13(s) && lu->sig == EVP_PKEY_DSA)
return 0;
/*
* At some point we should fully axe DSA/etc. in ClientHello as per TLS 1.3
* At some point we should fully axe DSA/etc. in ClientHello as per (D)TLSv1.3
* spec
*/
if (!s->server && !SSL_CONNECTION_IS_DTLS(s)
&& s->s3.tmp.min_ver >= TLS1_3_VERSION
if (!s->server && s->s3.tmp.min_ver > 0
&& ssl_version_cmp(s, s->s3.tmp.min_ver, version1_3) >= 0
&& (lu->sig == EVP_PKEY_DSA || lu->hash_idx == SSL_MD_SHA1_IDX
|| lu->hash_idx == SSL_MD_MD5_IDX
|| lu->hash_idx == SSL_MD_SHA224_IDX))
@ -2665,22 +2679,26 @@ static int tls12_sigalg_allowed(const SSL_CONNECTION *s, int op,
if (lu->sig == NID_id_GostR3410_2012_256
|| lu->sig == NID_id_GostR3410_2012_512
|| lu->sig == NID_id_GostR3410_2001) {
/* We never allow GOST sig algs on the server with TLSv1.3 */
if (s->server && SSL_CONNECTION_IS_TLS13(s))
int any_version = SSL_CONNECTION_IS_DTLS(s) ? DTLS_ANY_VERSION : TLS_ANY_VERSION;
/* We never allow GOST sig algs on the server with (D)TLSv1.3 */
if (s->server && SSL_CONNECTION_IS_VERSION13(s))
return 0;
if (!s->server
&& SSL_CONNECTION_GET_SSL(s)->method->version == TLS_ANY_VERSION
&& s->s3.tmp.max_ver >= TLS1_3_VERSION) {
&& SSL_CONNECTION_GET_SSL(s)->method->version == any_version
&& s->s3.tmp.max_ver > 0
&& ssl_version_cmp(s, s->s3.tmp.max_ver, version1_3) >= 0) {
int i, num;
STACK_OF(SSL_CIPHER) *sk;
/*
* We're a client that could negotiate TLSv1.3. We only allow GOST
* sig algs if we could negotiate TLSv1.2 or below and we have GOST
* We're a client that could negotiate (D)TLSv1.3. We only allow GOST
* sig algs if we could negotiate (D)TLSv1.2 or below and we have GOST
* ciphersuites enabled.
*/
if (s->s3.tmp.min_ver >= TLS1_3_VERSION)
if (s->s3.tmp.min_ver > 0
&& ssl_version_cmp(s, s->s3.tmp.min_ver, version1_3) >= 0)
return 0;
sk = SSL_get_ciphers(SSL_CONNECTION_GET_SSL(s));
@ -2762,7 +2780,7 @@ int tls12_copy_sigalgs(SSL_CONNECTION *s, WPACKET *pkt,
* If TLS 1.3 must have at least one valid TLS 1.3 message
* signing algorithm: i.e. neither RSA nor SHA1/SHA224
*/
if (rv == 0 && (!SSL_CONNECTION_IS_TLS13(s)
if (rv == 0 && (!SSL_CONNECTION_IS_VERSION13(s)
|| (lu->sig != EVP_PKEY_RSA
&& lu->hash != NID_sha1
&& lu->hash != NID_sha224)))
@ -2913,7 +2931,7 @@ int tls1_process_sigalgs(SSL_CONNECTION *s)
int idx = sigptr->sig_idx;
/* Ignore PKCS1 based sig algs in TLSv1.3 */
if (SSL_CONNECTION_IS_TLS13(s) && sigptr->sig == EVP_PKEY_RSA)
if (SSL_CONNECTION_IS_VERSION13(s) && sigptr->sig == EVP_PKEY_RSA)
continue;
/* If not disabled indicate we can explicitly sign */
if (pvalid[idx] == 0
@ -3215,7 +3233,7 @@ static int tls1_check_sig_alg(SSL_CONNECTION *s, X509 *x, int default_nid)
if (default_nid)
return sig_nid == default_nid ? 1 : 0;
if (SSL_CONNECTION_IS_TLS13(s) && s->s3.tmp.peer_cert_sigalgs != NULL) {
if (SSL_CONNECTION_IS_VERSION13(s) && s->s3.tmp.peer_cert_sigalgs != NULL) {
/*
* If we're in TLSv1.3 then we only get here if we're checking the
* chain. If the peer has specified peer_cert_sigalgs then we use them
@ -3405,7 +3423,7 @@ int tls1_check_chain(SSL_CONNECTION *s, X509 *x, EVP_PKEY *pk,
}
}
/* Check signature algorithm of each cert in chain */
if (SSL_CONNECTION_IS_TLS13(s)) {
if (SSL_CONNECTION_IS_VERSION13(s)) {
/*
* We only get here if the application has called SSL_check_chain(),
* so check_flags is always set.
@ -3902,7 +3920,7 @@ int tls_choose_sigalg(SSL_CONNECTION *s, int fatalerrs)
s->s3.tmp.cert = NULL;
s->s3.tmp.sigalg = NULL;
if (SSL_CONNECTION_IS_TLS13(s)) {
if (SSL_CONNECTION_IS_VERSION13(s)) {
lu = find_sig_alg(s, NULL, NULL);
if (lu == NULL) {
if (!fatalerrs)

View file

@ -68,6 +68,7 @@ static const ssl_trace_tbl ssl_version_tbl[] = {
{TLS1_3_VERSION, "TLS 1.3"},
{DTLS1_VERSION, "DTLS 1.0"},
{DTLS1_2_VERSION, "DTLS 1.2"},
{DTLS1_3_VERSION, "DTLS 1.3"},
{DTLS1_BAD_VER, "DTLS 1.0 (bad)"}
};
@ -1350,7 +1351,7 @@ static int ssl_print_certificates(BIO *bio, const SSL_CONNECTION *sc, int server
{
size_t clen;
if (SSL_CONNECTION_IS_TLS13(sc)
if (SSL_CONNECTION_IS_VERSION13(sc)
&& !ssl_print_hexbuf(bio, indent, "context", 1, &msg, &msglen))
return 0;
@ -1364,7 +1365,7 @@ static int ssl_print_certificates(BIO *bio, const SSL_CONNECTION *sc, int server
|| (!server && sc->ext.client_cert_type == TLSEXT_cert_type_rpk)) {
if (!ssl_print_raw_public_key(bio, &sc->ssl, server, indent, &msg, &clen))
return 0;
if (SSL_CONNECTION_IS_TLS13(sc)
if (SSL_CONNECTION_IS_VERSION13(sc)
&& !ssl_print_extensions(bio, indent + 2, server,
SSL3_MT_CERTIFICATE, &msg, &clen))
return 0;
@ -1375,7 +1376,7 @@ static int ssl_print_certificates(BIO *bio, const SSL_CONNECTION *sc, int server
while (clen > 0) {
if (!ssl_print_certificate(bio, sc, indent + 2, &msg, &clen))
return 0;
if (SSL_CONNECTION_IS_TLS13(sc)
if (SSL_CONNECTION_IS_VERSION13(sc)
&& !ssl_print_extensions(bio, indent + 2, server,
SSL3_MT_CERTIFICATE, &msg, &clen))
return 0;
@ -1461,7 +1462,7 @@ static int ssl_print_cert_request(BIO *bio, int indent, const SSL_CONNECTION *sc
size_t xlen;
unsigned int sigalg;
if (SSL_CONNECTION_IS_TLS13(sc)) {
if (SSL_CONNECTION_IS_VERSION13(sc)) {
if (!ssl_print_hexbuf(bio, indent, "request_context", 1, &msg, &msglen))
return 0;
if (!ssl_print_extensions(bio, indent, 1,
@ -1536,7 +1537,7 @@ static int ssl_print_cert_request(BIO *bio, int indent, const SSL_CONNECTION *sc
xlen -= dlen + 2;
msg += dlen;
}
if (SSL_CONNECTION_IS_TLS13(sc)) {
if (SSL_CONNECTION_IS_VERSION13(sc)) {
if (!ssl_print_hexbuf(bio, indent, "request_extensions", 2,
&msg, &msglen))
return 0;
@ -1564,7 +1565,7 @@ static int ssl_print_ticket(BIO *bio, int indent, const SSL_CONNECTION *sc,
msg += 4;
BIO_indent(bio, indent + 2, 80);
BIO_printf(bio, "ticket_lifetime_hint=%u\n", tick_life);
if (SSL_CONNECTION_IS_TLS13(sc)) {
if (SSL_CONNECTION_IS_VERSION13(sc)) {
unsigned int ticket_age_add;
if (msglen < 4)
@ -1584,7 +1585,7 @@ static int ssl_print_ticket(BIO *bio, int indent, const SSL_CONNECTION *sc,
}
if (!ssl_print_hexbuf(bio, indent + 2, "ticket", 2, &msg, &msglen))
return 0;
if (SSL_CONNECTION_IS_TLS13(sc)
if (SSL_CONNECTION_IS_VERSION13(sc)
&& !ssl_print_extensions(bio, indent + 2, 0,
SSL3_MT_NEWSESSION_TICKET, &msg, &msglen))
return 0;

View file

@ -18,20 +18,24 @@
#define TLS13_MAX_LABEL_LEN 249
/* ASCII: "dtls13", in hex for EBCDIC compatibility */
static const unsigned char label_prefix_dtls13[] = "\x64\x74\x6C\x73\x31\x33";
/* ASCII: "tls13 ", in hex for EBCDIC compatibility */
static const unsigned char label_prefix[] = "\x74\x6C\x73\x31\x33\x20";
static const unsigned char label_prefix_tls13[] = "\x74\x6C\x73\x31\x33\x20";
/*
* Given a |secret|; a |label| of length |labellen|; and |data| of length
* |datalen| (e.g. typically a hash of the handshake messages), derive a new
* secret |outlen| bytes long and store it in the location pointed to be |out|.
* Given a |secret|; a |label_prefix| of length |label_prefix_len|; a |label|
* of length |labellen|; and |data| of length |datalen| (e.g. typically a hash
* of the handshake messages), derive a new secret |outlen| bytes long and
* store it in the location pointed to be |out|.
* The |data| value may be zero length. Any errors will be treated as fatal if
* |fatal| is set. Returns 1 on success 0 on failure.
* If |raise_error| is set, ERR_raise is called on failure.
*/
int tls13_hkdf_expand_ex(OSSL_LIB_CTX *libctx, const char *propq,
static int hkdf_expand(OSSL_LIB_CTX *libctx, const char *propq,
const EVP_MD *md,
const unsigned char *secret,
const unsigned char *label_prefix, size_t label_prefix_len,
const unsigned char *label, size_t labellen,
const unsigned char *data, size_t datalen,
unsigned char *out, size_t outlen, int raise_error)
@ -76,7 +80,7 @@ int tls13_hkdf_expand_ex(OSSL_LIB_CTX *libctx, const char *propq,
(unsigned char *)secret, hashlen);
*p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_PREFIX,
(unsigned char *)label_prefix,
sizeof(label_prefix) - 1);
label_prefix_len);
*p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_LABEL,
(unsigned char *)label, labellen);
if (data != NULL)
@ -96,6 +100,20 @@ int tls13_hkdf_expand_ex(OSSL_LIB_CTX *libctx, const char *propq,
return ret == 0;
}
int tls13_hkdf_expand_ex(OSSL_LIB_CTX *libctx, const char *propq,
const EVP_MD *md,
const unsigned char *secret,
const unsigned char *label, size_t labellen,
const unsigned char *data, size_t datalen,
unsigned char *out, size_t outlen, int raise_error)
{
/* This function only supports TLSv1.3 and not DTLSv1.3 */
return hkdf_expand(libctx, propq, md, secret, label_prefix_tls13,
sizeof(label_prefix_tls13) - 1,
label, labellen, data, datalen, out, outlen,
raise_error);
}
int tls13_hkdf_expand(SSL_CONNECTION *s, const EVP_MD *md,
const unsigned char *secret,
const unsigned char *label, size_t labellen,
@ -104,10 +122,15 @@ int tls13_hkdf_expand(SSL_CONNECTION *s, const EVP_MD *md,
{
int ret;
SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s);
const int isdtls = SSL_CONNECTION_IS_DTLS(s);
const unsigned char *label_prefix = isdtls ? label_prefix_dtls13
: label_prefix_tls13;
const size_t label_prefix_len = isdtls ? sizeof(label_prefix_dtls13) - 1
: sizeof(label_prefix_tls13) - 1;
ret = tls13_hkdf_expand_ex(sctx->libctx, sctx->propq, md,
secret, label, labellen, data, datalen,
out, outlen, !fatal);
ret = hkdf_expand(sctx->libctx, sctx->propq, md, secret, label_prefix,
label_prefix_len, label, labellen, data,
datalen, out, outlen, !fatal);
if (ret == 0 && fatal)
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
@ -155,6 +178,21 @@ int tls13_derive_finishedkey(SSL_CONNECTION *s, const EVP_MD *md,
sizeof(finishedlabel) - 1, NULL, 0, fin, finlen, 1);
}
/*
* Given a |secret| generate a |snkey| of length |snkeylen| bytes. Returns 1 on
* success 0 on failure. (rfc9147 section 4.2.3)
*/
static int dtls13_derive_snkey(SSL_CONNECTION *s, const EVP_MD *md,
const unsigned char *secret,
unsigned char *snkey, size_t keylen)
{
/* ASCII: "sn", in hex for EBCDIC compatibility */
static const unsigned char sn_str[] = "\x73\x6E";
return tls13_hkdf_expand(s, md, secret, sn_str, sizeof(sn_str) - 1,
NULL, 0, snkey, keylen, 1);
}
/*
* Given the previous secret |prevsecret| and a new input secret |insecret| of
* length |insecretlen|, generate a new secret and store it in the location
@ -177,6 +215,7 @@ int tls13_generate_secret(SSL_CONNECTION *s, const EVP_MD *md,
/* ASCII: "derived", in hex for EBCDIC compatibility */
static const char derived_secret_label[] = "\x64\x65\x72\x69\x76\x65\x64";
SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s);
int isdtls = SSL_CONNECTION_IS_DTLS(s);
kdf = EVP_KDF_fetch(sctx->libctx, OSSL_KDF_NAME_TLS1_3_KDF, sctx->propq);
kctx = EVP_KDF_CTX_new(kdf);
@ -205,9 +244,15 @@ int tls13_generate_secret(SSL_CONNECTION *s, const EVP_MD *md,
if (prevsecret != NULL)
*p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT,
(unsigned char *)prevsecret, mdlen);
if (isdtls)
*p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_PREFIX,
(unsigned char *)label_prefix,
sizeof(label_prefix) - 1);
(unsigned char *)label_prefix_dtls13,
sizeof(label_prefix_dtls13) - 1);
else
*p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_PREFIX,
(unsigned char *)label_prefix_tls13,
sizeof(label_prefix_tls13) - 1);
*p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_LABEL,
(unsigned char *)derived_secret_label,
sizeof(derived_secret_label) - 1);
@ -322,13 +367,15 @@ size_t tls13_final_finish_mac(SSL_CONNECTION *s, const char *str, size_t slen,
int tls13_setup_key_block(SSL_CONNECTION *s)
{
const EVP_CIPHER *c;
const EVP_CIPHER *snc = NULL, **p_snc = SSL_CONNECTION_IS_DTLS(s) ? &snc : NULL;
size_t snoffs;
const EVP_MD *hash;
int mac_type = NID_undef;
size_t mac_secret_size = 0;
s->session->cipher = s->s3.tmp.new_cipher;
if (!ssl_cipher_get_evp(SSL_CONNECTION_GET_CTX(s), s->session, &c, &hash,
&mac_type, &mac_secret_size, NULL, 0)) {
if (!ssl_cipher_get_evp(SSL_CONNECTION_GET_CTX(s), s->session, p_snc, &snoffs, &c,
&hash, &mac_type, &mac_secret_size, NULL, 0)) {
/* Error is already recorded */
SSLfatal_alert(s, SSL_AD_INTERNAL_ERROR);
return 0;
@ -336,6 +383,9 @@ int tls13_setup_key_block(SSL_CONNECTION *s)
ssl_evp_cipher_free(s->s3.tmp.new_sym_enc);
s->s3.tmp.new_sym_enc = c;
ssl_evp_cipher_free(s->s3.tmp.new_sym_enc_sn);
s->s3.tmp.new_sym_enc_sn = snc;
s->s3.tmp.new_sym_enc_sn_offs = snoffs;
ssl_evp_md_free(s->s3.tmp.new_hash);
s->s3.tmp.new_hash = hash;
s->s3.tmp.new_mac_pkey_type = mac_type;
@ -352,6 +402,7 @@ static int derive_secret_key_and_iv(SSL_CONNECTION *s, const EVP_MD *md,
const unsigned char *hash,
const unsigned char *label,
size_t labellen, unsigned char *secret,
unsigned char *snkey,
unsigned char *key, size_t *keylen,
unsigned char **iv, size_t *ivlen,
size_t *taglen)
@ -437,7 +488,9 @@ static int derive_secret_key_and_iv(SSL_CONNECTION *s, const EVP_MD *md,
}
if (!tls13_derive_key(s, md, secret, key, *keylen)
|| !tls13_derive_iv(s, md, secret, *iv, *ivlen)) {
|| !tls13_derive_iv(s, md, secret, *iv, *ivlen)
|| (SSL_CONNECTION_IS_DTLS(s)
&& !dtls13_derive_snkey(s, md, secret, snkey, *keylen))) {
/* SSLfatal() already called */
return 0;
}
@ -466,6 +519,8 @@ int tls13_change_cipher_state(SSL_CONNECTION *s, int which)
unsigned char iv_intern[EVP_MAX_IV_LENGTH];
unsigned char *iv = iv_intern;
unsigned char key[EVP_MAX_KEY_LENGTH];
unsigned char snkey[EVP_MAX_KEY_LENGTH];
size_t sn_input_offs = 0;
unsigned char secret[EVP_MAX_MD_SIZE];
unsigned char hashval[EVP_MAX_MD_SIZE];
unsigned char *hash = hashval;
@ -477,7 +532,7 @@ int tls13_change_cipher_state(SSL_CONNECTION *s, int which)
size_t labellen, hashlen = 0;
int ret = 0;
const EVP_MD *md = NULL, *mac_md = NULL;
const EVP_CIPHER *cipher = NULL;
const EVP_CIPHER *cipher = NULL, *sncipher = NULL;
int mac_pkey_type = NID_undef;
SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s);
size_t keylen, ivlen = EVP_MAX_IV_LENGTH, taglen;
@ -530,7 +585,10 @@ int tls13_change_cipher_state(SSL_CONNECTION *s, int which)
* This ups the ref count on cipher so we better make sure we free
* it again
*/
if (!ssl_cipher_get_evp_cipher(sctx, sslcipher, &cipher)) {
if (!ssl_cipher_get_evp_cipher(sctx, sslcipher, &cipher)
|| (SSL_CONNECTION_IS_DTLS(s)
&& !ssl_cipher_get_evp_cipher_sn(sctx, sslcipher, &sncipher,
&sn_input_offs))) {
/* Error is already recorded */
SSLfatal_alert(s, SSL_AD_INTERNAL_ERROR);
goto err;
@ -640,6 +698,11 @@ int tls13_change_cipher_state(SSL_CONNECTION *s, int which)
cipher = s->s3.tmp.new_sym_enc;
mac_md = s->s3.tmp.new_hash;
mac_pkey_type = s->s3.tmp.new_mac_pkey_type;
if (SSL_CONNECTION_IS_DTLS(s)) {
sncipher = s->s3.tmp.new_sym_enc_sn;
sn_input_offs = s->s3.tmp.new_sym_enc_sn_offs;
}
if (!ssl3_digest_cached_records(s, 1)
|| !ssl_handshake_hash(s, hashval, sizeof(hashval), &hashlen)) {
/* SSLfatal() already called */;
@ -677,8 +740,8 @@ int tls13_change_cipher_state(SSL_CONNECTION *s, int which)
goto err;
if (!derive_secret_key_and_iv(s, md, cipher, mac_pkey_type, mac_md,
insecret, hash, label, labellen, secret, key,
&keylen, &iv, &ivlen, &taglen)) {
insecret, hash, label, labellen, secret,
snkey, key, &keylen, &iv, &ivlen, &taglen)) {
/* SSLfatal() already called */
goto err;
}
@ -728,10 +791,28 @@ int tls13_change_cipher_state(SSL_CONNECTION *s, int which)
? OSSL_RECORD_PROTECTION_LEVEL_HANDSHAKE
: OSSL_RECORD_PROTECTION_LEVEL_APPLICATION);
if (!ssl_set_new_record_layer(s, s->version,
direction,
level, secret, hashlen, key, keylen, iv,
ivlen, NULL, 0, cipher, taglen,
if (SSL_CONNECTION_IS_DTLS(s)) {
/* We have moved to the next flight lets clear out old messages */
if (direction == OSSL_RECORD_DIRECTION_READ)
dtls1_clear_received_buffer(s);
else
dtls1_clear_sent_buffer(s);
dtls1_increment_epoch(s, which);
if (level == OSSL_RECORD_PROTECTION_LEVEL_HANDSHAKE
&& dtls1_get_epoch(s, which) == 1) {
/*
* We must manually increment epoch because
* client early traffic was not sent/recv
*/
dtls1_increment_epoch(s, which);
}
}
if (!ssl_set_new_record_layer(s, s->version, direction, level, secret,
hashlen, snkey, key, keylen, iv, ivlen,
NULL, 0, sncipher, sn_input_offs, cipher, taglen,
mac_pkey_type, mac_md, NULL, md)) {
/* SSLfatal already called */
goto err;
@ -744,8 +825,10 @@ int tls13_change_cipher_state(SSL_CONNECTION *s, int which)
if ((EVP_CIPHER_flags(cipher) & EVP_CIPH_FLAG_AEAD_CIPHER) == 0)
ssl_evp_md_free(mac_md);
ssl_evp_cipher_free(cipher);
ssl_evp_cipher_free(sncipher);
}
OPENSSL_cleanse(key, sizeof(key));
OPENSSL_cleanse(snkey, sizeof(snkey));
OPENSSL_cleanse(secret, sizeof(secret));
if (iv != iv_intern)
OPENSSL_free(iv);
@ -759,6 +842,9 @@ int tls13_update_key(SSL_CONNECTION *s, int sending)
const EVP_MD *md = ssl_handshake_md(s);
size_t hashlen;
unsigned char key[EVP_MAX_KEY_LENGTH];
unsigned char snkey[EVP_MAX_KEY_LENGTH];
const EVP_CIPHER *snenc = NULL;
size_t snoffs = 0;
unsigned char *insecret;
unsigned char secret[EVP_MAX_MD_SIZE];
char *log_label;
@ -766,6 +852,7 @@ int tls13_update_key(SSL_CONNECTION *s, int sending)
int ret = 0, l;
int direction = sending ? OSSL_RECORD_DIRECTION_WRITE
: OSSL_RECORD_DIRECTION_READ;
int which = sending ? SSL3_CC_WRITE : SSL3_CC_READ;
unsigned char iv_intern[EVP_MAX_IV_LENGTH];
unsigned char *iv = iv_intern;
@ -785,20 +872,27 @@ int tls13_update_key(SSL_CONNECTION *s, int sending)
s->s3.tmp.new_mac_pkey_type, s->s3.tmp.new_hash,
insecret, NULL,
application_traffic,
sizeof(application_traffic) - 1, secret, key,
&keylen, &iv, &ivlen, &taglen)) {
sizeof(application_traffic) - 1, secret, snkey,
key, &keylen, &iv, &ivlen, &taglen)) {
/* SSLfatal() already called */
goto err;
}
memcpy(insecret, secret, hashlen);
if (!ssl_set_new_record_layer(s, s->version,
direction,
if (SSL_CONNECTION_IS_DTLS(s)) {
dtls1_increment_epoch(s, which);
snenc = s->s3.tmp.new_sym_enc_sn;
snoffs = s->s3.tmp.new_sym_enc_sn_offs;
}
if (!ssl_set_new_record_layer(s, s->version, direction,
OSSL_RECORD_PROTECTION_LEVEL_APPLICATION,
insecret, hashlen, key, keylen, iv, ivlen, NULL, 0,
s->s3.tmp.new_sym_enc, taglen, NID_undef, NULL,
NULL, md)) {
insecret, hashlen, snkey, key, keylen,
iv, ivlen, NULL, 0,
snenc, snoffs,
s->s3.tmp.new_sym_enc,
taglen, NID_undef, NULL, NULL, md)) {
/* SSLfatal already called */
goto err;
}
@ -812,6 +906,7 @@ int tls13_update_key(SSL_CONNECTION *s, int sending)
ret = 1;
err:
OPENSSL_cleanse(key, sizeof(key));
OPENSSL_cleanse(snkey, sizeof(snkey));
OPENSSL_cleanse(secret, sizeof(secret));
if (iv != iv_intern)
OPENSSL_free(iv);

View file

@ -110,7 +110,12 @@ static int mtu_test(SSL_CTX *ctx, const char *cs, int no_etm)
for (i = 0; i < 30; i++) {
/* DTLS_get_data_mtu() with record MTU 500+i returned mtus[i] ... */
if (!TEST_false(s <= mtus[i] && reclen > (size_t)(500 + i))) {
/**
* TODO(DTLSv1.3): This check fails with message:
* PSK-AES256-GCM-SHA384: s=471, mtus[i]=471, reclen=501, i=500
*/
if (!TEST_false(s <= mtus[i] && reclen > (size_t)(500 + i))
&& SSL_version(clnt_ssl) != DTLS1_3_VERSION) {
/*
* We sent a packet smaller than or equal to mtus[j] and
* that made a record *larger* than the record MTU 500+j!
@ -212,6 +217,13 @@ static int test_server_mtu_larger_than_max_fragment_length(void)
NULL, NULL)))
goto end;
/**
* TODO(DTLSv1.3): Test fails with
* SSL routines:tls_parse_ctos_maxfragmentlen:ssl3 ext invalid max fragment length:
* ssl/statem/extensions_srvr.c:202:
*/
OPENSSL_assert(SSL_set_max_proto_version(clnt_ssl, DTLS1_2_VERSION) == 1);
SSL_set_options(srvr_ssl, SSL_OP_NO_QUERY_MTU);
if (!TEST_true(DTLS_set_link_mtu(srvr_ssl, 1500)))
goto end;

View file

@ -77,9 +77,15 @@ static int test_dtls_unprocessed(int testidx)
timer_cb_count = 0;
/**
* TODO(DTLSv1.3): Tests fails with
* # No progress made
* # ERROR: (bool) 'create_bare_ssl_connection(serverssl1, clientssl1,
* SSL_ERROR_NONE, 0, 0) == true' failed @ ../test/dtlstest.c:128
*/
if (!TEST_true(create_ssl_ctx_pair(NULL, DTLS_server_method(),
DTLS_client_method(),
DTLS1_VERSION, 0,
DTLS1_VERSION, DTLS1_2_VERSION,
&sctx, &cctx, cert, privkey)))
return 0;
@ -199,9 +205,15 @@ static int test_dtls_drop_records(int idx)
int cli_to_srv_cookie, cli_to_srv_epoch0, cli_to_srv_epoch1;
int srv_to_cli_epoch0;
/**
* TODO(DTLSv1.3): Tests fails with
* dtls1_read_bytes:ssl/tls alert unexpected message:
* ssl/record/rec_layer_d1.c:454:SSL alert number 10
* And "no progress made"
*/
if (!TEST_true(create_ssl_ctx_pair(NULL, DTLS_server_method(),
DTLS_client_method(),
DTLS1_VERSION, 0,
DTLS1_VERSION, DTLS1_2_VERSION,
&sctx, &cctx, cert, privkey)))
return 0;
@ -322,7 +334,7 @@ static int test_cookie(void)
SSL_CTX_set_cookie_generate_cb(sctx, generate_cookie_cb);
SSL_CTX_set_cookie_verify_cb(sctx, verify_cookie_cb);
#ifdef OPENSSL_NO_DTLS1_2
#if defined(OPENSSL_NO_DTLS1_2) && defined(OPENSSL_NO_DTLS1_3)
/* Default sigalgs are SHA1 based in <DTLS1.2 which is in security level 0 */
if (!TEST_true(SSL_CTX_set_cipher_list(sctx, "DEFAULT:@SECLEVEL=0"))
|| !TEST_true(SSL_CTX_set_cipher_list(cctx,
@ -352,9 +364,13 @@ static int test_dtls_duplicate_records(void)
SSL *serverssl = NULL, *clientssl = NULL;
int testresult = 0;
/**
* TODO(DTLSv1.3): Tests fails with
* dtls1_read_bytes:unexpected record:../ssl/record/rec_layer_d1.c:609:
*/
if (!TEST_true(create_ssl_ctx_pair(NULL, DTLS_server_method(),
DTLS_client_method(),
DTLS1_VERSION, 0,
DTLS1_VERSION, DTLS1_2_VERSION,
&sctx, &cctx, cert, privkey)))
return 0;
@ -425,7 +441,7 @@ static int test_just_finished(void)
&sctx, NULL, cert, privkey)))
return 0;
#ifdef OPENSSL_NO_DTLS1_2
#if defined(OPENSSL_NO_DTLS1_2) && defined(OPENSSL_NO_DTLS1_3)
/* DTLSv1 is not allowed at the default security level */
if (!TEST_true(SSL_CTX_set_cipher_list(sctx, "DEFAULT:@SECLEVEL=0")))
goto end;
@ -484,9 +500,12 @@ static int test_swap_records(int idx)
char msg[] = { 0x00, 0x01, 0x02, 0x03 };
char buf[10];
/**
* TODO(DTLSv1.3): Tests fails
*/
if (!TEST_true(create_ssl_ctx_pair(NULL, DTLS_server_method(),
DTLS_client_method(),
DTLS1_VERSION, 0,
DTLS1_VERSION, DTLS1_2_VERSION,
&sctx, &cctx, cert, privkey)))
return 0;

View file

@ -156,6 +156,7 @@ static const test_enum ssl_protocols[] = {
{"SSLv3", SSL3_VERSION},
{"DTLSv1", DTLS1_VERSION},
{"DTLSv1.2", DTLS1_2_VERSION},
{"DTLSv1.3", DTLS1_3_VERSION},
};
__owur static int parse_protocol(SSL_TEST_CTX *test_ctx, const char *value)

View file

@ -120,6 +120,21 @@ static void copy_flags(BIO *bio)
#define MSG_FRAG_LEN_MID 10
#define MSG_FRAG_LEN_LO 11
/* Returns true if the unified header fixed bits are set (rfc9147 section 4) */
#define DTLS13_UNI_HDR_FIX_BITS_IS_SET(byte) \
(((byte) & DTLS13_UNI_HDR_FIX_BITS_MASK) == DTLS13_UNI_HDR_FIX_BITS)
/* Returns true if the unified header connection id bit is set (rfc9147 section 4) */
#define DTLS13_UNI_HDR_CID_BIT_IS_SET(byte) \
(((byte) & DTLS13_UNI_HDR_CID_BIT) == DTLS13_UNI_HDR_CID_BIT)
/* Returns true if the unified header sequence number bit is set (rfc9147 section 4) */
#define DTLS13_UNI_HDR_SEQ_BIT_IS_SET(byte) \
(((byte) & DTLS13_UNI_HDR_SEQ_BIT) == DTLS13_UNI_HDR_SEQ_BIT)
/* Returns true if the unified header length bit is set (rfc9147 section 4) */
#define DTLS13_UNI_HDR_LEN_BIT_IS_SET(byte) \
(((byte) & DTLS13_UNI_HDR_LEN_BIT) == DTLS13_UNI_HDR_LEN_BIT)
static void dump_data(const char *data, int len)
{
@ -135,6 +150,9 @@ static void dump_data(const char *data, int len)
if (rem != len)
printf("*\n");
printf("*---- START OF RECORD ----\n");
/*
* TODO(DTLSv1.3): support variable length headers
*/
if (rem < DTLS1_RT_HEADER_LENGTH) {
printf("*---- RECORD TRUNCATED ----\n");
break;
@ -543,8 +561,22 @@ int mempacket_test_inject(BIO *bio, const char *in, int inl, int pktnum,
MEMPACKET *thispkt = NULL, *looppkt, *nextpkt, *allpkts[3];
int i, duprec;
const unsigned char *inu = (const unsigned char *)in;
size_t len = ((inu[RECORD_LEN_HI] << 8) | inu[RECORD_LEN_LO])
+ DTLS1_RT_HEADER_LENGTH;
size_t len;
if (DTLS13_UNI_HDR_FIX_BITS_IS_SET(*in)
/* The following code does not handle connection ids */
&& ossl_assert(!DTLS13_UNI_HDR_CID_BIT_IS_SET(*in))) {
if (DTLS13_UNI_HDR_LEN_BIT_IS_SET(*in)) {
len = 3; /* 2 bytes for len field and 1 byte for record type */
len += DTLS13_UNI_HDR_SEQ_BIT_IS_SET(*in) ? 2 : 1;
} else {
/* We assert that inl is the correct record length */
len = inl;
}
} else {
len = ((inu[RECORD_LEN_HI] << 8) | inu[RECORD_LEN_LO]);
len += DTLS1_RT_HEADER_LENGTH;
}
if (ctx == NULL)
return -1;

View file

@ -0,0 +1,114 @@
#! /usr/bin/env perl
# Copyright 2024 The OpenSSL Project Authors. All Rights Reserved.
#
# Licensed under the Apache License 2.0 (the "License"). You may not use
# this file except in compliance with the License. You can obtain a copy
# in the file LICENSE in the source distribution or at
# https://www.openssl.org/source/license.html
use strict;
use feature 'state';
use OpenSSL::Test qw/:DEFAULT cmdstr srctop_file bldtop_dir/;
use OpenSSL::Test::Utils;
use TLSProxy::Proxy;
use TLSProxy::Message;
my $test_name = "test_dtls13epoch";
setup($test_name);
plan skip_all => "DTLSProxy isn't usable on $^O"
if ($^O =~ /^(VMS)$/) || ($^O =~ /^(MSWin32)$/);
plan skip_all => "$test_name needs the dynamic engine feature enabled"
if disabled("engine") || disabled("dynamic-engine");
plan skip_all => "$test_name needs the sock feature enabled"
if disabled("sock");
plan skip_all => "$test_name needs DTLSv1.3 enabled"
if disabled("dtls1_3");
my $proxy = TLSProxy::Proxy->new_dtls(
undef,
cmdstr(app(["openssl"]), display => 1),
srctop_file("apps", "server.pem"),
(!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE})
);
plan tests => 1;
my $epoch_check_failed;
my $latest_epoch;
#Test 1: Check that epoch is incremented as expected during a handshake
$epoch_check_failed = 0;
$latest_epoch = 0;
$proxy->serverflags("-min_protocol DTLSv1.3 -max_protocol DTLSv1.3");
$proxy->clientflags("-min_protocol DTLSv1.3 -max_protocol DTLSv1.3");
$proxy->filter(\&current_record_epoch_filter);
TLSProxy::Message->successondata(1);
skip "TLS Proxy did not start", 1 if !$proxy->start();
ok(!$epoch_check_failed
&& $latest_epoch == 3, "Epoch changes correctly during handshake");
sub current_record_epoch_filter
{
my $records = $proxy->record_list;
my $latest_record = @{$records}[-1];
my $epoch = $latest_record->epoch;
my @badmessagetypes = undef;
$latest_epoch = $epoch;
if ($epoch == 0) {
@badmessagetypes = (
TLSProxy::Message::MT_NEW_SESSION_TICKET,
TLSProxy::Message::MT_ENCRYPTED_EXTENSIONS,
TLSProxy::Message::MT_CERTIFICATE,
TLSProxy::Message::MT_SERVER_KEY_EXCHANGE,
TLSProxy::Message::MT_CERTIFICATE_REQUEST,
TLSProxy::Message::MT_SERVER_HELLO_DONE,
TLSProxy::Message::MT_CERTIFICATE_VERIFY,
TLSProxy::Message::MT_CLIENT_KEY_EXCHANGE,
TLSProxy::Message::MT_FINISHED,
TLSProxy::Message::MT_CERTIFICATE_STATUS,
TLSProxy::Message::MT_COMPRESSED_CERTIFICATE,
TLSProxy::Message::MT_NEXT_PROTO
);
} elsif ($epoch == 1) {
@badmessagetypes = (
TLSProxy::Message::MT_NEW_SESSION_TICKET,
TLSProxy::Message::MT_ENCRYPTED_EXTENSIONS,
TLSProxy::Message::MT_CERTIFICATE,
TLSProxy::Message::MT_SERVER_KEY_EXCHANGE,
TLSProxy::Message::MT_CERTIFICATE_REQUEST,
TLSProxy::Message::MT_SERVER_HELLO_DONE,
TLSProxy::Message::MT_CERTIFICATE_VERIFY,
TLSProxy::Message::MT_CLIENT_KEY_EXCHANGE,
TLSProxy::Message::MT_FINISHED,
TLSProxy::Message::MT_CERTIFICATE_STATUS,
TLSProxy::Message::MT_COMPRESSED_CERTIFICATE,
TLSProxy::Message::MT_NEXT_PROTO
);
} elsif ($epoch == 2) {
@badmessagetypes = (
TLSProxy::Message::MT_NEW_SESSION_TICKET,
TLSProxy::Message::MT_CERTIFICATE_STATUS,
TLSProxy::Message::MT_COMPRESSED_CERTIFICATE,
TLSProxy::Message::MT_NEXT_PROTO
);
}
# Check that message types are acceptable
foreach (@{$proxy->message_list})
{
my $mt = $_->mt;
if (grep(/^$mt$/, @badmessagetypes)) {
print "Did not expect $mt in epoch $latest_epoch\n";
$epoch_check_failed = 1;
}
}
}

View file

@ -23,23 +23,64 @@ plan skip_all => "$test_name needs the dynamic engine feature enabled"
plan skip_all => "$test_name needs the sock feature enabled"
if disabled("sock");
plan skip_all => "$test_name needs TLS1.3 enabled"
if disabled("tls1_3") || (disabled("ec") && disabled("dh"));
plan skip_all => "$test_name needs elliptic curves or diffie-hellman enabled"
if disabled("ec") && disabled("dh");
my $proxy = TLSProxy::Proxy->new(
my $testcount = 1;
plan tests => 2 * $testcount;
SKIP: {
skip "TLS 1.3 is disabled", $testcount if disabled("tls1_3");
# Run tests with TLS
run_tests(0);
}
SKIP: {
skip "DTLS 1.3 is disabled", $testcount if disabled("dtls1_3");
skip "DTLSProxy does not work on Windows", $testcount if $^O =~ /^(MSWin32)$/;
run_tests(1);
}
sub run_tests
{
my $run_test_as_dtls = shift;
my $proxy_start_success = 0;
my $proxy;
if ($run_test_as_dtls == 1) {
$proxy = TLSProxy::Proxy->new_dtls(
undef,
cmdstr(app([ "openssl" ]), display => 1),
srctop_file("apps", "server.pem"),
(!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE})
);
}
else {
$proxy = TLSProxy::Proxy->new(
undef,
cmdstr(app(["openssl"]), display => 1),
srctop_file("apps", "server.pem"),
(!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE})
);
);
}
#Test 1: We test that a server can handle an unencrypted alert when normally the
# next message is encrypted
$proxy->filter(\&alert_filter);
$proxy->start() or plan skip_all => "Unable to start up Proxy for tests";
plan tests => 1;
my $alert = TLSProxy::Message->alert();
ok(TLSProxy::Message->fail() && !$alert->server() && !$alert->encrypted(), "Client sends an unencrypted alert");
SKIP: {
skip "TODO(DTLSv1.3): Test fails because client sends alert with 0 epoch but"
. " the server increments the epoch after sending ServerHello and thus"
. " does not accept the alert message.",
$testcount if $run_test_as_dtls == 1;
#Test 1: We test that a server can handle an unencrypted alert when normally the
# next message is encrypted
$proxy->clear();
$proxy->filter(\&alert_filter);
$proxy_start_success = $proxy->start();
skip "TLSProxy did not start correctly", $testcount if $proxy_start_success == 0;
my $alert = TLSProxy::Message->alert();
ok(TLSProxy::Message->fail() && !$alert->server() && !$alert->encrypted(), "Client sends an unencrypted alert");
}
}
sub alert_filter
{

View file

@ -206,93 +206,131 @@ plan skip_all => "$test_name needs compression and algorithms enabled"
[0,0,0,0]
);
my $proxy = TLSProxy::Proxy->new(
my $testcount = 8;
plan tests => 2 * $testcount;
SKIP: {
skip "TLS 1.3 is disabled", $testcount if disabled("tls1_3");
# Run tests with TLS
run_tests(0);
}
SKIP: {
skip "DTLS 1.3 is disabled", $testcount if disabled("dtls1_3");
skip "DTLSProxy does not work on Windows", $testcount if $^O =~ /^(MSWin32)$/;
run_tests(1);
}
sub run_tests
{
my $run_test_as_dtls = shift;
my $proxy_start_success = 0;
my $proxy;
if ($run_test_as_dtls == 1) {
$proxy = TLSProxy::Proxy->new_dtls(
undef,
cmdstr(app(["openssl"]), display => 1),
cmdstr(app([ "openssl" ]), display => 1),
srctop_file("apps", "server.pem"),
(!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE})
);
);
}
else {
$proxy = TLSProxy::Proxy->new(
undef,
cmdstr(app([ "openssl" ]), display => 1),
srctop_file("apps", "server.pem"),
(!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE})
);
}
$proxy->clear();
#Test 1: Client sends cert comp, but no client auth
$proxy->serverconnects(2);
$proxy->clear();
$proxy->serverflags("-no_tx_cert_comp -no_rx_cert_comp");
# One final skip check
$proxy->start() or plan skip_all => "Unable to start up Proxy for tests";
plan tests => 8;
checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
#Test 1: Client sends cert comp, but no client auth
$proxy->serverconnects(2);
$proxy->clear();
$proxy->serverflags("-no_tx_cert_comp -no_rx_cert_comp");
# One final skip check
$proxy_start_success = $proxy->start();
skip "TLSProxy did not start correctly", $testcount if $proxy_start_success == 0;
checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
checkhandshake::DEFAULT_EXTENSIONS
| checkhandshake::CERT_COMP_CLI_EXTENSION,
"Client supports certificate compression");
#Test 2: Server sends cert comp, no client auth
$proxy->clear();
$proxy->clientflags("-no_tx_cert_comp -no_rx_cert_comp");
$proxy->serverflags("-cert_comp");
$proxy->start();
checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
#Test 2: Server sends cert comp, no client auth
$proxy->clear();
$proxy->clientflags("-no_tx_cert_comp -no_rx_cert_comp");
$proxy->serverflags("-cert_comp");
$proxy->start();
checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
checkhandshake::DEFAULT_EXTENSIONS
| checkhandshake::CERT_COMP_SRV_EXTENSION,
"Server supports certificate compression, but no client auth");
#Test 3: Both send cert comp, no client auth
$proxy->clear();
$proxy->serverflags("-cert_comp");
$proxy->start();
checkhandshake($proxy, checkhandshake::CERT_COMP_SRV_HANDSHAKE,
#Test 3: Both send cert comp, no client auth
$proxy->clear();
$proxy->serverflags("-cert_comp");
$proxy->start();
checkhandshake($proxy, checkhandshake::CERT_COMP_SRV_HANDSHAKE,
checkhandshake::DEFAULT_EXTENSIONS
| checkhandshake::CERT_COMP_CLI_EXTENSION
| checkhandshake::CERT_COMP_SRV_EXTENSION,
"Both support certificate compression, but no client auth");
#Test 4: Both send cert comp, with client auth
$proxy->clear();
$proxy->clientflags("-cert ".srctop_file("apps", "server.pem"));
$proxy->serverflags("-Verify 5 -cert_comp");
$proxy->start();
checkhandshake($proxy, checkhandshake::CERT_COMP_BOTH_HANDSHAKE,
SKIP: {
skip "TODO(DTLSv1.3): Server hangs on client certificate + finish", 2
if $run_test_as_dtls == 1;
#Test 4: Both send cert comp, with client auth
$proxy->clear();
$proxy->clientflags("-cert " . srctop_file("apps", "server.pem"));
$proxy->serverflags("-Verify 5 -cert_comp");
$proxy->start();
checkhandshake($proxy, checkhandshake::CERT_COMP_BOTH_HANDSHAKE,
checkhandshake::DEFAULT_EXTENSIONS
| checkhandshake::CERT_COMP_CLI_EXTENSION
| checkhandshake::CERT_COMP_SRV_EXTENSION,
"Both support certificate compression, with client auth");
#Test 5: Client-to-server-only certificate compression, with client auth
$proxy->clear();
$proxy->clientflags("-no_rx_cert_comp -cert ".srctop_file("apps", "server.pem"));
$proxy->serverflags("-no_tx_cert_comp -Verify 5 -cert_comp");
$proxy->start();
checkhandshake($proxy, checkhandshake::CERT_COMP_CLI_HANDSHAKE,
#Test 5: Client-to-server-only certificate compression, with client auth
$proxy->clear();
$proxy->clientflags("-no_rx_cert_comp -cert " . srctop_file("apps", "server.pem"));
$proxy->serverflags("-no_tx_cert_comp -Verify 5 -cert_comp");
$proxy->start();
checkhandshake($proxy, checkhandshake::CERT_COMP_CLI_HANDSHAKE,
checkhandshake::DEFAULT_EXTENSIONS
| checkhandshake::CERT_COMP_SRV_EXTENSION,
"Client-to-server-only certificate compression, with client auth");
}
#Test 6: Server-to-client-only certificate compression
$proxy->clear();
$proxy->clientflags("-no_tx_cert_comp");
$proxy->serverflags("-no_rx_cert_comp -cert_comp");
$proxy->start();
checkhandshake($proxy, checkhandshake::CERT_COMP_SRV_HANDSHAKE,
#Test 6: Server-to-client-only certificate compression
$proxy->clear();
$proxy->clientflags("-no_tx_cert_comp");
$proxy->serverflags("-no_rx_cert_comp -cert_comp");
$proxy->start();
checkhandshake($proxy, checkhandshake::CERT_COMP_SRV_HANDSHAKE,
checkhandshake::DEFAULT_EXTENSIONS
| checkhandshake::CERT_COMP_CLI_EXTENSION,
"Server-to-client-only certificate compression");
#Test 7: Neither side wants to send a compressed cert, but will accept one
$proxy->clear();
$proxy->clientflags("-no_tx_cert_comp");
$proxy->serverflags("-no_tx_cert_comp -cert_comp");
$proxy->start();
checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
#Test 7: Neither side wants to send a compressed cert, but will accept one
$proxy->clear();
$proxy->clientflags("-no_tx_cert_comp");
$proxy->serverflags("-no_tx_cert_comp -cert_comp");
$proxy->start();
checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
checkhandshake::DEFAULT_EXTENSIONS
| checkhandshake::CERT_COMP_CLI_EXTENSION
| checkhandshake::CERT_COMP_SRV_EXTENSION,
"Accept but not send compressed certificates");
#Test 8: Neither side wants to receive a compressed cert, but will send one
$proxy->clear();
$proxy->clientflags("-no_rx_cert_comp");
$proxy->serverflags("-no_rx_cert_comp -cert_comp");
$proxy->start();
checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
#Test 8: Neither side wants to receive a compressed cert, but will send one
$proxy->clear();
$proxy->clientflags("-no_rx_cert_comp");
$proxy->serverflags("-no_rx_cert_comp -cert_comp");
$proxy->start();
checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
checkhandshake::DEFAULT_EXTENSIONS,
"Send but not accept compressed certificates");
}

View file

@ -23,50 +23,83 @@ plan skip_all => "$test_name needs the dynamic engine feature enabled"
plan skip_all => "$test_name needs the sock feature enabled"
if disabled("sock");
plan skip_all => "$test_name needs TLS1.3 enabled"
if disabled("tls1_3") || (disabled("ec") && disabled("dh"));
plan skip_all => "$test_name needs EC or DH enabled"
if disabled("ec") && disabled("dh");
my $testcount = 2;
plan tests => 2 * $testcount;
SKIP: {
skip "TLS 1.3 is disabled", $testcount if disabled("tls1_3");
# Run tests with TLS
run_tests(0);
}
SKIP: {
skip "DTLS 1.3 is disabled", $testcount if disabled("dtls1_3");
skip "DTLSProxy does not work on Windows", $testcount if $^O =~ /^(MSWin32)$/;
run_tests(1);
}
use constant {
COOKIE_ONLY => 0,
COOKIE_AND_KEY_SHARE => 1
};
my $proxy = TLSProxy::Proxy->new(
undef,
cmdstr(app(["openssl"]), display => 1),
srctop_file("apps", "server.pem"),
(!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE})
);
my $cookieseen = 0;
my $testtype;
#Test 1: Inserting a cookie into an HRR should see it echoed in the ClientHello
$testtype = COOKIE_ONLY;
$proxy->filter(\&cookie_filter);
$proxy->serverflags("-curves X25519") if !disabled("ecx");
$proxy->start() or plan skip_all => "Unable to start up Proxy for tests";
plan tests => 2;
SKIP: {
sub run_tests
{
my $run_test_as_dtls = shift;
my $proxy_start_success = 0;
my $proxy;
if ($run_test_as_dtls == 1) {
$proxy = TLSProxy::Proxy->new_dtls(
undef,
cmdstr(app([ "openssl" ]), display => 1),
srctop_file("apps", "server.pem"),
(!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE})
);
}
else {
$proxy = TLSProxy::Proxy->new(
undef,
cmdstr(app([ "openssl" ]), display => 1),
srctop_file("apps", "server.pem"),
(!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE})
);
}
#Test 1: Inserting a cookie into an HRR should see it echoed in the ClientHello
$testtype = COOKIE_ONLY;
$proxy->clear();
$proxy->filter(\&cookie_filter);
$proxy->serverflags("-curves X25519") if !disabled("ecx");
$proxy_start_success = $proxy->start();
skip "TLSProxy did not start correctly", $testcount if $proxy_start_success == 0;
SKIP: {
skip "ECX disabled", 1, if (disabled("ecx"));
ok(TLSProxy::Message->success() && $cookieseen == 1, "Cookie seen");
}
}
#Test 2: Same as test 1 but should also work where a new key_share is also
# required
$testtype = COOKIE_AND_KEY_SHARE;
$proxy->clear();
if (disabled("ecx")) {
#Test 2: Same as test 1 but should also work where a new key_share is also
# required
$testtype = COOKIE_AND_KEY_SHARE;
$proxy->clear();
if (disabled("ecx")) {
$proxy->clientflags("-curves ffdhe3072:ffdhe2048");
$proxy->serverflags("-curves ffdhe2048");
} else {
}
else {
$proxy->clientflags("-curves P-256:X25519");
$proxy->serverflags("-curves X25519");
}
$proxy->start();
ok(TLSProxy::Message->success() && $cookieseen == 1, "Cookie seen");
}
$proxy->start();
ok(TLSProxy::Message->success() && $cookieseen == 1, "Cookie seen");
sub cookie_filter
{

View file

@ -23,17 +23,8 @@ plan skip_all => "$test_name needs the dynamic engine feature enabled"
plan skip_all => "$test_name needs the sock feature enabled"
if disabled("sock");
plan skip_all => "$test_name needs TLS1.3 and TLS1.2 enabled"
if disabled("tls1_3")
|| (disabled("ec") && disabled("dh"))
|| disabled("tls1_2");
my $proxy = TLSProxy::Proxy->new(
undef,
cmdstr(app(["openssl"]), display => 1),
srctop_file("apps", "server.pem"),
(!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE})
);
plan skip_all => "$test_name needs EC or DH enabled"
if disabled("ec") && disabled("dh");
use constant {
DOWNGRADE_TO_TLS_1_2 => 0,
@ -41,82 +32,143 @@ use constant {
FALLBACK_FROM_TLS_1_3 => 2,
};
#Test 1: Downgrade from TLSv1.3 to TLSv1.2
$proxy->filter(\&downgrade_filter);
my $testtype = DOWNGRADE_TO_TLS_1_2;
$proxy->start() or plan skip_all => "Unable to start up Proxy for tests";
plan tests => 6;
ok(TLSProxy::Message->fail(), "Downgrade TLSv1.3 to TLSv1.2");
my $testcount = 6;
plan tests => 2 * $testcount;
#Test 2: Downgrade from TLSv1.3 to TLSv1.1
$proxy->clear();
$testtype = DOWNGRADE_TO_TLS_1_1;
$proxy->start();
ok(TLSProxy::Message->fail(), "Downgrade TLSv1.3 to TLSv1.1");
#Test 3: Downgrade from TLSv1.2 to TLSv1.1
$proxy->clear();
$proxy->clientflags("-no_tls1_3");
$proxy->serverflags("-no_tls1_3");
$proxy->start();
ok(TLSProxy::Message->fail(), "Downgrade TLSv1.2 to TLSv1.1");
#Test 4: Client falls back from TLSv1.3 (server does not support the fallback
# SCSV)
$proxy->clear();
$testtype = FALLBACK_FROM_TLS_1_3;
$proxy->clientflags("-fallback_scsv -no_tls1_3");
$proxy->start();
my $alert = TLSProxy::Message->alert();
ok(TLSProxy::Message->fail()
&& !$alert->server()
&& $alert->description() == TLSProxy::Message::AL_DESC_ILLEGAL_PARAMETER,
"Fallback from TLSv1.3");
my $testtype;
SKIP: {
skip "TLS 1.2 or 1.3 is disabled", $testcount if disabled("tls1_3")
|| disabled("tls1_2");
# Run tests with TLS
run_tests(0);
}
SKIP: {
skip "DTLS 1.2 or 1.3 is disabled", $testcount if disabled("dtls1_3")
|| disabled("dtls1_2");
skip "DTLSProxy does not work on Windows", $testcount if $^O =~ /^(MSWin32)$/;
run_tests(1);
}
sub run_tests
{
my $run_test_as_dtls = shift;
my $proto1_1 = $run_test_as_dtls == 1 ? "DTLSv1" : "TLSv1.1";
my $proto1_2 = $run_test_as_dtls == 1 ? "DTLSv1.2" : "TLSv1.2";
my $proto1_3 = $run_test_as_dtls == 1 ? "DTLSv1.3" : "TLSv1.3";
my $proxy;
if ($run_test_as_dtls == 1) {
$proxy = TLSProxy::Proxy->new_dtls(
undef,
cmdstr(app([ "openssl" ]), display => 1),
srctop_file("apps", "server.pem"),
(!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE})
);
} else {
$proxy = TLSProxy::Proxy->new(
undef,
cmdstr(app([ "openssl" ]), display => 1),
srctop_file("apps", "server.pem"),
(!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE})
);
}
#Test 1: Downgrade from (D)TLSv1.3 to (D)TLSv1.2
$proxy->clear();
$proxy->filter(\&downgrade_filter);
$testtype = DOWNGRADE_TO_TLS_1_2;
skip "Unable to start up Proxy for tests", $testcount if !$proxy->start() &&
!TLSProxy::Message->fail();
ok(TLSProxy::Message->fail(), "Downgrade ".$proto1_3." to ".$proto1_2);
#Test 2: Downgrade from (D)TLSv1.3 to TLSv1.1/DTLSv1
$proxy->clear();
$testtype = DOWNGRADE_TO_TLS_1_1;
$proxy->start();
ok(TLSProxy::Message->fail(), "Downgrade ".$proto1_3." to ".$proto1_1);
#Test 3: Downgrade from (D)TLSv1.2 to TLSv1.1/DTLSv1
$proxy->clear();
$proxy->clientflags("-max_protocol ".$proto1_2);
$proxy->serverflags("-max_protocol ".$proto1_2);
$proxy->start();
ok(TLSProxy::Message->fail(), "Downgrade ".$proto1_2." to ".$proto1_1);
#Test 4: Client falls back from (D)TLSv1.3 (server does not support the
# fallback SCSV)
$proxy->clear();
$testtype = FALLBACK_FROM_TLS_1_3;
$proxy->clientflags("-fallback_scsv -max_protocol ".$proto1_2);
$proxy->start();
my $alert = TLSProxy::Message->alert();
ok(TLSProxy::Message->fail()
&& !$alert->server()
&& $alert->description() == TLSProxy::Message::AL_DESC_ILLEGAL_PARAMETER,
"Fallback from ".$proto1_3);
SKIP: {
skip "TLSv1.1 disabled", 2 if disabled("tls1_1");
skip "Missing support for no_dtls1_2", 2 if $run_test_as_dtls == 1;
#Test 5: A client side protocol "hole" should not be detected as a downgrade
$proxy->clear();
$proxy->filter(undef);
$proxy->clientflags("-no_tls1_2");
$proxy->ciphers("AES128-SHA:\@SECLEVEL=0");
$proxy->start();
ok(TLSProxy::Message->success(), "TLSv1.2 client-side protocol hole");
ok(TLSProxy::Message->success(), $proto1_2." client-side protocol hole");
#Test 6: A server side protocol "hole" should not be detected as a downgrade
$proxy->clear();
$proxy->filter(undef);
$proxy->serverflags("-no_tls1_2");
$proxy->start();
ok(TLSProxy::Message->success(), "TLSv1.2 server-side protocol hole");
ok(TLSProxy::Message->success(), $proto1_2." server-side protocol hole");
}
}
sub downgrade_filter
{
my $proxy = shift;
# We're only interested in the initial ClientHello
if ($proxy->flight != 0) {
# We're only interested in the initial ClientHello except if we are expecting
# DTLS1.2 handshake in which case the client will send a second ClientHello
my $second_client_hello = $testtype == FALLBACK_FROM_TLS_1_3 && $proxy->isdtls
&& $proxy->flight == 2;
if ($proxy->flight != 0 && !$second_client_hello) {
return;
}
my $message = ${$proxy->message_list}[0];
my $message;
if ($second_client_hello == 0) {
$message = ${$proxy->message_list}[0];
} else {
$message = ${$proxy->message_list}[2];
}
my $ext;
if ($testtype == FALLBACK_FROM_TLS_1_3) {
#The default ciphersuite we use for TLSv1.2 without any SCSV
my @ciphersuites = (TLSProxy::Message::CIPHER_RSA_WITH_AES_128_CBC_SHA);
$message->ciphersuite_len(2 * scalar @ciphersuites);
$message->ciphersuites(\@ciphersuites);
} else {
my $ext;
my $version12hi = $proxy->isdtls == 1 ? 0xFE : 0x03;
my $version12lo = $proxy->isdtls == 1 ? 0xFD : 0x03;
my $version11hi = $proxy->isdtls == 1 ? 0xFE : 0x03;
my $version11lo = $proxy->isdtls == 1 ? 0xFF : 0x02;
if ($testtype == DOWNGRADE_TO_TLS_1_2) {
$ext = pack "C3",
0x02, # Length
0x03, 0x03; #TLSv1.2
$version12hi, $version12lo;
} else {
$ext = pack "C3",
0x02, # Length
0x03, 0x02; #TLSv1.1
$version11hi, $version11lo;
}
$message->set_extension(TLSProxy::Message::EXT_SUPPORTED_VERSIONS, $ext);

View file

@ -24,15 +24,12 @@ plan skip_all => "$test_name needs the dynamic engine feature enabled"
plan skip_all => "$test_name needs the sock feature enabled"
if disabled("sock");
plan skip_all => "$test_name needs TLS1.3 enabled"
if disabled("tls1_3") || (disabled("ec") && disabled("dh"));
plan skip_all => "$test_name needs elliptic curves or diffie-hellman enabled"
if disabled("ec") && disabled("dh");
my $proxy = TLSProxy::Proxy->new(
undef,
cmdstr(app(["openssl"]), display => 1),
srctop_file("apps", "server.pem"),
(!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE})
);
my $testcount = 5;
plan tests => 2 * $testcount;
use constant {
CHANGE_HRR_CIPHERSUITE => 0,
@ -42,54 +39,107 @@ use constant {
NO_SUPPORTED_VERSIONS => 4
};
#Test 1: A client should fail if the server changes the ciphersuite between the
# HRR and the SH
$proxy->filter(\&hrr_filter);
if (disabled("ec")) {
$proxy->serverflags("-curves ffdhe3072");
} else {
$proxy->serverflags("-curves P-256");
}
my $testtype = CHANGE_HRR_CIPHERSUITE;
$proxy->start() or plan skip_all => "Unable to start up Proxy for tests";
plan tests => 5;
ok(TLSProxy::Message->fail(), "Server ciphersuite changes");
#Test 2: It is an error if the client changes the offered ciphersuites so that
# we end up selecting a different ciphersuite between HRR and the SH
$proxy->clear();
if (disabled("ec")) {
$proxy->serverflags("-curves ffdhe3072");
} else {
$proxy->serverflags("-curves P-384");
}
$proxy->ciphersuitess("TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384");
$testtype = CHANGE_CH1_CIPHERSUITE;
$proxy->start();
ok(TLSProxy::Message->fail(), "Client ciphersuite changes");
#Test 3: A client should fail with unexpected_message alert if the server
# sends more than 1 HRR
my $fatal_alert = 0;
$proxy->clear();
if (disabled("ec")) {
$proxy->serverflags("-curves ffdhe3072");
} else {
$proxy->serverflags("-curves P-384");
}
$testtype = DUPLICATE_HRR;
$proxy->start();
ok($fatal_alert, "Server duplicated HRR");
my $testtype = -1;
#Test 4: If the client sends a group that is in the supported_groups list but
# otherwise not valid (e.g. not suitable for TLSv1.3) we should reject it
# and not consider it when sending the HRR. We send brainpoolP512r1 in
# the ClientHello, which is acceptable to the server but is not valid in
# TLSv1.3. We expect the server to select P-521 in the HRR and the
# handshake to complete successfully
SKIP: {
skip "EC/TLSv1.2 is disabled in this build", 1
if disabled("ec") || disabled("tls1_2");
skip "TLS 1.3 is disabled", $testcount if disabled("tls1_3");
# Run tests with TLS
run_tests(0);
}
SKIP: {
skip "DTLS 1.3 is disabled", $testcount if disabled("dtls1_3");
skip "DTLSProxy does not work on Windows", $testcount if $^O =~ /^(MSWin32)$/;
run_tests(1);
}
sub run_tests
{
my $run_test_as_dtls = shift;
my $proxy;
if ($run_test_as_dtls == 1) {
$proxy = TLSProxy::Proxy->new_dtls(
\&hrr_filter,
cmdstr(app([ "openssl" ]), display => 1),
srctop_file("apps", "server.pem"),
(!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE})
);
}
else {
$proxy = TLSProxy::Proxy->new(
\&hrr_filter,
cmdstr(app([ "openssl" ]), display => 1),
srctop_file("apps", "server.pem"),
(!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE})
);
}
SKIP: {
skip "TODO(DTLSv1.3): Test stalls when server sends its ServerHello.",
1 if $run_test_as_dtls == 1 && disabled("ecx");
#Test 1: A client should fail if the server changes the ciphersuite between the
# HRR and the SH
$proxy->clear();
if (disabled("ec")) {
$proxy->serverflags("-curves ffdhe3072");
}
else {
$proxy->serverflags("-curves P-256");
}
$testtype = CHANGE_HRR_CIPHERSUITE;
# Skip tests if TLSProxy if it fails to start. For DTLS this return is always
# false when the handshake fails so we skip the check.
skip "TLSProxy did not start correctly", $testcount if $proxy->start() == 0
&& $run_test_as_dtls == 0;
ok(TLSProxy::Message->fail(), "Server ciphersuite changes");
}
#Test 2: It is an error if the client changes the offered ciphersuites so that
# we end up selecting a different ciphersuite between HRR and the SH
$proxy->clear();
if (disabled("ec")) {
$proxy->serverflags("-curves ffdhe3072");
}
else {
$proxy->serverflags("-curves P-384");
}
$proxy->ciphersuitess("TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384");
$testtype = CHANGE_CH1_CIPHERSUITE;
$proxy->start();
ok(TLSProxy::Message->fail(), "Client ciphersuite changes");
SKIP: {
skip "TODO(DTLSv1.3): Re-enable when #26465 has been merged.",
1 if $run_test_as_dtls == 1;
#Test 3: A client should fail with unexpected_message alert if the server
# sends more than 1 HRR
$fatal_alert = 0;
$proxy->clear();
if (disabled("ec")) {
$proxy->serverflags("-curves ffdhe3072");
}
else {
$proxy->serverflags("-curves P-384");
}
$testtype = DUPLICATE_HRR;
$proxy->start();
ok($fatal_alert, "Server duplicated HRR");
}
#Test 4: If the client sends a group that is in the supported_groups list but
# otherwise not valid (e.g. not suitable for TLSv1.3) we should reject it
# and not consider it when sending the HRR. We send brainpoolP512r1 in
# the ClientHello, which is acceptable to the server but is not valid in
# TLSv1.3. We expect the server to select P-521 in the HRR and the
# handshake to complete successfully
SKIP: {
skip "EC/(D)TLSv1.2 is disabled in this build", 1
if disabled("ec") || ($run_test_as_dtls == 0 && disabled("tls1_2"))
|| $run_test_as_dtls == 1;
#TODO(DTLSv1.3): Fails when running with DTLS.
# || ($run_test_as_dtls == 1 && disabled("dtls1_2"));
$proxy->clear();
$proxy->clientflags("-groups P-256:brainpoolP512r1:P-521");
@ -97,20 +147,21 @@ SKIP: {
$testtype = INVALID_GROUP;
$proxy->start();
ok(TLSProxy::Message->success(), "Invalid group with HRR");
}
}
#Test 5: A failure should occur if an HRR is sent without the supported_versions
# extension
$fatal_alert = 0;
$proxy->clear();
if (disabled("ec")) {
#Test 5: A failure should occur if an HRR is sent without the supported_versions
# extension
$fatal_alert = 0;
$proxy->clear();
if (disabled("ec")) {
$proxy->serverflags("-curves ffdhe3072");
} else {
} else {
$proxy->serverflags("-curves P-384");
}
$testtype = NO_SUPPORTED_VERSIONS;
$proxy->start();
ok($fatal_alert, "supported_versions missing from HRR");
}
$testtype = NO_SUPPORTED_VERSIONS;
$proxy->start();
ok($fatal_alert, "supported_versions missing from HRR");
sub hrr_filter
{
@ -169,7 +220,23 @@ sub hrr_filter
next;
}
my $hrr_record = ${$proxy->record_list}[$i];
my $dup_hrr = TLSProxy::Record->new(3,
my $dup_hrr;
if ($proxy->isdtls()) {
$dup_hrr = TLSProxy::Record->new_dtls(3,
$hrr_record->content_type(),
$hrr_record->version(),
$hrr_record->epoch(),
$hrr_record->seq(),
$hrr_record->len(),
$hrr_record->sslv2(),
$hrr_record->len_real(),
$hrr_record->decrypt_len(),
$hrr_record->data(),
$hrr_record->decrypt_data());
} else {
$dup_hrr = TLSProxy::Record->new(3,
$hrr_record->content_type(),
$hrr_record->version(),
$hrr_record->len(),
@ -178,6 +245,7 @@ sub hrr_filter
$hrr_record->decrypt_len(),
$hrr_record->data(),
$hrr_record->decrypt_data());
}
$i++;
splice @{$proxy->record_list}, $i, 0, $dup_hrr;

View file

@ -183,65 +183,102 @@ use constant {
UNKNOWN_KEX_MODES => 4,
BOTH_KEX_MODES => 5
};
my $testcount = 13;
my $proxy = TLSProxy::Proxy->new(
plan tests => 2 * $testcount;
SKIP: {
skip "TLS 1.3 is disabled", $testcount if disabled("tls1_3");
# Run tests with TLS
run_tests(0);
}
SKIP: {
skip "TODO(DTLSv1.3): When enabling sessionfile and dtls TLSProxy hangs after"
." the handshake.", $testcount;
skip "DTLS 1.3 is disabled", $testcount if disabled("dtls1_3");
skip "DTLSProxy does not work on Windows", $testcount if $^O =~ /^(MSWin32)$/;
run_tests(1);
}
my $testtype = -1;
sub run_tests
{
my $run_test_as_dtls = shift;
my $proxy_start_success = 0;
(undef, my $session) = tempfile();
my $proxy;
if ($run_test_as_dtls == 1) {
$proxy = TLSProxy::Proxy->new_dtls(
undef,
cmdstr(app(["openssl"]), display => 1),
cmdstr(app([ "openssl" ]), display => 1),
srctop_file("apps", "server.pem"),
(!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE})
);
);
}
else {
$proxy = TLSProxy::Proxy->new(
undef,
cmdstr(app([ "openssl" ]), display => 1),
srctop_file("apps", "server.pem"),
(!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE})
);
}
#Test 1: First get a session
(undef, my $session) = tempfile();
$proxy->cipherc("DEFAULT:\@SECLEVEL=2");
$proxy->clientflags("-no_rx_cert_comp -sess_out ".$session);
$proxy->serverflags("-no_rx_cert_comp -servername localhost");
$proxy->sessionfile($session);
$proxy->start() or plan skip_all => "Unable to start up Proxy for tests";
plan tests => 13;
ok(TLSProxy::Message->success(), "Initial connection");
$proxy->clear();
#Test 2: Attempt a resume with no kex modes extension. Should fail (server
# MUST abort handshake with pre_shared key and no psk_kex_modes)
$proxy->clear();
$proxy->cipherc("DEFAULT:\@SECLEVEL=2");
$proxy->clientflags("-no_rx_cert_comp -sess_in ".$session);
my $testtype = DELETE_EXTENSION;
$proxy->filter(\&modify_kex_modes_filter);
$proxy->start();
ok(TLSProxy::Message->fail(), "Resume with no kex modes");
#Test 1: First get a session
$proxy->cipherc("DEFAULT:\@SECLEVEL=2");
$proxy->clientflags("-no_rx_cert_comp -sess_out " . $session);
$proxy->serverflags("-no_rx_cert_comp -servername localhost");
$proxy->sessionfile($session);
$proxy_start_success = $proxy->start();
skip "TLSProxy did not start correctly", $testcount if $proxy_start_success == 0;
ok(TLSProxy::Message->success(), "Initial connection");
#Test 3: Attempt a resume with empty kex modes extension. Should fail (empty
# extension is invalid)
$proxy->clear();
$proxy->cipherc("DEFAULT:\@SECLEVEL=2");
$proxy->clientflags("-no_rx_cert_comp -sess_in ".$session);
$testtype = EMPTY_EXTENSION;
$proxy->start();
ok(TLSProxy::Message->fail(), "Resume with empty kex modes");
#Test 2: Attempt a resume with no kex modes extension. Should fail (server
# MUST abort handshake with pre_shared key and no psk_kex_modes)
$proxy->clear();
$proxy->cipherc("DEFAULT:\@SECLEVEL=2");
$proxy->clientflags("-no_rx_cert_comp -sess_in " . $session);
$testtype = DELETE_EXTENSION;
$proxy->filter(\&modify_kex_modes_filter);
$proxy->start();
ok(TLSProxy::Message->fail(), "Resume with no kex modes");
#Test 4: Attempt a resume with non-dhe kex mode only. Should resume without a
# key_share
$proxy->clear();
$proxy->cipherc("DEFAULT:\@SECLEVEL=2");
$proxy->clientflags("-no_rx_cert_comp -allow_no_dhe_kex -sess_in ".$session);
$proxy->serverflags("-no_rx_cert_comp -allow_no_dhe_kex");
$testtype = NON_DHE_KEX_MODE_ONLY;
$proxy->start();
checkhandshake($proxy, checkhandshake::RESUME_HANDSHAKE,
#Test 3: Attempt a resume with empty kex modes extension. Should fail (empty
# extension is invalid)
$proxy->clear();
$proxy->cipherc("DEFAULT:\@SECLEVEL=2");
$proxy->clientflags("-no_rx_cert_comp -sess_in " . $session);
$testtype = EMPTY_EXTENSION;
$proxy->start();
ok(TLSProxy::Message->fail(), "Resume with empty kex modes");
#Test 4: Attempt a resume with non-dhe kex mode only. Should resume without a
# key_share
$proxy->clear();
$proxy->cipherc("DEFAULT:\@SECLEVEL=2");
$proxy->clientflags("-no_rx_cert_comp -allow_no_dhe_kex -sess_in " . $session);
$proxy->serverflags("-no_rx_cert_comp -allow_no_dhe_kex");
$testtype = NON_DHE_KEX_MODE_ONLY;
$proxy->start();
checkhandshake($proxy, checkhandshake::RESUME_HANDSHAKE,
checkhandshake::DEFAULT_EXTENSIONS
| checkhandshake::PSK_KEX_MODES_EXTENSION
| checkhandshake::PSK_CLI_EXTENSION
| checkhandshake::PSK_SRV_EXTENSION,
"Resume with non-dhe kex mode");
#Test 5: Attempt a resume with dhe kex mode only. Should resume with a key_share
$proxy->clear();
$proxy->cipherc("DEFAULT:\@SECLEVEL=2");
$proxy->clientflags("-no_rx_cert_comp -sess_in ".$session);
$testtype = DHE_KEX_MODE_ONLY;
$proxy->start();
checkhandshake($proxy, checkhandshake::RESUME_HANDSHAKE,
#Test 5: Attempt a resume with dhe kex mode only. Should resume with a key_share
$proxy->clear();
$proxy->cipherc("DEFAULT:\@SECLEVEL=2");
$proxy->clientflags("-no_rx_cert_comp -sess_in " . $session);
$testtype = DHE_KEX_MODE_ONLY;
$proxy->start();
checkhandshake($proxy, checkhandshake::RESUME_HANDSHAKE,
checkhandshake::DEFAULT_EXTENSIONS
| checkhandshake::PSK_KEX_MODES_EXTENSION
| checkhandshake::KEY_SHARE_SRV_EXTENSION
@ -249,29 +286,29 @@ checkhandshake($proxy, checkhandshake::RESUME_HANDSHAKE,
| checkhandshake::PSK_SRV_EXTENSION,
"Resume with non-dhe kex mode");
#Test 6: Attempt a resume with only unrecognised kex modes. Should not resume
# but rather fall back to full handshake
$proxy->clear();
$proxy->cipherc("DEFAULT:\@SECLEVEL=2");
$proxy->clientflags("-no_rx_cert_comp -sess_in ".$session);
$testtype = UNKNOWN_KEX_MODES;
$proxy->start();
checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
#Test 6: Attempt a resume with only unrecognised kex modes. Should not resume
# but rather fall back to full handshake
$proxy->clear();
$proxy->cipherc("DEFAULT:\@SECLEVEL=2");
$proxy->clientflags("-no_rx_cert_comp -sess_in " . $session);
$testtype = UNKNOWN_KEX_MODES;
$proxy->start();
checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
checkhandshake::DEFAULT_EXTENSIONS
| checkhandshake::PSK_KEX_MODES_EXTENSION
| checkhandshake::KEY_SHARE_SRV_EXTENSION
| checkhandshake::PSK_CLI_EXTENSION,
"Resume with unrecognized kex mode");
#Test 7: Attempt a resume with both, non-dhe and dhe kex mode. Should resume with
# a key_share, even though non-dhe is allowed, but not explicitly preferred.
$proxy->clear();
$proxy->cipherc("DEFAULT:\@SECLEVEL=2");
$proxy->clientflags("-no_rx_cert_comp -allow_no_dhe_kex -sess_in ".$session);
$proxy->serverflags("-allow_no_dhe_kex");
$testtype = BOTH_KEX_MODES;
$proxy->start();
checkhandshake($proxy, checkhandshake::RESUME_HANDSHAKE,
#Test 7: Attempt a resume with both, non-dhe and dhe kex mode. Should resume with
# a key_share, even though non-dhe is allowed, but not explicitly preferred.
$proxy->clear();
$proxy->cipherc("DEFAULT:\@SECLEVEL=2");
$proxy->clientflags("-no_rx_cert_comp -allow_no_dhe_kex -sess_in " . $session);
$proxy->serverflags("-allow_no_dhe_kex");
$testtype = BOTH_KEX_MODES;
$proxy->start();
checkhandshake($proxy, checkhandshake::RESUME_HANDSHAKE,
checkhandshake::DEFAULT_EXTENSIONS
| checkhandshake::PSK_KEX_MODES_EXTENSION
| checkhandshake::KEY_SHARE_SRV_EXTENSION
@ -279,30 +316,30 @@ checkhandshake($proxy, checkhandshake::RESUME_HANDSHAKE,
| checkhandshake::PSK_SRV_EXTENSION,
"Resume with both kex modes");
#Test 8: Attempt a resume with both, non-dhe and dhe kex mode, but with server-side
# preference for non-dhe. Should resume without a key_share.
$proxy->clear();
$proxy->cipherc("DEFAULT:\@SECLEVEL=2");
$proxy->clientflags("-no_rx_cert_comp -allow_no_dhe_kex -sess_in ".$session);
$proxy->serverflags("-allow_no_dhe_kex -prefer_no_dhe_kex");
$testtype = BOTH_KEX_MODES;
$proxy->start();
checkhandshake($proxy, checkhandshake::RESUME_HANDSHAKE,
#Test 8: Attempt a resume with both, non-dhe and dhe kex mode, but with server-side
# preference for non-dhe. Should resume without a key_share.
$proxy->clear();
$proxy->cipherc("DEFAULT:\@SECLEVEL=2");
$proxy->clientflags("-no_rx_cert_comp -allow_no_dhe_kex -sess_in " . $session);
$proxy->serverflags("-allow_no_dhe_kex -prefer_no_dhe_kex");
$testtype = BOTH_KEX_MODES;
$proxy->start();
checkhandshake($proxy, checkhandshake::RESUME_HANDSHAKE,
checkhandshake::DEFAULT_EXTENSIONS
| checkhandshake::PSK_KEX_MODES_EXTENSION
| checkhandshake::PSK_CLI_EXTENSION
| checkhandshake::PSK_SRV_EXTENSION,
"Resume with both kex modes, preference for non-dhe");
#Test 9: Attempt a resume with both, non-dhe and dhe kex mode, with server-side
# preference for non-dhe, but non-dhe not allowed. Should resume with a key_share.
$proxy->clear();
$proxy->cipherc("DEFAULT:\@SECLEVEL=2");
$proxy->clientflags("-no_rx_cert_comp -allow_no_dhe_kex -sess_in ".$session);
$proxy->serverflags("-prefer_no_dhe_kex");
$testtype = BOTH_KEX_MODES;
$proxy->start();
checkhandshake($proxy, checkhandshake::RESUME_HANDSHAKE,
#Test 9: Attempt a resume with both, non-dhe and dhe kex mode, with server-side
# preference for non-dhe, but non-dhe not allowed. Should resume with a key_share.
$proxy->clear();
$proxy->cipherc("DEFAULT:\@SECLEVEL=2");
$proxy->clientflags("-no_rx_cert_comp -allow_no_dhe_kex -sess_in " . $session);
$proxy->serverflags("-prefer_no_dhe_kex");
$testtype = BOTH_KEX_MODES;
$proxy->start();
checkhandshake($proxy, checkhandshake::RESUME_HANDSHAKE,
checkhandshake::DEFAULT_EXTENSIONS
| checkhandshake::PSK_KEX_MODES_EXTENSION
| checkhandshake::KEY_SHARE_SRV_EXTENSION
@ -310,15 +347,15 @@ checkhandshake($proxy, checkhandshake::RESUME_HANDSHAKE,
| checkhandshake::PSK_SRV_EXTENSION,
"Resume with both kex modes, preference for but disabled non-dhe");
#Test 10: Attempt a resume with both non-dhe and dhe kex mode, but unacceptable
# initial key_share. Should resume with a key_share following an HRR
$proxy->clear();
$proxy->cipherc("DEFAULT:\@SECLEVEL=2");
$proxy->clientflags("-no_rx_cert_comp -sess_in ".$session);
$proxy->serverflags("-no_rx_cert_comp -curves P-384");
$testtype = BOTH_KEX_MODES;
$proxy->start();
checkhandshake($proxy, checkhandshake::HRR_RESUME_HANDSHAKE,
#Test 10: Attempt a resume with both non-dhe and dhe kex mode, but unacceptable
# initial key_share. Should resume with a key_share following an HRR
$proxy->clear();
$proxy->cipherc("DEFAULT:\@SECLEVEL=2");
$proxy->clientflags("-no_rx_cert_comp -sess_in " . $session);
$proxy->serverflags("-no_rx_cert_comp -curves P-384");
$testtype = BOTH_KEX_MODES;
$proxy->start();
checkhandshake($proxy, checkhandshake::HRR_RESUME_HANDSHAKE,
checkhandshake::DEFAULT_EXTENSIONS
| checkhandshake::PSK_KEX_MODES_EXTENSION
| checkhandshake::KEY_SHARE_SRV_EXTENSION
@ -327,15 +364,15 @@ checkhandshake($proxy, checkhandshake::HRR_RESUME_HANDSHAKE,
| checkhandshake::PSK_SRV_EXTENSION,
"Resume with both kex modes and HRR");
#Test 11: Attempt a resume with dhe kex mode only and an unacceptable initial
# key_share. Should resume with a key_share following an HRR
$proxy->clear();
$proxy->cipherc("DEFAULT:\@SECLEVEL=2");
$proxy->clientflags("-no_rx_cert_comp -sess_in ".$session);
$proxy->serverflags("-no_rx_cert_comp -curves P-384");
$testtype = DHE_KEX_MODE_ONLY;
$proxy->start();
checkhandshake($proxy, checkhandshake::HRR_RESUME_HANDSHAKE,
#Test 11: Attempt a resume with dhe kex mode only and an unacceptable initial
# key_share. Should resume with a key_share following an HRR
$proxy->clear();
$proxy->cipherc("DEFAULT:\@SECLEVEL=2");
$proxy->clientflags("-no_rx_cert_comp -sess_in " . $session);
$proxy->serverflags("-no_rx_cert_comp -curves P-384");
$testtype = DHE_KEX_MODE_ONLY;
$proxy->start();
checkhandshake($proxy, checkhandshake::HRR_RESUME_HANDSHAKE,
checkhandshake::DEFAULT_EXTENSIONS
| checkhandshake::PSK_KEX_MODES_EXTENSION
| checkhandshake::KEY_SHARE_SRV_EXTENSION
@ -344,33 +381,34 @@ checkhandshake($proxy, checkhandshake::HRR_RESUME_HANDSHAKE,
| checkhandshake::PSK_SRV_EXTENSION,
"Resume with dhe kex mode and HRR");
#Test 12: Attempt a resume with both non-dhe and dhe kex mode, unacceptable
# initial key_share and no overlapping groups. Should resume without a
# key_share
$proxy->clear();
$proxy->cipherc("DEFAULT:\@SECLEVEL=2");
$proxy->clientflags("-no_rx_cert_comp -allow_no_dhe_kex -curves P-384 -sess_in ".$session);
$proxy->serverflags("-no_rx_cert_comp -allow_no_dhe_kex -curves P-256");
$testtype = BOTH_KEX_MODES;
$proxy->start();
checkhandshake($proxy, checkhandshake::RESUME_HANDSHAKE,
#Test 12: Attempt a resume with both non-dhe and dhe kex mode, unacceptable
# initial key_share and no overlapping groups. Should resume without a
# key_share
$proxy->clear();
$proxy->cipherc("DEFAULT:\@SECLEVEL=2");
$proxy->clientflags("-no_rx_cert_comp -allow_no_dhe_kex -curves P-384 -sess_in " . $session);
$proxy->serverflags("-no_rx_cert_comp -allow_no_dhe_kex -curves P-256");
$testtype = BOTH_KEX_MODES;
$proxy->start();
checkhandshake($proxy, checkhandshake::RESUME_HANDSHAKE,
checkhandshake::DEFAULT_EXTENSIONS
| checkhandshake::PSK_KEX_MODES_EXTENSION
| checkhandshake::PSK_CLI_EXTENSION
| checkhandshake::PSK_SRV_EXTENSION,
"Resume with both kex modes, no overlapping groups");
#Test 13: Attempt a resume with dhe kex mode only, unacceptable
# initial key_share and no overlapping groups. Should fail
$proxy->clear();
$proxy->cipherc("DEFAULT:\@SECLEVEL=2");
$proxy->clientflags("-no_rx_cert_comp -curves P-384 -sess_in ".$session);
$proxy->serverflags("-no_rx_cert_comp -curves P-256");
$testtype = DHE_KEX_MODE_ONLY;
$proxy->start();
ok(TLSProxy::Message->fail(), "Resume with dhe kex mode, no overlapping groups");
#Test 13: Attempt a resume with dhe kex mode only, unacceptable
# initial key_share and no overlapping groups. Should fail
$proxy->clear();
$proxy->cipherc("DEFAULT:\@SECLEVEL=2");
$proxy->clientflags("-no_rx_cert_comp -curves P-384 -sess_in " . $session);
$proxy->serverflags("-no_rx_cert_comp -curves P-256");
$testtype = DHE_KEX_MODE_ONLY;
$proxy->start();
ok(TLSProxy::Message->fail(), "Resume with dhe kex mode, no overlapping groups");
unlink $session;
unlink $session;
}
sub modify_kex_modes_filter
{

View file

@ -25,9 +25,6 @@ plan skip_all => "$test_name needs the dynamic engine feature enabled"
plan skip_all => "$test_name needs the sock feature enabled"
if disabled("sock");
plan skip_all => "$test_name needs TLSv1.3 enabled"
if disabled("tls1_3");
plan skip_all => "$test_name needs EC enabled"
if disabled("ec");
@ -199,44 +196,83 @@ plan skip_all => "$test_name needs EC enabled"
[0,0,0,0]
);
my $proxy = TLSProxy::Proxy->new(
my $testcount = 17;
plan tests => 2 * $testcount;
SKIP: {
skip "TLS 1.3 is disabled", $testcount if disabled("tls1_3");
# Run tests with TLS
run_tests(0);
}
SKIP: {
skip "DTLS 1.3 is disabled", $testcount if disabled("dtls1_3");
skip "DTLSProxy does not work on Windows", $testcount if $^O =~ /^(MSWin32)$/;
run_tests(1);
}
sub run_tests
{
my $run_test_as_dtls = shift;
my $proxy_start_success = 0;
(undef, my $session) = tempfile();
my $proxy;
if ($run_test_as_dtls == 1) {
$proxy = TLSProxy::Proxy->new_dtls(
undef,
cmdstr(app(["openssl"]), display => 1),
cmdstr(app([ "openssl" ]), display => 1),
srctop_file("apps", "server.pem"),
(!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE})
);
);
}
else {
$proxy = TLSProxy::Proxy->new(
undef,
cmdstr(app([ "openssl" ]), display => 1),
srctop_file("apps", "server.pem"),
(!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE})
);
}
#Test 1: Check we get all the right messages for a default handshake
(undef, my $session) = tempfile();
$proxy->serverconnects(2);
$proxy->cipherc("DEFAULT:\@SECLEVEL=2");
$proxy->clientflags("-no_rx_cert_comp -sess_out ".$session);
$proxy->sessionfile($session);
$proxy->start() or plan skip_all => "Unable to start up Proxy for tests";
plan tests => 17;
checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
$proxy->clear();
SKIP: {
skip "TODO(DTLSv1.3): When enabling sessionfile and dtls TLSProxy hangs"
." after the handshake.", 2 if $run_test_as_dtls == 1;
#Test 1: Check we get all the right messages for a default handshake
$proxy->serverconnects(2);
$proxy->cipherc("DEFAULT:\@SECLEVEL=2");
$proxy->clientflags("-no_rx_cert_comp -sess_out " . $session);
$proxy->sessionfile($session);
$proxy_start_success = $proxy->start();
skip "TLSProxy did not start correctly", $testcount if $proxy_start_success == 0;
checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
checkhandshake::DEFAULT_EXTENSIONS,
"Default handshake test");
#Test 2: Resumption handshake
$proxy->clearClient();
$proxy->cipherc("DEFAULT:\@SECLEVEL=2");
$proxy->clientflags("-no_rx_cert_comp -sess_in ".$session);
$proxy->clientstart();
checkhandshake($proxy, checkhandshake::RESUME_HANDSHAKE,
#Test 2: Resumption handshake
$proxy->clearClient();
$proxy->cipherc("DEFAULT:\@SECLEVEL=2");
$proxy->clientflags("-no_rx_cert_comp -sess_in " . $session);
$proxy->clientstart();
checkhandshake($proxy, checkhandshake::RESUME_HANDSHAKE,
(checkhandshake::DEFAULT_EXTENSIONS
| checkhandshake::PSK_CLI_EXTENSION
| checkhandshake::PSK_SRV_EXTENSION),
"Resumption handshake test");
}
SKIP: {
SKIP: {
skip "No OCSP support in this OpenSSL build", 4
if disabled("ct") || disabled("ec") || disabled("ocsp");
#Test 3: A status_request handshake (client request only)
$proxy->clear();
$proxy->cipherc("DEFAULT:\@SECLEVEL=2");
$proxy->clientflags("-no_rx_cert_comp -status");
$proxy->start();
$proxy_start_success = $proxy->start();
skip "TLSProxy did not start correctly", 4 if $proxy_start_success == 0;
checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
checkhandshake::DEFAULT_EXTENSIONS
| checkhandshake::STATUS_REQUEST_CLI_EXTENSION,
@ -247,7 +283,7 @@ SKIP: {
$proxy->cipherc("DEFAULT:\@SECLEVEL=2");
$proxy->clientflags("-no_rx_cert_comp");
$proxy->serverflags("-no_rx_cert_comp -status_file "
.srctop_file("test", "recipes", "ocsp-response.der"));
. srctop_file("test", "recipes", "ocsp-response.der"));
$proxy->start();
checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
checkhandshake::DEFAULT_EXTENSIONS,
@ -258,7 +294,7 @@ SKIP: {
$proxy->cipherc("DEFAULT:\@SECLEVEL=2");
$proxy->clientflags("-no_rx_cert_comp -status");
$proxy->serverflags("-no_rx_cert_comp -status_file "
.srctop_file("test", "recipes", "ocsp-response.der"));
. srctop_file("test", "recipes", "ocsp-response.der"));
$proxy->start();
checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
checkhandshake::DEFAULT_EXTENSIONS
@ -270,9 +306,9 @@ SKIP: {
$proxy->clear();
$proxy->cipherc("DEFAULT:\@SECLEVEL=2");
$proxy->clientflags("-no_rx_cert_comp -status -enable_pha -cert "
.srctop_file("apps", "server.pem"));
. srctop_file("apps", "server.pem"));
$proxy->serverflags("-no_rx_cert_comp -Verify 5 -status_file "
.srctop_file("test", "recipes", "ocsp-response.der"));
. srctop_file("test", "recipes", "ocsp-response.der"));
$proxy->start();
checkhandshake($proxy, checkhandshake::CLIENT_AUTH_HANDSHAKE,
checkhandshake::DEFAULT_EXTENSIONS
@ -280,86 +316,90 @@ SKIP: {
| checkhandshake::STATUS_REQUEST_SRV_EXTENSION
| checkhandshake::POST_HANDSHAKE_AUTH_CLI_EXTENSION,
"status_request handshake with client auth test");
}
}
#Test 7: A client auth handshake
$proxy->clear();
$proxy->cipherc("DEFAULT:\@SECLEVEL=2");
$proxy->clientflags("-no_rx_cert_comp -enable_pha -cert ".srctop_file("apps", "server.pem"));
$proxy->serverflags("-no_rx_cert_comp -Verify 5");
$proxy->start();
checkhandshake($proxy, checkhandshake::CLIENT_AUTH_HANDSHAKE,
checkhandshake::DEFAULT_EXTENSIONS |
checkhandshake::POST_HANDSHAKE_AUTH_CLI_EXTENSION,
#Test 7: A client auth handshake
$proxy->clear();
$proxy->cipherc("DEFAULT:\@SECLEVEL=2");
$proxy->clientflags("-no_rx_cert_comp -enable_pha -cert " . srctop_file("apps", "server.pem"));
$proxy->serverflags("-no_rx_cert_comp -Verify 5");
$proxy_start_success = $proxy->start();
skip "TLSProxy did not start correctly", $testcount - 6 if $proxy_start_success == 0;
checkhandshake($proxy, checkhandshake::CLIENT_AUTH_HANDSHAKE,
checkhandshake::DEFAULT_EXTENSIONS
| checkhandshake::POST_HANDSHAKE_AUTH_CLI_EXTENSION,
"Client auth handshake test");
#Test 8: Server name handshake (no client request)
$proxy->clear();
$proxy->cipherc("DEFAULT:\@SECLEVEL=2");
$proxy->clientflags("-no_rx_cert_comp -noservername");
$proxy->start();
checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
#Test 8: Server name handshake (no client request)
$proxy->clear();
$proxy->cipherc("DEFAULT:\@SECLEVEL=2");
$proxy->clientflags("-no_rx_cert_comp -noservername");
$proxy->start();
checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
checkhandshake::DEFAULT_EXTENSIONS
& ~checkhandshake::SERVER_NAME_CLI_EXTENSION,
"Server name handshake test (client)");
#Test 9: Server name handshake (server support only)
$proxy->clear();
$proxy->cipherc("DEFAULT:\@SECLEVEL=2");
$proxy->clientflags("-no_rx_cert_comp -noservername");
$proxy->serverflags("-no_rx_cert_comp -servername testhost");
$proxy->start();
checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
#Test 9: Server name handshake (server support only)
$proxy->clear();
$proxy->cipherc("DEFAULT:\@SECLEVEL=2");
$proxy->clientflags("-no_rx_cert_comp -noservername");
$proxy->serverflags("-no_rx_cert_comp -servername testhost");
$proxy->start();
checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
checkhandshake::DEFAULT_EXTENSIONS
& ~checkhandshake::SERVER_NAME_CLI_EXTENSION,
"Server name handshake test (server)");
#Test 10: Server name handshake (client and server)
$proxy->clear();
$proxy->cipherc("DEFAULT:\@SECLEVEL=2");
$proxy->clientflags("-no_rx_cert_comp -servername testhost");
$proxy->serverflags("-no_rx_cert_comp -servername testhost");
$proxy->start();
checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
#Test 10: Server name handshake (client and server)
$proxy->clear();
$proxy->cipherc("DEFAULT:\@SECLEVEL=2");
$proxy->clientflags("-no_rx_cert_comp -servername testhost");
$proxy->serverflags("-no_rx_cert_comp -servername testhost");
$proxy->start();
checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
checkhandshake::DEFAULT_EXTENSIONS
| checkhandshake::SERVER_NAME_SRV_EXTENSION,
"Server name handshake test");
#Test 11: ALPN handshake (client request only)
$proxy->clear();
$proxy->cipherc("DEFAULT:\@SECLEVEL=2");
$proxy->clientflags("-no_rx_cert_comp -alpn test");
$proxy->start();
checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
#Test 11: ALPN handshake (client request only)
$proxy->clear();
$proxy->cipherc("DEFAULT:\@SECLEVEL=2");
$proxy->clientflags("-no_rx_cert_comp -alpn test");
$proxy->start();
checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
checkhandshake::DEFAULT_EXTENSIONS
| checkhandshake::ALPN_CLI_EXTENSION,
"ALPN handshake test (client)");
#Test 12: ALPN handshake (server support only)
$proxy->clear();
$proxy->cipherc("DEFAULT:\@SECLEVEL=2");
$proxy->clientflags("-no_rx_cert_comp");
$proxy->serverflags("-no_rx_cert_comp -alpn test");
$proxy->start();
checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
#Test 12: ALPN handshake (server support only)
$proxy->clear();
$proxy->cipherc("DEFAULT:\@SECLEVEL=2");
$proxy->clientflags("-no_rx_cert_comp");
$proxy->serverflags("-no_rx_cert_comp -alpn test");
$proxy->start();
checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
checkhandshake::DEFAULT_EXTENSIONS,
"ALPN handshake test (server)");
#Test 13: ALPN handshake (client and server)
$proxy->clear();
$proxy->cipherc("DEFAULT:\@SECLEVEL=2");
$proxy->clientflags("-no_rx_cert_comp -alpn test");
$proxy->serverflags("-no_rx_cert_comp -alpn test");
$proxy->start();
checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
#Test 13: ALPN handshake (client and server)
$proxy->clear();
$proxy->cipherc("DEFAULT:\@SECLEVEL=2");
$proxy->clientflags("-no_rx_cert_comp -alpn test");
$proxy->serverflags("-no_rx_cert_comp -alpn test");
$proxy->start();
checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
checkhandshake::DEFAULT_EXTENSIONS
| checkhandshake::ALPN_CLI_EXTENSION
| checkhandshake::ALPN_SRV_EXTENSION,
"ALPN handshake test");
SKIP: {
SKIP: {
# TODO(DTLSv1.3): When ecx is disabled the test reports "Invalid
# CertificateVerify signature length" when running with DTLS.
skip "No CT, EC or OCSP support in this OpenSSL build", 1
if disabled("ct") || disabled("ec") || disabled("ocsp");
if disabled("ct") || disabled("ec") || disabled("ocsp")
|| ($run_test_as_dtls == 1 && disabled("ecx"));
#Test 14: SCT handshake (client request only)
$proxy->clear();
@ -367,8 +407,8 @@ SKIP: {
#Note: -ct also sends status_request
$proxy->clientflags("-no_rx_cert_comp -ct");
$proxy->serverflags("-no_rx_cert_comp -status_file "
.srctop_file("test", "recipes", "ocsp-response.der")
." -serverinfo ".srctop_file("test", "serverinfo2.pem"));
. srctop_file("test", "recipes", "ocsp-response.der")
. " -serverinfo " . srctop_file("test", "serverinfo2.pem"));
$proxy->start();
checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
checkhandshake::DEFAULT_EXTENSIONS
@ -377,40 +417,49 @@ SKIP: {
| checkhandshake::STATUS_REQUEST_CLI_EXTENSION
| checkhandshake::STATUS_REQUEST_SRV_EXTENSION,
"SCT handshake test");
}
}
#Test 15: HRR Handshake
$proxy->clear();
$proxy->cipherc("DEFAULT:\@SECLEVEL=2");
$proxy->clientflags("-no_rx_cert_comp");
$proxy->serverflags("-no_rx_cert_comp -curves P-384");
$proxy->start();
checkhandshake($proxy, checkhandshake::HRR_HANDSHAKE,
SKIP: {
skip "TODO(DTLSv1.3): Re-enable when #26465 is merged.", 1
if $run_test_as_dtls == 1;
#Test 15: HRR Handshake
$proxy->clear();
$proxy->cipherc("DEFAULT:\@SECLEVEL=2");
$proxy->clientflags("-no_rx_cert_comp");
$proxy->serverflags("-no_rx_cert_comp -curves P-384");
$proxy->start();
checkhandshake($proxy, checkhandshake::HRR_HANDSHAKE,
checkhandshake::DEFAULT_EXTENSIONS
| checkhandshake::KEY_SHARE_HRR_EXTENSION,
"HRR handshake test");
}
#Test 16: Resumption handshake with HRR
$proxy->clear();
$proxy->cipherc("DEFAULT:\@SECLEVEL=2");
$proxy->clientflags("-no_rx_cert_comp -sess_in ".$session);
$proxy->serverflags("-no_rx_cert_comp -curves P-384");
$proxy->start();
checkhandshake($proxy, checkhandshake::HRR_RESUME_HANDSHAKE,
SKIP: {
skip "TODO(DTLSv1.3): When enabling sessionfile and dtls TLSProxy hangs"
. " after the handshake.", 1 if $run_test_as_dtls == 1;
#Test 16: Resumption handshake with HRR
$proxy->clear();
$proxy->cipherc("DEFAULT:\@SECLEVEL=2");
$proxy->clientflags("-no_rx_cert_comp -sess_in " . $session);
$proxy->serverflags("-no_rx_cert_comp -curves P-384");
$proxy->start();
checkhandshake($proxy, checkhandshake::HRR_RESUME_HANDSHAKE,
(checkhandshake::DEFAULT_EXTENSIONS
| checkhandshake::KEY_SHARE_HRR_EXTENSION
| checkhandshake::PSK_CLI_EXTENSION
| checkhandshake::PSK_SRV_EXTENSION),
"Resumption handshake with HRR test");
}
#Test 17: Acceptable but non preferred key_share
$proxy->clear();
$proxy->cipherc("DEFAULT:\@SECLEVEL=2");
$proxy->clientflags("-no_rx_cert_comp -curves P-384");
$proxy->start();
checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
#Test 17: Acceptable but non preferred key_share
$proxy->clear();
$proxy->cipherc("DEFAULT:\@SECLEVEL=2");
$proxy->clientflags("-no_rx_cert_comp -curves P-384");
$proxy->start();
checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
checkhandshake::DEFAULT_EXTENSIONS
| checkhandshake::SUPPORTED_GROUPS_SRV_EXTENSION,
"Acceptable but non preferred key_share");
unlink $session;
unlink $session;
}

View file

@ -24,91 +24,131 @@ plan skip_all => "$test_name needs the dynamic engine feature enabled"
plan skip_all => "$test_name needs the sock feature enabled"
if disabled("sock");
plan skip_all => "$test_name needs TLSv1.3 enabled"
if disabled("tls1_3") || (disabled("ec") && disabled("dh"));
plan skip_all => "$test_name needs elliptic curves or diffie-hellman enabled"
if disabled("ec") && disabled("dh");
my $proxy = TLSProxy::Proxy->new(
undef,
cmdstr(app(["openssl"]), display => 1),
srctop_file("apps", "server.pem"),
(!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE})
);
my $testcount = 5;
plan tests => 2 * $testcount;
use constant {
PSK_LAST_FIRST_CH => 0,
ILLEGAL_EXT_SECOND_CH => 1
};
#Most PSK tests are done in test_ssl_new. This tests various failure scenarios
#around PSK
#Test 1: First get a session
(undef, my $session) = tempfile();
$proxy->clientflags("-sess_out ".$session);
$proxy->serverflags("-servername localhost");
$proxy->sessionfile($session);
$proxy->start() or plan skip_all => "Unable to start up Proxy for tests";
plan tests => 5;
ok(TLSProxy::Message->success(), "Initial connection");
#Test 2: Attempt a resume with PSK not in last place. Should fail
$proxy->clear();
$proxy->clientflags("-sess_in ".$session);
$proxy->filter(\&modify_psk_filter);
my $testtype = PSK_LAST_FIRST_CH;
$proxy->start();
ok(TLSProxy::Message->fail(), "PSK not last");
#Test 3: Attempt a resume after an HRR where PSK hash matches selected
# ciphersuite. Should see PSK on second ClientHello
$proxy->clear();
$proxy->clientflags("-sess_in ".$session);
if (disabled("ec")) {
$proxy->serverflags("-curves ffdhe3072");
} else {
$proxy->serverflags("-curves P-384");
SKIP: {
skip "TLS 1.3 is disabled", $testcount if disabled("tls1_3");
# Run tests with TLS
run_tests(0);
}
$proxy->filter(undef);
$proxy->start();
#Check if the PSK is present in the second ClientHello
my $ch2 = ${$proxy->message_list}[2];
my $ch2seen = defined $ch2 && $ch2->mt() == TLSProxy::Message::MT_CLIENT_HELLO;
my $pskseen = $ch2seen
SKIP: {
skip "TODO(DTLSv1.3): When enabling sessionfile and dtls TLSProxy hangs after"
." the handshake.", $testcount;
skip "DTLS 1.3 is disabled", $testcount if disabled("dtls1_3");
skip "DTLSProxy does not work on Windows", $testcount if $^O =~ /^(MSWin32)$/;
run_tests(1);
}
my $testtype = -1;
sub run_tests
{
my $run_test_as_dtls = shift;
my $proxy_start_success = 0;
my $proxy;
if ($run_test_as_dtls == 1) {
$proxy = TLSProxy::Proxy->new_dtls(
undef,
cmdstr(app([ "openssl" ]), display => 1),
srctop_file("apps", "server.pem"),
(!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE})
);
}
else {
$proxy = TLSProxy::Proxy->new(
undef,
cmdstr(app([ "openssl" ]), display => 1),
srctop_file("apps", "server.pem"),
(!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE})
);
}
#Most PSK tests are done in test_ssl_new. This tests various failure scenarios
#around PSK
#Test 1: First get a session
$proxy->clear();
(undef, my $session) = tempfile();
$proxy->clientflags("-sess_out " . $session);
$proxy->serverflags("-servername localhost");
$proxy->sessionfile($session);
$proxy_start_success = $proxy->start();
skip "TLSProxy did not start correctly", $testcount if $proxy_start_success == 0;
ok(TLSProxy::Message->success(), "Initial connection");
#Test 2: Attempt a resume with PSK not in last place. Should fail
$proxy->clear();
$proxy->clientflags("-sess_in " . $session);
$proxy->filter(\&modify_psk_filter);
$testtype = PSK_LAST_FIRST_CH;
$proxy->start();
ok(TLSProxy::Message->fail(), "PSK not last");
#Test 3: Attempt a resume after an HRR where PSK hash matches selected
# ciphersuite. Should see PSK on second ClientHello
$proxy->clear();
$proxy->clientflags("-sess_in " . $session);
if (disabled("ec")) {
$proxy->serverflags("-curves ffdhe3072");
}
else {
$proxy->serverflags("-curves P-384");
}
$proxy->filter(undef);
$proxy->start();
#Check if the PSK is present in the second ClientHello
my $ch2 = ${$proxy->message_list}[2];
my $ch2seen = defined $ch2 && $ch2->mt() == TLSProxy::Message::MT_CLIENT_HELLO;
my $pskseen = $ch2seen
&& defined ${$ch2->{extension_data}}{TLSProxy::Message::EXT_PSK};
ok($pskseen, "PSK hash matches");
ok($pskseen, "PSK hash matches");
#Test 4: Attempt a resume after an HRR where PSK hash does not match selected
# ciphersuite. Should not see PSK on second ClientHello
$proxy->clear();
$proxy->clientflags("-sess_in ".$session);
$proxy->filter(\&modify_psk_filter);
if (disabled("ec")) {
#Test 4: Attempt a resume after an HRR where PSK hash does not match selected
# ciphersuite. Should not see PSK on second ClientHello
$proxy->clear();
$proxy->clientflags("-sess_in " . $session);
$proxy->filter(\&modify_psk_filter);
if (disabled("ec")) {
$proxy->serverflags("-curves ffdhe3072");
} else {
}
else {
$proxy->serverflags("-curves P-384");
}
$proxy->ciphersuitesc("TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384");
$proxy->ciphersuitess("TLS_AES_256_GCM_SHA384");
#We force an early failure because TLS Proxy doesn't actually support
#TLS_AES_256_GCM_SHA384. That doesn't matter for this test though.
$testtype = ILLEGAL_EXT_SECOND_CH;
$proxy->start();
#Check if the PSK is present in the second ClientHello
$ch2 = ${$proxy->message_list}[2];
$ch2seen = defined $ch2 && $ch2->mt() == TLSProxy::Message::MT_CLIENT_HELLO;
$pskseen = $ch2seen
}
$proxy->ciphersuitesc("TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384");
$proxy->ciphersuitess("TLS_AES_256_GCM_SHA384");
#We force an early failure because TLS Proxy doesn't actually support
#TLS_AES_256_GCM_SHA384. That doesn't matter for this test though.
$testtype = ILLEGAL_EXT_SECOND_CH;
$proxy->start();
#Check if the PSK is present in the second ClientHello
$ch2 = ${$proxy->message_list}[2];
$ch2seen = defined $ch2 && $ch2->mt() == TLSProxy::Message::MT_CLIENT_HELLO;
$pskseen = $ch2seen
&& defined ${$ch2->extension_data}{TLSProxy::Message::EXT_PSK};
ok($ch2seen && !$pskseen, "PSK hash does not match");
ok($ch2seen && !$pskseen, "PSK hash does not match");
#Test 5: Attempt a resume without a sig agls extension. Should succeed because
# sig algs is not needed in a resumption.
$proxy->clear();
$proxy->clientflags("-sess_in ".$session);
$proxy->filter(\&remove_sig_algs_filter);
$proxy->start();
ok(TLSProxy::Message->success(), "Remove sig algs");
#Test 5: Attempt a resume without a sig agls extension. Should succeed because
# sig algs is not needed in a resumption.
$proxy->clear();
$proxy->clientflags("-sess_in " . $session);
$proxy->filter(\&remove_sig_algs_filter);
$proxy->start();
ok(TLSProxy::Message->success(), "Remove sig algs");
unlink $session;
unlink $session;
}
sub modify_psk_filter
{

View file

@ -678,8 +678,8 @@ test-672 = 672-version-negotiation
test-673 = 673-version-negotiation
test-674 = 674-version-negotiation
test-675 = 675-version-negotiation
test-676 = 676-ciphersuite-sanity-check-client
test-677 = 677-ciphersuite-sanity-check-server
test-676 = 676-ciphersuite-sanity-check-tls-client
test-677 = 677-ciphersuite-sanity-check-tls-server
# ===========================================================
[0-version-negotiation]
@ -18772,20 +18772,20 @@ ExpectedResult = Success
# ===========================================================
[676-ciphersuite-sanity-check-client]
ssl_conf = 676-ciphersuite-sanity-check-client-ssl
[676-ciphersuite-sanity-check-tls-client]
ssl_conf = 676-ciphersuite-sanity-check-tls-client-ssl
[676-ciphersuite-sanity-check-client-ssl]
server = 676-ciphersuite-sanity-check-client-server
client = 676-ciphersuite-sanity-check-client-client
[676-ciphersuite-sanity-check-tls-client-ssl]
server = 676-ciphersuite-sanity-check-tls-client-server
client = 676-ciphersuite-sanity-check-tls-client-client
[676-ciphersuite-sanity-check-client-server]
[676-ciphersuite-sanity-check-tls-client-server]
Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
CipherString = DEFAULT
MaxProtocol = TLSv1.2
PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
[676-ciphersuite-sanity-check-client-client]
[676-ciphersuite-sanity-check-tls-client-client]
CipherString = AES128-SHA
Ciphersuites =
VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
@ -18793,24 +18793,25 @@ VerifyMode = Peer
[test-676]
ExpectedResult = ClientFail
Method = TLS
# ===========================================================
[677-ciphersuite-sanity-check-server]
ssl_conf = 677-ciphersuite-sanity-check-server-ssl
[677-ciphersuite-sanity-check-tls-server]
ssl_conf = 677-ciphersuite-sanity-check-tls-server-ssl
[677-ciphersuite-sanity-check-server-ssl]
server = 677-ciphersuite-sanity-check-server-server
client = 677-ciphersuite-sanity-check-server-client
[677-ciphersuite-sanity-check-tls-server-ssl]
server = 677-ciphersuite-sanity-check-tls-server-server
client = 677-ciphersuite-sanity-check-tls-server-client
[677-ciphersuite-sanity-check-server-server]
[677-ciphersuite-sanity-check-tls-server-server]
Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
CipherString = AES128-SHA
Ciphersuites =
PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
[677-ciphersuite-sanity-check-server-client]
[677-ciphersuite-sanity-check-tls-server-client]
CipherString = AES128-SHA
MaxProtocol = TLSv1.2
VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
@ -18818,5 +18819,6 @@ VerifyMode = Peer
[test-677]
ExpectedResult = ServerFail
Method = TLS

File diff suppressed because it is too large Load diff

View file

@ -66,7 +66,7 @@ test-60 = 60-resumption
test-61 = 61-resumption
test-62 = 62-resumption
test-63 = 63-resumption
test-64 = 64-resumption-with-hrr
test-64 = 64-tls13-resumption-with-hrr
# ===========================================================
[0-resumption]
@ -2405,27 +2405,27 @@ ResumptionExpected = Yes
# ===========================================================
[64-resumption-with-hrr]
ssl_conf = 64-resumption-with-hrr-ssl
[64-tls13-resumption-with-hrr]
ssl_conf = 64-tls13-resumption-with-hrr-ssl
[64-resumption-with-hrr-ssl]
server = 64-resumption-with-hrr-server
client = 64-resumption-with-hrr-client
resume-server = 64-resumption-with-hrr-server
resume-client = 64-resumption-with-hrr-resume-client
[64-tls13-resumption-with-hrr-ssl]
server = 64-tls13-resumption-with-hrr-server
client = 64-tls13-resumption-with-hrr-client
resume-server = 64-tls13-resumption-with-hrr-server
resume-client = 64-tls13-resumption-with-hrr-resume-client
[64-resumption-with-hrr-server]
[64-tls13-resumption-with-hrr-server]
Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
CipherString = DEFAULT
Curves = P-256
PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
[64-resumption-with-hrr-client]
[64-tls13-resumption-with-hrr-client]
CipherString = DEFAULT
VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
VerifyMode = Peer
[64-resumption-with-hrr-resume-client]
[64-tls13-resumption-with-hrr-resume-client]
CipherString = DEFAULT
VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
VerifyMode = Peer

View file

@ -1,620 +1,4 @@
# Generated with generate_ssl_tests.pl
num_tests = 16
test-0 = 0-resumption
test-1 = 1-resumption
test-2 = 2-resumption
test-3 = 3-resumption
test-4 = 4-resumption
test-5 = 5-resumption
test-6 = 6-resumption
test-7 = 7-resumption
test-8 = 8-resumption
test-9 = 9-resumption
test-10 = 10-resumption
test-11 = 11-resumption
test-12 = 12-resumption
test-13 = 13-resumption
test-14 = 14-resumption
test-15 = 15-resumption
# ===========================================================
[0-resumption]
ssl_conf = 0-resumption-ssl
[0-resumption-ssl]
server = 0-resumption-server
client = 0-resumption-client
resume-server = 0-resumption-resume-server
resume-client = 0-resumption-client
[0-resumption-server]
Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
CipherString = DEFAULT:@SECLEVEL=0
MaxProtocol = DTLSv1
MinProtocol = DTLSv1
Options = SessionTicket
PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
[0-resumption-resume-server]
Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
CipherString = DEFAULT:@SECLEVEL=0
MaxProtocol = DTLSv1
Options = SessionTicket
PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
[0-resumption-client]
CipherString = DEFAULT:@SECLEVEL=0
VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
VerifyMode = Peer
[test-0]
ExpectedProtocol = DTLSv1
HandshakeMode = Resume
Method = DTLS
ResumptionExpected = Yes
# ===========================================================
[1-resumption]
ssl_conf = 1-resumption-ssl
[1-resumption-ssl]
server = 1-resumption-server
client = 1-resumption-client
resume-server = 1-resumption-resume-server
resume-client = 1-resumption-client
[1-resumption-server]
Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
CipherString = DEFAULT:@SECLEVEL=0
MaxProtocol = DTLSv1
MinProtocol = DTLSv1
Options = -SessionTicket
PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
[1-resumption-resume-server]
Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
CipherString = DEFAULT:@SECLEVEL=0
MaxProtocol = DTLSv1
Options = -SessionTicket
PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
[1-resumption-client]
CipherString = DEFAULT:@SECLEVEL=0
VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
VerifyMode = Peer
[test-1]
ExpectedProtocol = DTLSv1
HandshakeMode = Resume
Method = DTLS
ResumptionExpected = Yes
# ===========================================================
[2-resumption]
ssl_conf = 2-resumption-ssl
[2-resumption-ssl]
server = 2-resumption-server
client = 2-resumption-client
resume-server = 2-resumption-resume-server
resume-client = 2-resumption-client
[2-resumption-server]
Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
CipherString = DEFAULT:@SECLEVEL=0
MaxProtocol = DTLSv1
MinProtocol = DTLSv1
Options = SessionTicket
PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
[2-resumption-resume-server]
Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
CipherString = DEFAULT:@SECLEVEL=0
MaxProtocol = DTLSv1.2
Options = SessionTicket
PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
[2-resumption-client]
CipherString = DEFAULT:@SECLEVEL=0
VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
VerifyMode = Peer
[test-2]
ExpectedProtocol = DTLSv1.2
HandshakeMode = Resume
Method = DTLS
ResumptionExpected = No
# ===========================================================
[3-resumption]
ssl_conf = 3-resumption-ssl
[3-resumption-ssl]
server = 3-resumption-server
client = 3-resumption-client
resume-server = 3-resumption-resume-server
resume-client = 3-resumption-client
[3-resumption-server]
Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
CipherString = DEFAULT:@SECLEVEL=0
MaxProtocol = DTLSv1
MinProtocol = DTLSv1
Options = -SessionTicket
PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
[3-resumption-resume-server]
Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
CipherString = DEFAULT:@SECLEVEL=0
MaxProtocol = DTLSv1.2
Options = -SessionTicket
PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
[3-resumption-client]
CipherString = DEFAULT:@SECLEVEL=0
VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
VerifyMode = Peer
[test-3]
ExpectedProtocol = DTLSv1.2
HandshakeMode = Resume
Method = DTLS
ResumptionExpected = No
# ===========================================================
[4-resumption]
ssl_conf = 4-resumption-ssl
[4-resumption-ssl]
server = 4-resumption-server
client = 4-resumption-client
resume-server = 4-resumption-resume-server
resume-client = 4-resumption-client
[4-resumption-server]
Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
CipherString = DEFAULT:@SECLEVEL=0
MaxProtocol = DTLSv1.2
MinProtocol = DTLSv1.2
Options = SessionTicket
PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
[4-resumption-resume-server]
Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
CipherString = DEFAULT:@SECLEVEL=0
MaxProtocol = DTLSv1
Options = SessionTicket
PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
[4-resumption-client]
CipherString = DEFAULT:@SECLEVEL=0
VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
VerifyMode = Peer
[test-4]
ExpectedProtocol = DTLSv1
HandshakeMode = Resume
Method = DTLS
ResumptionExpected = No
# ===========================================================
[5-resumption]
ssl_conf = 5-resumption-ssl
[5-resumption-ssl]
server = 5-resumption-server
client = 5-resumption-client
resume-server = 5-resumption-resume-server
resume-client = 5-resumption-client
[5-resumption-server]
Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
CipherString = DEFAULT:@SECLEVEL=0
MaxProtocol = DTLSv1.2
MinProtocol = DTLSv1.2
Options = -SessionTicket
PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
[5-resumption-resume-server]
Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
CipherString = DEFAULT:@SECLEVEL=0
MaxProtocol = DTLSv1
Options = -SessionTicket
PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
[5-resumption-client]
CipherString = DEFAULT:@SECLEVEL=0
VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
VerifyMode = Peer
[test-5]
ExpectedProtocol = DTLSv1
HandshakeMode = Resume
Method = DTLS
ResumptionExpected = No
# ===========================================================
[6-resumption]
ssl_conf = 6-resumption-ssl
[6-resumption-ssl]
server = 6-resumption-server
client = 6-resumption-client
resume-server = 6-resumption-resume-server
resume-client = 6-resumption-client
[6-resumption-server]
Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
CipherString = DEFAULT:@SECLEVEL=0
MaxProtocol = DTLSv1.2
MinProtocol = DTLSv1.2
Options = SessionTicket
PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
[6-resumption-resume-server]
Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
CipherString = DEFAULT:@SECLEVEL=0
MaxProtocol = DTLSv1.2
Options = SessionTicket
PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
[6-resumption-client]
CipherString = DEFAULT:@SECLEVEL=0
VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
VerifyMode = Peer
[test-6]
ExpectedProtocol = DTLSv1.2
HandshakeMode = Resume
Method = DTLS
ResumptionExpected = Yes
# ===========================================================
[7-resumption]
ssl_conf = 7-resumption-ssl
[7-resumption-ssl]
server = 7-resumption-server
client = 7-resumption-client
resume-server = 7-resumption-resume-server
resume-client = 7-resumption-client
[7-resumption-server]
Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
CipherString = DEFAULT:@SECLEVEL=0
MaxProtocol = DTLSv1.2
MinProtocol = DTLSv1.2
Options = -SessionTicket
PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
[7-resumption-resume-server]
Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
CipherString = DEFAULT:@SECLEVEL=0
MaxProtocol = DTLSv1.2
Options = -SessionTicket
PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
[7-resumption-client]
CipherString = DEFAULT:@SECLEVEL=0
VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
VerifyMode = Peer
[test-7]
ExpectedProtocol = DTLSv1.2
HandshakeMode = Resume
Method = DTLS
ResumptionExpected = Yes
# ===========================================================
[8-resumption]
ssl_conf = 8-resumption-ssl
[8-resumption-ssl]
server = 8-resumption-server
client = 8-resumption-client
resume-server = 8-resumption-server
resume-client = 8-resumption-resume-client
[8-resumption-server]
Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
CipherString = DEFAULT:@SECLEVEL=0
Options = SessionTicket
PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
[8-resumption-client]
CipherString = DEFAULT:@SECLEVEL=0
MaxProtocol = DTLSv1
MinProtocol = DTLSv1
VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
VerifyMode = Peer
[8-resumption-resume-client]
CipherString = DEFAULT:@SECLEVEL=0
MaxProtocol = DTLSv1
VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
VerifyMode = Peer
[test-8]
ExpectedProtocol = DTLSv1
HandshakeMode = Resume
Method = DTLS
ResumptionExpected = Yes
# ===========================================================
[9-resumption]
ssl_conf = 9-resumption-ssl
[9-resumption-ssl]
server = 9-resumption-server
client = 9-resumption-client
resume-server = 9-resumption-server
resume-client = 9-resumption-resume-client
[9-resumption-server]
Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
CipherString = DEFAULT:@SECLEVEL=0
Options = -SessionTicket
PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
[9-resumption-client]
CipherString = DEFAULT:@SECLEVEL=0
MaxProtocol = DTLSv1
MinProtocol = DTLSv1
VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
VerifyMode = Peer
[9-resumption-resume-client]
CipherString = DEFAULT:@SECLEVEL=0
MaxProtocol = DTLSv1
VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
VerifyMode = Peer
[test-9]
ExpectedProtocol = DTLSv1
HandshakeMode = Resume
Method = DTLS
ResumptionExpected = Yes
# ===========================================================
[10-resumption]
ssl_conf = 10-resumption-ssl
[10-resumption-ssl]
server = 10-resumption-server
client = 10-resumption-client
resume-server = 10-resumption-server
resume-client = 10-resumption-resume-client
[10-resumption-server]
Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
CipherString = DEFAULT:@SECLEVEL=0
Options = SessionTicket
PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
[10-resumption-client]
CipherString = DEFAULT:@SECLEVEL=0
MaxProtocol = DTLSv1
MinProtocol = DTLSv1
VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
VerifyMode = Peer
[10-resumption-resume-client]
CipherString = DEFAULT:@SECLEVEL=0
MaxProtocol = DTLSv1.2
VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
VerifyMode = Peer
[test-10]
ExpectedProtocol = DTLSv1.2
HandshakeMode = Resume
Method = DTLS
ResumptionExpected = No
# ===========================================================
[11-resumption]
ssl_conf = 11-resumption-ssl
[11-resumption-ssl]
server = 11-resumption-server
client = 11-resumption-client
resume-server = 11-resumption-server
resume-client = 11-resumption-resume-client
[11-resumption-server]
Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
CipherString = DEFAULT:@SECLEVEL=0
Options = -SessionTicket
PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
[11-resumption-client]
CipherString = DEFAULT:@SECLEVEL=0
MaxProtocol = DTLSv1
MinProtocol = DTLSv1
VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
VerifyMode = Peer
[11-resumption-resume-client]
CipherString = DEFAULT:@SECLEVEL=0
MaxProtocol = DTLSv1.2
VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
VerifyMode = Peer
[test-11]
ExpectedProtocol = DTLSv1.2
HandshakeMode = Resume
Method = DTLS
ResumptionExpected = No
# ===========================================================
[12-resumption]
ssl_conf = 12-resumption-ssl
[12-resumption-ssl]
server = 12-resumption-server
client = 12-resumption-client
resume-server = 12-resumption-server
resume-client = 12-resumption-resume-client
[12-resumption-server]
Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
CipherString = DEFAULT:@SECLEVEL=0
Options = SessionTicket
PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
[12-resumption-client]
CipherString = DEFAULT:@SECLEVEL=0
MaxProtocol = DTLSv1.2
MinProtocol = DTLSv1.2
VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
VerifyMode = Peer
[12-resumption-resume-client]
CipherString = DEFAULT:@SECLEVEL=0
MaxProtocol = DTLSv1
VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
VerifyMode = Peer
[test-12]
ExpectedProtocol = DTLSv1
HandshakeMode = Resume
Method = DTLS
ResumptionExpected = No
# ===========================================================
[13-resumption]
ssl_conf = 13-resumption-ssl
[13-resumption-ssl]
server = 13-resumption-server
client = 13-resumption-client
resume-server = 13-resumption-server
resume-client = 13-resumption-resume-client
[13-resumption-server]
Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
CipherString = DEFAULT:@SECLEVEL=0
Options = -SessionTicket
PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
[13-resumption-client]
CipherString = DEFAULT:@SECLEVEL=0
MaxProtocol = DTLSv1.2
MinProtocol = DTLSv1.2
VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
VerifyMode = Peer
[13-resumption-resume-client]
CipherString = DEFAULT:@SECLEVEL=0
MaxProtocol = DTLSv1
VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
VerifyMode = Peer
[test-13]
ExpectedProtocol = DTLSv1
HandshakeMode = Resume
Method = DTLS
ResumptionExpected = No
# ===========================================================
[14-resumption]
ssl_conf = 14-resumption-ssl
[14-resumption-ssl]
server = 14-resumption-server
client = 14-resumption-client
resume-server = 14-resumption-server
resume-client = 14-resumption-resume-client
[14-resumption-server]
Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
CipherString = DEFAULT:@SECLEVEL=0
Options = SessionTicket
PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
[14-resumption-client]
CipherString = DEFAULT:@SECLEVEL=0
MaxProtocol = DTLSv1.2
MinProtocol = DTLSv1.2
VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
VerifyMode = Peer
[14-resumption-resume-client]
CipherString = DEFAULT:@SECLEVEL=0
MaxProtocol = DTLSv1.2
VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
VerifyMode = Peer
[test-14]
ExpectedProtocol = DTLSv1.2
HandshakeMode = Resume
Method = DTLS
ResumptionExpected = Yes
# ===========================================================
[15-resumption]
ssl_conf = 15-resumption-ssl
[15-resumption-ssl]
server = 15-resumption-server
client = 15-resumption-client
resume-server = 15-resumption-server
resume-client = 15-resumption-resume-client
[15-resumption-server]
Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
CipherString = DEFAULT:@SECLEVEL=0
Options = -SessionTicket
PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
[15-resumption-client]
CipherString = DEFAULT:@SECLEVEL=0
MaxProtocol = DTLSv1.2
MinProtocol = DTLSv1.2
VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
VerifyMode = Peer
[15-resumption-resume-client]
CipherString = DEFAULT:@SECLEVEL=0
MaxProtocol = DTLSv1.2
VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
VerifyMode = Peer
[test-15]
ExpectedProtocol = DTLSv1.2
HandshakeMode = Resume
Method = DTLS
ResumptionExpected = Yes
num_tests = 0

View file

@ -72,6 +72,7 @@ client = 2-SCTPLabelBug-bad1-client
[2-SCTPLabelBug-bad1-server]
Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
CipherString = DEFAULT
MaxProtocol = DTLSv1.2
PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
[2-SCTPLabelBug-bad1-client]
@ -99,6 +100,7 @@ client = 3-SCTPLabelBug-bad2-client
[3-SCTPLabelBug-bad2-server]
Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
CipherString = DEFAULT
MaxProtocol = DTLSv1.2
PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
[3-SCTPLabelBug-bad2-client]

View file

@ -42,7 +42,10 @@ our @tests = (
},
{
name => "SCTPLabelBug-bad1",
server => {},
# TODO(DTLSv1.3): Fix SCTP support
server => {
MaxProtocol => "DTLSv1.2"
},
client => {},
test => {
"Method" => "DTLS",
@ -54,7 +57,10 @@ our @tests = (
},
{
name => "SCTPLabelBug-bad2",
server => {},
# TODO(DTLSv1.3): Fix SCTP support
server => {
MaxProtocol => "DTLSv1.2"
},
client => {},
test => {
"Method" => "DTLS",

View file

@ -66,6 +66,9 @@ sub max_prot_enabled {
foreach my $i (0..$#protocols) {
if (!$is_disabled[$i]
&& ($protocols[$i] ne "TLSv1.3"
|| !disabled("ec")
|| !disabled("dh"))
&& ($protocols[$i] ne "DTLSv1.3"
|| !disabled("ec")
|| !disabled("dh"))) {
$max_enabled = $i;
@ -80,16 +83,16 @@ $min_tls_enabled_fips = min_prot_enabled(\@tls_protocols_fips, \@is_tls_disabled
$max_tls_enabled_fips = max_prot_enabled(\@tls_protocols_fips, \@is_tls_disabled_fips);
my @dtls_protocols = ("DTLSv1", "DTLSv1.2");
my @dtls_protocols_fips = ("DTLSv1.2");
my @dtls_protocols = ("DTLSv1", "DTLSv1.2", "DTLSv1.3");
my @dtls_protocols_fips = ("DTLSv1.2", "DTLSv1.3");
# undef stands for "no limit".
my @min_dtls_protocols = (undef, "DTLSv1", "DTLSv1.2");
my @min_dtls_protocols_fips = (undef, "DTLSv1.2");
my @max_dtls_protocols = ("DTLSv1", "DTLSv1.2", undef);
my @max_dtls_protocols_fips = ("DTLSv1.2", undef);
my @min_dtls_protocols = (undef, "DTLSv1", "DTLSv1.2", "DTLSv1.3");
my @min_dtls_protocols_fips = (undef, "DTLSv1.2", "DTLSv1.3");
my @max_dtls_protocols = ("DTLSv1", "DTLSv1.2", "DTLSv1.3", undef);
my @max_dtls_protocols_fips = ("DTLSv1.2", "DTLSv1.3", undef);
my @is_dtls_disabled = anydisabled("dtls1", "dtls1_2");
my @is_dtls_disabled_fips = anydisabled("dtls1_2");
my @is_dtls_disabled = anydisabled("dtls1", "dtls1_2", "dtls1_3");
my @is_dtls_disabled_fips = anydisabled("dtls1_2", "dtls1_3");
my $min_dtls_enabled; my $max_dtls_enabled;
my $min_dtls_enabled_fips; my $max_dtls_enabled_fips;
@ -104,9 +107,9 @@ $max_dtls_enabled_fips = max_prot_enabled(\@dtls_protocols_fips, \@is_dtls_disab
sub no_tests {
my ($dtls, $fips) = @_;
if ($dtls && $fips) {
return disabled("dtls1_2");
return alldisabled("dtls1_2", "dtls1_3");
}
return $dtls ? alldisabled("dtls1", "dtls1_2") :
return $dtls ? alldisabled("dtls1", "dtls1_2", "dtls1_3") :
alldisabled("ssl3", "tls1", "tls1_1", "tls1_2", "tls1_3");
}
@ -178,15 +181,14 @@ sub generate_version_tests {
}
}
}
return @tests
if disabled("tls1_3")
|| disabled("tls1_2")
|| (disabled("ec") && disabled("dh"))
|| $dtls;
if (!$dtls && !(disabled("tls1_3")
|| disabled("tls1_2")
|| (disabled("ec") && disabled("dh"))))
{
#Add some version/ciphersuite sanity check tests
push @tests, {
"name" => "ciphersuite-sanity-check-client",
"name" => "ciphersuite-sanity-check-tls-client",
"client" => {
#Offering only <=TLSv1.2 ciphersuites with TLSv1.3 should fail
"CipherString" => "AES128-SHA",
@ -196,11 +198,12 @@ sub generate_version_tests {
"MaxProtocol" => "TLSv1.2"
},
"test" => {
"Method" => "TLS",
"ExpectedResult" => "ClientFail",
}
};
push @tests, {
"name" => "ciphersuite-sanity-check-server",
"name" => "ciphersuite-sanity-check-tls-server",
"client" => {
"CipherString" => "AES128-SHA",
"MaxProtocol" => "TLSv1.2"
@ -211,9 +214,49 @@ sub generate_version_tests {
"Ciphersuites" => "",
},
"test" => {
"Method" => "TLS",
"ExpectedResult" => "ServerFail",
}
};
}
if ($dtls && !(disabled("dtls1_3")
|| disabled("dtls1_2")
|| (disabled("ec") && disabled("dh"))))
{
#Add some version/ciphersuite sanity check tests
push @tests, {
"name" => "ciphersuite-sanity-check-dtls-client",
"client" => {
#Offering only <=DTLSv1.2 ciphersuites with DTLSv1.3 should fail
"CipherString" => "AES128-SHA",
"Ciphersuites" => "",
},
"server" => {
"MaxProtocol" => "DTLSv1.2"
},
"test" => {
"Method" => "DTLS",
"ExpectedResult" => "ClientFail",
}
};
push @tests, {
"name" => "ciphersuite-sanity-check-dtls-server",
"client" => {
"CipherString" => "AES128-SHA",
"MaxProtocol" => "DTLSv1.2"
},
"server" => {
#Allowing only <=DTLSv1.2 ciphersuites with DTLSv1.3 should fail
"CipherString" => "AES128-SHA",
"Ciphersuites" => "",
},
"test" => {
"Method" => "DTLS",
"ExpectedResult" => "ServerFail",
}
};
}
return @tests;
}
@ -240,6 +283,9 @@ sub generate_resumption_tests {
$max_enabled = $dtls ? $max_dtls_enabled : $max_tls_enabled;
}
# TODO(DTLSv1.3): Resumption tests fails
return if($dtls == 1);
if (no_tests($dtls)) {
return;
}
@ -319,7 +365,7 @@ sub generate_resumption_tests {
if (!disabled("tls1_3") && (!disabled("ec") || !disabled("dh")) && !$dtls) {
push @client_tests, {
"name" => "resumption-with-hrr",
"name" => "tls13-resumption-with-hrr",
"client" => {
},
"server" => {
@ -336,6 +382,25 @@ sub generate_resumption_tests {
};
}
if (!disabled("dtls1_3") && (!disabled("ec") || !disabled("dh")) && $dtls) {
push @client_tests, {
"name" => "dtls13-resumption-with-hrr",
"client" => {
},
"server" => {
"Curves" => disabled("ec") ? "ffdhe3072" : "P-256"
},
"resume_client" => {
},
"test" => {
"ExpectedProtocol" => "DTLSv1.3",
"Method" => "DTLS",
"HandshakeMode" => "Resume",
"ResumptionExpected" => "Yes",
}
};
}
return (@server_tests, @client_tests);
}
@ -362,7 +427,11 @@ sub expected_result {
|| ($orig_c_max != scalar @$protocols
&& $prots[$orig_c_max] eq "TLSv1.3"
&& $c_max != $orig_c_max
&& !disabled("tls1_3"))) {
&& !disabled("tls1_3"))
|| ($orig_c_max != scalar @$protocols
&& $prots[$orig_c_max] eq "DTLSv1.3"
&& $c_max != $orig_c_max
&& !disabled("dtls1_3"))) {
# Client should fail to even send a hello.
return ("ClientFail", undef);
} elsif ($s_min > $s_max) {
@ -372,7 +441,8 @@ sub expected_result {
# Server doesn't support the client range.
return ("ServerFail", undef);
} elsif ($c_min > $s_max) {
if ($prots[$c_max] eq "TLSv1.3") {
if ($prots[$c_max] eq "TLSv1.3"
|| $prots[$c_max] eq "DTLSv1.3") {
# Client will have sent supported_versions, so server will know
# that there are no overlapping versions.
return ("ServerFail", undef);

View file

@ -47,6 +47,9 @@ static const version_test version_testdata[] = {
{PROTO_TLS, 7, 42, 0, 0, 0, 0},
{PROTO_DTLS, 0, 0, 1, 1, 0, 0},
{PROTO_DTLS, DTLS1_VERSION, DTLS1_2_VERSION, 1, 1, DTLS1_VERSION, DTLS1_2_VERSION},
{PROTO_DTLS, DTLS1_VERSION, DTLS1_3_VERSION, 1, 1, DTLS1_VERSION, DTLS1_3_VERSION},
{PROTO_DTLS, DTLS1_2_VERSION, DTLS1_3_VERSION, 1, 1, DTLS1_2_VERSION, DTLS1_3_VERSION},
{PROTO_DTLS, DTLS1_3_VERSION, DTLS1_3_VERSION, 1, 1, DTLS1_3_VERSION, DTLS1_3_VERSION},
#ifndef OPENSSL_NO_DTLS1_2
{PROTO_DTLS, DTLS1_2_VERSION, DTLS1_2_VERSION, 1, 1, DTLS1_2_VERSION, DTLS1_2_VERSION},
#endif
@ -56,8 +59,8 @@ static const version_test version_testdata[] = {
#if !defined(OPENSSL_NO_DTLS1) && !defined(OPENSSL_NO_DTLS1_2)
{PROTO_DTLS, DTLS1_2_VERSION, DTLS1_VERSION, 1, 1, DTLS1_2_VERSION, DTLS1_VERSION},
#endif
{PROTO_DTLS, DTLS1_VERSION + 1, DTLS1_2_VERSION, 0, 1, 0, DTLS1_2_VERSION},
{PROTO_DTLS, DTLS1_VERSION, DTLS1_2_VERSION - 1, 1, 0, DTLS1_VERSION, 0},
{PROTO_DTLS, DTLS1_VERSION + 1, DTLS1_3_VERSION, 0, 1, 0, DTLS1_3_VERSION},
{PROTO_DTLS, DTLS1_VERSION, DTLS1_3_VERSION - 1, 1, 0, DTLS1_VERSION, 0},
{PROTO_DTLS, TLS1_VERSION, TLS1_3_VERSION, 1, 1, 0, 0},
{PROTO_DTLS, OSSL_QUIC1_VERSION, OSSL_QUIC1_VERSION, 0, 0, 0, 0},
/* These functions never have an effect when called on a QUIC object */
@ -66,7 +69,7 @@ static const version_test version_testdata[] = {
{PROTO_QUIC, OSSL_QUIC1_VERSION, OSSL_QUIC1_VERSION + 1, 0, 0, 0, 0},
{PROTO_QUIC, TLS1_VERSION, TLS1_3_VERSION, 1, 1, 0, 0},
#ifndef OPENSSL_NO_DTLS
{PROTO_QUIC, DTLS1_VERSION, DTLS1_2_VERSION, 1, 1, 0, 0},
{PROTO_QUIC, DTLS1_VERSION, DTLS1_3_VERSION, 1, 1, 0, 0},
#endif
};

View file

@ -826,7 +826,8 @@ static int protocol_from_string(const char *value)
{"tls1.2", TLS1_2_VERSION},
{"tls1.3", TLS1_3_VERSION},
{"dtls1", DTLS1_VERSION},
{"dtls1.2", DTLS1_2_VERSION}};
{"dtls1.2", DTLS1_2_VERSION},
{"dtls1.3", DTLS1_3_VERSION}};
size_t i;
size_t n = OSSL_NELEM(versions);

View file

@ -969,7 +969,7 @@ static int execute_test_large_message(const SSL_METHOD *smeth,
privkey)))
goto end;
#ifdef OPENSSL_NO_DTLS1_2
#if defined(OPENSSL_NO_DTLS1_2) && defined(OPENSSL_NO_DTLS1_3)
if (smeth == DTLS_server_method()) {
/*
* Default sigalgs are SHA1 based in <DTLS1.2 which is in security
@ -11484,6 +11484,9 @@ static int check_version_string(SSL *s, int version)
break;
case DTLS1_2_VERSION:
verstr = "DTLSv1.2";
break;
case DTLS1_3_VERSION:
verstr = "DTLSv1.3";
}
return TEST_str_eq(verstr, SSL_get_version(s));

View file

@ -336,7 +336,8 @@ static int test_tls13_encryption(void)
NULL, NULL, TLS1_3_VERSION, OSSL_RECORD_ROLE_SERVER,
OSSL_RECORD_DIRECTION_WRITE,
OSSL_RECORD_PROTECTION_LEVEL_APPLICATION, 0, NULL, 0,
key, 16, iv, ivlen, NULL, 0, EVP_aes_128_gcm(),
NULL, key, 16, iv, ivlen, NULL, 0, NULL, 0,
EVP_aes_128_gcm(),
EVP_GCM_TLS_TAG_LEN, 0, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
&wrl)))
@ -359,7 +360,8 @@ static int test_tls13_encryption(void)
NULL, NULL, TLS1_3_VERSION, OSSL_RECORD_ROLE_SERVER,
OSSL_RECORD_DIRECTION_READ,
OSSL_RECORD_PROTECTION_LEVEL_APPLICATION, 0, NULL, 0,
key, 16, iv, ivlen, NULL, 0, EVP_aes_128_gcm(),
NULL, key, 16, iv, ivlen, NULL, 0, NULL, 0,
EVP_aes_128_gcm(),
EVP_GCM_TLS_TAG_LEN, 0, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
&rrl)))

View file

@ -157,6 +157,11 @@ const EVP_MD *ssl_handshake_md(SSL_CONNECTION *s)
return EVP_sha256();
}
int ssl_cipher_get_evp_cipher_sn(SSL_CTX *ctx, const SSL_CIPHER *sslc,
const EVP_CIPHER **enc, size_t *inputoffs) {
return 0;
}
int ssl_cipher_get_evp_cipher(SSL_CTX *ctx, const SSL_CIPHER *sslc,
const EVP_CIPHER **enc)
{
@ -171,7 +176,9 @@ int ssl_cipher_get_evp_md_mac(SSL_CTX *ctx, const SSL_CIPHER *sslc,
}
int ssl_cipher_get_evp(SSL_CTX *ctx, const SSL_SESSION *s,
const EVP_CIPHER **enc, const EVP_MD **md,
const EVP_CIPHER **snenc, size_t *snencoffs,
const EVP_CIPHER **enc,
const EVP_MD **md,
int *mac_pkey_type, size_t *mac_secret_size,
SSL_COMP **comp, int use_etm)
@ -226,9 +233,11 @@ void ssl_evp_md_free(const EVP_MD *md)
int ssl_set_new_record_layer(SSL_CONNECTION *s, int version, int direction,
int level, unsigned char *secret, size_t secretlen,
unsigned char *snkey,
unsigned char *key, size_t keylen,
unsigned char *iv, size_t ivlen,
unsigned char *mackey, size_t mackeylen,
const EVP_CIPHER *snciph, size_t snoffs,
const EVP_CIPHER *ciph, size_t taglen,
int mactype, const EVP_MD *md,
const SSL_COMP *comp, const EVP_MD *kdfdigest)
@ -236,6 +245,23 @@ int ssl_set_new_record_layer(SSL_CONNECTION *s, int version, int direction,
return 0;
}
void dtls1_clear_received_buffer(SSL_CONNECTION *s)
{
}
void dtls1_clear_sent_buffer(SSL_CONNECTION *s)
{
}
uint16_t dtls1_get_epoch(SSL_CONNECTION *s, int rw)
{
return 0;
}
void dtls1_increment_epoch(SSL_CONNECTION *s, int rw)
{
}
/* End of mocked out code */
static int test_secret(SSL_CONNECTION *s, unsigned char *prk,

View file

@ -600,6 +600,8 @@
-T clock_t
-T custom_ext_methods
-T hm_fragment
-T dtls_msg_info
-T dtls_sent_msg
-T ssl_ctx_st
-T ssl_flag_tbl
-T ssl_st

View file

@ -18,7 +18,7 @@ sub new
my ($isdtls,
$server,
$msgseq,
$msgfrag,
$msgfraglen,
$msgfragoffs,
$data,
$records,
@ -30,7 +30,7 @@ sub new
$server,
TLSProxy::Message::MT_CERTIFICATE,
$msgseq,
$msgfrag,
$msgfraglen,
$msgfragoffs,
$data,
$records,

View file

@ -18,7 +18,7 @@ sub new
my ($isdtls,
$server,
$msgseq,
$msgfrag,
$msgfraglen,
$msgfragoffs,
$data,
$records,
@ -30,7 +30,7 @@ sub new
$server,
TLSProxy::Message::MT_CERTIFICATE_REQUEST,
$msgseq,
$msgfrag,
$msgfraglen,
$msgfragoffs,
$data,
$records,

View file

@ -18,7 +18,7 @@ sub new
my ($isdtls,
$server,
$msgseq,
$msgfrag,
$msgfraglen,
$msgfragoffs,
$data,
$records,
@ -30,7 +30,7 @@ sub new
$server,
TLSProxy::Message::MT_CERTIFICATE_VERIFY,
$msgseq,
$msgfrag,
$msgfraglen,
$msgfragoffs,
$data,
$records,

View file

@ -20,7 +20,7 @@ sub new
my ($isdtls,
$server,
$msgseq,
$msgfrag,
$msgfraglen,
$msgfragoffs,
$data,
$records,
@ -32,7 +32,7 @@ sub new
$server,
TLSProxy::Message::MT_CLIENT_HELLO,
$msgseq,
$msgfrag,
$msgfraglen,
$msgfragoffs,
$data,
$records,

View file

@ -18,7 +18,7 @@ sub new
my ($isdtls,
$server,
$msgseq,
$msgfrag,
$msgfraglen,
$msgfragoffs,
$data,
$records,
@ -30,7 +30,7 @@ sub new
$server,
TLSProxy::Message::MT_ENCRYPTED_EXTENSIONS,
$msgseq,
$msgfrag,
$msgfraglen,
$msgfragoffs,
$data,
$records,

View file

@ -21,7 +21,7 @@ sub new
my ($isdtls,
$server,
$msgseq,
$msgfrag,
$msgfraglen,
$msgfragoffs,
$data,
$records,
@ -33,7 +33,7 @@ sub new
$server,
TLSProxy::Message::MT_HELLO_VERIFY_REQUEST,
$msgseq,
$msgfrag,
$msgfraglen,
$msgfragoffs,
$data,
$records,

Some files were not shown because too many files have changed in this diff Show more