Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(261)

Side by Side Diff: media/cdm/aes_decryptor.cc

Issue 2545083004: [eme] Handle multiple calls to MediaKeySession.close() (Closed)
Patch Set: rebase for MediaKeys rename Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 "media/cdm/aes_decryptor.h" 5 #include "media/cdm/aes_decryptor.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <list> 8 #include <list>
9 #include <utility> 9 #include <utility>
10 #include <vector> 10 #include <vector>
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
254 promise->reject(CdmPromise::NOT_SUPPORTED_ERROR, 0, 254 promise->reject(CdmPromise::NOT_SUPPORTED_ERROR, 0,
255 "SetServerCertificate() is not supported."); 255 "SetServerCertificate() is not supported.");
256 } 256 }
257 257
258 void AesDecryptor::CreateSessionAndGenerateRequest( 258 void AesDecryptor::CreateSessionAndGenerateRequest(
259 SessionType session_type, 259 SessionType session_type,
260 EmeInitDataType init_data_type, 260 EmeInitDataType init_data_type,
261 const std::vector<uint8_t>& init_data, 261 const std::vector<uint8_t>& init_data,
262 std::unique_ptr<NewSessionCdmPromise> promise) { 262 std::unique_ptr<NewSessionCdmPromise> promise) {
263 std::string session_id(base::UintToString(next_session_id_++)); 263 std::string session_id(base::UintToString(next_session_id_++));
264 valid_sessions_.insert(session_id); 264 open_sessions_.insert(session_id);
265 265
266 // For now, the AesDecryptor does not care about |session_type|. 266 // For now, the AesDecryptor does not care about |session_type|.
267 // TODO(jrummell): Validate |session_type|. 267 // TODO(jrummell): Validate |session_type|.
268 268
269 std::vector<uint8_t> message; 269 std::vector<uint8_t> message;
270 std::vector<std::vector<uint8_t>> keys; 270 std::vector<std::vector<uint8_t>> keys;
271 switch (init_data_type) { 271 switch (init_data_type) {
272 case EmeInitDataType::WEBM: 272 case EmeInitDataType::WEBM:
273 // |init_data| is simply the key needed. 273 // |init_data| is simply the key needed.
274 if (init_data.size() < limits::kMinKeyIdLength || 274 if (init_data.size() < limits::kMinKeyIdLength ||
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
322 // that do not support loadSession. See http://crbug.com/342481 322 // that do not support loadSession. See http://crbug.com/342481
323 promise->reject(CdmPromise::NOT_SUPPORTED_ERROR, 0, 323 promise->reject(CdmPromise::NOT_SUPPORTED_ERROR, 0,
324 "LoadSession() is not supported."); 324 "LoadSession() is not supported.");
325 } 325 }
326 326
327 void AesDecryptor::UpdateSession(const std::string& session_id, 327 void AesDecryptor::UpdateSession(const std::string& session_id,
328 const std::vector<uint8_t>& response, 328 const std::vector<uint8_t>& response,
329 std::unique_ptr<SimpleCdmPromise> promise) { 329 std::unique_ptr<SimpleCdmPromise> promise) {
330 CHECK(!response.empty()); 330 CHECK(!response.empty());
331 331
332 // TODO(jrummell): Convert back to a DCHECK once prefixed EME is removed. 332 // Currently the EME spec has blink check for session closed synchronously,
333 if (valid_sessions_.find(session_id) == valid_sessions_.end()) { 333 // but then this is called asynchronously. So it is possible that update()
334 // could get called on a closed session.
335 // https://github.com/w3c/encrypted-media/issues/365
336 if (open_sessions_.find(session_id) == open_sessions_.end()) {
334 promise->reject(CdmPromise::INVALID_ACCESS_ERROR, 0, 337 promise->reject(CdmPromise::INVALID_ACCESS_ERROR, 0,
335 "Session does not exist."); 338 "Session does not exist.");
336 return; 339 return;
337 } 340 }
338 341
339 std::string key_string(response.begin(), response.end()); 342 std::string key_string(response.begin(), response.end());
340 343
341 KeyIdAndKeyPairs keys; 344 KeyIdAndKeyPairs keys;
342 SessionType session_type = ContentDecryptionModule::TEMPORARY_SESSION; 345 SessionType session_type = ContentDecryptionModule::TEMPORARY_SESSION;
343 if (!ExtractKeysFromJWKSet(key_string, &keys, &session_type)) { 346 if (!ExtractKeysFromJWKSet(key_string, &keys, &session_type)) {
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
398 } 401 }
399 } 402 }
400 } 403 }
401 404
402 session_keys_change_cb_.Run(session_id, key_added, std::move(keys_info)); 405 session_keys_change_cb_.Run(session_id, key_added, std::move(keys_info));
403 } 406 }
404 407
405 // Runs the parallel steps from https://w3c.github.io/encrypted-media/#close. 408 // Runs the parallel steps from https://w3c.github.io/encrypted-media/#close.
406 void AesDecryptor::CloseSession(const std::string& session_id, 409 void AesDecryptor::CloseSession(const std::string& session_id,
407 std::unique_ptr<SimpleCdmPromise> promise) { 410 std::unique_ptr<SimpleCdmPromise> promise) {
408 // Validate that this is a reference to an active session and then forget it. 411 // Validate that this is a reference to an open session. close() shouldn't
409 std::set<std::string>::iterator it = valid_sessions_.find(session_id); 412 // be called if the session is already closed. However, the operation is
410 DCHECK(it != valid_sessions_.end()); 413 // asynchronous, so there is a window where close() was called a second time
414 // just before the closed event arrives. As a result it is possible that the
415 // session is already closed, so assume that the session is closed if it
416 // doesn't exist. https://github.com/w3c/encrypted-media/issues/365.
417 //
418 // close() is called from a MediaKeySession object, so it is unlikely that
419 // this method will be called with a previously unseen |session_id|.
420 std::set<std::string>::iterator it = open_sessions_.find(session_id);
421 if (it == open_sessions_.end()) {
422 promise->resolve();
423 return;
424 }
411 425
412 // 5.1. Let cdm be the CDM instance represented by session's cdm instance 426 // 5.1. Let cdm be the CDM instance represented by session's cdm instance
413 // value. 427 // value.
414 // 5.2. Use cdm to close the session associated with session. 428 // 5.2. Use cdm to close the session associated with session.
415 valid_sessions_.erase(it); 429 open_sessions_.erase(it);
416 DeleteKeysForSession(session_id); 430 DeleteKeysForSession(session_id);
417 431
418 // 5.3. Queue a task to run the following steps: 432 // 5.3. Queue a task to run the following steps:
419 // 5.3.1. Run the Session Closed algorithm on the session. 433 // 5.3.1. Run the Session Closed algorithm on the session.
420 session_closed_cb_.Run(session_id); 434 session_closed_cb_.Run(session_id);
421 // 5.3.2. Resolve promise. 435 // 5.3.2. Resolve promise.
422 promise->resolve(); 436 promise->resolve();
423 } 437 }
424 438
425 void AesDecryptor::RemoveSession(const std::string& session_id, 439 void AesDecryptor::RemoveSession(const std::string& session_id,
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
602 bool AesDecryptor::DecryptionKey::Init() { 616 bool AesDecryptor::DecryptionKey::Init() {
603 CHECK(!secret_.empty()); 617 CHECK(!secret_.empty());
604 decryption_key_ = 618 decryption_key_ =
605 crypto::SymmetricKey::Import(crypto::SymmetricKey::AES, secret_); 619 crypto::SymmetricKey::Import(crypto::SymmetricKey::AES, secret_);
606 if (!decryption_key_) 620 if (!decryption_key_)
607 return false; 621 return false;
608 return true; 622 return true;
609 } 623 }
610 624
611 } // namespace media 625 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698