Minimal implementation of Widevine MediaCAS ECMG.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=226515998
This commit is contained in:
Fang Yu
2018-12-21 11:17:37 -08:00
parent 7487ce5aa8
commit bc68878bdf
88 changed files with 2456 additions and 2774 deletions

View File

@@ -265,10 +265,10 @@ class VerifiedCertSignatureCache {
// Checks cache, on miss, uses public key. If successful, adds to
// cache.
util::Status VerifySignature(const std::string& cert, const std::string& serial_number,
const std::string& signature,
const std::string& signer_public_key,
const std::string& signer_serial_number) {
Status VerifySignature(const std::string& cert, const std::string& serial_number,
const std::string& signature,
const std::string& signer_public_key,
const std::string& signer_serial_number) {
{
VerifiedCertSignatures::iterator cached_signature;
absl::ReaderMutexLock read_lock(&signature_cache_mutex_);
@@ -279,11 +279,11 @@ class VerifiedCertSignatureCache {
(signature != cached_signature->second.signature) ||
(signer_serial_number != cached_signature->second.signer_serial)) {
// Cached signature mismatch.
return util::Status(error_space, INVALID_SIGNATURE,
"cached-signature-mismatch");
return Status(error_space, INVALID_SIGNATURE,
"cached-signature-mismatch");
}
// Cached signature match.
return util::OkStatus();
return OkStatus();
}
}
@@ -291,12 +291,12 @@ class VerifiedCertSignatureCache {
std::unique_ptr<RsaPublicKey> signer_key(
key_factory_->CreateFromPkcs1PublicKey(signer_public_key));
if (!signer_key) {
return util::Status(error_space, INVALID_DRM_CERTIFICATE,
"invalid-signer-public-key");
return Status(error_space, INVALID_DRM_CERTIFICATE,
"invalid-signer-public-key");
}
if (!signer_key->VerifySignature(cert, signature)) {
return util::Status(error_space, INVALID_SIGNATURE,
"cache-miss-invalid-signature");
return Status(error_space, INVALID_SIGNATURE,
"cache-miss-invalid-signature");
}
// Add signature to cache.
@@ -304,7 +304,7 @@ class VerifiedCertSignatureCache {
signature_cache_.emplace(
serial_number,
VerifiedCertSignature(cert, signature, signer_serial_number));
return util::OkStatus();
return OkStatus();
}
private:
@@ -313,7 +313,7 @@ class VerifiedCertSignatureCache {
const RsaKeyFactory* key_factory_;
};
util::Status DrmRootCertificate::CreateByType(
Status DrmRootCertificate::CreateByType(
CertificateType cert_type, std::unique_ptr<DrmRootCertificate>* cert) {
CHECK(cert);
@@ -321,7 +321,7 @@ util::Status DrmRootCertificate::CreateByType(
}
std::unique_ptr<DrmRootCertificate> DrmRootCertificate::CreateByType(
CertificateType cert_type, util::Status* status) {
CertificateType cert_type, Status* status) {
CHECK(status);
std::unique_ptr<DrmRootCertificate> new_root_cert;
@@ -329,7 +329,7 @@ std::unique_ptr<DrmRootCertificate> DrmRootCertificate::CreateByType(
return new_root_cert;
}
util::Status DrmRootCertificate::CreateByTypeString(
Status DrmRootCertificate::CreateByTypeString(
const std::string& cert_type_string, std::unique_ptr<DrmRootCertificate>* cert) {
CHECK(cert);
@@ -341,17 +341,16 @@ util::Status DrmRootCertificate::CreateByTypeString(
} else if (cert_type_string == kTestingString) {
cert_type = kCertificateTypeTesting;
} else {
return util::Status(
error_space, INVALID_PARAMETER,
absl::StrCat("invalid-certificate-type ", cert_type_string));
return Status(error_space, INVALID_PARAMETER,
absl::StrCat("invalid-certificate-type ", cert_type_string));
}
return CreateByType(cert_type, cert);
}
util::Status DrmRootCertificate::Create(
CertificateType cert_type, std::unique_ptr<RsaKeyFactory> key_factory,
std::unique_ptr<DrmRootCertificate>* cert) {
Status DrmRootCertificate::Create(CertificateType cert_type,
std::unique_ptr<RsaKeyFactory> key_factory,
std::unique_ptr<DrmRootCertificate>* cert) {
DCHECK(cert);
std::string serialized_certificate;
@@ -375,49 +374,48 @@ util::Status DrmRootCertificate::Create(
break;
}
default:
return util::Status(error_space, INVALID_PARAMETER,
"invalid-certificate-type");
return Status(error_space, INVALID_PARAMETER, "invalid-certificate-type");
}
SignedDrmCertificate signed_root_cert;
if (!signed_root_cert.ParseFromString(serialized_certificate)) {
return util::Status(error_space, INVALID_DRM_CERTIFICATE,
"signed-root-cert-deserialize-fail");
return Status(error_space, INVALID_DRM_CERTIFICATE,
"signed-root-cert-deserialize-fail");
}
DrmCertificate root_cert;
if (!signed_root_cert.has_drm_certificate()) {
return util::Status(error_space, INVALID_DRM_CERTIFICATE,
"missing-root-device-certificate");
return Status(error_space, INVALID_DRM_CERTIFICATE,
"missing-root-device-certificate");
}
if (!root_cert.ParseFromString(signed_root_cert.drm_certificate())) {
return util::Status(error_space, INVALID_DRM_CERTIFICATE,
"root-cert-deserialize-fail");
return Status(error_space, INVALID_DRM_CERTIFICATE,
"root-cert-deserialize-fail");
}
if (!root_cert.has_public_key()) {
return util::Status(error_space, INVALID_DRM_CERTIFICATE,
"missing-root-cert-public-key");
return Status(error_space, INVALID_DRM_CERTIFICATE,
"missing-root-cert-public-key");
}
if (!signed_root_cert.has_signature()) {
return util::Status(error_space, INVALID_DRM_CERTIFICATE,
"missing-root-certificate-signature");
return Status(error_space, INVALID_DRM_CERTIFICATE,
"missing-root-certificate-signature");
}
std::unique_ptr<RsaPublicKey> public_key(
key_factory->CreateFromPkcs1PublicKey(root_cert.public_key()));
if (!public_key) {
return util::Status(error_space, INVALID_DRM_CERTIFICATE,
"invalid-root-public-key");
return Status(error_space, INVALID_DRM_CERTIFICATE,
"invalid-root-public-key");
}
if (!public_key->VerifySignature(signed_root_cert.drm_certificate(),
signed_root_cert.signature())) {
return util::Status(error_space, INVALID_DRM_CERTIFICATE,
"invalid-root-certificate-signature");
return Status(error_space, INVALID_DRM_CERTIFICATE,
"invalid-root-certificate-signature");
}
cert->reset(new DrmRootCertificate(
cert_type, serialized_certificate, root_cert.serial_number(),
root_cert.public_key(), std::move(key_factory)));
return util::OkStatus();
return OkStatus();
}
DrmRootCertificate::DrmRootCertificate(
@@ -437,7 +435,7 @@ std::string DrmRootCertificate::GetDigest() const {
return absl::BytesToHexString(Sha256_Hash(serialized_certificate_));
}
util::Status DrmRootCertificate::VerifyCertificate(
Status DrmRootCertificate::VerifyCertificate(
const std::string& serialized_certificate,
SignedDrmCertificate* signed_certificate,
DrmCertificate* certificate) const {
@@ -447,8 +445,8 @@ util::Status DrmRootCertificate::VerifyCertificate(
signed_certificate = local_signed_certificate.get();
}
if (!signed_certificate->ParseFromString(serialized_certificate)) {
return util::Status(error_space, INVALID_DRM_CERTIFICATE,
"invalid-signed-drm-certificate");
return Status(error_space, INVALID_DRM_CERTIFICATE,
"invalid-signed-drm-certificate");
}
std::unique_ptr<DrmCertificate> local_certificate;
@@ -458,20 +456,19 @@ util::Status DrmRootCertificate::VerifyCertificate(
}
if (signed_certificate->drm_certificate().empty() ||
!certificate->ParseFromString(signed_certificate->drm_certificate())) {
return util::Status(error_space, INVALID_DRM_CERTIFICATE,
"invalid-drm-certificate");
return Status(error_space, INVALID_DRM_CERTIFICATE,
"invalid-drm-certificate");
}
if (certificate->serial_number().empty()) {
return util::Status(error_space, INVALID_DRM_CERTIFICATE,
"missing-serial-number");
return Status(error_space, INVALID_DRM_CERTIFICATE,
"missing-serial-number");
}
if (!certificate->has_creation_time_seconds()) {
return util::Status(error_space, INVALID_DRM_CERTIFICATE,
"missing-creation-time");
return Status(error_space, INVALID_DRM_CERTIFICATE,
"missing-creation-time");
}
if (certificate->public_key().empty()) {
return util::Status(error_space, INVALID_DRM_CERTIFICATE,
"missing-public-key");
return Status(error_space, INVALID_DRM_CERTIFICATE, "missing-public-key");
}
// Verify signature chain, but do not use cache for leaf certificates.
@@ -485,7 +482,7 @@ util::Status DrmRootCertificate::VerifyCertificate(
// the case of device-unique device certificates.
// Signatures for root-signed certificates are always cached, even if they are
// leaf certificates. For example service, and provisioner certificates.
util::Status DrmRootCertificate::VerifySignatures(
Status DrmRootCertificate::VerifySignatures(
const SignedDrmCertificate& signed_cert, const std::string& cert_serial_number,
bool use_cache) const {
if (!signed_cert.has_signer()) {
@@ -497,12 +494,12 @@ util::Status DrmRootCertificate::VerifySignatures(
DrmCertificate signer;
if (!signer.ParseFromString(signed_cert.signer().drm_certificate())) {
return util::Status(error_space, INVALID_DRM_CERTIFICATE,
"invalid-signer-certificate");
return Status(error_space, INVALID_DRM_CERTIFICATE,
"invalid-signer-certificate");
}
// Verify the signer before verifying signed_cert.
util::Status status =
Status status =
VerifySignatures(signed_cert.signer(), signer.serial_number(), kUseCache);
if (!status.ok()) {
return status;
@@ -519,17 +516,17 @@ util::Status DrmRootCertificate::VerifySignatures(
std::unique_ptr<RsaPublicKey> signer_public_key(
key_factory_->CreateFromPkcs1PublicKey(signer.public_key()));
if (!signer_public_key) {
return util::Status(error_space, INVALID_DRM_CERTIFICATE,
"invalid-leaf-signer-public-key");
return Status(error_space, INVALID_DRM_CERTIFICATE,
"invalid-leaf-signer-public-key");
}
if (!signer_public_key->VerifySignature(signed_cert.drm_certificate(),
signed_cert.signature())) {
return util::Status(error_space, INVALID_SIGNATURE,
"cache-miss-invalid-signature");
return Status(error_space, INVALID_SIGNATURE,
"cache-miss-invalid-signature");
}
}
return util::OkStatus();
return OkStatus();
}
} // namespace widevine