Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2015 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/renderer/media/rtc_certificate_generator.h" | 5 #include "content/renderer/media/rtc_certificate_generator.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/macros.h" | 10 #include "base/macros.h" |
| 11 #include "base/memory/ptr_util.h" | 11 #include "base/memory/ptr_util.h" |
| 12 #include "base/synchronization/lock.h" | |
| 13 #include "base/synchronization/waitable_event.h" | |
| 12 #include "content/renderer/media/peer_connection_identity_store.h" | 14 #include "content/renderer/media/peer_connection_identity_store.h" |
| 13 #include "content/renderer/media/rtc_certificate.h" | 15 #include "content/renderer/media/rtc_certificate.h" |
| 14 #include "content/renderer/media/webrtc/peer_connection_dependency_factory.h" | 16 #include "content/renderer/media/webrtc/peer_connection_dependency_factory.h" |
| 15 #include "content/renderer/render_thread_impl.h" | 17 #include "content/renderer/render_thread_impl.h" |
| 16 #include "third_party/webrtc/base/rtccertificate.h" | |
| 17 #include "third_party/webrtc/base/scoped_ref_ptr.h" | |
| 18 #include "url/gurl.h" | 18 #include "url/gurl.h" |
| 19 | 19 |
| 20 namespace content { | 20 namespace content { |
| 21 namespace { | 21 namespace { |
| 22 | 22 |
| 23 rtc::KeyParams WebRTCKeyParamsToKeyParams( | 23 rtc::KeyParams WebRTCKeyParamsToKeyParams( |
| 24 const blink::WebRTCKeyParams& key_params) { | 24 const blink::WebRTCKeyParams& key_params) { |
| 25 switch (key_params.keyType()) { | 25 switch (key_params.keyType()) { |
| 26 case blink::WebRTCKeyTypeRSA: | 26 case blink::WebRTCKeyTypeRSA: |
| 27 return rtc::KeyParams::RSA(key_params.rsaParams().modLength, | 27 return rtc::KeyParams::RSA(key_params.rsaParams().modLength, |
| 28 key_params.rsaParams().pubExp); | 28 key_params.rsaParams().pubExp); |
| 29 case blink::WebRTCKeyTypeECDSA: | 29 case blink::WebRTCKeyTypeECDSA: |
| 30 return rtc::KeyParams::ECDSA( | 30 return rtc::KeyParams::ECDSA( |
| 31 static_cast<rtc::ECCurve>(key_params.ecCurve())); | 31 static_cast<rtc::ECCurve>(key_params.ecCurve())); |
| 32 default: | 32 default: |
| 33 NOTREACHED(); | 33 NOTREACHED(); |
| 34 return rtc::KeyParams(); | 34 return rtc::KeyParams(); |
| 35 } | 35 } |
| 36 } | 36 } |
| 37 | 37 |
| 38 // Observer used by RTCCertificateGenerator::generateCertificate. | 38 // Observer used by RTCCertificateGenerator::generateCertificate. |
| 39 class RTCCertificateIdentityObserver | 39 class RTCCertificateIdentityObserver |
| 40 : public webrtc::DtlsIdentityRequestObserver { | 40 : public webrtc::DtlsIdentityRequestObserver { |
| 41 public: | 41 public: |
| 42 RTCCertificateIdentityObserver( | 42 RTCCertificateIdentityObserver( |
| 43 const scoped_refptr<base::SingleThreadTaskRunner>& main_thread, | 43 const scoped_refptr<base::SingleThreadTaskRunner>& main_thread, |
| 44 const scoped_refptr<base::SingleThreadTaskRunner>& signaling_thread) | 44 const scoped_refptr<base::SingleThreadTaskRunner>& signaling_thread) |
| 45 : main_thread_(main_thread), | 45 : main_thread_(main_thread), |
| 46 signaling_thread_(signaling_thread), | 46 signaling_thread_(signaling_thread), |
| 47 observer_(nullptr) { | 47 observer_(nullptr), |
| 48 request_event_(false, false) { | |
| 48 DCHECK(main_thread_); | 49 DCHECK(main_thread_); |
| 49 DCHECK(signaling_thread_); | 50 DCHECK(signaling_thread_); |
| 50 } | 51 } |
| 51 ~RTCCertificateIdentityObserver() override {} | 52 ~RTCCertificateIdentityObserver() override {} |
| 52 | 53 |
| 53 // Perform |store|->RequestIdentity with this identity observer and ensure | 54 base::WaitableEvent& request_event() { |
|
tommi (sloooow) - chröme
2016/05/12 12:42:55
non-const on purpose? If you only need it to wait
hbos_chromium
2016/05/12 14:27:59
Done. Made request_event_ mutable.
| |
| 54 // that this identity observer is not deleted until the request has completed | 55 return request_event_; |
| 55 // by holding on to a reference to itself for the duration of the request. | 56 } |
| 57 | |
| 58 rtc::scoped_refptr<rtc::RTCCertificate> Result() const { | |
|
tommi (sloooow) - chröme
2016/05/12 12:42:55
avoid using rtc:: types in Chrome whenever you can
hbos_chromium
2016/05/12 14:27:59
Done.
| |
| 59 result_lock_.Acquire(); | |
|
tommi (sloooow) - chröme
2016/05/12 12:42:55
use a scoped locker object.
Why do you need the l
hbos_chromium
2016/05/12 14:27:59
Removed the lock and added comment to make sure ca
| |
| 60 rtc::scoped_refptr<rtc::RTCCertificate> ret(result_); | |
| 61 result_lock_.Release(); | |
| 62 return ret; | |
|
tommi (sloooow) - chröme
2016/05/12 12:42:55
std::move, to avoid extra refcount?
hbos_chromium
2016/05/12 14:28:00
Now returning const& instead.
| |
| 63 } | |
| 64 | |
| 65 // Perform |store|->RequestIdentity with |this| identity observer and ensure | |
| 66 // that |this| identity observer is not deleted until the request has | |
| 67 // completed by holding on to a reference to itself for the duration of the | |
| 68 // request. The |observer| is optional, see |request_event| and |Result|. | |
| 56 void RequestIdentity( | 69 void RequestIdentity( |
| 57 const blink::WebRTCKeyParams& key_params, | 70 const rtc::KeyParams& key_params, |
| 58 const GURL& url, | 71 const GURL& url, |
| 59 const GURL& first_party_for_cookies, | 72 const GURL& first_party_for_cookies, |
| 60 const rtc::Optional<uint64_t>& expires_ms, | 73 const rtc::Optional<uint64_t>& expires_ms, |
| 61 std::unique_ptr<blink::WebRTCCertificateCallback> observer) { | 74 std::unique_ptr<blink::WebRTCCertificateCallback> observer) { |
| 62 DCHECK(main_thread_->BelongsToCurrentThread()); | 75 DCHECK(main_thread_->BelongsToCurrentThread()); |
| 63 DCHECK(!observer_) << "Already have a RequestIdentity in progress."; | |
| 64 key_params_ = key_params; | 76 key_params_ = key_params; |
| 65 observer_ = std::move(observer); | 77 observer_ = std::move(observer); |
| 66 DCHECK(observer_); | 78 request_event_.Reset(); |
|
tommi (sloooow) - chröme
2016/05/12 12:42:55
needed?
hbos_chromium
2016/05/12 14:28:00
Removed.
| |
| 67 // Identity request must be performed on the WebRTC signaling thread. | 79 // Identity request must be performed on the WebRTC signaling thread. |
| 68 signaling_thread_->PostTask(FROM_HERE, base::Bind( | 80 signaling_thread_->PostTask(FROM_HERE, base::Bind( |
| 69 &RTCCertificateIdentityObserver::RequestIdentityOnWebRtcSignalingThread, | 81 &RTCCertificateIdentityObserver::RequestIdentityOnWebRtcSignalingThread, |
| 70 this, url, first_party_for_cookies, expires_ms)); | 82 this, url, first_party_for_cookies, expires_ms)); |
| 71 } | 83 } |
| 72 | 84 |
| 73 private: | 85 private: |
| 74 void RequestIdentityOnWebRtcSignalingThread( | 86 void RequestIdentityOnWebRtcSignalingThread( |
| 75 GURL url, | 87 GURL url, |
|
tommi (sloooow) - chröme
2016/05/12 12:42:55
const &
hbos_chromium
2016/05/12 14:27:59
This copy is on purpose because it is being called
| |
| 76 GURL first_party_for_cookies, | 88 GURL first_party_for_cookies, |
| 77 rtc::Optional<uint64_t> expires_ms) { | 89 rtc::Optional<uint64_t> expires_ms) { |
| 78 DCHECK(signaling_thread_->BelongsToCurrentThread()); | 90 DCHECK(signaling_thread_->BelongsToCurrentThread()); |
| 79 std::unique_ptr<PeerConnectionIdentityStore> store( | 91 std::unique_ptr<PeerConnectionIdentityStore> store( |
| 80 new PeerConnectionIdentityStore(main_thread_, signaling_thread_, url, | 92 new PeerConnectionIdentityStore(main_thread_, signaling_thread_, url, |
| 81 first_party_for_cookies)); | 93 first_party_for_cookies)); |
| 82 // Request identity with |this| as the observer. OnSuccess/OnFailure will be | 94 // Request identity with |this| as the observer. |OnSuccess|/|OnFailure| |
| 83 // called asynchronously. | 95 // will be called asynchronously. |
| 84 store->RequestIdentity(WebRTCKeyParamsToKeyParams(key_params_), | 96 store->RequestIdentity(key_params_, expires_ms, this); |
| 85 expires_ms, this); | |
| 86 } | 97 } |
| 87 | 98 |
| 88 // webrtc::DtlsIdentityRequestObserver implementation. | 99 // webrtc::DtlsIdentityRequestObserver implementation. |
| 89 void OnFailure(int error) override { | 100 void OnFailure(int error) override { |
| 90 DCHECK(signaling_thread_->BelongsToCurrentThread()); | 101 DCHECK(signaling_thread_->BelongsToCurrentThread()); |
| 91 DCHECK(observer_); | |
| 92 main_thread_->PostTask(FROM_HERE, base::Bind( | 102 main_thread_->PostTask(FROM_HERE, base::Bind( |
| 93 &RTCCertificateIdentityObserver::DoCallbackOnMainThread, | 103 &RTCCertificateIdentityObserver::DoCallbackOnMainThread, |
| 94 this, nullptr)); | 104 this, nullptr)); |
| 95 } | 105 } |
| 96 void OnSuccess(const std::string& der_cert, | 106 void OnSuccess(const std::string& der_cert, |
| 97 const std::string& der_private_key) override { | 107 const std::string& der_private_key) override { |
| 98 std::string pem_cert = rtc::SSLIdentity::DerToPem( | 108 std::string pem_cert = rtc::SSLIdentity::DerToPem( |
| 99 rtc::kPemTypeCertificate, | 109 rtc::kPemTypeCertificate, |
| 100 reinterpret_cast<const unsigned char*>(der_cert.data()), | 110 reinterpret_cast<const unsigned char*>(der_cert.data()), |
| 101 der_cert.length()); | 111 der_cert.length()); |
| 102 std::string pem_key = rtc::SSLIdentity::DerToPem( | 112 std::string pem_key = rtc::SSLIdentity::DerToPem( |
| 103 rtc::kPemTypeRsaPrivateKey, | 113 rtc::kPemTypeRsaPrivateKey, |
| 104 reinterpret_cast<const unsigned char*>(der_private_key.data()), | 114 reinterpret_cast<const unsigned char*>(der_private_key.data()), |
| 105 der_private_key.length()); | 115 der_private_key.length()); |
| 106 OnSuccess(std::unique_ptr<rtc::SSLIdentity>( | 116 OnSuccess(std::unique_ptr<rtc::SSLIdentity>( |
| 107 rtc::SSLIdentity::FromPEMStrings(pem_key, pem_cert))); | 117 rtc::SSLIdentity::FromPEMStrings(pem_key, pem_cert))); |
| 108 } | 118 } |
| 109 void OnSuccess(std::unique_ptr<rtc::SSLIdentity> identity) override { | 119 void OnSuccess(std::unique_ptr<rtc::SSLIdentity> identity) override { |
| 110 DCHECK(signaling_thread_->BelongsToCurrentThread()); | 120 DCHECK(signaling_thread_->BelongsToCurrentThread()); |
| 111 DCHECK(observer_); | |
| 112 rtc::scoped_refptr<rtc::RTCCertificate> certificate = | 121 rtc::scoped_refptr<rtc::RTCCertificate> certificate = |
| 113 rtc::RTCCertificate::Create(std::move(identity)); | 122 rtc::RTCCertificate::Create(std::move(identity)); |
| 114 main_thread_->PostTask( | 123 result_lock_.Acquire(); |
| 115 FROM_HERE, | 124 result_ = certificate; |
| 116 base::Bind(&RTCCertificateIdentityObserver::DoCallbackOnMainThread, | 125 result_lock_.Release(); |
| 117 this, base::Passed(base::WrapUnique( | 126 request_event_.Signal(); |
|
tommi (sloooow) - chröme
2016/05/12 12:42:55
will this signal always be waited upon on the main
hbos_chromium
2016/05/12 14:28:00
Can't do Wait on the same thread as does the Signa
| |
| 118 new RTCCertificate(certificate))))); | 127 if (observer_) { |
|
tommi (sloooow) - chröme
2016/05/12 12:42:55
is it safe to check observer_ on this thread witho
hbos_chromium
2016/05/12 14:27:59
There is an assumption about there only being one
| |
| 128 main_thread_->PostTask( | |
| 129 FROM_HERE, | |
| 130 base::Bind(&RTCCertificateIdentityObserver::DoCallbackOnMainThread, | |
| 131 this, certificate)); | |
| 132 } | |
| 119 } | 133 } |
| 120 | 134 |
| 121 void DoCallbackOnMainThread( | 135 void DoCallbackOnMainThread( |
| 122 std::unique_ptr<blink::WebRTCCertificate> certificate) { | 136 rtc::scoped_refptr<rtc::RTCCertificate> certificate) { |
| 123 DCHECK(main_thread_->BelongsToCurrentThread()); | 137 DCHECK(main_thread_->BelongsToCurrentThread()); |
| 124 DCHECK(observer_); | 138 DCHECK(observer_); |
| 125 if (certificate) | 139 if (certificate) |
|
tommi (sloooow) - chröme
2016/05/12 12:42:55
now you need {} else {}
hbos_chromium
2016/05/12 14:27:59
Done.
| |
| 126 observer_->onSuccess(std::move(certificate)); | 140 observer_->onSuccess(std::unique_ptr<blink::WebRTCCertificate>( |
| 141 new RTCCertificate(certificate))); | |
| 127 else | 142 else |
| 128 observer_->onError(); | 143 observer_->onError(); |
| 129 observer_.reset(); | 144 observer_.reset(); |
| 130 } | 145 } |
| 131 | 146 |
| 132 // The main thread is the renderer thread. | 147 // The main thread is the renderer thread. |
| 133 const scoped_refptr<base::SingleThreadTaskRunner> main_thread_; | 148 const scoped_refptr<base::SingleThreadTaskRunner> main_thread_; |
| 134 // The signaling thread is a WebRTC thread used to invoke | 149 // The signaling thread is a WebRTC thread used to invoke |
| 135 // PeerConnectionIdentityStore::RequestIdentity on, as is required. | 150 // PeerConnectionIdentityStore::RequestIdentity on, as is required. |
| 136 const scoped_refptr<base::SingleThreadTaskRunner> signaling_thread_; | 151 const scoped_refptr<base::SingleThreadTaskRunner> signaling_thread_; |
| 137 blink::WebRTCKeyParams key_params_; | 152 rtc::KeyParams key_params_; |
|
tommi (sloooow) - chröme
2016/05/12 12:42:55
can these be const?
hbos_chromium
2016/05/12 14:27:59
I tried to make them const by moving what RequestI
| |
| 138 std::unique_ptr<blink::WebRTCCertificateCallback> observer_; | 153 std::unique_ptr<blink::WebRTCCertificateCallback> observer_; |
| 154 base::WaitableEvent request_event_; | |
| 155 rtc::scoped_refptr<rtc::RTCCertificate> result_; | |
| 156 mutable base::Lock result_lock_; | |
| 139 | 157 |
| 140 DISALLOW_COPY_AND_ASSIGN(RTCCertificateIdentityObserver); | 158 DISALLOW_COPY_AND_ASSIGN(RTCCertificateIdentityObserver); |
| 141 }; | 159 }; |
| 142 | 160 |
| 143 } // namespace | 161 } // namespace |
| 144 | 162 |
| 145 void RTCCertificateGenerator::generateCertificate( | 163 void RTCCertificateGenerator::generateCertificate( |
| 146 const blink::WebRTCKeyParams& key_params, | 164 const blink::WebRTCKeyParams& key_params, |
| 147 const blink::WebURL& url, | 165 const blink::WebURL& url, |
| 148 const blink::WebURL& first_party_for_cookies, | 166 const blink::WebURL& first_party_for_cookies, |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 178 PeerConnectionDependencyFactory* pc_dependency_factory = | 196 PeerConnectionDependencyFactory* pc_dependency_factory = |
| 179 RenderThreadImpl::current()->GetPeerConnectionDependencyFactory(); | 197 RenderThreadImpl::current()->GetPeerConnectionDependencyFactory(); |
| 180 pc_dependency_factory->EnsureInitialized(); | 198 pc_dependency_factory->EnsureInitialized(); |
| 181 const scoped_refptr<base::SingleThreadTaskRunner> signaling_thread = | 199 const scoped_refptr<base::SingleThreadTaskRunner> signaling_thread = |
| 182 pc_dependency_factory->GetWebRtcSignalingThread(); | 200 pc_dependency_factory->GetWebRtcSignalingThread(); |
| 183 | 201 |
| 184 rtc::scoped_refptr<RTCCertificateIdentityObserver> identity_observer( | 202 rtc::scoped_refptr<RTCCertificateIdentityObserver> identity_observer( |
| 185 new rtc::RefCountedObject<RTCCertificateIdentityObserver>( | 203 new rtc::RefCountedObject<RTCCertificateIdentityObserver>( |
| 186 main_thread, signaling_thread)); | 204 main_thread, signaling_thread)); |
| 187 // |identity_observer| lives until request has completed. | 205 // |identity_observer| lives until request has completed. |
| 188 identity_observer->RequestIdentity(key_params, url, first_party_for_cookies, | 206 identity_observer->RequestIdentity( |
| 189 expires_ms, std::move(observer)); | 207 WebRTCKeyParamsToKeyParams(key_params), url, first_party_for_cookies, |
| 208 expires_ms, std::move(observer)); | |
| 190 #else | 209 #else |
| 191 observer->onError(); | 210 observer->onError(); |
| 192 #endif | 211 #endif |
| 193 } | 212 } |
| 194 | 213 |
| 214 rtc::scoped_refptr<rtc::RTCCertificate> | |
| 215 RTCCertificateGenerator::generateCertificateAndWait( | |
| 216 const rtc::KeyParams& key_params, | |
| 217 const rtc::Optional<uint64_t>& expires_ms) { | |
| 218 #if defined(ENABLE_WEBRTC) | |
| 219 const scoped_refptr<base::SingleThreadTaskRunner> main_thread = | |
| 220 base::ThreadTaskRunnerHandle::Get(); | |
| 221 | |
| 222 PeerConnectionDependencyFactory* pc_dependency_factory = | |
| 223 RenderThreadImpl::current()->GetPeerConnectionDependencyFactory(); | |
| 224 pc_dependency_factory->EnsureInitialized(); | |
| 225 const scoped_refptr<base::SingleThreadTaskRunner> signaling_thread = | |
| 226 pc_dependency_factory->GetWebRtcSignalingThread(); | |
| 227 | |
| 228 rtc::scoped_refptr<RTCCertificateIdentityObserver> identity_observer( | |
| 229 new rtc::RefCountedObject<RTCCertificateIdentityObserver>( | |
| 230 main_thread, signaling_thread)); | |
| 231 | |
| 232 // Don't care about URL origin parameters, using empty URL. | |
| 233 identity_observer->RequestIdentity(key_params, GURL(), GURL(), | |
| 234 expires_ms, nullptr); | |
| 235 identity_observer->request_event().Wait(); | |
| 236 return identity_observer->Result(); | |
|
tommi (sloooow) - chröme
2016/05/12 12:42:55
thinking about it some more, do we need the observ
hbos_chromium
2016/05/12 14:28:00
I think I need to re-read that to understand. I'll
| |
| 237 #else | |
| 238 return nullptr; | |
| 239 #endif | |
| 240 } | |
| 241 | |
| 195 bool RTCCertificateGenerator::isSupportedKeyParams( | 242 bool RTCCertificateGenerator::isSupportedKeyParams( |
| 196 const blink::WebRTCKeyParams& key_params) { | 243 const blink::WebRTCKeyParams& key_params) { |
| 197 return WebRTCKeyParamsToKeyParams(key_params).IsValid(); | 244 return WebRTCKeyParamsToKeyParams(key_params).IsValid(); |
| 198 } | 245 } |
| 199 | 246 |
| 200 std::unique_ptr<blink::WebRTCCertificate> RTCCertificateGenerator::fromPEM( | 247 std::unique_ptr<blink::WebRTCCertificate> RTCCertificateGenerator::fromPEM( |
| 201 const std::string& pem_private_key, | 248 const std::string& pem_private_key, |
| 202 const std::string& pem_certificate) { | 249 const std::string& pem_certificate) { |
| 203 rtc::scoped_refptr<rtc::RTCCertificate> certificate = | 250 rtc::scoped_refptr<rtc::RTCCertificate> certificate = |
| 204 rtc::RTCCertificate::FromPEM( | 251 rtc::RTCCertificate::FromPEM( |
| 205 rtc::RTCCertificatePEM(pem_private_key, pem_certificate)); | 252 rtc::RTCCertificatePEM(pem_private_key, pem_certificate)); |
| 206 return std::unique_ptr<blink::WebRTCCertificate>( | 253 return std::unique_ptr<blink::WebRTCCertificate>( |
| 207 new RTCCertificate(certificate)); | 254 new RTCCertificate(certificate)); |
| 208 } | 255 } |
| 209 | 256 |
| 210 } // namespace content | 257 } // namespace content |
| OLD | NEW |