diff options
Diffstat (limited to 'drm')
-rw-r--r-- | drm/common/IDrmManagerService.cpp | 56 | ||||
-rw-r--r-- | drm/libdrmframework/plugins/forward-lock/internal-format/converter/FwdLockConv.c | 1 | ||||
-rw-r--r-- | drm/mediadrm/plugins/clearkey/CryptoFactory.cpp | 16 | ||||
-rw-r--r-- | drm/mediadrm/plugins/clearkey/CryptoPlugin.cpp | 16 | ||||
-rw-r--r-- | drm/mediadrm/plugins/clearkey/CryptoPlugin.h | 11 | ||||
-rw-r--r-- | drm/mediadrm/plugins/clearkey/DrmPlugin.cpp | 17 | ||||
-rw-r--r-- | drm/mediadrm/plugins/clearkey/DrmPlugin.h | 3 | ||||
-rw-r--r-- | drm/mediadrm/plugins/clearkey/SessionLibrary.cpp | 7 | ||||
-rw-r--r-- | drm/mediadrm/plugins/clearkey/SessionLibrary.h | 4 | ||||
-rw-r--r-- | drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.cpp | 93 | ||||
-rw-r--r-- | drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.h | 3 |
11 files changed, 184 insertions, 43 deletions
diff --git a/drm/common/IDrmManagerService.cpp b/drm/common/IDrmManagerService.cpp index 57e5fc5..f2e14b6 100644 --- a/drm/common/IDrmManagerService.cpp +++ b/drm/common/IDrmManagerService.cpp @@ -34,6 +34,7 @@ #include "IDrmManagerService.h" #define INVALID_BUFFER_LENGTH -1 +#define MAX_BINDER_TRANSACTION_SIZE ((1*1024*1024)-(4096*2)) using namespace android; @@ -935,7 +936,12 @@ status_t BnDrmManagerService::onTransact( //Filling DRM info const int infoType = data.readInt32(); - const int bufferSize = data.readInt32(); + const uint32_t bufferSize = data.readInt32(); + + if (bufferSize > data.dataAvail()) { + return BAD_VALUE; + } + char* buffer = NULL; if (0 < bufferSize) { buffer = (char *)data.readInplace(bufferSize); @@ -988,6 +994,9 @@ status_t BnDrmManagerService::onTransact( const int size = data.readInt32(); for (int index = 0; index < size; ++index) { + if (!data.dataAvail()) { + break; + } const String8 key(data.readString8()); if (key == String8("FileDescriptorKey")) { char buffer[16]; @@ -1037,7 +1046,12 @@ status_t BnDrmManagerService::onTransact( const int uniqueId = data.readInt32(); //Filling DRM Rights - const int bufferSize = data.readInt32(); + const uint32_t bufferSize = data.readInt32(); + if (bufferSize > data.dataAvail()) { + reply->writeInt32(BAD_VALUE); + return DRM_NO_ERROR; + } + const DrmBuffer drmBuffer((char *)data.readInplace(bufferSize), bufferSize); const String8 mimeType(data.readString8()); @@ -1208,10 +1222,13 @@ status_t BnDrmManagerService::onTransact( const int convertId = data.readInt32(); //Filling input data - const int bufferSize = data.readInt32(); + const uint32_t bufferSize = data.readInt32(); + if (bufferSize > data.dataAvail()) { + return BAD_VALUE; + } DrmBuffer* inputData = new DrmBuffer((char *)data.readInplace(bufferSize), bufferSize); - DrmConvertedStatus* drmConvertedStatus = convertData(uniqueId, convertId, inputData); + DrmConvertedStatus* drmConvertedStatus = convertData(uniqueId, convertId, inputData); if (NULL != drmConvertedStatus) { //Filling Drm Converted Ststus @@ -1395,7 +1412,12 @@ status_t BnDrmManagerService::onTransact( const int decryptUnitId = data.readInt32(); //Filling Header info - const int bufferSize = data.readInt32(); + const uint32_t bufferSize = data.readInt32(); + if (bufferSize > data.dataAvail()) { + reply->writeInt32(BAD_VALUE); + clearDecryptHandle(&handle); + return DRM_NO_ERROR; + } DrmBuffer* headerInfo = NULL; headerInfo = new DrmBuffer((char *)data.readInplace(bufferSize), bufferSize); @@ -1419,9 +1441,17 @@ status_t BnDrmManagerService::onTransact( readDecryptHandleFromParcelData(&handle, data); const int decryptUnitId = data.readInt32(); - const int decBufferSize = data.readInt32(); + const uint32_t decBufferSize = data.readInt32(); + const uint32_t encBufferSize = data.readInt32(); + + if (encBufferSize > data.dataAvail() || + decBufferSize > MAX_BINDER_TRANSACTION_SIZE) { + reply->writeInt32(BAD_VALUE); + reply->writeInt32(0); + clearDecryptHandle(&handle); + return DRM_NO_ERROR; + } - const int encBufferSize = data.readInt32(); DrmBuffer* encBuffer = new DrmBuffer((char *)data.readInplace(encBufferSize), encBufferSize); @@ -1431,8 +1461,10 @@ status_t BnDrmManagerService::onTransact( DrmBuffer* IV = NULL; if (0 != data.dataAvail()) { - const int ivBufferlength = data.readInt32(); - IV = new DrmBuffer((char *)data.readInplace(ivBufferlength), ivBufferlength); + const uint32_t ivBufferlength = data.readInt32(); + if (ivBufferlength <= data.dataAvail()) { + IV = new DrmBuffer((char *)data.readInplace(ivBufferlength), ivBufferlength); + } } const status_t status @@ -1481,7 +1513,11 @@ status_t BnDrmManagerService::onTransact( DecryptHandle handle; readDecryptHandleFromParcelData(&handle, data); - const int numBytes = data.readInt32(); + const uint32_t numBytes = data.readInt32(); + if (numBytes > MAX_BINDER_TRANSACTION_SIZE) { + reply->writeInt32(BAD_VALUE); + return DRM_NO_ERROR; + } char* buffer = new char[numBytes]; const off64_t offset = data.readInt64(); diff --git a/drm/libdrmframework/plugins/forward-lock/internal-format/converter/FwdLockConv.c b/drm/libdrmframework/plugins/forward-lock/internal-format/converter/FwdLockConv.c index 9d15835..6a0b3c0 100644 --- a/drm/libdrmframework/plugins/forward-lock/internal-format/converter/FwdLockConv.c +++ b/drm/libdrmframework/plugins/forward-lock/internal-format/converter/FwdLockConv.c @@ -19,6 +19,7 @@ #include <fcntl.h> #include <limits.h> #include <pthread.h> +#include <stdlib.h> #include <string.h> #include <sys/stat.h> #include <unistd.h> diff --git a/drm/mediadrm/plugins/clearkey/CryptoFactory.cpp b/drm/mediadrm/plugins/clearkey/CryptoFactory.cpp index ee3189b..eeb64c3 100644 --- a/drm/mediadrm/plugins/clearkey/CryptoFactory.cpp +++ b/drm/mediadrm/plugins/clearkey/CryptoFactory.cpp @@ -43,10 +43,18 @@ android::status_t CryptoFactory::createPlugin( return android::BAD_VALUE; } - android::sp<Session> session = SessionLibrary::get()->findSession( - data, size); - *plugin = new CryptoPlugin(session); - return android::OK; + android::Vector<uint8_t> sessionId; + sessionId.appendArray(reinterpret_cast<const uint8_t*>(data), size); + + CryptoPlugin *clearKeyPlugin = new CryptoPlugin(sessionId); + android::status_t result = clearKeyPlugin->getInitStatus(); + if (result == android::OK) { + *plugin = clearKeyPlugin; + } else { + delete clearKeyPlugin; + *plugin = NULL; + } + return result; } } // namespace clearkeydrm diff --git a/drm/mediadrm/plugins/clearkey/CryptoPlugin.cpp b/drm/mediadrm/plugins/clearkey/CryptoPlugin.cpp index adad136..53cbf80 100644 --- a/drm/mediadrm/plugins/clearkey/CryptoPlugin.cpp +++ b/drm/mediadrm/plugins/clearkey/CryptoPlugin.cpp @@ -19,9 +19,9 @@ #include <utils/Log.h> #include <media/stagefright/MediaErrors.h> -#include <utils/Errors.h> #include "CryptoPlugin.h" +#include "SessionLibrary.h" namespace clearkeydrm { @@ -80,4 +80,18 @@ ssize_t CryptoPlugin::decrypt(bool secure, const KeyId keyId, const Iv iv, } } +android::status_t CryptoPlugin::setMediaDrmSession( + const android::Vector<uint8_t>& sessionId) { + if (!sessionId.size()) { + mSession.clear(); + } else { + mSession = SessionLibrary::get()->findSession(sessionId); + if (!mSession.get()) { + return android::ERROR_DRM_SESSION_NOT_OPENED; + } + } + return android::OK; +} + + } // namespace clearkeydrm diff --git a/drm/mediadrm/plugins/clearkey/CryptoPlugin.h b/drm/mediadrm/plugins/clearkey/CryptoPlugin.h index 002d9e0..fd38f28 100644 --- a/drm/mediadrm/plugins/clearkey/CryptoPlugin.h +++ b/drm/mediadrm/plugins/clearkey/CryptoPlugin.h @@ -31,7 +31,10 @@ namespace clearkeydrm { class CryptoPlugin : public android::CryptoPlugin { public: - CryptoPlugin(const android::sp<Session>& session) : mSession(session) {} + CryptoPlugin(const android::Vector<uint8_t>& sessionId) { + mInitStatus = setMediaDrmSession(sessionId); + } + virtual ~CryptoPlugin() {} virtual bool requiresSecureDecoderComponent(const char* mime) const { @@ -45,10 +48,16 @@ public: const SubSample* subSamples, size_t numSubSamples, void* dstPtr, android::AString* errorDetailMsg); + virtual android::status_t setMediaDrmSession( + const android::Vector<uint8_t>& sessionId); + + android::status_t getInitStatus() const {return mInitStatus;} + private: DISALLOW_EVIL_CONSTRUCTORS(CryptoPlugin); android::sp<Session> mSession; + android::status_t mInitStatus; }; } // namespace clearkeydrm diff --git a/drm/mediadrm/plugins/clearkey/DrmPlugin.cpp b/drm/mediadrm/plugins/clearkey/DrmPlugin.cpp index 96fca94..e5ee403 100644 --- a/drm/mediadrm/plugins/clearkey/DrmPlugin.cpp +++ b/drm/mediadrm/plugins/clearkey/DrmPlugin.cpp @@ -37,7 +37,9 @@ status_t DrmPlugin::openSession(Vector<uint8_t>& sessionId) { status_t DrmPlugin::closeSession(const Vector<uint8_t>& sessionId) { sp<Session> session = mSessionLibrary->findSession(sessionId); - mSessionLibrary->destroySession(session); + if (session.get()) { + mSessionLibrary->destroySession(session); + } return android::OK; } @@ -48,14 +50,18 @@ status_t DrmPlugin::getKeyRequest( KeyType keyType, const KeyedVector<String8, String8>& optionalParameters, Vector<uint8_t>& request, - String8& defaultUrl) { + String8& defaultUrl, + DrmPlugin::KeyRequestType *keyRequestType) { UNUSED(optionalParameters); if (keyType != kKeyType_Streaming) { return android::ERROR_DRM_CANNOT_HANDLE; } - - sp<Session> session = mSessionLibrary->findSession(scope); + *keyRequestType = DrmPlugin::kKeyRequestType_Initial; defaultUrl.clear(); + sp<Session> session = mSessionLibrary->findSession(scope); + if (!session.get()) { + return android::ERROR_DRM_SESSION_NOT_OPENED; + } return session->getKeyRequest(initData, initDataType, &request); } @@ -64,6 +70,9 @@ status_t DrmPlugin::provideKeyResponse( const Vector<uint8_t>& response, Vector<uint8_t>& keySetId) { sp<Session> session = mSessionLibrary->findSession(scope); + if (!session.get()) { + return android::ERROR_DRM_SESSION_NOT_OPENED; + } status_t res = session->provideKeyResponse(response); if (res == android::OK) { keySetId.clear(); diff --git a/drm/mediadrm/plugins/clearkey/DrmPlugin.h b/drm/mediadrm/plugins/clearkey/DrmPlugin.h index 6139f1f..ba4aefe 100644 --- a/drm/mediadrm/plugins/clearkey/DrmPlugin.h +++ b/drm/mediadrm/plugins/clearkey/DrmPlugin.h @@ -54,7 +54,8 @@ public: KeyType keyType, const KeyedVector<String8, String8>& optionalParameters, Vector<uint8_t>& request, - String8& defaultUrl); + String8& defaultUrl, + DrmPlugin::KeyRequestType *keyRequestType); virtual status_t provideKeyResponse( const Vector<uint8_t>& scope, diff --git a/drm/mediadrm/plugins/clearkey/SessionLibrary.cpp b/drm/mediadrm/plugins/clearkey/SessionLibrary.cpp index d047c53..46d7f77 100644 --- a/drm/mediadrm/plugins/clearkey/SessionLibrary.cpp +++ b/drm/mediadrm/plugins/clearkey/SessionLibrary.cpp @@ -63,13 +63,6 @@ const sp<Session>& SessionLibrary::findSession( return mSessions.valueFor(sessionId); } -const sp<Session>& SessionLibrary::findSession( - const void* data, size_t size) { - Vector<uint8_t> sessionId; - sessionId.appendArray(reinterpret_cast<const uint8_t*>(data), size); - return findSession(sessionId); -} - void SessionLibrary::destroySession(const sp<Session>& session) { Mutex::Autolock lock(mSessionsLock);\ mSessions.removeItem(session->sessionId()); diff --git a/drm/mediadrm/plugins/clearkey/SessionLibrary.h b/drm/mediadrm/plugins/clearkey/SessionLibrary.h index 56c8828..199ad64 100644 --- a/drm/mediadrm/plugins/clearkey/SessionLibrary.h +++ b/drm/mediadrm/plugins/clearkey/SessionLibrary.h @@ -36,8 +36,6 @@ public: const android::sp<Session>& findSession( const android::Vector<uint8_t>& sessionId); - const android::sp<Session>& findSession(const void* data, size_t size); - void destroySession(const android::sp<Session>& session); private: @@ -50,7 +48,7 @@ private: android::Mutex mSessionsLock; uint32_t mNextSessionId; - android::KeyedVector<android::Vector<uint8_t>, android::sp<Session> > + android::DefaultKeyedVector<android::Vector<uint8_t>, android::sp<Session> > mSessions; }; diff --git a/drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.cpp b/drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.cpp index 7eac0a1..851ad2c 100644 --- a/drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.cpp +++ b/drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.cpp @@ -56,7 +56,7 @@ namespace android { return true; } - status_t MockDrmFactory::createDrmPlugin(const uint8_t uuid[16], DrmPlugin **plugin) + status_t MockDrmFactory::createDrmPlugin(const uint8_t /* uuid */[16], DrmPlugin **plugin) { *plugin = new MockDrmPlugin(); return OK; @@ -68,8 +68,9 @@ namespace android { return (!memcmp(uuid, mock_uuid, sizeof(mock_uuid))); } - status_t MockCryptoFactory::createPlugin(const uint8_t uuid[16], const void *data, - size_t size, CryptoPlugin **plugin) + status_t MockCryptoFactory::createPlugin(const uint8_t /* uuid */[16], + const void * /* data */, + size_t /* size */, CryptoPlugin **plugin) { *plugin = new MockCryptoPlugin(); return OK; @@ -111,7 +112,8 @@ namespace android { Vector<uint8_t> const &initData, String8 const &mimeType, KeyType keyType, KeyedVector<String8, String8> const &optionalParameters, - Vector<uint8_t> &request, String8 &defaultUrl) + Vector<uint8_t> &request, String8 &defaultUrl, + KeyRequestType *keyRequestType) { Mutex::Autolock lock(mLock); ALOGD("MockDrmPlugin::getKeyRequest(sessionId=%s, initData=%s, mimeType=%s" @@ -149,6 +151,7 @@ namespace android { // Properties used in mock test, set by cts test app returned from mock plugin // byte[] mock-request -> request // string mock-default-url -> defaultUrl + // string mock-keyRequestType -> keyRequestType index = mByteArrayProperties.indexOfKey(String8("mock-request")); if (index < 0) { @@ -165,6 +168,16 @@ namespace android { } else { defaultUrl = mStringProperties.valueAt(index); } + + index = mStringProperties.indexOfKey(String8("mock-keyRequestType")); + if (index < 0) { + ALOGD("Missing 'mock-keyRequestType' parameter for mock"); + return BAD_VALUE; + } else { + *keyRequestType = static_cast<KeyRequestType>( + atoi(mStringProperties.valueAt(index).string())); + } + return OK; } @@ -254,8 +267,8 @@ namespace android { return OK; } - status_t MockDrmPlugin::getProvisionRequest(String8 const &certType, - String8 const &certAuthority, + status_t MockDrmPlugin::getProvisionRequest(String8 const & /* certType */, + String8 const & /* certAuthority */, Vector<uint8_t> &request, String8 &defaultUrl) { @@ -285,8 +298,8 @@ namespace android { } status_t MockDrmPlugin::provideProvisionResponse(Vector<uint8_t> const &response, - Vector<uint8_t> &certificate, - Vector<uint8_t> &wrappedKey) + Vector<uint8_t> & /* certificate */, + Vector<uint8_t> & /* wrappedKey */) { Mutex::Autolock lock(mLock); ALOGD("MockDrmPlugin::provideProvisionResponse(%s)", @@ -305,7 +318,8 @@ namespace android { return OK; } - status_t MockDrmPlugin::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) + status_t MockDrmPlugin::getSecureStop(Vector<uint8_t> const & /* ssid */, + Vector<uint8_t> & secureStop) { Mutex::Autolock lock(mLock); ALOGD("MockDrmPlugin::getSecureStop()"); @@ -427,6 +441,63 @@ namespace android { pData ? vectorToString(*pData) : "{}"); sendEvent(eventType, extra, pSessionId, pData); + } else if (name == "mock-send-expiration-update") { + int64_t expiryTimeMS; + sscanf(value.string(), "%jd", &expiryTimeMS); + + Vector<uint8_t> const *pSessionId = NULL; + ssize_t index = mByteArrayProperties.indexOfKey(String8("mock-event-session-id")); + if (index >= 0) { + pSessionId = &mByteArrayProperties[index]; + } + + ALOGD("sending expiration-update from mock drm plugin: %jd %s", + expiryTimeMS, pSessionId ? vectorToString(*pSessionId) : "{}"); + + sendExpirationUpdate(pSessionId, expiryTimeMS); + } else if (name == "mock-send-keys-change") { + Vector<uint8_t> const *pSessionId = NULL; + ssize_t index = mByteArrayProperties.indexOfKey(String8("mock-event-session-id")); + if (index >= 0) { + pSessionId = &mByteArrayProperties[index]; + } + + ALOGD("sending keys-change from mock drm plugin: %s", + pSessionId ? vectorToString(*pSessionId) : "{}"); + + Vector<DrmPlugin::KeyStatus> keyStatusList; + DrmPlugin::KeyStatus keyStatus; + uint8_t keyId1[] = {'k', 'e', 'y', '1'}; + keyStatus.mKeyId.clear(); + keyStatus.mKeyId.appendArray(keyId1, sizeof(keyId1)); + keyStatus.mType = DrmPlugin::kKeyStatusType_Usable; + keyStatusList.add(keyStatus); + + uint8_t keyId2[] = {'k', 'e', 'y', '2'}; + keyStatus.mKeyId.clear(); + keyStatus.mKeyId.appendArray(keyId2, sizeof(keyId2)); + keyStatus.mType = DrmPlugin::kKeyStatusType_Expired; + keyStatusList.add(keyStatus); + + uint8_t keyId3[] = {'k', 'e', 'y', '3'}; + keyStatus.mKeyId.clear(); + keyStatus.mKeyId.appendArray(keyId3, sizeof(keyId3)); + keyStatus.mType = DrmPlugin::kKeyStatusType_OutputNotAllowed; + keyStatusList.add(keyStatus); + + uint8_t keyId4[] = {'k', 'e', 'y', '4'}; + keyStatus.mKeyId.clear(); + keyStatus.mKeyId.appendArray(keyId4, sizeof(keyId4)); + keyStatus.mType = DrmPlugin::kKeyStatusType_StatusPending; + keyStatusList.add(keyStatus); + + uint8_t keyId5[] = {'k', 'e', 'y', '5'}; + keyStatus.mKeyId.clear(); + keyStatus.mKeyId.appendArray(keyId5, sizeof(keyId5)); + keyStatus.mType = DrmPlugin::kKeyStatusType_InternalError; + keyStatusList.add(keyStatus); + + sendKeysChange(pSessionId, &keyStatusList, true); } else { mStringProperties.add(name, value); } @@ -728,7 +799,7 @@ namespace android { ssize_t MockCryptoPlugin::decrypt(bool secure, const uint8_t key[16], const uint8_t iv[16], Mode mode, const void *srcPtr, const SubSample *subSamples, - size_t numSubSamples, void *dstPtr, AString *errorDetailMsg) + size_t numSubSamples, void *dstPtr, AString * /* errorDetailMsg */) { ALOGD("MockCryptoPlugin::decrypt(secure=%d, key=%s, iv=%s, mode=%d, src=%p, " "subSamples=%s, dst=%p)", @@ -757,7 +828,7 @@ namespace android { { String8 result; for (size_t i = 0; i < numSubSamples; i++) { - result.appendFormat("[%zu] {clear:%zu, encrypted:%zu} ", i, + result.appendFormat("[%zu] {clear:%u, encrypted:%u} ", i, subSamples[i].mNumBytesOfClearData, subSamples[i].mNumBytesOfEncryptedData); } diff --git a/drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.h b/drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.h index d1d8058..d0f2ddb 100644 --- a/drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.h +++ b/drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.h @@ -62,7 +62,8 @@ namespace android { Vector<uint8_t> const &initData, String8 const &mimeType, KeyType keyType, KeyedVector<String8, String8> const &optionalParameters, - Vector<uint8_t> &request, String8 &defaultUrl); + Vector<uint8_t> &request, String8 &defaultUrl, + KeyRequestType *keyRequestType); status_t provideKeyResponse(Vector<uint8_t> const &sessionId, Vector<uint8_t> const &response, |