am b5a782bd: Changes JSON format for provisioning request and response to match server change.

* commit 'b5a782bdb22cb5698302665640f72cdc0b753f84':
  Changes JSON format for provisioning request and response to match server change.
This commit is contained in:
Jeff Tinker
2013-04-25 05:45:11 -07:00
committed by Android Git Automerger
3 changed files with 63 additions and 53 deletions

View File

@@ -102,7 +102,6 @@ class CdmEngine : public TimerHandler {
bool CancelSessions();
void CleanupProvisioningSession(const CdmSessionId& cdm_session_id);
void ComposeJsonRequest(const std::string& message,
const std::string& signature,
CdmProvisioningRequest* request);
// Parse a blob of multiple concatenated PSSH atoms to extract the first

View File

@@ -22,7 +22,9 @@
namespace {
const std::string kDefaultProvisioningServerUrl =
"http://www-googleapis-test.sandbox.google.com/certificateprovisioning/v1/devicecertificates/create";
"http://www-googleapis-test.sandbox.google.com/"
"certificateprovisioning/v1/devicecertificates/create"
"?key=AIzaSyB-5OLKTx2iU5mko18DfdwK5611JIjbUhE";
}
namespace wvcdm {
@@ -340,38 +342,29 @@ void CdmEngine::CleanupProvisioningSession(const CdmSessionId& cdm_session_id) {
}
/*
* This function converts message and signature into base64 format.
* This function converts SignedProvisioningRequest into base64 format.
* It then wraps it in JSON format expected by the Apiary frontend.
* Apiary requires the base64 encoding to replace '+' with minus '-',
* and '/' with underscore '_'; opposite to stubby's.
*
* Returns the JSON formated string in *request.
* The JSON formated request takes the following format:
* {
* 'signedRequest': {
* 'message': 'base64 encoded message',
* 'signature': 'base64 encoded signature'
* }
* }
*
* {'signedRequest':'base64 encoded message'}
*/
void CdmEngine::ComposeJsonRequest(
const std::string& message,
const std::string& signature,
CdmProvisioningRequest* request) {
// performs base64 encoding for message
std::vector<uint8_t> message_vector(message.begin(), message.end());
std::string message_b64 = Base64SafeEncode(message_vector);
// performs base64 encoding for signature
std::vector<uint8_t> signature_vector(signature.begin(), signature.end());
std::string signature_b64 = Base64SafeEncode(signature_vector);
request->assign("{'signedRequest':{'message':'");
request->assign("{'signedRequest':'");
request->append(message_b64);
request->append("','signature':'");
request->append(signature_b64);
request->append("'}}");
request->append("'}");
LOGD("json request:\r\n%s", request->c_str());
}
/*
@@ -458,27 +451,33 @@ CdmResponseType CdmEngine::GetProvisioningRequest(
std::string the_nonce(reinterpret_cast<char*>(&nonce), sizeof(nonce));
provisioning_request.set_nonce(the_nonce);
// Serializes the provisioning request.
std::string serialized_request;
provisioning_request.SerializeToString(&serialized_request);
std::string serialized_message;
provisioning_request.SerializeToString(&serialized_message);
// Derives signing and encryption keys and constructs signature.
std::string request_signature;
if (!crypto_session->PrepareRequest(serialized_request,
if (!crypto_session->PrepareRequest(serialized_message,
&request_signature, true)) {
request->clear();
CleanupProvisioningSession(cdm_session_id);
return UNKNOWN_ERROR;
}
if (request_signature.empty()) {
request->clear();
CleanupProvisioningSession(cdm_session_id);
return UNKNOWN_ERROR;
request->clear();
CleanupProvisioningSession(cdm_session_id);
return UNKNOWN_ERROR;
}
SignedProvisioningMessage signed_provisioning_msg;
signed_provisioning_msg.set_message(serialized_message);
signed_provisioning_msg.set_signature(request_signature);
std::string serialized_request;
signed_provisioning_msg.SerializeToString(&serialized_request);
// converts request into JSON string
ComposeJsonRequest(serialized_request, request_signature, request);
ComposeJsonRequest(serialized_request, request);
return NO_ERROR;
}
@@ -527,26 +526,18 @@ bool CdmEngine::ParseJsonResponse(
CdmResponseType CdmEngine::HandleProvisioningResponse(
CdmProvisioningResponse& response) {
if (response.empty()) {
LOGE("CdmEngine::HandleProvisioningResponse: Empty provisioning response.");
LOGE("Empty provisioning response.");
return UNKNOWN_ERROR;
}
//---------------------------------------------------------------------------
// Extracts response from JSON string, decodes base64 signed message
const std::string kMessageStart = "\"message\": \"";
const std::string kMessageEnd = "\",";
std::string signed_message;
if (!ParseJsonResponse(response, kMessageStart, kMessageEnd, &signed_message)) {
LOGE("Fails to extract signed message from JSON response");
return UNKNOWN_ERROR;
}
// Extracts signature from JSON string, decodes base64 signature
const std::string kSignatureStart = "\"signature\": \"";
const std::string kSignatureEnd = "\"";
std::string signature;
if (!ParseJsonResponse(response, kSignatureStart, kSignatureEnd, &signature)) {
LOGE("Fails to extract signature from JSON response");
// Extracts signed response from JSON string, decodes base64 signed response
const std::string kMessageStart = "\"signedResponse\": \"";
const std::string kMessageEnd = "\"";
std::string serialized_signed_response;
if (!ParseJsonResponse(response, kMessageStart, kMessageEnd,
&serialized_signed_response)) {
LOGE("Fails to extract signed serialized response from JSON response");
return UNKNOWN_ERROR;
}
@@ -568,7 +559,8 @@ CdmResponseType CdmEngine::HandleProvisioningResponse(
CdmSessionId cdm_session_id = provisioning_session_->session_id();
CryptoSession* crypto_session = crypto_engine->FindSession(cdm_session_id);
if (!crypto_session) {
LOGE("HandleProvisioningResponse: fails to find %s", cdm_session_id.c_str());
LOGE("HandleProvisioningResponse: fails to find %s",
cdm_session_id.c_str());
return UNKNOWN_ERROR;
}
@@ -576,23 +568,38 @@ CdmResponseType CdmEngine::HandleProvisioningResponse(
// Authenticates provisioning response using D1s (server key derived from
// the provisioing request's input). Validate provisioning response and
// stores private device RSA key and certificate.
SignedProvisioningMessage signed_response;
if (!signed_response.ParseFromString(serialized_signed_response)) {
LOGE("Fails to parse signed serialized response");
CleanupProvisioningSession(cdm_session_id);
return UNKNOWN_ERROR;
}
if (!signed_response.has_signature() || !signed_response.has_message()) {
LOGE("Invalid response - signature or message not found");
CleanupProvisioningSession(cdm_session_id);
return UNKNOWN_ERROR;
}
const std::string& signed_message = signed_response.message();
ProvisioningResponse provisioning_response;
if (!provisioning_response.ParseFromString(signed_message)) {
LOGE("HandleProvisioningResponse: fails to parse signed message");
LOGE("Fails to parse signed message");
CleanupProvisioningSession(cdm_session_id);
return UNKNOWN_ERROR;
}
if (!provisioning_response.has_device_rsa_key()) {
LOGE("HandleProvisioningResponse: invalid response - key not found");
LOGE("Invalid response - key not found");
CleanupProvisioningSession(cdm_session_id);
return UNKNOWN_ERROR;
}
const std::string& enc_rsa_key = provisioning_response.device_rsa_key();
const std::string& rsa_key_iv = provisioning_response.device_rsa_key_iv();
const std::string& nonce = provisioning_response.nonce();
const std::string& rsa_key_iv = provisioning_response.device_rsa_key_iv();
const std::string& signature = signed_response.signature();
std::string wrapped_rsa_key;
if (!crypto_session->RewrapDeviceRSAKey(signed_message,

View File

@@ -25,7 +25,9 @@ wvcdm::KeyId g_wrong_key_id;
int g_use_full_path = 0; // cannot use boolean in getopt_long
const std::string kDefaultProvisioningServerUrl =
"http://www-googleapis-test.sandbox.google.com/certificateprovisioning/v1/devicecertificates/create";
"http://www-googleapis-test.sandbox.google.com/"
"certificateprovisioning/v1/devicecertificates/create"
"?key=AIzaSyB-5OLKTx2iU5mko18DfdwK5611JIjbUhE";
} // namespace
namespace wvcdm {
@@ -56,7 +58,7 @@ class WvCdmRequestLicenseTest : public testing::Test {
app_parameters,
&key_msg_,
&server_url), wvcdm::KEY_MESSAGE);
EXPECT_EQ((size_t)0, server_url.size());
EXPECT_EQ(0, static_cast<int>(server_url.size()));
}
void GenerateRenewalRequest(const std::string& key_system,
@@ -71,7 +73,7 @@ class WvCdmRequestLicenseTest : public testing::Test {
app_parameters,
&key_msg_,
&server_url), wvcdm::KEY_MESSAGE);
EXPECT_NE((size_t)0, server_url.size());
EXPECT_NE(0, static_cast<int>(server_url.size()));
}
// posts a request and extracts the drm message from the response
@@ -122,9 +124,11 @@ class WvCdmRequestLicenseTest : public testing::Test {
url_request.PostCertRequest(key_msg_);
std::string response;
int resp_bytes = url_request.GetResponse(response);
LOGD("size=%u, response start: %s", response.size(),
response.substr(0, 1024).c_str());
LOGD("end: %s", response.substr(response.size() - 256).c_str());
if (resp_bytes) {
LOGD("size=%u, response start:\t\rn%s", response.size(),
response.substr(0, 1024).c_str());
LOGD("end:\r\n%s", response.substr(response.size() - 256).c_str());
}
LOGD("end %d bytes response dump", resp_bytes);
// Youtube server returns 400 for invalid message while play server returns