| Index: third_party/WebKit/Source/modules/mediastream/RTCPeerConnection.cpp
|
| diff --git a/third_party/WebKit/Source/modules/mediastream/RTCPeerConnection.cpp b/third_party/WebKit/Source/modules/mediastream/RTCPeerConnection.cpp
|
| index b9f5ee76b80a519c58851c9fbcd767251cddc7f5..c8f45a414826fb0677a74e360d3abaa9416f22e8 100644
|
| --- a/third_party/WebKit/Source/modules/mediastream/RTCPeerConnection.cpp
|
| +++ b/third_party/WebKit/Source/modules/mediastream/RTCPeerConnection.cpp
|
| @@ -34,6 +34,9 @@
|
| #include "bindings/core/v8/ArrayValue.h"
|
| #include "bindings/core/v8/ExceptionMessages.h"
|
| #include "bindings/core/v8/ExceptionState.h"
|
| +#include "bindings/core/v8/Nullable.h"
|
| +#include "bindings/core/v8/ScriptPromiseResolver.h"
|
| +#include "bindings/modules/v8/V8RTCCertificate.h"
|
| #include "core/dom/Document.h"
|
| #include "core/dom/ExceptionCode.h"
|
| #include "core/dom/ExecutionContext.h"
|
| @@ -58,10 +61,13 @@
|
| #include "platform/mediastream/RTCOfferOptions.h"
|
| #include "public/platform/Platform.h"
|
| #include "public/platform/WebMediaStream.h"
|
| +#include "public/platform/WebRTCCertificate.h"
|
| +#include "public/platform/WebRTCCertificateGenerator.h"
|
| #include "public/platform/WebRTCConfiguration.h"
|
| #include "public/platform/WebRTCDataChannelHandler.h"
|
| #include "public/platform/WebRTCDataChannelInit.h"
|
| #include "public/platform/WebRTCICECandidate.h"
|
| +#include "public/platform/WebRTCKeyType.h"
|
| #include "public/platform/WebRTCOfferOptions.h"
|
| #include "public/platform/WebRTCSessionDescription.h"
|
| #include "public/platform/WebRTCSessionDescriptionRequest.h"
|
| @@ -82,6 +88,44 @@ static bool throwExceptionIfSignalingStateClosed(RTCPeerConnection::SignalingSta
|
| return false;
|
| }
|
|
|
| +// Helper class for RTCPeerConnection::generateCertificate.
|
| +class WebRTCCertificateObserver : public WebCallbacks<WebRTCCertificate*, void> {
|
| +public:
|
| + // The created observer is responsible for deleting itself after onSuccess/onError. To avoid memory
|
| + // leak the observer should therefore be used in a WebRTCCertificateGenerator::generateCertificate call.
|
| + // which is ensured to invoke one of these. Takes ownership of |resolver|.
|
| + static WebRTCCertificateObserver* Create(ScriptPromiseResolver* resolver)
|
| + {
|
| + return new WebRTCCertificateObserver(resolver);
|
| + }
|
| +
|
| + DEFINE_INLINE_TRACE() { visitor->trace(m_resolver); }
|
| +
|
| +private:
|
| + WebRTCCertificateObserver(ScriptPromiseResolver* resolver)
|
| + : m_resolver(resolver)
|
| + {
|
| + }
|
| +
|
| + ~WebRTCCertificateObserver() override
|
| + {
|
| + }
|
| +
|
| + void onSuccess(WebRTCCertificate* certificate) override
|
| + {
|
| + m_resolver->resolve(new RTCCertificate(certificate));
|
| + delete this;
|
| + }
|
| +
|
| + void onError() override
|
| + {
|
| + m_resolver->reject();
|
| + delete this;
|
| + }
|
| +
|
| + Persistent<ScriptPromiseResolver> m_resolver;
|
| +};
|
| +
|
| } // namespace
|
|
|
| RTCConfiguration* RTCPeerConnection::parseConfiguration(const Dictionary& configuration, ExceptionState& exceptionState)
|
| @@ -207,6 +251,29 @@ RTCConfiguration* RTCPeerConnection::parseConfiguration(const Dictionary& config
|
| }
|
| }
|
|
|
| + ArrayValue certificates;
|
| + if (DictionaryHelper::get(configuration, "certificates", certificates)
|
| + && !certificates.isUndefinedOrNull()) {
|
| + size_t numberOfCertificates;
|
| + certificates.length(numberOfCertificates);
|
| + for (size_t i = 0; i < numberOfCertificates; ++i) {
|
| + RTCCertificate* certificate = nullptr;
|
| +
|
| + Dictionary dictCert;
|
| + certificates.get(i, dictCert);
|
| + v8::Local<v8::Value> valCert = dictCert.v8Value();
|
| + if (!valCert.IsEmpty()) {
|
| + certificate = V8RTCCertificate::toImplWithTypeCheck(configuration.isolate(), valCert);
|
| + }
|
| + if (!certificate) {
|
| + exceptionState.throwTypeError("Malformed sequence<RTCCertificate>");
|
| + return 0;
|
| + }
|
| +
|
| + rtcConfiguration->appendCertificate(certificate->certificateShallowCopy());
|
| + }
|
| + }
|
| +
|
| return rtcConfiguration;
|
| }
|
|
|
| @@ -411,6 +478,60 @@ void RTCPeerConnection::updateIce(const Dictionary& rtcConfiguration, const Dict
|
| exceptionState.throwDOMException(SyntaxError, "Could not update the ICE Agent with the given configuration.");
|
| }
|
|
|
| +ScriptPromise RTCPeerConnection::generateCertificate(ScriptState* scriptState, const Dictionary& keygenAlgorithm, ExceptionState& exceptionState)
|
| +{
|
| + // Validate and interpret input |keygenAlgorithm|.
|
| + // The value |keyType| corresponds to the rtc::KeyType in libjingle.
|
| + Nullable<WebRTCKeyType> keyType;
|
| + String name;
|
| + if (DictionaryHelper::get(keygenAlgorithm, "name", name)) {
|
| + if (name == "RSASSA-PKCS1-v1_5") {
|
| + // RSA - Supported |keygenAlgorithm|:
|
| + // { name: "RSASSA-PKCS1-v1_5", modulusLength: <int>, publicExponent: 65537 }
|
| + // Where 1024 <= modulusLength <= 8192. This is a somewhat arbitrary
|
| + // restriction. The idea is that less than 1024 is unsafe and
|
| + // greater than 8192 is unreasonably large and slow.
|
| + int modulusLength = -1;
|
| + DictionaryHelper::get(keygenAlgorithm, "modulusLength", modulusLength);
|
| + int publicExponent = -1;
|
| + DictionaryHelper::get(keygenAlgorithm, "publicExponent", publicExponent);
|
| + if (modulusLength >= 1024 && modulusLength <= 8192 && publicExponent == 65537) {
|
| + keyType.set(blink::WebRTCKeyType::createRSA(modulusLength));
|
| + }
|
| + } else if (name == "ECDSA") {
|
| + // ECDSA - Supported |keygenAlgorithm|:
|
| + // { name: "ECDSA", namedCurve: "P-256" }
|
| + String namedCurve;
|
| + DictionaryHelper::get(keygenAlgorithm, "namedCurve", namedCurve);
|
| + if (namedCurve == "P-256") {
|
| + keyType.set(blink::WebRTCKeyType::createECDSA());
|
| + }
|
| + }
|
| + }
|
| + if (keyType.isNull()) {
|
| + // Invalid argument.
|
| + return ScriptPromise::rejectWithDOMException(
|
| + scriptState, DOMException::create(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "AlgorithmIdentifier")));
|
| + }
|
| +
|
| + ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
|
| + ScriptPromise promise = resolver->promise();
|
| +
|
| + WebRTCCertificateObserver* certificateObserver = WebRTCCertificateObserver::Create(resolver);
|
| +
|
| + // Generate certificate. The |certificateObserver| will resolve the promise asynchronously upon generate completion.
|
| + // The observer will manage its own and the resolver's destruction as well.
|
| + OwnPtr<WebRTCCertificateGenerator> certificateGenerator = adoptPtr(
|
| + Platform::current()->createRTCCertificateGenerator());
|
| + certificateGenerator->generateCertificate(
|
| + keyType.get(),
|
| + toDocument(scriptState->executionContext())->url(),
|
| + toDocument(scriptState->executionContext())->firstPartyForCookies(),
|
| + certificateObserver);
|
| +
|
| + return promise;
|
| +}
|
| +
|
| void RTCPeerConnection::addIceCandidate(RTCIceCandidate* iceCandidate, ExceptionState& exceptionState)
|
| {
|
| if (throwExceptionIfSignalingStateClosed(m_signalingState, exceptionState))
|
|
|