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:
parent
b270e9fe0c
commit
8336801ffc
24
README.md
24
README.md
|
@ -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()) { … }
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue