diff -r 000000000000 -r 95b198f216e5 omadrm/drmengine/dm/src/Oma1DcfCreator.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omadrm/drmengine/dm/src/Oma1DcfCreator.cpp Thu Dec 17 08:52:27 2009 +0200 @@ -0,0 +1,366 @@ +/* +* Copyright (c) 2002, 2003 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Implementation of the DRM access functions that are available +* to authenticated clients. +* +*/ + + +// INCLUDE FILES + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "Oma1DcfCreator.h" +#include "DRMRightsClient.h" +#include "DRMPermission.h" +#include "DRMConstraint.h" +#include "DRMCommon.h" +#include "DrmKeyStorage.h" + + +// EXTERNAL DATA STRUCTURES + +// EXTERNAL FUNCTION PROTOTYPES + +// CONSTANTS + +static const TInt KMaxEncryptionSize = 2048; + +// MACROS + +// LOCAL CONSTANTS AND MACROS + +_LIT8(KLDContentURI, "ldf:31415926535@localhost"); +_LIT8(KLDFHeader, "Encryption-Method:AES128CBC;padding=RFC2630\x0d\x0a"); + +// ============================= LOCAL FUNCTIONS =============================== + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// COma1DcfCreator::COma1DcfCreator +// C++ default constructor can NOT contain any code, that +// might leave. +// ----------------------------------------------------------------------------- +EXPORT_C COma1DcfCreator::COma1DcfCreator(void) + { + iEncryptionStream = NULL; + iEncryptionBuffer = NULL; + } + +// ----------------------------------------------------------------------------- +// COma1DcfCreator::ConstructL +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +// +EXPORT_C void COma1DcfCreator::ConstructL() + { + iEncryptionBuffer = HBufC8::NewL(KMaxEncryptionSize); + } + +// ----------------------------------------------------------------------------- +// COma1DcfCreator::NewL +// Two-phased constructor. +// ----------------------------------------------------------------------------- +EXPORT_C COma1DcfCreator* COma1DcfCreator::NewL() + { + COma1DcfCreator* self = new COma1DcfCreator(); + + User::LeaveIfNull(self); + + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(); + + return self; + } + + +// Destructor +EXPORT_C COma1DcfCreator::~COma1DcfCreator() + { + delete iEncryptionBuffer; + iRdb.Close(); + } + +// ================= MEMBER FUNCTIONS ======================= + +// ----------------------------------------------------------------------------- +// COma1DcfCreator:: +// +// ----------------------------------------------------------------------------- +EXPORT_C void COma1DcfCreator::EncryptInitializeL( + RWriteStream& anOutput, + const TDesC8& aMIMEType, + CDRMRights* aRightsObject) + { + const TUint KVersion = 1; + CDRMPermission *rights = CDRMPermission::NewLC(); + TInt err = 0; + TDRMUniqueID id = 0; + TBuf8 key; + TPtrC8 uri(0, 0); + + User::LeaveIfError(iRdb.Connect()); + iBytesWritten = 0; + + // generate rights + if (aRightsObject) + { + uri.Set(aRightsObject->GetAsset().iUid->Des()); + err = iRdb.InitializeKey(uri); + if (err == KErrCANoRights) + { + key.SetLength(KDCFKeySize); + iRdb.GetRandomDataL(key); + User::LeaveIfError(iRdb.AddRecord(key, aRightsObject->GetPermission(), + uri, id)); + User::LeaveIfError(iRdb.InitializeKey(uri)); + } + else + { + User::LeaveIfError(err); + } + } + else + { + uri.Set(KLDContentURI); + err = iRdb.InitializeKey(uri); + if (err == KErrCANoRights) + { + rights->iAvailableRights = ERightsAll; + rights->iTopLevel->iActiveConstraints = EConstraintNone; + rights->iPlay->iActiveConstraints = EConstraintNone; + rights->iDisplay->iActiveConstraints = EConstraintNone; + rights->iPrint->iActiveConstraints = EConstraintNone; + rights->iExecute->iActiveConstraints = EConstraintNone; + rights->iUniqueID = 0; + key.SetLength(KDCFKeySize); + iRdb.GetRandomDataL(key); + User::LeaveIfError(iRdb.AddRecord(key, *rights, uri, id)); + User::LeaveIfError(iRdb.InitializeKey(uri)); + } + else + { + User::LeaveIfError(err); + } + } + + iIv.SetLength(KDCFKeySize); + iRdb.GetRandomDataL(iIv); + + iEncryptionStream = &anOutput; + + anOutput.WriteUint8L(KVersion); + anOutput.WriteUint8L(aMIMEType.Length()); + anOutput.WriteUint8L(uri.Length()); + anOutput.WriteL(aMIMEType); + anOutput.WriteL(uri); + anOutput.WriteUint8L(KLDFHeader().Size()); + anOutput.WriteUint8L(0); + anOutput.WriteL(KLDFHeader); + anOutput.WriteL(iIv); + anOutput.CommitL(); + iBytesWritten += 3 + aMIMEType.Size() + 2 + KLDFHeader().Size() + + iIv.Size(); + + CleanupStack::PopAndDestroy(); // rights + } + +// ----------------------------------------------------------------------------- +// COma1DcfCreator::EncryptUpdateL +// update the encryption +// ----------------------------------------------------------------------------- +EXPORT_C void COma1DcfCreator::EncryptUpdateL(const TDesC8& aMessageData) + { + TInt i; + TInt n; + TInt size; + TPtr8 ptr(iEncryptionBuffer->Des()); + TPtrC8 data; + + data.Set(aMessageData); + if (iRemainder.Size() > 0 && iRemainder.Size() + data.Size() >= KDCFKeySize) + { + ptr.Copy(iRemainder); + n = Min(KDCFKeySize - iRemainder.Size(), data.Size()); + ptr.Append(data.Left(n)); + iRdb.Encrypt(iIv, ptr); + iEncryptionStream->WriteL(ptr); + iBytesWritten += ptr.Size(); + iIv.Copy(ptr.Right(KDCFKeySize)); + data.Set(data.Right(data.Size() - n)); + iRemainder.SetLength(0); + } + + size = data.Size(); + for (i = 0; size > KDCFKeySize; i += KMaxEncryptionSize) + { + n = Min(KMaxEncryptionSize, ((size / KDCFKeySize) * KDCFKeySize)); + ptr.Copy(data.Mid(i, n)); + iRdb.Encrypt(iIv, ptr); + iEncryptionStream->WriteL(ptr); + iBytesWritten += ptr.Size(); + iIv.Copy(ptr.Right(KDCFKeySize)); + size -= n; + } + iRemainder.Append(data.Right(size)); + } + + +// ----------------------------------------------------------------------------- +// COma1DcfCreator::EncryptFinalizeL +// finalize the encryption +// ----------------------------------------------------------------------------- +EXPORT_C void COma1DcfCreator::EncryptFinalizeL() + { + TPtr8 ptr(iEncryptionBuffer->Des()); + + ptr.Copy(iRemainder); + iRdb.Encrypt(iIv, ptr, ETrue); + iEncryptionStream->WriteL(ptr); + iEncryptionStream->CommitL(); + + iBytesWritten += ptr.Size(); + iRdb.Close(); + } + +// ----------------------------------------------------------------------------- +// COma1DcfCreator::EncryptContent +// Encrypt plain content to a DCF. Replaces the input buffer with the plain +// content with the DCF. +// ----------------------------------------------------------------------------- +EXPORT_C void COma1DcfCreator::EncryptContentL( + HBufC8*& aContent, + const TDesC8& aMIMEType, + CDRMRights* aRightsObject) + { + RMemWriteStream output; + TAny* buffer; + TInt size; + + size = aContent->Length() + + aMIMEType.Length() + + KLDContentURI().Length() + + KLDFHeader().Length() + 256; + buffer = User::Alloc(size); + User::LeaveIfNull(buffer); + CleanupStack::PushL(buffer); + output.Open(buffer, size); + CleanupClosePushL(output); + EncryptInitializeL(output, aMIMEType, aRightsObject); + EncryptUpdateL(*aContent); + EncryptFinalizeL(); + delete aContent; + aContent = HBufC8::NewMax(size); + User::LeaveIfNull(aContent); + size = iBytesWritten; + *aContent = TPtr8(static_cast(buffer), size, size); + CleanupStack::PopAndDestroy(2); // output, buffer + } + +// ----------------------------------------------------------------------------- +// COma1DcfCreator::EncryptFileL +// Turn a plain content file into a DCF. +// ----------------------------------------------------------------------------- +EXPORT_C void COma1DcfCreator::EncryptFileL( + const TDesC& aFileName, + const TDesC& aDCFFileName, + const TDesC8& aMIMEType, + CDRMRights* aRightsObject) + { + TInt r = KErrNone; + RFs fs; + RFile input; + RFileWriteStream output; + HBufC8* buf = HBufC8::NewLC(8000); + TPtr8 buffer(const_cast(buf->Ptr()),0,8000); + + + User::LeaveIfError(fs.Connect()); + CleanupClosePushL(fs); + + r = input.Open(fs, aFileName, EFileRead|EFileShareReadersOrWriters); + if(r == KErrInUse) + { + r = input.Open(fs, aFileName, EFileRead | EFileShareAny); + + if(r == KErrInUse) + { + User::LeaveIfError(input.Open(fs, aFileName, EFileRead | + EFileShareReadersOnly)); + r = KErrNone; + } + } + + User::LeaveIfError( r ); + + CleanupClosePushL(input); + + User::LeaveIfError(output.Replace(fs, aDCFFileName, EFileWrite)); + CleanupClosePushL(output); + + + EncryptInitializeL(output, aMIMEType, aRightsObject); + + + do + { + input.Read(buffer, buffer.MaxSize()); + if (buffer.Size() > 0) + { + + EncryptUpdateL(buffer); + + } + } + while (buffer.Size() > 0); + + EncryptFinalizeL(); + + CleanupStack::PopAndDestroy(4); // output, input, fs, buf + } + +// ----------------------------------------------------------------------------- +// COma1DcfCreator::EncryptContentToFile +// Encrypt plain content to a DCF and stores it in a file. +// ----------------------------------------------------------------------------- +EXPORT_C void COma1DcfCreator::EncryptContentToFileL( + const TDesC8& aContent, + const TDesC& aFileName, + const TDesC8& aMIMEType, + CDRMRights* aRightsObject) + { + RFs fs; + RFileWriteStream output; + + User::LeaveIfError(fs.Connect()); + CleanupClosePushL(fs); + fs.Delete(aFileName); + User::LeaveIfError(output.Create(fs, aFileName, EFileWrite)); + CleanupClosePushL(output); + EncryptInitializeL(output, aMIMEType, aRightsObject); + EncryptUpdateL(aContent); + EncryptFinalizeL(); + CleanupStack::PopAndDestroy(2); // output, fs + } + +// End of File