RTCDtlsTransport.start() with multiple RTCDtlsFingerprint #317

Closed
ibc opened this Issue Jan 3, 2016 · 16 comments

Projects

None yet

4 participants

@ibc
Contributor
ibc commented Jan 3, 2016
start (RTCDtlsParameters remoteParameters);
dictionary RTCDtlsParameters {
             RTCDtlsRole                  role = "auto";
             sequence<RTCDtlsFingerprint> fingerprints;
};

Which is the purpose of passing multiple remote RTCDtlsFingerprint to the start() method? what should the UA do with them when it comes to verify the remote certificate? Should the UA check all the fingerprints?

@aboba
Contributor
aboba commented Jan 3, 2016

According to JSEP Section 5.2.1, more than one fingerprint will be present when there is more than one certificate (as opposed to having multiple fingerprints for the same certificate):

o An "a=fingerprint" line for each of the endpoint's certificates,
as specified in [RFC4572], Section 5; the digest algorithm used
for the fingerprint MUST match that used in the certificate
signature.

However, in the same section it also says:

For DTLS, all m= sections MUST use the certificate for the identity
that has been specified for the PeerConnection; as a result, they
MUST all have the same [RFC4572] fingerprint value, or this value
MUST be a session-level attribute.

From this I conclude that we can have multiple fingerprints only if multiple certificates are passed in the DtlsTransport constructor.

@ibc
Contributor
ibc commented Jan 3, 2016

I expected that the purpose multiple RTCDtlsFingerprint was letting the UA to validate a supported hash. This is, the user provides N RTCDtlsFingerprint with different hash (so different value) for the same remote certificate, and the browser can choose one of them (sha-224, sha-256, sha-384, sha-512...) to perform the validation.

From this I conclude that we can have multiple fingerprints only if multiple certificates are passed in the DtlsTransport constructor.

I don't think that a single DTLS peer can provide multiple certificates to the remote DTLS peer, so I don't understand how and why multiple certificates could be passed in the RTCDtlsTransport constructor.

@rshpount
rshpount commented Jan 3, 2016

I think it was expected for end points to support multiple fingerprints in order to allow to match any of the several remote certificates. One use case was using different certificates when RTP and RTCP use different ports (which is no longer supported by WebRTC endpoints). In such case fingerprints for each of the certificates is provided and one of them matches on either RTP or RTCP.

@ibc
Contributor
ibc commented Jan 3, 2016

So, to make things clear, the RTCDtlsFingerprint sequence has never been supposed to indicate different pairs of hash/value for the same fingerprint?

@ibc
Contributor
ibc commented Jan 3, 2016

