Address failures when provisioning methods differ am: f0cd22d4f4

am: 89f6b215e9

Change-Id: Ic9e300c25404127746cb1995449fe33efd076399
This commit is contained in:
Rahul Frias
2018-04-09 16:53:22 -07:00
committed by android-build-merger
9 changed files with 83 additions and 26 deletions

View File

@@ -199,7 +199,8 @@ class CryptoSession {
private: private:
friend class CryptoSessionForTest; friend class CryptoSessionForTest;
bool GetProvisioningMethod(CdmClientTokenType* token_type); CdmResponseType GetProvisioningMethod(SecurityLevel requested_security_level,
CdmClientTokenType* token_type);
void Init(); void Init();
void Terminate(); void Terminate();
bool GetTokenFromKeybox(std::string* token); bool GetTokenFromKeybox(std::string* token);

View File

@@ -324,6 +324,7 @@ enum CdmResponseType {
REMOVE_USAGE_INFO_ERROR_1 = 282, REMOVE_USAGE_INFO_ERROR_1 = 282,
REMOVE_USAGE_INFO_ERROR_2 = 283, REMOVE_USAGE_INFO_ERROR_2 = 283,
REMOVE_USAGE_INFO_ERROR_3 = 284, REMOVE_USAGE_INFO_ERROR_3 = 284,
GET_PROVISIONING_METHOD_ERROR = 285,
}; };
enum CdmKeyStatus { enum CdmKeyStatus {
@@ -397,7 +398,8 @@ enum CdmSigningAlgorithm {
enum CdmClientTokenType { enum CdmClientTokenType {
kClientTokenKeybox, kClientTokenKeybox,
kClientTokenDrmCert, kClientTokenDrmCert,
kClientTokenOemCert kClientTokenOemCert,
kClientTokenUninitialized,
}; };
// kNonSecureUsageSupport - TEE does not provide any support for usage // kNonSecureUsageSupport - TEE does not provide any support for usage

View File

@@ -757,6 +757,7 @@ CdmResponseType CdmEngine::QueryOemCryptoSessionId(
CdmResponseType CdmEngine::GetProvisioningRequest( CdmResponseType CdmEngine::GetProvisioningRequest(
CdmCertificateType cert_type, const std::string& cert_authority, CdmCertificateType cert_type, const std::string& cert_authority,
CdmProvisioningRequest* request, std::string* default_url) { CdmProvisioningRequest* request, std::string* default_url) {
LOGI("CdmEngine::GetProvisioningRequest");
if (!request) { if (!request) {
LOGE("CdmEngine::GetProvisioningRequest: invalid output parameters"); LOGE("CdmEngine::GetProvisioningRequest: invalid output parameters");
return INVALID_PROVISIONING_REQUEST_PARAM_1; return INVALID_PROVISIONING_REQUEST_PARAM_1;
@@ -794,6 +795,7 @@ CdmResponseType CdmEngine::GetProvisioningRequest(
CdmResponseType CdmEngine::HandleProvisioningResponse( CdmResponseType CdmEngine::HandleProvisioningResponse(
const CdmProvisioningResponse& response, std::string* cert, const CdmProvisioningResponse& response, std::string* cert,
std::string* wrapped_key) { std::string* wrapped_key) {
LOGI("CdmEngine::HandleProvisioningResponse");
if (response.empty()) { if (response.empty()) {
LOGE("CdmEngine::HandleProvisioningResponse: Empty provisioning response."); LOGE("CdmEngine::HandleProvisioningResponse: Empty provisioning response.");
cert_provisioning_.reset(NULL); cert_provisioning_.reset(NULL);

View File

@@ -138,6 +138,7 @@ CryptoSession::CryptoSession(metrics::CryptoMetrics* metrics)
: metrics_(metrics), : metrics_(metrics),
system_id_(-1), system_id_(-1),
open_(false), open_(false),
pre_provision_token_type_(kClientTokenUninitialized),
update_usage_table_after_close_session_(false), update_usage_table_after_close_session_(false),
is_destination_buffer_type_valid_(false), is_destination_buffer_type_valid_(false),
requested_security_level_(kLevelDefault), requested_security_level_(kLevelDefault),
@@ -160,9 +161,11 @@ CryptoSession::~CryptoSession() {
M_RECORD(metrics_, crypto_session_life_span_, life_span_.AsMs()); M_RECORD(metrics_, crypto_session_life_span_, life_span_.AsMs());
} }
bool CryptoSession::GetProvisioningMethod(CdmClientTokenType* token_type) { CdmResponseType CryptoSession::GetProvisioningMethod(
SecurityLevel requested_security_level,
CdmClientTokenType* token_type) {
OEMCrypto_ProvisioningMethod method = OEMCrypto_ProvisioningMethod method =
OEMCrypto_GetProvisioningMethod(requested_security_level_); OEMCrypto_GetProvisioningMethod(requested_security_level);
metrics_->oemcrypto_provisioning_method_.Record(method); metrics_->oemcrypto_provisioning_method_.Record(method);
CdmClientTokenType type; CdmClientTokenType type;
switch (method) { switch (method) {
@@ -179,10 +182,10 @@ bool CryptoSession::GetProvisioningMethod(CdmClientTokenType* token_type) {
default: default:
LOGE("OEMCrypto_GetProvisioningMethod failed. %d", method); LOGE("OEMCrypto_GetProvisioningMethod failed. %d", method);
metrics_->oemcrypto_provisioning_method_.SetError(method); metrics_->oemcrypto_provisioning_method_.SetError(method);
return false; return GET_PROVISIONING_METHOD_ERROR;
} }
*token_type = type; *token_type = type;
return true; return NO_ERROR;
} }
void CryptoSession::Init() { void CryptoSession::Init() {
@@ -198,9 +201,6 @@ void CryptoSession::Init() {
} }
initialized_ = true; initialized_ = true;
} }
if (!GetProvisioningMethod(&pre_provision_token_type_)) {
initialized_ = false;
}
} }
void CryptoSession::Terminate() { void CryptoSession::Terminate() {
@@ -594,10 +594,12 @@ bool CryptoSession::GetProvisioningId(std::string* provisioning_id) {
uint8_t buf[KEYBOX_KEY_DATA_SIZE]; uint8_t buf[KEYBOX_KEY_DATA_SIZE];
size_t buf_size = sizeof(buf); size_t buf_size = sizeof(buf);
LOGV("CryptoSession::GetProvisioningId: Lock"); {
AutoLock auto_lock(crypto_lock_); LOGV("CryptoSession::GetProvisioningId: Lock");
if (!initialized_) { AutoLock auto_lock(crypto_lock_);
return false; if (!initialized_) {
return false;
}
} }
if (pre_provision_token_type_ == kClientTokenOemCert) { if (pre_provision_token_type_ == kClientTokenOemCert) {
@@ -614,6 +616,8 @@ bool CryptoSession::GetProvisioningId(std::string* provisioning_id) {
return true; return true;
} else { } else {
OEMCryptoResult sts; OEMCryptoResult sts;
LOGV("CryptoSession::GetProvisioningId: Lock");
AutoLock auto_lock(crypto_lock_);
M_TIME( M_TIME(
sts = OEMCrypto_GetKeyData(buf, &buf_size, requested_security_level_), sts = OEMCrypto_GetKeyData(buf, &buf_size, requested_security_level_),
metrics_, oemcrypto_get_key_data_, sts, metrics::Pow2Bucket(buf_size)); metrics_, oemcrypto_get_key_data_, sts, metrics::Pow2Bucket(buf_size));
@@ -633,14 +637,23 @@ uint8_t CryptoSession::GetSecurityPatchLevel() {
} }
CdmResponseType CryptoSession::Open(SecurityLevel requested_security_level) { CdmResponseType CryptoSession::Open(SecurityLevel requested_security_level) {
LOGD("CryptoSession::Open: Lock: requested_security_level: %s", {
requested_security_level == kLevel3 LOGD("CryptoSession::Open: Lock: requested_security_level: %s",
? QUERY_VALUE_SECURITY_LEVEL_L3.c_str() requested_security_level == kLevel3
: QUERY_VALUE_SECURITY_LEVEL_DEFAULT.c_str()); ? QUERY_VALUE_SECURITY_LEVEL_L3.c_str()
AutoLock auto_lock(crypto_lock_); : QUERY_VALUE_SECURITY_LEVEL_DEFAULT.c_str());
if (!initialized_) return UNKNOWN_ERROR; AutoLock auto_lock(crypto_lock_);
if (open_) return NO_ERROR; if (!initialized_) return UNKNOWN_ERROR;
if (open_) return NO_ERROR;
}
CdmResponseType result =
GetProvisioningMethod(requested_security_level,
&pre_provision_token_type_);
if (result != NO_ERROR) return result;
LOGV("CryptoSession::Open: Lock");
AutoLock auto_lock(crypto_lock_);
OEMCrypto_SESSION sid; OEMCrypto_SESSION sid;
requested_security_level_ = requested_security_level; requested_security_level_ = requested_security_level;
OEMCryptoResult sts = OEMCrypto_OpenSession(&sid, requested_security_level); OEMCryptoResult sts = OEMCrypto_OpenSession(&sid, requested_security_level);
@@ -679,7 +692,7 @@ CdmResponseType CryptoSession::Open(SecurityLevel requested_security_level) {
} }
CdmUsageSupportType usage_support_type; CdmUsageSupportType usage_support_type;
CdmResponseType result = GetUsageSupportType(&usage_support_type); result = GetUsageSupportType(&usage_support_type);
if (result == NO_ERROR) { if (result == NO_ERROR) {
metrics_->oemcrypto_usage_table_support_.Record(usage_support_type); metrics_->oemcrypto_usage_table_support_.Record(usage_support_type);
if (usage_support_type == kUsageEntrySupport) { if (usage_support_type == kUsageEntrySupport) {

View File

@@ -581,6 +581,8 @@ void PrintTo(const enum CdmResponseType& value, ::std::ostream* os) {
break; break;
case REMOVE_USAGE_INFO_ERROR_3: *os << "REMOVE_USAGE_INFO_ERROR_3"; case REMOVE_USAGE_INFO_ERROR_3: *os << "REMOVE_USAGE_INFO_ERROR_3";
break; break;
case GET_PROVISIONING_METHOD_ERROR: *os << "GET_PROVISIONING_METHOD_ERROR";
break;
default: default:
*os << "Unknown CdmResponseType"; *os << "Unknown CdmResponseType";
break; break;

View File

@@ -1620,8 +1620,39 @@ class WvCdmRequestLicenseTest : public WvCdmTestBase {
}; };
TEST_F(WvCdmRequestLicenseTest, ProvisioningTest) { TEST_F(WvCdmRequestLicenseTest, ProvisioningTest) {
decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, Unprovision();
&session_id_); EXPECT_EQ(NEED_PROVISIONING,
decryptor_.OpenSession(g_key_system, NULL,
kDefaultCdmIdentifier, NULL,
&session_id_));
std::string provisioning_server;
CdmCertificateType cert_type = kCertificateWidevine;
std::string cert_authority, cert, wrapped_key;
EXPECT_EQ(wvcdm::NO_ERROR, decryptor_.GetProvisioningRequest(
cert_type, cert_authority,
kDefaultCdmIdentifier, &key_msg_,
&provisioning_server));
EXPECT_EQ(provisioning_server, g_config->provisioning_server());
std::string response =
GetCertRequestResponse(g_config->provisioning_server());
EXPECT_NE(0, static_cast<int>(response.size()));
EXPECT_EQ(wvcdm::NO_ERROR, decryptor_.HandleProvisioningResponse(
kDefaultCdmIdentifier, response, &cert,
&wrapped_key));
EXPECT_EQ(0, static_cast<int>(cert.size()));
EXPECT_EQ(0, static_cast<int>(wrapped_key.size()));
decryptor_.CloseSession(session_id_);
}
TEST_F(WvCdmRequestLicenseTest, L3ProvisioningTest) {
TestWvCdmClientPropertySet property_set_L3;
property_set_L3.set_security_level(QUERY_VALUE_SECURITY_LEVEL_L3);
EXPECT_EQ(NEED_PROVISIONING,
decryptor_.OpenSession(g_key_system, &property_set_L3,
kDefaultCdmIdentifier, NULL,
&session_id_));
std::string provisioning_server; std::string provisioning_server;
CdmCertificateType cert_type = kCertificateWidevine; CdmCertificateType cert_type = kCertificateWidevine;
std::string cert_authority, cert, wrapped_key; std::string cert_authority, cert, wrapped_key;
@@ -3764,7 +3795,8 @@ TEST_F(WvCdmRequestLicenseTest, QueryStatus) {
EXPECT_EQ(wvcdm::NO_ERROR, EXPECT_EQ(wvcdm::NO_ERROR,
decryptor_.QueryStatus(kLevelDefault, decryptor_.QueryStatus(kLevelDefault,
wvcdm::QUERY_KEY_PROVISIONING_ID, &value)); wvcdm::QUERY_KEY_PROVISIONING_ID, &value));
EXPECT_EQ(16u, value.size()); EXPECT_TRUE(16u == value.size() || 32u == value.size())
<< "provisioning id size: " << value.size();
EXPECT_EQ(wvcdm::NO_ERROR, EXPECT_EQ(wvcdm::NO_ERROR,
decryptor_.QueryStatus( decryptor_.QueryStatus(
@@ -3866,7 +3898,8 @@ TEST_F(WvCdmRequestLicenseTest, QueryStatusL3) {
EXPECT_EQ(wvcdm::NO_ERROR, EXPECT_EQ(wvcdm::NO_ERROR,
decryptor_.QueryStatus(kLevel3, wvcdm::QUERY_KEY_PROVISIONING_ID, decryptor_.QueryStatus(kLevel3, wvcdm::QUERY_KEY_PROVISIONING_ID,
&value)); &value));
EXPECT_EQ(16u, value.size()); EXPECT_TRUE(16u == value.size() || 32u == value.size())
<< "provisioning id size: " << value.size();
EXPECT_EQ(wvcdm::NO_ERROR, EXPECT_EQ(wvcdm::NO_ERROR,
decryptor_.QueryStatus(kLevel3, wvcdm::QUERY_KEY_CURRENT_HDCP_LEVEL, decryptor_.QueryStatus(kLevel3, wvcdm::QUERY_KEY_CURRENT_HDCP_LEVEL,

View File

@@ -263,10 +263,11 @@ enum {
kRemoveUsageInfoError1 = ERROR_DRM_VENDOR_MIN + 274, kRemoveUsageInfoError1 = ERROR_DRM_VENDOR_MIN + 274,
kRemoveUsageInfoError2 = ERROR_DRM_VENDOR_MIN + 275, kRemoveUsageInfoError2 = ERROR_DRM_VENDOR_MIN + 275,
kRemoveUsageInfoError3 = ERROR_DRM_VENDOR_MIN + 276, kRemoveUsageInfoError3 = ERROR_DRM_VENDOR_MIN + 276,
kGetProvisioningError = ERROR_DRM_VENDOR_MIN + 277,
// This should always follow the last error code. // This should always follow the last error code.
// The offset value should be updated each time a new error code is added. // The offset value should be updated each time a new error code is added.
kErrorWVDrmMaxErrorUsed = ERROR_DRM_VENDOR_MIN + 276, kErrorWVDrmMaxErrorUsed = ERROR_DRM_VENDOR_MIN + 277,
// Used by crypto test mode // Used by crypto test mode
kErrorTestMode = ERROR_DRM_VENDOR_MAX, kErrorTestMode = ERROR_DRM_VENDOR_MAX,

View File

@@ -507,6 +507,8 @@ static android::status_t mapCdmResponseType(wvcdm::CdmResponseType res) {
return kRemoveUsageInfoError2; return kRemoveUsageInfoError2;
case wvcdm::REMOVE_USAGE_INFO_ERROR_3: case wvcdm::REMOVE_USAGE_INFO_ERROR_3:
return kRemoveUsageInfoError3; return kRemoveUsageInfoError3;
case wvcdm::GET_PROVISIONING_METHOD_ERROR:
return kGetProvisioningError;
} }
// Return here instead of as a default case so that the compiler will warn // Return here instead of as a default case so that the compiler will warn

View File

@@ -290,6 +290,7 @@ static Status mapCdmResponseType(wvcdm::CdmResponseType res) {
case wvcdm::REMOVE_USAGE_INFO_ERROR_1: case wvcdm::REMOVE_USAGE_INFO_ERROR_1:
case wvcdm::REMOVE_USAGE_INFO_ERROR_2: case wvcdm::REMOVE_USAGE_INFO_ERROR_2:
case wvcdm::REMOVE_USAGE_INFO_ERROR_3: case wvcdm::REMOVE_USAGE_INFO_ERROR_3:
case wvcdm::GET_PROVISIONING_METHOD_ERROR:
ALOGW("Returns UNKNOWN error for legacy status: %d", res); ALOGW("Returns UNKNOWN error for legacy status: %d", res);
return Status::ERROR_DRM_UNKNOWN; return Status::ERROR_DRM_UNKNOWN;