webrtc
webrtc copied to clipboard
GetConfiguration should return the original configuration provided
Your environment.
- Version: master
What did you do?
While writing tests for the WASM bindings, I came across this line in the existing tests for PeerConnection.GetConfiguration:
assert.NotEqual(t, len(expected.Certificates), len(actual.Certificates))
This line caught my attention because we are asserting that the actual number of certificates is not equal to the expected number of certificates. I dug into the issue a bit more and I think this is a bug, or at least non-standard behavior.
What did you expect?
I admit the WebRTC specification is somewhat unclear about this, but my read on the situation is that this behavior is in violation of the spec. What should happen is that GetConfiguration should return exactly the configuration that was passed in to the PeerConnection constructor (or what was passed in to the SetConfiguration method, where applicable).
Here's the what the spec says about the GetConfiguration method:
When this method is called, the user agent MUST return the RTCConfiguration object stored in the [[Configuration]] internal slot.
Other parts of the spec describe how and when the [[Configuration]] internal slot is updated. It is only updated when a user initially creates the PeerConnection or when they call SetConfiguration, and not when anything happens in the background.
I can confirm this by observing the behavior in browsers and in the wrtc package for Node.js. In both cases, GetConfiguration does not return a certificate unless one was passed in by the user.
What happened?
GetConfiguration returns a certificate even if none was provided. It is part of the spec to create a certificate if none was provided, but that certificate is not supposed to be returned by GetConfiguration.
@albrow The assertion is not a mistake. The reason for it is because the expected object is a direct creation of the Configuration struct without any certificates while the actual := pc.GetConfiguration() is produced from which internally generated a new certificate if one not provided. Therefore the len() is different. This is according to the specification.
https://www.w3.org/TR/webrtc/#dom-rtcconfiguration-certificates
If this value is absent, then a default set of certificates is generated for each RTCPeerConnection instance.
@trivigy you are correct that according to the spec, a default certificate should be generated if one is not provided in the configuration. We're in agreement here and I even mentioned this in my original issue description. However, the spec does not say that the generated certificate should be stored in the "[[Configuration]] internal slot". (To be fair, it doesn't explicitly say that it should not be stored in the [[Configuration]] internal slot either.)
Chrome, Firefox, and the Node.js package I mentioned above all have the same behavior here. They do not return the generated certificate in GetConfiguration. Here's a screenshot from Chrome:

And here is a screenshot from Firefox:

I think it is completely fair to consider the spec somewhat ambiguous in this regard. In the face of this ambiguity, IMO it is better for pions/webrtc to mimic the behavior of browsers. They seem to have already come to a consensus on interpretation of the spec.
The whole reason I'm bringing this up is that I have been working on the WASM bindings for pions/webrtc. The goal is to use a unified API that works in both the browser and vanilla Go environments. We can't do that if the Go implementation differs from the browser implementations.
What do you think?
@trivigy Couldn't that spec line you quoted refer to way the configuration is used, rather than what should be returned by GetConfiguration? The reason @albrow brought this up is because he found it when trying to run the test suite against browser implementations of the spec as part of his WASM efforts. GetConfiguration doesn't return a cert in that case.
@albrow So I think the reason for this ambiguity when it comes to golang is because in browser like environments the actual certificate is generated and stored inside the browser crypt. Like secure appdata of that nature. With that being the case, all of the sctp and srtp configurations then rely on that since it is accessible from within the c++ environment. When it comes to golang we don't have that distinction.
I personally don't feel strong one way or another. Maybe we could create a separate variable that loads the certificate there?! I am just really not sure what would such implication do on the entire system. The way stuff got implemented over time is that I created the Configuration struct to be super compliant with the spec and then once the certificates were properly generated the sctp and srtp rely on it.
To clarify, the browser environment DOES generate the certificate and it does set it properly. It just does not return it in console for security reasons. Which is not the case for pions/webrtc.
In the 5 years since this was filed no user has brought this up as an issue.
The API differences between WASM/Go are unfortunate, but nothing we can do on this one.