commondrm/drmencryptor/src/DrmKeyStorage.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Mon, 15 Mar 2010 12:41:43 +0200
branchRCL_3
changeset 18 8a03a285ab14
parent 0 95b198f216e5
permissions -rw-r--r--
Revision: 201009 Kit: 201010

/*
* Copyright (c) 2003-2009 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:
*
*/


// INCLUDE FILES
#include <e32std.h>
#include <f32file.h>
#include <flogger.h>
#include <x509cert.h>
#include <symmetric.h>
#include <asymmetric.h>

#ifdef RD_MULTIPLE_DRIVE
#include <driveinfo.h>
#endif

#include <zipfile.h>
#include <aknnotewrappers.h>

#include "DrmKeyStorage.h"

// EXTERNAL DATA STRUCTURES

// EXTERNAL FUNCTION PROTOTYPES

// CONSTANTS

// MACROS

// LOCAL CONSTANTS AND MACROS

// Test logging macros

#ifdef RD_MULTIPLE_DRIVE
_LIT(KPrivateRightsDir, "%c:\\private\\101F51F2\\PKI");
_LIT(KFullLogDir, "%c:\\logs\\drm\\");
#else
_LIT(KPrivateRightsDir, "c:\\private\\101F51F2\\PKI");
_LIT(KFullLogDir, "c:\\logs\\drm\\");
#endif


#ifdef __WINS__
_LIT(KInputDir, "c:\\data\\drm\\keys\\");
_LIT(KInputFilePattern, "c:\\data\\drm\\keys\\SigningCert*");
#else
#ifdef RD_MULTIPLE_DRIVE
_LIT(KInputDir, "%c:\\drm\\keys\\");
_LIT(KInputFilePattern, "%c:\\drm\\keys\\SigningCert*");
#else
_LIT(KInputDir, "e:\\drm\\keys\\");
_LIT(KInputFilePattern, "e:\\drm\\keys\\SigningCert*");
#endif
#endif

_LIT(KLogDir, "drm");
_LIT(KLogName, "MtDrmKeyStorage.log");
_LIT(KDeviceKeyFileName, "DevicePrivateKey.der");
_LIT(KDeviceCertFileName, "DeviceCert.der");

#define TEST_STEP(string) \
    GLog.WriteFormat(_L("Next Test: %S"), &string);

#define CHECK(condition) \
    if (!condition) GLog.WriteFormat(_L("FAIL: line %d"), __LINE__);

// MODULE DATA STRUCTURES

RFs GFs;
RFileLogger GLog;

// STATIC TEST CONTENT AND RIGHTS OBJECTS

// LOCAL FUNCTION PROTOTYPES

// ==================== LOCAL FUNCTIONS ====================

LOCAL_C void ReadFileL(HBufC8*& aContent, const TDesC& aName)
    {
    TInt size = 0;
    RFile file;

    User::LeaveIfError(file.Open(GFs, aName, EFileRead));
    User::LeaveIfError(file.Size(size));
    aContent = HBufC8::NewLC(size);
    TPtr8 ptr(aContent->Des());
    User::LeaveIfError(file.Read(ptr, size));
    CleanupStack::Pop(); //aContent
    }


// ==================== TEST FUNCTIONS =====================

LOCAL_C TUint MDrmKeyStorage_ImportDataL()
    {
    MDrmKeyStorage* storage = NULL;
    HBufC8* privateKey = NULL;
    HBufC8* cert = NULL;
    RArray<TPtrC8> certChain;
    RPointerArray<HBufC8> buffers;
    TFileName fileName;
    TInt i;
    CDir* dir;
    TEntry entry;
    TUint fileCount = 0;

    storage = DrmKeyStorageNewL();

#ifndef RD_MULTIPLE_DRIVE

    GFs.SetSessionPath(KInputDir);

#else //RD_MULTIPLE_DRIVE

    TFileName tempPath;
    TInt driveNumber( -1 );
    TChar driveLetter;
    DriveInfo::GetDefaultDrive( DriveInfo::EDefaultMassStorage, driveNumber );
    GFs.DriveToChar( driveNumber, driveLetter );

    tempPath.Format( KInputDir, (TUint)driveLetter );

    GFs.SetSessionPath(tempPath);

#endif

    ReadFileL(privateKey, KDeviceKeyFileName);
    ReadFileL(cert, KDeviceCertFileName);
    buffers.Append(cert);

#ifndef RD_MULTIPLE_DRIVE

    GFs.GetDir(KInputFilePattern, KEntryAttNormal, ESortByName, dir);

#else //RD_MULTIPLE_DRIVE

    tempPath.Format( KInputFilePattern, (TUint)driveLetter );

    GFs.GetDir(tempPath, KEntryAttNormal, ESortByName, dir);

#endif

    for (i = 0; i < dir->Count(); i++)
        {
        ReadFileL(cert, (*dir)[i].iName);
        buffers.Append(cert);
        }
    for (i = 0; i < buffers.Count(); i++)
        {
        certChain.Append(*(buffers[i]));
        }
    storage->ImportDataL(*privateKey, certChain);
    delete storage;
    delete privateKey;
    fileCount = buffers.Count();
    certChain.Close();
    buffers.ResetAndDestroy();
    buffers.Close();
    return fileCount;
    }


