Accept signed service certificates

[ Merge of http://go/wvgerrit/14410 ]

When specifying a service certificate though mediaDrm, the CDM earlier expected
serialized service certificates rather than signed ones.

b/21334970

Change-Id: I39af2aa25e8dc2a651cbdce84eb32f266b5b3382
This commit is contained in:
Rahul Frias
2015-05-26 10:33:50 -07:00
parent 3cdc43caeb
commit 997ea4f447
3 changed files with 50 additions and 28 deletions

View File

@@ -62,8 +62,6 @@ class CdmLicense {
private: private:
bool PrepareServiceCertificateRequest(CdmKeyMessage* signed_request, bool PrepareServiceCertificateRequest(CdmKeyMessage* signed_request,
std::string* server_url); std::string* server_url);
CdmResponseType HandleServiceCertificateResponse(
const video_widevine_server::sdk::SignedMessage& signed_message);
CdmResponseType HandleKeyErrorResponse( CdmResponseType HandleKeyErrorResponse(
const video_widevine_server::sdk::SignedMessage& signed_message); const video_widevine_server::sdk::SignedMessage& signed_message);
@@ -76,6 +74,9 @@ class CdmLicense {
bool PrepareContentId(const CdmLicenseType license_type, bool PrepareContentId(const CdmLicenseType license_type,
const std::string& request_id, T* content_id); const std::string& request_id, T* content_id);
CdmResponseType VerifySignedServiceCertificate(
const std::string& signed_service_certificate,
std::string* service_certificate);
bool GetServiceCertificate(const CdmSessionId& session_id, bool GetServiceCertificate(const CdmSessionId& session_id,
std::string* service_certificate); std::string* service_certificate);

View File

@@ -441,8 +441,11 @@ CdmResponseType CdmLicense::HandleKeyResponse(
switch (signed_response.type()) { switch (signed_response.type()) {
case SignedMessage::LICENSE: case SignedMessage::LICENSE:
break; break;
case SignedMessage::SERVICE_CERTIFICATE: case SignedMessage::SERVICE_CERTIFICATE: {
return CdmLicense::HandleServiceCertificateResponse(signed_response); CdmResponseType status = CdmLicense::VerifySignedServiceCertificate(
signed_response.msg(), &service_certificate_);
return status == NO_ERROR ? NEED_KEY : status;
}
case SignedMessage::ERROR_RESPONSE: case SignedMessage::ERROR_RESPONSE:
return HandleKeyErrorResponse(signed_response); return HandleKeyErrorResponse(signed_response);
default: default:
@@ -549,8 +552,11 @@ CdmResponseType CdmLicense::HandleKeyUpdateResponse(
switch (signed_response.type()) { switch (signed_response.type()) {
case SignedMessage::LICENSE: case SignedMessage::LICENSE:
break; break;
case SignedMessage::SERVICE_CERTIFICATE: case SignedMessage::SERVICE_CERTIFICATE: {
return CdmLicense::HandleServiceCertificateResponse(signed_response); CdmResponseType status = CdmLicense::VerifySignedServiceCertificate(
signed_response.msg(), &service_certificate_);
return status == NO_ERROR ? NEED_KEY : status;
}
case SignedMessage::ERROR_RESPONSE: case SignedMessage::ERROR_RESPONSE:
return HandleKeyErrorResponse(signed_response); return HandleKeyErrorResponse(signed_response);
default: default:
@@ -803,12 +809,12 @@ bool CdmLicense::PrepareServiceCertificateRequest(CdmKeyMessage* signed_request,
return true; return true;
} }
CdmResponseType CdmLicense::HandleServiceCertificateResponse( CdmResponseType CdmLicense::VerifySignedServiceCertificate(
const video_widevine_server::sdk::SignedMessage& signed_response) { const std::string& signed_certificate, std::string* certificate) {
SignedDeviceCertificate signed_service_certificate; SignedDeviceCertificate signed_service_certificate;
if (!signed_service_certificate.ParseFromString(signed_response.msg())) { if (!signed_service_certificate.ParseFromString(signed_certificate)) {
LOGE( LOGE(
"CdmLicense::HandleServiceCertificateResponse: unable to parse" "CdmLicense::VerifySignedServiceCertificate: unable to parse"
"signed device certificate"); "signed device certificate");
return DEVICE_CERTIFICATE_ERROR_1; return DEVICE_CERTIFICATE_ERROR_1;
} }
@@ -819,7 +825,7 @@ CdmResponseType CdmLicense::HandleServiceCertificateResponse(
&kServiceCertificateCAPublicKey[sizeof(kServiceCertificateCAPublicKey)]); &kServiceCertificateCAPublicKey[sizeof(kServiceCertificateCAPublicKey)]);
if (!root_ca_key.Init(ca_public_key)) { if (!root_ca_key.Init(ca_public_key)) {
LOGE( LOGE(
"CdmLicense::HandleServiceCertificateResponse: public key " "CdmLicense::VerifySignedServiceCertificate: public key "
"initialization failed"); "initialization failed");
return DEVICE_CERTIFICATE_ERROR_2; return DEVICE_CERTIFICATE_ERROR_2;
} }
@@ -828,7 +834,7 @@ CdmResponseType CdmLicense::HandleServiceCertificateResponse(
signed_service_certificate.device_certificate(), signed_service_certificate.device_certificate(),
signed_service_certificate.signature())) { signed_service_certificate.signature())) {
LOGE( LOGE(
"CdmLicense::HandleServiceCertificateResponse: service " "CdmLicense::VerifySignedServiceCertificate: service "
"certificate verification failed"); "certificate verification failed");
return DEVICE_CERTIFICATE_ERROR_3; return DEVICE_CERTIFICATE_ERROR_3;
} }
@@ -837,7 +843,7 @@ CdmResponseType CdmLicense::HandleServiceCertificateResponse(
if (!service_certificate.ParseFromString( if (!service_certificate.ParseFromString(
signed_service_certificate.device_certificate())) { signed_service_certificate.device_certificate())) {
LOGE( LOGE(
"CdmLicense::HandleServiceCertificateResponse: unable to parse " "CdmLicense::VerifySignedServiceCertificate: unable to parse "
"retrieved service certificate"); "retrieved service certificate");
return DEVICE_CERTIFICATE_ERROR_4; return DEVICE_CERTIFICATE_ERROR_4;
} }
@@ -845,14 +851,14 @@ CdmResponseType CdmLicense::HandleServiceCertificateResponse(
if (service_certificate.type() != if (service_certificate.type() !=
video_widevine_server::sdk::DeviceCertificate_CertificateType_SERVICE) { video_widevine_server::sdk::DeviceCertificate_CertificateType_SERVICE) {
LOGE( LOGE(
"CdmLicense::HandleServiceCertificateResponse: certificate not of type" "CdmLicense::VerifySignedServiceCertificate: certificate not of type"
" service, %d", " service, %d",
service_certificate.type()); service_certificate.type());
return INVALID_DEVICE_CERTIFICATE_TYPE; return INVALID_DEVICE_CERTIFICATE_TYPE;
} }
service_certificate_ = signed_service_certificate.device_certificate(); *certificate = signed_service_certificate.device_certificate();
return NEED_KEY; return NO_ERROR;
} }
CdmResponseType CdmLicense::HandleKeyErrorResponse( CdmResponseType CdmLicense::HandleKeyErrorResponse(
@@ -1045,9 +1051,14 @@ CdmResponseType CdmLicense::PrepareClientId(
bool CdmLicense::GetServiceCertificate(const CdmSessionId& session_id, bool CdmLicense::GetServiceCertificate(const CdmSessionId& session_id,
std::string* service_certificate) { std::string* service_certificate) {
if (!Properties::GetServiceCertificate(session_id, service_certificate) || std::string signed_service_certificate;
service_certificate->empty()) if (!Properties::GetServiceCertificate(session_id,
&signed_service_certificate) ||
signed_service_certificate.empty() ||
NO_ERROR != VerifySignedServiceCertificate(signed_service_certificate,
service_certificate)) {
*service_certificate = service_certificate_; *service_certificate = service_certificate_;
}
if (service_certificate->size() > 0) return true; if (service_certificate->size() > 0) return true;
return false; return false;

View File

@@ -54,16 +54,26 @@ wvcdm::KeyId g_wrong_key_id;
wvcdm::LicenseServerId g_license_server_id = wvcdm::kContentProtectionServer; wvcdm::LicenseServerId g_license_server_id = wvcdm::kContentProtectionServer;
std::string kServiceCertificate = std::string kServiceCertificate =
"0803121028703454C008F63618ADE7443DB6C4C8188BE7F99005228E023082010" "0ABF020803121028703454C008F63618ADE7443DB6C4C8188BE7F99005228E023082010A02"
"A0282010100B52112B8D05D023FCC5D95E2C251C1C649B4177CD8D2BEEF355BB0" "82010100B52112B8D05D023FCC5D95E2C251C1C649B4177CD8D2BEEF355BB06743DE661E3D"
"6743DE661E3D2ABC3182B79946D55FDC08DFE95407815E9A6274B322A2C7F5E06" "2ABC3182B79946D55FDC08DFE95407815E9A6274B322A2C7F5E067BB5F0AC07A89D45AEA94"
"7BB5F0AC07A89D45AEA94B2516F075B66EF811D0D26E1B9A6B894F2B9857962AA" "B2516F075B66EF811D0D26E1B9A6B894F2B9857962AA171C4F66630D3E4C602718897F5E1E"
"171C4F66630D3E4C602718897F5E1EF9B6AAF5AD4DBA2A7E14176DF134A1D3185" "F9B6AAF5AD4DBA2A7E14176DF134A1D3185B5A218AC05A4C41F081EFFF80A3A040C50B09BB"
"B5A218AC05A4C41F081EFFF80A3A040C50B09BBC740EEDCD8F14D675A91980F92" "C740EEDCD8F14D675A91980F92CA7DDC646A06ADAD5101F74A0E498CC01F00532BAC217850"
"CA7DDC646A06ADAD5101F74A0E498CC01F00532BAC217850BD905E90923656B7D" "BD905E90923656B7DFEFEF42486767F33EF6283D4F4254AB72589390BEE55808F1D668080D"
"FEFEF42486767F33EF6283D4F4254AB72589390BEE55808F1D668080D45D893C2" "45D893C2BCA2F74D60A0C0D0A0993CEF01604703334C3638139486BC9DAF24FD67A07F9AD9"
"BCA2F74D60A0C0D0A0993CEF01604703334C3638139486BC9DAF24FD67A07F9AD" "4302030100013A1273746167696E672E676F6F676C652E636F6D128003983E30352675F40B"
"94302030100013A1273746167696E672E676F6F676C652E636F6D"; "A715FC249BDAE5D4AC7249A2666521E43655739529721FF880E0AAEFC5E27BC980DAEADABF"
"3FC386D084A02C82537848CC753FF497B011A7DA97788A00E2AA6B84CD7D71C07A48EBF616"
"02CCA5A3F32030A7295C30DA915B91DC18B9BC9593B8DE8BB50F0DEDC12938B8E9E039CDDE"
"18FA82E81BB032630FE955D85A566CE154300BF6D4C1BD126966356B287D657B18CE63D0EF"
"D45FC5269E97EAB11CB563E55643B26FF49F109C2101AFCAF35B832F288F0D9D45960E259E"
"85FB5D24DBD2CF82764C5DD9BF727EFBE9C861F869321F6ADE18905F4D92F9A6DA6536DB84"
"75871D168E870BB2303CF70C6E9784C93D2DE845AD8262BE7E0D4E2E4A0759CEF82D109D25"
"92C72429F8C01742BAE2B3DECADBC33C3E5F4BAF5E16ECB74EADBAFCB7C6705F7A9E3B6F39"
"40383F9C5116D202A20C9229EE969C2519718303B50D0130C3352E06B014D838540F8A0C22"
"7C0011E0F5B38E4E298ED2CB301EB4564965F55C5D79757A250A4EB9C84AB3E6539F6B6FDF"
"56899EA29914";
// TODO(rfrias): refactor to print out the decryption test names // TODO(rfrias): refactor to print out the decryption test names
struct SubSampleInfo { struct SubSampleInfo {