diff -Nru erlang-22.2.7+dfsg/debian/changelog erlang-22.2.7+dfsg/debian/changelog --- erlang-22.2.7+dfsg/debian/changelog 2023-04-26 09:07:20.000000000 +0000 +++ erlang-22.2.7+dfsg/debian/changelog 2023-04-26 09:07:20.000000000 +0000 @@ -1,4 +1,4 @@ -erlang (1:22.2.7+dfsg-1ubuntu0.1) focal-security; urgency=medium +erlang (1:22.2.7+dfsg-1ubuntu0.2) focal-security; urgency=medium * SECURITY UPDATE: SSL, TLS and DTLS client authentication bypass - d/p/CVE-2022-37026-1.patch: fix handling of unexpected diff -Nru erlang-22.2.7+dfsg/debian/patches/CVE-2022-37026-1.patch erlang-22.2.7+dfsg/debian/patches/CVE-2022-37026-1.patch --- erlang-22.2.7+dfsg/debian/patches/CVE-2022-37026-1.patch 2023-04-26 09:07:20.000000000 +0000 +++ erlang-22.2.7+dfsg/debian/patches/CVE-2022-37026-1.patch 2023-04-26 09:07:20.000000000 +0000 @@ -27,7 +27,7 @@ connection/3]). %% gen_statem callbacks -export([callback_mode/0, terminate/3, code_change/4, format_status/2]). -@@ -656,6 +656,24 @@ +@@ -656,6 +656,21 @@ certify(Type, Event, State) -> gen_handshake(?FUNCTION_NAME, Type, Event, State). @@ -44,10 +44,7 @@ +wait_cert_verify(state_timeout, Event, State) -> + handle_state_timeout(Event, ?FUNCTION_NAME, State); +wait_cert_verify(Type, Event, #state{connection_env = #connection_env{negotiated_version = Version}} = State) -> -+ try tls_dtls_connection:gen_handshake(?FUNCTION_NAME, Type, Event, State) -+ catch throw:#alert{} = Alert -> -+ ssl_gen_statem:handle_own_alert(Alert, Version, ?FUNCTION_NAME, State) -+ end. ++ gen_handshake(?FUNCTION_NAME, Type, Event, State). + %%-------------------------------------------------------------------- -spec cipher(gen_statem:event_type(), term(), #state{}) -> @@ -69,7 +66,7 @@ %% General gen_statem state functions with extra callback argument %% to determine if it is an SSL/TLS or DTLS gen_statem machine --export([init/4, error/4, hello/4, user_hello/4, abbreviated/4, certify/4, cipher/4, -+-export([init/4, error/4, hello/4, user_hello/4, abbreviated/4, certify/4, cipher/4, wait_cert_verify/3, ++-export([init/4, error/4, hello/4, user_hello/4, abbreviated/4, certify/4, cipher/4, wait_cert_verify/4, connection/4, downgrade/4]). %% gen_statem callbacks @@ -124,30 +121,24 @@ handshake_env = HsEnv#handshake_env{cert_hashsign_algorithm = NegotiatedHashSign}}) end; %% PSK and RSA_PSK might bypass the Server-Key-Exchange -@@ -1153,13 +1158,6 @@ - #alert{} = Alert -> - handle_own_alert(Alert, Version, ?FUNCTION_NAME, State0) +@@ -1155,7 +1160,7 @@ end; --certify(internal = Type, #client_key_exchange{} = Msg, -- #state{static_env = #static_env{role = server}, + certify(internal = Type, #client_key_exchange{} = Msg, + #state{static_env = #static_env{role = server}, - client_certificate_requested = true, -- ssl_options = #{fail_if_no_peer_cert := true}} = State, -- Connection) -> -- %% We expect a certificate here -- handle_common_event(Type, Msg, ?FUNCTION_NAME, State, Connection); - certify(internal, #client_key_exchange{exchange_keys = Keys}, - State = #state{handshake_env = #handshake_env{kex_algorithm = KeyAlg}, - connection_env = #connection_env{negotiated_version = Version}}, Connection) -> -@@ -1174,36 +1172,54 @@ ++ client_certificate_status = requested, + ssl_options = #{fail_if_no_peer_cert := true}} = State, + Connection) -> + %% We expect a certificate here +@@ -1174,36 +1179,53 @@ handle_common_event(Type, Msg, ?FUNCTION_NAME, State, Connection). %%-------------------------------------------------------------------- --spec cipher(gen_statem:event_type(), - #hello_request{} | #certificate_verify{} | #finished{} | term(), -- #state{}, tls_connection | dtls_connection) -> +-spec wait_cert_verify(gen_statem:event_type(), + #hello_request{} | #certificate_verify{} | term(), -+ #state{}) -> + #state{}, tls_connection | dtls_connection) -> gen_statem:state_function_result(). %%-------------------------------------------------------------------- -cipher({call, From}, Msg, State, Connection) -> @@ -163,18 +154,18 @@ - connection_env = #connection_env{negotiated_version = Version}, - session = #session{master_secret = MasterSecret} - } = State, Connection) -> +- +wait_cert_verify(internal, #certificate_verify{signature = Signature, + hashsign_algorithm = CertHashSign}, -+ #state{static_env = #static_env{role = server, -+ protocol_cb = Connection}, ++ #state{static_env = #static_env{role = server}, + 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) -> - ++ session = #session{master_secret = MasterSecret} = Session0, ++ ssl_options = #{log_level := Level} ++ } = State, Connection) -> TLSVersion = ssl:tls_version(Version), - %% Use negotiated value if TLS-1.2 otherwhise return default + %% Use negotiated value if TLS-1.2 otherwise return default @@ -188,14 +179,13 @@ + State#state{client_certificate_status = verified, + session = Session0#session{sign_alg = HashSign}}); #alert{} = Alert -> -- handle_own_alert(Alert, Version, ?FUNCTION_NAME, State) -+ throw(Alert) + handle_own_alert(Alert, Version, ?FUNCTION_NAME, State) end; + -+wait_cert_verify(internal, #hello_request{}, _) -> ++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). ++wait_cert_verify(Type, Event, State, Connection) -> ++ handle_common_event(Type, Event, ?FUNCTION_NAME, State, Connection). + +%%-------------------------------------------------------------------- +-spec cipher(gen_statem:event_type(), @@ -213,7 +203,7 @@ %% client must send a next protocol message if we are expecting it cipher(internal, #finished{}, #state{static_env = #static_env{role = server}, -@@ -1243,6 +1259,7 @@ +@@ -1243,6 +1265,7 @@ Connection:next_event(?FUNCTION_NAME, no_record, State#state{handshake_env = HsEnv#handshake_env{negotiated_protocol = SelectedProtocol, expecting_next_protocol_negotiation = false}}); @@ -221,18 +211,7 @@ cipher(internal, #change_cipher_spec{type = <<1>>}, #state{handshake_env = HsEnv, connection_states = ConnectionStates0} = State, Connection) -> ConnectionStates = -@@ -1358,10 +1375,6 @@ - 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{connection_env = #connection_env{negotiated_version = Version}} = State, _) -> -- handle_own_alert(?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE), Version, -- StateName, State); - handle_common_event({timeout, handshake}, close, _StateName, #state{start_or_recv_from = StartFrom} = State, _) -> - {stop_and_reply, - {shutdown, user_timeout}, -@@ -1810,12 +1823,12 @@ +@@ -1810,12 +1833,12 @@ certify_client(#state{static_env = #static_env{role = client, cert_db = CertDbHandle, cert_db_ref = CertDbRef}, @@ -247,7 +226,7 @@ State. verify_client_cert(#state{static_env = #static_env{role = client}, -@@ -1823,7 +1836,7 @@ +@@ -1823,7 +1846,7 @@ cert_hashsign_algorithm = HashSign}, connection_env = #connection_env{negotiated_version = Version, private_key = PrivateKey}, @@ -256,7 +235,7 @@ session = #session{master_secret = MasterSecret, own_certificate = OwnCert}} = State, Connection) -> -@@ -1836,7 +1849,7 @@ +@@ -1836,7 +1859,7 @@ #alert{} = Alert -> throw(Alert) end; @@ -265,7 +244,7 @@ State. client_certify_and_key_exchange(#state{connection_env = #connection_env{negotiated_version = Version}} = -@@ -1846,7 +1859,7 @@ +@@ -1846,7 +1869,7 @@ {State2, Actions} = finalize_handshake(State1, certify, Connection), State = State2#state{ %% Reinitialize @@ -274,7 +253,7 @@ Connection:next_event(cipher, no_record, State, Actions) catch throw:#alert{} = Alert -> -@@ -1865,8 +1878,9 @@ +@@ -1865,8 +1888,9 @@ certify_client_key_exchange(#encrypted_premaster_secret{premaster_secret= EncPMS}, #state{connection_env = #connection_env{private_key = Key}, @@ -286,7 +265,7 @@ FakeSecret = make_premaster_secret(Version, rsa), %% Countermeasure for Bleichenbacher attack always provide some kind of premaster secret %% and fail handshake later.RFC 5246 section 7.4.7.1. -@@ -1885,55 +1899,63 @@ +@@ -1885,55 +1909,63 @@ #alert{description = ?DECRYPT_ERROR} -> FakeSecret end, @@ -365,7 +344,7 @@ certify_server(#state{handshake_env = #handshake_env{kex_algorithm = KexAlg}} = State, _) when KexAlg == dh_anon; -@@ -2266,7 +2288,7 @@ +@@ -2266,7 +2298,7 @@ Msg = ssl_handshake:certificate_request(CipherSuite, CertDbHandle, CertDbRef, HashSigns, TLSVersion), State = Connection:queue_handshake(Msg, State0), @@ -418,7 +397,7 @@ connection/3]). %% TLS 1.3 state functions (server) -export([start/3, %% common state with client -@@ -304,7 +304,28 @@ +@@ -304,7 +304,27 @@ {next_state, StateName, State, [{next_event, internal, Alert} | Actions]}. %%% TLS record protocol level application data messages @@ -431,24 +410,23 @@ + StateName == hello; + StateName == certify; + StateName == wait_cert_verify, -+ StateName == wait_ocsp_stapling, + StateName == abbreviated; + StateName == cipher + -> + %% Application data can not be sent before initial handshake pre TLS-1.3. + Alert = ?ALERT_REC(?FATAL, ?UNEXPECTED_MESSAGE, application_data_before_initial_handshake), -+ ssl_gen_statem:handle_own_alert(Alert, Version, StateName, State); ++ ssl_connection:handle_own_alert(Alert, Version, StateName, State); +handle_protocol_record(#ssl_tls{type = ?APPLICATION_DATA}, start = StateName, + #state{static_env = #static_env{role = server}, + connection_env = #connection_env{negotiated_version = Version} + } = State) -> + Alert = ?ALERT_REC(?FATAL, ?DECODE_ERROR, invalid_tls_13_message), -+ ssl_gen_statem:handle_own_alert(Alert, Version, StateName, State); ++ ssl_connection:handle_own_alert(Alert, Version, StateName, State); +handle_protocol_record(#ssl_tls{type = ?APPLICATION_DATA, fragment = Data}, StateName, #state{start_or_recv_from = From, socket_options = #socket_options{active = false}} = State0) when From =/= undefined -> case ssl_connection:read_application_data(Data, State0) of -@@ -478,6 +499,19 @@ +@@ -478,6 +498,16 @@ %% Alert and close handling %%==================================================================== @@ -460,10 +438,7 @@ +wait_cert_verify(info, Event, State) -> + gen_info(Event, ?FUNCTION_NAME, State); +wait_cert_verify(Type, Event, #state{connection_env = #connection_env{negotiated_version = Version}} = State) -> -+ try tls_dtls_connection:gen_handshake(?FUNCTION_NAME, Type, Event, State) -+ catch throw:#alert{} = Alert -> -+ ssl_gen_statem:handle_own_alert(Alert, Version, ?FUNCTION_NAME, State) -+ end. ++ gen_handshake(?FUNCTION_NAME, Type, Event, State). + %%-------------------------------------------------------------------- -spec encode_alert(#alert{}, ssl_record:ssl_version(), ssl_record:connection_states()) -> diff -Nru erlang-22.2.7+dfsg/debian/patches/CVE-2022-37026-2.patch erlang-22.2.7+dfsg/debian/patches/CVE-2022-37026-2.patch --- erlang-22.2.7+dfsg/debian/patches/CVE-2022-37026-2.patch 2023-04-26 09:07:20.000000000 +0000 +++ erlang-22.2.7+dfsg/debian/patches/CVE-2022-37026-2.patch 2023-04-26 09:07:20.000000000 +0000 @@ -10,14 +10,12 @@ --- a/lib/ssl/src/tls_connection.erl +++ b/lib/ssl/src/tls_connection.erl -@@ -311,8 +311,8 @@ +@@ -311,7 +311,7 @@ } = State) when StateName == initial_hello; StateName == hello; StateName == certify; - StateName == wait_cert_verify, -- StateName == wait_ocsp_stapling, + StateName == wait_cert_verify; -+ StateName == wait_ocsp_stapling; StateName == abbreviated; StateName == cipher ->