Merge "Allow CE CDM to Create Sessions Without a Service Certificate"
This commit is contained in:
@@ -137,6 +137,10 @@ class CdmEngine {
|
|||||||
virtual CdmResponseType RenewKey(const CdmSessionId& session_id,
|
virtual CdmResponseType RenewKey(const CdmSessionId& session_id,
|
||||||
const CdmKeyResponse& key_data);
|
const CdmKeyResponse& key_data);
|
||||||
|
|
||||||
|
// Change the service certificate installed in a given session.
|
||||||
|
virtual CdmResponseType SetSessionServiceCertificate(
|
||||||
|
const CdmSessionId& session_id, const std::string& service_certificate);
|
||||||
|
|
||||||
// Query system information
|
// Query system information
|
||||||
virtual CdmResponseType QueryStatus(SecurityLevel security_level,
|
virtual CdmResponseType QueryStatus(SecurityLevel security_level,
|
||||||
const std::string& query_token,
|
const std::string& query_token,
|
||||||
|
|||||||
@@ -43,19 +43,23 @@ class CdmSession {
|
|||||||
bool IsClosed() { return closed_; }
|
bool IsClosed() { return closed_; }
|
||||||
|
|
||||||
// Initializes this instance of CdmSession with the given property set.
|
// Initializes this instance of CdmSession with the given property set.
|
||||||
// |cdm_client_property_set| MAY be null, is owned by the caller,
|
//
|
||||||
// and must remain in scope throughout the scope of this session.
|
// |cdm_client_property_set| is caller owned, may be null, but must be in
|
||||||
|
// scope as long as the session is in scope. The service certificate field is
|
||||||
|
// cached at the time Init() is called.
|
||||||
virtual CdmResponseType Init(CdmClientPropertySet* cdm_client_property_set);
|
virtual CdmResponseType Init(CdmClientPropertySet* cdm_client_property_set);
|
||||||
|
|
||||||
// Initializes this instance of CdmSession with the given parmeters.
|
// Initializes this instance of CdmSession with the given parmeters.
|
||||||
// All parameters are owned by the caller.
|
// All parameters are owned by the caller.
|
||||||
// |service_certificate| is caller owned, cannot be null, and must be in
|
//
|
||||||
// scope as long as the session is in scope.
|
// |cdm_client_property_set| is caller owned, may be null, but must be in
|
||||||
// |cdm_client_property_set| is caller owned, may be null, but must be
|
// scope as long as the session is in scope. The service certificate field is
|
||||||
// in scope as long as the session is in scope.
|
// cached at the time Init() is called.
|
||||||
|
//
|
||||||
// |forced_session_id| is caller owned and may be null.
|
// |forced_session_id| is caller owned and may be null.
|
||||||
// |event_listener| is caller owned, may be null, but must be in scope
|
//
|
||||||
// as long as the session is in scope.
|
// |event_listener| is caller owned, may be null, but must be in scope as long
|
||||||
|
// as the session is in scope.
|
||||||
virtual CdmResponseType Init(CdmClientPropertySet* cdm_client_property_set,
|
virtual CdmResponseType Init(CdmClientPropertySet* cdm_client_property_set,
|
||||||
const CdmSessionId* forced_session_id,
|
const CdmSessionId* forced_session_id,
|
||||||
WvCdmEventListener* event_listener);
|
WvCdmEventListener* event_listener);
|
||||||
@@ -84,6 +88,11 @@ class CdmSession {
|
|||||||
// AddKey() - Accept license response and extract key info.
|
// AddKey() - Accept license response and extract key info.
|
||||||
virtual CdmResponseType AddKey(const CdmKeyResponse& key_response);
|
virtual CdmResponseType AddKey(const CdmKeyResponse& key_response);
|
||||||
|
|
||||||
|
// Override the currently-installed service certificate with a new service
|
||||||
|
// certificate.
|
||||||
|
virtual CdmResponseType SetServiceCertificate(
|
||||||
|
const std::string& service_certificate);
|
||||||
|
|
||||||
// Query session status
|
// Query session status
|
||||||
virtual CdmResponseType QueryStatus(CdmQueryMap* query_response);
|
virtual CdmResponseType QueryStatus(CdmQueryMap* query_response);
|
||||||
|
|
||||||
|
|||||||
@@ -44,6 +44,11 @@ class CdmLicense {
|
|||||||
const std::string& signed_service_certificate,
|
const std::string& signed_service_certificate,
|
||||||
CryptoSession* session, PolicyEngine* policy_engine);
|
CryptoSession* session, PolicyEngine* policy_engine);
|
||||||
|
|
||||||
|
// Override the currently-installed service certificate with a new service
|
||||||
|
// certificate.
|
||||||
|
virtual CdmResponseType SetServiceCertificate(
|
||||||
|
const std::string& signed_service_certificate);
|
||||||
|
|
||||||
virtual CdmResponseType PrepareKeyRequest(
|
virtual CdmResponseType PrepareKeyRequest(
|
||||||
const InitializationData& init_data, CdmLicenseType license_type,
|
const InitializationData& init_data, CdmLicenseType license_type,
|
||||||
const CdmAppParameterMap& app_parameters, CdmKeyMessage* signed_request,
|
const CdmAppParameterMap& app_parameters, CdmKeyMessage* signed_request,
|
||||||
|
|||||||
@@ -399,7 +399,11 @@ enum CdmResponseType {
|
|||||||
REWRAP_DEVICE_RSA_KEY_30_ERROR = 345,
|
REWRAP_DEVICE_RSA_KEY_30_ERROR = 345,
|
||||||
INVALID_SRM_LIST = 346,
|
INVALID_SRM_LIST = 346,
|
||||||
KEYSET_ID_NOT_FOUND_4 = 347,
|
KEYSET_ID_NOT_FOUND_4 = 347,
|
||||||
// Don't forget to add new values to ../test/test_printers.cpp.
|
SESSION_NOT_FOUND_22 = 348,
|
||||||
|
// Don't forget to add new values to
|
||||||
|
// * core/test/test_printers.cpp.
|
||||||
|
// * android/include/mapErrors-inl.h
|
||||||
|
// * android/include_hidl/mapErrors-inl.h
|
||||||
};
|
};
|
||||||
|
|
||||||
enum CdmKeyStatus {
|
enum CdmKeyStatus {
|
||||||
|
|||||||
@@ -507,6 +507,19 @@ CdmResponseType CdmEngine::RenewKey(const CdmSessionId& session_id,
|
|||||||
return KEY_ADDED;
|
return KEY_ADDED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CdmResponseType CdmEngine::SetSessionServiceCertificate(
|
||||||
|
const CdmSessionId& session_id, const std::string& service_certificate) {
|
||||||
|
LOGI("Setting service certificate: session_id = %s", session_id.c_str());
|
||||||
|
|
||||||
|
std::shared_ptr<CdmSession> session;
|
||||||
|
if (!session_map_.FindSession(session_id, &session)) {
|
||||||
|
LOGE("Session ID not found: %s", session_id.c_str());
|
||||||
|
return SESSION_NOT_FOUND_22;
|
||||||
|
}
|
||||||
|
|
||||||
|
return session->SetServiceCertificate(service_certificate);
|
||||||
|
}
|
||||||
|
|
||||||
CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level,
|
CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level,
|
||||||
const std::string& query_token,
|
const std::string& query_token,
|
||||||
std::string* query_response) {
|
std::string* query_response) {
|
||||||
|
|||||||
@@ -586,6 +586,11 @@ CdmResponseType CdmSession::QueryStatus(CdmQueryMap* query_response) {
|
|||||||
return NO_ERROR;
|
return NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CdmResponseType CdmSession::SetServiceCertificate(
|
||||||
|
const std::string& service_certificate) {
|
||||||
|
return license_parser_->SetServiceCertificate(service_certificate);
|
||||||
|
}
|
||||||
|
|
||||||
CdmResponseType CdmSession::QueryKeyStatus(CdmQueryMap* query_response) {
|
CdmResponseType CdmSession::QueryKeyStatus(CdmQueryMap* query_response) {
|
||||||
return policy_engine_->Query(query_response);
|
return policy_engine_->Query(query_response);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -226,16 +226,9 @@ bool CdmLicense::Init(const std::string& client_token,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (use_privacy_mode) {
|
if (use_privacy_mode && !signed_service_certificate.empty() &&
|
||||||
if (!signed_service_certificate.empty()) {
|
service_certificate_.Init(signed_service_certificate) != NO_ERROR) {
|
||||||
if (service_certificate_.Init(signed_service_certificate) != NO_ERROR)
|
return false;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!service_certificate_.has_certificate() &&
|
|
||||||
!Properties::allow_service_certificate_requests()) {
|
|
||||||
LOGE("Required service certificate not provided");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
client_token_ = client_token;
|
client_token_ = client_token;
|
||||||
@@ -248,6 +241,11 @@ bool CdmLicense::Init(const std::string& client_token,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CdmResponseType CdmLicense::SetServiceCertificate(
|
||||||
|
const std::string& signed_service_certificate) {
|
||||||
|
return service_certificate_.Init(signed_service_certificate);
|
||||||
|
}
|
||||||
|
|
||||||
CdmResponseType CdmLicense::PrepareKeyRequest(
|
CdmResponseType CdmLicense::PrepareKeyRequest(
|
||||||
const InitializationData& init_data, CdmLicenseType license_type,
|
const InitializationData& init_data, CdmLicenseType license_type,
|
||||||
const CdmAppParameterMap& app_parameters, CdmKeyMessage* signed_request,
|
const CdmAppParameterMap& app_parameters, CdmKeyMessage* signed_request,
|
||||||
|
|||||||
@@ -44,6 +44,8 @@ const std::string kWebmMimeType = "video/webm";
|
|||||||
const std::string kEmptyString;
|
const std::string kEmptyString;
|
||||||
const std::string kComma = ",";
|
const std::string kComma = ",";
|
||||||
|
|
||||||
|
const std::string kFakeSessionId = "TotallyARealSession123456789";
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
class WvCdmEnginePreProvTest : public WvCdmTestBase {
|
class WvCdmEnginePreProvTest : public WvCdmTestBase {
|
||||||
@@ -317,6 +319,27 @@ TEST_F(WvCdmEnginePreProvTestUat, ProvisioningServiceCertificateInvalidTest) {
|
|||||||
ASSERT_NE(cdm_engine_.ValidateServiceCertificate(certificate), NO_ERROR);
|
ASSERT_NE(cdm_engine_.ValidateServiceCertificate(certificate), NO_ERROR);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
TEST_F(WvCdmEngineTest, SetLicensingServiceValidCertificate) {
|
||||||
|
ASSERT_EQ(cdm_engine_.SetSessionServiceCertificate(
|
||||||
|
session_id_, config_.license_service_certificate()),
|
||||||
|
NO_ERROR);
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_F(WvCdmEngineTest, SetLicensingServiceCertificateUnknownSession) {
|
||||||
|
ASSERT_EQ(cdm_engine_.SetSessionServiceCertificate(
|
||||||
|
kFakeSessionId, config_.license_service_certificate()),
|
||||||
|
SESSION_NOT_FOUND_22);
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_F(WvCdmEngineTest, SetLicensingServiceInvalidCertificate) {
|
||||||
|
std::string certificate = config_.license_service_certificate();
|
||||||
|
// Add four nulls to the beginning of the cert to invalidate it
|
||||||
|
certificate.insert(0, 4, '\0');
|
||||||
|
|
||||||
|
ASSERT_NE(cdm_engine_.SetSessionServiceCertificate(session_id_, certificate),
|
||||||
|
NO_ERROR);
|
||||||
|
};
|
||||||
|
|
||||||
TEST_F(WvCdmEnginePreProvTestStaging, ProvisioningTest) { Provision(); }
|
TEST_F(WvCdmEnginePreProvTestStaging, ProvisioningTest) { Provision(); }
|
||||||
|
|
||||||
TEST_F(WvCdmEnginePreProvTestUatBinary, ProvisioningTest) {
|
TEST_F(WvCdmEnginePreProvTestUatBinary, ProvisioningTest) {
|
||||||
|
|||||||
@@ -282,10 +282,9 @@ TEST_F(CdmLicenseTest, InitWithEmptyServiceCert) {
|
|||||||
EXPECT_CALL(*crypto_session_, IsOpen()).WillOnce(Return(true));
|
EXPECT_CALL(*crypto_session_, IsOpen()).WillOnce(Return(true));
|
||||||
|
|
||||||
CreateCdmLicense();
|
CreateCdmLicense();
|
||||||
EXPECT_EQ(cdm_license_->Init(kToken, kClientTokenDrmCert, "", true,
|
EXPECT_TRUE(cdm_license_->Init(kToken, kClientTokenDrmCert, "", true,
|
||||||
kEmptyServiceCertificate, crypto_session_,
|
kEmptyServiceCertificate, crypto_session_,
|
||||||
policy_engine_),
|
policy_engine_));
|
||||||
Properties::allow_service_certificate_requests());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(CdmLicenseTest, InitWithInvalidServiceCert) {
|
TEST_F(CdmLicenseTest, InitWithInvalidServiceCert) {
|
||||||
|
|||||||
@@ -781,6 +781,9 @@ void PrintTo(const enum CdmResponseType& value, ::std::ostream* os) {
|
|||||||
case SESSION_NOT_FOUND_21:
|
case SESSION_NOT_FOUND_21:
|
||||||
*os << "SESSION_NOT_FOUND_21";
|
*os << "SESSION_NOT_FOUND_21";
|
||||||
break;
|
break;
|
||||||
|
case SESSION_NOT_FOUND_22:
|
||||||
|
*os << "SESSION_NOT_FOUND_22";
|
||||||
|
break;
|
||||||
case INVALID_DECRYPT_HASH_FORMAT:
|
case INVALID_DECRYPT_HASH_FORMAT:
|
||||||
*os << "INVALID_DECRYPT_HASH_FORMAT";
|
*os << "INVALID_DECRYPT_HASH_FORMAT";
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -231,6 +231,7 @@ static android::status_t mapCdmResponseType(wvcdm::CdmResponseType res) {
|
|||||||
case wvcdm::SESSION_NOT_FOUND_19:
|
case wvcdm::SESSION_NOT_FOUND_19:
|
||||||
case wvcdm::SESSION_NOT_FOUND_20:
|
case wvcdm::SESSION_NOT_FOUND_20:
|
||||||
case wvcdm::SESSION_NOT_FOUND_21:
|
case wvcdm::SESSION_NOT_FOUND_21:
|
||||||
|
case wvcdm::SESSION_NOT_FOUND_22:
|
||||||
return android::ERROR_DRM_SESSION_NOT_OPENED;
|
return android::ERROR_DRM_SESSION_NOT_OPENED;
|
||||||
case wvcdm::SESSION_KEYS_NOT_FOUND:
|
case wvcdm::SESSION_KEYS_NOT_FOUND:
|
||||||
return kSessionKeysNotFound;
|
return kSessionKeysNotFound;
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ static Status mapCdmResponseType(wvcdm::CdmResponseType res) {
|
|||||||
case wvcdm::SESSION_NOT_FOUND_19:
|
case wvcdm::SESSION_NOT_FOUND_19:
|
||||||
case wvcdm::SESSION_NOT_FOUND_20:
|
case wvcdm::SESSION_NOT_FOUND_20:
|
||||||
case wvcdm::SESSION_NOT_FOUND_21:
|
case wvcdm::SESSION_NOT_FOUND_21:
|
||||||
|
case wvcdm::SESSION_NOT_FOUND_22:
|
||||||
return Status::ERROR_DRM_SESSION_NOT_OPENED;
|
return Status::ERROR_DRM_SESSION_NOT_OPENED;
|
||||||
|
|
||||||
case wvcdm::DECRYPT_ERROR:
|
case wvcdm::DECRYPT_ERROR:
|
||||||
|
|||||||
Reference in New Issue
Block a user