Allows sharing of keys between sessions
This change allows the app to specify that keys may be shared by sessions. The app enables this by setting the session sharing properties in DRM Plugin. Keys are shared only amoungst the specified group of sessions. Merged from widevine CDM repo * https://widevine-internal-review.googlesource.com/#/c/8019/ * https://widevine-internal-review.googlesource.com/#/c/8021/ Bug: 11013707 Change-Id: I52db41a53138b4fc563ebc6d38a623f23f7cdfb5
This commit is contained in:
@@ -161,40 +161,58 @@ class WVDrmPlugin : public android::DrmPlugin,
|
||||
class WVClientPropertySet : public wvcdm::CdmClientPropertySet {
|
||||
public:
|
||||
WVClientPropertySet()
|
||||
: mUsePrivacyMode(false) {}
|
||||
: mUsePrivacyMode(false), mShareKeys(false), mSessionSharingId(0) {}
|
||||
|
||||
virtual ~WVClientPropertySet() {}
|
||||
|
||||
void set_security_level(const std::string& securityLevel) {
|
||||
mSecurityLevel = securityLevel;
|
||||
}
|
||||
|
||||
virtual std::string security_level() const {
|
||||
return mSecurityLevel;
|
||||
}
|
||||
|
||||
void set_use_privacy_mode(bool usePrivacyMode) {
|
||||
mUsePrivacyMode = usePrivacyMode;
|
||||
void set_security_level(const std::string& securityLevel) {
|
||||
mSecurityLevel = securityLevel;
|
||||
}
|
||||
|
||||
virtual bool use_privacy_mode() const {
|
||||
return mUsePrivacyMode;
|
||||
}
|
||||
|
||||
void set_service_certificate(const std::vector<uint8_t>& serviceCertificate) {
|
||||
mServiceCertificate = serviceCertificate;
|
||||
void set_use_privacy_mode(bool usePrivacyMode) {
|
||||
mUsePrivacyMode = usePrivacyMode;
|
||||
}
|
||||
|
||||
virtual std::vector<uint8_t> service_certificate() const {
|
||||
return mServiceCertificate;
|
||||
}
|
||||
|
||||
void set_service_certificate(const std::vector<uint8_t>& serviceCertificate) {
|
||||
mServiceCertificate = serviceCertificate;
|
||||
}
|
||||
|
||||
virtual bool is_session_sharing_enabled() const {
|
||||
return mShareKeys;
|
||||
}
|
||||
|
||||
void set_is_session_sharing_enabled(bool shareKeys) {
|
||||
mShareKeys = shareKeys;
|
||||
}
|
||||
|
||||
virtual uint32_t session_sharing_id() const {
|
||||
return mSessionSharingId;
|
||||
}
|
||||
|
||||
virtual void set_session_sharing_id(uint32_t id) {
|
||||
mSessionSharingId = id;
|
||||
}
|
||||
|
||||
private:
|
||||
DISALLOW_EVIL_CONSTRUCTORS(WVClientPropertySet);
|
||||
|
||||
std::string mSecurityLevel;
|
||||
bool mUsePrivacyMode;
|
||||
std::vector<uint8_t> mServiceCertificate;
|
||||
bool mShareKeys;
|
||||
uint32_t mSessionSharingId;
|
||||
} mPropertySet;
|
||||
|
||||
WvContentDecryptionModule* mCDM;
|
||||
|
||||
@@ -392,6 +392,12 @@ status_t WVDrmPlugin::getPropertyString(const String8& name,
|
||||
} else {
|
||||
value = kDisable;
|
||||
}
|
||||
} else if (name == "sessionSharing") {
|
||||
if (mPropertySet.is_session_sharing_enabled()) {
|
||||
value = kEnable;
|
||||
} else {
|
||||
value = kDisable;
|
||||
}
|
||||
} else {
|
||||
ALOGE("App requested unknown string property %s", name.string());
|
||||
return android::ERROR_DRM_CANNOT_HANDLE;
|
||||
@@ -475,6 +481,20 @@ status_t WVDrmPlugin::setPropertyString(const String8& name,
|
||||
ALOGE("App requested unknown privacy mode %s", value.string());
|
||||
return android::BAD_VALUE;
|
||||
}
|
||||
} else if (name == "sessionSharing") {
|
||||
if (mCryptoSessions.size() == 0) {
|
||||
if (value == kEnable) {
|
||||
mPropertySet.set_is_session_sharing_enabled(true);
|
||||
} else if (value == kDisable) {
|
||||
mPropertySet.set_is_session_sharing_enabled(false);
|
||||
} else {
|
||||
ALOGE("App requested unknown sharing type %s", value.string());
|
||||
return android::BAD_VALUE;
|
||||
}
|
||||
} else {
|
||||
ALOGE("App tried to change key sharing while sessions are open.");
|
||||
return kErrorSessionIsOpen;
|
||||
}
|
||||
} else {
|
||||
ALOGE("App set unknown string property %s", name.string());
|
||||
return android::ERROR_DRM_CANNOT_HANDLE;
|
||||
|
||||
@@ -26,7 +26,7 @@ using namespace wvdrm;
|
||||
class MockCDM : public WvContentDecryptionModule {
|
||||
public:
|
||||
MOCK_METHOD3(OpenSession, CdmResponseType(const CdmKeySystem&,
|
||||
const CdmClientPropertySet*,
|
||||
CdmClientPropertySet*,
|
||||
CdmSessionId*));
|
||||
|
||||
MOCK_METHOD1(CloseSession, CdmResponseType(const CdmSessionId&));
|
||||
@@ -1181,7 +1181,6 @@ TEST_F(WVDrmPluginTest, GeneratesProvisioningNeededEvent) {
|
||||
ASSERT_EQ(ERROR_DRM_NOT_PROVISIONED, res);
|
||||
}
|
||||
|
||||
|
||||
TEST_F(WVDrmPluginTest, ProvidesExpectedDefaultPropertiesToCdm) {
|
||||
StrictMock<MockCDM> cdm;
|
||||
StrictMock<MockCrypto> crypto;
|
||||
@@ -1219,6 +1218,8 @@ TEST_F(WVDrmPluginTest, ProvidesExpectedDefaultPropertiesToCdm) {
|
||||
EXPECT_STREQ("", propertySet->security_level().c_str());
|
||||
EXPECT_FALSE(propertySet->use_privacy_mode());
|
||||
EXPECT_EQ(0u, propertySet->service_certificate().size());
|
||||
EXPECT_FALSE(propertySet->is_session_sharing_enabled());
|
||||
EXPECT_EQ(0u, propertySet->session_sharing_id());
|
||||
}
|
||||
|
||||
TEST_F(WVDrmPluginTest, CanSetSecurityLevel) {
|
||||
@@ -1395,3 +1396,107 @@ TEST_F(WVDrmPluginTest, CanSetServiceCertificate) {
|
||||
ASSERT_EQ(OK, res);
|
||||
EXPECT_EQ(0u, propertySet->service_certificate().size());
|
||||
}
|
||||
|
||||
TEST_F(WVDrmPluginTest, CanSetSessionSharing) {
|
||||
StrictMock<MockCDM> cdm;
|
||||
StrictMock<MockCrypto> crypto;
|
||||
WVDrmPlugin plugin(&cdm, &crypto);
|
||||
|
||||
const CdmClientPropertySet* propertySet = NULL;
|
||||
|
||||
// Provide expected mock behavior
|
||||
{
|
||||
// Provide expected behavior in response to OpenSession and store the
|
||||
// property set
|
||||
EXPECT_CALL(cdm, OpenSession(_, _, _))
|
||||
.WillRepeatedly(DoAll(SetArgPointee<2>(cdmSessionId),
|
||||
SaveArg<1>(&propertySet),
|
||||
Return(wvcdm::NO_ERROR)));
|
||||
|
||||
// Provide expected behavior when plugin requests session control info
|
||||
EXPECT_CALL(cdm, QueryKeyControlInfo(cdmSessionId, _))
|
||||
.WillRepeatedly(Invoke(setSessionIdOnMap<4>));
|
||||
|
||||
// Let gMock know these calls will happen but we aren't interested in them.
|
||||
EXPECT_CALL(cdm, AttachEventListener(_, _))
|
||||
.Times(AtLeast(0));
|
||||
|
||||
EXPECT_CALL(cdm, DetachEventListener(_, _))
|
||||
.Times(AtLeast(0));
|
||||
|
||||
EXPECT_CALL(cdm, CloseSession(_))
|
||||
.Times(AtLeast(0));
|
||||
}
|
||||
|
||||
status_t res;
|
||||
|
||||
// Test turning on session sharing
|
||||
res = plugin.setPropertyString(String8("sessionSharing"), String8("enable"));
|
||||
ASSERT_EQ(OK, res);
|
||||
|
||||
plugin.openSession(sessionId);
|
||||
ASSERT_THAT(propertySet, NotNull());
|
||||
EXPECT_TRUE(propertySet->is_session_sharing_enabled());
|
||||
plugin.closeSession(sessionId);
|
||||
|
||||
// Test turning off session sharing
|
||||
res = plugin.setPropertyString(String8("sessionSharing"), String8("disable"));
|
||||
ASSERT_EQ(OK, res);
|
||||
|
||||
plugin.openSession(sessionId);
|
||||
ASSERT_THAT(propertySet, NotNull());
|
||||
EXPECT_FALSE(propertySet->is_session_sharing_enabled());
|
||||
plugin.closeSession(sessionId);
|
||||
|
||||
// Test nonsense (Should Fail)
|
||||
res = plugin.setPropertyString(String8("sessionSharing"), String8("nonsense"));
|
||||
ASSERT_NE(OK, res);
|
||||
|
||||
// Test changing sharing with a session open (Should Fail)
|
||||
plugin.openSession(sessionId);
|
||||
res = plugin.setPropertyString(String8("sessionSharing"), String8("enable"));
|
||||
ASSERT_NE(OK, res);
|
||||
}
|
||||
|
||||
TEST_F(WVDrmPluginTest, AllowsStoringOfSessionSharingId) {
|
||||
StrictMock<MockCDM> cdm;
|
||||
StrictMock<MockCrypto> crypto;
|
||||
WVDrmPlugin plugin(&cdm, &crypto);
|
||||
|
||||
CdmClientPropertySet* propertySet = NULL;
|
||||
|
||||
uint32_t sharingId;
|
||||
FILE* fp = fopen("/dev/urandom", "r");
|
||||
fread(&sharingId, sizeof(uint32_t), 1, fp);
|
||||
fclose(fp);
|
||||
|
||||
// Provide expected mock behavior
|
||||
{
|
||||
// Provide expected behavior in response to OpenSession and store the
|
||||
// property set
|
||||
EXPECT_CALL(cdm, OpenSession(_, _, _))
|
||||
.WillRepeatedly(DoAll(SetArgPointee<2>(cdmSessionId),
|
||||
SaveArg<1>(&propertySet),
|
||||
Return(wvcdm::NO_ERROR)));
|
||||
|
||||
// Provide expected behavior when plugin requests session control info
|
||||
EXPECT_CALL(cdm, QueryKeyControlInfo(cdmSessionId, _))
|
||||
.WillRepeatedly(Invoke(setSessionIdOnMap<4>));
|
||||
|
||||
// Let gMock know these calls will happen but we aren't interested in them.
|
||||
EXPECT_CALL(cdm, AttachEventListener(_, _))
|
||||
.Times(AtLeast(0));
|
||||
|
||||
EXPECT_CALL(cdm, DetachEventListener(_, _))
|
||||
.Times(AtLeast(0));
|
||||
|
||||
EXPECT_CALL(cdm, CloseSession(_))
|
||||
.Times(AtLeast(0));
|
||||
}
|
||||
|
||||
plugin.openSession(sessionId);
|
||||
|
||||
ASSERT_THAT(propertySet, NotNull());
|
||||
propertySet->set_session_sharing_id(sharingId);
|
||||
EXPECT_EQ(sharingId, propertySet->session_sharing_id());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user