Update to support OEMCrypto v16 with ODK
This commit is contained in:
@@ -15,6 +15,7 @@ package_group(
|
||||
"//arcpp_provisioning/...",
|
||||
"//provisioning_sdk/...",
|
||||
"//sigma101_provisioning/...",
|
||||
"//sigma210_provisioning/...",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -29,21 +30,23 @@ cc_library(
|
||||
deps = [
|
||||
":oem_device_cert",
|
||||
"//base",
|
||||
"@abseil_repo//absl/base:core_headers",
|
||||
"@abseil_repo//absl/synchronization",
|
||||
"//common:aes_cbc_util",
|
||||
"//common:certificate_type",
|
||||
"//common:crypto_util",
|
||||
"//common:drm_root_certificate",
|
||||
"//common:drm_service_certificate",
|
||||
"//common:hash_algorithm_util",
|
||||
"//common:random_util",
|
||||
"//common:rsa_key",
|
||||
"//provisioning_sdk/internal/certificates:root_oem_certificates",
|
||||
"//provisioning_sdk/public:provisioning_status",
|
||||
"//protos/public:certificate_provisioning_proto",
|
||||
"//protos/public:device_certificate_status_proto",
|
||||
"//protos/public:drm_certificate_proto",
|
||||
"//protos/public:provisioned_device_info_proto",
|
||||
"//protos/public:signed_drm_certificate_proto",
|
||||
"//protos/public:certificate_provisioning_cc_proto",
|
||||
"//protos/public:device_certificate_status_cc_proto",
|
||||
"//protos/public:drm_certificate_cc_proto",
|
||||
"//protos/public:provisioned_device_info_cc_proto",
|
||||
"//protos/public:signed_drm_certificate_cc_proto",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -62,7 +65,7 @@ cc_test(
|
||||
"//common:rsa_util",
|
||||
"//common:status",
|
||||
"//common:test_drm_certificates",
|
||||
"//protos/public:certificate_provisioning_proto",
|
||||
"//protos/public:certificate_provisioning_cc_proto",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -99,15 +102,18 @@ cc_library(
|
||||
":provisioning_session_impl",
|
||||
"//base",
|
||||
"//common:aes_cbc_util",
|
||||
"//common:core_message_util",
|
||||
"//common:drm_service_certificate",
|
||||
"//common:hash_algorithm",
|
||||
"//common:hash_algorithm_util",
|
||||
"//common:random_util",
|
||||
"//common:rsa_key",
|
||||
"//common:sha_util",
|
||||
"//provisioning_sdk/public:provisioning_status",
|
||||
"//protos/public:certificate_provisioning_proto",
|
||||
"//protos/public:client_identification_proto",
|
||||
"//protos/public:drm_certificate_proto",
|
||||
"//protos/public:provisioned_device_info_proto",
|
||||
"//protos/public:certificate_provisioning_cc_proto",
|
||||
"//protos/public:client_identification_cc_proto",
|
||||
"//protos/public:drm_certificate_cc_proto",
|
||||
"//protos/public:provisioned_device_info_cc_proto",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -121,9 +127,13 @@ cc_test(
|
||||
":provisioning_engine_impl",
|
||||
":provisioning_session_impl",
|
||||
"//testing:gunit_main",
|
||||
"@abseil_repo//absl/strings",
|
||||
"//common:aes_cbc_util",
|
||||
"//common:hash_algorithm",
|
||||
"//common:hash_algorithm_util",
|
||||
"//common:mock_rsa_key",
|
||||
"//common:sha_util",
|
||||
"//protos/public:hash_algorithm_cc_proto",
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
@@ -12,6 +12,9 @@
|
||||
|
||||
#include "glog/logging.h"
|
||||
#include "common/aes_cbc_util.h"
|
||||
#include "common/core_message_util.h"
|
||||
#include "common/hash_algorithm.h"
|
||||
#include "common/hash_algorithm_util.h"
|
||||
#include "common/random_util.h"
|
||||
#include "common/rsa_key.h"
|
||||
#include "common/sha_util.h"
|
||||
@@ -21,7 +24,8 @@
|
||||
#define LOG_EVERY_N_WITH_PROTO(message, proto) \
|
||||
LOG_EVERY_N(WARNING, FLAGS_prov_sdk_log_every_n) \
|
||||
<< (message) << " [proto: " << (proto).ShortDebugString() << "]"
|
||||
|
||||
// TODO(user): Use instantiate_test_suite_p to reorg the test case to cover
|
||||
// with or withoutcore_message.
|
||||
namespace widevine {
|
||||
|
||||
Provisioning30SessionImpl::Provisioning30SessionImpl(
|
||||
@@ -66,12 +70,14 @@ ProvisioningStatus Provisioning30SessionImpl::ProcessMessage(
|
||||
LOG_EVERY_N_WITH_PROTO("Invalid token", client_id);
|
||||
return INVALID_REQUEST_MESSAGE;
|
||||
}
|
||||
if (!cert_public_key->VerifySignature(signed_request.message(),
|
||||
signed_request.signature())) {
|
||||
const HashAlgorithm hash_algorithm =
|
||||
HashAlgorithmProtoToEnum(signed_request.hash_algorithm());
|
||||
if (!cert_public_key->VerifySignature(
|
||||
signed_request.oemcrypto_core_message() + signed_request.message(),
|
||||
hash_algorithm, signed_request.signature())) {
|
||||
LOG_EVERY_N_WITH_PROTO("Signature verification failed", client_id);
|
||||
return INVALID_REQUEST_MESSAGE;
|
||||
}
|
||||
|
||||
// Save device_info for query later.
|
||||
device_info_ = engine_.GetDeviceInfo(system_id);
|
||||
|
||||
@@ -81,8 +87,8 @@ ProvisioningStatus Provisioning30SessionImpl::ProcessMessage(
|
||||
} else {
|
||||
// Generate stable serial number.
|
||||
const std::string stable_data(client_id.token() + request.stable_id() +
|
||||
request.provider_id() +
|
||||
engine_.secret_spoid_sauce());
|
||||
request.provider_id() +
|
||||
engine_.secret_spoid_sauce());
|
||||
const std::string hash = Sha256_Hash(stable_data);
|
||||
const size_t RootCertificateSerialNumberSize = 16;
|
||||
certificate_serial_number = hash.substr(0, RootCertificateSerialNumberSize);
|
||||
@@ -102,8 +108,25 @@ ProvisioningStatus Provisioning30SessionImpl::ProcessMessage(
|
||||
LOG(WARNING) << "Error serializing ProvisioningResponse.";
|
||||
return INTERNAL_ERROR;
|
||||
}
|
||||
if (signed_request.has_oemcrypto_core_message() &&
|
||||
!signed_request.oemcrypto_core_message().empty()) {
|
||||
if (!core_message_util::GetCoreProvisioningResponse(
|
||||
signed_message.message(), signed_request.oemcrypto_core_message(),
|
||||
signed_message.mutable_oemcrypto_core_message())) {
|
||||
LOG(WARNING) << "Failed to get signed core message, response: "
|
||||
<< signed_message.ShortDebugString();
|
||||
return INTERNAL_ERROR;
|
||||
}
|
||||
if (signed_message.oemcrypto_core_message().empty()) {
|
||||
LOG(WARNING) << "Failed to get signed core message, response: "
|
||||
<< signed_message.ShortDebugString();
|
||||
return INTERNAL_ERROR;
|
||||
}
|
||||
}
|
||||
signed_message.set_hash_algorithm(HashAlgorithmEnumToProto(hash_algorithm));
|
||||
if (!service_private_key_.GenerateSignature(
|
||||
signed_message.message(), signed_message.mutable_signature())) {
|
||||
signed_message.oemcrypto_core_message() + signed_message.message(),
|
||||
hash_algorithm, signed_message.mutable_signature())) {
|
||||
LOG(WARNING) << "Failed to sign ProvisioningResponse.";
|
||||
return INTERNAL_ERROR;
|
||||
}
|
||||
@@ -111,7 +134,6 @@ ProvisioningStatus Provisioning30SessionImpl::ProcessMessage(
|
||||
LOG(WARNING) << "Error serializing SignedProvisioningMessage.";
|
||||
return INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
*done = true;
|
||||
return OK;
|
||||
}
|
||||
@@ -197,7 +219,8 @@ bool Provisioning30SessionImpl::DecryptClientIdentification(
|
||||
|
||||
ProvisioningStatus Provisioning30SessionImpl::GenerateProvisioningResponse(
|
||||
uint32_t system_id, const std::string& oem_ca_serial_number,
|
||||
const std::string& provider_id, const std::string& certificate_serial_number,
|
||||
const std::string& provider_id,
|
||||
const std::string& certificate_serial_number,
|
||||
const RsaPublicKey& cert_public_key, ProvisioningResponse* response) {
|
||||
ProvisioningStatus status = engine_.GenerateProviderDeviceDrmCertificate(
|
||||
system_id, oem_ca_serial_number, provider_id, device_drm_public_key_,
|
||||
|
||||
@@ -43,8 +43,7 @@ class Provisioning30SessionImpl : public ProvisioningSessionImpl {
|
||||
// exchange is complete.
|
||||
// Returns OK if successful, or an appropriate error status code otherwise.
|
||||
ProvisioningStatus ProcessMessage(const std::string& message,
|
||||
std::string* response,
|
||||
bool* done) override;
|
||||
std::string* response, bool* done) override;
|
||||
|
||||
// * Returns a ProvisioneddeviceInfo message containing information about the
|
||||
// type of device being provisioned. May return nullptr.
|
||||
@@ -65,7 +64,8 @@ class Provisioning30SessionImpl : public ProvisioningSessionImpl {
|
||||
ClientIdentification* client_id);
|
||||
ProvisioningStatus GenerateProvisioningResponse(
|
||||
uint32_t system_id, const std::string& oem_ca_serial_number,
|
||||
const std::string& provider_id, const std::string& certificate_serial_number,
|
||||
const std::string& provider_id,
|
||||
const std::string& certificate_serial_number,
|
||||
const RsaPublicKey& cert_public_key, ProvisioningResponse* response);
|
||||
|
||||
const OemDeviceCert& oem_device_cert_;
|
||||
|
||||
@@ -8,13 +8,20 @@
|
||||
|
||||
#include "provisioning_sdk/internal/provisioning30_session_impl.h"
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include "testing/gmock.h"
|
||||
#include "testing/gunit.h"
|
||||
#include "absl/strings/escaping.h"
|
||||
#include "absl/strings/str_cat.h"
|
||||
#include "common/aes_cbc_util.h"
|
||||
#include "common/hash_algorithm.h"
|
||||
#include "common/hash_algorithm_util.h"
|
||||
#include "common/mock_rsa_key.h"
|
||||
#include "common/sha_util.h"
|
||||
#include "provisioning_sdk/internal/oem_device_cert.h"
|
||||
#include "provisioning_sdk/internal/provisioning_engine_impl.h"
|
||||
#include "protos/public/hash_algorithm.pb.h"
|
||||
|
||||
using ::testing::_;
|
||||
using ::testing::ByMove;
|
||||
@@ -23,8 +30,16 @@ using ::testing::IsEmpty;
|
||||
using ::testing::Return;
|
||||
using ::testing::SaveArg;
|
||||
using ::testing::SetArgPointee;
|
||||
|
||||
// TODO(user): use a real test key instead of mock_key to testcore message
|
||||
// code change.
|
||||
namespace {
|
||||
const char kCoreMessage[] =
|
||||
"00000005000000580000001000000010000000000000004000000000000000000000000000"
|
||||
"00000000000000000000000000000000000000000000000000000000000000000000000000"
|
||||
"0000000000000000000000000000";
|
||||
const char kInvalidCoreMessage[] =
|
||||
"0000000500000058000000100000001000000000000000400000000000000000000000000";
|
||||
const char kEmptyCoreMessage[] = "";
|
||||
const char kEncryptedClientIdIv[] = "sixteen_bytes_iv";
|
||||
const char kPrivacyKey[] = "privacy_key_16B_";
|
||||
const char kProviderId[] = "testing_provider";
|
||||
@@ -38,8 +53,9 @@ const char kNonce[] = "testing_nonce";
|
||||
const char kSignature[] = "generated_signature";
|
||||
|
||||
// Derives Stable Per-Origin IDentifiers.
|
||||
std::string DeriveSpoid(const std::string& client_token, const std::string& provider_id,
|
||||
const std::string& secret_sauce) {
|
||||
std::string DeriveSpoid(const std::string& client_token,
|
||||
const std::string& provider_id,
|
||||
const std::string& secret_sauce) {
|
||||
return widevine::Sha256_Hash(client_token + provider_id + secret_sauce)
|
||||
.substr(0, 16);
|
||||
}
|
||||
@@ -50,27 +66,27 @@ namespace widevine {
|
||||
|
||||
class MockProvisioningEngineImpl : public ProvisioningEngineImpl {
|
||||
public:
|
||||
MOCK_CONST_METHOD6(GenerateProviderDeviceDrmCertificate,
|
||||
ProvisioningStatus(uint32_t system_id,
|
||||
const std::string& oem_ca_serial_number,
|
||||
const std::string& provider_id,
|
||||
const std::string& public_key,
|
||||
const std::string& certificate_serial_number,
|
||||
std::string* certificate));
|
||||
MOCK_METHOD(ProvisioningStatus, GenerateProviderDeviceDrmCertificate,
|
||||
(uint32_t system_id, const std::string& oem_ca_serial_number,
|
||||
const std::string& provider_id, const std::string& public_key,
|
||||
const std::string& certificate_serial_number,
|
||||
std::string* certificate),
|
||||
(const, override));
|
||||
};
|
||||
|
||||
class MockOemDeviceCert : public OemDeviceCert {
|
||||
public:
|
||||
// gmock does not support SetArgPointee on std::unique_ptr, so we have to
|
||||
// workaround it with a trick.
|
||||
MOCK_CONST_METHOD4(DoVerifyCertificateChain,
|
||||
bool(const std::string& certificate_chain,
|
||||
RsaPublicKey** leaf_public_key, uint32_t* system_id,
|
||||
std::string* oem_ca_serial_number));
|
||||
bool VerifyCertificateChain(const std::string& certificate_chain,
|
||||
std::unique_ptr<RsaPublicKey>* leaf_public_key,
|
||||
uint32_t* system_id,
|
||||
std::string* oem_ca_serial_number) const override {
|
||||
MOCK_METHOD(bool, DoVerifyCertificateChain,
|
||||
(const std::string& certificate_chain,
|
||||
RsaPublicKey** leaf_public_key, uint32_t* system_id,
|
||||
std::string* oem_ca_serial_number),
|
||||
(const));
|
||||
bool VerifyCertificateChain(
|
||||
const std::string& certificate_chain,
|
||||
std::unique_ptr<RsaPublicKey>* leaf_public_key, uint32_t* system_id,
|
||||
std::string* oem_ca_serial_number) const override {
|
||||
RsaPublicKey* raw_leaf_public_key = nullptr;
|
||||
if (!DoVerifyCertificateChain(certificate_chain, &raw_leaf_public_key,
|
||||
system_id, oem_ca_serial_number)) {
|
||||
@@ -133,9 +149,61 @@ class Provisioning30SessionImplProcessTest
|
||||
signed_prov_message_.set_signature("testing_signature");
|
||||
}
|
||||
|
||||
void ProcessMessage(std::string core_message) {
|
||||
signed_prov_message_.set_oemcrypto_core_message(
|
||||
absl::HexStringToBytes(core_message));
|
||||
const uint32_t kSystemId = 1234;
|
||||
EXPECT_CALL(mock_service_private_key_, Decrypt(kEncryptedPrivacyKey, _))
|
||||
.WillOnce(DoAll(SetArgPointee<1>(kPrivacyKey), Return(true)));
|
||||
MockRsaPublicKey* mock_cert_public_key = new MockRsaPublicKey;
|
||||
EXPECT_CALL(mock_oem_device_cert_,
|
||||
DoVerifyCertificateChain(kClientToken, _, _, _))
|
||||
.WillOnce(DoAll(SetArgPointee<1>(mock_cert_public_key),
|
||||
SetArgPointee<2>(kSystemId), Return(true)));
|
||||
const HashAlgorithm hash_algorithm =
|
||||
HashAlgorithmProtoToEnum(signed_prov_message_.hash_algorithm());
|
||||
EXPECT_CALL(
|
||||
*mock_cert_public_key,
|
||||
VerifySignature(signed_prov_message_.oemcrypto_core_message() +
|
||||
signed_prov_message_.message(),
|
||||
hash_algorithm, signed_prov_message_.signature()))
|
||||
.WillOnce(Return(true));
|
||||
|
||||
EXPECT_CALL(mock_engine_impl_, GenerateProviderDeviceDrmCertificate(
|
||||
kSystemId, _, _, kDevicePublicKey, _, _))
|
||||
.WillOnce(DoAll(SetArgPointee<5>(kDeviceCertificate), Return(OK)));
|
||||
EXPECT_CALL(*mock_cert_public_key, Encrypt(_, _))
|
||||
.WillOnce(DoAll(SaveArg<0>(&message_key_),
|
||||
SetArgPointee<1>(kWrappingKey), Return(true)));
|
||||
}
|
||||
|
||||
void ValidateMessage(std::string core_message) {
|
||||
ProvisioningResponse prov_response;
|
||||
// Verify the response.
|
||||
ASSERT_TRUE(signed_prov_message_.ParseFromString(response_));
|
||||
EXPECT_EQ(kSignature, signed_prov_message_.signature());
|
||||
ASSERT_TRUE(prov_response.ParseFromString(signed_prov_message_.message()));
|
||||
if (!core_message.empty()) {
|
||||
EXPECT_TRUE(signed_prov_message_.has_oemcrypto_core_message());
|
||||
EXPECT_EQ(signature_input_,
|
||||
absl::StrCat(signed_prov_message_.oemcrypto_core_message(),
|
||||
signed_prov_message_.message()));
|
||||
}
|
||||
EXPECT_EQ(kDevicePrivateKey,
|
||||
crypto_util::DecryptAesCbc(message_key_,
|
||||
prov_response.device_rsa_key_iv(),
|
||||
prov_response.device_rsa_key()));
|
||||
EXPECT_EQ(kDeviceCertificate, prov_response.device_certificate());
|
||||
EXPECT_EQ(kNonce, prov_response.nonce());
|
||||
EXPECT_EQ(kWrappingKey, prov_response.wrapping_key());
|
||||
}
|
||||
|
||||
ClientIdentification client_id_;
|
||||
ProvisioningRequest prov_request_;
|
||||
SignedProvisioningMessage signed_prov_message_;
|
||||
std::string signature_input_;
|
||||
std::string message_key_;
|
||||
std::string response_;
|
||||
};
|
||||
|
||||
TEST_F(Provisioning30SessionImplProcessTest, InvalidMessage) {
|
||||
@@ -310,8 +378,10 @@ TEST_F(Provisioning30SessionImplProcessTest, VerifySignatureFailed) {
|
||||
EXPECT_CALL(mock_oem_device_cert_,
|
||||
DoVerifyCertificateChain(kClientToken, _, _, _))
|
||||
.WillOnce(DoAll(SetArgPointee<1>(mock_cert_public_key), Return(true)));
|
||||
const HashAlgorithm hash_algorithm =
|
||||
HashAlgorithmProtoToEnum(signed_prov_message_.hash_algorithm());
|
||||
EXPECT_CALL(*mock_cert_public_key,
|
||||
VerifySignature(signed_prov_message_.message(),
|
||||
VerifySignature(signed_prov_message_.message(), hash_algorithm,
|
||||
signed_prov_message_.signature()))
|
||||
.WillOnce(Return(false));
|
||||
|
||||
@@ -334,8 +404,10 @@ TEST_F(Provisioning30SessionImplProcessTest, GenerateDeviceCertificateFailed) {
|
||||
.WillOnce(DoAll(
|
||||
SetArgPointee<1>(mock_cert_public_key), SetArgPointee<2>(kSystemId),
|
||||
SetArgPointee<3>(kExpectedOemSerialNumber), Return(true)));
|
||||
const HashAlgorithm hash_algorithm =
|
||||
HashAlgorithmProtoToEnum(signed_prov_message_.hash_algorithm());
|
||||
EXPECT_CALL(*mock_cert_public_key,
|
||||
VerifySignature(signed_prov_message_.message(),
|
||||
VerifySignature(signed_prov_message_.message(), hash_algorithm,
|
||||
signed_prov_message_.signature()))
|
||||
.WillOnce(Return(true));
|
||||
|
||||
@@ -353,54 +425,57 @@ TEST_F(Provisioning30SessionImplProcessTest, GenerateDeviceCertificateFailed) {
|
||||
signed_prov_message_.SerializeAsString(), &response, &done));
|
||||
}
|
||||
|
||||
TEST_F(Provisioning30SessionImplProcessTest, Success) {
|
||||
const uint32_t kSystemId = 1234;
|
||||
EXPECT_CALL(mock_service_private_key_, Decrypt(kEncryptedPrivacyKey, _))
|
||||
.WillOnce(DoAll(SetArgPointee<1>(kPrivacyKey), Return(true)));
|
||||
MockRsaPublicKey* mock_cert_public_key = new MockRsaPublicKey;
|
||||
EXPECT_CALL(mock_oem_device_cert_,
|
||||
DoVerifyCertificateChain(kClientToken, _, _, _))
|
||||
.WillOnce(DoAll(SetArgPointee<1>(mock_cert_public_key),
|
||||
SetArgPointee<2>(kSystemId), Return(true)));
|
||||
EXPECT_CALL(*mock_cert_public_key,
|
||||
VerifySignature(signed_prov_message_.message(),
|
||||
signed_prov_message_.signature()))
|
||||
.WillOnce(Return(true));
|
||||
|
||||
EXPECT_CALL(mock_engine_impl_, GenerateProviderDeviceDrmCertificate(
|
||||
kSystemId, _, _, kDevicePublicKey, _, _))
|
||||
.WillOnce(DoAll(SetArgPointee<5>(kDeviceCertificate), Return(OK)));
|
||||
|
||||
std::string message_key;
|
||||
EXPECT_CALL(*mock_cert_public_key, Encrypt(_, _))
|
||||
.WillOnce(DoAll(SaveArg<0>(&message_key), SetArgPointee<1>(kWrappingKey),
|
||||
Return(true)));
|
||||
std::string message;
|
||||
EXPECT_CALL(mock_service_private_key_, GenerateSignature(_, _))
|
||||
.WillOnce(DoAll(SaveArg<0>(&message), SetArgPointee<1>(kSignature),
|
||||
Return(true)));
|
||||
|
||||
std::string response;
|
||||
TEST_F(Provisioning30SessionImplProcessTest, SuccessWithCoreMessage) {
|
||||
ProcessMessage(kCoreMessage);
|
||||
bool done;
|
||||
ASSERT_EQ(OK, session_impl_.ProcessMessage(
|
||||
signed_prov_message_.SerializeAsString(), &response, &done));
|
||||
|
||||
// Verify the response.
|
||||
EXPECT_TRUE(done);
|
||||
SignedProvisioningMessage signed_prov_message;
|
||||
ASSERT_TRUE(signed_prov_message.ParseFromString(response));
|
||||
EXPECT_EQ(message, signed_prov_message.message());
|
||||
EXPECT_EQ(kSignature, signed_prov_message.signature());
|
||||
|
||||
ProvisioningResponse prov_response;
|
||||
ASSERT_TRUE(prov_response.ParseFromString(message));
|
||||
EXPECT_EQ(
|
||||
kDevicePrivateKey,
|
||||
crypto_util::DecryptAesCbc(message_key, prov_response.device_rsa_key_iv(),
|
||||
prov_response.device_rsa_key()));
|
||||
EXPECT_EQ(kDeviceCertificate, prov_response.device_certificate());
|
||||
EXPECT_EQ(kNonce, prov_response.nonce());
|
||||
EXPECT_EQ(kWrappingKey, prov_response.wrapping_key());
|
||||
EXPECT_CALL(mock_service_private_key_, GenerateSignature(_, _, _))
|
||||
.WillOnce(DoAll(SaveArg<0>(&signature_input_),
|
||||
SetArgPointee<2>(kSignature), Return(true)));
|
||||
ASSERT_EQ(
|
||||
OK, session_impl_.ProcessMessage(signed_prov_message_.SerializeAsString(),
|
||||
&response_, &done));
|
||||
ASSERT_TRUE(done);
|
||||
ValidateMessage(kCoreMessage);
|
||||
}
|
||||
|
||||
TEST_F(Provisioning30SessionImplProcessTest, SuccessWithEmptyCoreMessage) {
|
||||
ProcessMessage(kEmptyCoreMessage);
|
||||
bool done;
|
||||
EXPECT_CALL(mock_service_private_key_, GenerateSignature(_, _, _))
|
||||
.WillOnce(DoAll(SaveArg<0>(&signature_input_),
|
||||
SetArgPointee<2>(kSignature), Return(true)));
|
||||
ASSERT_EQ(
|
||||
OK, session_impl_.ProcessMessage(signed_prov_message_.SerializeAsString(),
|
||||
&response_, &done));
|
||||
ASSERT_TRUE(done);
|
||||
ValidateMessage(kEmptyCoreMessage);
|
||||
}
|
||||
|
||||
TEST_F(Provisioning30SessionImplProcessTest, FailedWithInvalidCoreMessage) {
|
||||
ProcessMessage(kInvalidCoreMessage);
|
||||
bool done;
|
||||
ASSERT_EQ(INTERNAL_ERROR,
|
||||
session_impl_.ProcessMessage(
|
||||
signed_prov_message_.SerializeAsString(), &response_, &done));
|
||||
ASSERT_FALSE(done);
|
||||
}
|
||||
|
||||
TEST_F(Provisioning30SessionImplProcessTest, VerifyHashAlgorithmInResponse) {
|
||||
const HashAlgorithm hash_algorithm = HashAlgorithm::kSha256;
|
||||
signed_prov_message_.set_hash_algorithm(
|
||||
HashAlgorithmEnumToProto(hash_algorithm));
|
||||
ProcessMessage(kCoreMessage);
|
||||
bool done;
|
||||
EXPECT_CALL(mock_service_private_key_, GenerateSignature(_, _, _))
|
||||
.WillOnce(DoAll(SaveArg<0>(&signature_input_),
|
||||
SetArgPointee<2>(kSignature), Return(true)));
|
||||
ASSERT_EQ(
|
||||
OK, session_impl_.ProcessMessage(signed_prov_message_.SerializeAsString(),
|
||||
&response_, &done));
|
||||
ASSERT_TRUE(done);
|
||||
SignedProvisioningMessage signed_response;
|
||||
signed_response.ParseFromString(response_);
|
||||
EXPECT_EQ(signed_response.hash_algorithm(),
|
||||
signed_prov_message_.hash_algorithm());
|
||||
}
|
||||
} // namespace widevine
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#include <stddef.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
@@ -22,6 +23,7 @@
|
||||
#include "common/crypto_util.h"
|
||||
#include "common/drm_root_certificate.h"
|
||||
#include "common/drm_service_certificate.h"
|
||||
#include "common/hash_algorithm_util.h"
|
||||
#include "common/random_util.h"
|
||||
#include "common/rsa_key.h"
|
||||
#include "provisioning_sdk/internal/certificates/root_oem_certificates.h"
|
||||
@@ -38,7 +40,8 @@ const size_t kContextEncryptionIvSize(16);
|
||||
const size_t kContextMacKeySize(32);
|
||||
|
||||
bool GenerateCertificate(DrmCertificate::Type type, uint32_t system_id,
|
||||
const std::string& provider_id, const std::string& serial_number,
|
||||
const std::string& provider_id,
|
||||
const std::string& serial_number,
|
||||
const std::string& public_key,
|
||||
const RsaPrivateKey& signing_key,
|
||||
const SignedDrmCertificate& signer,
|
||||
@@ -63,8 +66,10 @@ bool GenerateCertificate(DrmCertificate::Type type, uint32_t system_id,
|
||||
LOG(WARNING) << "Error serializing DrmCertificate.";
|
||||
return false;
|
||||
}
|
||||
if (!signing_key.GenerateSignature(signed_cert.drm_certificate(),
|
||||
signed_cert.mutable_signature())) {
|
||||
if (!signing_key.GenerateSignature(
|
||||
signed_cert.drm_certificate(),
|
||||
HashAlgorithmProtoToEnum(signed_cert.hash_algorithm()),
|
||||
signed_cert.mutable_signature())) {
|
||||
LOG(WARNING) << "Failed to generate signature for DrmCertificate.";
|
||||
return false;
|
||||
}
|
||||
@@ -105,7 +110,8 @@ ProvisioningEngineImpl::ProvisioningEngineImpl()
|
||||
ProvisioningEngineImpl::~ProvisioningEngineImpl() {}
|
||||
|
||||
ProvisioningStatus ProvisioningEngineImpl::Initialize(
|
||||
CertificateType certificate_type, const std::string& drm_service_certificate,
|
||||
CertificateType certificate_type,
|
||||
const std::string& drm_service_certificate,
|
||||
const std::string& service_private_key,
|
||||
const std::string& service_private_key_passphrase,
|
||||
const std::string& provisioning_drm_certificate,
|
||||
@@ -173,7 +179,8 @@ ProvisioningStatus ProvisioningEngineImpl::Initialize(
|
||||
}
|
||||
|
||||
ProvisioningStatus ProvisioningEngineImpl::SetCertificateStatusList(
|
||||
const std::string& certificate_status_list, uint32_t expiration_period_seconds) {
|
||||
const std::string& certificate_status_list,
|
||||
uint32_t expiration_period_seconds) {
|
||||
if (certificate_status_list.empty()) {
|
||||
LOG(WARNING) << "Empty certificate_status_list.";
|
||||
return INVALID_STATUS_LIST;
|
||||
@@ -187,6 +194,7 @@ ProvisioningStatus ProvisioningEngineImpl::SetCertificateStatusList(
|
||||
|
||||
if (!drm_root_public_key_->VerifySignature(
|
||||
signed_cert_status_list.certificate_status_list(),
|
||||
HashAlgorithmProtoToEnum(signed_cert_status_list.hash_algorithm()),
|
||||
signed_cert_status_list.signature())) {
|
||||
LOG_WITH_PROTO("Signature verification failed", signed_cert_status_list);
|
||||
return INVALID_STATUS_LIST;
|
||||
@@ -236,7 +244,8 @@ ProvisioningStatus ProvisioningEngineImpl::SetCertificateStatusList(
|
||||
}
|
||||
|
||||
ProvisioningStatus ProvisioningEngineImpl::GenerateDrmIntermediateCertificate(
|
||||
uint32_t system_id, const std::string& public_key, std::string* certificate) const {
|
||||
uint32_t system_id, const std::string& public_key,
|
||||
std::string* certificate) const {
|
||||
auto intermediate_public_key =
|
||||
rsa_key_factory_->CreateFromPkcs1PublicKey(public_key);
|
||||
if (!intermediate_public_key) return INVALID_INTERMEDIATE_PUBLIC_KEY;
|
||||
@@ -247,8 +256,8 @@ ProvisioningStatus ProvisioningEngineImpl::GenerateDrmIntermediateCertificate(
|
||||
LOG(WARNING) << "Failed to generate serial_number.";
|
||||
return INTERNAL_ERROR;
|
||||
}
|
||||
if (!GenerateCertificate(DrmCertificate::DEVICE_MODEL, system_id, std::string(),
|
||||
serial_number, public_key,
|
||||
if (!GenerateCertificate(DrmCertificate::DEVICE_MODEL, system_id,
|
||||
std::string(), serial_number, public_key,
|
||||
*provisioning_private_key_,
|
||||
signed_provisioning_cert_, certificate)) {
|
||||
return INTERNAL_ERROR;
|
||||
@@ -318,7 +327,8 @@ ProvisioningStatus ProvisioningEngineImpl::GenerateDeviceDrmCertificate(
|
||||
ProvisioningStatus ProvisioningEngineImpl::GenerateProviderDeviceDrmCertificate(
|
||||
uint32_t system_id, const std::string& oem_ca_serial_number,
|
||||
const std::string& provider_id, const std::string& public_key,
|
||||
const std::string& certificate_serial_number, std::string* certificate) const {
|
||||
const std::string& certificate_serial_number,
|
||||
std::string* certificate) const {
|
||||
// |oem_ca_serial_number| could be empty if it is called directly from
|
||||
// ProvisioningEngine::GenerateDeviceDrmCertificate.
|
||||
DCHECK(!certificate_serial_number.empty());
|
||||
@@ -365,40 +375,67 @@ std::shared_ptr<ProvisionedDeviceInfo> ProvisioningEngineImpl::GetDeviceInfo(
|
||||
}
|
||||
|
||||
ProvisioningStatus ProvisioningEngineImpl::StoreContext(
|
||||
const std::string& context_data, ProvisioningContext* context) const {
|
||||
DCHECK(context);
|
||||
const std::string& context_data,
|
||||
SignedProvisioningContext* signed_context) const {
|
||||
DCHECK(signed_context);
|
||||
|
||||
ProvisioningContextKeyData key_data;
|
||||
if (!RandomBytes(kContextEncryptionKeySize,
|
||||
key_data.mutable_encryption_key()) ||
|
||||
!RandomBytes(kContextEncryptionIvSize,
|
||||
key_data.mutable_encryption_iv()) ||
|
||||
!RandomBytes(kContextMacKeySize, key_data.mutable_mac_key())) {
|
||||
key_data.mutable_encryption_iv())) {
|
||||
LOG(ERROR) << "Failed to generate random context key data.";
|
||||
return INTERNAL_ERROR;
|
||||
}
|
||||
context->set_context_data(crypto_util::EncryptAesCbc(
|
||||
|
||||
const DrmServiceCertificate* service_cert =
|
||||
DrmServiceCertificate::GetDefaultDrmServiceCertificateOrDie();
|
||||
|
||||
ProvisioningContext context;
|
||||
context.set_context_data(crypto_util::EncryptAesCbc(
|
||||
key_data.encryption_key(), key_data.encryption_iv(), context_data));
|
||||
context->set_mac(crypto_util::CreateSignatureHmacSha256(
|
||||
key_data.mac_key(), context->context_data()));
|
||||
if (!DrmServiceCertificate::GetDefaultDrmServiceCertificateOrDie()
|
||||
->public_key()
|
||||
->Encrypt(key_data.SerializeAsString(),
|
||||
context->mutable_key_data())) {
|
||||
if (!service_cert->public_key()->Encrypt(key_data.SerializeAsString(),
|
||||
context.mutable_key_data())) {
|
||||
LOG(WARNING) << "Context key data encryption failed";
|
||||
return INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
signed_context->set_provisioning_context(context.SerializeAsString());
|
||||
if (!service_cert->private_key()->GenerateSignature(
|
||||
signed_context->provisioning_context(),
|
||||
HashAlgorithmProtoToEnum(signed_context->hash_algorithm()),
|
||||
signed_context->mutable_signature())) {
|
||||
LOG(WARNING) << "Failed to generate signature for ProvisioningContext.";
|
||||
return INTERNAL_ERROR;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
ProvisioningStatus ProvisioningEngineImpl::RetrieveContext(
|
||||
const ProvisioningContext& context, std::string* context_data) const {
|
||||
const SignedProvisioningContext& signed_context,
|
||||
std::string* context_data) const {
|
||||
DCHECK(context_data);
|
||||
|
||||
const DrmServiceCertificate* service_cert =
|
||||
DrmServiceCertificate::GetDefaultDrmServiceCertificateOrDie();
|
||||
|
||||
if (!service_cert->public_key()->VerifySignature(
|
||||
signed_context.provisioning_context(),
|
||||
HashAlgorithmProtoToEnum(signed_context.hash_algorithm()),
|
||||
signed_context.signature())) {
|
||||
LOG(WARNING) << "ProvisioningContext signature verification failed.";
|
||||
return INVALID_CONTEXT;
|
||||
}
|
||||
|
||||
ProvisioningContext context;
|
||||
if (!context.ParseFromString(signed_context.provisioning_context())) {
|
||||
LOG(WARNING) << "Invalid context.";
|
||||
return INVALID_CONTEXT;
|
||||
}
|
||||
|
||||
std::string serialized_key_data;
|
||||
if (!DrmServiceCertificate::GetDefaultDrmServiceCertificateOrDie()
|
||||
->private_key()
|
||||
->Decrypt(context.key_data(), &serialized_key_data)) {
|
||||
if (!service_cert->private_key()->Decrypt(context.key_data(),
|
||||
&serialized_key_data)) {
|
||||
LOG(WARNING) << "Could not decrypt context key data";
|
||||
return INVALID_CONTEXT_KEY_DATA;
|
||||
}
|
||||
@@ -411,11 +448,6 @@ ProvisioningStatus ProvisioningEngineImpl::RetrieveContext(
|
||||
LOG(WARNING) << "Invalid context key data.";
|
||||
return INVALID_CONTEXT_KEY_DATA;
|
||||
}
|
||||
if (!crypto_util::VerifySignatureHmacSha256(key_data.mac_key(), context.mac(),
|
||||
context.context_data())) {
|
||||
LOG(WARNING) << "Provisioning context MAC verification failed.";
|
||||
return INVALID_CONTEXT;
|
||||
}
|
||||
*context_data = crypto_util::DecryptAesCbc(key_data.encryption_key(),
|
||||
key_data.encryption_iv(),
|
||||
context.context_data());
|
||||
|
||||
@@ -12,13 +12,14 @@
|
||||
#define PROVISIONING_SDK_INTERNAL_PROVISIONING_ENGINE_IMPL_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include <cstdint>
|
||||
#include "base/thread_annotations.h"
|
||||
#include "absl/base/thread_annotations.h"
|
||||
#include "absl/synchronization/mutex.h"
|
||||
#include "common/certificate_type.h"
|
||||
#include "common/drm_root_certificate.h"
|
||||
@@ -61,7 +62,8 @@ class ProvisioningEngineImpl {
|
||||
// derivation of Stable Per-Origin IDentifiers.
|
||||
// * Returns OK on success, or an appropriate error status code otherwise.
|
||||
ProvisioningStatus Initialize(
|
||||
CertificateType certificate_type, const std::string& drm_service_certificate,
|
||||
CertificateType certificate_type,
|
||||
const std::string& drm_service_certificate,
|
||||
const std::string& service_private_key,
|
||||
const std::string& service_private_key_passphrase,
|
||||
const std::string& provisioning_drm_certificate,
|
||||
@@ -77,7 +79,8 @@ class ProvisioningEngineImpl {
|
||||
// (creation_time_seconds). Zero means it will never expire.
|
||||
// * Returns OK on success, or an appropriate error status code otherwise.
|
||||
ProvisioningStatus SetCertificateStatusList(
|
||||
const std::string& certificate_status_list, uint32_t expiration_period_seconds);
|
||||
const std::string& certificate_status_list,
|
||||
uint32_t expiration_period_seconds);
|
||||
|
||||
// Generate an intermediate DRM certificate.
|
||||
// * |system_id| is the Widevine system ID for the type of device.
|
||||
@@ -91,7 +94,8 @@ class ProvisioningEngineImpl {
|
||||
// engines, including this one, by invoking
|
||||
// |AddIntermediatedrmcertificate| on all active ProvisioningEngine(s).
|
||||
ProvisioningStatus GenerateDrmIntermediateCertificate(
|
||||
uint32_t system_id, const std::string& public_key, std::string* certificate) const;
|
||||
uint32_t system_id, const std::string& public_key,
|
||||
std::string* certificate) const;
|
||||
|
||||
// Add an intermediate DRM certificate to the provisioning engine. This is
|
||||
// usually done once for each supported device type.
|
||||
@@ -123,26 +127,30 @@ class ProvisioningEngineImpl {
|
||||
// Virtual for mocking.
|
||||
virtual ProvisioningStatus GenerateDeviceDrmCertificate(
|
||||
uint32_t system_id, const std::string& oem_ca_serial_number,
|
||||
const std::string& public_key, const std::string& certificate_serial_number,
|
||||
const std::string& public_key,
|
||||
const std::string& certificate_serial_number,
|
||||
std::string* certificate) const;
|
||||
|
||||
// Internal version of the method above. Allows specifying |provider_id|.
|
||||
virtual ProvisioningStatus GenerateProviderDeviceDrmCertificate(
|
||||
uint32_t system_id, const std::string& oem_ca_serial_number,
|
||||
const std::string& provider_id, const std::string& public_key,
|
||||
const std::string& certificate_serial_number, std::string* certificate) const;
|
||||
const std::string& certificate_serial_number,
|
||||
std::string* certificate) const;
|
||||
|
||||
// Get the device info for the given |system_id|.
|
||||
virtual std::shared_ptr<ProvisionedDeviceInfo> GetDeviceInfo(
|
||||
uint32_t system_id) const;
|
||||
|
||||
// Encrypt, store, and sign context/state data.
|
||||
virtual ProvisioningStatus StoreContext(const std::string& context_data,
|
||||
ProvisioningContext* context) const;
|
||||
virtual ProvisioningStatus StoreContext(
|
||||
const std::string& context_data,
|
||||
SignedProvisioningContext* context) const;
|
||||
|
||||
// Verify, decrypt, and retrieve context/state data.
|
||||
virtual ProvisioningStatus RetrieveContext(const ProvisioningContext& context,
|
||||
std::string* context_data) const;
|
||||
virtual ProvisioningStatus RetrieveContext(
|
||||
const SignedProvisioningContext& context,
|
||||
std::string* context_data) const;
|
||||
|
||||
const DrmRootCertificate* drm_root_certificate() const {
|
||||
return drm_root_certificate_.get();
|
||||
@@ -154,6 +162,7 @@ class ProvisioningEngineImpl {
|
||||
friend class ProvisioningEngineImplTest;
|
||||
friend class ProvisioningEngineImplProvTest;
|
||||
friend class Sigma101ProvisioningSessionImplTest;
|
||||
friend class Sigma210ProvisioningSessionImplTest;
|
||||
|
||||
ProvisioningEngineImpl(const ProvisioningEngineImpl&) = delete;
|
||||
ProvisioningEngineImpl& operator=(const ProvisioningEngineImpl&) = delete;
|
||||
@@ -189,10 +198,11 @@ class ProvisioningEngineImpl {
|
||||
|
||||
mutable absl::Mutex cert_status_mutex_;
|
||||
// POSIX time, in seconds, when the list would be expired.
|
||||
uint32_t certificate_expiration_seconds_utc_ GUARDED_BY(cert_status_mutex_);
|
||||
uint32_t certificate_expiration_seconds_utc_
|
||||
ABSL_GUARDED_BY(cert_status_mutex_);
|
||||
// Maps with system_id as the key.
|
||||
std::map<uint32_t, DeviceCertificateStatus> certificate_status_map_
|
||||
GUARDED_BY(cert_status_mutex_);
|
||||
ABSL_GUARDED_BY(cert_status_mutex_);
|
||||
struct IntermediateCertificateInfo {
|
||||
SignedDrmCertificate signed_drm_certificate;
|
||||
std::shared_ptr<ProvisionedDeviceInfo> device_info;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
#include "provisioning_sdk/internal/provisioning_engine_impl.h"
|
||||
|
||||
#include <time.h>
|
||||
#include <ctime>
|
||||
#include <memory>
|
||||
|
||||
#include "glog/logging.h"
|
||||
@@ -69,14 +69,14 @@ namespace widevine {
|
||||
class MockDrmRootCertificate : public DrmRootCertificate {
|
||||
public:
|
||||
MockDrmRootCertificate()
|
||||
: DrmRootCertificate(kCertificateTypeTesting, std::string(), std::string(),
|
||||
kDrmRootPublicKey,
|
||||
: DrmRootCertificate(kCertificateTypeTesting, std::string(),
|
||||
std::string(), kDrmRootPublicKey,
|
||||
std::unique_ptr<RsaKeyFactory>()) {}
|
||||
|
||||
MOCK_CONST_METHOD3(VerifyCertificate,
|
||||
Status(const std::string& serialized_cert,
|
||||
SignedDrmCertificate* signed_drm_cert,
|
||||
DrmCertificate* drm_cert));
|
||||
MOCK_METHOD(Status, VerifyCertificate,
|
||||
(const std::string& serialized_cert,
|
||||
SignedDrmCertificate* signed_drm_cert, DrmCertificate* drm_cert),
|
||||
(const, override));
|
||||
};
|
||||
|
||||
class ProvisioningEngineImplTest : public ::testing::Test {
|
||||
@@ -87,11 +87,11 @@ class ProvisioningEngineImplTest : public ::testing::Test {
|
||||
test_keys.private_test_key_2_2048_bits(), kServicePrivateKeyPassphrase,
|
||||
&service_private_key_);
|
||||
TestDrmCertificates test_certificates;
|
||||
service_certificate_ = test_certificates.test_service_certificate();
|
||||
service_certificate_ = test_certificates.test_service_certificate_no_type();
|
||||
}
|
||||
|
||||
ProvisioningStatus CheckDeviceStatus(uint32_t system_id,
|
||||
const std::string& oem_ca_serial_number) {
|
||||
ProvisioningStatus CheckDeviceStatus(
|
||||
uint32_t system_id, const std::string& oem_ca_serial_number) {
|
||||
return engine_impl_.CheckDeviceStatus(system_id, oem_ca_serial_number);
|
||||
}
|
||||
|
||||
@@ -177,7 +177,8 @@ class ProvisioningEngineImplProvTest : public ProvisioningEngineImplTest {
|
||||
ByMove(std::unique_ptr<RsaPublicKey>(mock_root_public_key_))));
|
||||
}
|
||||
|
||||
ProvisioningStatus Initialize(const std::string& provisioning_drm_certificate) {
|
||||
ProvisioningStatus Initialize(
|
||||
const std::string& provisioning_drm_certificate) {
|
||||
return engine_impl_.Initialize(
|
||||
kCertificateTypeTesting, service_certificate_, service_private_key_,
|
||||
kServicePrivateKeyPassphrase, provisioning_drm_certificate,
|
||||
@@ -268,44 +269,33 @@ class ProvisioningEngineImplContextTest
|
||||
|
||||
TEST_F(ProvisioningEngineImplContextTest, ContextStoreAndRetrieveSuccess) {
|
||||
const char kContextData[] = "I dislike tacky orange things";
|
||||
ProvisioningContext context;
|
||||
ASSERT_EQ(OK, engine_impl_.StoreContext(kContextData, &context));
|
||||
EXPECT_NE(kContextData, context.context_data());
|
||||
EXPECT_FALSE(context.mac().empty());
|
||||
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(context, &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";
|
||||
ProvisioningContext context;
|
||||
ASSERT_EQ(OK, engine_impl_.StoreContext(kContextData, &context));
|
||||
++(*context.mutable_context_data())[5];
|
||||
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(context, &context_data));
|
||||
}
|
||||
|
||||
TEST_F(ProvisioningEngineImplContextTest, ContextStoreAndRetrieveFailBadMac) {
|
||||
const char kContextData[] = "No one wants coal anymore";
|
||||
ProvisioningContext context;
|
||||
ASSERT_EQ(OK, engine_impl_.StoreContext(kContextData, &context));
|
||||
++(*context.mutable_mac())[5];
|
||||
std::string context_data;
|
||||
ASSERT_EQ(INVALID_CONTEXT,
|
||||
engine_impl_.RetrieveContext(context, &context_data));
|
||||
engine_impl_.RetrieveContext(signed_context, &context_data));
|
||||
}
|
||||
|
||||
TEST_F(ProvisioningEngineImplContextTest,
|
||||
ContextStoreAndRetrieveFailBadKeyData) {
|
||||
ContextStoreAndRetrieveFailBadSignature) {
|
||||
const char kContextData[] = "No one wants coal anymore";
|
||||
ProvisioningContext context;
|
||||
ASSERT_EQ(OK, engine_impl_.StoreContext(kContextData, &context));
|
||||
++(*context.mutable_key_data())[5];
|
||||
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_KEY_DATA,
|
||||
engine_impl_.RetrieveContext(context, &context_data));
|
||||
ASSERT_EQ(INVALID_CONTEXT,
|
||||
engine_impl_.RetrieveContext(signed_context, &context_data));
|
||||
}
|
||||
|
||||
class ProvisioningEngineImplGeneralTest
|
||||
@@ -365,7 +355,7 @@ class ProvisioningEngineImplGeneralTest
|
||||
cert_status_list_.SerializeAsString());
|
||||
EXPECT_CALL(*mock_root_public_key_,
|
||||
VerifySignature(
|
||||
StrEq(signed_cert_status_list.certificate_status_list()),
|
||||
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");
|
||||
@@ -395,7 +385,7 @@ TEST_F(ProvisioningEngineImplGeneralTest,
|
||||
signed_cert_status_list.set_certificate_status_list(
|
||||
cert_status_list_.SerializeAsString());
|
||||
EXPECT_CALL(*mock_root_public_key_,
|
||||
VerifySignature(_, "cert_status_list_signature"))
|
||||
VerifySignature(_, _, "cert_status_list_signature"))
|
||||
.WillOnce(Return(false));
|
||||
signed_cert_status_list.set_signature("cert_status_list_signature");
|
||||
ASSERT_EQ(INVALID_STATUS_LIST,
|
||||
@@ -440,7 +430,7 @@ TEST_F(ProvisioningEngineImplGeneralTest, UpdateCertificateStatusList) {
|
||||
signed_cert_status_list.set_certificate_status_list(
|
||||
cert_status_list_.SerializeAsString());
|
||||
EXPECT_CALL(*mock_root_public_key_,
|
||||
VerifySignature(_, "cert_status_list_signature"))
|
||||
VerifySignature(_, _, "cert_status_list_signature"))
|
||||
.WillOnce(Return(true));
|
||||
signed_cert_status_list.set_signature("cert_status_list_signature");
|
||||
ASSERT_EQ(OK, engine_impl_.SetCertificateStatusList(
|
||||
@@ -476,9 +466,9 @@ TEST_F(ProvisioningEngineImplGeneralTest, GenerateDrmIntermediateCertificate) {
|
||||
CreateFromPkcs1PublicKey(kIntermediatePublicKey))
|
||||
.WillOnce(
|
||||
Return(ByMove(std::unique_ptr<RsaPublicKey>(new MockRsaPublicKey))));
|
||||
EXPECT_CALL(*mock_prov_private_key_, GenerateSignature(_, _))
|
||||
EXPECT_CALL(*mock_prov_private_key_, GenerateSignature(_, _, _))
|
||||
.WillOnce(DoAll(SaveArg<0>(&drm_certificate),
|
||||
SetArgPointee<1>(kSignature), Return(true)));
|
||||
SetArgPointee<2>(kSignature), Return(true)));
|
||||
std::string certificate;
|
||||
ASSERT_EQ(OK, engine_impl_.GenerateDrmIntermediateCertificate(
|
||||
kSystemId, kIntermediatePublicKey, &certificate));
|
||||
@@ -634,7 +624,7 @@ TEST_F(ProvisioningEngineImplGeneralTest, ExpiredCertificateStatusList) {
|
||||
signed_cert_status_list.set_certificate_status_list(
|
||||
cert_status_list_.SerializeAsString());
|
||||
EXPECT_CALL(*mock_root_public_key_,
|
||||
VerifySignature(_, "cert_status_list_signature"))
|
||||
VerifySignature(_, _, "cert_status_list_signature"))
|
||||
.WillOnce(Return(true));
|
||||
signed_cert_status_list.set_signature("cert_status_list_signature");
|
||||
ASSERT_EQ(OK, engine_impl_.SetCertificateStatusList(
|
||||
@@ -706,9 +696,9 @@ TEST_F(ProvisioningEngineImplGeneralTest, GenerateDeviceDrmCertificate) {
|
||||
|
||||
// Intermediate private key expectation.
|
||||
std::string drm_certificate;
|
||||
EXPECT_CALL(*mock_intermediate_private_key, GenerateSignature(_, _))
|
||||
EXPECT_CALL(*mock_intermediate_private_key, GenerateSignature(_, _, _))
|
||||
.WillOnce(DoAll(SaveArg<0>(&drm_certificate),
|
||||
SetArgPointee<1>(kSignature), Return(true)));
|
||||
SetArgPointee<2>(kSignature), Return(true)));
|
||||
std::string certificate;
|
||||
EXPECT_EQ(OK, engine_impl_.GenerateDeviceDrmCertificate(
|
||||
kSystemId, kOemSerialNumber0, kDevicePublicKey,
|
||||
|
||||
@@ -26,7 +26,8 @@ ProvisioningSessionImpl::ProvisioningSessionImpl(
|
||||
ProvisioningSessionImpl::~ProvisioningSessionImpl() {}
|
||||
|
||||
ProvisioningStatus ProvisioningSessionImpl::Initialize(
|
||||
const std::string& device_drm_public_key, const std::string& device_drm_private_key) {
|
||||
const std::string& device_drm_public_key,
|
||||
const std::string& device_drm_private_key) {
|
||||
auto rsa_public_key =
|
||||
rsa_key_factory_->CreateFromPkcs1PublicKey(device_drm_public_key);
|
||||
if (!rsa_public_key) return INVALID_DRM_DEVICE_PUBLIC_KEY;
|
||||
|
||||
@@ -36,7 +36,7 @@ cc_library(
|
||||
deps = [
|
||||
"//base",
|
||||
"//common:certificate_type",
|
||||
"//protos/public:certificate_provisioning_proto",
|
||||
"//protos/public:certificate_provisioning_cc_proto",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -56,8 +56,10 @@ cc_library(
|
||||
"//provisioning_sdk/internal:provisioning30_session_impl",
|
||||
"//provisioning_sdk/internal:provisioning_engine_impl",
|
||||
"//provisioning_sdk/internal:provisioning_session_impl",
|
||||
"//protos/public:certificate_provisioning_proto",
|
||||
"//protos/public:certificate_provisioning_cc_proto",
|
||||
],
|
||||
# Make sure libprovisioning_sdk links in symbols defined in this target.
|
||||
alwayslink = 1,
|
||||
)
|
||||
|
||||
cc_test(
|
||||
@@ -79,7 +81,7 @@ cc_library(
|
||||
":provisioning_status",
|
||||
"//base",
|
||||
"//provisioning_sdk/internal:provisioning_session_impl",
|
||||
"//protos/public:drm_certificate_proto",
|
||||
"//protos/public:drm_certificate_cc_proto",
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
@@ -27,7 +27,8 @@ ProvisioningEngine::ProvisioningEngine() {}
|
||||
ProvisioningEngine::~ProvisioningEngine() {}
|
||||
|
||||
ProvisioningStatus ProvisioningEngine::Initialize(
|
||||
CertificateType certificate_type, const std::string& service_drm_certificate,
|
||||
CertificateType certificate_type,
|
||||
const std::string& service_drm_certificate,
|
||||
const std::string& service_private_key,
|
||||
const std::string& service_private_key_passphrase,
|
||||
const std::string& provisioning_drm_certificate,
|
||||
@@ -64,20 +65,22 @@ ProvisioningStatus ProvisioningEngine::Initialize(
|
||||
}
|
||||
|
||||
void ProvisioningEngine::RegisterProtocol(
|
||||
SignedProvisioningMessage::ProtocolVersion protocol,
|
||||
int protocol,
|
||||
SessionFactory session_factory) {
|
||||
protocol_registry_[protocol] = std::move(session_factory);
|
||||
}
|
||||
|
||||
ProvisioningStatus ProvisioningEngine::SetCertificateStatusList(
|
||||
const std::string& certificate_status_list, uint32_t expiration_period_seconds) {
|
||||
const std::string& certificate_status_list,
|
||||
uint32_t expiration_period_seconds) {
|
||||
if (!impl_) return PROVISIONING_ENGINE_UNINITIALIZED;
|
||||
return impl_->SetCertificateStatusList(certificate_status_list,
|
||||
expiration_period_seconds);
|
||||
}
|
||||
|
||||
ProvisioningStatus ProvisioningEngine::GenerateDrmIntermediateCertificate(
|
||||
uint32_t system_id, const std::string& public_key, std::string* certificate) const {
|
||||
uint32_t system_id, const std::string& public_key,
|
||||
std::string* certificate) const {
|
||||
if (!impl_) return PROVISIONING_ENGINE_UNINITIALIZED;
|
||||
if (!certificate) {
|
||||
LOG(WARNING) << "|certificate| should not be a nullptr.";
|
||||
@@ -97,7 +100,6 @@ ProvisioningStatus ProvisioningEngine::AddDrmIntermediateCertificate(
|
||||
}
|
||||
|
||||
ProvisioningStatus ProvisioningEngine::NewProvisioningSession(
|
||||
SignedProvisioningMessage::ProtocolVersion protocol,
|
||||
const std::string& device_public_key, const std::string& device_private_key,
|
||||
std::unique_ptr<ProvisioningSession>* new_session) const {
|
||||
if (!impl_) return PROVISIONING_ENGINE_UNINITIALIZED;
|
||||
@@ -106,6 +108,7 @@ ProvisioningStatus ProvisioningEngine::NewProvisioningSession(
|
||||
return INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
const int protocol = 3; // Provisioning 3.0
|
||||
auto factory = protocol_registry_.find(protocol);
|
||||
if (factory == protocol_registry_.end()) {
|
||||
LOG(WARNING) << "Provisioning protocol not supported (" << protocol << ")";
|
||||
@@ -124,45 +127,17 @@ ProvisioningStatus ProvisioningEngine::NewProvisioningSession(
|
||||
}
|
||||
|
||||
std::unique_ptr<ProvisioningSession> ProvisioningEngine::NewProvisioningSession(
|
||||
SignedProvisioningMessage::ProtocolVersion protocol,
|
||||
const std::string& device_public_key, const std::string& device_private_key,
|
||||
ProvisioningStatus* status) const {
|
||||
std::unique_ptr<ProvisioningSession> new_session;
|
||||
*status = NewProvisioningSession(protocol, device_public_key,
|
||||
device_private_key, &new_session);
|
||||
*status = NewProvisioningSession(device_public_key,
|
||||
device_private_key, &new_session);
|
||||
return new_session;
|
||||
}
|
||||
|
||||
ProvisioningStatus ProvisioningEngine::NewKeyboxProvisioningSession(
|
||||
const std::string& keybox_device_key,
|
||||
std::unique_ptr<ProvisioningSession>* new_session) const {
|
||||
if (!impl_) return PROVISIONING_ENGINE_UNINITIALIZED;
|
||||
if (!new_session) {
|
||||
LOG(WARNING) << "|new_session| should not be a nullptr.";
|
||||
return INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
SignedProvisioningMessage::ProtocolVersion protocol =
|
||||
SignedProvisioningMessage::ARCPP_PROVISIONING;
|
||||
auto factory = protocol_registry_.find(protocol);
|
||||
if (factory == protocol_registry_.end()) {
|
||||
LOG(WARNING) << "Provisioning protocol not supported (" << protocol << ")";
|
||||
return INVALID_PROTOCOL;
|
||||
}
|
||||
std::unique_ptr<ProvisioningSessionImpl> session_impl;
|
||||
ProvisioningStatus status = (factory->second)(*impl_, &session_impl);
|
||||
if (status != OK) return status;
|
||||
|
||||
status = session_impl->Initialize(keybox_device_key);
|
||||
if (status != OK) return status;
|
||||
|
||||
new_session->reset(new ProvisioningSession(std::move(session_impl)));
|
||||
return OK;
|
||||
}
|
||||
|
||||
ProvisioningStatus ProvisioningEngine::GenerateDeviceDrmCertificate(
|
||||
uint32_t system_id, const std::string& public_key, const std::string& serial_number,
|
||||
std::string* certificate) const {
|
||||
uint32_t system_id, const std::string& public_key,
|
||||
const std::string& serial_number, std::string* certificate) const {
|
||||
if (!impl_) return PROVISIONING_ENGINE_UNINITIALIZED;
|
||||
if (!certificate) {
|
||||
LOG(WARNING) << "|certificate| should not be a nullptr.";
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
|
||||
#include "common/certificate_type.h"
|
||||
#include "provisioning_sdk/public/provisioning_status.h"
|
||||
#include "protos/public/certificate_provisioning.pb.h"
|
||||
|
||||
namespace widevine {
|
||||
|
||||
@@ -65,7 +64,8 @@ class ProvisioningEngine {
|
||||
// derivation of Stable Per-Origin IDentifiers.
|
||||
// * Returns OK on success, or an appropriate error status code otherwise.
|
||||
ProvisioningStatus Initialize(
|
||||
CertificateType certificate_type, const std::string& service_drm_certificate,
|
||||
CertificateType certificate_type,
|
||||
const std::string& service_drm_certificate,
|
||||
const std::string& service_private_key,
|
||||
const std::string& service_private_key_passphrase,
|
||||
const std::string& provisioning_drm_certificate,
|
||||
@@ -78,7 +78,7 @@ class ProvisioningEngine {
|
||||
// SignedProvisioningMessage message.
|
||||
// * |session_factory| is the function which instantiates the appropriate
|
||||
// ProvisioningSessionImpl object for the specified protocol.
|
||||
void RegisterProtocol(SignedProvisioningMessage::ProtocolVersion protocol,
|
||||
void RegisterProtocol(int protocol,
|
||||
SessionFactory session_factory);
|
||||
|
||||
// Set the certificate status list for this engine.
|
||||
@@ -89,7 +89,8 @@ class ProvisioningEngine {
|
||||
// (creation_time_seconds). Zero means it will never expire.
|
||||
// * Returns OK on success, or an appropriate error status code otherwise.
|
||||
virtual ProvisioningStatus SetCertificateStatusList(
|
||||
const std::string& certificate_status_list, uint32_t expiration_period_seconds);
|
||||
const std::string& certificate_status_list,
|
||||
uint32_t expiration_period_seconds);
|
||||
|
||||
// Generate an intermediate DRM certificate.
|
||||
// * |system_id| is the Widevine system ID for the type of device.
|
||||
@@ -103,7 +104,8 @@ class ProvisioningEngine {
|
||||
// engines, including this one, by invoking
|
||||
// |AddIntermediatedrmcertificate| on all active ProvisioningEngine(s).
|
||||
ProvisioningStatus GenerateDrmIntermediateCertificate(
|
||||
uint32_t system_id, const std::string& public_key, std::string* certificate) const;
|
||||
uint32_t system_id, const std::string& public_key,
|
||||
std::string* certificate) const;
|
||||
|
||||
// Add an intermediate DRM certificate to the provisioning engine. This is
|
||||
// usually done once for each supported device type.
|
||||
@@ -134,29 +136,15 @@ class ProvisioningEngine {
|
||||
// NOTE: All ProvisioningSession objects must be deleted before the
|
||||
// ProvisioningEngine which created them.
|
||||
virtual ProvisioningStatus NewProvisioningSession(
|
||||
SignedProvisioningMessage::ProtocolVersion protocol,
|
||||
const std::string& device_public_key, const std::string& device_private_key,
|
||||
const std::string& device_public_key,
|
||||
const std::string& device_private_key,
|
||||
std::unique_ptr<ProvisioningSession>* new_session) const;
|
||||
|
||||
// This is the same as NewProvisioningSession above, but with outputs reversed
|
||||
// To get around CLIF bug https://github.com/google/clif/issues/30.
|
||||
std::unique_ptr<ProvisioningSession> NewProvisioningSession(
|
||||
SignedProvisioningMessage::ProtocolVersion protocol,
|
||||
const std::string& device_public_key, const std::string& device_private_key,
|
||||
ProvisioningStatus* status) const;
|
||||
|
||||
// Create a session to handle a keybox provisioning exchange between
|
||||
// a client device (e.g., ChromeOS) and the provisioning server.
|
||||
// It would use ARCPP_PROVISIONING protocol.
|
||||
// * |keybox_device_key| is the secret device key in the keybox.
|
||||
// * |new_session| will point, on successful return, to the newly created
|
||||
// ProvisioningSession.
|
||||
// * Returns OK if successful, or an appropriate error status code otherwise.
|
||||
// NOTE: All ProvisioningSession objects must be deleted before the
|
||||
// ProvisioningEngine which created them.
|
||||
virtual ProvisioningStatus NewKeyboxProvisioningSession(
|
||||
const std::string& keybox_device_key,
|
||||
std::unique_ptr<ProvisioningSession>* new_session) const;
|
||||
const std::string& device_public_key,
|
||||
const std::string& device_private_key, ProvisioningStatus* status) const;
|
||||
|
||||
// Generate a new device DRM certificate to be provisioned by means other than
|
||||
// the Widevine provisioning protocol.
|
||||
@@ -173,13 +161,12 @@ class ProvisioningEngine {
|
||||
// * |certificate| will contain, upon successful return the generated
|
||||
// certificate.
|
||||
// * Returns OK on success, or an appropriate error status code otherwise.
|
||||
ProvisioningStatus GenerateDeviceDrmCertificate(uint32_t system_id,
|
||||
const std::string& public_key,
|
||||
const std::string& serial_number,
|
||||
std::string* certificate) const;
|
||||
ProvisioningStatus GenerateDeviceDrmCertificate(
|
||||
uint32_t system_id, const std::string& public_key,
|
||||
const std::string& serial_number, std::string* certificate) const;
|
||||
|
||||
private:
|
||||
std::map<SignedProvisioningMessage::ProtocolVersion, SessionFactory>
|
||||
std::map<int, SessionFactory>
|
||||
protocol_registry_;
|
||||
|
||||
#ifndef SWIGPYTHON
|
||||
|
||||
@@ -26,9 +26,8 @@ ProvisioningSession::ProvisioningSession() {}
|
||||
|
||||
ProvisioningSession::~ProvisioningSession() {}
|
||||
|
||||
ProvisioningStatus ProvisioningSession::ProcessMessage(const std::string& message,
|
||||
std::string* response,
|
||||
bool* done) {
|
||||
ProvisioningStatus ProvisioningSession::ProcessMessage(
|
||||
const std::string& message, std::string* response, bool* done) {
|
||||
if (!response) {
|
||||
LOG(WARNING) << "|response| should not be a nullptr.";
|
||||
return INTERNAL_ERROR;
|
||||
|
||||
@@ -32,8 +32,7 @@ class ProvisioningSession {
|
||||
// exchange is complete.
|
||||
// Returns OK if successful, or an appropriate error status code otherwise.
|
||||
virtual ProvisioningStatus ProcessMessage(const std::string& message,
|
||||
std::string* response,
|
||||
bool* done);
|
||||
std::string* response, bool* done);
|
||||
|
||||
// * Returns a ProvisioneddeviceInfo message containing information about the
|
||||
// type of device being provisioned. May return nullptr.
|
||||
|
||||
@@ -11,76 +11,7 @@ package(default_visibility = ["//visibility:public"])
|
||||
filegroup(
|
||||
name = "binary_release_files",
|
||||
srcs = glob([
|
||||
"*.clif",
|
||||
"*.py",
|
||||
"*.i",
|
||||
]),
|
||||
)
|
||||
|
||||
py_library(
|
||||
name = "test_data_utility",
|
||||
srcs = [
|
||||
"test_data_provider.py",
|
||||
"test_data_utility.py",
|
||||
],
|
||||
data = [
|
||||
"//example:example_data",
|
||||
],
|
||||
deps = [
|
||||
"//protos/public:certificate_provisioning_py_pb2",
|
||||
],
|
||||
)
|
||||
|
||||
py_library(
|
||||
name = "crypto_utility",
|
||||
srcs = ["crypto_utility.py"],
|
||||
)
|
||||
|
||||
py_test(
|
||||
name = "init_engine_test",
|
||||
size = "small",
|
||||
srcs = ["init_engine_test.py"],
|
||||
deps = [
|
||||
":test_data_utility",
|
||||
],
|
||||
)
|
||||
|
||||
py_test(
|
||||
name = "set_certificate_status_list_test",
|
||||
size = "small",
|
||||
srcs = ["set_certificate_status_list_test.py"],
|
||||
deps = [
|
||||
":test_data_utility",
|
||||
],
|
||||
)
|
||||
|
||||
py_test(
|
||||
name = "drm_intermediate_certificate_test",
|
||||
size = "small",
|
||||
srcs = ["drm_intermediate_certificate_test.py"],
|
||||
deps = [
|
||||
":test_data_utility",
|
||||
],
|
||||
)
|
||||
|
||||
py_test(
|
||||
name = "engine_generate_certificate_test",
|
||||
size = "small",
|
||||
srcs = ["engine_generate_certificate_test.py"],
|
||||
deps = [
|
||||
":crypto_utility",
|
||||
":test_data_utility",
|
||||
"//protos/public:signed_drm_certificate_py_pb2",
|
||||
],
|
||||
)
|
||||
|
||||
py_test(
|
||||
name = "new_session_test",
|
||||
size = "small",
|
||||
srcs = ["new_session_test.py"],
|
||||
deps = [
|
||||
":crypto_utility",
|
||||
":test_data_utility",
|
||||
"//protos/public:certificate_provisioning_py_pb2",
|
||||
"//protos/public:signed_drm_certificate_py_pb2",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -13,7 +13,6 @@ import test_data_provider
|
||||
import test_data_utility
|
||||
from provisioning_engine import ProvisioningEngine
|
||||
from provisioning_status import ProvisioningStatus
|
||||
from protos.public import certificate_provisioning_pb2
|
||||
|
||||
|
||||
class InitEngineTest(unittest.TestCase):
|
||||
@@ -22,8 +21,6 @@ class InitEngineTest(unittest.TestCase):
|
||||
self._engine = ProvisioningEngine()
|
||||
self._data_provider = test_data_provider.TestDataProvider(
|
||||
CertificateType.kCertificateTypeTesting)
|
||||
self._prov30 = (
|
||||
certificate_provisioning_pb2.SignedProvisioningMessage.PROVISIONING_30)
|
||||
|
||||
def testInitEngineSucceed(self):
|
||||
status = test_data_utility.InitProvisionEngineWithTestData(
|
||||
@@ -57,7 +54,8 @@ class InitEngineTest(unittest.TestCase):
|
||||
|
||||
def testNewProvisioningSessionWithoutInit(self):
|
||||
session, status = self._engine.NewProvisioningSession(
|
||||
self._prov30, 'DEVICE_PUBLIC_KEY', 'DEVICE_PRIVATE_KEY')
|
||||
'DEVICE_PUBLIC_KEY',
|
||||
'DEVICE_PRIVATE_KEY')
|
||||
self.assertEqual(ProvisioningStatus.PROVISIONING_ENGINE_UNINITIALIZED,
|
||||
status)
|
||||
self.assertIsNone(session)
|
||||
|
||||
@@ -28,8 +28,6 @@ class NewSessionTest(unittest.TestCase):
|
||||
self._engine, 0, verify_success=True)
|
||||
self._data_provider = test_data_provider.TestDataProvider(
|
||||
CertificateType.kCertificateTypeTesting)
|
||||
self._prov30 = (
|
||||
certificate_provisioning_pb2.SignedProvisioningMessage.PROVISIONING_30)
|
||||
|
||||
def testNewSessionSuccess(self):
|
||||
test_data_utility.AddDrmIntermediateCertificateWithTestData(
|
||||
@@ -77,7 +75,7 @@ class NewSessionTest(unittest.TestCase):
|
||||
test_data_utility.AddDrmIntermediateCertificateWithTestData(
|
||||
self._engine, 2001, verify_success=True)
|
||||
(_, session_status) = self._engine.NewProvisioningSession(
|
||||
self._prov30, 'INVALID_PUBLIC_KEY',
|
||||
'INVALID_PUBLIC_KEY',
|
||||
self._data_provider.device_private_key)
|
||||
self.assertEqual(ProvisioningStatus.INVALID_DRM_DEVICE_PUBLIC_KEY,
|
||||
session_status)
|
||||
@@ -86,19 +84,11 @@ class NewSessionTest(unittest.TestCase):
|
||||
test_data_utility.AddDrmIntermediateCertificateWithTestData(
|
||||
self._engine, 2001, verify_success=True)
|
||||
(_, session_status) = self._engine.NewProvisioningSession(
|
||||
self._prov30, self._data_provider.device_public_key,
|
||||
self._data_provider.device_public_key,
|
||||
'INVALID_PRIVATE_KEY')
|
||||
self.assertEqual(ProvisioningStatus.INVALID_DRM_DEVICE_PRIVATE_KEY,
|
||||
session_status)
|
||||
|
||||
def testNewSessionInvalidProtocol(self):
|
||||
test_data_utility.AddDrmIntermediateCertificateWithTestData(
|
||||
self._engine, 2001, verify_success=True)
|
||||
(_, session_status) = self._engine.NewProvisioningSession(
|
||||
1234, self._data_provider.device_public_key,
|
||||
self._data_provider.device_private_key)
|
||||
self.assertEqual(ProvisioningStatus.INVALID_PROTOCOL, session_status)
|
||||
|
||||
def _VerifyMessageSignature(self, public_key, signed_response):
|
||||
crypto_utility.VerifySignature(public_key, signed_response.signature,
|
||||
signed_response.message)
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
from "common/python/certificate_type.h" import *
|
||||
from "provisioning_sdk/public/python/provisioning_status.h" import *
|
||||
from "provisioning_sdk/public/python/provisioning_session.h" import *
|
||||
from "protos/public/certificate_provisioning_pyclif.h" import *
|
||||
|
||||
from "provisioning_sdk/public/provisioning_engine.h":
|
||||
namespace `widevine`:
|
||||
@@ -35,7 +34,6 @@ from "provisioning_sdk/public/provisioning_engine.h":
|
||||
cert_private_key: bytes,
|
||||
cert_private_key_passhprase: bytes) -> ProvisioningStatus
|
||||
def NewProvisioningSession(self,
|
||||
protocol: SignedProvisioningMessage.ProtocolVersion,
|
||||
device_public_key: bytes,
|
||||
device_private_key: bytes) -> (new_session: ProvisioningSession,
|
||||
status: ProvisioningStatus)
|
||||
|
||||
@@ -26,8 +26,6 @@ if __name__ == '__main__':
|
||||
'%s/clif/python/runtime.cc' % common.CLIF_PREFIX,
|
||||
'%s/clif/python/slots.cc' % common.CLIF_PREFIX,
|
||||
'%s/clif/python/types.cc' % common.CLIF_PREFIX,
|
||||
'%s/certificate_provisioning_pyclif.cc' %
|
||||
common.WVPROTO_SRC_DIR,
|
||||
],
|
||||
include_dirs=[
|
||||
common.SDK_ROOT_DIR, common.GEN_DIR, common.CLIF_PREFIX, '/'
|
||||
|
||||
@@ -9,4 +9,3 @@
|
||||
from "provisioning_sdk/public/provisioning_status.h":
|
||||
namespace `widevine`:
|
||||
enum ProvisioningStatus
|
||||
def GetProvisioningStatusMessage(status: ProvisioningStatus) -> str
|
||||
|
||||
@@ -24,8 +24,12 @@ def _GetSdkRootDir():
|
||||
|
||||
SDK_ROOT_DIR = _GetSdkRootDir()
|
||||
GEN_DIR = '%s/%s' % (SDK_ROOT_DIR, GEN_DIRNAME)
|
||||
|
||||
SDK_LIBRARY_DIR = os.path.join(SDK_ROOT_DIR, 'bazel-bin', 'provisioning_sdk',
|
||||
'public')
|
||||
if not os.path.exists(SDK_LIBRARY_DIR):
|
||||
SDK_LIBRARY_DIR = SDK_ROOT_DIR
|
||||
|
||||
CLIF_PREFIX = os.environ['CLIF_PREFIX']
|
||||
BUILD_DIR = os.environ['PYEXT_BUILD_DIR']
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
# Lint as: python2, python3
|
||||
################################################################################
|
||||
# Copyright 2017 Google LLC.
|
||||
#
|
||||
@@ -7,6 +8,10 @@
|
||||
################################################################################
|
||||
"""Class that provides test data for Provisioning SDK testing."""
|
||||
|
||||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
import os
|
||||
from certificate_type import CertificateType
|
||||
|
||||
@@ -34,11 +39,11 @@ class TestDataProvider(object):
|
||||
current_dir = os.path.dirname(current_dir)
|
||||
filename = os.path.join(current_dir, subfolder_path, filename)
|
||||
try:
|
||||
with open(filename, 'r') as data_file:
|
||||
with open(filename, 'rb') as data_file:
|
||||
data = data_file.read()
|
||||
return data
|
||||
except IOError:
|
||||
print 'TestDataProvider: Failed to read \'%s\'' % filename
|
||||
print('TestDataProvider: Failed to read \'%s\'' % filename)
|
||||
return None
|
||||
|
||||
@property
|
||||
|
||||
@@ -170,8 +170,8 @@ def NewProvisioningSessionWithTestData(
|
||||
'sample device public and private keys.')
|
||||
data_provider = test_data_provider.TestDataProvider(cert_type)
|
||||
new_session, status = engine.NewProvisioningSession(
|
||||
certificate_provisioning_pb2.SignedProvisioningMessage.PROVISIONING_30,
|
||||
data_provider.device_public_key, data_provider.device_private_key)
|
||||
data_provider.device_public_key,
|
||||
data_provider.device_private_key)
|
||||
if verify_success:
|
||||
assert (ProvisioningStatus.OK == status), 'status = %r' % status
|
||||
|
||||
|
||||
Reference in New Issue
Block a user