Cas Client repo update-2.

-Parse EMM in Cas plugin
-Entitlement key rotation support
-Multi_content_license support
This commit is contained in:
huihli
2021-06-28 11:34:11 -07:00
parent 4e4f8c468f
commit 065ca035c9
42 changed files with 1748 additions and 234 deletions

View File

@@ -5063,6 +5063,29 @@ OEMCryptoResult OEMCrypto_CreateEntitledKeySession(
OEMCryptoResult OEMCrypto_RemoveEntitledKeySession(
OEMCrypto_SESSION key_session);
/*
* OEMCrypto_ReassociateEntitledKeySession
*
* Description:
* This method associates an existing entitled key session to the specified OEMCrypto session.
*
* Parameters:
* [in] key_session: id of the entitled key session.
* [in] oec_session: handle for the OEMCrypto session to be associated with
* the entitled key session.
*
* Returns:
* OEMCrypto_SUCCESS success
* OEMCrypto_ERROR_NOT_IMPLEMENTED
* OEMCrypto_ERROR_INVALID_ENTITLED_KEY_SESSION
* OEMCrypto_ERROR_INVALID_SESSION
*
* Version:
* This method is new in API version 17.
*/
OEMCryptoResult OEMCrypto_ReassociateEntitledKeySession(
OEMCrypto_SESSION key_session, OEMCrypto_SESSION oec_session);
/****************************************************************************/
/****************************************************************************/
/* The following functions are deprecated. They are not required for the

View File

@@ -166,6 +166,22 @@ OEMCryptoResult CryptoEngine::RemoveEntitledKeySession(SessionId key_sid) {
return OEMCrypto_SUCCESS;
}
OEMCryptoResult CryptoEngine::ReassociateEntitledKeySession(SessionId key_sid,
SessionId oec_sid) {
std::unique_lock<std::mutex> lock(session_table_lock_);
if (entitled_key_session_table_ == nullptr) {
return OEMCrypto_ERROR_INVALID_ENTITLED_KEY_SESSION;
}
if (entitled_key_session_table_->FindEntitledKeySession(key_sid) == nullptr) {
return OEMCrypto_ERROR_INVALID_ENTITLED_KEY_SESSION;
}
if (!entitled_key_session_table_->ReassociateEntitledKeySession(key_sid,
oec_sid)) {
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
return OEMCrypto_SUCCESS;
}
EntitledKeySession* CryptoEngine::FindEntitledKeySession(SessionId key_sid) {
std::unique_lock<std::mutex> lock(session_table_lock_);
if (entitled_key_session_table_ == nullptr) {

View File

@@ -110,6 +110,8 @@ class CryptoEngine {
virtual OEMCryptoResult RemoveEntitledKeySession(SessionId key_sid);
virtual OEMCryptoResult ReassociateEntitledKeySession(SessionId key_sid, SessionId oec_sid);
EntitledKeySession* FindEntitledKeySession(SessionId key_sid);
size_t GetNumberOfOpenSessions() { return sessions_.size(); }

View File

@@ -279,6 +279,21 @@ void EntitledKeySessionTable::RemoveEntitledKeySession(SessionId key_sid) {
entitled_key_sessions_.erase(key_sid);
}
bool EntitledKeySessionTable::ReassociateEntitledKeySession(SessionId key_sid,
SessionId oec_sid) {
std::unique_lock<std::mutex> lock(session_lock_);
// The given |key_sid| does not exist.
if (entitled_key_sessions_.find(key_sid) == entitled_key_sessions_.end()) {
return false;
}
oec_session_to_key_sessions_[oec_sid].erase(
key_session_to_oec_session_[key_sid]);
oec_session_to_key_sessions_[oec_sid].insert(oec_sid);
key_session_to_oec_session_[key_sid] = oec_sid;
return true;
}
SessionId EntitledKeySessionTable::GetOEMCryptoSessionId(SessionId key_sid) {
std::unique_lock<std::mutex> lock(session_lock_);
if (key_session_to_oec_session_.find(key_sid) ==

View File

@@ -113,6 +113,9 @@ class EntitledKeySessionTable {
EntitledKeySession* FindEntitledKeySession(SessionId key_sid);
// Remove the entitled key session that has |key_sid| as the id.
void RemoveEntitledKeySession(SessionId key_sid);
// Reassociates an existing entitled key session |key_sid| to an existing
// OEMCrypto session |oec_sid|.
bool ReassociateEntitledKeySession(SessionId key_sid, SessionId oec_sid);
// Get the referenced OEMCrypto session id of entitled key session |key_sid|.
SessionId GetOEMCryptoSessionId(SessionId key_sid);

View File

@@ -1989,4 +1989,38 @@ OEMCrypto_RemoveEntitledKeySession(OEMCrypto_SESSION key_session) {
return crypto_engine->RemoveEntitledKeySession(key_session);
}
OEMCRYPTO_API OEMCryptoResult OEMCrypto_ReassociateEntitledKeySession(
OEMCrypto_SESSION key_session, OEMCrypto_SESSION oec_session) {
if (crypto_engine == nullptr) {
LOGE(
"[OEMCrypto_ReassociateEntitledKeySession: OEMCrypto Not "
"Initialized.]");
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
#ifndef NDEBUG
if (!crypto_engine->ValidRootOfTrust()) {
LOGE("[OEMCrypto_ReassociateEntitledKeySession(): ERROR_KEYBOX_INVALID]");
return OEMCrypto_ERROR_KEYBOX_INVALID;
}
#endif
if (crypto_engine->SessionTypeBits(key_session) != kSessionTypeEntitledKey) {
LOGE(
"[OEMCrypto_ReassociateEntitledKeySession: Unexpected key_session "
"type.]");
return OEMCrypto_ERROR_INVALID_ENTITLED_KEY_SESSION;
}
if (crypto_engine->SessionTypeBits(oec_session) != kSessionTypeOEMCrypto) {
LOGE(
"[OEMCrypto_ReassociateEntitledKeySession: Unexpected oec_session "
"type.]");
return OEMCrypto_ERROR_INVALID_SESSION;
}
SessionContext* session_ctx = crypto_engine->FindSession(oec_session);
if (!session_ctx || !session_ctx->isValid()) {
LOGE("[OEMCrypto_ReassociateEntitledKeySession(): ERROR_INVALID_SESSION]");
return OEMCrypto_ERROR_INVALID_SESSION;
}
return crypto_engine->ReassociateEntitledKeySession(key_session, oec_session);
}
} // namespace wvoec_ref

View File

@@ -1736,6 +1736,45 @@ TEST_P(OEMCryptoLicenseTest,
strlen(content_key_id_1), OEMCrypto_CipherMode_CTR));
}
// This verifies that an entitled key session can be reassociated to an OEMCrypto session.
TEST_P(OEMCryptoLicenseTest, ReassociateEntitledKeySessionAPI16) {
ASSERT_NO_FATAL_FAILURE(session_.GenerateNonce());
license_messages_.set_license_type(OEMCrypto_EntitlementLicense);
ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest());
ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse());
ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse());
ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse());
// Setup another session.
Session session2;
ASSERT_NO_FATAL_FAILURE(session2.open());
ASSERT_NO_FATAL_FAILURE(InstallTestRSAKey(&session2));
ASSERT_NO_FATAL_FAILURE(session2.GenerateDerivedKeysFromSessionKey());
// Setup an entitled key session in the first OEMCrypto session.
uint32_t key_session_id;
OEMCryptoResult sts = OEMCrypto_CreateEntitledKeySession(
session_.session_id(), &key_session_id);
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
EntitledMessage entitled_message(&license_messages_);
entitled_message.FillKeyArray();
entitled_message.SetEntitledKeySession(key_session_id);
ASSERT_NO_FATAL_FAILURE(entitled_message.LoadCasKeys(
OEMCrypto_SUCCESS, /*load_even=*/true, /*load_odd=*/true));
// Now reassociate the entitled key session to the second OEMCrypto session.
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_ReassociateEntitledKeySession(
key_session_id, session2.session_id()));
// session2 does not have entitlement keys.
ASSERT_NO_FATAL_FAILURE(entitled_message.LoadCasKeys(
OEMCrypto_ERROR_INVALID_CONTEXT, /*load_even=*/true, /*load_odd=*/true));
// Now reassociate the entitled key session back to the first OEMCrypto
// session.
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_ReassociateEntitledKeySession(
key_session_id, session_.session_id()));
ASSERT_NO_FATAL_FAILURE(entitled_message.LoadCasKeys(
OEMCrypto_SUCCESS, /*load_even=*/true, /*load_odd=*/true));
}
// 'cens' mode is no longer supported in v16
TEST_P(OEMCryptoLicenseTest, RejectCensAPI16) {
ASSERT_NO_FATAL_FAILURE(session_.GenerateNonce());