aboutsummaryrefslogtreecommitdiffstats
path: root/lib/ssl/src/dtls_connection.erl
diff options
context:
space:
mode:
authorIngela Anderton Andin <[email protected]>2017-05-10 23:36:44 +0200
committerIngela Anderton Andin <[email protected]>2017-05-16 09:53:21 +0200
commit4fd3360bb68adb2ee942b3fbaeab7d766b6d3454 (patch)
treeb3e6f2fb5f1757e16591f5c5cefc6ac05e98fb65 /lib/ssl/src/dtls_connection.erl
parentc23d7ad97889589dd5ac890626af65840ea60c99 (diff)
downloadotp-4fd3360bb68adb2ee942b3fbaeab7d766b6d3454.tar.gz
otp-4fd3360bb68adb2ee942b3fbaeab7d766b6d3454.tar.bz2
otp-4fd3360bb68adb2ee942b3fbaeab7d766b6d3454.zip
dtls: Implement replay protection
See RFC 6347 section 3.3
Diffstat (limited to 'lib/ssl/src/dtls_connection.erl')
-rw-r--r--lib/ssl/src/dtls_connection.erl32
1 files changed, 23 insertions, 9 deletions
diff --git a/lib/ssl/src/dtls_connection.erl b/lib/ssl/src/dtls_connection.erl
index 9937373e6e..b52896a458 100644
--- a/lib/ssl/src/dtls_connection.erl
+++ b/lib/ssl/src/dtls_connection.erl
@@ -688,16 +688,19 @@ next_record(#state{unprocessed_handshake_events = N} = State) when N > 0 ->
{no_record, State#state{unprocessed_handshake_events = N-1}};
next_record(#state{protocol_buffers =
- #protocol_buffers{dtls_cipher_texts = [CT | Rest]}
+ #protocol_buffers{dtls_cipher_texts = [#ssl_tls{epoch = Epoch} = CT | Rest]}
= Buffers,
- connection_states = ConnStates0} = State) ->
- case dtls_record:decode_cipher_text(CT, ConnStates0) of
- {Plain, ConnStates} ->
- {Plain, State#state{protocol_buffers =
- Buffers#protocol_buffers{dtls_cipher_texts = Rest},
- connection_states = ConnStates}};
- #alert{} = Alert ->
- {Alert, State}
+ connection_states = ConnectionStates} = State) ->
+ CurrentRead = dtls_record:get_connection_state_by_epoch(Epoch, ConnectionStates, read),
+ case dtls_record:replay_detect(CT, CurrentRead) of
+ false ->
+ decode_cipher_text(State#state{connection_states = ConnectionStates}) ;
+ true ->
+ ct:pal("Replay detect", []),
+ %% Ignore replayed record
+ next_record(State#state{protocol_buffers =
+ Buffers#protocol_buffers{dtls_cipher_texts = Rest},
+ connection_states = ConnectionStates})
end;
next_record(#state{role = server,
socket = {Listener, {Client, _}},
@@ -770,6 +773,17 @@ next_event(StateName, Record,
{next_state, StateName, State, [{next_event, internal, Alert} | Actions]}
end.
+decode_cipher_text(#state{protocol_buffers = #protocol_buffers{dtls_cipher_texts = [ CT | Rest]} = Buffers,
+ connection_states = ConnStates0} = State) ->
+ case dtls_record:decode_cipher_text(CT, ConnStates0) of
+ {Plain, ConnStates} ->
+ {Plain, State#state{protocol_buffers =
+ Buffers#protocol_buffers{dtls_cipher_texts = Rest},
+ connection_states = ConnStates}};
+ #alert{} = Alert ->
+ {Alert, State}
+ end.
+
dtls_version(hello, Version, #state{role = server} = State) ->
State#state{negotiated_version = Version}; %%Inital version
dtls_version(_,_, State) ->