resolved conflicts for merge of 3db90f54 to master

Change-Id: Ie9e46292e003fefce9ca44a31cb338a0ecf51930
This commit is contained in:
Jeff Tinker
2014-04-01 16:32:36 -07:00
26 changed files with 874 additions and 49 deletions

View File

@@ -72,10 +72,14 @@ class WVDrmPlugin : public android::DrmPlugin,
const Vector<uint8_t>& sessionId,
KeyedVector<String8, String8>& infoMap) const;
virtual status_t getProvisionRequest(Vector<uint8_t>& request,
virtual status_t getProvisionRequest(const String8& cert_type,
const String8& cert_authority,
Vector<uint8_t>& request,
String8& defaultUrl);
virtual status_t provideProvisionResponse(const Vector<uint8_t>& response);
virtual status_t provideProvisionResponse(const Vector<uint8_t>& response,
Vector<uint8_t>& certificate,
Vector<uint8_t>& wrapped_key);
virtual status_t getSecureStops(List<Vector<uint8_t> >& secureStops);
@@ -120,6 +124,12 @@ class WVDrmPlugin : public android::DrmPlugin,
const Vector<uint8_t>& signature,
bool& match);
virtual status_t signRSA(const Vector<uint8_t>& sessionId,
const String8& algorithm,
const Vector<uint8_t>& message,
const Vector<uint8_t>& wrappedKey,
Vector<uint8_t>& signature);
virtual void OnEvent(const CdmSessionId& cdmSessionId,
CdmEventType cdmEventType);
@@ -224,6 +234,8 @@ class WVDrmPlugin : public android::DrmPlugin,
status_t mapAndNotifyOfOEMCryptoResult(const Vector<uint8_t>& sessionId,
OEMCryptoResult res);
status_t mapOEMCryptoResult(OEMCryptoResult res);
};
} // namespace wvdrm

View File

@@ -57,6 +57,33 @@ class WVGenericCryptoInterface {
algorithm, signature, signature_length);
}
virtual OEMCryptoResult openSession(OEMCrypto_SESSION *session) {
return OEMCrypto_OpenSession(session);
}
virtual OEMCryptoResult closeSession(OEMCrypto_SESSION session) {
return OEMCrypto_CloseSession(session);
}
virtual OEMCryptoResult loadDeviceRSAKey(OEMCrypto_SESSION session,
const uint8_t* wrapped_rsa_key,
size_t wrapped_rsa_key_length) {
return OEMCrypto_LoadDeviceRSAKey(session, wrapped_rsa_key,
wrapped_rsa_key_length);
}
virtual OEMCryptoResult generateRSASignature(
OEMCrypto_SESSION session,
const uint8_t* message,
size_t message_length,
uint8_t* signature,
size_t* signature_length,
RSA_Padding_Scheme padding_scheme) {
return OEMCrypto_GenerateRSASignature(session, message, message_length,
signature, signature_length,
padding_scheme);
}
private:
DISALLOW_EVIL_CONSTRUCTORS(WVGenericCryptoInterface);
};

View File

