diff options
author | Erlang/OTP <otp@erlang.org> | 2022-06-21 08:26:00 +0200 |
---|---|---|
committer | Erlang/OTP <otp@erlang.org> | 2022-06-21 08:26:00 +0200 |
commit | cfa6f8ab5c0f5232c2eea768f66aea6dccf2cb88 (patch) | |
tree | e971f26bd3273f9df9fcc17a622f44a02566aa68 | |
parent | 3f7ec1043a7b1f814386388cf959b668fd1ed1e5 (diff) | |
parent | 254f2728902bc7e80a67726ebbc1a0b3ab7742eb (diff) | |
download | erlang-cfa6f8ab5c0f5232c2eea768f66aea6dccf2cb88.tar.gz |
Merge branch 'ingela/ssl/client-certification/OTP-18145' into maint-25
* ingela/ssl/client-certification/OTP-18145:
ssl: Enhanch handling of unexpected messages
-rw-r--r-- | lib/ssl/src/dtls_connection.erl | 25 | ||||
-rw-r--r-- | lib/ssl/src/ssl_connection.hrl | 6 | ||||
-rw-r--r-- | lib/ssl/src/ssl_gen_statem.erl | 2 | ||||
-rw-r--r-- | lib/ssl/src/tls_connection.erl | 21 | ||||
-rw-r--r-- | lib/ssl/src/tls_dtls_connection.erl | 137 | ||||
-rw-r--r-- | lib/ssl/src/tls_gen_connection.erl | 2 | ||||
-rw-r--r-- | lib/ssl/src/tls_handshake_1_3.erl | 4 | ||||
-rw-r--r-- | lib/ssl/test/ssl_npn_SUITE.erl | 8 |
8 files changed, 140 insertions, 65 deletions
diff --git a/lib/ssl/src/dtls_connection.erl b/lib/ssl/src/dtls_connection.erl index d0a6032e28..8f2eb7d82b 100644 --- a/lib/ssl/src/dtls_connection.erl +++ b/lib/ssl/src/dtls_connection.erl @@ -46,7 +46,8 @@ %% ClientKeyExchange \ %% CertificateVerify* Flight 5 %% [ChangeCipherSpec] / -%% Finished --------> / +%% NextProtocol* / +%% Finished --------> / %% %% [ChangeCipherSpec] \ Flight 6 %% <-------- Finished / @@ -64,7 +65,8 @@ %% <-------- Finished / part 2 %% %% [ChangeCipherSpec] \ Abbrev Flight 3 -%% Finished --------> / +%% NextProtocol* / +%% Finished --------> / %% %% %% Message Flights for Abbbriviated Handshake @@ -142,6 +144,7 @@ user_hello/3, wait_ocsp_stapling/3, certify/3, + wait_cert_verify/3, cipher/3, abbreviated/3, connection/3]). @@ -463,6 +466,24 @@ certify(state_timeout, Event, State) -> certify(Type, Event, State) -> gen_handshake(?FUNCTION_NAME, Type, Event, State). + +%%-------------------------------------------------------------------- +-spec wait_cert_verify(gen_statem:event_type(), term(), #state{}) -> + gen_statem:state_function_result(). +%%-------------------------------------------------------------------- +wait_cert_verify(enter, _Event, State0) -> + {State, Actions} = handle_flight_timer(State0), + {keep_state, State, Actions}; +wait_cert_verify(info, Event, State) -> + gen_info(Event, ?FUNCTION_NAME, State); +wait_cert_verify(state_timeout, Event, State) -> + handle_state_timeout(Event, ?FUNCTION_NAME, State); +wait_cert_verify(Type, Event, State) -> + try tls_dtls_connection:gen_handshake(?FUNCTION_NAME, Type, Event, State) + catch throw:#alert{} = Alert -> + ssl_gen_statem:handle_own_alert(Alert, ?FUNCTION_NAME, State) + end. + %%-------------------------------------------------------------------- -spec cipher(gen_statem:event_type(), term(), #state{}) -> gen_statem:state_function_result(). diff --git a/lib/ssl/src/ssl_connection.hrl b/lib/ssl/src/ssl_connection.hrl index 02b3a6a50d..c8295f339f 100644 --- a/lib/ssl/src/ssl_connection.hrl +++ b/lib/ssl/src/ssl_connection.hrl @@ -123,7 +123,7 @@ %% need to worry about packet loss in TLS. In DTLS we %% need to track DTLS handshake seqnr flight_buffer = [] :: list() | map(), - client_certificate_requested = false :: boolean(), + client_certificate_status = not_requested :: not_requested | requested | empty | needs_verifying | verified, protocol_specific = #{} :: map(), session :: #session{} | secret_printout(), key_share, @@ -155,8 +155,8 @@ %% session_cache_cb - not implemented %% crl_db - not implemented %% client_hello_version - Bleichenbacher mitigation in TLS 1.2 -%% client_certificate_requested - Built into TLS 1.3 state machine -%% key_algorithm - not used +%% client_certificate_status - only uses non_requested| requested +%% key_algorithm - only uses not_requested and requested %% diffie_hellman_params - used in TLS 1.2 ECDH key exchange %% diffie_hellman_keys - used in TLS 1.2 ECDH key exchange %% psk_identity - not used diff --git a/lib/ssl/src/ssl_gen_statem.erl b/lib/ssl/src/ssl_gen_statem.erl index 45f938fecb..a379c8d94f 100644 --- a/lib/ssl/src/ssl_gen_statem.erl +++ b/lib/ssl/src/ssl_gen_statem.erl @@ -725,8 +725,6 @@ handle_common_event(internal, {protocol_record, TLSorDTLSRecord}, StateName, Connection:handle_protocol_record(TLSorDTLSRecord, StateName, State); handle_common_event(timeout, hibernate, _, _) -> {keep_state_and_data, [hibernate]}; -handle_common_event(internal, #change_cipher_spec{type = <<1>>}, StateName, State) -> - handle_own_alert(?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE), StateName, State); handle_common_event({timeout, handshake}, close, _StateName, #state{start_or_recv_from = StartFrom} = State) -> {stop_and_reply, {shutdown, user_timeout}, diff --git a/lib/ssl/src/tls_connection.erl b/lib/ssl/src/tls_connection.erl index 9ed8588f81..6b659881eb 100644 --- a/lib/ssl/src/tls_connection.erl +++ b/lib/ssl/src/tls_connection.erl @@ -34,6 +34,7 @@ %% ClientKeyExchange \ %% CertificateVerify* Flight 3 part 1 %% [ChangeCipherSpec] / +%% NextProtocol* %% Finished --------> / Flight 3 part 2 %% [ChangeCipherSpec] %% <-------- Finished Flight 4 @@ -48,6 +49,7 @@ %% [ChangeCipherSpec] %% <-------- Finished Abbrev Flight 2 part 2 %% [ChangeCipherSpec] +%% NextProtocol* %% Finished --------> Abbrev Flight 3 %% Application Data <-------> Application Data %% @@ -70,13 +72,14 @@ %% | %% New session | Resumed session %% WAIT_OCSP_STAPELING CERTIFY <----------------------------------> ABBRIVIATED -%% +%% WAIT_CERT_VERIFY %% <- Possibly Receive -- | | -%% OCSP Stapel ------> | Flight 3 part 1 | +%% OCSP Stapel/CertVerify -> | Flight 3 part 1 | %% | | %% V | Abbrev Flight 2 part 2 to Abbrev Flight 3 %% CIPHER | %% | | +%% | | %% | Fligth 3 part 2 to Flight 4 | %% | | %% V V @@ -122,6 +125,7 @@ user_hello/3, wait_ocsp_stapling/3, certify/3, + wait_cert_verify/3, cipher/3, abbreviated/3, connection/3]). @@ -316,6 +320,19 @@ certify(Type, Event, State) -> ssl_gen_statem:handle_own_alert(Alert, ?FUNCTION_NAME, State) end. + +%%-------------------------------------------------------------------- +-spec wait_cert_verify(gen_statem:event_type(), term(), #state{}) -> + gen_statem:state_function_result(). +%%-------------------------------------------------------------------- +wait_cert_verify(info, Event, State) -> + gen_info(Event, ?FUNCTION_NAME, State); +wait_cert_verify(Type, Event, State) -> + try tls_dtls_connection:gen_handshake(?FUNCTION_NAME, Type, Event, State) + catch throw:#alert{} = Alert -> + ssl_gen_statem:handle_own_alert(Alert, ?FUNCTION_NAME, State) + end. + %%-------------------------------------------------------------------- -spec cipher(gen_statem:event_type(), term(), #state{}) -> gen_statem:state_function_result(). diff --git a/lib/ssl/src/tls_dtls_connection.erl b/lib/ssl/src/tls_dtls_connection.erl index 0e5197647f..5f27d944c7 100644 --- a/lib/ssl/src/tls_dtls_connection.erl +++ b/lib/ssl/src/tls_dtls_connection.erl @@ -56,6 +56,7 @@ user_hello/3, abbreviated/3, certify/3, + wait_cert_verify/3, wait_ocsp_stapling/3, cipher/3, connection/3, @@ -318,7 +319,7 @@ certify(internal, #certificate{asn1_certificates = []}, ssl_options = #{verify := verify_peer, fail_if_no_peer_cert := false}} = State0) -> - Connection:next_event(?FUNCTION_NAME, no_record, State0#state{client_certificate_requested = false}); + Connection:next_event(?FUNCTION_NAME, no_record, State0#state{client_certificate_status = empty}); certify(internal, #certificate{}, #state{static_env = #static_env{role = server}, ssl_options = #{verify := verify_none}}) -> @@ -340,14 +341,19 @@ certify(internal, #certificate{asn1_certificates = [Peer|_]} = Cert, ocsp_stapling_state = #{ocsp_expect := Status} = OcspState}, connection_env = #connection_env{ negotiated_version = Version}, - ssl_options = Opts} = State) when Status =/= staple -> + ssl_options = Opts} = State0) when Status =/= staple -> OcspInfo = ocsp_info(OcspState, Opts, Peer), case ssl_handshake:certify(Cert, CertDbHandle, CertDbRef, Opts, CRLDbInfo, Role, Host, ensure_tls(Version), OcspInfo) of {PeerCert, PublicKeyInfo} -> - handle_peer_cert(Role, PeerCert, PublicKeyInfo, - State#state{client_certificate_requested = false}, Connection, []); + State = case Role of + server -> + State0#state{client_certificate_status = needs_verifying}; + client -> + State0 + end, + handle_peer_cert(Role, PeerCert, PublicKeyInfo, State, Connection, []); #alert{} = Alert -> throw(Alert) end; @@ -415,7 +421,7 @@ certify(internal, #certificate_request{}, %% The client does not have a certificate and will send an empty reply, the server may fail %% or accept the connection by its own preference. No signature algorithms needed as there is %% no certificate to verify. - Connection:next_event(?FUNCTION_NAME, no_record, State#state{client_certificate_requested = true, + Connection:next_event(?FUNCTION_NAME, no_record, State#state{client_certificate_status = requested, session = Session0#session{own_certificates = [[]], private_key = #{}}}); certify(internal, #certificate_request{} = CertRequest, @@ -434,7 +440,7 @@ certify(internal, #certificate_request{} = CertRequest, SupportedHashSigns, TLSVersion, CertDbHandle, CertDbRef), Connection:next_event(?FUNCTION_NAME, no_record, - State#state{client_certificate_requested = true, + State#state{client_certificate_status = requested, session = Session}); %% PSK and RSA_PSK might bypass the Server-Key-Exchange certify(internal, #server_hello_done{}, @@ -513,7 +519,7 @@ certify(internal, #server_hello_done{}, end; certify(internal = Type, #client_key_exchange{} = Msg, #state{static_env = #static_env{role = server}, - client_certificate_requested = true, + client_certificate_status = requested, ssl_options = #{fail_if_no_peer_cert := true}}) -> %% We expect a certificate here throw(?ALERT_REC(?FATAL,?UNEXPECTED_MESSAGE, {unexpected_msg, {Type, Msg}})); @@ -534,25 +540,22 @@ certify(Type, Event, State) -> ssl_gen_statem:handle_common_event(Type, Event, ?FUNCTION_NAME, State). %%-------------------------------------------------------------------- --spec cipher(gen_statem:event_type(), - #hello_request{} | #certificate_verify{} | #finished{} | term(), +-spec wait_cert_verify(gen_statem:event_type(), + #hello_request{} | #certificate_verify{} | term(), #state{}) -> gen_statem:state_function_result(). %%-------------------------------------------------------------------- -cipher({call, From}, Msg, State) -> - handle_call(Msg, From, ?FUNCTION_NAME, State); -cipher(info, Msg, State) -> - handle_info(Msg, ?FUNCTION_NAME, State); -cipher(internal, #certificate_verify{signature = Signature, - hashsign_algorithm = CertHashSign}, - #state{static_env = #static_env{role = server, - protocol_cb = Connection}, - handshake_env = #handshake_env{tls_handshake_history = Hist, - kex_algorithm = KexAlg, +wait_cert_verify(internal, #certificate_verify{signature = Signature, + hashsign_algorithm = CertHashSign}, + #state{static_env = #static_env{role = server, + protocol_cb = Connection}, + client_certificate_status = needs_verifying, + handshake_env = #handshake_env{tls_handshake_history = Hist, + kex_algorithm = KexAlg, public_key_info = PubKeyInfo}, - connection_env = #connection_env{negotiated_version = Version}, - session = #session{master_secret = MasterSecret} = Session0 - } = State) -> + connection_env = #connection_env{negotiated_version = Version}, + session = #session{master_secret = MasterSecret} = Session0 + } = State) -> TLSVersion = ssl:tls_version(Version), %% Use negotiated value if TLS-1.2 otherwise return default @@ -560,17 +563,27 @@ cipher(internal, #certificate_verify{signature = Signature, case ssl_handshake:certificate_verify(Signature, PubKeyInfo, TLSVersion, HashSign, MasterSecret, Hist) of valid -> - Connection:next_event(?FUNCTION_NAME, no_record, - State#state{session = Session0#session{sign_alg = HashSign}}); + Connection:next_event(cipher, no_record, + State#state{client_certificate_status = verified, + session = Session0#session{sign_alg = HashSign}}); #alert{} = Alert -> throw(Alert) end; -%% client must send a next protocol message if we are expecting it -cipher(internal, #finished{}, - #state{static_env = #static_env{role = server}, - handshake_env = #handshake_env{expecting_next_protocol_negotiation = true, - negotiated_protocol = undefined}}) -> - throw(?ALERT_REC(?FATAL,?UNEXPECTED_MESSAGE)); +wait_cert_verify(internal, #hello_request{}, _) -> + keep_state_and_data; +wait_cert_verify(Type, Event, State) -> + ssl_gen_statem:handle_common_event(Type, Event, ?FUNCTION_NAME, State). + +%%-------------------------------------------------------------------- +-spec cipher(gen_statem:event_type(), + #hello_request{} | #finished{} | term(), + #state{}) -> + gen_statem:state_function_result(). +%%-------------------------------------------------------------------- +cipher({call, From}, Msg, State) -> + handle_call(Msg, From, ?FUNCTION_NAME, State); +cipher(info, Msg, State) -> + handle_info(Msg, ?FUNCTION_NAME, State); cipher(internal, #finished{verify_data = Data} = Finished, #state{static_env = #static_env{role = Role, host = Host, @@ -866,18 +879,18 @@ handle_peer_cert_key(_, _, _, _, State) -> certify_client(#state{static_env = #static_env{role = client, cert_db = CertDbHandle, cert_db_ref = CertDbRef}, - client_certificate_requested = true, + client_certificate_status = requested, session = #session{own_certificates = OwnCerts}} = State, Connection) -> Certificate = ssl_handshake:certificate(OwnCerts, CertDbHandle, CertDbRef, client), Connection:queue_handshake(Certificate, State); -certify_client(#state{client_certificate_requested = false} = State, _) -> +certify_client(#state{client_certificate_status = not_requested} = State, _) -> State. verify_client_cert(#state{static_env = #static_env{role = client}, handshake_env = #handshake_env{tls_handshake_history = Hist}, connection_env = #connection_env{negotiated_version = Version}, - client_certificate_requested = true, + client_certificate_status = requested, session = #session{sign_alg = HashSign, master_secret = MasterSecret, private_key = PrivateKey, @@ -891,13 +904,13 @@ verify_client_cert(#state{static_env = #static_env{role = client}, #alert{} = Alert -> throw(Alert) end; -verify_client_cert(#state{client_certificate_requested = false} = State, _) -> +verify_client_cert(#state{client_certificate_status = not_requested} = State, _) -> State. client_certify_and_key_exchange(State0, Connection) -> State1 = do_client_certify_and_key_exchange(State0, Connection), {State2, Actions} = finalize_handshake(State1, certify, Connection), - State = State2#state{client_certificate_requested = false}, %% Reinitialize + State = State2#state{client_certificate_status = not_requested}, %% Reinitialize Connection:next_event(cipher, no_record, State, Actions). do_client_certify_and_key_exchange(State0, Connection) -> @@ -912,7 +925,8 @@ server_certify_and_key_exchange(State0, Connection) -> certify_client_key_exchange(#encrypted_premaster_secret{premaster_secret= EncPMS}, #state{session = #session{private_key = PrivateKey}, - handshake_env = #handshake_env{client_hello_version = {Major, Minor} = Version}} + handshake_env = #handshake_env{client_hello_version = {Major, Minor} = Version}, + client_certificate_status = CCStatus} = State, Connection) -> FakeSecret = make_premaster_secret(Version, rsa), %% Countermeasure for Bleichenbacher attack always provide some kind of premaster secret @@ -932,55 +946,74 @@ certify_client_key_exchange(#encrypted_premaster_secret{premaster_secret= EncPMS #alert{description = ?DECRYPT_ERROR} -> FakeSecret end, - calculate_master_secret(PremasterSecret, State, Connection, certify, cipher); + calculate_master_secret(PremasterSecret, State, Connection, certify, client_kex_next_state(CCStatus)); certify_client_key_exchange(#client_diffie_hellman_public{dh_public = ClientPublicDhKey}, #state{handshake_env = #handshake_env{diffie_hellman_params = #'DHParameter'{} = Params, - kex_keys = {_, ServerDhPrivateKey}} + kex_keys = {_, ServerDhPrivateKey}}, + client_certificate_status = CCStatus } = State, Connection) -> PremasterSecret = ssl_handshake:premaster_secret(ClientPublicDhKey, ServerDhPrivateKey, Params), - calculate_master_secret(PremasterSecret, State, Connection, certify, cipher); + calculate_master_secret(PremasterSecret, State, Connection, certify, client_kex_next_state(CCStatus)); certify_client_key_exchange(#client_ec_diffie_hellman_public{dh_public = ClientPublicEcDhPoint}, - #state{handshake_env = #handshake_env{kex_keys = ECDHKey}} = State, Connection) -> + #state{handshake_env = #handshake_env{kex_keys = ECDHKey}, + client_certificate_status = CCStatus + } = State, Connection) -> PremasterSecret = ssl_handshake:premaster_secret(#'ECPoint'{point = ClientPublicEcDhPoint}, ECDHKey), - calculate_master_secret(PremasterSecret, State, Connection, certify, cipher); + calculate_master_secret(PremasterSecret, State, Connection, certify, client_kex_next_state(CCStatus)); certify_client_key_exchange(#client_psk_identity{} = ClientKey, #state{ssl_options = - #{user_lookup_fun := PSKLookup}} = State0, + #{user_lookup_fun := PSKLookup}, + client_certificate_status = CCStatus + } = State0, Connection) -> PremasterSecret = ssl_handshake:premaster_secret(ClientKey, PSKLookup), - calculate_master_secret(PremasterSecret, State0, Connection, certify, cipher); + calculate_master_secret(PremasterSecret, State0, Connection, certify, client_kex_next_state(CCStatus)); certify_client_key_exchange(#client_dhe_psk_identity{} = ClientKey, #state{handshake_env = #handshake_env{diffie_hellman_params = #'DHParameter'{} = Params, kex_keys = {_, ServerDhPrivateKey}}, ssl_options = - #{user_lookup_fun := PSKLookup}} = State0, + #{user_lookup_fun := PSKLookup}, + client_certificate_status = CCStatus + } = State0, Connection) -> PremasterSecret = ssl_handshake:premaster_secret(ClientKey, ServerDhPrivateKey, Params, PSKLookup), - calculate_master_secret(PremasterSecret, State0, Connection, certify, cipher); + calculate_master_secret(PremasterSecret, State0, Connection, certify, client_kex_next_state(CCStatus)); certify_client_key_exchange(#client_ecdhe_psk_identity{} = ClientKey, #state{handshake_env = #handshake_env{kex_keys = ServerEcDhPrivateKey}, ssl_options = - #{user_lookup_fun := PSKLookup}} = State, + #{user_lookup_fun := PSKLookup}, + client_certificate_status = CCStatus + } = State, Connection) -> PremasterSecret = ssl_handshake:premaster_secret(ClientKey, ServerEcDhPrivateKey, PSKLookup), - calculate_master_secret(PremasterSecret, State, Connection, certify, cipher); + calculate_master_secret(PremasterSecret, State, Connection, certify, client_kex_next_state(CCStatus)); certify_client_key_exchange(#client_rsa_psk_identity{} = ClientKey, #state{session = #session{private_key = PrivateKey}, ssl_options = - #{user_lookup_fun := PSKLookup}} = State0, + #{user_lookup_fun := PSKLookup}, + client_certificate_status = CCStatus + } = State0, Connection) -> PremasterSecret = ssl_handshake:premaster_secret(ClientKey, PrivateKey, PSKLookup), - calculate_master_secret(PremasterSecret, State0, Connection, certify, cipher); + calculate_master_secret(PremasterSecret, State0, Connection, certify, client_kex_next_state(CCStatus)); certify_client_key_exchange(#client_srp_public{} = ClientKey, #state{handshake_env = #handshake_env{srp_params = Params, - kex_keys = Key} + kex_keys = Key}, + client_certificate_status = CCStatus } = State0, Connection) -> PremasterSecret = ssl_handshake:premaster_secret(ClientKey, Key, Params), - calculate_master_secret(PremasterSecret, State0, Connection, certify, cipher). + calculate_master_secret(PremasterSecret, State0, Connection, certify, client_kex_next_state(CCStatus)). + +client_kex_next_state(needs_verifying) -> + wait_cert_verify; +client_kex_next_state(empty) -> + cipher; +client_kex_next_state(not_requested) -> + cipher. certify_server(#state{handshake_env = #handshake_env{kex_algorithm = KexAlg}} = State, _) when KexAlg == dh_anon; @@ -1297,7 +1330,7 @@ request_client_cert(#state{static_env = #static_env{cert_db = CertDbHandle, Msg = ssl_handshake:certificate_request(CertDbHandle, CertDbRef, HashSigns, TLSVersion), State = Connection:queue_handshake(Msg, State0), - State#state{client_certificate_requested = true}; + State#state{client_certificate_status = requested}; request_client_cert(#state{ssl_options = #{verify := verify_none}} = State, _) -> diff --git a/lib/ssl/src/tls_gen_connection.erl b/lib/ssl/src/tls_gen_connection.erl index bf83d9f859..1442c69927 100644 --- a/lib/ssl/src/tls_gen_connection.erl +++ b/lib/ssl/src/tls_gen_connection.erl @@ -356,6 +356,8 @@ handle_protocol_record(#ssl_tls{type = ?APPLICATION_DATA}, StateName, } = State) when StateName == initial_hello; StateName == hello; StateName == certify; + StateName == wait_cert_verify, + StateName == wait_ocsp_stapling, StateName == abbreviated; StateName == cipher -> diff --git a/lib/ssl/src/tls_handshake_1_3.erl b/lib/ssl/src/tls_handshake_1_3.erl index bc46fb2fad..87855f2989 100644 --- a/lib/ssl/src/tls_handshake_1_3.erl +++ b/lib/ssl/src/tls_handshake_1_3.erl @@ -1208,7 +1208,7 @@ maybe_append_change_cipher_spec(#state{ maybe_append_change_cipher_spec(State, Bin) -> {State, Bin}. -maybe_queue_cert_cert_cv(#state{client_certificate_requested = false} = State) -> +maybe_queue_cert_cert_cv(#state{client_certificate_status = not_requested} = State) -> {ok, State}; maybe_queue_cert_cert_cv(#state{connection_states = _ConnectionStates0, session = #session{session_id = _SessionId, @@ -1447,7 +1447,7 @@ process_certificate_request(#certificate_request_1_3{ Session = select_client_cert_key_pair(Session0, CertKeyPairs, ServerSignAlgs, ServerSignAlgsCert, ClientSignAlgs, CertDbHandle, CertDbRef, CertAuths), - {ok, {State#state{client_certificate_requested = true, session = Session}, wait_cert}}. + {ok, {State#state{client_certificate_status = requested, session = Session}, wait_cert}}. process_certificate(#certificate_1_3{ certificate_request_context = <<>>, diff --git a/lib/ssl/test/ssl_npn_SUITE.erl b/lib/ssl/test/ssl_npn_SUITE.erl index 6dc889852d..98a1bec9c0 100644 --- a/lib/ssl/test/ssl_npn_SUITE.erl +++ b/lib/ssl/test/ssl_npn_SUITE.erl @@ -68,14 +68,18 @@ all() -> [{group, 'tlsv1.2'}, {group, 'tlsv1.1'}, - {group, 'tlsv1'} + {group, 'tlsv1'}, + {group, 'dtlsv1.2'}, + {group, 'dtlsv1'} ]. groups() -> [ {'tlsv1.2', [], next_protocol_tests()}, {'tlsv1.1', [], next_protocol_tests()}, - {'tlsv1', [], next_protocol_tests()} + {'tlsv1', [], next_protocol_tests()}, + {'dtlsv1.2', [], next_protocol_tests()}, + {'dtlsv1', [], next_protocol_tests()} ]. next_protocol_tests() -> |