Files
provisioning_sdk_source/provisioning_sdk/internal/provisioning_engine_impl_test.cc
2020-09-21 15:54:27 -07:00

723 lines
29 KiB
C++

////////////////////////////////////////////////////////////////////////////////
// Copyright 2016 Google LLC.
//
// This software is licensed under the terms defined in the Widevine Master
// License Agreement. For a copy of this agreement, please contact
// widevine-licensing@google.com.
////////////////////////////////////////////////////////////////////////////////
#include "provisioning_sdk/internal/provisioning_engine_impl.h"
#include <ctime>
#include <memory>
#include "glog/logging.h"
#include "testing/gmock.h"
#include "testing/gunit.h"
#include "common/certificate_type.h"
#include "common/mock_rsa_key.h"
#include "common/rsa_test_keys.h"
#include "common/rsa_util.h"
#include "common/test_drm_certificates.h"
using ::testing::_;
using ::testing::ByMove;
using ::testing::DoAll;
using ::testing::Invoke;
using ::testing::Return;
using ::testing::SaveArg;
using ::testing::SetArgPointee;
using ::testing::StrEq;
namespace {
const int kSystemId = 100;
const int kExpirationPeriodSeconds = 3600;
const int kInfiniteExpirationPeriodSeconds = 0;
const char kEmptyOemSerialNumber[] = "";
const char kSecretSauce[] = "Twas bryllyg, and ye slythy toves";
const char RootCertificateSerialNumber[] = "certificate_serial_number";
const char kDrmRootPublicKey[] = "drm_root_public_key";
const char kOemSerialNumber0[] = "oem_serial_number_0";
const char kOemSerialNumber1[] = "oem_serial_number_1";
const char kDevicePublicKey[] = "device_public_key";
const char kSignature[] = "mock_signature";
const char kIntermediatePrivateKey[] = "intermediate_private_key";
const char kIntermediatePrivateKeyPassphrase[] =
"intermediate_private_key_passphrase";
const char kIntermediatePublicKey[] = "intermediate_public_key";
const char kServicePrivateKeyPassphrase[] = "service_private_key_passphrase";
const char kProvisioningDrmCertificate[] = "provisioning_drm_certificate";
const char kProvisioningPrivateKey[] = "provisioning_private_key";
const char kProvisioningPrivateKeyPassphrase[] =
"provisioning_private_key_passphrase";
const char kProvisioningPublicKey[] = "provisioning_public_key";
const char kProvisioningSignature[] = "provisioning_signature";
// A simple std::string concatenation function. This assumes i within [0, 9].
std::string StrCat(const std::string& in, int i) {
DCHECK_LE(i, 9);
DCHECK_GE(i, 0);
std::string out = in + "0";
out[out.size() - 1] += i;
return out;
}
} // namespace
namespace widevine {
class MockDrmRootCertificate : public DrmRootCertificate {
public:
MockDrmRootCertificate()
: DrmRootCertificate(kCertificateTypeTesting, std::string(),
std::string(), kDrmRootPublicKey,
std::unique_ptr<RsaKeyFactory>()) {}
MOCK_METHOD(Status, VerifyCertificate,
(const std::string& serialized_cert,
SignedDrmCertificate* signed_drm_cert, DrmCertificate* drm_cert),
(const, override));
};
class ProvisioningEngineImplTest : public ::testing::Test {
protected:
ProvisioningEngineImplTest() {
RsaTestKeys test_keys;
rsa_util::RsaPrivateKeyToEncryptedPrivateKeyInfo(
test_keys.private_test_key_2_2048_bits(), kServicePrivateKeyPassphrase,
&service_private_key_);
TestDrmCertificates test_certificates;
service_certificate_ = test_certificates.test_service_certificate_no_type();
}
ProvisioningStatus CheckDeviceStatus(
uint32_t system_id, const std::string& oem_ca_serial_number) {
return engine_impl_.CheckDeviceStatus(system_id, oem_ca_serial_number);
}
ProvisioningEngineImpl engine_impl_;
std::string service_certificate_;
std::string service_private_key_;
};
TEST_F(ProvisioningEngineImplTest, InvalidDrmServiceCertificate) {
EXPECT_EQ(INVALID_SERVICE_DRM_CERTIFICATE,
engine_impl_.Initialize(
kCertificateTypeTesting, "bad-certificate",
service_private_key_, kServicePrivateKeyPassphrase,
kProvisioningDrmCertificate, kProvisioningPrivateKey,
kProvisioningPrivateKeyPassphrase, kSecretSauce));
}
TEST_F(ProvisioningEngineImplTest, InvalidServiceKey) {
EXPECT_EQ(INVALID_SERVICE_DRM_CERTIFICATE,
engine_impl_.Initialize(
kCertificateTypeTesting, service_certificate_, "bad_key",
kServicePrivateKeyPassphrase, kProvisioningDrmCertificate,
kProvisioningPrivateKey, kProvisioningPrivateKeyPassphrase,
kSecretSauce));
}
TEST_F(ProvisioningEngineImplTest, InvalidServiceKeyPassprase) {
EXPECT_EQ(INVALID_SERVICE_DRM_CERTIFICATE,
engine_impl_.Initialize(
kCertificateTypeTesting, service_certificate_,
service_private_key_, "bad-passphrase",
kProvisioningDrmCertificate, kProvisioningPrivateKey,
kProvisioningPrivateKeyPassphrase, kSecretSauce));
}
class ProvisioningEngineImplProvTest : public ProvisioningEngineImplTest {
protected:
void SetUp() override {
prov_cert_.set_public_key(kProvisioningPublicKey);
prov_cert_.set_type(DrmCertificate::PROVISIONER);
signed_prov_cert_.set_drm_certificate(prov_cert_.SerializeAsString());
signed_prov_cert_.set_signature(kProvisioningSignature);
SetUpMockDrmRootCertificateWithExpectations();
SetUpMockRsa();
SetUpMockRootPublicKey();
}
void SetUpMockDrmRootCertificateWithExpectations() {
mock_drm_root_certificate_ = new MockDrmRootCertificate;
engine_impl_.set_drm_root_certificate(
std::unique_ptr<DrmRootCertificate>(mock_drm_root_certificate_));
EXPECT_CALL(*mock_drm_root_certificate_, VerifyCertificate(_, _, _))
.WillRepeatedly(Invoke([](const std::string& serialized_cert,
SignedDrmCertificate* signed_drm_cert,
DrmCertificate* drm_cert) {
SignedDrmCertificate signed_cert;
if (!signed_cert.ParseFromString(serialized_cert)) {
return Status(error::INVALID_ARGUMENT,
"Invalid SignedDrmCertificate proto");
}
if (signed_drm_cert) *signed_drm_cert = signed_cert;
if (drm_cert) {
EXPECT_TRUE(
drm_cert->ParseFromString(signed_cert.drm_certificate()));
}
return OkStatus();
}));
}
void SetUpMockRsa() {
mock_rsa_key_factory_ = new MockRsaKeyFactory;
engine_impl_.set_rsa_key_factory(
std::unique_ptr<RsaKeyFactory>(mock_rsa_key_factory_));
}
void SetUpMockRootPublicKey() {
mock_root_public_key_ = new MockRsaPublicKey();
EXPECT_CALL(*mock_rsa_key_factory_,
CreateFromPkcs1PublicKey(kDrmRootPublicKey))
.WillOnce(Return(
ByMove(std::unique_ptr<RsaPublicKey>(mock_root_public_key_))));
}
ProvisioningStatus Initialize(
const std::string& provisioning_drm_certificate) {
return engine_impl_.Initialize(
kCertificateTypeTesting, service_certificate_, service_private_key_,
kServicePrivateKeyPassphrase, provisioning_drm_certificate,
kProvisioningPrivateKey, kProvisioningPrivateKeyPassphrase,
kSecretSauce);
}
RsaTestKeys test_keys_;
MockRsaKeyFactory* mock_rsa_key_factory_ = nullptr;
MockDrmRootCertificate* mock_drm_root_certificate_ = nullptr;
MockRsaPublicKey* mock_root_public_key_ = nullptr;
DrmCertificate prov_cert_;
SignedDrmCertificate signed_prov_cert_;
};
TEST_F(ProvisioningEngineImplProvTest, InvalidDeviceCertType) {
prov_cert_.set_type(DrmCertificate::SERVICE);
signed_prov_cert_.set_drm_certificate(prov_cert_.SerializeAsString());
EXPECT_EQ(INVALID_PROVISIONER_DRM_CERTIFICATE,
Initialize(signed_prov_cert_.SerializeAsString()));
}
TEST_F(ProvisioningEngineImplProvTest, InvalidPublicKey) {
EXPECT_CALL(*mock_rsa_key_factory_,
CreateFromPkcs1PublicKey(kProvisioningPublicKey))
.WillOnce(Return(ByMove(nullptr)));
EXPECT_EQ(INVALID_PROVISIONER_DRM_CERTIFICATE,
Initialize(signed_prov_cert_.SerializeAsString()));
}
TEST_F(ProvisioningEngineImplProvTest, InvalidPrivateKey) {
EXPECT_CALL(*mock_rsa_key_factory_,
CreateFromPkcs1PublicKey(kProvisioningPublicKey))
.WillOnce(
Return(ByMove(std::unique_ptr<RsaPublicKey>(new MockRsaPublicKey))));
EXPECT_CALL(*mock_rsa_key_factory_,
CreateFromPkcs8PrivateKey(kProvisioningPrivateKey,
kProvisioningPrivateKeyPassphrase))
.WillOnce(Return(ByMove(nullptr)));
EXPECT_EQ(INVALID_PROVISIONER_PRIVATE_KEY,
Initialize(signed_prov_cert_.SerializeAsString()));
}
TEST_F(ProvisioningEngineImplProvTest, MismatchPublicKeyPrivateKey) {
MockRsaPublicKey* mock_rsa_public_key = new MockRsaPublicKey;
EXPECT_CALL(*mock_rsa_key_factory_,
CreateFromPkcs1PublicKey(kProvisioningPublicKey))
.WillOnce(
Return(ByMove(std::unique_ptr<RsaPublicKey>(mock_rsa_public_key))));
MockRsaPrivateKey* mock_rsa_private_key = new MockRsaPrivateKey;
EXPECT_CALL(*mock_rsa_key_factory_,
CreateFromPkcs8PrivateKey(kProvisioningPrivateKey,
kProvisioningPrivateKeyPassphrase))
.WillOnce(
Return(ByMove(std::unique_ptr<RsaPrivateKey>(mock_rsa_private_key))));
EXPECT_CALL(*mock_rsa_public_key, MatchesPrivateKey(_))
.WillOnce(Return(false));
EXPECT_EQ(INVALID_PROVISIONER_PRIVATE_KEY,
Initialize(signed_prov_cert_.SerializeAsString()));
}
class ProvisioningEngineImplContextTest
: public ProvisioningEngineImplProvTest {
protected:
void SetUp() override {
ProvisioningEngineImplProvTest::SetUp();
SetUpMockRsaExpectations();
ASSERT_EQ(OK, ProvisioningEngineImplProvTest::Initialize(
signed_prov_cert_.SerializeAsString()));
}
void SetUpMockRsaExpectations() {
MockRsaPublicKey* mock_prov_public_key(new MockRsaPublicKey);
EXPECT_CALL(*mock_rsa_key_factory_,
CreateFromPkcs1PublicKey(kProvisioningPublicKey))
.WillOnce(Return(
ByMove(std::unique_ptr<RsaPublicKey>(mock_prov_public_key))));
EXPECT_CALL(*mock_rsa_key_factory_,
CreateFromPkcs8PrivateKey(kProvisioningPrivateKey,
kProvisioningPrivateKeyPassphrase))
.WillOnce(Return(
ByMove(std::unique_ptr<RsaPrivateKey>(new MockRsaPrivateKey))));
EXPECT_CALL(*mock_prov_public_key, MatchesPrivateKey(_))
.WillOnce(Return(true));
}
};
TEST_F(ProvisioningEngineImplContextTest, ContextStoreAndRetrieveSuccess) {
const char kContextData[] = "I dislike tacky orange things";
SignedProvisioningContext signed_context;
ASSERT_EQ(OK, engine_impl_.StoreContext(kContextData, &signed_context));
EXPECT_FALSE(signed_context.signature().empty());
std::string context_data;
ASSERT_EQ(OK, engine_impl_.RetrieveContext(signed_context, &context_data));
EXPECT_EQ(kContextData, context_data);
}
TEST_F(ProvisioningEngineImplContextTest, ContextStoreAndRetrieveFailBadData) {
const char kContextData[] = "Climate change is not a hoax";
SignedProvisioningContext signed_context;
ASSERT_EQ(OK, engine_impl_.StoreContext(kContextData, &signed_context));
++(*signed_context.mutable_provisioning_context())[5];
std::string context_data;
ASSERT_EQ(INVALID_CONTEXT,
engine_impl_.RetrieveContext(signed_context, &context_data));
}
TEST_F(ProvisioningEngineImplContextTest,
ContextStoreAndRetrieveFailBadSignature) {
const char kContextData[] = "No one wants coal anymore";
SignedProvisioningContext signed_context;
ASSERT_EQ(OK, engine_impl_.StoreContext(kContextData, &signed_context));
++(*signed_context.mutable_signature())[5];
std::string context_data;
ASSERT_EQ(INVALID_CONTEXT,
engine_impl_.RetrieveContext(signed_context, &context_data));
}
class ProvisioningEngineImplGeneralTest
: public ProvisioningEngineImplProvTest {
protected:
void SetUp() override {
ProvisioningEngineImplProvTest::SetUp();
SetUpMockProvisionerKey();
// Set up a DrmCertificate to be used later.
intermediate_cert_.set_type(DrmCertificate::DEVICE_MODEL);
intermediate_cert_.set_system_id(kSystemId);
intermediate_cert_.set_public_key(kIntermediatePublicKey);
signed_intermediate_cert_.set_drm_certificate(
intermediate_cert_.SerializeAsString());
signed_intermediate_cert_.set_signature(kSignature);
ASSERT_EQ(OK, ProvisioningEngineImplProvTest::Initialize(
signed_prov_cert_.SerializeAsString()));
}
void SetUpMockProvisionerKey() {
mock_prov_public_key_ = new MockRsaPublicKey();
EXPECT_CALL(*mock_rsa_key_factory_,
CreateFromPkcs1PublicKey(kProvisioningPublicKey))
.WillOnce(Return(
ByMove(std::unique_ptr<RsaPublicKey>(mock_prov_public_key_))));
mock_prov_private_key_ = new MockRsaPrivateKey();
ON_CALL(*mock_rsa_key_factory_,
CreateFromPkcs8PrivateKey(kProvisioningPrivateKey,
kProvisioningPrivateKeyPassphrase))
.WillByDefault(Return(
ByMove(std::unique_ptr<RsaPrivateKey>(mock_prov_private_key_))));
EXPECT_CALL(*mock_prov_public_key_, MatchesPrivateKey(_))
.WillOnce(Return(true));
}
void SetUpDcsl() {
// SetUp certificate status list.
cert_status_list_.set_creation_time_seconds(time(nullptr));
for (int i = 0; i < 2; ++i) {
DeviceCertificateStatus* cert_status =
cert_status_list_.add_certificate_status();
cert_status->set_oem_serial_number(StrCat("oem_serial_number_", i));
ProvisionedDeviceInfo* device_info = cert_status->mutable_device_info();
device_info->set_system_id(kSystemId + i);
device_info->set_model(StrCat("model_", i));
}
cert_status_list_.mutable_certificate_status(0)->set_status(
DeviceCertificateStatus::STATUS_RELEASED);
cert_status_list_.mutable_certificate_status(1)->set_status(
DeviceCertificateStatus::STATUS_REVOKED);
SignedDeviceCertificateStatusList signed_cert_status_list;
signed_cert_status_list.set_certificate_status_list(
cert_status_list_.SerializeAsString());
EXPECT_CALL(*mock_root_public_key_,
VerifySignature(
StrEq(signed_cert_status_list.certificate_status_list()), _,
"cert_status_list_signature"))
.WillOnce(Return(true));
signed_cert_status_list.set_signature("cert_status_list_signature");
ASSERT_EQ(OK, engine_impl_.SetCertificateStatusList(
signed_cert_status_list.SerializeAsString(),
kInfiniteExpirationPeriodSeconds));
}
MockRsaPublicKey* mock_prov_public_key_ = nullptr;
MockRsaPrivateKey* mock_prov_private_key_ = nullptr;
DeviceCertificateStatusList cert_status_list_;
DrmCertificate intermediate_cert_;
SignedDrmCertificate signed_intermediate_cert_;
};
TEST_F(ProvisioningEngineImplGeneralTest, InvalidCertificateStatusList) {
EXPECT_EQ(INVALID_STATUS_LIST, engine_impl_.SetCertificateStatusList(
"", kExpirationPeriodSeconds));
EXPECT_EQ(INVALID_STATUS_LIST,
engine_impl_.SetCertificateStatusList(
"invalid_certificate_status_list", kExpirationPeriodSeconds));
}
TEST_F(ProvisioningEngineImplGeneralTest,
CertificateStatusListIncorrectSignature) {
SignedDeviceCertificateStatusList signed_cert_status_list;
signed_cert_status_list.set_certificate_status_list(
cert_status_list_.SerializeAsString());
EXPECT_CALL(*mock_root_public_key_,
VerifySignature(_, _, "cert_status_list_signature"))
.WillOnce(Return(false));
signed_cert_status_list.set_signature("cert_status_list_signature");
ASSERT_EQ(INVALID_STATUS_LIST,
engine_impl_.SetCertificateStatusList(
signed_cert_status_list.SerializeAsString(),
kExpirationPeriodSeconds));
}
TEST_F(ProvisioningEngineImplGeneralTest, GetDeviceInfoAndCheckDeviceStatus) {
SetUpDcsl();
EXPECT_EQ(OK, CheckDeviceStatus(kSystemId, kEmptyOemSerialNumber));
auto device_info = engine_impl_.GetDeviceInfo(kSystemId);
ASSERT_NE(nullptr, device_info);
EXPECT_EQ("model_0", device_info->model());
EXPECT_EQ(DEVICE_REVOKED,
CheckDeviceStatus(kSystemId + 1, kEmptyOemSerialNumber));
// We can still query device info for revoked device.
device_info = engine_impl_.GetDeviceInfo(kSystemId + 1);
ASSERT_NE(nullptr, device_info);
EXPECT_EQ("model_1", device_info->model());
EXPECT_EQ(UNKNOWN_SYSTEM_ID,
CheckDeviceStatus(kSystemId + 2, kEmptyOemSerialNumber));
EXPECT_EQ(nullptr, engine_impl_.GetDeviceInfo(kSystemId + 2));
}
TEST_F(ProvisioningEngineImplGeneralTest, UpdateCertificateStatusList) {
SetUpDcsl();
cert_status_list_.mutable_certificate_status(0)->set_status(
DeviceCertificateStatus::STATUS_REVOKED);
DeviceCertificateStatus* cert_status =
cert_status_list_.add_certificate_status();
ProvisionedDeviceInfo* device_info = cert_status->mutable_device_info();
device_info->set_system_id(kSystemId + 2);
device_info->set_model("model_2");
SignedDeviceCertificateStatusList signed_cert_status_list;
signed_cert_status_list.set_certificate_status_list(
cert_status_list_.SerializeAsString());
EXPECT_CALL(*mock_root_public_key_,
VerifySignature(_, _, "cert_status_list_signature"))
.WillOnce(Return(true));
signed_cert_status_list.set_signature("cert_status_list_signature");
ASSERT_EQ(OK, engine_impl_.SetCertificateStatusList(
signed_cert_status_list.SerializeAsString(),
kInfiniteExpirationPeriodSeconds));
// Now device with system id = kSystemId is revoked.
EXPECT_EQ(DEVICE_REVOKED,
CheckDeviceStatus(kSystemId, kEmptyOemSerialNumber));
EXPECT_EQ("model_0", engine_impl_.GetDeviceInfo(kSystemId)->model());
EXPECT_EQ(DEVICE_REVOKED,
CheckDeviceStatus(kSystemId + 1, kEmptyOemSerialNumber));
EXPECT_EQ("model_1", engine_impl_.GetDeviceInfo(kSystemId + 1)->model());
EXPECT_EQ(OK, CheckDeviceStatus(kSystemId + 2, kEmptyOemSerialNumber));
EXPECT_EQ("model_2", engine_impl_.GetDeviceInfo(kSystemId + 2)->model());
}
TEST_F(ProvisioningEngineImplGeneralTest,
GenerateDrmIntermediateCertificateInvalidPublicKey) {
std::string drm_certificate;
EXPECT_CALL(*mock_rsa_key_factory_,
CreateFromPkcs1PublicKey(kIntermediatePublicKey))
.WillOnce(Return(ByMove(nullptr)));
std::string certificate;
ASSERT_EQ(INVALID_INTERMEDIATE_PUBLIC_KEY,
engine_impl_.GenerateDrmIntermediateCertificate(
kSystemId, kIntermediatePublicKey, &certificate));
}
TEST_F(ProvisioningEngineImplGeneralTest, GenerateDrmIntermediateCertificate) {
std::string drm_certificate;
EXPECT_CALL(*mock_rsa_key_factory_,
CreateFromPkcs1PublicKey(kIntermediatePublicKey))
.WillOnce(
Return(ByMove(std::unique_ptr<RsaPublicKey>(new MockRsaPublicKey))));
EXPECT_CALL(*mock_prov_private_key_, GenerateSignature(_, _, _))
.WillOnce(DoAll(SaveArg<0>(&drm_certificate),
SetArgPointee<2>(kSignature), Return(true)));
std::string certificate;
ASSERT_EQ(OK, engine_impl_.GenerateDrmIntermediateCertificate(
kSystemId, kIntermediatePublicKey, &certificate));
SignedDrmCertificate signed_drm_cert_proto;
ASSERT_TRUE(signed_drm_cert_proto.ParseFromString(certificate));
EXPECT_EQ(drm_certificate, signed_drm_cert_proto.drm_certificate());
EXPECT_EQ(kSignature, signed_drm_cert_proto.signature());
EXPECT_EQ(signed_prov_cert_.SerializeAsString(),
signed_drm_cert_proto.signer().SerializeAsString());
DrmCertificate drm_cert_proto;
ASSERT_TRUE(drm_cert_proto.ParseFromString(drm_certificate));
EXPECT_EQ(DrmCertificate::DEVICE_MODEL, drm_cert_proto.type());
EXPECT_NE("", drm_cert_proto.serial_number());
EXPECT_EQ(kSystemId, drm_cert_proto.system_id());
EXPECT_EQ(kIntermediatePublicKey, drm_cert_proto.public_key());
}
TEST_F(ProvisioningEngineImplGeneralTest,
AddDrmIntermediateCertificateInvalidCert) {
EXPECT_EQ(
INVALID_INTERMEDIATE_DRM_CERTIFICATE,
engine_impl_.AddDrmIntermediateCertificate(
"", kIntermediatePrivateKey, kIntermediatePrivateKeyPassphrase));
EXPECT_EQ(INVALID_INTERMEDIATE_DRM_CERTIFICATE,
engine_impl_.AddDrmIntermediateCertificate(
"invalid_intermediate_cert", kIntermediatePrivateKey,
kIntermediatePrivateKeyPassphrase));
}
TEST_F(ProvisioningEngineImplGeneralTest,
AddDrmIntermediateCertificateIncorrectCertType) {
intermediate_cert_.set_type(DrmCertificate::DEVICE);
signed_intermediate_cert_.set_drm_certificate(
intermediate_cert_.SerializeAsString());
EXPECT_EQ(INVALID_INTERMEDIATE_DRM_CERTIFICATE,
engine_impl_.AddDrmIntermediateCertificate(
signed_intermediate_cert_.SerializeAsString(),
kIntermediatePrivateKey, kIntermediatePrivateKeyPassphrase));
}
TEST_F(ProvisioningEngineImplGeneralTest,
AddDrmIntermediateCertificateMissingSystemId) {
intermediate_cert_.clear_system_id();
signed_intermediate_cert_.set_drm_certificate(
intermediate_cert_.SerializeAsString());
EXPECT_EQ(UNKNOWN_SYSTEM_ID,
engine_impl_.AddDrmIntermediateCertificate(
signed_intermediate_cert_.SerializeAsString(),
kIntermediatePrivateKey, kIntermediatePrivateKeyPassphrase));
}
TEST_F(ProvisioningEngineImplGeneralTest,
AddDrmIntermediateCertificateRevokedCert) {
SetUpDcsl();
intermediate_cert_.set_system_id(kSystemId + 1);
signed_intermediate_cert_.set_drm_certificate(
intermediate_cert_.SerializeAsString());
EXPECT_EQ(DEVICE_REVOKED,
engine_impl_.AddDrmIntermediateCertificate(
signed_intermediate_cert_.SerializeAsString(),
kIntermediatePrivateKey, kIntermediatePrivateKeyPassphrase));
}
TEST_F(ProvisioningEngineImplGeneralTest,
AddDrmIntermediateCertificateInvalidPublicKey) {
SetUpDcsl();
EXPECT_CALL(*mock_rsa_key_factory_,
CreateFromPkcs1PublicKey(kIntermediatePublicKey))
.WillOnce(Return(ByMove(nullptr)));
EXPECT_EQ(INVALID_INTERMEDIATE_DRM_CERTIFICATE,
engine_impl_.AddDrmIntermediateCertificate(
signed_intermediate_cert_.SerializeAsString(),
kIntermediatePrivateKey, kIntermediatePrivateKeyPassphrase));
}
TEST_F(ProvisioningEngineImplGeneralTest,
AddDrmIntermediateCertificateInvalidPrivateKey) {
SetUpDcsl();
EXPECT_CALL(*mock_rsa_key_factory_,
CreateFromPkcs1PublicKey(kIntermediatePublicKey))
.WillOnce(
Return(ByMove(std::unique_ptr<RsaPublicKey>(new MockRsaPublicKey))));
EXPECT_CALL(*mock_rsa_key_factory_,
CreateFromPkcs8PrivateKey(kIntermediatePrivateKey,
kIntermediatePrivateKeyPassphrase))
.WillOnce(Return(ByMove(nullptr)));
EXPECT_EQ(INVALID_INTERMEDIATE_PRIVATE_KEY,
engine_impl_.AddDrmIntermediateCertificate(
signed_intermediate_cert_.SerializeAsString(),
kIntermediatePrivateKey, kIntermediatePrivateKeyPassphrase));
}
TEST_F(ProvisioningEngineImplGeneralTest,
AddDrmIntermediateCertificateMismatchPublicPrivateKey) {
SetUpDcsl();
MockRsaPublicKey* mock_intermediate_public_key = new MockRsaPublicKey;
EXPECT_CALL(*mock_rsa_key_factory_,
CreateFromPkcs1PublicKey(kIntermediatePublicKey))
.WillOnce(Return(
ByMove(std::unique_ptr<RsaPublicKey>(mock_intermediate_public_key))));
EXPECT_CALL(*mock_rsa_key_factory_,
CreateFromPkcs8PrivateKey(kIntermediatePrivateKey,
kIntermediatePrivateKeyPassphrase))
.WillOnce(Return(
ByMove(std::unique_ptr<RsaPrivateKey>(new MockRsaPrivateKey))));
EXPECT_CALL(*mock_intermediate_public_key, MatchesPrivateKey(_))
.WillOnce(Return(false));
EXPECT_EQ(INVALID_INTERMEDIATE_PRIVATE_KEY,
engine_impl_.AddDrmIntermediateCertificate(
signed_intermediate_cert_.SerializeAsString(),
kIntermediatePrivateKey, kIntermediatePrivateKeyPassphrase));
}
TEST_F(ProvisioningEngineImplGeneralTest,
AddDrmIntermediateCertificateSuccess) {
SetUpDcsl();
MockRsaPublicKey* mock_intermediate_public_key = new MockRsaPublicKey;
EXPECT_CALL(*mock_rsa_key_factory_,
CreateFromPkcs1PublicKey(kIntermediatePublicKey))
.WillOnce(Return(
ByMove(std::unique_ptr<RsaPublicKey>(mock_intermediate_public_key))));
EXPECT_CALL(*mock_rsa_key_factory_,
CreateFromPkcs8PrivateKey(kIntermediatePrivateKey,
kIntermediatePrivateKeyPassphrase))
.WillOnce(Return(
ByMove(std::unique_ptr<RsaPrivateKey>(new MockRsaPrivateKey))));
EXPECT_CALL(*mock_intermediate_public_key, MatchesPrivateKey(_))
.WillOnce(Return(true));
EXPECT_EQ(OK,
engine_impl_.AddDrmIntermediateCertificate(
signed_intermediate_cert_.SerializeAsString(),
kIntermediatePrivateKey, kIntermediatePrivateKeyPassphrase));
}
TEST_F(ProvisioningEngineImplGeneralTest, ExpiredCertificateStatusList) {
cert_status_list_.set_creation_time_seconds(time(nullptr) -
kExpirationPeriodSeconds - 1);
SignedDeviceCertificateStatusList signed_cert_status_list;
signed_cert_status_list.set_certificate_status_list(
cert_status_list_.SerializeAsString());
EXPECT_CALL(*mock_root_public_key_,
VerifySignature(_, _, "cert_status_list_signature"))
.WillOnce(Return(true));
signed_cert_status_list.set_signature("cert_status_list_signature");
ASSERT_EQ(OK, engine_impl_.SetCertificateStatusList(
signed_cert_status_list.SerializeAsString(),
kExpirationPeriodSeconds));
EXPECT_EQ(STATUS_LIST_EXPIRED,
engine_impl_.AddDrmIntermediateCertificate(
signed_intermediate_cert_.SerializeAsString(),
kIntermediatePrivateKey, kIntermediatePrivateKeyPassphrase));
}
TEST_F(ProvisioningEngineImplGeneralTest,
GenerateDeviceDrmCertificateRevokedDevice) {
SetUpDcsl();
std::string certificate;
EXPECT_EQ(DEVICE_REVOKED,
engine_impl_.GenerateDeviceDrmCertificate(
kSystemId + 1, kOemSerialNumber1, kDevicePublicKey,
RootCertificateSerialNumber, &certificate));
}
TEST_F(ProvisioningEngineImplGeneralTest,
GenerateDeviceDrmCertificateWithMismatchingOemSerialNumber) {
SetUpDcsl();
std::string certificate;
// If oem serial number does not match, consider as revoked.
EXPECT_EQ(DEVICE_REVOKED, engine_impl_.GenerateDeviceDrmCertificate(
kSystemId, kOemSerialNumber1, kDevicePublicKey,
RootCertificateSerialNumber, &certificate));
}
TEST_F(ProvisioningEngineImplGeneralTest,
GenerateDeviceDrmCertificateWithoutIntermediateCert) {
SetUpDcsl();
std::string certificate;
EXPECT_EQ(MISSING_DEVICE_MODEL_CERT,
engine_impl_.GenerateDeviceDrmCertificate(
kSystemId, kOemSerialNumber0, kDevicePublicKey,
RootCertificateSerialNumber, &certificate));
}
TEST_F(ProvisioningEngineImplGeneralTest, GenerateDeviceDrmCertificate) {
SetUpDcsl();
// Add Intermediate certificate.
MockRsaPublicKey* mock_intermediate_public_key = new MockRsaPublicKey;
EXPECT_CALL(*mock_rsa_key_factory_,
CreateFromPkcs1PublicKey(kIntermediatePublicKey))
.WillOnce(Return(
ByMove(std::unique_ptr<RsaPublicKey>(mock_intermediate_public_key))));
MockRsaPrivateKey* mock_intermediate_private_key = new MockRsaPrivateKey;
EXPECT_CALL(*mock_rsa_key_factory_,
CreateFromPkcs8PrivateKey(kIntermediatePrivateKey,
kIntermediatePrivateKeyPassphrase))
.WillOnce(Return(ByMove(
std::unique_ptr<RsaPrivateKey>(mock_intermediate_private_key))));
EXPECT_CALL(*mock_intermediate_public_key, MatchesPrivateKey(_))
.WillOnce(Return(true));
EXPECT_EQ(OK,
engine_impl_.AddDrmIntermediateCertificate(
signed_intermediate_cert_.SerializeAsString(),
kIntermediatePrivateKey, kIntermediatePrivateKeyPassphrase));
// Intermediate private key expectation.
std::string drm_certificate;
EXPECT_CALL(*mock_intermediate_private_key, GenerateSignature(_, _, _))
.WillOnce(DoAll(SaveArg<0>(&drm_certificate),
SetArgPointee<2>(kSignature), Return(true)));
std::string certificate;
EXPECT_EQ(OK, engine_impl_.GenerateDeviceDrmCertificate(
kSystemId, kOemSerialNumber0, kDevicePublicKey,
RootCertificateSerialNumber, &certificate));
SignedDrmCertificate signed_drm_cert_proto;
ASSERT_TRUE(signed_drm_cert_proto.ParseFromString(certificate));
EXPECT_EQ(drm_certificate, signed_drm_cert_proto.drm_certificate());
EXPECT_EQ(kSignature, signed_drm_cert_proto.signature());
EXPECT_THAT(signed_intermediate_cert_.SerializeAsString(),
signed_drm_cert_proto.signer().SerializeAsString());
DrmCertificate drm_cert_proto;
ASSERT_TRUE(drm_cert_proto.ParseFromString(drm_certificate));
EXPECT_EQ(DrmCertificate::DEVICE, drm_cert_proto.type());
EXPECT_EQ(RootCertificateSerialNumber, drm_cert_proto.serial_number());
EXPECT_EQ(kSystemId, drm_cert_proto.system_id());
EXPECT_EQ(kDevicePublicKey, drm_cert_proto.public_key());
}
} // namespace widevine