aboutsummaryrefslogtreecommitdiffstats
path: root/lib/ssl/src/ssl_connection.erl
diff options
context:
space:
mode:
authorIngela Anderton Andin <[email protected]>2010-11-12 17:28:11 +0100
committerIngela Anderton Andin <[email protected]>2010-11-18 10:17:53 +0100
commit121047232026505d0e23de1cc15137d986a4b4b4 (patch)
tree198e0a4230931eec73eee150d59e7a3fa52d2a4d /lib/ssl/src/ssl_connection.erl
parent49f6d49d77adb123800f5ff7b7726a8aecb3a87c (diff)
downloadotp-121047232026505d0e23de1cc15137d986a4b4b4.tar.gz
otp-121047232026505d0e23de1cc15137d986a4b4b4.tar.bz2
otp-121047232026505d0e23de1cc15137d986a4b4b4.zip
Added alert in stream cipher case.
Also changed alert to BAD_RECORD_MAC as: "differentiating between bad_record_mac and decryption_failed alerts may permit certain attacks against CBC mode as used in TLS [CBCATT]. It is preferable to uniformly use the bad_record_mac alert to hide the specific type of the error." Also cleaned up the code and changed a few other alert reasons in according to alert descriptions in the TLS RFC 4346. And added function terminate_alert/3 so that we can differentiate between a crash in ssl (a bug in our code) and a crash in the application using ssl.
Diffstat (limited to 'lib/ssl/src/ssl_connection.erl')
-rw-r--r--lib/ssl/src/ssl_connection.erl20
1 files changed, 12 insertions, 8 deletions
diff --git a/lib/ssl/src/ssl_connection.erl b/lib/ssl/src/ssl_connection.erl
index 3a9cada81e..ce90d22c09 100644
--- a/lib/ssl/src/ssl_connection.erl
+++ b/lib/ssl/src/ssl_connection.erl
@@ -967,15 +967,14 @@ handle_info(Msg, StateName, State) ->
%% necessary cleaning up. When it returns, the gen_fsm terminates with
%% Reason. The return value is ignored.
%%--------------------------------------------------------------------
-terminate(_Reason, connection, #state{negotiated_version = Version,
+terminate(Reason, connection, #state{negotiated_version = Version,
connection_states = ConnectionStates,
transport_cb = Transport,
socket = Socket, send_queue = SendQueue,
renegotiation = Renegotiate}) ->
notify_senders(SendQueue),
notify_renegotiater(Renegotiate),
- {BinAlert, _} = encode_alert(?ALERT_REC(?WARNING,?CLOSE_NOTIFY),
- Version, ConnectionStates),
+ BinAlert = terminate_alert(Reason, Version, ConnectionStates),
Transport:send(Socket, BinAlert),
workaround_transport_delivery_problems(Socket, Transport),
Transport:close(Socket);
@@ -1519,7 +1518,7 @@ handle_server_key(
true ->
dh_master_secret(P, G, ServerPublicDhKey, undefined, State);
false ->
- ?ALERT_REC(?FATAL,?HANDSHAKE_FAILURE)
+ ?ALERT_REC(?FATAL, ?DECRYPT_ERROR)
end.
verify_dh_params(Signed, Hashes, {?rsaEncryption, PubKey, _PubKeyParams}) ->
@@ -1574,15 +1573,12 @@ cipher_role(server, Data, Session, #state{connection_states = ConnectionStates0
tls_handshake_hashes =
Hashes})).
encode_alert(#alert{} = Alert, Version, ConnectionStates) ->
- ?DBG_TERM(Alert),
ssl_record:encode_alert_record(Alert, Version, ConnectionStates).
encode_change_cipher(#change_cipher_spec{}, Version, ConnectionStates) ->
- ?DBG_TERM(#change_cipher_spec{}),
ssl_record:encode_change_cipher_spec(Version, ConnectionStates).
encode_handshake(HandshakeRec, Version, ConnectionStates0, Hashes0) ->
- ?DBG_TERM(HandshakeRec),
Frag = ssl_handshake:encode_handshake(HandshakeRec, Version),
Hashes1 = ssl_handshake:update_hashes(Hashes0, Frag),
{E, ConnectionStates1} =
@@ -1840,7 +1836,6 @@ next_state(StateName, #ssl_tls{type = ?APPLICATION_DATA, fragment = Data}, State
next_state(StateName, #ssl_tls{type = ?CHANGE_CIPHER_SPEC, fragment = <<1>>} =
_ChangeCipher,
#state{connection_states = ConnectionStates0} = State0) ->
- ?DBG_TERM(_ChangeCipher),
ConnectionStates1 =
ssl_record:activate_pending_connection_state(ConnectionStates0, read),
{Record, State} = next_record(State0#state{connection_states = ConnectionStates1}),
@@ -2191,6 +2186,15 @@ notify_renegotiater({true, From}) when not is_atom(From) ->
notify_renegotiater(_) ->
ok.
+terminate_alert(Reason, Version, ConnectionStates) when Reason == normal; Reason == shutdown ->
+ {BinAlert, _} = encode_alert(?ALERT_REC(?WARNING, ?CLOSE_NOTIFY),
+ Version, ConnectionStates),
+ BinAlert;
+terminate_alert(_, Version, ConnectionStates) ->
+ {BinAlert, _} = encode_alert(?ALERT_REC(?FATAL, ?INTERNAL_ERROR),
+ Version, ConnectionStates),
+ BinAlert.
+
workaround_transport_delivery_problems(Socket, Transport) ->
%% Standard trick to try to make sure all
%% data sent to to tcp port is really sent