//////////////////////////////////////////////////////////////////////////////// // 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 #include #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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(mock_intermediate_public_key)))); EXPECT_CALL(*mock_rsa_key_factory_, CreateFromPkcs8PrivateKey(kIntermediatePrivateKey, kIntermediatePrivateKeyPassphrase)) .WillOnce(Return( ByMove(std::unique_ptr(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(mock_intermediate_public_key)))); EXPECT_CALL(*mock_rsa_key_factory_, CreateFromPkcs8PrivateKey(kIntermediatePrivateKey, kIntermediatePrivateKeyPassphrase)) .WillOnce(Return( ByMove(std::unique_ptr(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(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(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