am e15a73ee: Merge "Bug fixes in OMA DRM v1 Forward Lock Agent"

* commit 'e15a73ee4c9a28d89888095c7649a70c116ee160':
  Bug fixes in OMA DRM v1 Forward Lock Agent
This commit is contained in:
Gloria Wang
2011-08-04 14:33:06 -07:00
committed by Android Git Automerger
6 changed files with 263 additions and 189 deletions

View File

@@ -13,26 +13,28 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
#ifndef __SESSIONMAP_H__ #ifndef __SESSIONMAP_H__
#define __SESSIONMAP_H__ #define __SESSIONMAP_H__
#include <utils/KeyedVector.h> #include <utils/KeyedVector.h>
#include <utils/threads.h>
namespace android { namespace android {
/** /**
* A wrapper template class for handling DRM Engine sessions. * A thread safe wrapper template class for session handlings for Drm Engines. It wraps a
* pointer type over KeyedVector. It keeps pointer as data in the vector and free up memory
* allocated pointer can be of any type of structure/class meant for keeping session data.
* so session object here means pointer to the session data.
*/ */
template <typename NODE> template <typename TValue>
class SessionMap { class SessionMap {
public: public:
KeyedVector<int, NODE> map;
SessionMap() {} SessionMap() {}
virtual ~SessionMap() { virtual ~SessionMap() {
Mutex::Autolock lock(mLock);
destroyMap(); destroyMap();
} }
@@ -45,18 +47,15 @@ public:
* *
* @return boolean result of adding value. returns false if key is already exist. * @return boolean result of adding value. returns false if key is already exist.
*/ */
bool addValue(int key, NODE value) { bool addValue(int key, TValue value) {
bool result = false; Mutex::Autolock lock(mLock);
if (!isCreatedInternal(key)) {
if (!isCreated(key)) {
map.add(key, value); map.add(key, value);
result = true; return true;
} }
return false;
return result;
} }
/** /**
* returns the session object by the key * returns the session object by the key
* *
@@ -64,14 +63,9 @@ bool addValue(int key, NODE value) {
* *
* @return session object as per the key * @return session object as per the key
*/ */
NODE getValue(int key) { TValue getValue(int key) {
NODE value = NULL; Mutex::Autolock lock(mLock);
return getValueInternal(key);
if (isCreated(key)) {
value = (NODE) map.valueFor(key);
}
return value;
} }
/** /**
@@ -80,6 +74,7 @@ NODE getValue(int key) {
* @return count of number of session objects. * @return count of number of session objects.
*/ */
int getSize() { int getSize() {
Mutex::Autolock lock(mLock);
return map.size(); return map.size();
} }
@@ -90,13 +85,13 @@ int getSize() {
* *
* @return session object as per the index * @return session object as per the index
*/ */
NODE getValueAt(unsigned int index) { TValue getValueAt(unsigned int index) {
NODE value = NULL; TValue value = NULL;
Mutex::Autolock lock(mLock);
if (map.size() > index) { if (map.size() > index) {
value = map.valueAt(index); value = map.valueAt(index);
} }
return value; return value;
} }
@@ -107,7 +102,8 @@ NODE getValueAt(unsigned int index) {
* *
*/ */
void removeValue(int key) { void removeValue(int key) {
deleteValue(getValue(key)); Mutex::Autolock lock(mLock);
deleteValue(getValueInternal(key));
map.removeItem(key); map.removeItem(key);
} }
@@ -119,22 +115,21 @@ void removeValue(int key) {
* @return boolean result of whether session is created * @return boolean result of whether session is created
*/ */
bool isCreated(int key) { bool isCreated(int key) {
return (0 <= map.indexOfKey(key)); Mutex::Autolock lock(mLock);
return isCreatedInternal(key);
} }
/** SessionMap<TValue> & operator=(const SessionMap<TValue> & objectCopy) {
* empty the entire session table. It releases all the memory for session objects. Mutex::Autolock lock(mLock);
*/
void destroyMap() {
int size = map.size();
int i = 0;
for (i = 0; i < size; i++) { destroyMap();
deleteValue(map.valueAt(i)); map = objectCopy.map;
return *this;
} }
map.clear(); private:
} KeyedVector<int, TValue> map;
Mutex mLock;
/** /**
* free up the memory for the session object. * free up the memory for the session object.
@@ -144,10 +139,49 @@ void destroyMap() {
* @param value - session object to free * @param value - session object to free
* *
*/ */
void deleteValue(NODE value) { void deleteValue(TValue value) {
delete value; delete value;
} }
/**
* free up the memory for the entire map.
* free up any resources in the sessions before calling this funtion.
*
*/
void destroyMap() {
int size = map.size();
for (int i = 0; i < size; i++) {
deleteValue(map.valueAt(i));
}
map.clear();
}
/**
* decides if session is already created.
*
* @param key - key of the value for the session
*
* @return boolean result of whether session is created
*/
bool isCreatedInternal(int key) {
return(0 <= map.indexOfKey(key));
}
/**
* returns the session object by the key
*
* @param key - key or Session ID
*
* @return session object as per the key
*/
TValue getValueInternal(int key) {
TValue value = NULL;
if (isCreatedInternal(key)) {
value = (TValue) map.valueFor(key);
}
return value;
}
}; };
}; };

View File

@@ -22,6 +22,13 @@ namespace android {
#undef LOG_TAG #undef LOG_TAG
#define LOG_TAG "MimeTypeUtil" #define LOG_TAG "MimeTypeUtil"
#ifdef DRM_OMA_FL_ENGINE_DEBUG
#define LOG_NDEBUG 0
#define LOG_DEBUG(...) LOGD(__VA_ARGS__)
#else
#define LOG_DEBUG(...)
#endif
enum { enum {
MIMETYPE_AUDIO = 0, MIMETYPE_AUDIO = 0,
MIMETYPE_APPLICATION = 1, MIMETYPE_APPLICATION = 1,
@@ -59,6 +66,7 @@ static const char mime_group_audio[] = "audio/";
static const char mime_group_application[] = "application/"; static const char mime_group_application[] = "application/";
static const char mime_group_image[] = "image/"; static const char mime_group_image[] = "image/";
static const char mime_group_video[] = "video/"; static const char mime_group_video[] = "video/";
static const char mime_type_unsupported[] = "unsupported/drm.mimetype";
static struct MimeGroup mimeGroup[] = { static struct MimeGroup mimeGroup[] = {
{MIMETYPE_AUDIO, mime_group_audio, sizeof(mime_group_audio)-1}, {MIMETYPE_AUDIO, mime_group_audio, sizeof(mime_group_audio)-1},
@@ -107,23 +115,25 @@ static struct MimeTypeList mimeTypeList[] = {
* replacement mimetype otherwise the original mimetype * replacement mimetype otherwise the original mimetype
* is returned. * is returned.
* *
* If the mimetype is of unsupported group i.e. application/*
* then "unsupported/drm.mimetype" will be returned.
*
* @param mimeType - mimetype in lower case to convert. * @param mimeType - mimetype in lower case to convert.
* *
* @return mimetype or null. * @return mimetype or "unsupported/drm.mimetype".
*/ */
String8 MimeTypeUtil::convertMimeType(String8& mimeType) { String8 MimeTypeUtil::convertMimeType(String8& mimeType) {
String8 result = mimeType; String8 result = mimeType;
const char* pTmp;
const char* pMimeType; const char* pMimeType;
struct MimeGroup* pGroup; struct MimeGroup* pGroup;
struct MimeTypeList* pMimeItem; struct MimeTypeList* pMimeItem;
int len; int len;
pMimeType = mimeType.string(); pMimeType = mimeType.string();
if (NULL != pMimeType) { if (NULL != pMimeType) {
if ((0 == strncmp(pMimeType, mime_group_audio, (sizeof mime_group_audio) - 1)) ||
(0 == strncmp(pMimeType, mime_group_video, (sizeof mime_group_video) - 1))) {
/* Check which group the mimetype is */ /* Check which group the mimetype is */
pGroup = mimeGroup; pGroup = mimeGroup;
while (MIMETYPE_LAST != pGroup->type) { while (MIMETYPE_LAST != pGroup->type) {
if (0 == strncmp(pMimeType, pGroup->pGroup, pGroup->size)) { if (0 == strncmp(pMimeType, pGroup->pGroup, pGroup->size)) {
break; break;
@@ -135,9 +145,9 @@ String8 MimeTypeUtil::convertMimeType(String8& mimeType) {
if (MIMETYPE_LAST != pGroup->type) { if (MIMETYPE_LAST != pGroup->type) {
pMimeItem = mimeTypeList; pMimeItem = mimeTypeList;
len = strlen (pMimeType+pGroup->size); len = strlen (pMimeType+pGroup->size);
while (MIMETYPE_LAST != pMimeItem->type) { while (MIMETYPE_LAST != pMimeItem->type) {
if ((len == pMimeItem->size) && if ((pGroup->type == pMimeItem->type) &&
(len == pMimeItem->size) &&
(0 == strcmp(pMimeType+pGroup->size, pMimeItem->pMimeExt))) { (0 == strcmp(pMimeType+pGroup->size, pMimeItem->pMimeExt))) {
result = String8(pMimeItem->pMimeType); result = String8(pMimeItem->pMimeType);
break; break;
@@ -145,10 +155,12 @@ String8 MimeTypeUtil::convertMimeType(String8& mimeType) {
pMimeItem++; pMimeItem++;
} }
} }
LOGI("convertMimeType got mimetype %s, converted into mimetype %s", } else {
result = String8(mime_type_unsupported);
}
LOG_DEBUG("convertMimeType got mimetype %s, converted into mimetype %s",
pMimeType, result.string()); pMimeType, result.string());
} }
return result; return result;
} }
}; };

View File

@@ -17,6 +17,9 @@ LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS) include $(CLEAR_VARS)
# The flag below turns on local debug printouts
#LOCAL_CFLAGS += -DDRM_OMA_FL_ENGINE_DEBUG
base := frameworks/base base := frameworks/base
# Determine whether the DRM framework uses 64-bit data types for file offsets and do the same. # Determine whether the DRM framework uses 64-bit data types for file offsets and do the same.

View File

@@ -41,6 +41,13 @@
#undef LOG_TAG #undef LOG_TAG
#define LOG_TAG "FwdLockEngine" #define LOG_TAG "FwdLockEngine"
#ifdef DRM_OMA_FL_ENGINE_DEBUG
#define LOG_NDEBUG 0
#define LOG_VERBOSE(...) LOGV(__VA_ARGS__)
#else
#define LOG_VERBOSE(...)
#endif
using namespace android; using namespace android;
// This extern "C" is mandatory to be managed by TPlugInManager // This extern "C" is mandatory to be managed by TPlugInManager
extern "C" IDrmEngine* create() { extern "C" IDrmEngine* create() {
@@ -53,14 +60,25 @@ extern "C" void destroy(IDrmEngine* plugIn) {
} }
FwdLockEngine::FwdLockEngine() { FwdLockEngine::FwdLockEngine() {
LOGD("FwdLockEngine Construction"); LOG_VERBOSE("FwdLockEngine Construction");
} }
FwdLockEngine::~FwdLockEngine() { FwdLockEngine::~FwdLockEngine() {
LOGD("FwdLockEngine Destruction"); LOG_VERBOSE("FwdLockEngine Destruction");
convertSessionMap.destroyMap(); int size = decodeSessionMap.getSize();
decodeSessionMap.destroyMap();
for (int i = 0; i < size; i++) {
DecodeSession *session = (DecodeSession*) decodeSessionMap.getValueAt(i);
FwdLockFile_detach(session->fileDesc);
::close(session->fileDesc);
}
size = convertSessionMap.getSize();
for (int i = 0; i < size; i++) {
ConvertSession *convSession = (ConvertSession*) convertSessionMap.getValueAt(i);
FwdLockConv_CloseSession(convSession->uniqueId, &(convSession->output));
}
} }
int FwdLockEngine::getConvertedStatus(FwdLockConv_Status_t status) { int FwdLockEngine::getConvertedStatus(FwdLockConv_Status_t status) {
@@ -74,12 +92,12 @@ int FwdLockEngine::getConvertedStatus(FwdLockConv_Status_t status) {
case FwdLockConv_Status_InvalidArgument: case FwdLockConv_Status_InvalidArgument:
case FwdLockConv_Status_UnsupportedFileFormat: case FwdLockConv_Status_UnsupportedFileFormat:
case FwdLockConv_Status_UnsupportedContentTransferEncoding: case FwdLockConv_Status_UnsupportedContentTransferEncoding:
LOGD("FwdLockEngine getConvertedStatus: file conversion Error %d. " \ LOGE("FwdLockEngine getConvertedStatus: file conversion Error %d. "
"Returning STATUS_INPUTDATA_ERROR", status); "Returning STATUS_INPUTDATA_ERROR", status);
retStatus = DrmConvertedStatus::STATUS_INPUTDATA_ERROR; retStatus = DrmConvertedStatus::STATUS_INPUTDATA_ERROR;
break; break;
default: default:
LOGD("FwdLockEngine getConvertedStatus: file conversion Error %d. " \ LOGE("FwdLockEngine getConvertedStatus: file conversion Error %d. "
"Returning STATUS_ERROR", status); "Returning STATUS_ERROR", status);
retStatus = DrmConvertedStatus::STATUS_ERROR; retStatus = DrmConvertedStatus::STATUS_ERROR;
break; break;
@@ -91,7 +109,7 @@ int FwdLockEngine::getConvertedStatus(FwdLockConv_Status_t status) {
DrmConstraints* FwdLockEngine::onGetConstraints(int uniqueId, const String8* path, int action) { DrmConstraints* FwdLockEngine::onGetConstraints(int uniqueId, const String8* path, int action) {
DrmConstraints* drmConstraints = NULL; DrmConstraints* drmConstraints = NULL;
LOGD("FwdLockEngine::onGetConstraints"); LOG_VERBOSE("FwdLockEngine::onGetConstraints");
if (NULL != path && if (NULL != path &&
(RightsStatus::RIGHTS_VALID == onCheckRightsStatus(uniqueId, *path, action))) { (RightsStatus::RIGHTS_VALID == onCheckRightsStatus(uniqueId, *path, action))) {
@@ -105,7 +123,7 @@ DrmConstraints* FwdLockEngine::onGetConstraints(int uniqueId, const String8* pat
DrmMetadata* FwdLockEngine::onGetMetadata(int uniqueId, const String8* path) { DrmMetadata* FwdLockEngine::onGetMetadata(int uniqueId, const String8* path) {
DrmMetadata* drmMetadata = NULL; DrmMetadata* drmMetadata = NULL;
LOGD("FwdLockEngine::onGetMetadata"); LOG_VERBOSE("FwdLockEngine::onGetMetadata");
if (NULL != path) { if (NULL != path) {
// Returns empty metadata to show no error condition. // Returns empty metadata to show no error condition.
@@ -116,13 +134,12 @@ DrmMetadata* FwdLockEngine::onGetMetadata(int uniqueId, const String8* path) {
} }
android::status_t FwdLockEngine::onInitialize(int uniqueId) { android::status_t FwdLockEngine::onInitialize(int uniqueId) {
LOGD("FwdLockEngine::onInitialize"); LOG_VERBOSE("FwdLockEngine::onInitialize");
if (FwdLockGlue_InitializeKeyEncryption()) { if (FwdLockGlue_InitializeKeyEncryption()) {
LOGD("FwdLockEngine::onInitialize -- FwdLockGlue_InitializeKeyEncryption succeeded"); LOG_VERBOSE("FwdLockEngine::onInitialize -- FwdLockGlue_InitializeKeyEncryption succeeded");
} else { } else {
LOGD("FwdLockEngine::onInitialize -- FwdLockGlue_InitializeKeyEncryption failed:" LOGE("FwdLockEngine::onInitialize -- FwdLockGlue_InitializeKeyEncryption failed:"
"errno = %d", errno); "errno = %d", errno);
} }
@@ -132,13 +149,13 @@ android::status_t FwdLockEngine::onInitialize(int uniqueId) {
android::status_t android::status_t
FwdLockEngine::onSetOnInfoListener(int uniqueId, const IDrmEngine::OnInfoListener* infoListener) { FwdLockEngine::onSetOnInfoListener(int uniqueId, const IDrmEngine::OnInfoListener* infoListener) {
// Not used // Not used
LOGD("FwdLockEngine::onSetOnInfoListener"); LOG_VERBOSE("FwdLockEngine::onSetOnInfoListener");
return DRM_NO_ERROR; return DRM_NO_ERROR;
} }
android::status_t FwdLockEngine::onTerminate(int uniqueId) { android::status_t FwdLockEngine::onTerminate(int uniqueId) {
LOGD("FwdLockEngine::onTerminate"); LOG_VERBOSE("FwdLockEngine::onTerminate");
return DRM_NO_ERROR; return DRM_NO_ERROR;
} }
@@ -146,7 +163,7 @@ android::status_t FwdLockEngine::onTerminate(int uniqueId) {
DrmSupportInfo* FwdLockEngine::onGetSupportInfo(int uniqueId) { DrmSupportInfo* FwdLockEngine::onGetSupportInfo(int uniqueId) {
DrmSupportInfo* pSupportInfo = new DrmSupportInfo(); DrmSupportInfo* pSupportInfo = new DrmSupportInfo();
LOGD("FwdLockEngine::onGetSupportInfo"); LOG_VERBOSE("FwdLockEngine::onGetSupportInfo");
// fill all Forward Lock mimetypes and extensions // fill all Forward Lock mimetypes and extensions
if (NULL != pSupportInfo) { if (NULL != pSupportInfo) {
@@ -182,7 +199,7 @@ DrmInfoStatus* FwdLockEngine::onProcessDrmInfo(int uniqueId, const DrmInfo* drmI
drmInfoStatus = new DrmInfoStatus((int)DrmInfoStatus::STATUS_OK, 0, NULL, String8("")); drmInfoStatus = new DrmInfoStatus((int)DrmInfoStatus::STATUS_OK, 0, NULL, String8(""));
LOGD("FwdLockEngine::onProcessDrmInfo"); LOG_VERBOSE("FwdLockEngine::onProcessDrmInfo");
return drmInfoStatus; return drmInfoStatus;
} }
@@ -193,7 +210,7 @@ status_t FwdLockEngine::onSaveRights(
const String8& rightsPath, const String8& rightsPath,
const String8& contentPath) { const String8& contentPath) {
// No rights to save. Return // No rights to save. Return
LOGD("FwdLockEngine::onSaveRights"); LOG_VERBOSE("FwdLockEngine::onSaveRights");
return DRM_ERROR_UNKNOWN; return DRM_ERROR_UNKNOWN;
} }
@@ -201,7 +218,7 @@ DrmInfo* FwdLockEngine::onAcquireDrmInfo(int uniqueId, const DrmInfoRequest* drm
DrmInfo* drmInfo = NULL; DrmInfo* drmInfo = NULL;
// Nothing to be done for Forward Lock file // Nothing to be done for Forward Lock file
LOGD("FwdLockEngine::onAcquireDrmInfo"); LOG_VERBOSE("FwdLockEngine::onAcquireDrmInfo");
return drmInfo; return drmInfo;
} }
@@ -211,7 +228,7 @@ int FwdLockEngine::onCheckRightsStatus(int uniqueId,
int action) { int action) {
int result = RightsStatus::RIGHTS_INVALID; int result = RightsStatus::RIGHTS_INVALID;
LOGD("FwdLockEngine::onCheckRightsStatus"); LOG_VERBOSE("FwdLockEngine::onCheckRightsStatus");
// Only Transfer action is not allowed for forward Lock files. // Only Transfer action is not allowed for forward Lock files.
if (onCanHandle(uniqueId, path)) { if (onCanHandle(uniqueId, path)) {
@@ -241,7 +258,7 @@ status_t FwdLockEngine::onConsumeRights(int uniqueId,
int action, int action,
bool reserve) { bool reserve) {
// No rights consumption // No rights consumption
LOGD("FwdLockEngine::onConsumeRights"); LOG_VERBOSE("FwdLockEngine::onConsumeRights");
return DRM_NO_ERROR; return DRM_NO_ERROR;
} }
@@ -249,14 +266,14 @@ bool FwdLockEngine::onValidateAction(int uniqueId,
const String8& path, const String8& path,
int action, int action,
const ActionDescription& description) { const ActionDescription& description) {
LOGD("FwdLockEngine::onValidateAction"); LOG_VERBOSE("FwdLockEngine::onValidateAction");
// For the forwardlock engine checkRights and ValidateAction are the same. // For the forwardlock engine checkRights and ValidateAction are the same.
return (onCheckRightsStatus(uniqueId, path, action) == RightsStatus::RIGHTS_VALID); return (onCheckRightsStatus(uniqueId, path, action) == RightsStatus::RIGHTS_VALID);
} }
String8 FwdLockEngine::onGetOriginalMimeType(int uniqueId, const String8& path) { String8 FwdLockEngine::onGetOriginalMimeType(int uniqueId, const String8& path) {
LOGD("FwdLockEngine::onGetOriginalMimeType"); LOG_VERBOSE("FwdLockEngine::onGetOriginalMimeType");
String8 mimeString = String8(""); String8 mimeString = String8("");
int fileDesc = FwdLockFile_open(path.string()); int fileDesc = FwdLockFile_open(path.string());
@@ -280,7 +297,7 @@ int FwdLockEngine::onGetDrmObjectType(int uniqueId,
const String8& mimeType) { const String8& mimeType) {
String8 mimeStr = String8(mimeType); String8 mimeStr = String8(mimeType);
LOGD("FwdLockEngine::onGetDrmObjectType"); LOG_VERBOSE("FwdLockEngine::onGetDrmObjectType");
mimeStr.toLower(); mimeStr.toLower();
@@ -301,13 +318,13 @@ int FwdLockEngine::onGetDrmObjectType(int uniqueId,
status_t FwdLockEngine::onRemoveRights(int uniqueId, const String8& path) { status_t FwdLockEngine::onRemoveRights(int uniqueId, const String8& path) {
// No Rights to remove // No Rights to remove
LOGD("FwdLockEngine::onRemoveRights"); LOG_VERBOSE("FwdLockEngine::onRemoveRights");
return DRM_NO_ERROR; return DRM_NO_ERROR;
} }
status_t FwdLockEngine::onRemoveAllRights(int uniqueId) { status_t FwdLockEngine::onRemoveAllRights(int uniqueId) {
// No rights to remove // No rights to remove
LOGD("FwdLockEngine::onRemoveAllRights"); LOG_VERBOSE("FwdLockEngine::onRemoveAllRights");
return DRM_NO_ERROR; return DRM_NO_ERROR;
} }
@@ -319,14 +336,14 @@ status_t FwdLockEngine::onSetPlaybackStatus(int uniqueId, DecryptHandle* decrypt
int playbackStatus, int position) { int playbackStatus, int position) {
#endif #endif
// Not used // Not used
LOGD("FwdLockEngine::onSetPlaybackStatus"); LOG_VERBOSE("FwdLockEngine::onSetPlaybackStatus");
return DRM_NO_ERROR; return DRM_NO_ERROR;
} }
status_t FwdLockEngine::onOpenConvertSession(int uniqueId, status_t FwdLockEngine::onOpenConvertSession(int uniqueId,
int convertId) { int convertId) {
status_t result = DRM_ERROR_UNKNOWN; status_t result = DRM_ERROR_UNKNOWN;
LOGD("FwdLockEngine::onOpenConvertSession"); LOG_VERBOSE("FwdLockEngine::onOpenConvertSession");
if (!convertSessionMap.isCreated(convertId)) { if (!convertSessionMap.isCreated(convertId)) {
ConvertSession *newSession = new ConvertSession(); ConvertSession *newSession = new ConvertSession();
if (FwdLockConv_Status_OK == if (FwdLockConv_Status_OK ==
@@ -334,7 +351,7 @@ status_t FwdLockEngine::onOpenConvertSession(int uniqueId,
convertSessionMap.addValue(convertId, newSession); convertSessionMap.addValue(convertId, newSession);
result = DRM_NO_ERROR; result = DRM_NO_ERROR;
} else { } else {
LOGD("FwdLockEngine::onOpenConvertSession -- FwdLockConv_OpenSession failed."); LOGE("FwdLockEngine::onOpenConvertSession -- FwdLockConv_OpenSession failed.");
delete newSession; delete newSession;
} }
} }
@@ -383,7 +400,7 @@ DrmConvertedStatus* FwdLockEngine::onCloseConvertSession(int uniqueId,
DrmBuffer *convResult = new DrmBuffer(NULL, 0); DrmBuffer *convResult = new DrmBuffer(NULL, 0);
int offset = -1; int offset = -1;
LOGD("FwdLockEngine::onCloseConvertSession"); LOG_VERBOSE("FwdLockEngine::onCloseConvertSession");
if (convertSessionMap.isCreated(convertId)) { if (convertSessionMap.isCreated(convertId)) {
ConvertSession *convSession = convertSessionMap.getValue(convertId); ConvertSession *convSession = convertSessionMap.getValue(convertId);
@@ -424,14 +441,14 @@ status_t FwdLockEngine::onOpenDecryptSession(int uniqueId,
status_t result = DRM_ERROR_CANNOT_HANDLE; status_t result = DRM_ERROR_CANNOT_HANDLE;
int fileDesc = -1; int fileDesc = -1;
LOGD("FwdLockEngine::onOpenDecryptSession"); LOG_VERBOSE("FwdLockEngine::onOpenDecryptSession");
if ((-1 < fd) && if ((-1 < fd) &&
(NULL != decryptHandle) && (NULL != decryptHandle) &&
(!decodeSessionMap.isCreated(decryptHandle->decryptId))) { (!decodeSessionMap.isCreated(decryptHandle->decryptId))) {
fileDesc = dup(fd); fileDesc = dup(fd);
} else { } else {
LOGD("FwdLockEngine::onOpenDecryptSession parameter error"); LOGE("FwdLockEngine::onOpenDecryptSession parameter error");
return result; return result;
} }
@@ -453,14 +470,14 @@ status_t FwdLockEngine::onOpenDecryptSession(int uniqueId,
decryptHandle->decryptInfo = NULL; decryptHandle->decryptInfo = NULL;
result = DRM_NO_ERROR; result = DRM_NO_ERROR;
} else { } else {
LOGD("FwdLockEngine::onOpenDecryptSession Integrity Check failed for the fd"); LOG_VERBOSE("FwdLockEngine::onOpenDecryptSession Integrity Check failed for the fd");
FwdLockFile_detach(fileDesc); FwdLockFile_detach(fileDesc);
::close(fileDesc); ::close(fileDesc);
delete decodeSession; delete decodeSession;
} }
} }
LOGD("FwdLockEngine::onOpenDecryptSession Exit. result = %d", result); LOG_VERBOSE("FwdLockEngine::onOpenDecryptSession Exit. result = %d", result);
return result; return result;
} }
@@ -497,7 +514,7 @@ status_t FwdLockEngine::onOpenDecryptSession(int uniqueId,
status_t FwdLockEngine::onCloseDecryptSession(int uniqueId, status_t FwdLockEngine::onCloseDecryptSession(int uniqueId,
DecryptHandle* decryptHandle) { DecryptHandle* decryptHandle) {
status_t result = DRM_ERROR_UNKNOWN; status_t result = DRM_ERROR_UNKNOWN;
LOGD("FwdLockEngine::onCloseDecryptSession"); LOG_VERBOSE("FwdLockEngine::onCloseDecryptSession");
if (NULL != decryptHandle && decodeSessionMap.isCreated(decryptHandle->decryptId)) { if (NULL != decryptHandle && decodeSessionMap.isCreated(decryptHandle->decryptId)) {
DecodeSession* session = decodeSessionMap.getValue(decryptHandle->decryptId); DecodeSession* session = decodeSessionMap.getValue(decryptHandle->decryptId);
@@ -509,7 +526,7 @@ status_t FwdLockEngine::onCloseDecryptSession(int uniqueId,
} }
} }
LOGD("FwdLockEngine::onCloseDecryptSession Exit"); LOG_VERBOSE("FwdLockEngine::onCloseDecryptSession Exit");
return result; return result;
} }
@@ -517,13 +534,13 @@ status_t FwdLockEngine::onInitializeDecryptUnit(int uniqueId,
DecryptHandle* decryptHandle, DecryptHandle* decryptHandle,
int decryptUnitId, int decryptUnitId,
const DrmBuffer* headerInfo) { const DrmBuffer* headerInfo) {
LOGD("FwdLockEngine::onInitializeDecryptUnit"); LOGE("FwdLockEngine::onInitializeDecryptUnit is not supported for this DRM scheme");
return DRM_ERROR_UNKNOWN; return DRM_ERROR_UNKNOWN;
} }
status_t FwdLockEngine::onDecrypt(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId, status_t FwdLockEngine::onDecrypt(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId,
const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV) { const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV) {
LOGD("FwdLockEngine::onDecrypt"); LOGE("FwdLockEngine::onDecrypt is not supported for this DRM scheme");
return DRM_ERROR_UNKNOWN; return DRM_ERROR_UNKNOWN;
} }
@@ -532,14 +549,14 @@ status_t FwdLockEngine::onDecrypt(int uniqueId,
int decryptUnitId, int decryptUnitId,
const DrmBuffer* encBuffer, const DrmBuffer* encBuffer,
DrmBuffer** decBuffer) { DrmBuffer** decBuffer) {
LOGD("FwdLockEngine::onDecrypt"); LOGE("FwdLockEngine::onDecrypt is not supported for this DRM scheme");
return DRM_ERROR_UNKNOWN; return DRM_ERROR_UNKNOWN;
} }
status_t FwdLockEngine::onFinalizeDecryptUnit(int uniqueId, status_t FwdLockEngine::onFinalizeDecryptUnit(int uniqueId,
DecryptHandle* decryptHandle, DecryptHandle* decryptHandle,
int decryptUnitId) { int decryptUnitId) {
LOGD("FwdLockEngine::onFinalizeDecryptUnit"); LOGE("FwdLockEngine::onFinalizeDecryptUnit is not supported for this DRM scheme");
return DRM_ERROR_UNKNOWN; return DRM_ERROR_UNKNOWN;
} }
@@ -617,11 +634,11 @@ ssize_t FwdLockEngine::onPread(int uniqueId,
if (((off_t)-1) != decoderSession->offset) { if (((off_t)-1) != decoderSession->offset) {
bytesRead = onRead(uniqueId, decryptHandle, buffer, numBytes); bytesRead = onRead(uniqueId, decryptHandle, buffer, numBytes);
if (bytesRead < 0) { if (bytesRead < 0) {
LOGD("FwdLockEngine::onPread error reading"); LOGE("FwdLockEngine::onPread error reading");
} }
} }
} else { } else {
LOGD("FwdLockEngine::onPread decryptId not found"); LOGE("FwdLockEngine::onPread decryptId not found");
} }
return bytesRead; return bytesRead;

View File

@@ -275,17 +275,18 @@ static int FwdLockConv_DeriveKeys(FwdLockConv_Session_t *pSession) {
} }
/** /**
* Checks whether a given character is valid in a boundary. Note that the boundary may contain * Checks whether a given character is valid in a boundary. Allows some non-standard characters that
* leading and internal spaces. * are invalid according to RFC 2046 but nevertheless used by one vendor's DRM packager. Note that
* the boundary may contain leading and internal spaces.
* *
* @param[in] ch The character to check. * @param[in] ch The character to check.
* *
* @return A Boolean value indicating whether the given character is valid in a boundary. * @return A Boolean value indicating whether the given character is valid in a boundary.
*/ */
static int FwdLockConv_IsBoundaryChar(int ch) { static int FwdLockConv_IsBoundaryChar(int ch) {
return isalnum(ch) || ch == '\'' || return isalnum(ch) || ch == '\'' || ch == '(' || ch == ')' || ch == '+' || ch == '_' ||
ch == '(' || ch == ')' || ch == '+' || ch == '_' || ch == ',' || ch == '-' || ch == ',' || ch == '-' || ch == '.' || ch == '/' || ch == ':' || ch == '=' ||
ch == '.' || ch == '/' || ch == ':' || ch == '=' || ch == '?' || ch == ' '; ch == '?' || ch == ' ' || ch == '%' || ch == '[' || ch == '&' || ch == '*' || ch == '^';
} }
/** /**
@@ -1085,6 +1086,13 @@ static FwdLockConv_Status_t FwdLockConv_PushChar(FwdLockConv_Session_t *pSession
status = FwdLockConv_MatchBinaryEncodedData(pSession, ch, pOutput); status = FwdLockConv_MatchBinaryEncodedData(pSession, ch, pOutput);
break; break;
case FwdLockConv_ParserState_WantsBase64EncodedData: case FwdLockConv_ParserState_WantsBase64EncodedData:
if (ch == '\n' && pSession->scannerState != FwdLockConv_ScannerState_WantsLF) {
// Repair base64-encoded data that doesn't have carriage returns in its line breaks.
status = FwdLockConv_MatchBase64EncodedData(pSession, '\r', pOutput);
if (status != FwdLockConv_Status_OK) {
break;
}
}
status = FwdLockConv_MatchBase64EncodedData(pSession, ch, pOutput); status = FwdLockConv_MatchBase64EncodedData(pSession, ch, pOutput);
break; break;
case FwdLockConv_ParserState_Done: case FwdLockConv_ParserState_Done:
@@ -1199,7 +1207,7 @@ FwdLockConv_Status_t FwdLockConv_CloseSession(int sessionId, FwdLockConv_Output_
status = FwdLockConv_Status_SyntaxError; status = FwdLockConv_Status_SyntaxError;
} else { } else {
// Finalize the data signature. // Finalize the data signature.
size_t signatureSize; unsigned int signatureSize = SHA1_HASH_SIZE;
HMAC_Final(&pSession->signingContext, pOutput->fromCloseSession.signatures, HMAC_Final(&pSession->signingContext, pOutput->fromCloseSession.signatures,
&signatureSize); &signatureSize);
if (signatureSize != SHA1_HASH_SIZE) { if (signatureSize != SHA1_HASH_SIZE) {
@@ -1214,9 +1222,9 @@ FwdLockConv_Status_t FwdLockConv_CloseSession(int sessionId, FwdLockConv_Output_
HMAC_Update(&pSession->signingContext, pSession->pEncryptedSessionKey, HMAC_Update(&pSession->signingContext, pSession->pEncryptedSessionKey,
pSession->encryptedSessionKeyLength); pSession->encryptedSessionKeyLength);
HMAC_Update(&pSession->signingContext, pOutput->fromCloseSession.signatures, HMAC_Update(&pSession->signingContext, pOutput->fromCloseSession.signatures,
signatureSize); SHA1_HASH_SIZE);
HMAC_Final(&pSession->signingContext, &pOutput->fromCloseSession. HMAC_Final(&pSession->signingContext,
signatures[signatureSize], &signatureSize); &pOutput->fromCloseSession.signatures[SHA1_HASH_SIZE], &signatureSize);
if (signatureSize != SHA1_HASH_SIZE) { if (signatureSize != SHA1_HASH_SIZE) {
status = FwdLockConv_Status_ProgramError; status = FwdLockConv_Status_ProgramError;
} else { } else {

View File

@@ -114,7 +114,7 @@ static int FwdLockFile_AcquireSession(int fileDesc) {
} }
/** /**
* Finds the file session associated to the given file descriptor. * Finds the file session associated with the given file descriptor.
* *
* @param[in] fileDesc A file descriptor. * @param[in] fileDesc A file descriptor.
* *
@@ -389,7 +389,7 @@ int FwdLockFile_CheckDataIntegrity(int fileDesc) {
result = FALSE; result = FALSE;
} else { } else {
ssize_t numBytesRead; ssize_t numBytesRead;
size_t signatureSize = SHA1_HASH_SIZE; unsigned int signatureSize = SHA1_HASH_SIZE;
while ((numBytesRead = while ((numBytesRead =
read(pSession->fileDesc, pData->buffer, SIG_CALC_BUFFER_SIZE)) > 0) { read(pSession->fileDesc, pData->buffer, SIG_CALC_BUFFER_SIZE)) > 0) {
HMAC_Update(&pSession->signingContext, pData->buffer, (size_t)numBytesRead); HMAC_Update(&pSession->signingContext, pData->buffer, (size_t)numBytesRead);
@@ -399,7 +399,7 @@ int FwdLockFile_CheckDataIntegrity(int fileDesc) {
} else { } else {
HMAC_Final(&pSession->signingContext, pData->signature, &signatureSize); HMAC_Final(&pSession->signingContext, pData->signature, &signatureSize);
assert(signatureSize == SHA1_HASH_SIZE); assert(signatureSize == SHA1_HASH_SIZE);
result = memcmp(pData->signature, pSession->dataSignature, signatureSize) == 0; result = memcmp(pData->signature, pSession->dataSignature, SHA1_HASH_SIZE) == 0;
} }
HMAC_Init_ex(&pSession->signingContext, NULL, KEY_SIZE, NULL, NULL); HMAC_Init_ex(&pSession->signingContext, NULL, KEY_SIZE, NULL, NULL);
(void)lseek64(pSession->fileDesc, pSession->dataOffset + pSession->filePos, (void)lseek64(pSession->fileDesc, pSession->dataOffset + pSession->filePos,
@@ -419,16 +419,16 @@ int FwdLockFile_CheckHeaderIntegrity(int fileDesc) {
} else { } else {
FwdLockFile_Session_t *pSession = sessionPtrs[sessionId]; FwdLockFile_Session_t *pSession = sessionPtrs[sessionId];
unsigned char signature[SHA1_HASH_SIZE]; unsigned char signature[SHA1_HASH_SIZE];
size_t signatureSize = SHA1_HASH_SIZE; unsigned int signatureSize = SHA1_HASH_SIZE;
HMAC_Update(&pSession->signingContext, pSession->topHeader, TOP_HEADER_SIZE); HMAC_Update(&pSession->signingContext, pSession->topHeader, TOP_HEADER_SIZE);
HMAC_Update(&pSession->signingContext, (unsigned char *)pSession->pContentType, HMAC_Update(&pSession->signingContext, (unsigned char *)pSession->pContentType,
pSession->contentTypeLength); pSession->contentTypeLength);
HMAC_Update(&pSession->signingContext, pSession->pEncryptedSessionKey, HMAC_Update(&pSession->signingContext, pSession->pEncryptedSessionKey,
pSession->encryptedSessionKeyLength); pSession->encryptedSessionKeyLength);
HMAC_Update(&pSession->signingContext, pSession->dataSignature, signatureSize); HMAC_Update(&pSession->signingContext, pSession->dataSignature, SHA1_HASH_SIZE);
HMAC_Final(&pSession->signingContext, signature, &signatureSize); HMAC_Final(&pSession->signingContext, signature, &signatureSize);
assert(signatureSize == SHA1_HASH_SIZE); assert(signatureSize == SHA1_HASH_SIZE);
result = memcmp(signature, pSession->headerSignature, signatureSize) == 0; result = memcmp(signature, pSession->headerSignature, SHA1_HASH_SIZE) == 0;
HMAC_Init_ex(&pSession->signingContext, NULL, KEY_SIZE, NULL, NULL); HMAC_Init_ex(&pSession->signingContext, NULL, KEY_SIZE, NULL, NULL);
} }
return result; return result;