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

@@ -248,9 +248,9 @@ VmpChecker::VmpChecker() : allow_development_vmp_(false) {}
VmpChecker::~VmpChecker() {}
util::Status VmpChecker::SelectCertificateType(CertificateType cert_type) {
Status VmpChecker::SelectCertificateType(CertificateType cert_type) {
std::unique_ptr<X509Cert> ca_cert(new X509Cert);
util::Status status = ca_cert->LoadDer(
Status status = ca_cert->LoadDer(
cert_type == kCertificateTypeProduction
? std::string(reinterpret_cast<const char*>(
kProdVmpCodeSigningDrmRootCertificate),
@@ -262,7 +262,7 @@ util::Status VmpChecker::SelectCertificateType(CertificateType cert_type) {
ca_.reset(new X509CA(ca_cert.release()));
return util::OkStatus();
return OkStatus();
}
VmpChecker* VmpChecker::Instance() {
@@ -271,17 +271,16 @@ VmpChecker* VmpChecker::Instance() {
}
// Verify VMP data and return appropriate result.
util::Status VmpChecker::VerifyVmpData(const std::string& vmp_data, Result* result) {
Status VmpChecker::VerifyVmpData(const std::string& vmp_data, Result* result) {
DCHECK(!vmp_data.empty());
DCHECK(result);
if (!ca_) return util::Status(error_space, CERT_CHAIN_NOT_SELECTED, "");
if (!ca_) return Status(error_space, CERT_CHAIN_NOT_SELECTED, "");
vmp::VmpData vmp_data_obj;
if (!vmp_data_obj.ParseFromString(vmp_data)) {
LOG(INFO) << "Error deserializing VmpData.";
return util::Status(error_space, INVALID_MESSAGE,
"vmp-data-deserialize-failed");
return Status(error_space, INVALID_MESSAGE, "vmp-data-deserialize-failed");
}
std::vector<std::unique_ptr<X509Cert>> code_signing_certs;
@@ -290,7 +289,7 @@ util::Status VmpChecker::VerifyVmpData(const std::string& vmp_data, Result* resu
for (int cert_idx = 0; cert_idx < vmp_data_obj.certificates_size();
++cert_idx) {
code_signing_certs.emplace_back(new X509Cert);
util::Status status(code_signing_certs.back()->LoadDer(
Status status(code_signing_certs.back()->LoadDer(
vmp_data_obj.certificates(cert_idx)));
if (!status.ok()) return status;
@@ -299,8 +298,8 @@ util::Status VmpChecker::VerifyVmpData(const std::string& vmp_data, Result* resu
if (code_signing_certs.back()->GetV3BooleanExtension(kDevelopmentFlagOid,
&dev_flag) &&
dev_flag) {
return util::Status(error_space, DEVELOPMENT_CERTIFICATE_NOT_ALLOWED,
"development-vmp-certificate-not-allowed");
return Status(error_space, DEVELOPMENT_CERTIFICATE_NOT_ALLOWED,
"development-vmp-certificate-not-allowed");
}
}
status = ca_->VerifyCert(*code_signing_certs.back());
@@ -324,12 +323,12 @@ util::Status VmpChecker::VerifyVmpData(const std::string& vmp_data, Result* resu
if (binary_info.signature().empty()) {
LOG(INFO) << "Unsigned binary \"" << binary_info.file_name() << "\".";
*result = kTampered;
return util::OkStatus();
return OkStatus();
}
if (binary_info.certificate_index() >= code_signing_certs.size()) {
LOG(INFO) << "Invalid code signing certificate index.";
*result = kTampered;
return util::OkStatus();
return OkStatus();
}
X509Cert* cert = code_signing_certs[binary_info.certificate_index()].get();
std::unique_ptr<RsaPublicKey> key(cert->GetRsaPublicKey());
@@ -339,7 +338,7 @@ util::Status VmpChecker::VerifyVmpData(const std::string& vmp_data, Result* resu
LOG(INFO) << "Code signature verification failed for file \""
<< binary_info.file_name() << "\".";
*result = kTampered;
return util::OkStatus();
return OkStatus();
}
if (binary_info.flags() & kBlessedBinaryFlag) ++num_blessed_binaries;
}
@@ -347,13 +346,13 @@ util::Status VmpChecker::VerifyVmpData(const std::string& vmp_data, Result* resu
LOG(INFO) << "Invalid number of blessed binaries (" << num_blessed_binaries
<< ").";
*result = kTampered;
return util::OkStatus();
return OkStatus();
}
VLOG(2) << "VMP verification success. Secure storage: "
<< secure_storage_verified;
*result = secure_storage_verified ? kSecureStorageVerified : kVerified;
return util::OkStatus();
return OkStatus();
}
} // namespace widevine