OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "webcontentdecryptionmodulesession_impl.h" | 5 #include "webcontentdecryptionmodulesession_impl.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/callback_helpers.h" | 8 #include "base/callback_helpers.h" |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/numerics/safe_conversions.h" | 10 #include "base/numerics/safe_conversions.h" |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
95 break; | 95 break; |
96 } | 96 } |
97 | 97 |
98 NOTREACHED(); | 98 NOTREACHED(); |
99 return MediaKeys::TEMPORARY_SESSION; | 99 return MediaKeys::TEMPORARY_SESSION; |
100 } | 100 } |
101 | 101 |
102 static bool SanitizeInitData(EmeInitDataType init_data_type, | 102 static bool SanitizeInitData(EmeInitDataType init_data_type, |
103 const unsigned char* init_data, | 103 const unsigned char* init_data, |
104 size_t init_data_length, | 104 size_t init_data_length, |
105 std::vector<uint8>* sanitized_init_data, | 105 std::vector<uint8_t>* sanitized_init_data, |
106 std::string* error_message) { | 106 std::string* error_message) { |
107 if (init_data_length > limits::kMaxInitDataLength) { | 107 if (init_data_length > limits::kMaxInitDataLength) { |
108 error_message->assign("Initialization data too long."); | 108 error_message->assign("Initialization data too long."); |
109 return false; | 109 return false; |
110 } | 110 } |
111 | 111 |
112 switch (init_data_type) { | 112 switch (init_data_type) { |
113 case EmeInitDataType::WEBM: | 113 case EmeInitDataType::WEBM: |
114 sanitized_init_data->assign(init_data, init_data + init_data_length); | 114 sanitized_init_data->assign(init_data, init_data + init_data_length); |
115 return true; | 115 return true; |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
172 | 172 |
173 for (const char c : *sanitized_session_id) { | 173 for (const char c : *sanitized_session_id) { |
174 if (!base::IsAsciiAlpha(c) && !base::IsAsciiDigit(c)) | 174 if (!base::IsAsciiAlpha(c) && !base::IsAsciiDigit(c)) |
175 return false; | 175 return false; |
176 } | 176 } |
177 | 177 |
178 return true; | 178 return true; |
179 } | 179 } |
180 | 180 |
181 static bool SanitizeResponse(const std::string& key_system, | 181 static bool SanitizeResponse(const std::string& key_system, |
182 const uint8* response, | 182 const uint8_t* response, |
183 size_t response_length, | 183 size_t response_length, |
184 std::vector<uint8>* sanitized_response) { | 184 std::vector<uint8_t>* sanitized_response) { |
185 // The user agent should thoroughly validate the response before passing it | 185 // The user agent should thoroughly validate the response before passing it |
186 // to the CDM. This may include verifying values are within reasonable limits, | 186 // to the CDM. This may include verifying values are within reasonable limits, |
187 // stripping irrelevant data or fields, pre-parsing it, sanitizing it, | 187 // stripping irrelevant data or fields, pre-parsing it, sanitizing it, |
188 // and/or generating a fully sanitized version. The user agent should check | 188 // and/or generating a fully sanitized version. The user agent should check |
189 // that the length and values of fields are reasonable. Unknown fields should | 189 // that the length and values of fields are reasonable. Unknown fields should |
190 // be rejected or removed. | 190 // be rejected or removed. |
191 if (response_length > limits::kMaxSessionResponseLength) | 191 if (response_length > limits::kMaxSessionResponseLength) |
192 return false; | 192 return false; |
193 | 193 |
194 if (IsClearKey(key_system) || IsExternalClearKey(key_system)) { | 194 if (IsClearKey(key_system) || IsExternalClearKey(key_system)) { |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
272 // before passing it to the CDM. This includes verifying that the length | 272 // before passing it to the CDM. This includes verifying that the length |
273 // and values of fields are reasonable, verifying that values are within | 273 // and values of fields are reasonable, verifying that values are within |
274 // reasonable limits, and stripping irrelevant, unsupported, or unknown | 274 // reasonable limits, and stripping irrelevant, unsupported, or unknown |
275 // data or fields. It is recommended that user agents pre-parse, sanitize, | 275 // data or fields. It is recommended that user agents pre-parse, sanitize, |
276 // and/or generate a fully sanitized version of the Initialization Data. | 276 // and/or generate a fully sanitized version of the Initialization Data. |
277 // If the Initialization Data format specified by initDataType support | 277 // If the Initialization Data format specified by initDataType support |
278 // multiple entries, the user agent should remove entries that are not | 278 // multiple entries, the user agent should remove entries that are not |
279 // needed by the CDM. | 279 // needed by the CDM. |
280 // 9.3 If the previous step failed, reject promise with a new DOMException | 280 // 9.3 If the previous step failed, reject promise with a new DOMException |
281 // whose name is InvalidAccessError. | 281 // whose name is InvalidAccessError. |
282 std::vector<uint8> sanitized_init_data; | 282 std::vector<uint8_t> sanitized_init_data; |
283 std::string message; | 283 std::string message; |
284 if (!SanitizeInitData(eme_init_data_type, init_data, init_data_length, | 284 if (!SanitizeInitData(eme_init_data_type, init_data, init_data_length, |
285 &sanitized_init_data, &message)) { | 285 &sanitized_init_data, &message)) { |
286 result.completeWithError( | 286 result.completeWithError( |
287 blink::WebContentDecryptionModuleExceptionInvalidAccessError, 0, | 287 blink::WebContentDecryptionModuleExceptionInvalidAccessError, 0, |
288 blink::WebString::fromUTF8(message)); | 288 blink::WebString::fromUTF8(message)); |
289 return; | 289 return; |
290 } | 290 } |
291 | 291 |
292 // 9.4 Let session id be the empty string. | 292 // 9.4 Let session id be the empty string. |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
328 adapter_->LoadSession( | 328 adapter_->LoadSession( |
329 MediaKeys::PERSISTENT_LICENSE_SESSION, sanitized_session_id, | 329 MediaKeys::PERSISTENT_LICENSE_SESSION, sanitized_session_id, |
330 scoped_ptr<NewSessionCdmPromise>(new NewSessionCdmResultPromise( | 330 scoped_ptr<NewSessionCdmPromise>(new NewSessionCdmResultPromise( |
331 result, adapter_->GetKeySystemUMAPrefix() + kLoadSessionUMAName, | 331 result, adapter_->GetKeySystemUMAPrefix() + kLoadSessionUMAName, |
332 base::Bind( | 332 base::Bind( |
333 &WebContentDecryptionModuleSessionImpl::OnSessionInitialized, | 333 &WebContentDecryptionModuleSessionImpl::OnSessionInitialized, |
334 weak_ptr_factory_.GetWeakPtr())))); | 334 weak_ptr_factory_.GetWeakPtr())))); |
335 } | 335 } |
336 | 336 |
337 void WebContentDecryptionModuleSessionImpl::update( | 337 void WebContentDecryptionModuleSessionImpl::update( |
338 const uint8* response, | 338 const uint8_t* response, |
339 size_t response_length, | 339 size_t response_length, |
340 blink::WebContentDecryptionModuleResult result) { | 340 blink::WebContentDecryptionModuleResult result) { |
341 DCHECK(response); | 341 DCHECK(response); |
342 DCHECK(!session_id_.empty()); | 342 DCHECK(!session_id_.empty()); |
343 DCHECK(thread_checker_.CalledOnValidThread()); | 343 DCHECK(thread_checker_.CalledOnValidThread()); |
344 | 344 |
345 std::vector<uint8> sanitized_response; | 345 std::vector<uint8_t> sanitized_response; |
346 if (!SanitizeResponse(adapter_->GetKeySystem(), response, response_length, | 346 if (!SanitizeResponse(adapter_->GetKeySystem(), response, response_length, |
347 &sanitized_response)) { | 347 &sanitized_response)) { |
348 result.completeWithError( | 348 result.completeWithError( |
349 blink::WebContentDecryptionModuleExceptionInvalidAccessError, 0, | 349 blink::WebContentDecryptionModuleExceptionInvalidAccessError, 0, |
350 "Invalid response."); | 350 "Invalid response."); |
351 return; | 351 return; |
352 } | 352 } |
353 | 353 |
354 adapter_->UpdateSession( | 354 adapter_->UpdateSession( |
355 session_id_, sanitized_response, | 355 session_id_, sanitized_response, |
(...skipping 16 matching lines...) Expand all Loading... |
372 DCHECK(!session_id_.empty()); | 372 DCHECK(!session_id_.empty()); |
373 DCHECK(thread_checker_.CalledOnValidThread()); | 373 DCHECK(thread_checker_.CalledOnValidThread()); |
374 adapter_->RemoveSession( | 374 adapter_->RemoveSession( |
375 session_id_, | 375 session_id_, |
376 scoped_ptr<SimpleCdmPromise>(new CdmResultPromise<>( | 376 scoped_ptr<SimpleCdmPromise>(new CdmResultPromise<>( |
377 result, adapter_->GetKeySystemUMAPrefix() + kRemoveSessionUMAName))); | 377 result, adapter_->GetKeySystemUMAPrefix() + kRemoveSessionUMAName))); |
378 } | 378 } |
379 | 379 |
380 void WebContentDecryptionModuleSessionImpl::OnSessionMessage( | 380 void WebContentDecryptionModuleSessionImpl::OnSessionMessage( |
381 MediaKeys::MessageType message_type, | 381 MediaKeys::MessageType message_type, |
382 const std::vector<uint8>& message) { | 382 const std::vector<uint8_t>& message) { |
383 DCHECK(client_) << "Client not set before message event"; | 383 DCHECK(client_) << "Client not set before message event"; |
384 DCHECK(thread_checker_.CalledOnValidThread()); | 384 DCHECK(thread_checker_.CalledOnValidThread()); |
385 client_->message(convertMessageType(message_type), message.data(), | 385 client_->message(convertMessageType(message_type), message.data(), |
386 message.size()); | 386 message.size()); |
387 } | 387 } |
388 | 388 |
389 void WebContentDecryptionModuleSessionImpl::OnSessionKeysChange( | 389 void WebContentDecryptionModuleSessionImpl::OnSessionKeysChange( |
390 bool has_additional_usable_key, | 390 bool has_additional_usable_key, |
391 CdmKeysInfo keys_info) { | 391 CdmKeysInfo keys_info) { |
392 DCHECK(thread_checker_.CalledOnValidThread()); | 392 DCHECK(thread_checker_.CalledOnValidThread()); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
431 | 431 |
432 DCHECK(session_id_.empty()) << "Session ID may not be changed once set."; | 432 DCHECK(session_id_.empty()) << "Session ID may not be changed once set."; |
433 session_id_ = session_id; | 433 session_id_ = session_id; |
434 *status = | 434 *status = |
435 adapter_->RegisterSession(session_id_, weak_ptr_factory_.GetWeakPtr()) | 435 adapter_->RegisterSession(session_id_, weak_ptr_factory_.GetWeakPtr()) |
436 ? SessionInitStatus::NEW_SESSION | 436 ? SessionInitStatus::NEW_SESSION |
437 : SessionInitStatus::SESSION_ALREADY_EXISTS; | 437 : SessionInitStatus::SESSION_ALREADY_EXISTS; |
438 } | 438 } |
439 | 439 |
440 } // namespace media | 440 } // namespace media |
OLD | NEW |