@@ -320,12 +320,23 @@ status_t WVDrmPlugin::queryKeyStatus(
return mapCdmResponseType(res);
}
status_t WVDrmPlugin::getProvisionRequest(Vector<uint8_t>& request,
status_t WVDrmPlugin::getProvisionRequest(const String8& cert_type,
const String8& cert_authority,
Vector<uint8_t>& request,
String8& defaultUrl) {
CdmProvisioningRequest cdmProvisionRequest;
string cdmDefaultUrl;
CdmResponseType res = mCDM->GetProvisioningRequest(&cdmProvisionRequest,
CdmCertificateType cdmCertType = kCertificateWidevine;
if (cert_type == "X.509") {
cdmCertType = kCertificateX509;
}
string cdmCertAuthority = cert_authority.string();
CdmResponseType res = mCDM->GetProvisioningRequest(cdmCertType,
cdmCertAuthority,
&cdmProvisionRequest,
&cdmDefaultUrl);
if (isCdmResponseTypeSuccess(res)) {
@@ -342,9 +353,27 @@ status_t WVDrmPlugin::getProvisionRequest(Vector<uint8_t>& request,
}
status_t WVDrmPlugin::provideProvisionResponse(
const Vector<uint8_t>& response) {
const Vector<uint8_t>& response,
Vector<uint8_t>& certificate,
Vector<uint8_t>& wrapped_key) {
CdmProvisioningResponse cdmResponse(response.begin(), response.end());
CdmResponseType res = mCDM->HandleProvisioningResponse(cdmResponse);
string cdmCertificate;
string cdmWrappedKey;
CdmResponseType res = mCDM->HandleProvisioningResponse(cdmResponse,
&cdmCertificate,
&cdmWrappedKey);
if (isCdmResponseTypeSuccess(res)) {
certificate.clear();
certificate.appendArray(
reinterpret_cast<const uint8_t*>(cdmCertificate.data()),
cdmCertificate.size());
wrapped_key.clear();
wrapped_key.appendArray(
reinterpret_cast<const uint8_t*>(cdmWrappedKey.data()),
cdmWrappedKey.size());
}
return mapCdmResponseType(res);
}
@@ -706,7 +735,7 @@ status_t WVDrmPlugin::sign(const Vector<uint8_t>& sessionId,
res = mCrypto->sign(cryptoSession.oecSessionId(), message.array(),
message.size(), cryptoSession.macAlgorithm(),
signature.editArray(), &signatureSize);
NULL, &signatureSize);
if (res != OEMCrypto_ERROR_SHORT_BUFFER) {
ALOGE("OEMCrypto_Generic_Sign failed with %u when requesting signature "
@@ -773,6 +802,68 @@ status_t WVDrmPlugin::verify(const Vector<uint8_t>& sessionId,
}
}
status_t WVDrmPlugin::signRSA(const Vector<uint8_t>& sessionId,
const String8& algorithm,
const Vector<uint8_t>& message,
const Vector<uint8_t>& wrappedKey,
Vector<uint8_t>& signature) {
CdmSessionId cdmSessionId(sessionId.begin(), sessionId.end());
if (!mCryptoSessions.count(cdmSessionId)) {
return android::ERROR_DRM_SESSION_NOT_OPENED;
}
const CryptoSession& cryptoSession = mCryptoSessions[cdmSessionId];
RSA_Padding_Scheme padding_scheme;
if (algorithm == "RSASSA-PSS-SHA1") {
padding_scheme = kSign_RSASSA_PSS;
} else if (algorithm == "PKCS1-BlockType1") {
padding_scheme = kSign_PKCS1_Block1;
} else {
ALOGE("Unknown RSA Algorithm %s", algorithm.string());
return android::ERROR_DRM_CANNOT_HANDLE;
}
OEMCryptoResult res = mCrypto->loadDeviceRSAKey(cryptoSession.oecSessionId(),
wrappedKey.array(),
wrappedKey.size());
if (res != OEMCrypto_SUCCESS) {
ALOGE("OEMCrypto_LoadDeviceRSAKey failed with %u", res);
return mapOEMCryptoResult(res);
}
size_t signatureSize = 0;
res = mCrypto->generateRSASignature(cryptoSession.oecSessionId(),
message.array(), message.size(),
NULL, &signatureSize, padding_scheme);
if (res != OEMCrypto_ERROR_SHORT_BUFFER) {
ALOGE("OEMCrypto_GenerateRSASignature failed with %u when requesting "
"signature size", res);
if (res != OEMCrypto_SUCCESS) {
return mapOEMCryptoResult(res);
} else {
return android::ERROR_DRM_UNKNOWN;
}
}
signature.resize(signatureSize);
res = mCrypto->generateRSASignature(cryptoSession.oecSessionId(),
message.array(), message.size(),
signature.editArray(), &signatureSize,
padding_scheme);
if (res != OEMCrypto_SUCCESS) {
ALOGE("OEMCrypto_GenerateRSASignature failed with %u", res);
return mapOEMCryptoResult(res);
}
return android::OK;
}
void WVDrmPlugin::OnEvent(const CdmSessionId& cdmSessionId,
CdmEventType cdmEventType) {
Vector<uint8_t> sessionId;
@@ -809,8 +900,13 @@ status_t WVDrmPlugin::mapAndNotifyOfCdmResponseType(
status_t WVDrmPlugin::mapAndNotifyOfOEMCryptoResult(
const Vector<uint8_t>& sessionId,
OEMCryptoResult res) {
// Note that we only cover those errors that OEMCryptoCENC.h states may be
// returned by the generic crypto methods.
if (res == OEMCrypto_ERROR_NO_DEVICE_KEY) {
sendEvent(kDrmPluginEventProvisionRequired, 0, &sessionId, NULL);
}
return mapOEMCryptoResult(res);
}
status_t WVDrmPlugin::mapOEMCryptoResult(OEMCryptoResult res) {
switch (res) {
case OEMCrypto_SUCCESS:
return android::OK;
@@ -819,11 +915,19 @@ status_t WVDrmPlugin::mapAndNotifyOfOEMCryptoResult(
case OEMCrypto_ERROR_SHORT_BUFFER:
return kErrorIncorrectBufferSize;
case OEMCrypto_ERROR_NO_DEVICE_KEY:
sendEvent(kDrmPluginEventProvisionRequired, 0, &sessionId, NULL);
return android::ERROR_DRM_NOT_PROVISIONED;
case OEMCrypto_ERROR_INVALID_SESSION:
return android::ERROR_DRM_SESSION_NOT_OPENED;
case OEMCrypto_ERROR_TOO_MANY_SESSIONS:
return kErrorTooManySessions;
case OEMCrypto_ERROR_INVALID_RSA_KEY:
return kErrorInvalidKey;
case OEMCrypto_ERROR_INSUFFICIENT_RESOURCES:
return android::ERROR_DRM_RESOURCE_BUSY;
case OEMCrypto_ERROR_NOT_IMPLEMENTED:
return android::ERROR_DRM_CANNOT_HANDLE;
case OEMCrypto_ERROR_UNKNOWN_FAILURE:
case OEMCrypto_ERROR_OPEN_SESSION_FAILED:
return android::ERROR_DRM_UNKNOWN;
default:
return android::UNKNOWN_ERROR;

View File

@@ -56,11 +56,13 @@ class MockCDM : public WvContentDecryptionModule {
MOCK_METHOD2(QueryKeyControlInfo, CdmResponseType(const CdmSessionId&,
CdmQueryMap*));
MOCK_METHOD2(GetProvisioningRequest, CdmResponseType(CdmProvisioningRequest*,
MOCK_METHOD4(GetProvisioningRequest, CdmResponseType(CdmCertificateType,
const std::string&,
CdmProvisioningRequest*,
std::string*));
MOCK_METHOD1(HandleProvisioningResponse,
CdmResponseType(CdmProvisioningResponse&));
MOCK_METHOD3(HandleProvisioningResponse,
CdmResponseType(CdmProvisioningResponse&, std::string*, std::string*));
MOCK_METHOD1(GetSecureStops, CdmResponseType(CdmSecureStops*));
@@ -93,6 +95,18 @@ class MockCrypto : public WVGenericCryptoInterface {
MOCK_METHOD6(verify, OEMCryptoResult(OEMCrypto_SESSION, const uint8_t*,
size_t, OEMCrypto_Algorithm,
const uint8_t*, size_t));
MOCK_METHOD1(openSession, OEMCryptoResult(OEMCrypto_SESSION*));
MOCK_METHOD1(closeSession, OEMCryptoResult(OEMCrypto_SESSION));
MOCK_METHOD3(loadDeviceRSAKey, OEMCryptoResult(OEMCrypto_SESSION,
const uint8_t*, size_t));
MOCK_METHOD6(generateRSASignature, OEMCryptoResult(OEMCrypto_SESSION,
const uint8_t*, size_t,
uint8_t*, size_t*,
RSA_Padding_Scheme));
};
class MockDrmPluginListener : public DrmPluginListener {
@@ -567,15 +581,17 @@ TEST_F(WVDrmPluginTest, GetsProvisioningRequests) {
static const char* kDefaultUrl = "http://google.com/";
EXPECT_CALL(cdm, GetProvisioningRequest(_, _))
.WillOnce(DoAll(SetArgPointee<0>(cdmRequest),
SetArgPointee<1>(kDefaultUrl),
EXPECT_CALL(cdm, GetProvisioningRequest(kCertificateWidevine, IsEmpty(),
_, _))
.WillOnce(DoAll(SetArgPointee<2>(cdmRequest),
SetArgPointee<3>(kDefaultUrl),
Return(wvcdm::NO_ERROR)));
Vector<uint8_t> request;
String8 defaultUrl;
status_t res = plugin.getProvisionRequest(request, defaultUrl);
status_t res = plugin.getProvisionRequest(String8(""), String8(""), request,
defaultUrl);
ASSERT_EQ(OK, res);
EXPECT_THAT(request, ElementsAreArray(requestRaw, kRequestSize));
@@ -597,10 +613,14 @@ TEST_F(WVDrmPluginTest, HandlesProvisioningResponses) {
response.appendArray(responseRaw, kResponseSize);
EXPECT_CALL(cdm, HandleProvisioningResponse(ElementsAreArray(responseRaw,
kResponseSize)))
kResponseSize),
_, _))
.Times(1);
status_t res = plugin.provideProvisionResponse(response);
Vector<uint8_t> cert;
Vector<uint8_t> key;
status_t res = plugin.provideProvisionResponse(response, cert, key);
ASSERT_EQ(OK, res);
}