-
Notifications
You must be signed in to change notification settings - Fork 16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Verify peer cert fingerprint #22
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -45,25 +45,6 @@ defmodule ExWebRTC.PeerConnection do | |
""" | ||
@type connection_state() :: :closed | :failed | :disconnected | :new | :connecting | :connected | ||
|
||
@enforce_keys [:config, :owner] | ||
defstruct @enforce_keys ++ | ||
[ | ||
:current_local_desc, | ||
:pending_local_desc, | ||
:current_remote_desc, | ||
:pending_remote_desc, | ||
:ice_agent, | ||
:dtls_transport, | ||
demuxer: %Demuxer{}, | ||
transceivers: [], | ||
ice_state: nil, | ||
dtls_state: nil, | ||
signaling_state: :stable, | ||
conn_state: :new, | ||
last_offer: nil, | ||
last_answer: nil | ||
] | ||
|
||
#### API #### | ||
@spec start_link(Configuration.options()) :: GenServer.on_start() | ||
def start_link(options \\ []) do | ||
|
@@ -131,13 +112,24 @@ defmodule ExWebRTC.PeerConnection do | |
{:ok, dtls_transport} = DTLSTransport.start_link(ice_config) | ||
ice_agent = DTLSTransport.get_ice_agent(dtls_transport) | ||
|
||
state = %__MODULE__{ | ||
state = %{ | ||
owner: owner, | ||
config: config, | ||
current_local_desc: nil, | ||
pending_local_desc: nil, | ||
current_remote_desc: nil, | ||
pending_remote_desc: nil, | ||
ice_agent: ice_agent, | ||
dtls_transport: dtls_transport, | ||
demuxer: %Demuxer{}, | ||
transceivers: [], | ||
ice_state: :new, | ||
dtls_state: :new | ||
dtls_state: :new, | ||
signaling_state: :stable, | ||
conn_state: :new, | ||
last_offer: nil, | ||
last_answer: nil, | ||
peer_fingerprint: nil | ||
} | ||
|
||
notify(state.owner, {:connection_state_change, :new}) | ||
|
@@ -280,7 +272,7 @@ defmodule ExWebRTC.PeerConnection do | |
{:ok, state} <- apply_local_description(other_type, sdp, state) do | ||
{:reply, :ok, %{state | signaling_state: next_state}} | ||
else | ||
error -> {:reply, error, state} | ||
{:error, _reason} = error -> {:reply, error, state} | ||
end | ||
end | ||
end | ||
|
@@ -299,7 +291,7 @@ defmodule ExWebRTC.PeerConnection do | |
{:ok, state} <- apply_remote_description(other_type, sdp, state) do | ||
{:reply, :ok, %{state | signaling_state: next_state}} | ||
else | ||
error -> {:reply, error, state} | ||
{:error, _reason} = error -> {:reply, error, state} | ||
end | ||
end | ||
end | ||
|
@@ -348,10 +340,16 @@ defmodule ExWebRTC.PeerConnection do | |
|
||
@impl true | ||
def handle_info({:ex_ice, _from, {:connection_state_change, new_ice_state}}, state) do | ||
state = %__MODULE__{state | ice_state: new_ice_state} | ||
state = %{state | ice_state: new_ice_state} | ||
next_conn_state = next_conn_state(new_ice_state, state.dtls_state) | ||
state = update_conn_state(state, next_conn_state) | ||
{:noreply, state} | ||
|
||
if next_conn_state == :failed do | ||
Logger.debug("Stopping PeerConnection") | ||
{:stop, {:shutdown, :conn_state_failed}, state} | ||
else | ||
{:noreply, state} | ||
end | ||
end | ||
|
||
@impl true | ||
|
@@ -370,7 +368,7 @@ defmodule ExWebRTC.PeerConnection do | |
|
||
@impl true | ||
def handle_info({:dtls_transport, _pid, {:state_change, new_dtls_state}}, state) do | ||
state = %__MODULE__{state | dtls_state: new_dtls_state} | ||
state = %{state | dtls_state: new_dtls_state} | ||
next_conn_state = next_conn_state(state.ice_state, new_dtls_state) | ||
state = update_conn_state(state, next_conn_state) | ||
{:noreply, state} | ||
|
@@ -381,7 +379,7 @@ defmodule ExWebRTC.PeerConnection do | |
case Demuxer.demux(state.demuxer, data) do | ||
{:ok, demuxer, mid, packet} -> | ||
notify(state.owner, {:data, {mid, packet}}) | ||
{:noreply, %__MODULE__{state | demuxer: demuxer}} | ||
{:noreply, %{state | demuxer: demuxer}} | ||
|
||
{:error, reason} -> | ||
Logger.error("Unable to demux RTP, reason: #{inspect(reason)}") | ||
|
@@ -408,7 +406,7 @@ defmodule ExWebRTC.PeerConnection do | |
dtls = | ||
if type == :answer do | ||
{:setup, setup} = ExSDP.Media.get_attribute(hd(sdp.media), :setup) | ||
:ok = DTLSTransport.start_dtls(state.dtls_transport, setup) | ||
:ok = DTLSTransport.start_dtls(state.dtls_transport, setup, state.peer_fingerprint) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Isn't it an issue that the fingerprint here might be There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should never happen as we can't set SDP answer before receiving SDP offer. When we receive SDP offer we save peer_fingerprint in the state There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. right |
||
else | ||
state.dtls_transport | ||
end | ||
|
@@ -430,6 +428,7 @@ defmodule ExWebRTC.PeerConnection do | |
with :ok <- SDPUtils.ensure_mid(sdp), | ||
:ok <- SDPUtils.ensure_bundle(sdp), | ||
{:ok, {ice_ufrag, ice_pwd}} <- SDPUtils.get_ice_credentials(sdp), | ||
{:ok, {:fingerprint, {:sha256, peer_fingerprint}}} <- SDPUtils.get_cert_fingerprint(sdp), | ||
{:ok, new_transceivers} <- | ||
update_remote_transceivers(state.transceivers, sdp, state.config) do | ||
:ok = ICEAgent.set_remote_credentials(state.ice_agent, ice_ufrag, ice_pwd) | ||
|
@@ -460,12 +459,24 @@ defmodule ExWebRTC.PeerConnection do | |
:passive -> :active | ||
end | ||
|
||
:ok = DTLSTransport.start_dtls(state.dtls_transport, setup) | ||
:ok = DTLSTransport.start_dtls(state.dtls_transport, setup, peer_fingerprint) | ||
else | ||
state.dtls_transport | ||
end | ||
|
||
{:ok, %{state | transceivers: new_transceivers, dtls_transport: dtls}} | ||
{:ok, | ||
%{ | ||
state | ||
| transceivers: new_transceivers, | ||
dtls_transport: dtls, | ||
peer_fingerprint: peer_fingerprint | ||
}} | ||
else | ||
{:ok, {:fingerprint, {_hash_function, _fingerprint}}} -> | ||
{:error, :unsupported_cert_fingerprint_hash_function} | ||
|
||
{:error, _reason} = error -> | ||
error | ||
end | ||
end | ||
|
||
|
@@ -569,6 +580,7 @@ defmodule ExWebRTC.PeerConnection do | |
defp update_conn_state(%{conn_state: conn_state} = state, conn_state), do: state | ||
|
||
defp update_conn_state(state, new_conn_state) do | ||
Logger.debug("Changing PeerConnection state: #{state.conn_state} -> #{new_conn_state}") | ||
notify(state.owner, {:connection_state_change, new_conn_state}) | ||
%{state | conn_state: new_conn_state} | ||
end | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is probably a rare error, isn't it? Maybe
Logger.debug
is too lax for the severity? State change to:failed
doesn't really tell much about the reason, so it's gonna be easy to miss.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think so. PeerConnection state failed means that either ICE failed or DTLS failed. Because user has access to ICE state it can easily know that the problem is failing DTLS.
I would say that all our logs should be on debug as we create a library. It's API role to give user sufficient information on what's going on