Files
provisioning_sdk_source/provisioning_sdk/internal/provisioning_engine_impl_test.cc
Kongqun Yang 8d17e4549a Export provisioning sdk
Change-Id: I4d47d80444c9507f84896767dc676112ca11e901
2017-01-24 20:06:25 -08:00

784 lines
33 KiB
C++

////////////////////////////////////////////////////////////////////////////////
// Copyright 2016 Google Inc.
//
// 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 <time.h>
#include <memory>
#include "glog/logging.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "common/mock_rsa_key.h"
#include "provisioning_sdk/public/certificate_type.h"
using ::testing::_;
using ::testing::ByMove;
using ::testing::DoAll;
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 kCertificateSerialNumber[] = "certificate_serial_number";
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 kServicePrivateKey[] = "service_private_key";
const char kServicePrivateKeyPassphrase[] = "service_private_key_phassphrase";
const char kServiceDrmCertificate[] = "service_drm_certificate";
const char kProvisioningDrmCertificate[] = "provisioning_drm_certificate";
const char kProvisioningPrivateKey[] = "provisioning_private_key";
const char kProvisioningPrivateKeyPassphrase[] =
"provisioning_private_key_phassphrase";
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 ProvisioningEngineImplTest : public ::testing::Test {
protected:
ProvisioningEngineImplTest() {
mock_rsa_key_factory_ = new MockRsaKeyFactory;
engine_impl_.set_rsa_key_factory(
std::unique_ptr<RsaKeyFactory>(mock_rsa_key_factory_));
}
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_;
MockRsaKeyFactory* mock_rsa_key_factory_ = nullptr;
};
TEST_F(ProvisioningEngineImplTest, InvalidCertType) {
CertificateType invalid_certificate = static_cast<CertificateType>(100);
EXPECT_EQ(
INVALID_CERTIFICATE_TYPE,
engine_impl_.Initialize(
invalid_certificate, kServiceDrmCertificate, kServicePrivateKey,
kServicePrivateKeyPassphrase, kProvisioningDrmCertificate,
kProvisioningPrivateKey, kProvisioningPrivateKeyPassphrase,
kSecretSauce));
}
class ProvisioningEngineImplServiceTest : public ProvisioningEngineImplTest {
protected:
void SetUp() override {
mock_root_public_key_ = new MockRsaPublicKey();
EXPECT_CALL(*mock_rsa_key_factory_, CreateFromPkcs1PublicKey(_))
.WillOnce(Return(
ByMove(std::unique_ptr<RsaPublicKey>(mock_root_public_key_))));
service_cert_.set_public_key("service_public_key");
service_cert_.set_type(DrmDeviceCertificate::SERVICE);
signed_service_cert_.set_drm_certificate(service_cert_.SerializeAsString());
signed_service_cert_.set_signature("service_signature");
}
ProvisioningStatus Initialize(const std::string& service_drm_certificate) {
return engine_impl_.Initialize(
kCertTesting, service_drm_certificate, kServicePrivateKey,
kServicePrivateKeyPassphrase, kProvisioningDrmCertificate,
kProvisioningPrivateKey, kProvisioningPrivateKeyPassphrase,
kSecretSauce);
}
DrmDeviceCertificate service_cert_;
SignedDrmDeviceCertificate signed_service_cert_;
MockRsaPublicKey* mock_root_public_key_;
};
TEST_F(ProvisioningEngineImplServiceTest, Empty) {
EXPECT_EQ(INVALID_SERVICE_DRM_CERTIFICATE, Initialize(""));
}
TEST_F(ProvisioningEngineImplServiceTest, MissingDeviceCert) {
signed_service_cert_.clear_drm_certificate();
EXPECT_EQ(INVALID_SERVICE_DRM_CERTIFICATE,
Initialize(signed_service_cert_.SerializeAsString()));
}
TEST_F(ProvisioningEngineImplServiceTest, MissingSignature) {
signed_service_cert_.clear_signature();
EXPECT_EQ(INVALID_SERVICE_DRM_CERTIFICATE,
Initialize(signed_service_cert_.SerializeAsString()));
}
TEST_F(ProvisioningEngineImplServiceTest, SignatureVerificationFailure) {
EXPECT_CALL(*mock_root_public_key_,
VerifySignature(StrEq(service_cert_.SerializeAsString()),
"service_signature"))
.WillOnce(Return(false));
EXPECT_EQ(INVALID_SERVICE_DRM_CERTIFICATE,
Initialize(signed_service_cert_.SerializeAsString()));
}
TEST_F(ProvisioningEngineImplServiceTest, InvalidDeviceCertType) {
service_cert_.set_type(DrmDeviceCertificate::PROVISIONER);
signed_service_cert_.set_drm_certificate(service_cert_.SerializeAsString());
EXPECT_CALL(*mock_root_public_key_,
VerifySignature(StrEq(service_cert_.SerializeAsString()),
"service_signature"))
.WillOnce(Return(true));
EXPECT_EQ(INVALID_SERVICE_DRM_CERTIFICATE,
Initialize(signed_service_cert_.SerializeAsString()));
}
TEST_F(ProvisioningEngineImplServiceTest, InvaidPublicKey) {
EXPECT_CALL(*mock_root_public_key_, VerifySignature(_, "service_signature"))
.WillOnce(Return(true));
EXPECT_CALL(*mock_rsa_key_factory_,
CreateFromPkcs1PublicKey("service_public_key"))
.WillOnce(Return(ByMove(nullptr)));
EXPECT_EQ(INVALID_SERVICE_DRM_CERTIFICATE,
Initialize(signed_service_cert_.SerializeAsString()));
}
TEST_F(ProvisioningEngineImplServiceTest, InvalidPrivateKey) {
EXPECT_CALL(*mock_root_public_key_, VerifySignature(_, "service_signature"))
.WillOnce(Return(true));
EXPECT_CALL(*mock_rsa_key_factory_,
CreateFromPkcs1PublicKey("service_public_key"))
.WillOnce(
Return(ByMove(std::unique_ptr<RsaPublicKey>(new MockRsaPublicKey))));
EXPECT_CALL(*mock_rsa_key_factory_,
CreateFromPkcs8PrivateKey(kServicePrivateKey,
kServicePrivateKeyPassphrase))
.WillOnce(Return(ByMove(nullptr)));
EXPECT_EQ(INVALID_SERVICE_PRIVATE_KEY,
Initialize(signed_service_cert_.SerializeAsString()));
}
TEST_F(ProvisioningEngineImplServiceTest, MismatchPublicKeyPrivateKey) {
EXPECT_CALL(*mock_root_public_key_, VerifySignature(_, "service_signature"))
.WillOnce(Return(true));
MockRsaPublicKey* mock_rsa_public_key = new MockRsaPublicKey;
EXPECT_CALL(*mock_rsa_key_factory_,
CreateFromPkcs1PublicKey("service_public_key"))
.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(kServicePrivateKey,
kServicePrivateKeyPassphrase))
.WillOnce(
Return(ByMove(std::unique_ptr<RsaPrivateKey>(mock_rsa_private_key))));
EXPECT_CALL(*mock_rsa_public_key, MatchesPrivateKey(_))
.WillOnce(Return(false));
EXPECT_EQ(INVALID_SERVICE_PRIVATE_KEY,
Initialize(signed_service_cert_.SerializeAsString()));
}
class ProvisioningEngineImplProvTest
: public ProvisioningEngineImplServiceTest {
protected:
void SetUp() override {
ProvisioningEngineImplServiceTest::SetUp();
// Service certificate expectations.
EXPECT_CALL(*mock_root_public_key_, VerifySignature(_, "service_signature"))
.WillOnce(Return(true));
mock_service_public_key_ = new MockRsaPublicKey;
EXPECT_CALL(*mock_rsa_key_factory_,
CreateFromPkcs1PublicKey("service_public_key"))
.WillOnce(Return(
ByMove(std::unique_ptr<RsaPublicKey>(mock_service_public_key_))));
mock_service_private_key_ = new MockRsaPrivateKey;
EXPECT_CALL(*mock_rsa_key_factory_,
CreateFromPkcs8PrivateKey(kServicePrivateKey,
kServicePrivateKeyPassphrase))
.WillOnce(Return(
ByMove(std::unique_ptr<RsaPrivateKey>(mock_service_private_key_))));
EXPECT_CALL(*mock_service_public_key_, MatchesPrivateKey(_))
.WillOnce(Return(true));
prov_cert_.set_public_key(kProvisioningPublicKey);
prov_cert_.set_type(DrmDeviceCertificate::PROVISIONER);
signed_prov_cert_.set_drm_certificate(prov_cert_.SerializeAsString());
signed_prov_cert_.set_signature(kProvisioningSignature);
}
ProvisioningStatus Initialize(const std::string& provisioning_drm_certificate) {
return engine_impl_.Initialize(
kCertTesting, signed_service_cert_.SerializeAsString(),
kServicePrivateKey, kServicePrivateKeyPassphrase,
provisioning_drm_certificate, kProvisioningPrivateKey,
kProvisioningPrivateKeyPassphrase, "spoid_secret_sauce");
}
DrmDeviceCertificate prov_cert_;
SignedDrmDeviceCertificate signed_prov_cert_;
MockRsaPublicKey* mock_service_public_key_ = nullptr;
MockRsaPrivateKey* mock_service_private_key_ = nullptr;
};
TEST_F(ProvisioningEngineImplProvTest, Empty) {
EXPECT_EQ(INVALID_PROVISIONER_DRM_CERTIFICATE, Initialize(""));
}
TEST_F(ProvisioningEngineImplProvTest, MissingDeviceCert) {
signed_prov_cert_.clear_drm_certificate();
EXPECT_EQ(INVALID_PROVISIONER_DRM_CERTIFICATE,
Initialize(signed_prov_cert_.SerializeAsString()));
}
TEST_F(ProvisioningEngineImplProvTest, MissingSignature) {
signed_prov_cert_.clear_signature();
EXPECT_EQ(INVALID_PROVISIONER_DRM_CERTIFICATE,
Initialize(signed_prov_cert_.SerializeAsString()));
}
TEST_F(ProvisioningEngineImplProvTest, SignatureVerificationFailure) {
EXPECT_CALL(*mock_root_public_key_,
VerifySignature(StrEq(prov_cert_.SerializeAsString()),
kProvisioningSignature))
.WillOnce(Return(false));
EXPECT_EQ(INVALID_PROVISIONER_DRM_CERTIFICATE,
Initialize(signed_prov_cert_.SerializeAsString()));
}
TEST_F(ProvisioningEngineImplProvTest, InvalidDeviceCertType) {
prov_cert_.set_type(DrmDeviceCertificate::SERVICE);
signed_prov_cert_.set_drm_certificate(prov_cert_.SerializeAsString());
EXPECT_CALL(*mock_root_public_key_,
VerifySignature(StrEq(prov_cert_.SerializeAsString()),
kProvisioningSignature))
.WillOnce(Return(true));
EXPECT_EQ(INVALID_PROVISIONER_DRM_CERTIFICATE,
Initialize(signed_prov_cert_.SerializeAsString()));
}
TEST_F(ProvisioningEngineImplProvTest, InvaidPublicKey) {
EXPECT_CALL(*mock_root_public_key_,
VerifySignature(_, kProvisioningSignature))
.WillOnce(Return(true));
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_root_public_key_,
VerifySignature(_, kProvisioningSignature))
.WillOnce(Return(true));
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) {
EXPECT_CALL(*mock_root_public_key_,
VerifySignature(_, kProvisioningSignature))
.WillOnce(Return(true));
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 ProvisioningEngineImplGeneralTest
: public ProvisioningEngineImplProvTest {
protected:
void SetUp() override {
ProvisioningEngineImplProvTest::SetUp();
// Provisioning certificate expectations.
EXPECT_CALL(*mock_root_public_key_,
VerifySignature(_, kProvisioningSignature))
.WillOnce(Return(true));
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;
EXPECT_CALL(
*mock_rsa_key_factory_,
CreateFromPkcs8PrivateKey(kProvisioningPrivateKey,
kProvisioningPrivateKeyPassphrase))
.WillOnce(Return(
ByMove(std::unique_ptr<RsaPrivateKey>(mock_prov_private_key_))));
EXPECT_CALL(*mock_prov_public_key_, MatchesPrivateKey(_))
.WillOnce(Return(true));
ASSERT_EQ(OK, ProvisioningEngineImplProvTest::Initialize(
signed_prov_cert_.SerializeAsString()));
// 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::VALID);
cert_status_list_.mutable_certificate_status(1)->set_status(
DeviceCertificateStatus::REVOKED);
SignedCertificateStatusList 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(),
kExpirationPeriodSeconds));
// Setup a DrmDeviceCertificate to be used later.
intermediate_cert_.set_type(DrmDeviceCertificate::DRM_INTERMEDIATE);
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);
}
MockRsaPublicKey* mock_prov_public_key_ = nullptr;
MockRsaPrivateKey* mock_prov_private_key_ = nullptr;
DeviceCertificateStatusList cert_status_list_;
DrmDeviceCertificate intermediate_cert_;
SignedDrmDeviceCertificate 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) {
SignedCertificateStatusList 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) {
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) {
cert_status_list_.mutable_certificate_status(0)->set_status(
DeviceCertificateStatus::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");
SignedCertificateStatusList 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<1>(kSignature), Return(true)));
std::string certificate;
ASSERT_EQ(OK, engine_impl_.GenerateDrmIntermediateCertificate(
kSystemId, kIntermediatePublicKey, &certificate));
SignedDrmDeviceCertificate 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());
DrmDeviceCertificate drm_cert_proto;
ASSERT_TRUE(drm_cert_proto.ParseFromString(drm_certificate));
EXPECT_EQ(DrmDeviceCertificate::DRM_INTERMEDIATE, 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(DrmDeviceCertificate::DRM_USER_DEVICE);
signed_intermediate_cert_.set_drm_certificate(
intermediate_cert_.SerializeAsString());
EXPECT_CALL(
*mock_prov_public_key_,
VerifySignature(StrEq(signed_intermediate_cert_.drm_certificate()),
StrEq(signed_intermediate_cert_.signature())))
.WillOnce(Return(true));
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_CALL(
*mock_prov_public_key_,
VerifySignature(StrEq(signed_intermediate_cert_.drm_certificate()),
StrEq(signed_intermediate_cert_.signature())))
.WillOnce(Return(true));
EXPECT_EQ(
UNKNOWN_SYSTEM_ID,
engine_impl_.AddDrmIntermediateCertificate(
signed_intermediate_cert_.SerializeAsString(),
kIntermediatePrivateKey, kIntermediatePrivateKeyPassphrase));
}
TEST_F(ProvisioningEngineImplGeneralTest,
AddDrmIntermediateCertificateRevokedCert) {
intermediate_cert_.set_system_id(kSystemId + 1);
signed_intermediate_cert_.set_drm_certificate(
intermediate_cert_.SerializeAsString());
EXPECT_CALL(
*mock_prov_public_key_,
VerifySignature(StrEq(signed_intermediate_cert_.drm_certificate()),
StrEq(signed_intermediate_cert_.signature())))
.WillOnce(Return(true));
EXPECT_EQ(DEVICE_REVOKED, engine_impl_.AddDrmIntermediateCertificate(
signed_intermediate_cert_.SerializeAsString(),
kIntermediatePrivateKey,
kIntermediatePrivateKeyPassphrase));
}
TEST_F(ProvisioningEngineImplGeneralTest,
AddDrmIntermediateCertificateInvalidPublicKey) {
EXPECT_CALL(
*mock_prov_public_key_,
VerifySignature(StrEq(signed_intermediate_cert_.drm_certificate()),
StrEq(signed_intermediate_cert_.signature())))
.WillOnce(Return(true));
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) {
EXPECT_CALL(
*mock_prov_public_key_,
VerifySignature(StrEq(signed_intermediate_cert_.drm_certificate()),
StrEq(signed_intermediate_cert_.signature())))
.WillOnce(Return(true));
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) {
EXPECT_CALL(
*mock_prov_public_key_,
VerifySignature(StrEq(signed_intermediate_cert_.drm_certificate()),
StrEq(signed_intermediate_cert_.signature())))
.WillOnce(Return(true));
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) {
EXPECT_CALL(
*mock_prov_public_key_,
VerifySignature(StrEq(signed_intermediate_cert_.drm_certificate()),
StrEq(signed_intermediate_cert_.signature())))
.WillOnce(Return(true));
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);
SignedCertificateStatusList 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_CALL(
*mock_prov_public_key_,
VerifySignature(StrEq(signed_intermediate_cert_.drm_certificate()),
StrEq(signed_intermediate_cert_.signature())))
.WillOnce(Return(true));
EXPECT_EQ(
STATUS_LIST_EXPIRED,
engine_impl_.AddDrmIntermediateCertificate(
signed_intermediate_cert_.SerializeAsString(),
kIntermediatePrivateKey, kIntermediatePrivateKeyPassphrase));
}
TEST_F(ProvisioningEngineImplGeneralTest,
GenerateDeviceDrmCertificateRevokedDevice) {
std::string certificate;
EXPECT_EQ(DEVICE_REVOKED,
engine_impl_.GenerateDeviceDrmCertificate(
kSystemId + 1, kOemSerialNumber1, kDevicePublicKey,
kCertificateSerialNumber, &certificate));
}
TEST_F(ProvisioningEngineImplGeneralTest,
GenerateDeviceDrmCertificateWithMismatchingOemSerialNumber) {
std::string certificate;
// If oem serial number does not match, consider as revoked.
EXPECT_EQ(DEVICE_REVOKED,
engine_impl_.GenerateDeviceDrmCertificate(
kSystemId, kOemSerialNumber1, kDevicePublicKey,
kCertificateSerialNumber, &certificate));
}
TEST_F(ProvisioningEngineImplGeneralTest,
GenerateDeviceDrmCertificateWithoutIntermediateCert) {
std::string certificate;
EXPECT_EQ(MISSING_DRM_INTERMEDIATE_CERT,
engine_impl_.GenerateDeviceDrmCertificate(
kSystemId, kOemSerialNumber0, kDevicePublicKey,
kCertificateSerialNumber, &certificate));
}
TEST_F(ProvisioningEngineImplGeneralTest,
GenerateDeviceDrmCertificate) {
// Add Intermediate certificate.
EXPECT_CALL(
*mock_prov_public_key_,
VerifySignature(StrEq(signed_intermediate_cert_.drm_certificate()),
StrEq(signed_intermediate_cert_.signature())))
.WillOnce(Return(true));
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<1>(kSignature), Return(true)));
std::string certificate;
EXPECT_EQ(OK, engine_impl_.GenerateDeviceDrmCertificate(
kSystemId, kOemSerialNumber0, kDevicePublicKey,
kCertificateSerialNumber, &certificate));
SignedDrmDeviceCertificate 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());
DrmDeviceCertificate drm_cert_proto;
ASSERT_TRUE(drm_cert_proto.ParseFromString(drm_certificate));
EXPECT_EQ(DrmDeviceCertificate::DRM_USER_DEVICE, drm_cert_proto.type());
EXPECT_EQ(kCertificateSerialNumber, drm_cert_proto.serial_number());
EXPECT_EQ(kSystemId, drm_cert_proto.system_id());
EXPECT_EQ(kDevicePublicKey, drm_cert_proto.public_key());
}
} // namespace widevine