Closed Bug 1525241 Opened 7 years ago Closed 11 months ago

getFingerprints() method is missing from the Certificate returned by RTCPeerconnection.generateCertificate()

Categories

(Core :: WebRTC, defect, P3)

65 Branch
defect

Tracking

()

RESOLVED FIXED
138 Branch
Tracking Status
firefox138 --- fixed

People

(Reporter: thp, Assigned: mjf)

References

(Blocks 3 open bugs)

Details

(Keywords: dev-doc-complete, webcompat:platform-bug)

User Story

platform-scheduled:2025-04-01

Attachments

(1 file)

User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36

Steps to reproduce:

Browse to https://pi.pe/p/genCertTest.html
This page generates a new certificate for use with WebRTC testing support for various methods and exercising the available ones.

See https://www.w3.org/TR/webrtc/#dom-rtccertificate-getfingerprints for specification

Actual results:

The generated certificate has no getFingerprints() method - so we see a red line on the page.

Expected results:

All the tests should pass (green everywhere) - chrome passes this test, as does safari-preview.

Component: Untriaged → WebRTC
Product: Firefox → Core
Status: UNCONFIRMED → NEW
Ever confirmed: true
Priority: -- → P3
Blocks: 1533015
Severity: normal → S3

We have multiple work arounds for this. But LOE is pretty low as well so if we had to dedicate some time to it we could.

No longer blocks: webrtc-triage

We implement spec gaps based on external partner needs. This has not been flagged by anyone and as such is low priority / backlog.

User Story: (updated)
User Story: (updated)
Assignee: nobody → mfroman
User Story: (updated)
Pushed by mfroman@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/e788fc9baa88 implement RTCCertificate.getFingerprints method. r=bwc,webidl,smaug
Status: NEW → RESOLVED
Closed: 11 months ago
Resolution: --- → FIXED
Target Milestone: --- → 138 Branch
User Story: (updated)
Keywords: dev-doc-needed

FF138 docs for this can be tracked in https://github.com/mdn/content/issues/38882.

Can I please get a sanity check on the release note and documentation changes in https://github.com/mdn/content/pull/39010/ ?
Specifically, I understand that this allows you to get the fingerprints from a certificate.

As per this comment I think that the flow is that

  • you create an RTCPeerConnection
    • you can generate your own certificates or if you don't some will get created for you and you can query those using RTCPeerConnection.getConfiguration()
  • The fingerprints for these certificates need to be exchanged out of band with the remote peer during the signaling phase.
  • During the DTLS negotiation the identity of the remote peer is verified based on its fingerprints matching the values shared out of band.

IF that is about right, I'm confused:

  • We have to get the fingerprints to share out of band - how were we able to get them to share previously if getFingerprints() wasn't implemented?
  • DTLS negotiation somehow compares the remote server certificate fingerprints to what the current end expects. Assuming we got the fingerprints from that remote server out of band, how did we "give" them to DTLS so that it could use them?

Sorry if this is a dumb question!

Flags: needinfo?(mfroman)

We use this feature to support a Trust on First Use (tofu) model, where a peer can use an out of band proof (usually proximity based) to validate a fingerprint and then subsequently they can check the fingerprint and know it is the same user.

This depends on 4 API points:

  1. the static createCertificate (used in the first use case)
  2. the ability to store and recover an (opaque) certificate from indexedDB
  3. the ability to add a certificate to a peer connection config
    (Whilst as someone pointed out you can extract a fingerprint from SDP it is ugly and error prone)
  4. access the fingerprint using getFingerprint().

We test all of these in the bugreport page
https://pi.pe/p/genCertTest.html

Which astonishingly still works 6 years later.

To answer your specific questions:
"how were we able to get them to share previously if getFingerprints() wasn't implemented?"
You could have extracted them from the SDP or from getStats() - but this requires that you apply the certificate and/or use it - then subsequently reject the connection.

"how did we "give" them to DTLS so that it could use them?"
Again you could replace the fingerprint in the SDP with the one you are expecting - if they aren't the same DTLS handshake will fail.

Your questions are good. A better API would avoid the need to mess with the SDP.

We got to where we are now because this was a part of a larger IDP identity verification project that didn't get traction, so we are left with the husks that remain - ask Martin Thompson about that!

Our solution is a bit more complex than I've described it, because we have endpoints that aren't browsers. This API-set allows a user to 'claim' a baby monitor once, and subsequently use it securely without needing a centralised server based trust store.

Thanks Tim! My knowledge of WebRTC etc is a bit like a house of cards - it's built on the MDN docs which are a good start but not exhaustive.
In particular it is not aways clear what bits are handled by the browser and what bits have to be done by the developer - which is really what I was after.

Your response was helpful, because it showed my understand of the flow was incomplete. My understanding now is that a developer can inspect fingerprints but generally they shouldn't need to - the browser handles everything under the hood related to getting and comparing fingerprints, as these are taken from the configuration for the peerconnection "under the hood" when you create an offer and extracted by the browser at the other end.

As I understand it now:

  • RTCPeerConnection can be constructed with configuration that has certificate (created by static method) or will create certificate for you. Either way you can get the certificate from RTCPeerConnection.getConfiguration() and you can get its finger prints (now) from the new method on the certificate.
  • When you create an offer using the RTCPeerConnection SDP messages are sent to the remote end includes the fingerprint(s) for the certificates in the config. The developer doesn't have to do anything.
  • When an offer is received/accepted at the other end, the remote browser extracts the fingerprint.
  • When the DTLS handshake takes place
    • both browsers have the fingerprint from the other end.
    • They offer each other their own certificate, which is hashed and compared to the fingerprint they have.
    • If the fingerprints match, then the WebRTC connection knows that the identity of the remote party matches the certificate/endpoint send in the SDP.

I am not sure how this relates to the "We use this feature to support a Trust on First Use (tofu) model, where a peer can use an out of band proof (usually proximity based) to validate a fingerprint and then subsequently they can check the fingerprint and know it is the same user."

Hope that means I am starting to "get" this and not that I am hopelessly lost.

Byron, can you add anything to the use case for when getFingerprints() would be useful?

Flags: needinfo?(mfroman) → needinfo?(docfaraday)

I guess it could be useful for non-browser endpoints; in many cases, the browser is establishing an RTCPeerConnection to send/recv media with a middlebox (eg; conferencing server). Sometimes, those will want to know the fingerprint before doing any offer/answer (this has come up with specific implementers before).

Flags: needinfo?(docfaraday)

Hamish, yep, your understanding is right - but I'll add a couple of things.

RTCCertificates can be stored in Indexed DB - which adds a 3rd option to the 2 you mentioned - a previously stored certificate can be retrieved from indexed DB and put into a new peer connection configuration. So if you have established a trust relationship between 2 web-browsers you can persist it by storing the certs in Indexed DB and re-using them in a later session (up to a year later)

The certificate checking is done as part of the DTLS handshake rather than at a higher level. Since the DTLS handshake also generates all the keys used in webRTC encryption, if the handshake fails, no webRTC media or data will be exchanged - making this a very low-level 'cutout' for impersonations.

Thanks very much. I think the docs are good to go then.

You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: