Shaka Packager SDK
packager_util.cc
1 // Copyright 2014 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/app/packager_util.h"
8 
9 #include "packager/base/logging.h"
10 #include "packager/base/strings/string_number_conversions.h"
11 #include "packager/base/strings/string_split.h"
12 #include "packager/file/file.h"
13 #include "packager/media/base/media_handler.h"
14 #include "packager/media/base/muxer_options.h"
15 #include "packager/media/base/playready_key_source.h"
16 #include "packager/media/base/raw_key_source.h"
17 #include "packager/media/base/request_signer.h"
18 #include "packager/media/base/widevine_key_source.h"
19 #include "packager/media/chunking/chunking_handler.h"
20 #include "packager/media/crypto/encryption_handler.h"
21 #include "packager/mpd/base/mpd_options.h"
22 #include "packager/status.h"
23 
24 namespace shaka {
25 namespace media {
26 namespace {
27 
28 std::unique_ptr<RequestSigner> CreateSigner(const WidevineSigner& signer) {
29  std::unique_ptr<RequestSigner> request_signer;
30  switch (signer.signing_key_type) {
31  case WidevineSigner::SigningKeyType::kAes:
32  request_signer.reset(AesRequestSigner::CreateSigner(
33  signer.signer_name, signer.aes.key, signer.aes.iv));
34  break;
35  case WidevineSigner::SigningKeyType::kRsa:
36  request_signer.reset(
37  RsaRequestSigner::CreateSigner(signer.signer_name, signer.rsa.key));
38  break;
39  case WidevineSigner::SigningKeyType::kNone:
40  break;
41  }
42  if (!request_signer)
43  LOG(ERROR) << "Failed to create the signer object.";
44  return request_signer;
45 }
46 
47 } // namespace
48 
49 std::unique_ptr<KeySource> CreateEncryptionKeySource(
50  FourCC protection_scheme,
51  const EncryptionParams& encryption_params) {
52  int protection_systems_flags(0);
53  if (encryption_params.generate_common_pssh)
54  protection_systems_flags |= COMMON_PROTECTION_SYSTEM_FLAG;
55  if (encryption_params.generate_playready_pssh)
56  protection_systems_flags |= PLAYREADY_PROTECTION_SYSTEM_FLAG;
57  if (encryption_params.generate_widevine_pssh)
58  protection_systems_flags |= WIDEVINE_PROTECTION_SYSTEM_FLAG;
59 
60  std::unique_ptr<KeySource> encryption_key_source;
61  switch (encryption_params.key_provider) {
62  case KeyProvider::kWidevine: {
63  const WidevineEncryptionParams& widevine = encryption_params.widevine;
64  if (widevine.key_server_url.empty()) {
65  LOG(ERROR) << "'key_server_url' should not be empty.";
66  return nullptr;
67  }
68  if (widevine.content_id.empty()) {
69  LOG(ERROR) << "'content_id' should not be empty.";
70  return nullptr;
71  }
72  std::unique_ptr<WidevineKeySource> widevine_key_source(
73  new WidevineKeySource(widevine.key_server_url,
74  protection_systems_flags));
75  widevine_key_source->set_protection_scheme(protection_scheme);
76  if (!widevine.signer.signer_name.empty()) {
77  std::unique_ptr<RequestSigner> request_signer(
78  CreateSigner(widevine.signer));
79  if (!request_signer)
80  return nullptr;
81  widevine_key_source->set_signer(std::move(request_signer));
82  }
83  widevine_key_source->set_group_id(widevine.group_id);
84  widevine_key_source->set_enable_entitlement_license(
85  widevine.enable_entitlement_license);
86 
87  Status status =
88  widevine_key_source->FetchKeys(widevine.content_id, widevine.policy);
89  if (!status.ok()) {
90  LOG(ERROR) << "Widevine encryption key source failed to fetch keys: "
91  << status.ToString();
92  return nullptr;
93  }
94  encryption_key_source = std::move(widevine_key_source);
95  break;
96  }
97  case KeyProvider::kRawKey: {
98  encryption_key_source = RawKeySource::Create(encryption_params.raw_key,
99  protection_systems_flags);
100  break;
101  }
102  case KeyProvider::kPlayReady: {
103  const PlayReadyEncryptionParams& playready = encryption_params.playready;
104  if (!playready.key_server_url.empty() ||
105  !playready.program_identifier.empty()) {
106  if (playready.key_server_url.empty() ||
107  playready.program_identifier.empty()) {
108  LOG(ERROR) << "Either playready key_server_url or program_identifier "
109  "is not set.";
110  return nullptr;
111  }
112  std::unique_ptr<PlayReadyKeySource> playready_key_source;
113  // private_key_password is allowed to be empty for unencrypted key.
114  if (!playready.client_cert_file.empty() ||
115  !playready.client_cert_private_key_file.empty()) {
116  if (playready.client_cert_file.empty() ||
117  playready.client_cert_private_key_file.empty()) {
118  LOG(ERROR) << "Either playready client_cert_file or "
119  "client_cert_private_key_file is not set.";
120  return nullptr;
121  }
122  playready_key_source.reset(new PlayReadyKeySource(
123  playready.key_server_url, playready.client_cert_file,
124  playready.client_cert_private_key_file,
125  playready.client_cert_private_key_password,
126  protection_systems_flags));
127  } else {
128  playready_key_source.reset(new PlayReadyKeySource(
129  playready.key_server_url, protection_systems_flags));
130  }
131  if (!playready.ca_file.empty()) {
132  playready_key_source->SetCaFile(playready.ca_file);
133  }
134  playready_key_source->FetchKeysWithProgramIdentifier(
135  playready.program_identifier);
136  encryption_key_source = std::move(playready_key_source);
137  } else {
138  LOG(ERROR) << "Error creating PlayReady key source.";
139  return nullptr;
140  }
141  break;
142  }
143  case KeyProvider::kNone:
144  break;
145  }
146  return encryption_key_source;
147 }
148 
149 std::unique_ptr<KeySource> CreateDecryptionKeySource(
150  const DecryptionParams& decryption_params) {
151  std::unique_ptr<KeySource> decryption_key_source;
152  switch (decryption_params.key_provider) {
153  case KeyProvider::kWidevine: {
154  const WidevineDecryptionParams& widevine = decryption_params.widevine;
155  if (widevine.key_server_url.empty()) {
156  LOG(ERROR) << "'key_server_url' should not be empty.";
157  return std::unique_ptr<KeySource>();
158  }
159  std::unique_ptr<WidevineKeySource> widevine_key_source(new WidevineKeySource(
160  widevine.key_server_url,
161  WIDEVINE_PROTECTION_SYSTEM_FLAG /* value does not matter here */));
162  if (!widevine.signer.signer_name.empty()) {
163  std::unique_ptr<RequestSigner> request_signer(
164  CreateSigner(widevine.signer));
165  if (!request_signer)
166  return std::unique_ptr<KeySource>();
167  widevine_key_source->set_signer(std::move(request_signer));
168  }
169 
170  decryption_key_source = std::move(widevine_key_source);
171  break;
172  }
173  case KeyProvider::kRawKey: {
174  decryption_key_source = RawKeySource::Create(
175  decryption_params.raw_key,
176  COMMON_PROTECTION_SYSTEM_FLAG /* value does not matter here*/);
177  break;
178  }
179  case KeyProvider::kNone:
180  case KeyProvider::kPlayReady:
181  break;
182  }
183  return decryption_key_source;
184 }
185 
186 MpdOptions GetMpdOptions(bool on_demand_profile,
187  const MpdParams& mpd_params,
188  double target_segment_duration) {
189  MpdOptions mpd_options;
190  mpd_options.dash_profile =
191  on_demand_profile ? DashProfile::kOnDemand : DashProfile::kLive;
192  mpd_options.mpd_type =
193  (on_demand_profile || mpd_params.generate_static_live_mpd)
194  ? MpdType::kStatic
195  : MpdType::kDynamic;
196  mpd_options.mpd_params = mpd_params;
197  mpd_options.target_segment_duration = target_segment_duration;
198  return mpd_options;
199 }
200 
201 } // namespace media
202 } // namespace shaka
static RsaRequestSigner * CreateSigner(const std::string &signer_name, const std::string &pkcs1_rsa_key)
static AesRequestSigner * CreateSigner(const std::string &signer_name, const std::vector< uint8_t > &aes_key, const std::vector< uint8_t > &iv)
All the methods that are virtual are virtual for mocking.
void SetCaFile(const std::string &ca_file)
Sets the Certificate Authority file for validating self-signed certificates.
static std::unique_ptr< RawKeySource > Create(const RawKeyParams &raw_key, int protection_system_flags)