Guys, I don't understand anything. If someone wants different transports (with also different certificates) for RTP and RTCP he must:

  • create a rtpIceTransport for RTP and another rtcpIceTransport for RTCP (created via rtpIceTransport.createAssociatedTransport(),
  • create a rtpDtlsTransport for RTP (by passing rtpIceTransport to it) and another rtcpDtlsTransport for RTCP (by passing rtcpIceTransport to it).
  • call start() on both RTCDtlsTransport by passing the remote DTLS parameters, which may be different in each case if the remote endpoint uses different certificates for RTP and RTCP.

So, all the rationale above regarding multiple fingerprints for validating different certificates makes no sense IMHO.

@rshpount
rshpount commented Jan 3, 2016

Please keep in mind SDP interop. In case SDP is used to signal different certificates for RTP and RTCP, end point will specify fingerprints for two different certificates in the same m= line. There is no information in SDP which certificate is used for which component. Because of this, the end-point which receives such offer will not know which certificate will be used for RTP vs RTCP and will provide both fingerprints when starting rtp and rtcp transports. In any case, support for fingerprint sequence is required for SDP signaling interop, since SDP can include multiple fingerprints for the same m= line and all of them will need to be passed to RTCDtlsTransport.

Using RTCDtlsFingerprint sequence to specify different hash values for the same fingerprint is a valid scenario as well, especially when you need to interop with different end points which support different fingerprint algorithms. This is especially useful when new, more secure hash algorithm is being introduced in order to provide a clear migration strategy.

@ibc
Contributor
ibc commented Jan 4, 2016

@rshpount 100% clear. I was not aware that there are real WebRTC 1.0 based endpoints that use different DTLS certificates when it comes to separate RTP and RTCP transports.

@ibc
Contributor
ibc commented Jan 4, 2016

NOTE: I think the spec should detail this stuff in more detail.

@rshpount
rshpount commented Jan 4, 2016

@ibc I am not sure if there are any end points that actually use different certificates for RTP and RTCP but I do believe current WebRTC end points support getting multiple fingerprints for the same m= line. Ability to pass the sequence of fingerprints to RTCDtlsTransport is needed to replicate the same behavior.

@ibc
Contributor
ibc commented Jan 4, 2016

Clear. Thanks a lot.

I will send a PR with a more detailed text about this stuff, so will leave this issue open (unless the team decides that such a text is not needed).

@robin-raymond
Contributor

RTCDtlsTransport only uses a single certificate. A non-ORTC remote implementation might offer multiple certs which is why we need to allow a sequence of remote fingerprints so we can validate the remote party. But ORTC DTLS will never use more than one certificate which is why it's not a sequence in the constructor.

@aboba
Contributor
aboba commented Jan 5, 2016

@ibc - If ORTC requires the fingerprint algorithm to correspond to the algorithm used in the certificate (as required in JSEP), then multiple fingerprints/hashes implies multiple certificates. However, currently the DtlsTransport constructor requires only a single certificate to be passed (and the cert argument is mandatory). So my conclusion is RTCDtlsTransport.getLocalParameters() will only have a single fingerprint/algorithm, although the remote peer may provide multiple fingerprints/algorithms.

@rshpount
rshpount commented Jan 5, 2016

@adoba -- Actually fingerprint hash algorithm used for setting up the connection is independent from the hash algorithm used to sign the certificate. For instance you can create a SHA-256 fingerprint for the certificate signed with SHA-1. You can also generate multiple different hashes from the same certificate and provide them as fingerprints during the connection setup. Where did you see that JSEP requires that fingerprint algorithm should match the certificate hash algorithm?

@ibc
Contributor
ibc commented Jan 6, 2016

You can also generate multiple different hashes from the same certificate and provide them as fingerprints during the connection setup

Sure, I've just checked right now that, with the same certificate, you can provide Chrome with any valid fingerprint with hash SHA-1, SHA-224, SHA-256, SHA-385 or SHA-512, and it is accepted by the browser.

@aboba
Contributor
aboba commented Jan 7, 2016

Robin Raymond said:

“RTCDtlsTransport only uses a single certificate. A non-ORTC remote implementation might offer multiple certs which is why we need to allow a sequence of remote fingerprints so we can validate the remote party. But ORTC DTLS will never use more than one certificate which is why it's not a sequence in the constructor.”

[BA] While a RTCDtlsTransport will only select a single certificate in the DTLS handshake, WebRTC 1.0 provides for configuration of multiple self-signed certificates for use with a PeerConnection:

partial dictionary RTCConfiguration {
sequence certificates;
};

WebRTC 1.0 Section 4.2.1.1 says:

Although any given DTLS connection will only use one certificate, this attribute allows the caller to provide multiple certificates that support different algorithms. The final certificate will be selected based on the DTLS handshake, which establishes which certificates are allowed.

In order for ORTC to support the same behavior, it appears to me that the DtlsTransport constructor needs to be provided with a sequence of certificates:

[Constructor(RTCIceTransport transport, sequence certificates)]
Partial interface RTCDtlsTransport : RTCStatsProvider {
readonly attribute RTCCertificate certificate;

Since multiple certificates can be provided in the constructor but only one will be selected, a question arises as to the value of the certificate attribute. If this reflects the certificate selected in the DTLS handshake, it will not be known when the DtlsTransport is constructed, so presumably this will initially be unset. When the certificate is selected, it will be set. This should happen when (or perhaps before) DtlsTransportState transitions to “connected”, so the application can wait for this transition before utilizing the certificate attribute (or calling getRemoteCertificates(), for that matter).

With respect to the behavior of getRemoteCertificates(), an WebRTC 1.0 Issue was filed and resolved:
w3c/webrtc-pc#378

The resolution to this issue (see w3c/webrtc-pc#431), assumes that the sequence of certificates returned by getRemoteCertificates() represents a certificate chain, rather than a sequence of self-signed certificates. If getRemoteCertificates() is called in the “connected” state after the local and remote certificate(s) are selected, this makes some sense. However, if getRemoteCertificates() is called in the “new” or “connecting” state while negotiation is still in progress, the question is whether it should reflect the remote certificates that were offered, whether it should return null or throw an exception.

@aboba aboba added a commit that referenced this issue Jan 8, 2016
@aboba aboba Clarification for multiple fingerprints/certificates
Fix for Issue #317
579bc21
@aboba
Contributor
aboba commented Jan 14, 2016

After multiple PRs... is this issue fixed now? Please reopen it if there is a remaining problem.

@aboba aboba closed this Jan 14, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment