| 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 "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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |