Refactor WidevineKeySource to pass signer in setter instead

Since signer is now optional, it makes more sense to pass it in setter
function.

Also fix a problem in command line that if a signer or key source is
not specified correctly, the program should return immediately.

Change-Id: I3be6a4e2ba7bf7b8d5589ac8268390a0fe08a626
This commit is contained in:
KongQun Yang 2014-10-14 17:47:25 -07:00
parent b270e9fe0c
commit 8336801ffc
6 changed files with 72 additions and 45 deletions

View File

@ -93,13 +93,14 @@ Demuxer demuxer(input_media_file);
// Users may use WidevineKeySource to fetch keys from Widevine // Users may use WidevineKeySource to fetch keys from Widevine
// common encryption server. // common encryption server.
// A request signer is required to sign the common encryption request.
scoped_ptr<RequestSigner> signer(
RsaRequestSigner::CreateSigner(signer, pkcs1_rsa_private_key));
if (!signer) { … }
scoped_ptr<WidevineKeySource> widevine_decryption_key_source( scoped_ptr<WidevineKeySource> widevine_decryption_key_source(
new WidevineKeySource(key_server_url, signer.Pass())); new WidevineKeySource(key_server_url));
// A request signer might be required to sign the common encryption request.
scoped_ptr<RequestSigner> signer(
RsaRequestSigner::CreateSigner(signer_name, pkcs1_rsa_private_key));
if (!signer) { … }
widevine_decryption_key_source->set_signer(signer.Pass());
// Set encryption key source to demuxer. // Set encryption key source to demuxer.
muxer->SetKeySource(widevine_decryption_key_source.Pass()); muxer->SetKeySource(widevine_decryption_key_source.Pass());
@ -234,14 +235,15 @@ muxer_options.bandwidth = 0;
// Users may use WidevineKeySource to fetch keys from Widevine // Users may use WidevineKeySource to fetch keys from Widevine
// common encryption server. // common encryption server.
// A request signer is required to sign the common encryption request.
scoped_ptr<RequestSigner> signer(
RsaRequestSigner::CreateSigner(signer, pkcs1_rsa_private_key));
if (!signer) { … }
scoped_ptr<WidevineKeySource> widevine_encryption_key_source( scoped_ptr<WidevineKeySource> widevine_encryption_key_source(
new WidevineKeySource(key_server_url, signer.Pass())); new WidevineKeySource(key_server_url, signer.Pass()));
// A request signer might be required to sign the common encryption request.
scoped_ptr<RequestSigner> signer(
RsaRequestSigner::CreateSigner(signer_name, pkcs1_rsa_private_key));
if (!signer) { … }
widevine_encryption_key_source->set_signer(signer.Pass());
// Grab keys for the content. // Grab keys for the content.
status = widevine_encryption_key_source->FetchKeys(content_id, policy)); status = widevine_encryption_key_source->FetchKeys(content_id, policy));
if (!status.ok()) { … } if (!status.ok()) { … }

View File

