Minimal implementation of Widevine MediaCAS ECMG.
------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=226515998
This commit is contained in:
@@ -107,41 +107,41 @@ DrmServiceCertificateMap* DrmServiceCertificateMap::GetInstance() {
|
||||
|
||||
} // namespace
|
||||
|
||||
util::Status DrmServiceCertificate::AddDrmServiceCertificate(
|
||||
const DrmRootCertificate* root_cert, const std::string& service_certificate,
|
||||
Status DrmServiceCertificate::AddDrmServiceCertificate(
|
||||
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;
|
||||
util::Status status =
|
||||
root_cert->VerifyCertificate(service_certificate, nullptr, &drm_cert);
|
||||
Status status =
|
||||
root_drm_cert->VerifyCertificate(service_certificate, nullptr, &drm_cert);
|
||||
if (!status.ok()) {
|
||||
return status;
|
||||
}
|
||||
|
||||
if (drm_cert.type() != DrmCertificate::SERVICE) {
|
||||
return util::Status(error_space, INVALID_SERVICE_CERTIFICATE,
|
||||
"not-service-certificate");
|
||||
return Status(error_space, INVALID_SERVICE_CERTIFICATE,
|
||||
"not-service-certificate");
|
||||
}
|
||||
if (drm_cert.provider_id().empty()) {
|
||||
return util::Status(error_space, INVALID_SERVICE_CERTIFICATE,
|
||||
"missing-certificate-service-id");
|
||||
return Status(error_space, INVALID_SERVICE_CERTIFICATE,
|
||||
"missing-certificate-service-id");
|
||||
}
|
||||
std::unique_ptr<RsaPublicKey> public_key(
|
||||
RsaPublicKey::Create(drm_cert.public_key()));
|
||||
if (!public_key) {
|
||||
return util::Status(error_space, INVALID_SERVICE_CERTIFICATE,
|
||||
"invalid-certificate-public-key");
|
||||
return Status(error_space, INVALID_SERVICE_CERTIFICATE,
|
||||
"invalid-certificate-public-key");
|
||||
}
|
||||
std::string pkcs1_key;
|
||||
if (!rsa_util::EncryptedPrivateKeyInfoToRsaPrivateKey(
|
||||
service_private_key, service_private_key_passphrase, &pkcs1_key)) {
|
||||
return util::Status(error_space, INVALID_SERVICE_PRIVATE_KEY,
|
||||
"key-decryption-failed");
|
||||
return Status(error_space, INVALID_SERVICE_PRIVATE_KEY,
|
||||
"key-decryption-failed");
|
||||
}
|
||||
std::unique_ptr<RsaPrivateKey> private_key(RsaPrivateKey::Create(pkcs1_key));
|
||||
if (private_key == nullptr) {
|
||||
return util::Status(error_space, INVALID_SERVICE_PRIVATE_KEY,
|
||||
"invalid-private-key");
|
||||
return Status(error_space, INVALID_SERVICE_PRIVATE_KEY,
|
||||
"invalid-private-key");
|
||||
}
|
||||
|
||||
std::unique_ptr<DrmServiceCertificate> new_cert(new DrmServiceCertificate(
|
||||
@@ -150,7 +150,7 @@ util::Status DrmServiceCertificate::AddDrmServiceCertificate(
|
||||
std::move(private_key)));
|
||||
DrmServiceCertificateMap::GetInstance()->AddCert(std::move(new_cert));
|
||||
|
||||
return util::OkStatus();
|
||||
return OkStatus();
|
||||
}
|
||||
|
||||
const DrmServiceCertificate*
|
||||
@@ -171,7 +171,7 @@ const DrmServiceCertificate* DrmServiceCertificate::GetDrmServiceCertificate(
|
||||
return DrmServiceCertificateMap::GetInstance()->GetCert(serial_number);
|
||||
}
|
||||
|
||||
util::Status DrmServiceCertificate::SetDefaultDrmServiceCertificate(
|
||||
Status DrmServiceCertificate::SetDefaultDrmServiceCertificate(
|
||||
const DrmRootCertificate* root_drm_cert, const std::string& service_certificate,
|
||||
const std::string& service_private_key,
|
||||
const std::string& service_private_key_passphrase) {
|
||||
@@ -181,36 +181,36 @@ util::Status DrmServiceCertificate::SetDefaultDrmServiceCertificate(
|
||||
service_private_key_passphrase);
|
||||
}
|
||||
|
||||
util::Status DrmServiceCertificate::DecryptClientIdentification(
|
||||
Status DrmServiceCertificate::DecryptClientIdentification(
|
||||
const EncryptedClientIdentification& encrypted_client_id,
|
||||
ClientIdentification* client_id) {
|
||||
DCHECK(client_id);
|
||||
if (encrypted_client_id.service_certificate_serial_number().empty()) {
|
||||
return util::Status(error_space, INVALID_ENCRYPTED_CLIENT_IDENTIFICATION,
|
||||
"missing-service-certificate-serial-number");
|
||||
return Status(error_space, INVALID_ENCRYPTED_CLIENT_IDENTIFICATION,
|
||||
"missing-service-certificate-serial-number");
|
||||
}
|
||||
if (encrypted_client_id.provider_id().empty()) {
|
||||
return util::Status(error_space, INVALID_ENCRYPTED_CLIENT_IDENTIFICATION,
|
||||
"missing-service-id");
|
||||
return Status(error_space, INVALID_ENCRYPTED_CLIENT_IDENTIFICATION,
|
||||
"missing-service-id");
|
||||
}
|
||||
if (encrypted_client_id.encrypted_client_id().empty()) {
|
||||
return util::Status(error_space, INVALID_ENCRYPTED_CLIENT_IDENTIFICATION,
|
||||
"missing-encrypted-client-id");
|
||||
return Status(error_space, INVALID_ENCRYPTED_CLIENT_IDENTIFICATION,
|
||||
"missing-encrypted-client-id");
|
||||
}
|
||||
if (encrypted_client_id.encrypted_client_id_iv().empty()) {
|
||||
return util::Status(error_space, INVALID_ENCRYPTED_CLIENT_IDENTIFICATION,
|
||||
"missing-encrypted-client-id-iv");
|
||||
return Status(error_space, INVALID_ENCRYPTED_CLIENT_IDENTIFICATION,
|
||||
"missing-encrypted-client-id-iv");
|
||||
}
|
||||
if (encrypted_client_id.encrypted_privacy_key().empty()) {
|
||||
return util::Status(error_space, INVALID_ENCRYPTED_CLIENT_IDENTIFICATION,
|
||||
"missing-encrypted-privacy-key");
|
||||
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 util::Status(
|
||||
return Status(
|
||||
error_space, SERVICE_CERTIFICATE_NOT_FOUND,
|
||||
"service-certificate-not-found (SN " +
|
||||
absl::BytesToHexString(
|
||||
@@ -219,56 +219,56 @@ util::Status DrmServiceCertificate::DecryptClientIdentification(
|
||||
}
|
||||
if (!cert->private_key()->Decrypt(encrypted_client_id.encrypted_privacy_key(),
|
||||
&privacy_key)) {
|
||||
return util::Status(error_space, INVALID_ENCRYPTED_CLIENT_IDENTIFICATION,
|
||||
"privacy-key-decryption-failed");
|
||||
return Status(error_space, INVALID_ENCRYPTED_CLIENT_IDENTIFICATION,
|
||||
"privacy-key-decryption-failed");
|
||||
}
|
||||
if (cert->provider_id() != encrypted_client_id.provider_id()) {
|
||||
return util::Status(error_space, SERVICE_CERTIFICATE_NOT_FOUND,
|
||||
std::string("provider-id-mismatch (") + 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 util::Status(error_space, INVALID_ENCRYPTED_CLIENT_IDENTIFICATION,
|
||||
"client-id-decryption-failed");
|
||||
return Status(error_space, INVALID_ENCRYPTED_CLIENT_IDENTIFICATION,
|
||||
"client-id-decryption-failed");
|
||||
}
|
||||
if (!client_id->ParseFromString(serialized_client_id)) {
|
||||
return util::Status(error_space, INVALID_ENCRYPTED_CLIENT_IDENTIFICATION,
|
||||
"client-id-parse-failed");
|
||||
return Status(error_space, INVALID_ENCRYPTED_CLIENT_IDENTIFICATION,
|
||||
"client-id-parse-failed");
|
||||
}
|
||||
return util::OkStatus();
|
||||
return OkStatus();
|
||||
}
|
||||
|
||||
void DrmServiceCertificate::ResetServiceCertificates() {
|
||||
DrmServiceCertificateMap::GetInstance()->Reset();
|
||||
}
|
||||
|
||||
util::Status DrmServiceCertificate::ValidateDrmServiceCertificate() {
|
||||
Status DrmServiceCertificate::ValidateDrmServiceCertificate() {
|
||||
const DrmServiceCertificate* service_certificate =
|
||||
GetDefaultDrmServiceCertificate();
|
||||
if (!service_certificate) {
|
||||
return util::Status(error_space, SERVICE_CERTIFICATE_NOT_FOUND,
|
||||
"drm service certificate is not found.");
|
||||
return Status(error_space, SERVICE_CERTIFICATE_NOT_FOUND,
|
||||
"drm service certificate is not found.");
|
||||
}
|
||||
SignedDrmCertificate signed_cert;
|
||||
if (!signed_cert.ParseFromString(service_certificate->certificate())) {
|
||||
return util::Status(error_space, INVALID_DRM_CERTIFICATE,
|
||||
"signed drm service certificate is failed to parse.");
|
||||
return Status(error_space, INVALID_DRM_CERTIFICATE,
|
||||
"signed drm service certificate is failed to parse.");
|
||||
}
|
||||
DrmCertificate drm_cert;
|
||||
if (!drm_cert.ParseFromString(signed_cert.drm_certificate())) {
|
||||
return util::Status(error_space, INVALID_DRM_CERTIFICATE,
|
||||
"Drm service certificate is failed to parse.");
|
||||
return Status(error_space, INVALID_DRM_CERTIFICATE,
|
||||
"Drm service certificate is failed to parse.");
|
||||
}
|
||||
if (!drm_cert.has_creation_time_seconds()) {
|
||||
return util::Status(error_space, INVALID_SERVICE_CERTIFICATE,
|
||||
"missing certificate creation time");
|
||||
return Status(error_space, INVALID_SERVICE_CERTIFICATE,
|
||||
"missing certificate creation time");
|
||||
}
|
||||
// TODO(user): Check creation_time_seconds field in DrmCertificate and also
|
||||
// export the absl/time dependency through moe.
|
||||
return util::OkStatus();
|
||||
return OkStatus();
|
||||
}
|
||||
|
||||
DrmServiceCertificate::DrmServiceCertificate(
|
||||
|
||||
Reference in New Issue
Block a user