Files
media_cas_packager_sdk_source/common/client_cert.cc
2020-07-24 18:17:12 -07:00

131 lines
4.6 KiB
C++

////////////////////////////////////////////////////////////////////////////////
// Copyright 2019 Google LLC.
//
// This software is licensed under the terms defined in the Widevine Master
// License Agreement. For a copy of this agreement, please contact
// widevine-licensing@google.com.
////////////////////////////////////////////////////////////////////////////////
#include "common/client_cert.h"
#include <cstddef>
#include <memory>
#include <string>
#include "glog/logging.h"
#include "absl/memory/memory.h"
#include "absl/strings/escaping.h"
#include "common/certificate_client_cert.h"
#include "common/crypto_util.h"
#include "common/dual_certificate_client_cert.h"
#include "common/error_space.h"
#include "common/keybox_client_cert.h"
#include "common/random_util.h"
#include "common/rsa_key.h"
#include "common/sha_util.h"
#include "common/signing_key_util.h"
#include "common/status.h"
#include "common/wvm_token_handler.h"
#include "protos/public/drm_certificate.pb.h"
#include "protos/public/errors.pb.h"
#include "protos/public/signed_drm_certificate.pb.h"
namespace widevine {
void KeyboxClientCert::SetPreProvisioningKeys(
const std::multimap<uint32_t, std::string>& keymap) {
std::vector<WvmTokenHandler::PreprovKey> keyvector;
keyvector.reserve(keymap.size());
for (std::multimap<uint32_t, std::string>::const_iterator it = keymap.begin();
it != keymap.end(); ++it) {
std::string key = absl::HexStringToBytes(it->second);
DCHECK_EQ(key.size(), 16);
keyvector.push_back(WvmTokenHandler::PreprovKey(it->first, key));
}
WvmTokenHandler::SetPreprovKeys(keyvector);
}
bool KeyboxClientCert::IsSystemIdKnown(const uint32_t system_id) {
return WvmTokenHandler::IsSystemIdKnown(system_id);
}
uint32_t KeyboxClientCert::GetSystemId(const std::string& keybox_bytes) {
return WvmTokenHandler::GetSystemId(keybox_bytes);
}
Status ClientCert::Create(const DrmRootCertificate* root_certificate,
const widevine::ClientIdentification& client_id,
std::unique_ptr<ClientCert>* client_cert) {
CHECK(client_cert);
switch (client_id.type()) {
case ClientIdentification::KEYBOX:
return CreateWithKeybox(client_id.token(), client_cert);
case ClientIdentification::DRM_DEVICE_CERTIFICATE:
if (!client_id.has_device_credentials()) {
return CreateWithDrmCertificate(root_certificate, client_id.token(),
client_cert);
}
// Assumes |client_id.token| is the signing cert and
// |client_id.device_credentials().token| is the encryption cert.
if (client_id.device_credentials().type() !=
ClientIdentification::DRM_DEVICE_CERTIFICATE)
return Status(error_space, INVALID_DRM_CERTIFICATE,
"unsupported-encryption-certificate");
return CreateWithDualDrmCertificates(
root_certificate, client_id.token(),
client_id.device_credentials().token(), client_cert);
default:
return Status(error_space, error::UNIMPLEMENTED,
"client-type-not-implemented");
}
return OkStatus();
}
// Creates a Device Certificate based ClientCert. The |client_cert| is a
// caller supplied unique_ptr to receive the new ClientCert.
Status ClientCert::CreateWithDrmCertificate(
const DrmRootCertificate* root_certificate,
const std::string& drm_certificate,
std::unique_ptr<ClientCert>* client_cert) {
CHECK(root_certificate);
CHECK(client_cert);
auto device_cert = absl::make_unique<CertificateClientCert>();
Status status = device_cert->Initialize(root_certificate, drm_certificate);
if (status.ok()) {
*client_cert = std::move(device_cert);
}
return status;
}
Status ClientCert::CreateWithDualDrmCertificates(
const DrmRootCertificate* root_certificate,
const std::string& signing_drm_certificate,
const std::string& encryption_drm_certificate,
std::unique_ptr<ClientCert>* client_cert) {
CHECK(root_certificate);
CHECK(client_cert);
auto device_cert = absl::make_unique<DualCertificateClientCert>();
Status status = device_cert->Initialize(
root_certificate, signing_drm_certificate, encryption_drm_certificate);
if (status.ok()) {
*client_cert = std::move(device_cert);
}
return status;
}
Status ClientCert::CreateWithKeybox(const std::string& keybox_token,
std::unique_ptr<ClientCert>* client_cert) {
CHECK(client_cert);
auto kbx_cert = absl::make_unique<KeyboxClientCert>();
Status status = kbx_cert->Initialize(keybox_token);
if (status.ok()) {
*client_cert = std::move(kbx_cert);
}
return status;
}
} // namespace widevine