// Copyright 2014 Google Inc. All rights reserved. // // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file or at // https://developers.google.com/open-source/licenses/bsd #include "packager/media/base/key_source.h" #include "packager/base/strings/string_number_conversions.h" #include "packager/media/base/aes_encryptor.h" #include "packager/media/base/buffer_writer.h" namespace { const uint8_t kWidevineSystemId[] = {0xed, 0xef, 0x8b, 0xa9, 0x79, 0xd6, 0x4a, 0xce, 0xa3, 0xc8, 0x27, 0xdc, 0xd5, 0x1d, 0x21, 0xed}; const char kDefaultUUID[] = ""; const char kDefaultSystemName[] = ""; } // namespace namespace edash_packager { namespace media { EncryptionKey::EncryptionKey() {} EncryptionKey::~EncryptionKey() {} KeySource::~KeySource() {} Status KeySource::FetchKeys(const std::vector& content_id, const std::string& policy) { // Do nothing for fixed key encryption/decryption. return Status::OK; } Status KeySource::FetchKeys(const std::vector& pssh_data) { // Do nothing for fixed key encryption/decryption. return Status::OK; } Status KeySource::FetchKeys(uint32_t asset_id) { // Do nothing for fixed key encryption/decryption. return Status::OK; } Status KeySource::GetKey(TrackType track_type, EncryptionKey* key) { DCHECK(key); DCHECK(encryption_key_); *key = *encryption_key_; return Status::OK; } Status KeySource::GetKey(const std::vector& key_id, EncryptionKey* key) { DCHECK(key); DCHECK(encryption_key_); if (key_id != encryption_key_->key_id) { return Status(error::NOT_FOUND, std::string("Key for key ID ") + base::HexEncode(&key_id[0], key_id.size()) + " was not found."); } *key = *encryption_key_; return Status::OK; } Status KeySource::GetCryptoPeriodKey(uint32_t crypto_period_index, TrackType track_type, EncryptionKey* key) { NOTIMPLEMENTED(); return Status(error::UNIMPLEMENTED, ""); } std::string KeySource::UUID() { return kDefaultUUID; } std::string KeySource::SystemName() { return kDefaultSystemName; } scoped_ptr KeySource::CreateFromHexStrings( const std::string& key_id_hex, const std::string& key_hex, const std::string& pssh_data_hex, const std::string& iv_hex) { scoped_ptr encryption_key(new EncryptionKey()); if (!base::HexStringToBytes(key_id_hex, &encryption_key->key_id)) { LOG(ERROR) << "Cannot parse key_id_hex " << key_id_hex; return scoped_ptr(); } if (!base::HexStringToBytes(key_hex, &encryption_key->key)) { LOG(ERROR) << "Cannot parse key_hex " << key_hex; return scoped_ptr(); } std::vector pssh_data; if (!pssh_data_hex.empty() && !base::HexStringToBytes(pssh_data_hex, &pssh_data)) { LOG(ERROR) << "Cannot parse pssh_hex " << pssh_data_hex; return scoped_ptr(); } if (!iv_hex.empty()) { if (!base::HexStringToBytes(iv_hex, &encryption_key->iv)) { LOG(ERROR) << "Cannot parse iv_hex " << iv_hex; return scoped_ptr(); } } encryption_key->pssh = PsshBoxFromPsshData(pssh_data); return scoped_ptr( new KeySource(encryption_key.Pass())); } KeySource::TrackType KeySource::GetTrackTypeFromString( const std::string& track_type_string) { if (track_type_string == "SD") return TRACK_TYPE_SD; if (track_type_string == "HD") return TRACK_TYPE_HD; if (track_type_string == "AUDIO") return TRACK_TYPE_AUDIO; if (track_type_string == "UNSPECIFIED") return TRACK_TYPE_UNSPECIFIED; LOG(WARNING) << "Unexpected track type: " << track_type_string; return TRACK_TYPE_UNKNOWN; } std::string KeySource::TrackTypeToString(TrackType track_type) { switch (track_type) { case TRACK_TYPE_SD: return "SD"; case TRACK_TYPE_HD: return "HD"; case TRACK_TYPE_AUDIO: return "AUDIO"; default: NOTIMPLEMENTED() << "Unknown track type: " << track_type; return "UNKNOWN"; } } std::vector KeySource::PsshBoxFromPsshData( const std::vector& pssh_data) { const uint8_t kPsshFourCC[] = {'p', 's', 's', 'h'}; const uint32_t kVersionAndFlags = 0; const uint32_t pssh_data_size = pssh_data.size(); const uint32_t total_size = sizeof(total_size) + sizeof(kPsshFourCC) + sizeof(kVersionAndFlags) + sizeof(kWidevineSystemId) + sizeof(pssh_data_size) + pssh_data_size; BufferWriter writer; writer.AppendInt(total_size); writer.AppendArray(kPsshFourCC, sizeof(kPsshFourCC)); writer.AppendInt(kVersionAndFlags); writer.AppendArray(kWidevineSystemId, sizeof(kWidevineSystemId)); writer.AppendInt(pssh_data_size); writer.AppendVector(pssh_data); return std::vector(writer.Buffer(), writer.Buffer() + writer.Size()); } KeySource::KeySource() {} KeySource::KeySource(scoped_ptr encryption_key) : encryption_key_(encryption_key.Pass()) { DCHECK(encryption_key_); } } // namespace media } // namespace edash_packager