Merge "Support provisioning 3.0" into oc-mr1-dev
This commit is contained in:
@@ -55,7 +55,8 @@ void CertificateProvisioning::ComposeJsonRequestAsQueryString(
|
||||
*/
|
||||
bool CertificateProvisioning::GetProvisioningTokenType(
|
||||
ClientIdentification::TokenType* token_type) {
|
||||
switch (crypto_session_.GetPreProvisionTokenType()) {
|
||||
CdmClientTokenType token = crypto_session_.GetPreProvisionTokenType();
|
||||
switch (token) {
|
||||
case kClientTokenKeybox:
|
||||
*token_type = ClientIdentification::KEYBOX;
|
||||
return true;
|
||||
@@ -65,22 +66,23 @@ bool CertificateProvisioning::GetProvisioningTokenType(
|
||||
case kClientTokenDrmCert:
|
||||
default:
|
||||
// shouldn't happen
|
||||
LOGE("CertificateProvisioning::GetProvisioningTokenType: unexpected "
|
||||
"provisioning type: %d", token);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Fill in the appropriate field relating to stable IDs in the provisioning
|
||||
* request, no more than one of |stable_id|, |provider_id|, and |spoid|. It is
|
||||
* also valid (though deprecated) to fill in none of these in order to leave the
|
||||
* stable ID behavior up to the provisioning server.
|
||||
* Fill in the appropriate SPOID (Stable Per-Origin IDentifier) option.
|
||||
* One of spoid, provider_id or stable_id will be passed to the provisioning
|
||||
* server for determining a unique per origin ID for the device.
|
||||
* It is also valid (though deprecated) to leave the settings unset.
|
||||
*/
|
||||
bool CertificateProvisioning::FillStableIdField(
|
||||
const std::string& origin,
|
||||
const std::string& spoid,
|
||||
bool CertificateProvisioning::SetSpoidParameter(
|
||||
const std::string& origin, const std::string& spoid,
|
||||
ProvisioningRequest* request) {
|
||||
if (!request) {
|
||||
LOGE("CertificateProvisioning::FillStableIdField : No request buffer "
|
||||
LOGE("CertificateProvisioning::SetSpoidParameter: No request buffer "
|
||||
"passed to method.");
|
||||
return false;
|
||||
}
|
||||
@@ -160,21 +162,6 @@ CdmResponseType CertificateProvisioning::GetProvisioningRequest(
|
||||
client_id->set_token(token);
|
||||
client_id->set_type(token_type);
|
||||
|
||||
#if 0 // TODO(gmorgan) in progress - encrypt ClientIdentification.
|
||||
if (encrypt) {
|
||||
EncryptedClientIdentification* encrypted_client_id =
|
||||
provisioning_request->mutable_encrypted_client_id();
|
||||
CdmResponseType sts;
|
||||
sts = EncryptClientId(client_id, encrypted_client_id, certificate);
|
||||
if (NO_ERROR == sts) {
|
||||
provisioning_request->clear_client_id();
|
||||
} else {
|
||||
provisioning_request->clear_encrypted_client_id();
|
||||
}
|
||||
return sts;
|
||||
}
|
||||
#endif
|
||||
|
||||
uint32_t nonce;
|
||||
if (!crypto_session_.GenerateNonce(&nonce)) {
|
||||
LOGE("GetProvisioningRequest: fails to generate a nonce");
|
||||
@@ -204,7 +191,7 @@ CdmResponseType CertificateProvisioning::GetProvisioningRequest(
|
||||
cert_type_ = cert_type;
|
||||
options->set_certificate_authority(cert_authority);
|
||||
|
||||
if (!FillStableIdField(origin, spoid, &provisioning_request)) {
|
||||
if (!SetSpoidParameter(origin, spoid, &provisioning_request)) {
|
||||
return CERT_PROVISIONING_GET_KEYBOX_ERROR_2;
|
||||
}
|
||||
|
||||
@@ -326,11 +313,13 @@ CdmResponseType CertificateProvisioning::HandleProvisioningResponse(
|
||||
const std::string& enc_rsa_key = provisioning_response.device_rsa_key();
|
||||
const std::string& nonce = provisioning_response.nonce();
|
||||
const std::string& rsa_key_iv = provisioning_response.device_rsa_key_iv();
|
||||
const std::string& wrapping_key = (provisioning_response.has_wrapping_key()) ?
|
||||
provisioning_response.wrapping_key() : std::string();
|
||||
const std::string& signature = signed_response.signature();
|
||||
std::string wrapped_rsa_key;
|
||||
if (!crypto_session_.RewrapDeviceRSAKey(signed_message, signature, nonce,
|
||||
enc_rsa_key, rsa_key_iv,
|
||||
&wrapped_rsa_key)) {
|
||||
if (!crypto_session_.RewrapCertificate(signed_message, signature, nonce,
|
||||
enc_rsa_key, rsa_key_iv, wrapping_key,
|
||||
&wrapped_rsa_key)) {
|
||||
LOGE("HandleProvisioningResponse: RewrapDeviceRSAKey fails");
|
||||
return CERT_PROVISIONING_RESPONSE_ERROR_6;
|
||||
}
|
||||
|
||||
@@ -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