Restrict uses of BoringSSL.

(This is a merge of http://go/wvgerrit/71883)

This moves all the SSL code to privacy_crypto so we can use the
iOS-specific versions and not use any BoringSSL.  The iOS version
doesn't support OEM certificates.

Note that the tests still use BoringSSL.

Bug: 126559819
Test: build_and_run_all_unit_tests.sh
Change-Id: Ib0fad5d95b283b6cd6e02d8a08bcf248c5900bc4
This commit is contained in:
John W. Bruce
2019-02-28 17:32:22 -08:00
parent 50e4d67415
commit e5380ca59f
5 changed files with 200 additions and 168 deletions

View File

@@ -16,10 +16,8 @@
#include "crypto_key.h"
#include "entitlement_key_session.h"
#include "log.h"
#include "openssl/asn1.h"
#include "openssl/sha.h"
#include "openssl/x509v3.h"
#include "platform.h"
#include "privacy_crypto.h"
#include "properties.h"
#include "pst_report.h"
#include "string_conversions.h"
@@ -48,30 +46,8 @@ const size_t kOemCryptoApiVersionSupportsBigUsageTables = 13;
const size_t kOemCryptoApiVersionSupportsSwitchingCipherMode = 14;
// Constants and utility objects relating to OEM Certificates
const int kExtensionOidSize = 64;
const char* const kWidevineSystemIdExtensionOid = "1.3.6.1.4.1.11129.4.1.1";
// Helpers for working with BoringSSL
template <typename T, void (*func)(T*)>
class boringssl_ptr {
public:
explicit boringssl_ptr(T* p = NULL) : ptr_(p) {}
~boringssl_ptr() {
if (ptr_) func(ptr_);
}
T& operator*() const { return *ptr_; }
T* operator->() const { return ptr_; }
T* get() const { return ptr_; }
private:
T* ptr_;
CORE_DISALLOW_COPY_AND_ASSIGN(boringssl_ptr);
};
void DeleteX509Stack(STACK_OF(X509)* stack) {
sk_X509_pop_free(stack, X509_free);
}
} // namespace
namespace wvcdm {
@@ -503,13 +479,7 @@ CdmResponseType CryptoSession::GetExternalDeviceUniqueId(
pre_provision_token_type_ == kClientTokenOemCert) {
// To keep the size of the value passed back to the application down, hash
// the large OEM Public Cert to a smaller value.
uint8_t hash[SHA256_DIGEST_LENGTH];
SHA256_CTX ctx;
SHA256_Init(&ctx);
SHA256_Update(&ctx, temp.data(), temp.length());
SHA256_Final(hash, &ctx);
temp.assign(reinterpret_cast<char*>(hash), SHA256_DIGEST_LENGTH);
temp = Sha256Hash(temp);
}
*device_id = temp;
@@ -612,103 +582,8 @@ CdmResponseType CryptoSession::GetSystemIdInternal(uint32_t* system_id) {
bool CryptoSession::ExtractSystemIdFromOemCert(const std::string& oem_cert,
uint32_t* system_id) {
// Load the certificate chain into a BoringSSL X509 Stack
const boringssl_ptr<STACK_OF(X509), DeleteX509Stack> x509_stack(
sk_X509_new_null());
if (x509_stack.get() == NULL) {
LOGE("CryptoSession::ExtractSystemIdFromOemCert: "
"Unable to allocate X509 Stack.");
return false;
}
CBS pkcs7;
CBS_init(&pkcs7, reinterpret_cast<const uint8_t*>(oem_cert.data()),
oem_cert.size());
if (!PKCS7_get_certificates(x509_stack.get(), &pkcs7)) {
LOGE("CryptoSession::ExtractSystemIdFromOemCert: "
"Error getting certificate chain.");
return false;
}
STACK_OF(X509)* certs = x509_stack.get();
// Get the Widevine intermediate cert from the stack
if (sk_X509_num(certs) != 2) {
LOGE("CryptoSession::ExtractSystemIdFromOemCert: "
"Expected 2 certificates in chain, got %d",
sk_X509_num(certs));
return false;
}
X509* const intermediate_cert = sk_X509_value(certs, 1);
if (!intermediate_cert) {
LOGE("CryptoSession::ExtractSystemIdFromOemCert: "
"Unable to get intermediate cert.");
return false;
}
// Find the Widevine System ID extension in the intermediate cert
const int extension_count = X509_get_ext_count(intermediate_cert);
for (int i = 0; i < extension_count; ++i) {
X509_EXTENSION* const extension = X509_get_ext(intermediate_cert, i);
if (!extension) {
LOGE("CryptoSession::ExtractSystemIdFromOemCert: "
"Unable to get cert extension %d", i);
continue;
}
ASN1_OBJECT* const extension_object = X509_EXTENSION_get_object(extension);
if (!extension_object) {
LOGE("CryptoSession::ExtractSystemIdFromOemCert: "
"Unable to get object of cert extension %d", i);
continue;
}
char extension_name[kExtensionOidSize + 1];
OBJ_obj2txt(extension_name, kExtensionOidSize, extension_object, 1);
if (strcmp(extension_name, kWidevineSystemIdExtensionOid) != 0) {
// This extension is not the Widevine System ID, so we should move on to
// the next one.
continue;
}
ASN1_OCTET_STRING* const octet_str = X509_EXTENSION_get_data(extension);
if (!octet_str) {
LOGE("CryptoSession::ExtractSystemIdFromOemCert: "
"Unable to get data of Widevine System ID extension.");
return false;
}
const unsigned char* data = octet_str->data;
if (!data) {
LOGE("CryptoSession::ExtractSystemIdFromOemCert: "
"Null data in Widevine System ID extension.");
return false;
}
ASN1_INTEGER* const asn1_integer =
d2i_ASN1_INTEGER(NULL, &data, octet_str->length);
if (!asn1_integer) {
LOGE("CryptoSession::ExtractSystemIdFromOemCert: "
"Unable to decode data in Widevine System ID extension.");
return false;
}
const long system_id_long = ASN1_INTEGER_get(asn1_integer);
ASN1_INTEGER_free(asn1_integer);
if (system_id_long == -1) {
LOGE("CryptoSession::ExtractSystemIdFromOemCert: "
"Unable to decode ASN integer in Widevine System ID extension.");
return false;
}
*system_id = static_cast<uint32_t>(system_id_long);
return true;
}
LOGE("CryptoSession::ExtractSystemIdFromOemCert: "
"Widevine System ID extension not found.");
return false;
return ExtractExtensionValueFromCertificate(
oem_cert, kWidevineSystemIdExtensionOid, /* cert_index */ 1, system_id);
}
CdmResponseType CryptoSession::GetProvisioningId(std::string* provisioning_id) {