@ -127,7 +127,13 @@ bool CreateRemuxJobs(const StreamDescriptorList& stream_descriptors,
if (stream_iter->input != previous_input) { if (stream_iter->input != previous_input) {
// New remux job needed. Create demux and job thread. // New remux job needed. Create demux and job thread.
scoped_ptr<Demuxer> demuxer(new Demuxer(stream_iter->input)); scoped_ptr<Demuxer> demuxer(new Demuxer(stream_iter->input));
demuxer->SetKeySource(CreateDecryptionKeySource()); if (FLAGS_enable_widevine_decryption ||
FLAGS_enable_fixed_key_decryption) {
scoped_ptr<KeySource> key_source(CreateDecryptionKeySource());
if (!key_source)
return false;
demuxer->SetKeySource(key_source.Pass());
}
Status status = demuxer->Initialize(); Status status = demuxer->Initialize();
if (!status.ok()) { if (!status.ok()) {
LOG(ERROR) << "Demuxer failed to initialize: " << status.ToString(); LOG(ERROR) << "Demuxer failed to initialize: " << status.ToString();

View File

@ -66,23 +66,27 @@ scoped_ptr<RequestSigner> CreateSigner() {
scoped_ptr<KeySource> CreateEncryptionKeySource() { scoped_ptr<KeySource> CreateEncryptionKeySource() {
scoped_ptr<KeySource> encryption_key_source; scoped_ptr<KeySource> encryption_key_source;
if (FLAGS_enable_widevine_encryption) { if (FLAGS_enable_widevine_encryption) {
scoped_ptr<RequestSigner> signer(CreateSigner()); scoped_ptr<WidevineKeySource> widevine_key_source(
new WidevineKeySource(FLAGS_key_server_url));
if (!FLAGS_signer.empty()) {
scoped_ptr<RequestSigner> request_signer(CreateSigner());
if (!request_signer)
return scoped_ptr<KeySource>();
widevine_key_source->set_signer(request_signer.Pass());
}
std::vector<uint8_t> content_id; std::vector<uint8_t> content_id;
if (!base::HexStringToBytes(FLAGS_content_id, &content_id)) { if (!base::HexStringToBytes(FLAGS_content_id, &content_id)) {
LOG(ERROR) << "Invalid content_id hex string specified."; LOG(ERROR) << "Invalid content_id hex string specified.";
return scoped_ptr<KeySource>(); return scoped_ptr<KeySource>();
} }
scoped_ptr<WidevineKeySource> widevine_encryption_key_source( Status status = widevine_key_source->FetchKeys(content_id, FLAGS_policy);
new WidevineKeySource(FLAGS_key_server_url,
signer.Pass()));
Status status = widevine_encryption_key_source->FetchKeys(content_id,
FLAGS_policy);
if (!status.ok()) { if (!status.ok()) {
LOG(ERROR) << "Widevine encryption key source failed to fetch keys: " LOG(ERROR) << "Widevine encryption key source failed to fetch keys: "
<< status.ToString(); << status.ToString();
return scoped_ptr<KeySource>(); return scoped_ptr<KeySource>();
} }
encryption_key_source = widevine_encryption_key_source.Pass(); encryption_key_source = widevine_key_source.Pass();
} else if (FLAGS_enable_fixed_key_encryption) { } else if (FLAGS_enable_fixed_key_encryption) {
encryption_key_source = KeySource::CreateFromHexStrings( encryption_key_source = KeySource::CreateFromHexStrings(
FLAGS_key_id, FLAGS_key, FLAGS_pssh, ""); FLAGS_key_id, FLAGS_key, FLAGS_pssh, "");
@ -93,12 +97,19 @@ scoped_ptr<KeySource> CreateEncryptionKeySource() {
scoped_ptr<KeySource> CreateDecryptionKeySource() { scoped_ptr<KeySource> CreateDecryptionKeySource() {
scoped_ptr<KeySource> decryption_key_source; scoped_ptr<KeySource> decryption_key_source;
if (FLAGS_enable_widevine_decryption) { if (FLAGS_enable_widevine_decryption) {
scoped_ptr<RequestSigner> signer(CreateSigner()); scoped_ptr<WidevineKeySource> widevine_key_source(
decryption_key_source.reset(new WidevineKeySource(FLAGS_key_server_url, new WidevineKeySource(FLAGS_key_server_url));
signer.Pass())); if (!FLAGS_signer.empty()) {
scoped_ptr<RequestSigner> request_signer(CreateSigner());
if (!request_signer)
return scoped_ptr<KeySource>();
widevine_key_source->set_signer(request_signer.Pass());
}
decryption_key_source = widevine_key_source.Pass();
} else if (FLAGS_enable_fixed_key_decryption) { } else if (FLAGS_enable_fixed_key_decryption) {
decryption_key_source = KeySource::CreateFromHexStrings( decryption_key_source =
FLAGS_key_id, FLAGS_key, "", ""); KeySource::CreateFromHexStrings(FLAGS_key_id, FLAGS_key, "", "");
} }
return decryption_key_source.Pass(); return decryption_key_source.Pass();
} }

View File

@ -136,14 +136,12 @@ class WidevineKeySource::RefCountedEncryptionKeyMap
DISALLOW_COPY_AND_ASSIGN(RefCountedEncryptionKeyMap); DISALLOW_COPY_AND_ASSIGN(RefCountedEncryptionKeyMap);
}; };
WidevineKeySource::WidevineKeySource(const std::string& server_url, WidevineKeySource::WidevineKeySource(const std::string& server_url)
scoped_ptr<RequestSigner> signer)
: key_production_thread_("KeyProductionThread", : key_production_thread_("KeyProductionThread",
base::Bind(&WidevineKeySource::FetchKeysTask, base::Bind(&WidevineKeySource::FetchKeysTask,
base::Unretained(this))), base::Unretained(this))),
key_fetcher_(new HttpKeyFetcher(kKeyFetchTimeoutInSeconds)), key_fetcher_(new HttpKeyFetcher(kKeyFetchTimeoutInSeconds)),
server_url_(server_url), server_url_(server_url),
signer_(signer.Pass()),
crypto_period_count_(kDefaultCryptoPeriodCount), crypto_period_count_(kDefaultCryptoPeriodCount),
key_production_started_(false), key_production_started_(false),
start_key_production_(false, false), start_key_production_(false, false),
@ -248,8 +246,11 @@ Status WidevineKeySource::GetCryptoPeriodKey(uint32_t crypto_period_index,
return GetKeyInternal(crypto_period_index, track_type, key); return GetKeyInternal(crypto_period_index, track_type, key);
} }
void WidevineKeySource::set_key_fetcher( void WidevineKeySource::set_signer(scoped_ptr<RequestSigner> signer) {
scoped_ptr<KeyFetcher> key_fetcher) { signer_ = signer.Pass();
}
void WidevineKeySource::set_key_fetcher(scoped_ptr<KeyFetcher> key_fetcher) {
key_fetcher_ = key_fetcher.Pass(); key_fetcher_ = key_fetcher.Pass();
} }

View File

@ -26,9 +26,7 @@ template <class T> class ProducerConsumerQueue;
class WidevineKeySource : public KeySource { class WidevineKeySource : public KeySource {
public: public:
/// @param server_url is the Widevine common encryption server url. /// @param server_url is the Widevine common encryption server url.
/// @param signer signs the request message. Can be NULL. WidevineKeySource(const std::string& server_url);
WidevineKeySource(const std::string& server_url,
scoped_ptr<RequestSigner> signer);
virtual ~WidevineKeySource(); virtual ~WidevineKeySource();
@ -47,6 +45,10 @@ class WidevineKeySource : public KeySource {
EncryptionKey* key) OVERRIDE; EncryptionKey* key) OVERRIDE;
/// @} /// @}
/// Set signer for the key source.
/// @param signer signs the request message.
void set_signer(scoped_ptr<RequestSigner> signer);
/// Inject an @b KeyFetcher object, mainly used for testing. /// Inject an @b KeyFetcher object, mainly used for testing.
/// @param key_fetcher points to the @b KeyFetcher object to be injected. /// @param key_fetcher points to the @b KeyFetcher object to be injected.
void set_key_fetcher(scoped_ptr<KeyFetcher> key_fetcher); void set_key_fetcher(scoped_ptr<KeyFetcher> key_fetcher);

View File

@ -156,9 +156,8 @@ class WidevineKeySourceTest : public ::testing::Test {
} }
protected: protected:
void CreateWidevineKeySource(scoped_ptr<RequestSigner> request_signer) { void CreateWidevineKeySource() {
widevine_key_source_.reset( widevine_key_source_.reset(new WidevineKeySource(kServerUrl));
new WidevineKeySource(kServerUrl, request_signer.Pass()));
widevine_key_source_->set_key_fetcher( widevine_key_source_->set_key_fetcher(
mock_key_fetcher_.PassAs<KeyFetcher>()); mock_key_fetcher_.PassAs<KeyFetcher>());
} }
@ -203,7 +202,9 @@ TEST_F(WidevineKeySourceTest, GenerateSignatureFailure) {
EXPECT_CALL(*mock_request_signer_, GenerateSignature(_, _)) EXPECT_CALL(*mock_request_signer_, GenerateSignature(_, _))
.WillOnce(Return(false)); .WillOnce(Return(false));
CreateWidevineKeySource(mock_request_signer_.PassAs<RequestSigner>()); CreateWidevineKeySource();
widevine_key_source_->set_signer(
mock_request_signer_.PassAs<RequestSigner>());
ASSERT_EQ(Status(error::INTERNAL_ERROR, "Signature generation failed."), ASSERT_EQ(Status(error::INTERNAL_ERROR, "Signature generation failed."),
widevine_key_source_->FetchKeys(content_id_, kPolicy)); widevine_key_source_->FetchKeys(content_id_, kPolicy));
} }
@ -226,7 +227,9 @@ TEST_F(WidevineKeySourceTest, HttpFetchFailure) {
FetchKeys(StrEq(kServerUrl), expected_post_data, _)) FetchKeys(StrEq(kServerUrl), expected_post_data, _))
.WillOnce(Return(kMockStatus)); .WillOnce(Return(kMockStatus));
CreateWidevineKeySource(mock_request_signer_.PassAs<RequestSigner>()); CreateWidevineKeySource();
widevine_key_source_->set_signer(
mock_request_signer_.PassAs<RequestSigner>());
ASSERT_EQ(kMockStatus, ASSERT_EQ(kMockStatus,
widevine_key_source_->FetchKeys(content_id_, kPolicy)); widevine_key_source_->FetchKeys(content_id_, kPolicy));
} }
@ -238,7 +241,7 @@ TEST_F(WidevineKeySourceTest, LicenseStatusCencOK) {
EXPECT_CALL(*mock_key_fetcher_, FetchKeys(_, _, _)) EXPECT_CALL(*mock_key_fetcher_, FetchKeys(_, _, _))
.WillOnce(DoAll(SetArgPointee<2>(mock_response), Return(Status::OK))); .WillOnce(DoAll(SetArgPointee<2>(mock_response), Return(Status::OK)));
CreateWidevineKeySource(scoped_ptr<RequestSigner>()); CreateWidevineKeySource();
ASSERT_OK(widevine_key_source_->FetchKeys(content_id_, kPolicy)); ASSERT_OK(widevine_key_source_->FetchKeys(content_id_, kPolicy));
VerifyKeys(false); VerifyKeys(false);
} }
@ -251,7 +254,7 @@ TEST_F(WidevineKeySourceTest, LicenseStatusCencNotOK) {
EXPECT_CALL(*mock_key_fetcher_, FetchKeys(_, _, _)) EXPECT_CALL(*mock_key_fetcher_, FetchKeys(_, _, _))
.WillOnce(DoAll(SetArgPointee<2>(mock_response), Return(Status::OK))); .WillOnce(DoAll(SetArgPointee<2>(mock_response), Return(Status::OK)));
CreateWidevineKeySource(scoped_ptr<RequestSigner>()); CreateWidevineKeySource();
ASSERT_EQ(error::SERVER_ERROR, ASSERT_EQ(error::SERVER_ERROR,
widevine_key_source_->FetchKeys(content_id_, kPolicy) widevine_key_source_->FetchKeys(content_id_, kPolicy)
.error_code()); .error_code());
@ -264,7 +267,7 @@ TEST_F(WidevineKeySourceTest, LicenseStatusCencWithPsshDataOK) {
EXPECT_CALL(*mock_key_fetcher_, FetchKeys(_, _, _)) EXPECT_CALL(*mock_key_fetcher_, FetchKeys(_, _, _))
.WillOnce(DoAll(SetArgPointee<2>(mock_response), Return(Status::OK))); .WillOnce(DoAll(SetArgPointee<2>(mock_response), Return(Status::OK)));
CreateWidevineKeySource(scoped_ptr<RequestSigner>()); CreateWidevineKeySource();
std::vector<uint8_t> pssh_data( std::vector<uint8_t> pssh_data(
reinterpret_cast<const uint8_t*>(kRequestPsshData), reinterpret_cast<const uint8_t*>(kRequestPsshData),
reinterpret_cast<const uint8_t*>(kRequestPsshData) + strlen(kContentId)); reinterpret_cast<const uint8_t*>(kRequestPsshData) + strlen(kContentId));
@ -280,7 +283,7 @@ TEST_F(WidevineKeySourceTest, LicenseStatusClassicOK) {
EXPECT_CALL(*mock_key_fetcher_, FetchKeys(_, _, _)) EXPECT_CALL(*mock_key_fetcher_, FetchKeys(_, _, _))
.WillOnce(DoAll(SetArgPointee<2>(mock_response), Return(Status::OK))); .WillOnce(DoAll(SetArgPointee<2>(mock_response), Return(Status::OK)));
CreateWidevineKeySource(scoped_ptr<RequestSigner>()); CreateWidevineKeySource();
ASSERT_OK(widevine_key_source_->FetchKeys(kClassicAssetId)); ASSERT_OK(widevine_key_source_->FetchKeys(kClassicAssetId));
VerifyKeys(true); VerifyKeys(true);
} }
@ -294,7 +297,7 @@ TEST_F(WidevineKeySourceTest, RetryOnHttpTimeout) {
.WillOnce(Return(Status(error::TIME_OUT, ""))) .WillOnce(Return(Status(error::TIME_OUT, "")))
.WillOnce(DoAll(SetArgPointee<2>(mock_response), Return(Status::OK))); .WillOnce(DoAll(SetArgPointee<2>(mock_response), Return(Status::OK)));
CreateWidevineKeySource(scoped_ptr<RequestSigner>()); CreateWidevineKeySource();
ASSERT_OK(widevine_key_source_->FetchKeys(content_id_, kPolicy)); ASSERT_OK(widevine_key_source_->FetchKeys(content_id_, kPolicy));
VerifyKeys(false); VerifyKeys(false);
} }
@ -314,7 +317,7 @@ TEST_F(WidevineKeySourceTest, RetryOnTransientError) {
.WillOnce(DoAll(SetArgPointee<2>(expected_retried_response), .WillOnce(DoAll(SetArgPointee<2>(expected_retried_response),
Return(Status::OK))); Return(Status::OK)));
CreateWidevineKeySource(scoped_ptr<RequestSigner>()); CreateWidevineKeySource();
ASSERT_OK(widevine_key_source_->FetchKeys(content_id_, kPolicy)); ASSERT_OK(widevine_key_source_->FetchKeys(content_id_, kPolicy));
VerifyKeys(false); VerifyKeys(false);
} }
@ -328,7 +331,7 @@ TEST_F(WidevineKeySourceTest, NoRetryOnUnknownError) {
EXPECT_CALL(*mock_key_fetcher_, FetchKeys(_, _, _)) EXPECT_CALL(*mock_key_fetcher_, FetchKeys(_, _, _))
.WillOnce(DoAll(SetArgPointee<2>(mock_response), Return(Status::OK))); .WillOnce(DoAll(SetArgPointee<2>(mock_response), Return(Status::OK)));
CreateWidevineKeySource(scoped_ptr<RequestSigner>()); CreateWidevineKeySource();
ASSERT_EQ(error::SERVER_ERROR, ASSERT_EQ(error::SERVER_ERROR,
widevine_key_source_->FetchKeys(content_id_, kPolicy).error_code()); widevine_key_source_->FetchKeys(content_id_, kPolicy).error_code());
} }
@ -413,7 +416,9 @@ TEST_F(WidevineKeySourceTest, KeyRotationTest) {
.WillOnce(DoAll(SetArgPointee<2>(mock_response), Return(Status::OK))); .WillOnce(DoAll(SetArgPointee<2>(mock_response), Return(Status::OK)));
} }
CreateWidevineKeySource(mock_request_signer_.PassAs<RequestSigner>()); CreateWidevineKeySource();
widevine_key_source_->set_signer(
mock_request_signer_.PassAs<RequestSigner>());
ASSERT_OK(widevine_key_source_->FetchKeys(content_id_, kPolicy)); ASSERT_OK(widevine_key_source_->FetchKeys(content_id_, kPolicy));
EncryptionKey encryption_key; EncryptionKey encryption_key;