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
// 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(
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.
muxer->SetKeySource(widevine_decryption_key_source.Pass());
@ -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()) { … }

View File

@ -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();

View File

@ -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, "");
@ -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();
}

View File

@ -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),
@ -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();
}

View File

@ -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();
@ -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);

View File

@ -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>());
}
@ -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));
}
@ -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));
}
@ -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);
}
@ -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());
@ -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));
@ -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);
}
@ -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);
}
@ -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);
}
@ -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());
}
@ -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;