Support provisioning 3.0
[ Merge of http://go/wvgerrit/29004 ] Enable support for provisioning with OEM certificates as root of trust. b/62972441 Test: WV unit/intgration test, cdm_feature_test and GTSMediaTestCases Change-Id: I30576fc0bb68a873eeaaca03f6b9c89fa6a14327
This commit is contained in:
@@ -162,7 +162,15 @@ bool CryptoSession::GetTokenFromKeybox(std::string* token) {
|
||||
}
|
||||
|
||||
bool CryptoSession::GetTokenFromOemCert(std::string* token) {
|
||||
if (token == NULL) {
|
||||
LOGE("CryptoSession::GetTokenFromOemCert: token not provided ");
|
||||
return false;
|
||||
}
|
||||
OEMCryptoResult status;
|
||||
if (!oem_token_.empty()) {
|
||||
token->assign(oem_token_);
|
||||
return true;
|
||||
}
|
||||
std::string temp_buffer(CERTIFICATE_DATA_SIZE, '\0');
|
||||
// lock is held by caller
|
||||
bool retrying = false;
|
||||
@@ -171,7 +179,9 @@ bool CryptoSession::GetTokenFromOemCert(std::string* token) {
|
||||
uint8_t* buf = reinterpret_cast<uint8_t*>(&temp_buffer[0]);
|
||||
status = OEMCrypto_GetOEMPublicCertificate(oec_session_id_, buf, &buf_size);
|
||||
if (OEMCrypto_SUCCESS == status) {
|
||||
token->swap(temp_buffer);
|
||||
temp_buffer.resize(buf_size);
|
||||
oem_token_.assign(temp_buffer);
|
||||
token->assign(temp_buffer);
|
||||
return true;
|
||||
}
|
||||
if (OEMCrypto_ERROR_SHORT_BUFFER && !retrying) {
|
||||
@@ -568,8 +578,8 @@ bool CryptoSession::PrepareRequest(const std::string& message,
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO(gmorgan): rework this for OEM certs.
|
||||
if (!Properties::use_certificates_as_identification() || is_provisioning) {
|
||||
if (!Properties::use_certificates_as_identification() ||
|
||||
(is_provisioning && (pre_provision_token_type_ == kClientTokenKeybox))) {
|
||||
if (!GenerateDerivedKeys(message)) return false;
|
||||
|
||||
if (!GenerateSignature(message, signature)) return false;
|
||||
@@ -739,8 +749,15 @@ bool CryptoSession::LoadCertificatePrivateKey(std::string& wrapped_key) {
|
||||
LOGV("CryptoSession::LoadCertificatePrivateKey: Lock");
|
||||
AutoLock auto_lock(crypto_lock_);
|
||||
|
||||
// Call OEMCrypto_GetOEMPublicCertificate before OEMCrypto_LoadDeviceRSAKey
|
||||
// so it caches the OEMCrypto Public Key and then throw away result
|
||||
std::string temp_buffer(CERTIFICATE_DATA_SIZE, '\0');
|
||||
size_t buf_size = temp_buffer.size();
|
||||
uint8_t* buf = reinterpret_cast<uint8_t*>(&temp_buffer[0]);
|
||||
OEMCryptoResult sts =
|
||||
OEMCrypto_GetOEMPublicCertificate(oec_session_id_, buf, &buf_size);
|
||||
|
||||
LOGV("LoadDeviceRSAKey: id=%ld", (uint32_t)oec_session_id_);
|
||||
OEMCryptoResult sts;
|
||||
M_TIME(
|
||||
sts = OEMCrypto_LoadDeviceRSAKey(
|
||||
oec_session_id_,
|
||||
@@ -1458,6 +1475,34 @@ bool CryptoSession::SetDestinationBufferType() {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CryptoSession::RewrapCertificate(const std::string& signed_message,
|
||||
const std::string& signature,
|
||||
const std::string& nonce,
|
||||
const std::string& private_key,
|
||||
const std::string& iv,
|
||||
const std::string& wrapping_key,
|
||||
std::string* wrapped_private_key) {
|
||||
LOGV("CryptoSession::RewrapCertificate, session id=%ld",
|
||||
static_cast<uint32_t>(oec_session_id_));
|
||||
|
||||
if (pre_provision_token_type_ == kClientTokenKeybox) {
|
||||
|
||||
return RewrapDeviceRSAKey(signed_message, signature, nonce, private_key,
|
||||
iv, wrapped_private_key);
|
||||
|
||||
} else if (pre_provision_token_type_ == kClientTokenOemCert) {
|
||||
|
||||
return RewrapDeviceRSAKey30(signed_message, nonce, private_key, iv,
|
||||
wrapping_key, wrapped_private_key);
|
||||
|
||||
} else {
|
||||
LOGE("CryptoSession::RewrapCertificate, Bad pre-provision type=%d: "
|
||||
"session id=%ld", pre_provision_token_type_,
|
||||
static_cast<uint32_t>(oec_session_id_));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool CryptoSession::RewrapDeviceRSAKey(const std::string& message,
|
||||
const std::string& signature,
|
||||
const std::string& nonce,
|
||||
@@ -1531,6 +1576,57 @@ bool CryptoSession::RewrapDeviceRSAKey(const std::string& message,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CryptoSession::RewrapDeviceRSAKey30(const std::string& message,
|
||||
const std::string& nonce,
|
||||
const std::string& private_key,
|
||||
const std::string& iv,
|
||||
const std::string& wrapping_key,
|
||||
std::string* wrapped_private_key) {
|
||||
LOGV("CryptoSession::RewrapDeviceRSAKey30, session id=%ld",
|
||||
static_cast<uint32_t>(oec_session_id_));
|
||||
|
||||
const uint8_t* signed_msg = reinterpret_cast<const uint8_t*>(message.data());
|
||||
const uint8_t* msg_private_key = NULL;
|
||||
const uint8_t* msg_iv = NULL;
|
||||
const uint32_t* msg_nonce = NULL;
|
||||
const uint8_t* msg_wrapping_key = NULL;
|
||||
if (private_key.size() >= MAC_KEY_SIZE && iv.size() >= KEY_IV_SIZE) {
|
||||
msg_private_key = signed_msg + GetOffset(message, private_key);
|
||||
msg_iv = signed_msg + GetOffset(message, iv);
|
||||
msg_nonce = reinterpret_cast<const uint32_t*>(signed_msg +
|
||||
GetOffset(message, nonce));
|
||||
msg_wrapping_key = signed_msg + GetOffset(message, wrapping_key);
|
||||
}
|
||||
|
||||
// Gets wrapped_rsa_key_length by passing NULL as uint8_t* wrapped_rsa_key
|
||||
// and 0 as wrapped_rsa_key_length.
|
||||
size_t wrapped_private_key_length = 0;
|
||||
OEMCryptoResult status = OEMCrypto_RewrapDeviceRSAKey30(
|
||||
oec_session_id_, msg_nonce, msg_wrapping_key, wrapping_key.size(),
|
||||
msg_private_key, private_key.size(), msg_iv, NULL,
|
||||
&wrapped_private_key_length);
|
||||
|
||||
if (status != OEMCrypto_ERROR_SHORT_BUFFER) {
|
||||
LOGE("OEMCrypto_RewrapDeviceRSAKey30 failed getting wrapped key length");
|
||||
return false;
|
||||
}
|
||||
|
||||
wrapped_private_key->resize(wrapped_private_key_length);
|
||||
status = OEMCrypto_RewrapDeviceRSAKey30(
|
||||
oec_session_id_, msg_nonce, msg_wrapping_key, wrapping_key.size(),
|
||||
msg_private_key, private_key.size(), msg_iv,
|
||||
reinterpret_cast<uint8_t*>(&(*wrapped_private_key)[0]),
|
||||
&wrapped_private_key_length);
|
||||
|
||||
wrapped_private_key->resize(wrapped_private_key_length);
|
||||
|
||||
if (OEMCrypto_SUCCESS != status) {
|
||||
LOGE("OEMCrypto_RewrapDeviceRSAKey fails with %d", status);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CryptoSession::GetHdcpCapabilities(HdcpCapability* current,
|
||||
HdcpCapability* max) {
|
||||
LOGV("GetHdcpCapabilities: id=%ld", (uint32_t)oec_session_id_);
|
||||
|
||||
Reference in New Issue
Block a user