Update to support OEMCrypto v16 with ODK

This commit is contained in:
KongQun Yang
2020-09-21 15:54:04 -07:00
parent 93265ab9d1
commit 69d813f0f1
203 changed files with 16337 additions and 2290 deletions

View File

@@ -13,7 +13,7 @@
#include <utility>
#include "glog/logging.h"
#include "base/thread_annotations.h"
#include "absl/base/thread_annotations.h"
#include "absl/strings/escaping.h"
#include "absl/synchronization/mutex.h"
#include "util/gtl/map_util.h"
@@ -22,6 +22,7 @@
#include "common/drm_root_certificate.h"
#include "common/error_space.h"
#include "common/rsa_util.h"
#include "common/status.h"
#include "protos/public/client_identification.pb.h"
#include "protos/public/drm_certificate.pb.h"
#include "protos/public/errors.pb.h"
@@ -44,16 +45,18 @@ class DrmServiceCertificateMap {
void AddCert(std::unique_ptr<DrmServiceCertificate> new_cert);
void ClearDefaultDrmServiceCertificate();
const DrmServiceCertificate* GetDefaultCert();
const DrmServiceCertificate* GetCert(const std::string& serial_number);
const DrmServiceCertificate* GetCertBySerialNumber(
const std::string& serial_number);
const DrmServiceCertificate* GetCertByProvider(
const std::string& provider_id);
static DrmServiceCertificateMap* GetInstance();
private:
absl::Mutex mutex_;
// Certificate serial number to certificate map.
std::map<std::string, std::unique_ptr<DrmServiceCertificate>> map_
GUARDED_BY(mutex_);
DrmServiceCertificate* default_cert_ GUARDED_BY(mutex_);
ABSL_GUARDED_BY(mutex_);
DrmServiceCertificate* default_cert_ ABSL_GUARDED_BY(mutex_);
};
DrmServiceCertificateMap::DrmServiceCertificateMap() : default_cert_(nullptr) {}
@@ -94,12 +97,30 @@ const DrmServiceCertificate* DrmServiceCertificateMap::GetDefaultCert() {
return default_cert_;
}
const DrmServiceCertificate* DrmServiceCertificateMap::GetCert(
const DrmServiceCertificate* DrmServiceCertificateMap::GetCertBySerialNumber(
const std::string& serial_number) {
absl::ReaderMutexLock lock(&mutex_);
return map_[serial_number].get();
}
const DrmServiceCertificate* DrmServiceCertificateMap::GetCertByProvider(
const std::string& provider_id) {
absl::ReaderMutexLock lock(&mutex_);
DrmServiceCertificate* provider_drm_cert = nullptr;
for (const auto& drm_cert : map_) {
if (drm_cert.second->provider_id() == provider_id) {
if (provider_drm_cert == nullptr) {
provider_drm_cert = drm_cert.second.get();
} else if (drm_cert.second->creation_time_seconds() >
provider_drm_cert->creation_time_seconds()) {
// Use the newest cert.
provider_drm_cert = drm_cert.second.get();
}
}
}
return provider_drm_cert;
}
DrmServiceCertificateMap* DrmServiceCertificateMap::GetInstance() {
static auto* const kInstance = new DrmServiceCertificateMap();
return kInstance;
@@ -108,7 +129,8 @@ DrmServiceCertificateMap* DrmServiceCertificateMap::GetInstance() {
} // namespace
Status DrmServiceCertificate::AddDrmServiceCertificate(
const DrmRootCertificate* root_drm_cert, const std::string& service_certificate,
const DrmRootCertificate* root_drm_cert,
const std::string& service_certificate,
const std::string& service_private_key,
const std::string& service_private_key_passphrase) {
DrmCertificate drm_cert;
@@ -166,13 +188,22 @@ DrmServiceCertificate::GetDefaultDrmServiceCertificateOrDie() {
return default_cert;
}
const DrmServiceCertificate* DrmServiceCertificate::GetDrmServiceCertificate(
const DrmServiceCertificate*
DrmServiceCertificate::GetDrmServiceCertificateBySerialNumber(
const std::string& serial_number) {
return DrmServiceCertificateMap::GetInstance()->GetCert(serial_number);
return DrmServiceCertificateMap::GetInstance()->GetCertBySerialNumber(
serial_number);
}
const DrmServiceCertificate*
DrmServiceCertificate::GetDrmServiceCertificateByProvider(
const std::string& provider) {
return DrmServiceCertificateMap::GetInstance()->GetCertByProvider(provider);
}
Status DrmServiceCertificate::SetDefaultDrmServiceCertificate(
const DrmRootCertificate* root_drm_cert, const std::string& service_certificate,
const DrmRootCertificate* root_drm_cert,
const std::string& service_certificate,
const std::string& service_private_key,
const std::string& service_private_key_passphrase) {
DrmServiceCertificateMap::GetInstance()->ClearDefaultDrmServiceCertificate();
@@ -185,60 +216,22 @@ Status DrmServiceCertificate::DecryptClientIdentification(
const EncryptedClientIdentification& encrypted_client_id,
ClientIdentification* client_id) {
DCHECK(client_id);
if (encrypted_client_id.service_certificate_serial_number().empty()) {
std::string serialized_client_id;
Status status = DecryptEncryptedPayload(
encrypted_client_id.service_certificate_serial_number(),
encrypted_client_id.provider_id(),
encrypted_client_id.encrypted_client_id(),
encrypted_client_id.encrypted_client_id_iv(),
encrypted_client_id.encrypted_privacy_key(), &serialized_client_id);
if (status.error_code() == error::INVALID_ARGUMENT) {
return Status(error_space, INVALID_ENCRYPTED_CLIENT_IDENTIFICATION,
"missing-service-certificate-serial-number");
status.error_message());
}
if (encrypted_client_id.provider_id().empty()) {
return Status(error_space, INVALID_ENCRYPTED_CLIENT_IDENTIFICATION,
"missing-service-id");
}
if (encrypted_client_id.encrypted_client_id().empty()) {
return Status(error_space, INVALID_ENCRYPTED_CLIENT_IDENTIFICATION,
"missing-encrypted-client-id");
}
if (encrypted_client_id.encrypted_client_id_iv().empty()) {
return Status(error_space, INVALID_ENCRYPTED_CLIENT_IDENTIFICATION,
"missing-encrypted-client-id-iv");
}
if (encrypted_client_id.encrypted_privacy_key().empty()) {
return Status(error_space, INVALID_ENCRYPTED_CLIENT_IDENTIFICATION,
"missing-encrypted-privacy-key");
}
std::string privacy_key;
std::string provider_id;
const DrmServiceCertificate* cert = GetDrmServiceCertificate(
encrypted_client_id.service_certificate_serial_number());
if (!cert) {
return Status(
error_space, SERVICE_CERTIFICATE_NOT_FOUND,
"service-certificate-not-found (SN " +
absl::BytesToHexString(
encrypted_client_id.service_certificate_serial_number()) +
")");
}
if (!cert->private_key()->Decrypt(encrypted_client_id.encrypted_privacy_key(),
&privacy_key)) {
return Status(error_space, INVALID_ENCRYPTED_CLIENT_IDENTIFICATION,
"privacy-key-decryption-failed");
}
if (cert->provider_id() != encrypted_client_id.provider_id()) {
return Status(error_space, SERVICE_CERTIFICATE_NOT_FOUND,
std::string("provider-id-mismatch (") + cert->provider_id() +
" / " + encrypted_client_id.provider_id() + ")");
}
std::string serialized_client_id(crypto_util::DecryptAesCbc(
privacy_key, encrypted_client_id.encrypted_client_id_iv(),
encrypted_client_id.encrypted_client_id()));
if (serialized_client_id.empty()) {
return Status(error_space, INVALID_ENCRYPTED_CLIENT_IDENTIFICATION,
"client-id-decryption-failed");
}
if (!client_id->ParseFromString(serialized_client_id)) {
if (status.ok() && !client_id->ParseFromString(serialized_client_id)) {
return Status(error_space, INVALID_ENCRYPTED_CLIENT_IDENTIFICATION,
"client-id-parse-failed");
}
return OkStatus();
return status;
}
void DrmServiceCertificate::ResetServiceCertificates() {
@@ -271,6 +264,67 @@ Status DrmServiceCertificate::ValidateDrmServiceCertificate() {
return OkStatus();
}
Status DrmServiceCertificate::DecryptLicenseChallenge(
const EncryptedLicenseRequest& encrypted_license_request,
std::string* license_challenge) {
Status status = DecryptEncryptedPayload(
encrypted_license_request.service_certificate_serial_number(),
encrypted_license_request.provider_id(),
encrypted_license_request.encrypted_license_request(),
encrypted_license_request.encrypted_license_request_iv(),
encrypted_license_request.encrypted_privacy_key(), license_challenge);
if (status.error_code() == error::INVALID_ARGUMENT) {
return Status(error_space, INVALID_ENCRYPTED_LICENSE_CHALLENGE,
status.error_message());
}
return status;
}
Status DrmServiceCertificate::DecryptEncryptedPayload(
const std::string& service_certificate_serial_number,
const std::string& provider_id, const std::string& encrypted_payload,
const std::string& iv, const std::string& encrypted_privacy_key,
std::string* payload) {
if (payload == nullptr) {
return Status(error::INVALID_ARGUMENT, "null-payload");
}
payload->clear();
if (service_certificate_serial_number.empty()) {
return Status(error::INVALID_ARGUMENT,
"missing-service-certificate-serial-number");
} else if (provider_id.empty()) {
return Status(error::INVALID_ARGUMENT, "missing-service-id");
} else if (encrypted_payload.empty()) {
return Status(error::INVALID_ARGUMENT, "missing-encrypted-payload");
} else if (iv.empty()) {
return Status(error::INVALID_ARGUMENT, "missing-iv");
} else if (encrypted_privacy_key.empty()) {
return Status(error::INVALID_ARGUMENT, "missing-privacy-key");
}
std::string privacy_key;
const DrmServiceCertificate* cert =
GetDrmServiceCertificateBySerialNumber(service_certificate_serial_number);
if (!cert) {
return Status(
error_space, SERVICE_CERTIFICATE_NOT_FOUND,
"service-certificate-not-found (SN " +
absl::BytesToHexString(service_certificate_serial_number) + ")");
}
if (!cert->private_key()->Decrypt(encrypted_privacy_key, &privacy_key)) {
return Status(error::INVALID_ARGUMENT, "privacy-key-decryption-failed");
}
if (cert->provider_id() != provider_id) {
return Status(error_space, SERVICE_CERTIFICATE_NOT_FOUND,
std::string("provider-id-mismatch (") + cert->provider_id() +
" / " + provider_id + ")");
}
*payload = crypto_util::DecryptAesCbc(privacy_key, iv, encrypted_payload);
if (payload->empty()) {
return Status(error::INVALID_ARGUMENT, "payload-decryption-failed");
}
return OkStatus();
}
DrmServiceCertificate::DrmServiceCertificate(
const std::string& service_certificate, const std::string& provider_id,
const std::string& serial_number, const uint32_t creation_time_seconds,