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 int GetProtectionSystemsFlag(
48  const std::vector<EncryptionParams::ProtectionSystem>& protection_systems) {
49  int protection_systems_flags = 0;
50  for (const auto protection_system : protection_systems) {
51  switch (protection_system) {
52  case EncryptionParams::ProtectionSystem::kCommonSystem:
53  protection_systems_flags |= COMMON_PROTECTION_SYSTEM_FLAG;
54  break;
55  case EncryptionParams::ProtectionSystem::kFairPlay:
56  protection_systems_flags |= FAIRPLAY_PROTECTION_SYSTEM_FLAG;
57  break;
58  case EncryptionParams::ProtectionSystem::kPlayReady:
59  protection_systems_flags |= PLAYREADY_PROTECTION_SYSTEM_FLAG;
60  break;
61  case EncryptionParams::ProtectionSystem::kWidevine:
62  protection_systems_flags |= WIDEVINE_PROTECTION_SYSTEM_FLAG;
63  break;
64  }
65  }
66  return protection_systems_flags;
67 }
68 
69 } // namespace
70 
71 std::unique_ptr<KeySource> CreateEncryptionKeySource(
72  FourCC protection_scheme,
73  const EncryptionParams& encryption_params) {
74  int protection_systems_flags =
75  GetProtectionSystemsFlag(encryption_params.protection_systems);
76 
77  std::unique_ptr<KeySource> encryption_key_source;
78  switch (encryption_params.key_provider) {
79  case KeyProvider::kWidevine: {
80  const WidevineEncryptionParams& widevine = encryption_params.widevine;
81  if (widevine.key_server_url.empty()) {
82  LOG(ERROR) << "'key_server_url' should not be empty.";
83  return nullptr;
84  }
85  if (widevine.content_id.empty()) {
86  LOG(ERROR) << "'content_id' should not be empty.";
87  return nullptr;
88  }
89  std::unique_ptr<WidevineKeySource> widevine_key_source(
90  new WidevineKeySource(widevine.key_server_url,
91  protection_systems_flags, protection_scheme));
92  if (!widevine.signer.signer_name.empty()) {
93  std::unique_ptr<RequestSigner> request_signer(
94  CreateSigner(widevine.signer));
95  if (!request_signer)
96  return nullptr;
97  widevine_key_source->set_signer(std::move(request_signer));
98  }
99  widevine_key_source->set_group_id(widevine.group_id);
100  widevine_key_source->set_enable_entitlement_license(
101  widevine.enable_entitlement_license);
102 
103  Status status =
104  widevine_key_source->FetchKeys(widevine.content_id, widevine.policy);
105  if (!status.ok()) {
106  LOG(ERROR) << "Widevine encryption key source failed to fetch keys: "
107  << status.ToString();
108  return nullptr;
109  }
110  encryption_key_source = std::move(widevine_key_source);
111  break;
112  }
113  case KeyProvider::kRawKey: {
114  encryption_key_source =
115  RawKeySource::Create(encryption_params.raw_key,
116  protection_systems_flags, protection_scheme);
117  break;
118  }
119  case KeyProvider::kPlayReady: {
120  const PlayReadyEncryptionParams& playready = encryption_params.playready;
121  if (!playready.key_server_url.empty() ||
122  !playready.program_identifier.empty()) {
123  if (playready.key_server_url.empty() ||
124  playready.program_identifier.empty()) {
125  LOG(ERROR) << "Either PlayReady key_server_url or program_identifier "
126  "is not set.";
127  return nullptr;
128  }
129  std::unique_ptr<PlayReadyKeySource> playready_key_source;
130  // private_key_password is allowed to be empty for unencrypted key.
131  if (!playready.client_cert_file.empty() ||
132  !playready.client_cert_private_key_file.empty()) {
133  if (playready.client_cert_file.empty() ||
134  playready.client_cert_private_key_file.empty()) {
135  LOG(ERROR) << "Either PlayReady client_cert_file or "
136  "client_cert_private_key_file is not set.";
137  return nullptr;
138  }
139  playready_key_source.reset(new PlayReadyKeySource(
140  playready.key_server_url, playready.client_cert_file,
141  playready.client_cert_private_key_file,
142  playready.client_cert_private_key_password,
143  protection_systems_flags, protection_scheme));
144  } else {
145  playready_key_source.reset(new PlayReadyKeySource(
146  playready.key_server_url, protection_systems_flags,
147  protection_scheme));
148  }
149  if (!playready.ca_file.empty()) {
150  playready_key_source->SetCaFile(playready.ca_file);
151  }
152  Status status = playready_key_source->FetchKeysWithProgramIdentifier(
153  playready.program_identifier);
154  if (!status.ok()) {
155  LOG(ERROR) << "PlayReady encryption key source failed to fetch keys: "
156  << status.ToString();
157  return nullptr;
158  }
159  encryption_key_source = std::move(playready_key_source);
160  } else {
161  LOG(ERROR) << "Error creating PlayReady key source.";
162  return nullptr;
163  }
164  break;
165  }
166  case KeyProvider::kNone:
167  break;
168  }
169  return encryption_key_source;
170 }
171 
172 std::unique_ptr<KeySource> CreateDecryptionKeySource(
173  const DecryptionParams& decryption_params) {
174  std::unique_ptr<KeySource> decryption_key_source;
175  switch (decryption_params.key_provider) {
176  case KeyProvider::kWidevine: {
177  const WidevineDecryptionParams& widevine = decryption_params.widevine;
178  if (widevine.key_server_url.empty()) {
179  LOG(ERROR) << "'key_server_url' should not be empty.";
180  return std::unique_ptr<KeySource>();
181  }
182  std::unique_ptr<WidevineKeySource> widevine_key_source(
183  new WidevineKeySource(
184  widevine.key_server_url,
185  WIDEVINE_PROTECTION_SYSTEM_FLAG /* value does not matter here */,
186  FOURCC_NULL /* value does not matter here */));
187  if (!widevine.signer.signer_name.empty()) {
188  std::unique_ptr<RequestSigner> request_signer(
189  CreateSigner(widevine.signer));
190  if (!request_signer)
191  return std::unique_ptr<KeySource>();
192  widevine_key_source->set_signer(std::move(request_signer));
193  }
194 
195  decryption_key_source = std::move(widevine_key_source);
196  break;
197  }
198  case KeyProvider::kRawKey: {
199  decryption_key_source = RawKeySource::Create(
200  decryption_params.raw_key,
201  COMMON_PROTECTION_SYSTEM_FLAG /* value does not matter here */,
202  FOURCC_NULL /* value does not matter here */);
203  break;
204  }
205  case KeyProvider::kNone:
206  case KeyProvider::kPlayReady:
207  break;
208  }
209  return decryption_key_source;
210 }
211 
212 MpdOptions GetMpdOptions(bool on_demand_profile,
213  const MpdParams& mpd_params,
214  double target_segment_duration) {
215  MpdOptions mpd_options;
216  mpd_options.dash_profile =
217  on_demand_profile ? DashProfile::kOnDemand : DashProfile::kLive;
218  mpd_options.mpd_type =
219  (on_demand_profile || mpd_params.generate_static_live_mpd)
220  ? MpdType::kStatic
221  : MpdType::kDynamic;
222  mpd_options.mpd_params = mpd_params;
223  mpd_options.target_segment_duration = target_segment_duration;
224  return mpd_options;
225 }
226 
227 } // namespace media
228 } // namespace shaka
static RsaRequestSigner * CreateSigner(const std::string &signer_name, const std::string &pkcs1_rsa_key)
std::string ToString() const
Definition: status.cc:81
static std::unique_ptr< RawKeySource > Create(const RawKeyParams &raw_key, int protection_system_flags, FourCC protection_scheme)
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.