RE: Issue 168: Potential interop issue: Constructing a DtlsTransport from an existing IceTransport

Hi, team,

My multiple 2cs.

I agree that we’d better leave the DTLS rekey details to rfc5764.  From pure SRTP point of view, the try-authenticate method without MKI is more like a hack. In theory we will need to try different ROCs when seeing a new key to cover different scenarios. We probably want to leave it as a “MAY” as in the DTLS spec.

For the suggestion “if .stop() was not called on the previous DTLS transport an implicit .stop() should be called rather than throwing an error.”, it doesn’t sound safe. People can easily make mistakes and disrupt an existing session by starting a new DTLS transport accidentally. We may want to be more deterministic and force an explicit Stop() for the previous one (also means the 2nd Start() should raise exception).

Thanks,

-Jiannan

From: Roman Shpount [mailto:rshpount@turbobridge.com]
Sent: Wednesday, January 14, 2015 7:56 AM
To: Bernard Aboba
Cc: Robin Raymond; public-ortc@w3.org
Subject: Re: Issue 168: Potential interop issue: Constructing a DtlsTransport from an existing IceTransport

As far as key change handling is concerned this is simply interpretation of Section 5.2 of RFC RFC 5764 (https://tools.ietf.org/html/rfc5764#section-5.2):

If the authentication check on the packet fails and no MKI is being used, then the receiver MAY process the packet with the older set of keys.  If that authentication check indicates that the packet is valid, the packet should be accepted; otherwise, the packet MUST be discarded and rejected. Receivers MAY use the SRTP packet sequence number to aid in the selection of keys.  After a packet has been received and authenticated with the new key set, any packets with sequence numbers  that are greater will also have been protected with the new key set.

We can reference this or provide my proposed algorithm.

All of this being said, if there is no way to demux two DTLS sessions on the same ICE transport, we should not allow to create two DTLS sessions on the same transport. This applies not only to running two sessions at the same time but also to stopping and re-starting the DTLS session with different parameters since we cannot guarantee that late network packets can be properly handled.
_____________
Roman Shpount

On Tue, Jan 13, 2015 at 11:07 PM, Bernard Aboba <Bernard.Aboba@microsoft.com<mailto:Bernard.Aboba@microsoft.com>> wrote:
Your recommendation with respect to key change should work well.  Do think we should say anything about this in the specification?

AFAIK, there is no easy way to demultiplex multiple DTLS sessions over the same ICE transport.

I vaguely remember something about FF changing the certificate/fingerprint for each WebRTC call (a privacy scenario), but that would typically involve a new IceTransport so also not clear on the use case.

Note that the stalled DtlsTransport case need not involve renegotiation, just connectivity repair via ICE (either ICE re-start or via a new interface).  DLTS association can take a while to tear down after connectivity loss (so as to be robust against route flaps, for example) so if the ICE repair is timely it may have survived.  Of course if there is no DTLS data being sent (either because no data channel or no data being sent on the data channel), without RFC 6520 DTLS Heartbeat, the DTLS connection could survive even after a STUN consent freshness failure (not sure how the application would be made aware of that, BTW).
________________________________________
From: Roman Shpount [rshpount@turbobridge.com<mailto:rshpount@turbobridge.com>]
Sent: Tuesday, January 13, 2015 6:47 PM
To: Bernard Aboba
Cc: Robin Raymond; public-ortc@w3.org<mailto:public-ortc@w3.org>
Subject: Re: Issue 168: Potential interop issue: Constructing a DtlsTransport from an existing IceTransport

There are several mechanisms to deal with multiple SRTP keys being used at the same time. The most robust is simply use the old key, until the first SRTP packet fails to verify, try to verify the SRTP packet using new key and record sequence number for this SSRC as the first sequence for which new key is used. For all subsequent packets use the new SRTP key. For all previous -- repeat the above process. This should work in the absence of MKI (which is not implemented or planned to be implemented anywhere).

The question that I had was about demux of DTLS data. I am not sure there is a way to demux data packets from multiple DTLS sessions that reuse the same transport. I am pretty certain nobody actually implements this, but I might be missing something.

As far as new DtlsTransport is concerned, I understand that you need this to change the certificate, but I am not sure why would you ever do this without change of the underlying transport and what use case requires such a feature.

I think there is value in ability to force DtlsTransport renegotiation without changing any of its parameters. Restarting the transport after it stalled would be one use case. Forcing the rekeying of the existing connection can be another. I am pretty sure that renegotiation can be done much more efficiently then new connection setup. This alone can warrant a "restart" method on existing DtlsTransport instead of creating new DtlsTransport from scratch.
_____________
Roman Shpount

On Tue, Jan 13, 2015 at 2:15 PM, Bernard Aboba <Bernard.Aboba@microsoft.com<mailto:Bernard.Aboba@microsoft.com><mailto:Bernard.Aboba@microsoft.com<mailto:Bernard.Aboba@microsoft.com>>> wrote:
There are a few mechanisms that could be used to address temporary DtlsTransport overlap on the same IceTransport due to latency/reordering. RFC5763 optionally enables addition of the MKI field in SRTP to clarify which key is used. However the RTCWEB security and security-arch docs don't require this (is it implemented?). An alternative is to have an implicit .stop() once a new negotiation starts and when the new keys are derived for them to be installed and for packets failing validation to be discarded.

There appears to be situations where a stalled DtlsTransport can get going again after an ICE restart or an interface state change. No new negotiation, just restoration of connectivity.

Since calling DtlsTransport.start() again is illegal, a new DtlsTransport is needed to change parameters like the fingerprint. If DtlsTransport.stop() was called, it is possible to bring up a new DtlsTransport on the same IceTtansport. The potential scenario might be a desire to change the cert/fingerprint without a new IceTransport or ICE restart.
________________________________
From: Roman Shpount<mailto:rshpount@turbobridge.com<mailto:rshpount@turbobridge.com>>
Sent: ‎1/‎13/‎2015 9:27 AM
To: Robin Raymond<mailto:robin@hookflash.com<mailto:robin@hookflash.com>>
Cc: public-ortc@w3.org<mailto:public-ortc@w3.org><mailto:public-ortc@w3.org<mailto:public-ortc@w3.org>>; Bernard Aboba<mailto:Bernard.Aboba@microsoft.com<mailto:Bernard.Aboba@microsoft.com>>
Subject: Re: Issue 168: Potential interop issue: Constructing a DtlsTransport from an existing IceTransport

Also related:

New DTLS transport can be receiving packets associated with the previous DTLS transport (due to packet re-order, not having old DTLS properly shutdown on the remote side, or other network artifacts). Once again, there is no easy way to demux the packets that belong to the old DTLS session from the packets that belong to the new DTLS session. How is this suppose to work?

More importantly, what is the use case when new DTLS session is started on the same underlying transport? Why would you ever want to create a new DTLS session without setting up a new underlying transport connection? This is something definitely not supported by any of the existing browsers or major DTLS implementations.

The only related use case that I know of is the re-key, but this is a renegotiation on the existing DTLS session, not the new DTLS session.

_____________
Roman Shpount

On Tue, Jan 13, 2015 at 12:13 PM, Robin Raymond <robin@hookflash.com<mailto:robin@hookflash.com><mailto:robin@hookflash.com<mailto:robin@hookflash.com>>> wrote:

Related:

My $0.02 - if .start() is called on a new DTLS transport where there was a previous DTLS transport associated to the same underlying ICE transport, if .stop() was not called on the previous DTLS transport an implicit .stop() should be called rather than throwing an error. There's no way to demux two DTLS transports so let's not pester with needless errors where there's no recovery and we can understand what is the intention anyway…

-Robin


On January 12, 2015 at 8:26:43 PM, Bernard Aboba (bernard.aboba@microsoft.com<mailto:bernard.aboba@microsoft.com><mailto:bernard.aboba@microsoft.com<mailto:bernard.aboba@microsoft.com>>) wrote:

[BA] We can indicate that only one DtlsTransport can run over an IceTransport. So DtlsTransport.stop() MUST be called prior to calling DtlsTransport.start() on an DtlsTransport constructed from the same iceTransport. We can also indicate that an onerror event is fired in the case where two DTLS connections are attempting to be multiplexed over a single ICE connection.

However, this does not cover all corner cases.

Justin said: "Also, if DTLSTransport A is talking to DTLSTransport B, and then A goes away, this should tear down the DTLS association"

[BA] If A calls DtlsTransport.stop(), then the DTLS association will be torn down on both A and B. However, if there is a connectivity failure, there may be a period before B tears down the association. Although there has been previous discussion of DTLS Heartbeat [RFC6520] (see http://www.ietf.org/mail-archive/web/rtcweb/current/msg10224.html), this document is not referenced in any RTCWEB drafts, including draft-ietf-rtcweb-security, draft-ietf-rtcweb-security-arch, data channel drafts, etc. So if there is no data channel in use, B may not detect that DtlsTransport A has "gone away" until STUN consent freshness fails.

At that point, doesn't B need to construct a new ICE transport, rather than just calling iceTransport.start() with a newly constructed iceGatherer?

=================
>From Roman Shpount (see http://lists.w3.org/Archives/Public/public-ortc/2014Dec/0028.html):

All the tools needed to shoot oneself in the foot with the current WebRTC implementation are ready and provided to the ORTI API user.

A developer could construct a new RTCDtlsTransport based on an existing RTCIceTransport and then call RTCDtlsTransport.start(). This would cause a new DTLS negotiation to occur and the DTLS role, fingerprints, etc. could change with a new DTLS/SRTP key being derived.

Existing implementations will only expect a new DTLS session negotiation if transport parameters have changed. They will not handle a new DTLS session over the existing ICE transport connection and they have no way to demultiplex two DTLS sessions over the same ICE connection.

I do not think this needs to be specifically disabled since there are valid use cases when such functionality is needed to interwork with valid DTLS and DTLS-SRTP implementations.

Received on Wednesday, 14 January 2015 20:13:38 UTC