Skip to content

Commit

Permalink
Refactor WidevineKeySource to pass signer in setter instead
Browse files Browse the repository at this point in the history
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
  • Loading branch information
kqyang committed Oct 15, 2014
1 parent b270e9f commit 8336801
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 44 deletions.
22 changes: 12 additions & 10 deletions README.md
Expand Up @@ -93,13 +93,14 @@ Demuxer demuxer(input_media_file);
// Users may use WidevineKeySource to fetch keys from Widevine
// common encryption server.

// A request signer is required to sign the common encryption request.
scoped_ptr<WidevineKeySource> widevine_decryption_key_source(
new WidevineKeySource(key_server_url));

// A request signer might be required to sign the common encryption request.
scoped_ptr<RequestSigner> signer(
RsaRequestSigner::CreateSigner(signer, pkcs1_rsa_private_key));
RsaRequestSigner::CreateSigner(signer_name, pkcs1_rsa_private_key));
if (!signer) { … }

scoped_ptr<WidevineKeySource> widevine_decryption_key_source(
new WidevineKeySource(key_server_url, signer.Pass()));
widevine_decryption_key_source->set_signer(signer.Pass());

// Set encryption key source to demuxer.
muxer->SetKeySource(widevine_decryption_key_source.Pass());
Expand Down Expand Up @@ -234,14 +235,15 @@ muxer_options.bandwidth = 0;
// Users may use WidevineKeySource to fetch keys from Widevine
// 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(
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.
status = widevine_encryption_key_source->FetchKeys(content_id, policy));
if (!status.ok()) { … }
Expand Down
8 changes: 7 additions & 1 deletion packager/app/packager_main.cc
Expand Up @@ -127,7 +127,13 @@ bool CreateRemuxJobs(const StreamDescriptorList& stream_descriptors,
if (stream_iter->input != previous_input) {
// New remux job needed. Create demux and job thread.
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();
if (!status.ok()) {
LOG(ERROR) << "Demuxer failed to initialize: " << status.ToString();
Expand Down
35 changes: 23 additions & 12 deletions packager/app/packager_util.cc
Expand Up @@ -66,23 +66,27 @@ scoped_ptr<RequestSigner> CreateSigner() {
scoped_ptr<KeySource> CreateEncryptionKeySource() {
scoped_ptr<KeySource> encryption_key_source;
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;
if (!base::HexStringToBytes(FLAGS_content_id, &content_id)) {
LOG(ERROR) << "Invalid content_id hex string specified.";
return scoped_ptr<KeySource>();
}
scoped_ptr<WidevineKeySource> widevine_encryption_key_source(
new WidevineKeySource(FLAGS_key_server_url,
signer.Pass()));
Status status = widevine_encryption_key_source->FetchKeys(content_id,
FLAGS_policy);
Status status = widevine_key_source->FetchKeys(content_id, FLAGS_policy);
if (!status.ok()) {
LOG(ERROR) << "Widevine encryption key source failed to fetch keys: "
<< status.ToString();
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) {
encryption_key_source = KeySource::CreateFromHexStrings(
FLAGS_key_id, FLAGS_key, FLAGS_pssh, "");
Expand All @@ -93,12 +97,19 @@ scoped_ptr<KeySource> CreateEncryptionKeySource() {
scoped_ptr<KeySource> CreateDecryptionKeySource() {
scoped_ptr<KeySource> decryption_key_source;
if (FLAGS_enable_widevine_decryption) {
scoped_ptr<RequestSigner> signer(CreateSigner());
decryption_key_source.reset(new WidevineKeySource(FLAGS_key_server_url,
signer.Pass()));
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());
}

decryption_key_source = widevine_key_source.Pass();
} else if (FLAGS_enable_fixed_key_decryption) {
decryption_key_source = KeySource::CreateFromHexStrings(
FLAGS_key_id, FLAGS_key, "", "");
decryption_key_source =
KeySource::CreateFromHexStrings(FLAGS_key_id, FLAGS_key, "", "");
}
return decryption_key_source.Pass();
}
Expand Down
11 changes: 6 additions & 5 deletions packager/media/base/widevine_key_source.cc
Expand Up @@ -136,14 +136,12 @@ class WidevineKeySource::RefCountedEncryptionKeyMap
DISALLOW_COPY_AND_ASSIGN(RefCountedEncryptionKeyMap);
};

WidevineKeySource::WidevineKeySource(const std::string& server_url,
scoped_ptr<RequestSigner> signer)
WidevineKeySource::WidevineKeySource(const std::string& server_url)
: key_production_thread_("KeyProductionThread",
base::Bind(&WidevineKeySource::FetchKeysTask,
base::Unretained(this))),
key_fetcher_(new HttpKeyFetcher(kKeyFetchTimeoutInSeconds)),
server_url_(server_url),
signer_(signer.Pass()),
crypto_period_count_(kDefaultCryptoPeriodCount),
key_production_started_(false),
start_key_production_(false, false),
Expand Down Expand Up @@ -248,8 +246,11 @@ Status WidevineKeySource::GetCryptoPeriodKey(uint32_t crypto_period_index,
return GetKeyInternal(crypto_period_index, track_type, key);
}

void WidevineKeySource::set_key_fetcher(
scoped_ptr<KeyFetcher> key_fetcher) {
void WidevineKeySource::set_signer(scoped_ptr<RequestSigner> signer) {
signer_ = signer.Pass();
}

void WidevineKeySource::set_key_fetcher(scoped_ptr<KeyFetcher> key_fetcher) {
key_fetcher_ = key_fetcher.Pass();
}

Expand Down
8 changes: 5 additions & 3 deletions packager/media/base/widevine_key_source.h
Expand Up @@ -26,9 +26,7 @@ template <class T> class ProducerConsumerQueue;
class WidevineKeySource : public KeySource {
public:
/// @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,
scoped_ptr<RequestSigner> signer);
WidevineKeySource(const std::string& server_url);

virtual ~WidevineKeySource();

Expand All @@ -47,6 +45,10 @@ class WidevineKeySource : public KeySource {
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.
/// @param key_fetcher points to the @b KeyFetcher object to be injected.
void set_key_fetcher(scoped_ptr<KeyFetcher> key_fetcher);
Expand Down
31 changes: 18 additions & 13 deletions packager/media/base/widevine_key_source_unittest.cc
Expand Up @@ -156,9 +156,8 @@ class WidevineKeySourceTest : public ::testing::Test {
}

protected:
void CreateWidevineKeySource(scoped_ptr<RequestSigner> request_signer) {
widevine_key_source_.reset(
new WidevineKeySource(kServerUrl, request_signer.Pass()));
void CreateWidevineKeySource() {
widevine_key_source_.reset(new WidevineKeySource(kServerUrl));
widevine_key_source_->set_key_fetcher(
mock_key_fetcher_.PassAs<KeyFetcher>());
}
Expand Down Expand Up @@ -203,7 +202,9 @@ TEST_F(WidevineKeySourceTest, GenerateSignatureFailure) {
EXPECT_CALL(*mock_request_signer_, GenerateSignature(_, _))
.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."),
widevine_key_source_->FetchKeys(content_id_, kPolicy));
}
Expand All @@ -226,7 +227,9 @@ TEST_F(WidevineKeySourceTest, HttpFetchFailure) {
FetchKeys(StrEq(kServerUrl), expected_post_data, _))
.WillOnce(Return(kMockStatus));

CreateWidevineKeySource(mock_request_signer_.PassAs<RequestSigner>());
CreateWidevineKeySource();
widevine_key_source_->set_signer(
mock_request_signer_.PassAs<RequestSigner>());
ASSERT_EQ(kMockStatus,
widevine_key_source_->FetchKeys(content_id_, kPolicy));
}
Expand All @@ -238,7 +241,7 @@ TEST_F(WidevineKeySourceTest, LicenseStatusCencOK) {
EXPECT_CALL(*mock_key_fetcher_, FetchKeys(_, _, _))
.WillOnce(DoAll(SetArgPointee<2>(mock_response), Return(Status::OK)));

CreateWidevineKeySource(scoped_ptr<RequestSigner>());
CreateWidevineKeySource();
ASSERT_OK(widevine_key_source_->FetchKeys(content_id_, kPolicy));
VerifyKeys(false);
}
Expand All @@ -251,7 +254,7 @@ TEST_F(WidevineKeySourceTest, LicenseStatusCencNotOK) {
EXPECT_CALL(*mock_key_fetcher_, FetchKeys(_, _, _))
.WillOnce(DoAll(SetArgPointee<2>(mock_response), Return(Status::OK)));

CreateWidevineKeySource(scoped_ptr<RequestSigner>());
CreateWidevineKeySource();
ASSERT_EQ(error::SERVER_ERROR,
widevine_key_source_->FetchKeys(content_id_, kPolicy)
.error_code());
Expand All @@ -264,7 +267,7 @@ TEST_F(WidevineKeySourceTest, LicenseStatusCencWithPsshDataOK) {
EXPECT_CALL(*mock_key_fetcher_, FetchKeys(_, _, _))
.WillOnce(DoAll(SetArgPointee<2>(mock_response), Return(Status::OK)));

CreateWidevineKeySource(scoped_ptr<RequestSigner>());
CreateWidevineKeySource();
std::vector<uint8_t> pssh_data(
reinterpret_cast<const uint8_t*>(kRequestPsshData),
reinterpret_cast<const uint8_t*>(kRequestPsshData) + strlen(kContentId));
Expand All @@ -280,7 +283,7 @@ TEST_F(WidevineKeySourceTest, LicenseStatusClassicOK) {
EXPECT_CALL(*mock_key_fetcher_, FetchKeys(_, _, _))
.WillOnce(DoAll(SetArgPointee<2>(mock_response), Return(Status::OK)));

CreateWidevineKeySource(scoped_ptr<RequestSigner>());
CreateWidevineKeySource();
ASSERT_OK(widevine_key_source_->FetchKeys(kClassicAssetId));
VerifyKeys(true);
}
Expand All @@ -294,7 +297,7 @@ TEST_F(WidevineKeySourceTest, RetryOnHttpTimeout) {
.WillOnce(Return(Status(error::TIME_OUT, "")))
.WillOnce(DoAll(SetArgPointee<2>(mock_response), Return(Status::OK)));

CreateWidevineKeySource(scoped_ptr<RequestSigner>());
CreateWidevineKeySource();
ASSERT_OK(widevine_key_source_->FetchKeys(content_id_, kPolicy));
VerifyKeys(false);
}
Expand All @@ -314,7 +317,7 @@ TEST_F(WidevineKeySourceTest, RetryOnTransientError) {
.WillOnce(DoAll(SetArgPointee<2>(expected_retried_response),
Return(Status::OK)));

CreateWidevineKeySource(scoped_ptr<RequestSigner>());
CreateWidevineKeySource();
ASSERT_OK(widevine_key_source_->FetchKeys(content_id_, kPolicy));
VerifyKeys(false);
}
Expand All @@ -328,7 +331,7 @@ TEST_F(WidevineKeySourceTest, NoRetryOnUnknownError) {
EXPECT_CALL(*mock_key_fetcher_, FetchKeys(_, _, _))
.WillOnce(DoAll(SetArgPointee<2>(mock_response), Return(Status::OK)));

CreateWidevineKeySource(scoped_ptr<RequestSigner>());
CreateWidevineKeySource();
ASSERT_EQ(error::SERVER_ERROR,
widevine_key_source_->FetchKeys(content_id_, kPolicy).error_code());
}
Expand Down Expand Up @@ -413,7 +416,9 @@ TEST_F(WidevineKeySourceTest, KeyRotationTest) {
.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));

EncryptionKey encryption_key;
Expand Down

0 comments on commit 8336801

Please sign in to comment.