| Index: media/crypto/aes_decryptor.cc
|
| diff --git a/media/crypto/aes_decryptor.cc b/media/crypto/aes_decryptor.cc
|
| index cbb75b37bd33457f74b9f540d652ae01bbd77c19..49275fb7f031db0c45b46da9d61bffbe179f493c 100644
|
| --- a/media/crypto/aes_decryptor.cc
|
| +++ b/media/crypto/aes_decryptor.cc
|
| @@ -6,17 +6,21 @@
|
|
|
| #include "base/logging.h"
|
| #include "base/stl_util.h"
|
| +#include "base/string_number_conversions.h"
|
| #include "base/string_piece.h"
|
| #include "crypto/encryptor.h"
|
| #include "crypto/symmetric_key.h"
|
| #include "media/base/decoder_buffer.h"
|
| #include "media/base/decrypt_config.h"
|
| +#include "media/crypto/decryptor_client.h"
|
|
|
| namespace media {
|
|
|
| // TODO(xhwang): Get real IV from frames.
|
| static const char kInitialCounter[] = "0000000000000000";
|
|
|
| +uint32 AesDecryptor::next_session_id_ = 1;
|
| +
|
| // Decrypt |input| using |key|.
|
| // Return a DecoderBuffer with the decrypted data if decryption succeeded.
|
| // Return NULL if decryption failed.
|
| @@ -48,35 +52,83 @@ static scoped_refptr<DecoderBuffer> DecryptData(const DecoderBuffer& input,
|
| decrypted_text.size());
|
| }
|
|
|
| -AesDecryptor::AesDecryptor() {}
|
| +AesDecryptor::AesDecryptor(DecryptorClient* client)
|
| + : client_(client) {
|
| +}
|
|
|
| AesDecryptor::~AesDecryptor() {
|
| STLDeleteValues(&key_map_);
|
| }
|
|
|
| -void AesDecryptor::AddKey(const uint8* key_id, int key_id_size,
|
| - const uint8* key, int key_size) {
|
| - CHECK(key_id && key);
|
| - CHECK_GT(key_id_size, 0);
|
| - CHECK_GT(key_size, 0);
|
| +void AesDecryptor::GenerateKeyRequest(const std::string& key_system,
|
| + const uint8* init_data,
|
| + int init_data_length) {
|
| + std::string session_id_string(base::UintToString(next_session_id_++));
|
|
|
| - std::string key_id_string(reinterpret_cast<const char*>(key_id), key_id_size);
|
| - std::string key_string(reinterpret_cast<const char*>(key) , key_size);
|
| + // For now, just fire the event with the |init_data| as the request.
|
| + int message_length = init_data_length;
|
| + scoped_array<uint8> message(new uint8[message_length]);
|
| + memcpy(message.get(), init_data, message_length);
|
| +
|
| + client_->KeyMessage(key_system, session_id_string,
|
| + message.Pass(), message_length, "");
|
| +}
|
| +
|
| +void AesDecryptor::AddKey(const std::string& key_system,
|
| + const uint8* key,
|
| + int key_length,
|
| + const uint8* init_data,
|
| + int init_data_length,
|
| + const std::string& session_id) {
|
| + CHECK(key);
|
| + CHECK_GT(key_length, 0);
|
| +
|
| + // TODO(xhwang): Add |session_id| check after we figure out how:
|
| + // https://www.w3.org/Bugs/Public/show_bug.cgi?id=16550
|
| +
|
| + const int kSupportedKeyLength = 16; // 128-bit key.
|
| + if (key_length != kSupportedKeyLength) {
|
| + DVLOG(1) << "Invalid key length: " << key_length;
|
| + client_->KeyError(key_system, session_id, kUnknownError, 0);
|
| + return;
|
| + }
|
|
|
| + // TODO(xhwang): Fix the decryptor to accept no |init_data|. See
|
| + // http://crbug.com/123265. Until then, ensure a non-empty value is passed.
|
| + static const uint8 kDummyInitData[1] = { 0 };
|
| + if (!init_data) {
|
| + init_data = kDummyInitData;
|
| + init_data_length = arraysize(kDummyInitData);
|
| + }
|
| +
|
| + // TODO(xhwang): For now, use |init_data| for key ID. Make this more spec
|
| + // compliant later (http://crbug.com/123262, http://crbug.com/123265).
|
| + std::string key_id_string(reinterpret_cast<const char*>(init_data),
|
| + init_data_length);
|
| + std::string key_string(reinterpret_cast<const char*>(key) , key_length);
|
| crypto::SymmetricKey* symmetric_key = crypto::SymmetricKey::Import(
|
| crypto::SymmetricKey::AES, key_string);
|
| if (!symmetric_key) {
|
| DVLOG(1) << "Could not import key.";
|
| + client_->KeyError(key_system, session_id, kUnknownError, 0);
|
| return;
|
| }
|
|
|
| - base::AutoLock auto_lock(lock_);
|
| - KeyMap::iterator found = key_map_.find(key_id_string);
|
| - if (found != key_map_.end()) {
|
| - delete found->second;
|
| - key_map_.erase(found);
|
| + {
|
| + base::AutoLock auto_lock(key_map_lock_);
|
| + KeyMap::iterator found = key_map_.find(key_id_string);
|
| + if (found != key_map_.end()) {
|
| + delete found->second;
|
| + key_map_.erase(found);
|
| + }
|
| + key_map_[key_id_string] = symmetric_key;
|
| }
|
| - key_map_[key_id_string] = symmetric_key;
|
| +
|
| + client_->KeyAdded(key_system, session_id);
|
| +}
|
| +
|
| +void AesDecryptor::CancelKeyRequest(const std::string& key_system,
|
| + const std::string& session_id) {
|
| }
|
|
|
| scoped_refptr<DecoderBuffer> AesDecryptor::Decrypt(
|
| @@ -90,7 +142,7 @@ scoped_refptr<DecoderBuffer> AesDecryptor::Decrypt(
|
|
|
| crypto::SymmetricKey* key = NULL;
|
| {
|
| - base::AutoLock auto_lock(lock_);
|
| + base::AutoLock auto_lock(key_map_lock_);
|
| KeyMap::const_iterator found = key_map_.find(key_id_string);
|
| if (found == key_map_.end()) {
|
| DVLOG(1) << "Could not find a matching key for given key ID.";
|
|
|