omadrm/drmengine/dm/src/Oma1DcfCreator.cpp
changeset 0 95b198f216e5
child 18 8a03a285ab14
equal deleted inserted replaced
-1:000000000000 0:95b198f216e5
       
     1 /*
       
     2 * Copyright (c) 2002, 2003 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Implementation of the DRM access functions that are available
       
    15 *                to authenticated clients.
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 // INCLUDE FILES
       
    21 
       
    22 #include <e32base.h>
       
    23 #include <e32std.h>
       
    24 #include <e32math.h>
       
    25 #include <e32test.h>
       
    26 #include <f32file.h>
       
    27 #include <s32file.h>
       
    28 #include <s32mem.h>
       
    29 #include <apmstd.h>
       
    30 #include <symmetric.h>
       
    31 #include "Oma1DcfCreator.h"
       
    32 #include "DRMRightsClient.h"
       
    33 #include "DRMPermission.h"
       
    34 #include "DRMConstraint.h"
       
    35 #include "DRMCommon.h"
       
    36 #include "DrmKeyStorage.h"
       
    37 
       
    38 
       
    39 // EXTERNAL DATA STRUCTURES
       
    40 
       
    41 // EXTERNAL FUNCTION PROTOTYPES  
       
    42 
       
    43 // CONSTANTS
       
    44 
       
    45 static const TInt KMaxEncryptionSize = 2048;    
       
    46 
       
    47 // MACROS
       
    48 
       
    49 // LOCAL CONSTANTS AND MACROS
       
    50 
       
    51 _LIT8(KLDContentURI, "ldf:31415926535@localhost");
       
    52 _LIT8(KLDFHeader, "Encryption-Method:AES128CBC;padding=RFC2630\x0d\x0a");
       
    53 
       
    54 // ============================= LOCAL FUNCTIONS ===============================
       
    55 
       
    56 // ============================ MEMBER FUNCTIONS ===============================
       
    57 
       
    58 // -----------------------------------------------------------------------------
       
    59 // COma1DcfCreator::COma1DcfCreator
       
    60 // C++ default constructor can NOT contain any code, that
       
    61 // might leave.
       
    62 // -----------------------------------------------------------------------------
       
    63 EXPORT_C COma1DcfCreator::COma1DcfCreator(void)
       
    64     {
       
    65     iEncryptionStream = NULL;
       
    66     iEncryptionBuffer = NULL;
       
    67     } 
       
    68 
       
    69 // -----------------------------------------------------------------------------
       
    70 // COma1DcfCreator::ConstructL
       
    71 // Symbian 2nd phase constructor can leave.
       
    72 // -----------------------------------------------------------------------------
       
    73 //
       
    74 EXPORT_C void COma1DcfCreator::ConstructL()
       
    75     {
       
    76     iEncryptionBuffer = HBufC8::NewL(KMaxEncryptionSize);
       
    77     }
       
    78 
       
    79 // -----------------------------------------------------------------------------
       
    80 // COma1DcfCreator::NewL
       
    81 // Two-phased constructor.
       
    82 // -----------------------------------------------------------------------------
       
    83 EXPORT_C COma1DcfCreator* COma1DcfCreator::NewL()
       
    84     {
       
    85     COma1DcfCreator* self = new COma1DcfCreator();
       
    86     
       
    87     User::LeaveIfNull(self);
       
    88     
       
    89     CleanupStack::PushL(self);
       
    90     self->ConstructL();
       
    91     CleanupStack::Pop();
       
    92     
       
    93     return self;
       
    94     }
       
    95 
       
    96 
       
    97 // Destructor
       
    98 EXPORT_C COma1DcfCreator::~COma1DcfCreator()
       
    99     {
       
   100     delete iEncryptionBuffer;
       
   101     iRdb.Close();
       
   102     }
       
   103 
       
   104 // ================= MEMBER FUNCTIONS =======================
       
   105 
       
   106 // -----------------------------------------------------------------------------
       
   107 // COma1DcfCreator::
       
   108 // 
       
   109 // -----------------------------------------------------------------------------
       
   110 EXPORT_C void COma1DcfCreator::EncryptInitializeL(
       
   111     RWriteStream& anOutput,
       
   112     const TDesC8& aMIMEType, 
       
   113     CDRMRights* aRightsObject)
       
   114     {
       
   115     const TUint KVersion = 1;
       
   116     CDRMPermission *rights = CDRMPermission::NewLC();
       
   117     TInt err = 0;
       
   118     TDRMUniqueID id = 0;
       
   119     TBuf8<KDCFKeySize> key;
       
   120     TPtrC8 uri(0, 0);
       
   121 
       
   122     User::LeaveIfError(iRdb.Connect());
       
   123     iBytesWritten = 0;
       
   124 
       
   125     // generate rights
       
   126     if (aRightsObject)
       
   127         {
       
   128         uri.Set(aRightsObject->GetAsset().iUid->Des());
       
   129         err = iRdb.InitializeKey(uri);
       
   130         if (err == KErrCANoRights)
       
   131             {
       
   132             key.SetLength(KDCFKeySize);
       
   133             iRdb.GetRandomDataL(key);    
       
   134             User::LeaveIfError(iRdb.AddRecord(key, aRightsObject->GetPermission(),
       
   135                 uri, id));
       
   136             User::LeaveIfError(iRdb.InitializeKey(uri));
       
   137             }
       
   138         else
       
   139             {
       
   140             User::LeaveIfError(err);
       
   141             }
       
   142         }
       
   143     else
       
   144         {
       
   145         uri.Set(KLDContentURI);
       
   146         err = iRdb.InitializeKey(uri);
       
   147         if (err == KErrCANoRights)
       
   148             {
       
   149             rights->iAvailableRights = ERightsAll;
       
   150             rights->iTopLevel->iActiveConstraints = EConstraintNone;
       
   151             rights->iPlay->iActiveConstraints = EConstraintNone;
       
   152             rights->iDisplay->iActiveConstraints = EConstraintNone;
       
   153             rights->iPrint->iActiveConstraints = EConstraintNone;
       
   154             rights->iExecute->iActiveConstraints = EConstraintNone;
       
   155             rights->iUniqueID = 0;
       
   156             key.SetLength(KDCFKeySize);
       
   157             iRdb.GetRandomDataL(key);
       
   158             User::LeaveIfError(iRdb.AddRecord(key, *rights, uri, id));
       
   159             User::LeaveIfError(iRdb.InitializeKey(uri));
       
   160             }
       
   161         else
       
   162             {
       
   163             User::LeaveIfError(err);
       
   164             }
       
   165         }
       
   166 
       
   167     iIv.SetLength(KDCFKeySize);
       
   168     iRdb.GetRandomDataL(iIv);
       
   169 
       
   170     iEncryptionStream = &anOutput;
       
   171 
       
   172     anOutput.WriteUint8L(KVersion);
       
   173     anOutput.WriteUint8L(aMIMEType.Length());
       
   174     anOutput.WriteUint8L(uri.Length());
       
   175     anOutput.WriteL(aMIMEType);
       
   176     anOutput.WriteL(uri);
       
   177     anOutput.WriteUint8L(KLDFHeader().Size());
       
   178     anOutput.WriteUint8L(0);
       
   179     anOutput.WriteL(KLDFHeader);
       
   180     anOutput.WriteL(iIv);
       
   181     anOutput.CommitL();
       
   182     iBytesWritten += 3 + aMIMEType.Size() + 2 + KLDFHeader().Size() +
       
   183         iIv.Size();
       
   184     
       
   185     CleanupStack::PopAndDestroy(); // rights
       
   186     } 
       
   187 
       
   188 // -----------------------------------------------------------------------------
       
   189 // COma1DcfCreator::EncryptUpdateL
       
   190 // update the encryption
       
   191 // -----------------------------------------------------------------------------
       
   192 EXPORT_C void COma1DcfCreator::EncryptUpdateL(const TDesC8& aMessageData)
       
   193     {
       
   194     TInt i;
       
   195     TInt n;
       
   196     TInt size;
       
   197     TPtr8 ptr(iEncryptionBuffer->Des());
       
   198     TPtrC8 data;
       
   199     
       
   200     data.Set(aMessageData);
       
   201     if (iRemainder.Size() > 0 && iRemainder.Size() + data.Size() >= KDCFKeySize)
       
   202         {
       
   203         ptr.Copy(iRemainder);
       
   204         n = Min(KDCFKeySize - iRemainder.Size(), data.Size());
       
   205         ptr.Append(data.Left(n));
       
   206         iRdb.Encrypt(iIv, ptr);
       
   207         iEncryptionStream->WriteL(ptr);
       
   208         iBytesWritten += ptr.Size();
       
   209         iIv.Copy(ptr.Right(KDCFKeySize));
       
   210         data.Set(data.Right(data.Size() - n));
       
   211         iRemainder.SetLength(0);
       
   212         }
       
   213     
       
   214     size = data.Size();
       
   215     for (i = 0; size > KDCFKeySize; i += KMaxEncryptionSize)
       
   216         {
       
   217         n = Min(KMaxEncryptionSize, ((size / KDCFKeySize) * KDCFKeySize));
       
   218         ptr.Copy(data.Mid(i, n));
       
   219         iRdb.Encrypt(iIv, ptr);
       
   220         iEncryptionStream->WriteL(ptr);
       
   221         iBytesWritten += ptr.Size();
       
   222         iIv.Copy(ptr.Right(KDCFKeySize));
       
   223         size -= n;
       
   224         }
       
   225     iRemainder.Append(data.Right(size));
       
   226     }
       
   227 
       
   228 
       
   229 // -----------------------------------------------------------------------------
       
   230 // COma1DcfCreator::EncryptFinalizeL
       
   231 // finalize the encryption
       
   232 // -----------------------------------------------------------------------------
       
   233 EXPORT_C void COma1DcfCreator::EncryptFinalizeL()
       
   234     {
       
   235     TPtr8 ptr(iEncryptionBuffer->Des());
       
   236     
       
   237     ptr.Copy(iRemainder);
       
   238     iRdb.Encrypt(iIv, ptr, ETrue);
       
   239     iEncryptionStream->WriteL(ptr);
       
   240     iEncryptionStream->CommitL();
       
   241 
       
   242     iBytesWritten += ptr.Size();
       
   243     iRdb.Close();
       
   244     }
       
   245 
       
   246 // -----------------------------------------------------------------------------
       
   247 // COma1DcfCreator::EncryptContent
       
   248 // Encrypt plain content to a DCF. Replaces the input buffer with the plain
       
   249 // content with the DCF.
       
   250 // -----------------------------------------------------------------------------
       
   251 EXPORT_C void COma1DcfCreator::EncryptContentL(
       
   252     HBufC8*& aContent, 
       
   253     const TDesC8& aMIMEType, 
       
   254     CDRMRights* aRightsObject)
       
   255     {
       
   256     RMemWriteStream output;
       
   257     TAny* buffer;
       
   258     TInt size;
       
   259 
       
   260     size = aContent->Length() +
       
   261         aMIMEType.Length() +
       
   262         KLDContentURI().Length() + 
       
   263         KLDFHeader().Length() + 256;
       
   264     buffer = User::Alloc(size);
       
   265     User::LeaveIfNull(buffer);
       
   266     CleanupStack::PushL(buffer);
       
   267     output.Open(buffer, size);
       
   268     CleanupClosePushL(output);
       
   269     EncryptInitializeL(output, aMIMEType, aRightsObject);
       
   270     EncryptUpdateL(*aContent);
       
   271     EncryptFinalizeL();
       
   272     delete aContent;
       
   273     aContent = HBufC8::NewMax(size);
       
   274     User::LeaveIfNull(aContent);
       
   275     size = iBytesWritten;
       
   276     *aContent = TPtr8(static_cast<TUint8*>(buffer), size, size);
       
   277     CleanupStack::PopAndDestroy(2); // output, buffer
       
   278     }
       
   279 
       
   280 // -----------------------------------------------------------------------------
       
   281 // COma1DcfCreator::EncryptFileL
       
   282 // Turn a plain content file into a DCF.
       
   283 // -----------------------------------------------------------------------------
       
   284 EXPORT_C void COma1DcfCreator::EncryptFileL(
       
   285     const TDesC& aFileName, 
       
   286     const TDesC& aDCFFileName, 
       
   287     const TDesC8& aMIMEType, 
       
   288     CDRMRights* aRightsObject)
       
   289     {
       
   290     TInt r = KErrNone;    
       
   291     RFs fs;
       
   292     RFile input;
       
   293     RFileWriteStream output;
       
   294     HBufC8* buf = HBufC8::NewLC(8000);
       
   295     TPtr8 buffer(const_cast<TUint8*>(buf->Ptr()),0,8000);
       
   296    
       
   297 
       
   298     User::LeaveIfError(fs.Connect());
       
   299     CleanupClosePushL(fs);
       
   300 
       
   301     r = input.Open(fs, aFileName, EFileRead|EFileShareReadersOrWriters);
       
   302     if(r == KErrInUse)
       
   303         {
       
   304         r = input.Open(fs, aFileName, EFileRead | EFileShareAny);
       
   305                                                       
       
   306         if(r == KErrInUse)
       
   307             {
       
   308             User::LeaveIfError(input.Open(fs, aFileName, EFileRead | 
       
   309                                                          EFileShareReadersOnly));
       
   310             r = KErrNone;                                             
       
   311             }
       
   312         }
       
   313         
       
   314     User::LeaveIfError( r );        
       
   315     
       
   316     CleanupClosePushL(input);
       
   317     
       
   318     User::LeaveIfError(output.Replace(fs, aDCFFileName, EFileWrite));
       
   319     CleanupClosePushL(output);    
       
   320     
       
   321    
       
   322     EncryptInitializeL(output, aMIMEType, aRightsObject);
       
   323 
       
   324     
       
   325     do
       
   326         {
       
   327         input.Read(buffer, buffer.MaxSize());
       
   328         if (buffer.Size() > 0)
       
   329             {
       
   330 
       
   331             EncryptUpdateL(buffer);
       
   332 
       
   333             }
       
   334         }
       
   335     while (buffer.Size() > 0);
       
   336  
       
   337     EncryptFinalizeL();
       
   338 
       
   339     CleanupStack::PopAndDestroy(4); // output, input, fs, buf
       
   340     }
       
   341 
       
   342 // -----------------------------------------------------------------------------
       
   343 // COma1DcfCreator::EncryptContentToFile
       
   344 // Encrypt plain content to a DCF and stores it in a file.
       
   345 // -----------------------------------------------------------------------------
       
   346 EXPORT_C void COma1DcfCreator::EncryptContentToFileL(
       
   347     const TDesC8& aContent, 
       
   348     const TDesC& aFileName, 
       
   349     const TDesC8& aMIMEType, 
       
   350     CDRMRights* aRightsObject)
       
   351     {
       
   352     RFs fs;
       
   353     RFileWriteStream output;
       
   354 
       
   355     User::LeaveIfError(fs.Connect());
       
   356     CleanupClosePushL(fs);
       
   357     fs.Delete(aFileName);
       
   358     User::LeaveIfError(output.Create(fs, aFileName, EFileWrite));
       
   359     CleanupClosePushL(output);
       
   360     EncryptInitializeL(output, aMIMEType, aRightsObject);
       
   361     EncryptUpdateL(aContent);
       
   362     EncryptFinalizeL();
       
   363     CleanupStack::PopAndDestroy(2); // output, fs
       
   364     }
       
   365 
       
   366 // End of File