TUint KeyStorage()
    {
    TUint result = 0;
    result = GFs.Connect();
    if( result != KErrNone )
        {
        return result;
        }

#ifndef RD_MULTIPLE_DRIVE

    GFs.MkDirAll(KFullLogDir);
    GFs.MkDirAll(KPrivateRightsDir);
    GFs.MkDirAll(KInputDir);

#else //RD_MULTIPLE_DRIVE

    TFileName tempPath;
    TInt driveNumber( -1 );
    TChar driveLetter;
    DriveInfo::GetDefaultDrive( DriveInfo::EDefaultSystem, driveNumber );
    GFs.DriveToChar( driveNumber, driveLetter );

    tempPath.Format( KFullLogDir, (TUint)driveLetter );
    GFs.MkDirAll(tempPath);

    tempPath.Format( KPrivateRightsDir, (TUint)driveLetter );
    GFs.MkDirAll(tempPath);

    DriveInfo::GetDefaultDrive( DriveInfo::EDefaultMassStorage, driveNumber );
    GFs.DriveToChar( driveNumber, driveLetter );

    tempPath.Format( KInputDir, (TUint)driveLetter );
    GFs.MkDirAll(tempPath);

#endif


    result = GLog.Connect();
    if( result != KErrNone )
        {
        GFs.Close();
        return result;
        }
    GLog.CreateLog(KLogDir, KLogName, EFileLoggingModeOverwrite);
    GLog.Write(_L("Start %D"));

    TRAPD(err,result = MDrmKeyStorage_ImportDataL());

    GLog.WriteFormat(_L("Result: %d"), err);
    CHECK(err == KErrNone);
    GLog.CloseLog();
    GFs.Close();
    return result;
    }

TUint KeyStorageFromZipL(const TDesC& aFileName, RFs& aFs)
    {
    RFile f;
    CZipFile* file;
    CZipFileMemberIterator* iter;
    CZipFileMember* member;
    MDrmKeyStorage* storage = NULL;
    TInt err = KErrNone;
    HBufC8* privateKey = NULL;
    HBufC8* cert = NULL;
    RArray<TPtrC8> certChain;
    TInt numCerts;
    TInt i;
    RZipFileMemberReaderStream* data;
    TPtr8 ptr(NULL, 0);
    TFileName fileName;
    RPointerArray<HBufC8> buffers;

    storage = DrmKeyStorageNewL();

    err = f.Open( aFs, aFileName, EFileShareReadersOrWriters | EFileRead );
    if ( err == KErrInUse )
        {
        err = f.Open( aFs, aFileName, EFileShareAny | EFileRead );
        if ( err == KErrInUse )
            {
            err = f.Open( aFs, aFileName, EFileShareReadersOnly| EFileRead );
            }
        }
    User::LeaveIfError( err );

    CleanupClosePushL<RFile>( f );
    file = CZipFile::NewL( aFs, f );
    CleanupStack::PushL( file );
    iter = file->GetMembersL();
    CleanupStack::PushL( iter );
    member = iter->NextL();
    numCerts = 0;
    while ( member != NULL )
        {
        if (member->Name()->Left(11).CompareF(_L("SigningCert")) == 0)
            {
            numCerts++;
            }
        delete member;
        member = iter->NextL();
        }

    member = file->CaseInsensitiveMemberL(_L("DeviceCert.der"));
    cert = HBufC8::NewL(member->UncompressedSize());
    buffers.Append(cert);
    file->GetInputStreamL(member, data);
    ptr.Set(cert->Des());
    data->Read(ptr, member->UncompressedSize());
    certChain.Append(ptr);
    delete data;
    delete member;
    for (i = 0; i < numCerts; i++)
        {
        fileName.Copy(_L("SigningCert"));
        if (i < 10)
            {
            fileName.Append(_L("0"));
            }
        fileName.AppendNum(i);
        fileName.Append(_L(".der"));
        member = file->CaseInsensitiveMemberL(fileName);
        cert = HBufC8::NewL(member->UncompressedSize());
        buffers.Append(cert);
        file->GetInputStreamL(member, data);
        ptr.Set(cert->Des());
        data->Read(ptr, member->UncompressedSize());
        certChain.Append(ptr);
        delete data;
        delete member;
        }
    member = file->CaseInsensitiveMemberL(_L("DevicePrivateKey.der"));
    privateKey = HBufC8::NewL(member->UncompressedSize());
    file->GetInputStreamL(member, data);
    ptr.Set(privateKey->Des());
    data->Read(ptr, member->UncompressedSize());
    delete data;
    delete member;

    storage->ImportDataL(*privateKey, certChain);
    delete privateKey;
    certChain.Close();
    buffers.ResetAndDestroy();

    CleanupStack::PopAndDestroy(3);
    delete storage;

    numCerts++;
    fileName.SetLength(0);
    fileName.AppendNum(numCerts);
    fileName.Append(_L(" keys imported"));
    CAknInformationNote* informationNote = new (ELeave) CAknInformationNote;
    informationNote->ExecuteLD(fileName);

    return KErrNone;
    }