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  std::unique_ptr<KeySource> encryption_key_source;
53  switch (encryption_params.key_provider) {
54  case KeyProvider::kWidevine: {
55  const WidevineEncryptionParams& widevine = encryption_params.widevine;
56  if (widevine.key_server_url.empty()) {
57  LOG(ERROR) << "'key_server_url' should not be empty.";
58  return nullptr;
59  }
60  if (widevine.content_id.empty()) {
61  LOG(ERROR) << "'content_id' should not be empty.";
62  return nullptr;
63  }
64  std::unique_ptr<WidevineKeySource> widevine_key_source(
65  new WidevineKeySource(widevine.key_server_url,
66  widevine.include_common_pssh));
67  widevine_key_source->set_protection_scheme(protection_scheme);
68  if (!widevine.signer.signer_name.empty()) {
69  std::unique_ptr<RequestSigner> request_signer(
70  CreateSigner(widevine.signer));
71  if (!request_signer)
72  return nullptr;
73  widevine_key_source->set_signer(std::move(request_signer));
74  }
75  widevine_key_source->set_group_id(widevine.group_id);
76 
77  Status status =
78  widevine_key_source->FetchKeys(widevine.content_id, widevine.policy);
79  if (!status.ok()) {
80  LOG(ERROR) << "Widevine encryption key source failed to fetch keys: "
81  << status.ToString();
82  return nullptr;
83  }
84  encryption_key_source = std::move(widevine_key_source);
85  break;
86  }
87  case KeyProvider::kRawKey: {
88  encryption_key_source = RawKeySource::Create(encryption_params.raw_key);
89  break;
90  }
91  case KeyProvider::kPlayready: {
92  const PlayreadyEncryptionParams& playready = encryption_params.playready;
93  if (!playready.key_id.empty() || !playready.key.empty()) {
94  if (playready.key_id.empty() || playready.key.empty()) {
95  LOG(ERROR) << "Either playready key_id or key is not set.";
96  return nullptr;
97  }
98  encryption_key_source = PlayReadyKeySource::CreateFromKeyAndKeyId(
99  playready.key_id, playready.key);
100  } else if (!playready.key_server_url.empty() ||
101  !playready.program_identifier.empty()) {
102  if (playready.key_server_url.empty() ||
103  playready.program_identifier.empty()) {
104  LOG(ERROR) << "Either playready key_server_url or program_identifier "
105  "is not set.";
106  return nullptr;
107  }
108  std::unique_ptr<PlayReadyKeySource> playready_key_source;
109  // private_key_password is allowed to be empty for unencrypted key.
110  if (!playready.client_cert_file.empty() ||
111  !playready.client_cert_private_key_file.empty()) {
112  if (playready.client_cert_file.empty() ||
113  playready.client_cert_private_key_file.empty()) {
114  LOG(ERROR) << "Either playready client_cert_file or "
115  "client_cert_private_key_file is not set.";
116  return nullptr;
117  }
118  playready_key_source.reset(new PlayReadyKeySource(
119  playready.key_server_url, playready.client_cert_file,
120  playready.client_cert_private_key_file,
121  playready.client_cert_private_key_password));
122  } else {
123  playready_key_source.reset(
124  new PlayReadyKeySource(playready.key_server_url));
125  }
126  if (!playready.ca_file.empty()) {
127  playready_key_source->SetCaFile(playready.ca_file);
128  }
129  playready_key_source->FetchKeysWithProgramIdentifier(
130  playready.program_identifier);
131  encryption_key_source = std::move(playready_key_source);
132  } else {
133  LOG(ERROR) << "Error creating PlayReady key source.";
134  return nullptr;
135  }
136  break;
137  }
138  case KeyProvider::kNone:
139  break;
140  }
141  return encryption_key_source;
142 }
143 
144 std::unique_ptr<KeySource> CreateDecryptionKeySource(
145  const DecryptionParams& decryption_params) {
146  std::unique_ptr<KeySource> decryption_key_source;
147  switch (decryption_params.key_provider) {
148  case KeyProvider::kWidevine: {
149  const WidevineDecryptionParams& widevine = decryption_params.widevine;
150  if (widevine.key_server_url.empty()) {
151  LOG(ERROR) << "'key_server_url' should not be empty.";
152  return std::unique_ptr<KeySource>();
153  }
154  std::unique_ptr<WidevineKeySource> widevine_key_source(
155  new WidevineKeySource(widevine.key_server_url,
156  true /* commmon pssh, does not matter here */));
157  if (!widevine.signer.signer_name.empty()) {
158  std::unique_ptr<RequestSigner> request_signer(
159  CreateSigner(widevine.signer));
160  if (!request_signer)
161  return std::unique_ptr<KeySource>();
162  widevine_key_source->set_signer(std::move(request_signer));
163  }
164 
165  decryption_key_source = std::move(widevine_key_source);
166  break;
167  }
168  case KeyProvider::kRawKey: {
169  decryption_key_source = RawKeySource::Create(decryption_params.raw_key);
170  break;
171  }
172  case KeyProvider::kNone:
173  case KeyProvider::kPlayready:
174  break;
175  }
176  return decryption_key_source;
177 }
178 
179 MpdOptions GetMpdOptions(bool on_demand_profile, const MpdParams& mpd_params) {
180  MpdOptions mpd_options;
181  mpd_options.dash_profile =
182  on_demand_profile ? DashProfile::kOnDemand : DashProfile::kLive;
183  mpd_options.mpd_type =
184  (on_demand_profile || mpd_params.generate_static_live_mpd)
185  ? MpdType::kStatic
186  : MpdType::kDynamic;
187  mpd_options.mpd_params = mpd_params;
188  return mpd_options;
189 }
190 
191 } // namespace media
192 } // 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)
static std::unique_ptr< PlayReadyKeySource > CreateFromKeyAndKeyId(const std::vector< uint8_t > &key_id, const std::vector< uint8_t > &key)