Update Simulcrypt ECMg
This commit is contained in:
@@ -9,12 +9,16 @@
|
||||
#include "common/client_cert.h"
|
||||
|
||||
#include <memory>
|
||||
#include <tuple>
|
||||
|
||||
#include "testing/gmock.h"
|
||||
#include "testing/gunit.h"
|
||||
#include "absl/strings/escaping.h"
|
||||
#include "common/ec_key.h"
|
||||
#include "common/ec_test_keys.h"
|
||||
#include "common/error_space.h"
|
||||
#include "common/hash_algorithm.h"
|
||||
#include "common/hash_algorithm_util.h"
|
||||
#include "common/keybox_client_cert.h"
|
||||
#include "common/rsa_key.h"
|
||||
#include "common/rsa_test_keys.h"
|
||||
@@ -35,13 +39,16 @@ const DrmCertificate::Type kNoSigner = DrmCertificate::ROOT;
|
||||
const DrmCertificate::Type kDeviceModelSigner = DrmCertificate::DEVICE_MODEL;
|
||||
const DrmCertificate::Type kProvisionerSigner = DrmCertificate::PROVISIONER;
|
||||
|
||||
const HashAlgorithm kSha256 = HashAlgorithm::kSha256;
|
||||
|
||||
// TODO(user): Change these tests to use on-the-fly generated intermediate
|
||||
// and device certificates based on RsaTestKeys.
|
||||
// TODO(user): Add testcase(s) CreateSignature,
|
||||
// and GenerateSigningKey.
|
||||
|
||||
class ClientCertTest
|
||||
: public ::testing::TestWithParam<DrmCertificate::Algorithm> {
|
||||
: public ::testing::TestWithParam<
|
||||
std::tuple<DrmCertificate::Algorithm, DrmCertificate::Algorithm>> {
|
||||
public:
|
||||
~ClientCertTest() override = default;
|
||||
void SetUp() override {
|
||||
@@ -74,16 +81,30 @@ class ClientCertTest
|
||||
class TestCertificateAndData {
|
||||
public:
|
||||
const std::string certificate_;
|
||||
const std::string encryption_certificate_;
|
||||
const std::string expected_serial_number_;
|
||||
uint32_t expected_system_id_;
|
||||
Status expected_status_;
|
||||
SignedMessage::SessionKeyType expected_key_type_;
|
||||
TestCertificateAndData(const std::string& certificate,
|
||||
const std::string& expected_serial_number,
|
||||
uint32_t expected_system_id, Status expected_status)
|
||||
: certificate_(certificate),
|
||||
expected_serial_number_(expected_serial_number),
|
||||
expected_system_id_(expected_system_id),
|
||||
expected_status_(expected_status) {}
|
||||
expected_status_(expected_status),
|
||||
expected_key_type_(SignedMessage::WRAPPED_AES_KEY) {}
|
||||
TestCertificateAndData(const std::string& certificate,
|
||||
const std::string& encryption_certificate,
|
||||
const std::string& expected_serial_number,
|
||||
uint32_t expected_system_id, Status expected_status,
|
||||
SignedMessage::SessionKeyType expected_key_type)
|
||||
: certificate_(certificate),
|
||||
encryption_certificate_(encryption_certificate),
|
||||
expected_serial_number_(expected_serial_number),
|
||||
expected_system_id_(expected_system_id),
|
||||
expected_status_(expected_status),
|
||||
expected_key_type_(expected_key_type) {}
|
||||
};
|
||||
|
||||
void TestBasicValidation(const TestTokenAndKeys& expectation,
|
||||
@@ -94,31 +115,32 @@ class ClientCertTest
|
||||
|
||||
void GenerateSignature(const std::string& message,
|
||||
const std::string& private_key,
|
||||
std::string* signature);
|
||||
SignedDrmCertificate* SignCertificate(const DrmCertificate& certificate,
|
||||
SignedDrmCertificate* signer,
|
||||
const std::string& private_key);
|
||||
DrmCertificate* GenerateProvisionerCertificate(
|
||||
HashAlgorithm hash_algorithm, std::string* signature);
|
||||
std::unique_ptr<SignedDrmCertificate> SignCertificate(
|
||||
const DrmCertificate& certificate, const SignedDrmCertificate* signer,
|
||||
const std::string& private_key);
|
||||
std::unique_ptr<DrmCertificate> GenerateProvisionerCertificate(
|
||||
uint32_t system_id, const std::string& serial_number,
|
||||
const std::string& provider_id);
|
||||
SignedDrmCertificate* GenerateSignedProvisionerCertificate(
|
||||
std::unique_ptr<SignedDrmCertificate> GenerateSignedProvisionerCertificate(
|
||||
uint32_t system_id, const std::string& serial_number,
|
||||
const std::string& service_id);
|
||||
DrmCertificate* GenerateIntermediateCertificate(
|
||||
std::unique_ptr<DrmCertificate> GenerateIntermediateCertificate(
|
||||
uint32_t system_id, const std::string& serial_number);
|
||||
SignedDrmCertificate* GenerateSignedIntermediateCertificate(
|
||||
std::unique_ptr<SignedDrmCertificate> GenerateSignedIntermediateCertificate(
|
||||
SignedDrmCertificate* signer, uint32_t system_id,
|
||||
const std::string& serial_number, DrmCertificate::Type signer_cert_type);
|
||||
DrmCertificate* GenerateDrmCertificate(
|
||||
std::unique_ptr<DrmCertificate> GenerateDrmCertificate(
|
||||
uint32_t system_id, const std::string& serial_number,
|
||||
DrmCertificate::Algorithm = DrmCertificate::RSA);
|
||||
SignedDrmCertificate* GenerateSignedDrmCertificate(
|
||||
std::unique_ptr<SignedDrmCertificate> GenerateSignedDrmCertificate(
|
||||
SignedDrmCertificate* signer, uint32_t system_id,
|
||||
const std::string& serial_number,
|
||||
DrmCertificate::Algorithm = DrmCertificate::RSA);
|
||||
|
||||
std::string GetPublicKeyByCertType(DrmCertificate::Type cert_type);
|
||||
std::string GetPrivateKeyByCertType(DrmCertificate::Type cert_type);
|
||||
std::string GetECCPrivateKey(DrmCertificate::Algorithm algorithm);
|
||||
std::string GetECCPublicKey(DrmCertificate::Algorithm algorithm);
|
||||
|
||||
RsaTestKeys test_rsa_keys_;
|
||||
@@ -136,8 +158,11 @@ void ClientCertTest::TestBasicValidation(const TestTokenAndKeys& expectation,
|
||||
Status status;
|
||||
std::unique_ptr<ClientCert> keybox_cert;
|
||||
|
||||
status = ClientCert::Create(root_cert_.get(), ClientIdentification::KEYBOX,
|
||||
expectation.token_, &keybox_cert);
|
||||
ClientIdentification client_id;
|
||||
client_id.set_type(ClientIdentification::KEYBOX);
|
||||
client_id.set_token(expectation.token_);
|
||||
|
||||
status = ClientCert::Create(root_cert_.get(), client_id, &keybox_cert);
|
||||
if (expect_success) {
|
||||
ASSERT_EQ(OkStatus(), status);
|
||||
ASSERT_TRUE(keybox_cert.get());
|
||||
@@ -163,12 +188,25 @@ void ClientCertTest::TestBasicValidationDrmCertificate(
|
||||
// Test validation of a valid request.
|
||||
Status status;
|
||||
std::unique_ptr<ClientCert> drm_certificate_cert;
|
||||
status = ClientCert::Create(root_cert_.get(),
|
||||
ClientIdentification::DRM_DEVICE_CERTIFICATE,
|
||||
expectation.certificate_, &drm_certificate_cert);
|
||||
ClientIdentification client_id;
|
||||
client_id.set_type(ClientIdentification::DRM_DEVICE_CERTIFICATE);
|
||||
client_id.set_token(expectation.certificate_);
|
||||
if (!expectation.encryption_certificate_.empty()) {
|
||||
client_id.mutable_device_credentials()->set_token(
|
||||
expectation.encryption_certificate_);
|
||||
client_id.mutable_device_credentials()->set_type(
|
||||
ClientIdentification::DRM_DEVICE_CERTIFICATE);
|
||||
}
|
||||
|
||||
status =
|
||||
ClientCert::Create(root_cert_.get(), client_id, &drm_certificate_cert);
|
||||
ASSERT_EQ(expectation.expected_status_, status);
|
||||
if (expectation.expected_status_.ok()) {
|
||||
ASSERT_TRUE(drm_certificate_cert.get());
|
||||
if (!expectation.encryption_certificate_.empty()) {
|
||||
ASSERT_TRUE(drm_certificate_cert->using_dual_certificate());
|
||||
}
|
||||
ASSERT_EQ(expectation.expected_key_type_, drm_certificate_cert->key_type());
|
||||
if (compare_data) {
|
||||
ASSERT_EQ(expectation.expected_serial_number_,
|
||||
drm_certificate_cert->signer_serial_number());
|
||||
@@ -182,26 +220,29 @@ void ClientCertTest::TestBasicValidationDrmCertificate(
|
||||
|
||||
void ClientCertTest::GenerateSignature(const std::string& message,
|
||||
const std::string& private_key,
|
||||
HashAlgorithm hash_algorithm,
|
||||
std::string* signature) {
|
||||
std::unique_ptr<RsaPrivateKey> rsa_private_key(
|
||||
RsaPrivateKey::Create(private_key));
|
||||
ASSERT_TRUE(rsa_private_key != nullptr);
|
||||
rsa_private_key->GenerateSignature(message, signature);
|
||||
rsa_private_key->GenerateSignature(message, hash_algorithm, signature);
|
||||
}
|
||||
|
||||
// The caller relinquishes ownership of |signer|, which may also be nullptr.
|
||||
SignedDrmCertificate* ClientCertTest::SignCertificate(
|
||||
const DrmCertificate& certificate, SignedDrmCertificate* signer,
|
||||
// The caller retains ownership of |signer|, which may also be nullptr.
|
||||
std::unique_ptr<SignedDrmCertificate> ClientCertTest::SignCertificate(
|
||||
const DrmCertificate& certificate, const SignedDrmCertificate* signer,
|
||||
const std::string& private_key) {
|
||||
std::unique_ptr<SignedDrmCertificate> signed_certificate(
|
||||
new SignedDrmCertificate);
|
||||
signed_certificate->set_drm_certificate(certificate.SerializeAsString());
|
||||
GenerateSignature(signed_certificate->drm_certificate(), private_key,
|
||||
signed_certificate->mutable_signature());
|
||||
GenerateSignature(
|
||||
signed_certificate->drm_certificate(), private_key,
|
||||
HashAlgorithmProtoToEnum(signed_certificate->hash_algorithm()),
|
||||
signed_certificate->mutable_signature());
|
||||
if (signer != nullptr) {
|
||||
signed_certificate->set_allocated_signer(signer);
|
||||
*(signed_certificate->mutable_signer()) = *signer;
|
||||
}
|
||||
return signed_certificate.release();
|
||||
return signed_certificate;
|
||||
}
|
||||
|
||||
std::string ClientCertTest::GetPublicKeyByCertType(
|
||||
@@ -224,6 +265,21 @@ std::string ClientCertTest::GetPrivateKeyByCertType(
|
||||
return test_rsa_keys_.private_test_key_1_3072_bits();
|
||||
}
|
||||
|
||||
std::string ClientCertTest::GetECCPrivateKey(
|
||||
DrmCertificate::Algorithm algorithm) {
|
||||
ECTestKeys keys;
|
||||
switch (algorithm) {
|
||||
case DrmCertificate::ECC_SECP256R1:
|
||||
return keys.private_test_key_1_secp256r1();
|
||||
case DrmCertificate::ECC_SECP384R1:
|
||||
return keys.private_test_key_1_secp384r1();
|
||||
case DrmCertificate::ECC_SECP521R1:
|
||||
return keys.private_test_key_1_secp521r1();
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
std::string ClientCertTest::GetECCPublicKey(
|
||||
DrmCertificate::Algorithm algorithm) {
|
||||
ECTestKeys keys;
|
||||
@@ -239,7 +295,7 @@ std::string ClientCertTest::GetECCPublicKey(
|
||||
}
|
||||
}
|
||||
|
||||
DrmCertificate* ClientCertTest::GenerateIntermediateCertificate(
|
||||
std::unique_ptr<DrmCertificate> ClientCertTest::GenerateIntermediateCertificate(
|
||||
uint32_t system_id, const std::string& serial_number) {
|
||||
std::unique_ptr<DrmCertificate> intermediate_certificate(new DrmCertificate);
|
||||
intermediate_certificate->set_type(DrmCertificate::DEVICE_MODEL);
|
||||
@@ -248,10 +304,11 @@ DrmCertificate* ClientCertTest::GenerateIntermediateCertificate(
|
||||
GetPublicKeyByCertType(DrmCertificate::DEVICE_MODEL));
|
||||
intermediate_certificate->set_system_id(system_id);
|
||||
intermediate_certificate->set_creation_time_seconds(1234);
|
||||
return intermediate_certificate.release();
|
||||
return intermediate_certificate;
|
||||
}
|
||||
|
||||
SignedDrmCertificate* ClientCertTest::GenerateSignedIntermediateCertificate(
|
||||
std::unique_ptr<SignedDrmCertificate>
|
||||
ClientCertTest::GenerateSignedIntermediateCertificate(
|
||||
SignedDrmCertificate* signer, uint32_t system_id,
|
||||
const std::string& serial_number, DrmCertificate::Type signer_cert_type) {
|
||||
std::unique_ptr<DrmCertificate> intermediate_certificate(
|
||||
@@ -261,7 +318,7 @@ SignedDrmCertificate* ClientCertTest::GenerateSignedIntermediateCertificate(
|
||||
GetPrivateKeyByCertType(signer_cert_type));
|
||||
}
|
||||
|
||||
DrmCertificate* ClientCertTest::GenerateDrmCertificate(
|
||||
std::unique_ptr<DrmCertificate> ClientCertTest::GenerateDrmCertificate(
|
||||
uint32_t system_id, const std::string& serial_number,
|
||||
DrmCertificate::Algorithm algorithm) {
|
||||
std::unique_ptr<DrmCertificate> drm_certificate(new DrmCertificate);
|
||||
@@ -274,10 +331,11 @@ DrmCertificate* ClientCertTest::GenerateDrmCertificate(
|
||||
: GetECCPublicKey(algorithm));
|
||||
drm_certificate->set_creation_time_seconds(4321);
|
||||
drm_certificate->set_algorithm(algorithm);
|
||||
return drm_certificate.release();
|
||||
return drm_certificate;
|
||||
}
|
||||
|
||||
SignedDrmCertificate* ClientCertTest::GenerateSignedDrmCertificate(
|
||||
std::unique_ptr<SignedDrmCertificate>
|
||||
ClientCertTest::GenerateSignedDrmCertificate(
|
||||
SignedDrmCertificate* signer, uint32_t system_id,
|
||||
const std::string& serial_number, DrmCertificate::Algorithm algorithm) {
|
||||
std::unique_ptr<DrmCertificate> drm_certificate(
|
||||
@@ -285,10 +343,10 @@ SignedDrmCertificate* ClientCertTest::GenerateSignedDrmCertificate(
|
||||
std::unique_ptr<SignedDrmCertificate> signed_drm_certificate(
|
||||
SignCertificate(*drm_certificate, signer,
|
||||
GetPrivateKeyByCertType(DrmCertificate::DEVICE_MODEL)));
|
||||
return signed_drm_certificate.release();
|
||||
return signed_drm_certificate;
|
||||
}
|
||||
|
||||
DrmCertificate* ClientCertTest::GenerateProvisionerCertificate(
|
||||
std::unique_ptr<DrmCertificate> ClientCertTest::GenerateProvisionerCertificate(
|
||||
uint32_t system_id, const std::string& serial_number,
|
||||
const std::string& provider_id) {
|
||||
std::unique_ptr<DrmCertificate> provisioner_certificate(new DrmCertificate);
|
||||
@@ -299,10 +357,11 @@ DrmCertificate* ClientCertTest::GenerateProvisionerCertificate(
|
||||
provisioner_certificate->set_system_id(system_id);
|
||||
provisioner_certificate->set_provider_id(provider_id);
|
||||
provisioner_certificate->set_creation_time_seconds(1234);
|
||||
return provisioner_certificate.release();
|
||||
return provisioner_certificate;
|
||||
}
|
||||
|
||||
SignedDrmCertificate* ClientCertTest::GenerateSignedProvisionerCertificate(
|
||||
std::unique_ptr<SignedDrmCertificate>
|
||||
ClientCertTest::GenerateSignedProvisionerCertificate(
|
||||
uint32_t system_id, const std::string& serial_number,
|
||||
const std::string& service_id) {
|
||||
std::unique_ptr<DrmCertificate> provisioner_certificate(
|
||||
@@ -341,22 +400,48 @@ TEST_F(ClientCertTest, BasicValidation) {
|
||||
TEST_P(ClientCertTest, BasicCertValidation) {
|
||||
const uint32_t system_id = 1234;
|
||||
const std::string serial_number("serial_number");
|
||||
std::unique_ptr<SignedDrmCertificate> signed_cert(
|
||||
GenerateSignedDrmCertificate(
|
||||
GenerateSignedIntermediateCertificate(nullptr, system_id,
|
||||
serial_number, kNoSigner),
|
||||
system_id, serial_number + "-device", GetParam()));
|
||||
std::unique_ptr<SignedDrmCertificate> intermediate_certificate =
|
||||
GenerateSignedIntermediateCertificate(nullptr, system_id, serial_number,
|
||||
kNoSigner);
|
||||
std::unique_ptr<SignedDrmCertificate> signed_cert =
|
||||
GenerateSignedDrmCertificate(intermediate_certificate.get(), system_id,
|
||||
serial_number + "-device1",
|
||||
std::get<0>(GetParam()));
|
||||
SignedMessage::SessionKeyType expected_key_type =
|
||||
std::get<0>(GetParam()) != DrmCertificate::RSA
|
||||
? SignedMessage::EPHEMERAL_ECC_PUBLIC_KEY
|
||||
: SignedMessage::WRAPPED_AES_KEY;
|
||||
std::unique_ptr<SignedDrmCertificate> encryption_certificate;
|
||||
if (std::get<1>(GetParam()) != DrmCertificate::UNKNOWN_ALGORITHM) {
|
||||
encryption_certificate = GenerateSignedDrmCertificate(
|
||||
intermediate_certificate.get(), system_id, serial_number + "-device2",
|
||||
std::get<1>(GetParam()));
|
||||
expected_key_type = std::get<1>(GetParam()) != DrmCertificate::RSA
|
||||
? SignedMessage::EPHEMERAL_ECC_PUBLIC_KEY
|
||||
: SignedMessage::WRAPPED_AES_KEY;
|
||||
}
|
||||
const TestCertificateAndData kValidCertificateAndExpectedData(
|
||||
signed_cert->SerializeAsString(), serial_number, system_id, OkStatus());
|
||||
signed_cert->SerializeAsString(),
|
||||
encryption_certificate == nullptr
|
||||
? std::string()
|
||||
: encryption_certificate->SerializeAsString(),
|
||||
serial_number, system_id, OkStatus(), expected_key_type);
|
||||
const bool compare_data = true;
|
||||
TestBasicValidationDrmCertificate(kValidCertificateAndExpectedData,
|
||||
compare_data);
|
||||
}
|
||||
INSTANTIATE_TEST_SUITE_P(BasicCertValidation, ClientCertTest,
|
||||
testing::Values(DrmCertificate::RSA,
|
||||
DrmCertificate::ECC_SECP256R1,
|
||||
DrmCertificate::ECC_SECP384R1,
|
||||
DrmCertificate::ECC_SECP521R1));
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
BasicCertValidation, ClientCertTest,
|
||||
testing::Combine(testing::Values(DrmCertificate::RSA,
|
||||
DrmCertificate::ECC_SECP256R1,
|
||||
DrmCertificate::ECC_SECP384R1,
|
||||
DrmCertificate::ECC_SECP521R1),
|
||||
testing::Values(DrmCertificate::UNKNOWN_ALGORITHM,
|
||||
DrmCertificate::RSA,
|
||||
DrmCertificate::ECC_SECP256R1,
|
||||
DrmCertificate::ECC_SECP384R1,
|
||||
DrmCertificate::ECC_SECP521R1)));
|
||||
|
||||
TEST_F(ClientCertTest, InvalidKeybox) {
|
||||
const TestTokenAndKeys kInvalidTokenAndExpectedKeys[] = {
|
||||
@@ -395,71 +480,80 @@ TEST_F(ClientCertTest, InvalidCertificate) {
|
||||
std::unique_ptr<SignedDrmCertificate> invalid_drm_cert(
|
||||
new SignedDrmCertificate);
|
||||
invalid_drm_cert->set_drm_certificate("bad-serialized-cert");
|
||||
GenerateSignature(invalid_drm_cert->drm_certificate(),
|
||||
test_rsa_keys_.private_test_key_2_2048_bits(),
|
||||
invalid_drm_cert->mutable_signature());
|
||||
invalid_drm_cert->set_allocated_signer(GenerateSignedIntermediateCertificate(
|
||||
nullptr, system_id, signer_sn, kNoSigner));
|
||||
GenerateSignature(
|
||||
invalid_drm_cert->drm_certificate(),
|
||||
test_rsa_keys_.private_test_key_2_2048_bits(),
|
||||
HashAlgorithmProtoToEnum(invalid_drm_cert->hash_algorithm()),
|
||||
invalid_drm_cert->mutable_signature());
|
||||
invalid_drm_cert->set_allocated_signer(
|
||||
GenerateSignedIntermediateCertificate(nullptr, system_id, signer_sn,
|
||||
kNoSigner)
|
||||
.release());
|
||||
// Invalid device public key.
|
||||
dev_cert.reset(GenerateDrmCertificate(system_id, device_sn));
|
||||
dev_cert = GenerateDrmCertificate(system_id, device_sn);
|
||||
dev_cert->set_public_key("bad-device-public-key");
|
||||
std::unique_ptr<SignedDrmCertificate> bad_device_public_key(
|
||||
std::unique_ptr<SignedDrmCertificate> bad_device_public_key =
|
||||
SignCertificate(*dev_cert,
|
||||
GenerateSignedIntermediateCertificate(
|
||||
nullptr, system_id, signer_sn, kNoSigner),
|
||||
test_rsa_keys_.private_test_key_2_2048_bits()));
|
||||
nullptr, system_id, signer_sn, kNoSigner)
|
||||
.get(),
|
||||
test_rsa_keys_.private_test_key_2_2048_bits());
|
||||
// Invalid serialized intermediate certificate.
|
||||
signed_signer.reset(GenerateSignedIntermediateCertificate(
|
||||
nullptr, system_id, signer_sn, kNoSigner));
|
||||
signed_signer = GenerateSignedIntermediateCertificate(nullptr, system_id,
|
||||
signer_sn, kNoSigner);
|
||||
signed_signer->set_drm_certificate("bad-serialized-cert");
|
||||
GenerateSignature(signed_signer->drm_certificate(),
|
||||
test_rsa_keys_.private_test_key_1_3072_bits(),
|
||||
HashAlgorithmProtoToEnum(signed_signer->hash_algorithm()),
|
||||
signed_signer->mutable_signature());
|
||||
dev_cert.reset(GenerateDrmCertificate(system_id, device_sn));
|
||||
dev_cert = GenerateDrmCertificate(system_id, device_sn);
|
||||
std::unique_ptr<SignedDrmCertificate> invalid_signer(
|
||||
SignCertificate(*dev_cert, signed_signer.release(),
|
||||
SignCertificate(*dev_cert, signed_signer.get(),
|
||||
test_rsa_keys_.private_test_key_2_2048_bits()));
|
||||
// Invalid signer public key.
|
||||
dev_cert.reset(GenerateDrmCertificate(system_id, device_sn));
|
||||
signer_cert.reset(GenerateIntermediateCertificate(system_id, signer_sn));
|
||||
dev_cert = GenerateDrmCertificate(system_id, device_sn);
|
||||
signer_cert = GenerateIntermediateCertificate(system_id, signer_sn);
|
||||
signer_cert->set_public_key("bad-signer-public-key");
|
||||
std::unique_ptr<SignedDrmCertificate> bad_signer_public_key(SignCertificate(
|
||||
*dev_cert,
|
||||
SignCertificate(*signer_cert, nullptr,
|
||||
test_rsa_keys_.private_test_key_1_3072_bits()),
|
||||
test_rsa_keys_.private_test_key_1_3072_bits())
|
||||
.get(),
|
||||
test_rsa_keys_.private_test_key_2_2048_bits()));
|
||||
// Invalid device certificate signature.
|
||||
std::unique_ptr<SignedDrmCertificate> bad_device_signature(
|
||||
GenerateSignedDrmCertificate(
|
||||
GenerateSignedIntermediateCertificate(nullptr, system_id, signer_sn,
|
||||
kNoSigner),
|
||||
system_id, device_sn));
|
||||
GenerateSignedDrmCertificate(GenerateSignedIntermediateCertificate(
|
||||
nullptr, system_id, signer_sn, kNoSigner)
|
||||
.get(),
|
||||
system_id, device_sn));
|
||||
bad_device_signature->set_signature("bad-signature");
|
||||
// Missing model system ID.
|
||||
dev_cert.reset(GenerateDrmCertificate(system_id, device_sn));
|
||||
signer_cert.reset(GenerateIntermediateCertificate(system_id, signer_sn));
|
||||
dev_cert = GenerateDrmCertificate(system_id, device_sn);
|
||||
signer_cert = GenerateIntermediateCertificate(system_id, signer_sn);
|
||||
signer_cert->clear_system_id();
|
||||
std::unique_ptr<SignedDrmCertificate> missing_model_sn(SignCertificate(
|
||||
*dev_cert,
|
||||
SignCertificate(*signer_cert, nullptr,
|
||||
test_rsa_keys_.private_test_key_1_3072_bits()),
|
||||
test_rsa_keys_.private_test_key_1_3072_bits())
|
||||
.get(),
|
||||
test_rsa_keys_.private_test_key_2_2048_bits()));
|
||||
// Missing signer serial number.
|
||||
dev_cert.reset(GenerateDrmCertificate(system_id, device_sn));
|
||||
signer_cert.reset(GenerateIntermediateCertificate(system_id, signer_sn));
|
||||
dev_cert = GenerateDrmCertificate(system_id, device_sn);
|
||||
signer_cert = GenerateIntermediateCertificate(system_id, signer_sn);
|
||||
signer_cert->clear_serial_number();
|
||||
std::unique_ptr<SignedDrmCertificate> missing_signer_sn(SignCertificate(
|
||||
*dev_cert,
|
||||
SignCertificate(*signer_cert, nullptr,
|
||||
test_rsa_keys_.private_test_key_1_3072_bits()),
|
||||
test_rsa_keys_.private_test_key_1_3072_bits())
|
||||
.get(),
|
||||
test_rsa_keys_.private_test_key_2_2048_bits()));
|
||||
// Invalid serialized intermediate certificate.
|
||||
dev_cert.reset(GenerateDrmCertificate(system_id, device_sn));
|
||||
signed_signer.reset(GenerateSignedIntermediateCertificate(
|
||||
nullptr, system_id, signer_sn, kNoSigner));
|
||||
dev_cert = GenerateDrmCertificate(system_id, device_sn);
|
||||
signed_signer = GenerateSignedIntermediateCertificate(nullptr, system_id,
|
||||
signer_sn, kNoSigner);
|
||||
signed_signer->set_signature("bad-signature");
|
||||
std::unique_ptr<SignedDrmCertificate> bad_signer_signature(
|
||||
SignCertificate(*dev_cert, signed_signer.release(),
|
||||
SignCertificate(*dev_cert, signed_signer.get(),
|
||||
test_rsa_keys_.private_test_key_2_2048_bits()));
|
||||
|
||||
const TestCertificateAndData kInvalidCertificate[] = {
|
||||
@@ -504,8 +598,11 @@ TEST_F(ClientCertTest, MissingPreProvKey) {
|
||||
"beaa24924907e128f9ff49b54a165cd9c33e6547537eb4d29fb7e8df3c2c1cd9"
|
||||
"2517a12f4922953e"));
|
||||
std::unique_ptr<ClientCert> client_cert_ptr;
|
||||
Status status = ClientCert::Create(
|
||||
root_cert_.get(), ClientIdentification::KEYBOX, token, &client_cert_ptr);
|
||||
ClientIdentification client_id;
|
||||
client_id.set_type(ClientIdentification::KEYBOX);
|
||||
client_id.set_token(token);
|
||||
Status status =
|
||||
ClientCert::Create(root_cert_.get(), client_id, &client_cert_ptr);
|
||||
ASSERT_EQ(MISSING_PRE_PROV_KEY, status.error_code());
|
||||
}
|
||||
|
||||
@@ -516,26 +613,27 @@ TEST_F(ClientCertTest, ValidProvisionerDeviceCert) {
|
||||
const std::string intermediate_serial_number("intermediate-serial-number");
|
||||
const std::string provisioner_serial_number("provisioner-serial-number");
|
||||
|
||||
std::unique_ptr<SignedDrmCertificate> signed_provisioner_cert(
|
||||
std::unique_ptr<SignedDrmCertificate> signed_provisioner_cert =
|
||||
GenerateSignedProvisionerCertificate(system_id, provisioner_serial_number,
|
||||
service_id));
|
||||
service_id);
|
||||
|
||||
std::unique_ptr<SignedDrmCertificate> signed_intermediate_cert(
|
||||
std::unique_ptr<SignedDrmCertificate> signed_intermediate_cert =
|
||||
GenerateSignedIntermediateCertificate(
|
||||
signed_provisioner_cert.release(), system_id,
|
||||
intermediate_serial_number, kProvisionerSigner));
|
||||
signed_provisioner_cert.get(), system_id, intermediate_serial_number,
|
||||
kProvisionerSigner);
|
||||
|
||||
std::unique_ptr<SignedDrmCertificate> signed_device_cert(
|
||||
GenerateSignedDrmCertificate(signed_intermediate_cert.release(),
|
||||
system_id, device_serial_number));
|
||||
std::unique_ptr<SignedDrmCertificate> signed_device_cert =
|
||||
GenerateSignedDrmCertificate(signed_intermediate_cert.get(), system_id,
|
||||
device_serial_number);
|
||||
|
||||
std::string serialized_cert;
|
||||
signed_device_cert->SerializeToString(&serialized_cert);
|
||||
std::unique_ptr<ClientCert> drm_cert;
|
||||
ClientIdentification client_id;
|
||||
client_id.set_type(ClientIdentification::DRM_DEVICE_CERTIFICATE);
|
||||
client_id.set_token(serialized_cert);
|
||||
|
||||
EXPECT_OK(ClientCert::Create(root_cert_.get(),
|
||||
ClientIdentification::DRM_DEVICE_CERTIFICATE,
|
||||
serialized_cert, &drm_cert));
|
||||
EXPECT_OK(ClientCert::Create(root_cert_.get(), client_id, &drm_cert));
|
||||
ASSERT_TRUE(drm_cert);
|
||||
|
||||
EXPECT_EQ(service_id, drm_cert->service_id());
|
||||
@@ -551,27 +649,28 @@ TEST_F(ClientCertTest, InvalidProvisionerDeviceCertEmptyServiceId) {
|
||||
const std::string intermediate_serial_number("intermediate-serial-number");
|
||||
const std::string provisioner_serial_number("provisioner-serial-number");
|
||||
|
||||
std::unique_ptr<SignedDrmCertificate> signed_provisioner_cert(
|
||||
std::unique_ptr<SignedDrmCertificate> signed_provisioner_cert =
|
||||
GenerateSignedProvisionerCertificate(system_id, provisioner_serial_number,
|
||||
service_id));
|
||||
service_id);
|
||||
|
||||
std::unique_ptr<SignedDrmCertificate> signed_intermediate_cert(
|
||||
GenerateSignedIntermediateCertificate(
|
||||
signed_provisioner_cert.release(), system_id,
|
||||
intermediate_serial_number, kProvisionerSigner));
|
||||
signed_provisioner_cert.get(), system_id, intermediate_serial_number,
|
||||
kProvisionerSigner));
|
||||
|
||||
std::unique_ptr<SignedDrmCertificate> signed_device_cert(
|
||||
GenerateSignedDrmCertificate(signed_intermediate_cert.release(),
|
||||
system_id, device_serial_number));
|
||||
std::unique_ptr<SignedDrmCertificate> signed_device_cert =
|
||||
GenerateSignedDrmCertificate(signed_intermediate_cert.get(), system_id,
|
||||
device_serial_number);
|
||||
|
||||
std::string serialized_cert;
|
||||
signed_device_cert->SerializeToString(&serialized_cert);
|
||||
std::unique_ptr<ClientCert> client_cert_ptr;
|
||||
ClientIdentification client_id;
|
||||
client_id.set_type(ClientIdentification::DRM_DEVICE_CERTIFICATE);
|
||||
client_id.set_token(serialized_cert);
|
||||
|
||||
EXPECT_EQ("missing-provisioning-service-id",
|
||||
ClientCert::Create(root_cert_.get(),
|
||||
ClientIdentification::DRM_DEVICE_CERTIFICATE,
|
||||
serialized_cert, &client_cert_ptr)
|
||||
ClientCert::Create(root_cert_.get(), client_id, &client_cert_ptr)
|
||||
.error_message());
|
||||
EXPECT_FALSE(client_cert_ptr);
|
||||
}
|
||||
@@ -584,29 +683,30 @@ TEST_F(ClientCertTest, InvalidProvisionerDeviceCertChain) {
|
||||
const std::string intermediate_serial_number("intermediate-serial-number");
|
||||
const std::string intermediate_serial_number2("intermediate-serial-number-2");
|
||||
|
||||
std::unique_ptr<SignedDrmCertificate> signed_intermediate_cert2(
|
||||
std::unique_ptr<SignedDrmCertificate> signed_intermediate_cert2 =
|
||||
GenerateSignedIntermediateCertificate(
|
||||
nullptr, system_id2, intermediate_serial_number2, kNoSigner));
|
||||
nullptr, system_id2, intermediate_serial_number2, kNoSigner);
|
||||
|
||||
// Instead of using a provisioner certificate to sign this intermediate
|
||||
// certificate, use another intermediate certificate. This is an invalid
|
||||
// chain and should generate an error when trying to create a client
|
||||
// certificate.
|
||||
std::unique_ptr<SignedDrmCertificate> signed_intermediate_cert(
|
||||
std::unique_ptr<SignedDrmCertificate> signed_intermediate_cert =
|
||||
GenerateSignedIntermediateCertificate(
|
||||
signed_intermediate_cert2.release(), system_id,
|
||||
intermediate_serial_number, kDeviceModelSigner));
|
||||
std::unique_ptr<SignedDrmCertificate> signed_device_cert(
|
||||
GenerateSignedDrmCertificate(signed_intermediate_cert.release(),
|
||||
system_id, device_serial_number));
|
||||
signed_intermediate_cert2.get(), system_id,
|
||||
intermediate_serial_number, kDeviceModelSigner);
|
||||
std::unique_ptr<SignedDrmCertificate> signed_device_cert =
|
||||
GenerateSignedDrmCertificate(signed_intermediate_cert.get(), system_id,
|
||||
device_serial_number);
|
||||
std::string serialized_cert;
|
||||
signed_device_cert->SerializeToString(&serialized_cert);
|
||||
std::unique_ptr<ClientCert> client_cert_ptr;
|
||||
ClientIdentification client_id;
|
||||
client_id.set_type(ClientIdentification::DRM_DEVICE_CERTIFICATE);
|
||||
client_id.set_token(serialized_cert);
|
||||
|
||||
ASSERT_EQ("expected-provisioning-provider-certificate-type",
|
||||
ClientCert::Create(root_cert_.get(),
|
||||
ClientIdentification::DRM_DEVICE_CERTIFICATE,
|
||||
serialized_cert, &client_cert_ptr)
|
||||
ClientCert::Create(root_cert_.get(), client_id, &client_cert_ptr)
|
||||
.error_message());
|
||||
EXPECT_FALSE(client_cert_ptr);
|
||||
}
|
||||
@@ -619,32 +719,33 @@ TEST_F(ClientCertTest, InvalidDeviceCertChainSize_TooLong) {
|
||||
const std::string intermediate_serial_number2("intermediate-serial-number-2");
|
||||
const std::string provisioner_serial_number("provisioner-serial-number");
|
||||
|
||||
std::unique_ptr<SignedDrmCertificate> signed_provisioner_cert(
|
||||
std::unique_ptr<SignedDrmCertificate> signed_provisioner_cert =
|
||||
GenerateSignedProvisionerCertificate(system_id, provisioner_serial_number,
|
||||
service_id));
|
||||
service_id);
|
||||
|
||||
std::unique_ptr<SignedDrmCertificate> signed_intermediate_cert1(
|
||||
std::unique_ptr<SignedDrmCertificate> signed_intermediate_cert1 =
|
||||
GenerateSignedIntermediateCertificate(
|
||||
signed_provisioner_cert.release(), system_id,
|
||||
intermediate_serial_number1, kProvisionerSigner));
|
||||
signed_provisioner_cert.get(), system_id, intermediate_serial_number1,
|
||||
kProvisionerSigner);
|
||||
|
||||
std::unique_ptr<SignedDrmCertificate> signed_intermediate_cert2(
|
||||
std::unique_ptr<SignedDrmCertificate> signed_intermediate_cert2 =
|
||||
GenerateSignedIntermediateCertificate(
|
||||
signed_intermediate_cert1.release(), system_id,
|
||||
intermediate_serial_number2, kDeviceModelSigner));
|
||||
signed_intermediate_cert1.get(), system_id,
|
||||
intermediate_serial_number2, kDeviceModelSigner);
|
||||
|
||||
std::unique_ptr<SignedDrmCertificate> signed_device_cert(
|
||||
GenerateSignedDrmCertificate(signed_intermediate_cert2.release(),
|
||||
system_id, device_serial_number));
|
||||
std::unique_ptr<SignedDrmCertificate> signed_device_cert =
|
||||
GenerateSignedDrmCertificate(signed_intermediate_cert2.get(), system_id,
|
||||
device_serial_number);
|
||||
|
||||
std::string serialized_cert;
|
||||
signed_device_cert->SerializeToString(&serialized_cert);
|
||||
std::unique_ptr<ClientCert> client_cert_ptr = nullptr;
|
||||
ClientIdentification client_id;
|
||||
client_id.set_type(ClientIdentification::DRM_DEVICE_CERTIFICATE);
|
||||
client_id.set_token(serialized_cert);
|
||||
|
||||
ASSERT_EQ("certificate-chain-size-exceeded",
|
||||
ClientCert::Create(root_cert_.get(),
|
||||
ClientIdentification::DRM_DEVICE_CERTIFICATE,
|
||||
serialized_cert, &client_cert_ptr)
|
||||
ClientCert::Create(root_cert_.get(), client_id, &client_cert_ptr)
|
||||
.error_message());
|
||||
EXPECT_FALSE(client_cert_ptr);
|
||||
}
|
||||
@@ -656,26 +757,27 @@ TEST_F(ClientCertTest, DeviceCertTypeNotLeaf) {
|
||||
const std::string provisioner_serial_number("provisioner-serial-number");
|
||||
const std::string drm_serial_number("drm-serial-number");
|
||||
|
||||
std::unique_ptr<SignedDrmCertificate> signed_provisioner_cert(
|
||||
std::unique_ptr<SignedDrmCertificate> signed_provisioner_cert =
|
||||
GenerateSignedProvisionerCertificate(system_id, provisioner_serial_number,
|
||||
service_id));
|
||||
service_id);
|
||||
|
||||
// Use a DEVICE certificate as the intermediate certificate.
|
||||
std::unique_ptr<SignedDrmCertificate> signed_intermediate_cert(
|
||||
GenerateSignedDrmCertificate(signed_provisioner_cert.release(), system_id,
|
||||
intermediate_serial_number));
|
||||
std::unique_ptr<SignedDrmCertificate> signed_intermediate_cert =
|
||||
GenerateSignedDrmCertificate(signed_provisioner_cert.get(), system_id,
|
||||
intermediate_serial_number);
|
||||
|
||||
std::unique_ptr<SignedDrmCertificate> signed_drm_cert(
|
||||
GenerateSignedDrmCertificate(signed_intermediate_cert.release(),
|
||||
system_id, drm_serial_number));
|
||||
std::unique_ptr<SignedDrmCertificate> signed_drm_cert =
|
||||
GenerateSignedDrmCertificate(signed_intermediate_cert.get(), system_id,
|
||||
drm_serial_number);
|
||||
std::string serialized_cert;
|
||||
signed_drm_cert->SerializeToString(&serialized_cert);
|
||||
std::unique_ptr<ClientCert> client_cert_ptr;
|
||||
ClientIdentification client_id;
|
||||
client_id.set_type(ClientIdentification::DRM_DEVICE_CERTIFICATE);
|
||||
client_id.set_token(serialized_cert);
|
||||
|
||||
EXPECT_EQ("device-cert-must-be-leaf",
|
||||
ClientCert::Create(root_cert_.get(),
|
||||
ClientIdentification::DRM_DEVICE_CERTIFICATE,
|
||||
serialized_cert, &client_cert_ptr)
|
||||
ClientCert::Create(root_cert_.get(), client_id, &client_cert_ptr)
|
||||
.error_message());
|
||||
EXPECT_FALSE(client_cert_ptr);
|
||||
}
|
||||
@@ -686,21 +788,22 @@ TEST_F(ClientCertTest, InvalidLeafCertificateType) {
|
||||
const std::string intermediate_serial_number("intermediate-serial-number");
|
||||
const std::string provisioner_serial_number("provisioner-serial-number");
|
||||
|
||||
std::unique_ptr<SignedDrmCertificate> signed_provisioner_cert(
|
||||
std::unique_ptr<SignedDrmCertificate> signed_provisioner_cert =
|
||||
GenerateSignedProvisionerCertificate(system_id, provisioner_serial_number,
|
||||
service_id));
|
||||
std::unique_ptr<SignedDrmCertificate> signed_intermediate_cert(
|
||||
service_id);
|
||||
std::unique_ptr<SignedDrmCertificate> signed_intermediate_cert =
|
||||
GenerateSignedIntermediateCertificate(
|
||||
signed_provisioner_cert.release(), system_id,
|
||||
intermediate_serial_number, kProvisionerSigner));
|
||||
signed_provisioner_cert.get(), system_id, intermediate_serial_number,
|
||||
kProvisionerSigner);
|
||||
std::string serialized_cert;
|
||||
signed_intermediate_cert->SerializeToString(&serialized_cert);
|
||||
std::unique_ptr<ClientCert> client_cert_ptr;
|
||||
ClientIdentification client_id;
|
||||
client_id.set_type(ClientIdentification::DRM_DEVICE_CERTIFICATE);
|
||||
client_id.set_token(serialized_cert);
|
||||
// Leaf certificate must be a device certificate.
|
||||
EXPECT_EQ("expected-device-certificate-type",
|
||||
ClientCert::Create(root_cert_.get(),
|
||||
ClientIdentification::DRM_DEVICE_CERTIFICATE,
|
||||
serialized_cert, &client_cert_ptr)
|
||||
ClientCert::Create(root_cert_.get(), client_id, &client_cert_ptr)
|
||||
.error_message());
|
||||
EXPECT_FALSE(client_cert_ptr);
|
||||
}
|
||||
@@ -709,9 +812,10 @@ TEST_F(ClientCertTest, Protocol21WithDrmCert) {
|
||||
const char message[] = "A weekend wasted is a weekend well spent.";
|
||||
|
||||
std::unique_ptr<ClientCert> client_cert;
|
||||
ASSERT_OK(ClientCert::Create(
|
||||
root_cert_.get(), ClientIdentification::DRM_DEVICE_CERTIFICATE,
|
||||
test_drm_certs_.test_user_device_certificate(), &client_cert));
|
||||
ClientIdentification client_id;
|
||||
client_id.set_type(ClientIdentification::DRM_DEVICE_CERTIFICATE);
|
||||
client_id.set_token(test_drm_certs_.test_user_device_certificate());
|
||||
ASSERT_OK(ClientCert::Create(root_cert_.get(), client_id, &client_cert));
|
||||
|
||||
std::unique_ptr<RsaPrivateKey> private_key(
|
||||
RsaPrivateKey::Create(test_rsa_keys_.private_test_key_3_2048_bits()));
|
||||
@@ -719,14 +823,16 @@ TEST_F(ClientCertTest, Protocol21WithDrmCert) {
|
||||
|
||||
// Success
|
||||
std::string signature;
|
||||
ASSERT_TRUE(private_key->GenerateSignature(message, &signature));
|
||||
EXPECT_OK(client_cert->VerifySignature(message, signature, VERSION_2_1));
|
||||
ASSERT_TRUE(private_key->GenerateSignature(message, kSha256, &signature));
|
||||
EXPECT_OK(
|
||||
client_cert->VerifySignature(message, kSha256, signature, VERSION_2_1));
|
||||
|
||||
// Failure
|
||||
ASSERT_EQ(256, signature.size());
|
||||
++signature[127];
|
||||
EXPECT_FALSE(
|
||||
client_cert->VerifySignature(message, signature, VERSION_2_1).ok());
|
||||
client_cert->VerifySignature(message, kSha256, signature, VERSION_2_1)
|
||||
.ok());
|
||||
}
|
||||
|
||||
TEST_F(ClientCertTest, Protocol22WithDrmCert) {
|
||||
@@ -734,9 +840,10 @@ TEST_F(ClientCertTest, Protocol22WithDrmCert) {
|
||||
const std::string message_hash(Sha512_Hash(message));
|
||||
|
||||
std::unique_ptr<ClientCert> client_cert;
|
||||
ASSERT_OK(ClientCert::Create(
|
||||
root_cert_.get(), ClientIdentification::DRM_DEVICE_CERTIFICATE,
|
||||
test_drm_certs_.test_user_device_certificate(), &client_cert));
|
||||
ClientIdentification client_id;
|
||||
client_id.set_type(ClientIdentification::DRM_DEVICE_CERTIFICATE);
|
||||
client_id.set_token(test_drm_certs_.test_user_device_certificate());
|
||||
ASSERT_OK(ClientCert::Create(root_cert_.get(), client_id, &client_cert));
|
||||
|
||||
std::unique_ptr<RsaPrivateKey> private_key(
|
||||
RsaPrivateKey::Create(test_rsa_keys_.private_test_key_3_2048_bits()));
|
||||
@@ -744,14 +851,17 @@ TEST_F(ClientCertTest, Protocol22WithDrmCert) {
|
||||
|
||||
// Success
|
||||
std::string signature;
|
||||
ASSERT_TRUE(private_key->GenerateSignature(message_hash, &signature));
|
||||
EXPECT_OK(client_cert->VerifySignature(message, signature, VERSION_2_2));
|
||||
ASSERT_TRUE(
|
||||
private_key->GenerateSignature(message_hash, kSha256, &signature));
|
||||
EXPECT_OK(
|
||||
client_cert->VerifySignature(message, kSha256, signature, VERSION_2_2));
|
||||
|
||||
// Failure
|
||||
ASSERT_EQ(256, signature.size());
|
||||
++signature[127];
|
||||
EXPECT_FALSE(
|
||||
client_cert->VerifySignature(message, signature, VERSION_2_2).ok());
|
||||
client_cert->VerifySignature(message, kSha256, signature, VERSION_2_2)
|
||||
.ok());
|
||||
}
|
||||
|
||||
} // namespace widevine
|
||||
|
||||
Reference in New Issue
Block a user