--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/omadrm/drmengine/keystorage/src/DrmStdKeyStorage.cpp Thu Dec 17 08:52:27 2009 +0200
@@ -0,0 +1,1178 @@
+/*
+* Copyright (c) 2002-2004 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: OMA DRM 2.0 Key Storage
+*
+*/
+
+
+// INCLUDE FILES
+#include <e32std.h>
+#include <asymmetric.h>
+#include <symmetric.h>
+#include <hash.h>
+#include <asn1dec.h>
+#include <x509cert.h>
+#include <etelmm.h>
+#include <mmtsy_names.h>
+
+#ifdef RD_MULTIPLE_DRIVE
+#include <DriveInfo.h>
+#endif
+
+#include "DrmKeyStorage.h"
+#include "DrmStdKeyStorage.h"
+
+#ifdef _DEBUG
+#define LOGGING
+#endif
+
+#ifdef LOGGING
+_LIT(KLogDir, "DRM");
+_LIT(KLogName, "KeyStorage.log");
+#include "flogger.h"
+#define LOG(string) \
+ RFileLogger::Write(KLogDir, KLogName, \
+ EFileLoggingModeAppend, string);
+#define LOGHEX(buffer) \
+ RFileLogger::HexDump(KLogDir, KLogName, \
+ EFileLoggingModeAppend, _S(""), _S(""), \
+ buffer.Ptr(), buffer.Length());
+#else
+#define LOG(string)
+#define LOGHEX(buffer)
+#endif
+
+#pragma message("Compiling DRM Std KeyStorage..")
+
+
+// LOCAL CONSTANTS AND MACROS
+
+const TInt KKeyLength = 128;
+const TInt KWaitingTime = 2000000; // 2 sec
+
+#ifdef RD_MULTIPLE_DRIVE
+_LIT(KKeyStoragePath, "%c:\\private\\101F51F2\\PKI\\");
+_LIT(KRomKeyStoragePath, "%c:\\private\\101F51F2\\PKI\\");
+
+#else
+_LIT(KKeyStoragePath, "c:\\private\\101F51F2\\PKI\\");
+_LIT(KRomKeyStoragePath, "z:\\private\\101F51F2\\PKI\\");
+#endif
+
+_LIT(KDeviceKeyFileName, "DevicePrivateKey.der");
+_LIT(KDeviceCertFileName, "DeviceCert.der");
+_LIT(KSingingCertFmt, "SigningCert%02d.der");
+_LIT(KSingingCertPattern, "SigningCert*");
+_LIT8(KDefaultKey, "0000000000000000");
+
+#ifdef RD_MULTIPLE_DRIVE
+_LIT(KSerialNumberFile, "%c:\\private\\101F51F2\\rdbserial.dat");
+_LIT(KUdtCertFileName, "%c:\\private\\101F51F2\\PKI\\UdtCertificate.der");
+#else
+_LIT(KSerialNumberFile, "c:\\private\\101F51F2\\rdbserial.dat");
+_LIT(KUdtCertFileName, "z:\\private\\101F51F2\\PKI\\UdtCertificate.der");
+#endif
+
+_LIT(KCmla, "CMLA");
+_LIT(KPadding, "\x0");
+
+NONSHARABLE_STRUCT( TUnloadModule )
+ {
+ RTelServer* iServer;
+ const TDesC* iName;
+ };
+
+
+// ============================ LOCAL FUNCTIONS ================================
+LOCAL_C void DoUnloadPhoneModule( TAny* aAny );
+
+LOCAL_C void WriteFileL(RFs& aFs, const TDesC& aName, const TDesC8& aData)
+ {
+ RFile file;
+
+ User::LeaveIfError(file.Replace(aFs, aName, EFileWrite));
+ User::LeaveIfError(file.Write(aData));
+ file.Close();
+ }
+
+LOCAL_C void ReadFileL(RFs& aFs, const TDesC& aName, HBufC8*& aContent)
+ {
+ RFile file;
+ TInt size = 0;
+
+ User::LeaveIfError(file.Open(aFs, aName, EFileRead));
+ CleanupClosePushL(file);
+ User::LeaveIfError(file.Size(size));
+ aContent = HBufC8::NewLC(size);
+ TPtr8 ptr(aContent->Des());
+ User::LeaveIfError(file.Read(ptr, size));
+ CleanupStack::Pop(); //aContent
+ CleanupStack::PopAndDestroy(); // file
+ }
+
+HBufC8* I2OSPL(
+ RInteger& aInt, TInt& aKeySize )
+ {
+ HBufC8* integer = aInt.BufferLC();
+ if (integer->Length() < aKeySize)
+ {
+ HBufC8* r = HBufC8::NewLC(aKeySize);
+ TPtr8 ptr(r->Des());
+ for(TInt i = integer->Length(); i < aKeySize; i++)
+ {
+ ptr.Append(KPadding());
+ }
+ ptr.Append(*integer);
+ CleanupStack::Pop(r);
+ CleanupStack::PopAndDestroy(integer);
+ return r;
+ }
+ else
+ {
+ CleanupStack::Pop(integer);
+ return integer;
+ }
+ }
+
+RInteger OS2IPL(
+ const TDesC8& aOctetStream)
+ {
+ RInteger r;
+ TInt i;
+
+ r = RInteger::NewL(0);
+ for (i = 0; i < aOctetStream.Length(); i++)
+ {
+ r *= 256;
+ r += aOctetStream[i];
+ }
+ return r;
+ }
+
+void DoUnloadPhoneModule( TAny* aAny )
+ {
+ __ASSERT_DEBUG( aAny, User::Invariant() );
+ TUnloadModule* module = ( TUnloadModule* ) aAny;
+ module->iServer->UnloadPhoneModule( *( module->iName ) );
+ }
+
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CDrmStdKeyStorage* CDrmStdKeyStorage::NewL
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CDrmStdKeyStorage* CDrmStdKeyStorage::NewL(RLibrary aLibrary)
+ {
+ CDrmStdKeyStorage* self = new (ELeave) CDrmStdKeyStorage(aLibrary);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop();
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CDrmStdKeyStorage::CDrmStdKeyStorage
+//
+// -----------------------------------------------------------------------------
+//
+CDrmStdKeyStorage::CDrmStdKeyStorage(RLibrary aLibrary):
+ iFileMan(NULL),
+ iRootSelected(EFalse),
+ iKey(NULL),
+ iImei(NULL),
+ iLibrary(aLibrary)
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CDrmStdKeyStorage::ConstructL
+//
+// -----------------------------------------------------------------------------
+//
+void CDrmStdKeyStorage::ConstructL()
+ {
+
+ LOG(_L("CDrmStdKeyStorage::ConstructL ->"));
+ User::LeaveIfError(iFs.Connect());
+ iFileMan = CFileMan::NewL(iFs);
+
+#ifdef __DRM_OMA2
+ SelectDefaultRootL();
+#endif
+
+ iDeviceSpecificKey.Copy(KDefaultKey);
+
+ LOG(_L("CDrmStdKeyStorage::ConstructL <-"));
+ }
+
+// -----------------------------------------------------------------------------
+// MDrmKeyStorage::~MDrmKeyStorage
+//
+// -----------------------------------------------------------------------------
+//
+
+MDrmKeyStorage::~MDrmKeyStorage()
+ {
+ }
+// -----------------------------------------------------------------------------
+// DrmStdKeyStorage::~CDrmStdKeyStorage
+//
+// -----------------------------------------------------------------------------
+//
+
+CDrmStdKeyStorage::~CDrmStdKeyStorage()
+ {
+ LOG(_L("CDrmStdKeyStorage::~CDrmStdKeyStorage ->"));
+ delete iFileMan;
+ delete iKey;
+ delete iImei; iImei = NULL;
+ iFs.Close();
+ //iLibrary.Close();
+ LOG(_L("CDrmStdKeyStorage::~CDrmStdKeyStorage <-"));
+ }
+
+// -----------------------------------------------------------------------------
+// DrmStdKeyStorage::ModulusSize
+//
+// -----------------------------------------------------------------------------
+//
+
+TInt CDrmStdKeyStorage::ModulusSize()
+ {
+ LOG(_L("CDrmStdKeyStorage::ModulusSize ->"));
+
+ if(iKey == NULL)
+ {
+ return KErrGeneral;
+ }
+ LOG(_L("CDrmStdKeyStorage::ModulusSize <-"));
+ return iKey->N().BitCount();
+ }
+
+// -----------------------------------------------------------------------------
+// DrmStdKeyStorage::SelectTrustedRootL
+//
+// -----------------------------------------------------------------------------
+//
+void CDrmStdKeyStorage::SelectTrustedRootL(
+ const TDesC8& aRootKeyHash)
+ {
+ TFileName fileName;
+ TEntry entry;
+ TInt i;
+
+ LOG(_L("CDrmStdKeyStorage::SelectTrustedRootL ->"));
+ LOG(aRootKeyHash);
+ if (aRootKeyHash.Length() != 0)
+ {
+
+#ifndef RD_MULTIPLE_DRIVE
+
+ fileName.Copy(KKeyStoragePath);
+
+#else //RD_MULTIPLE_DRIVE
+
+ TFileName tempPath;
+ TInt driveNumber( -1 );
+ TChar driveLetter;
+ DriveInfo::GetDefaultDrive( DriveInfo::EDefaultSystem, driveNumber );
+ iFs.DriveToChar( driveNumber, driveLetter );
+
+ tempPath.Format( KKeyStoragePath, (TUint)driveLetter );
+
+ fileName.Copy(tempPath);
+
+#endif
+
+ for (i = 0; i < SHA1_HASH; i++)
+ {
+ fileName.AppendNumFixedWidth(aRootKeyHash[i], EHex, 2);
+ }
+ fileName.Append('\\');
+ if (iFs.Entry(fileName, entry) != KErrNone)
+ {
+
+#ifndef RD_MULTIPLE_DRIVE
+
+ fileName.Copy(KRomKeyStoragePath);
+
+#else //RD_MULTIPLE_DRIVE
+
+ DriveInfo::GetDefaultDrive( DriveInfo::EDefaultRom, driveNumber );
+ iFs.DriveToChar( driveNumber, driveLetter );
+
+ tempPath.Format( KRomKeyStoragePath, (TUint)driveLetter );
+
+ fileName.Copy(tempPath);
+
+#endif
+
+ for (i = 0; i < SHA1_HASH; i++)
+ {
+ fileName.AppendNumFixedWidth(aRootKeyHash[i], EHex, 2);
+ }
+ fileName.Append('\\');
+ // check that the path exists
+ User::LeaveIfError(iFs.Entry(fileName, entry));
+ }
+ User::LeaveIfError(iFs.SetSessionPath(fileName));
+ InitializeKeyL();
+ CheckRootForCmlaL();
+ iRootSelected = ETrue;
+ }
+ else
+ {
+ SelectDefaultRootL();
+ }
+ LOG(_L("CDrmStdKeyStorage::SelectTrustedRootL <-"));
+ }
+
+// -----------------------------------------------------------------------------
+// DrmStdKeyStorage::SelectDefaultRootL
+//
+// -----------------------------------------------------------------------------
+//
+void CDrmStdKeyStorage::SelectDefaultRootL()
+ {
+ CDir* dir = NULL;
+ TFileName dirName;
+ TBool found = EFalse;
+
+ LOG(_L("CDrmStdKeyStorage::SelectDefaultRootL ->"));
+
+#ifndef RD_MULTIPLE_DRIVE
+
+ if (iFs.GetDir(KKeyStoragePath, KEntryAttDir, ESortByName, dir) == KErrNone)
+
+#else //RD_MULTIPLE_DRIVE
+
+ TFileName tempPath;
+ TInt driveNumber( -1 );
+ TChar driveLetter;
+ DriveInfo::GetDefaultDrive( DriveInfo::EDefaultSystem, driveNumber );
+ iFs.DriveToChar( driveNumber, driveLetter );
+
+ tempPath.Format( KKeyStoragePath, (TUint)driveLetter );
+
+ if (iFs.GetDir(tempPath, KEntryAttDir, ESortByName, dir) == KErrNone)
+
+#endif
+
+ {
+ __UHEAP_MARK;
+ LOG(_L(" Checking keys on C:"));
+ CleanupStack::PushL(dir);
+ if (dir->Count() >= 1)
+ {
+
+#ifndef RD_MULTIPLE_DRIVE
+
+ dirName.Copy(KKeyStoragePath);
+
+#else //RD_MULTIPLE_DRIVE
+
+ dirName.Copy(tempPath);
+
+#endif
+
+ dirName.Append((*dir)[0].iName);
+ dirName.Append('\\');
+ User::LeaveIfError(iFs.SetSessionPath(dirName));
+ found = ETrue;
+ }
+ CleanupStack::PopAndDestroy(dir);
+ __UHEAP_MARKEND;
+ }
+
+#ifndef RD_MULTIPLE_DRIVE
+
+ if (!found && iFs.GetDir(KRomKeyStoragePath, KEntryAttDir, ESortByName, dir) == KErrNone)
+
+#else //RD_MULTIPLE_DRIVE
+
+ DriveInfo::GetDefaultDrive( DriveInfo::EDefaultRom, driveNumber );
+ iFs.DriveToChar( driveNumber, driveLetter );
+
+ tempPath.Format( KRomKeyStoragePath, (TUint)driveLetter );
+
+ if (!found && iFs.GetDir(tempPath, KEntryAttDir, ESortByName, dir) == KErrNone)
+
+#endif
+ {
+ LOG(_L(" Checking keys on Z:"));
+ CleanupStack::PushL(dir);
+ if (dir->Count() < 1)
+ {
+ User::Leave(KErrGeneral);
+ }
+
+#ifndef RD_MULTIPLE_DRIVE
+
+ dirName.Copy(KRomKeyStoragePath);
+
+#else //RD_MULTIPLE_DRIVE
+
+ dirName.Copy(tempPath);
+
+#endif
+
+ dirName.Append((*dir)[0].iName);
+ dirName.Append('\\');
+ User::LeaveIfError(iFs.SetSessionPath(dirName));
+ CleanupStack::PopAndDestroy(dir);
+ found = ETrue;
+ }
+ if (!found)
+ {
+ User::Leave(KErrGeneral);
+ }
+ InitializeKeyL();
+ CheckRootForCmlaL();
+ iRootSelected = ETrue;
+ LOG(_L("CDrmStdKeyStorage::SelectDefaultRootL <-"));
+ }
+
+TBool CDrmStdKeyStorage::SelectedRootIsCmla()
+ {
+ return iRootIsCmla;
+ }
+
+// -----------------------------------------------------------------------------
+// DrmStdKeyStorage::GetTrustedRootsL
+//
+// -----------------------------------------------------------------------------
+//
+
+void CDrmStdKeyStorage::GetTrustedRootsL(
+ RPointerArray<HBufC8>& aRootList)
+ {
+ CDir* dir = NULL;
+ TInt i;
+ TInt j;
+ TBuf8<SHA1_HASH> hash;
+ TEntry entry;
+ TUint8 c;
+ TInt r = KErrNone;
+
+ LOG(_L("CDrmStdKeyStorage::GetTrustedRootsL ->"));
+ aRootList.ResetAndDestroy();
+
+#ifndef RD_MULTIPLE_DRIVE
+
+ if (iFs.GetDir(KKeyStoragePath, KEntryAttDir, ESortByName, dir) == KErrNone)
+
+#else //RD_MULTIPLE_DRIVE
+
+ TFileName tempPath;
+ TInt driveNumber( -1 );
+ TChar driveLetter;
+ DriveInfo::GetDefaultDrive( DriveInfo::EDefaultSystem, driveNumber );
+ iFs.DriveToChar( driveNumber, driveLetter );
+
+ tempPath.Format( KKeyStoragePath, (TUint)driveLetter );
+
+ if (iFs.GetDir(tempPath, KEntryAttDir, ESortByName, dir) == KErrNone)
+
+#endif
+ {
+ LOG(_L(" Getting roots on C:"));
+ CleanupStack::PushL(dir);
+ for (i = 0; i < dir->Count(); i++)
+ {
+ entry = (*dir)[i];
+ hash.SetLength(0);
+ LOG(entry.iName);
+ r = KErrNone;
+ for (j = 0; r == KErrNone && j < SHA1_HASH; j++)
+ {
+ TLex lex(entry.iName.Mid(j * 2, 2));
+ r = lex.Val(c, EHex);
+ hash.Append(c);
+ }
+ if (r == KErrNone)
+ {
+ aRootList.Append(hash.AllocL());
+ }
+ }
+ CleanupStack::PopAndDestroy(dir);
+ }
+
+#ifndef RD_MULTIPLE_DRIVE
+
+ if (iFs.GetDir(KRomKeyStoragePath, KEntryAttDir, ESortByName, dir) == KErrNone)
+
+#else //RD_MULTIPLE_DRIVE
+
+ DriveInfo::GetDefaultDrive( DriveInfo::EDefaultRom, driveNumber );
+ iFs.DriveToChar( driveNumber, driveLetter );
+
+ tempPath.Format( KRomKeyStoragePath, (TUint)driveLetter );
+
+ if (iFs.GetDir(tempPath, KEntryAttDir, ESortByName, dir) == KErrNone)
+
+#endif
+ {
+ LOG(_L(" Getting roots on Z:"));
+ CleanupStack::PushL(dir);
+ for (i = 0; i < dir->Count(); i++)
+ {
+ LOG(entry.iName);
+ entry = (*dir)[i];
+ hash.SetLength(0);
+ r = KErrNone;
+ for (j = 0; r == KErrNone && j < SHA1_HASH; j++)
+ {
+ TLex lex(entry.iName.Mid(j * 2, 2));
+ r = lex.Val(c, EHex);
+ hash.Append(c);
+ }
+ if (r == KErrNone)
+ {
+ aRootList.Append(hash.AllocL());
+ }
+ }
+ CleanupStack::PopAndDestroy(dir);
+ }
+ LOG(_L("CDrmStdKeyStorage::GetTrustedRootsL <-"));
+ }
+
+// -----------------------------------------------------------------------------
+// DrmStdKeyStorage::GetCertificateChainL
+//
+// -----------------------------------------------------------------------------
+//
+void CDrmStdKeyStorage::GetCertificateChainL(
+ RPointerArray<HBufC8>& aCertChain)
+ {
+ TFileName fileName;
+ TInt i;
+ CDir* dir = NULL;
+ HBufC8* cert = NULL;
+
+ LOG(_L("CDrmStdKeyStorage::GetCertificateChainL ->"));
+ if (!iRootSelected)
+ {
+ User::Leave(KErrGeneral);
+ }
+ aCertChain.ResetAndDestroy();
+ ReadFileL(iFs, KDeviceCertFileName, cert);
+ aCertChain.Append(cert);
+ iFs.GetDir(KSingingCertPattern, KEntryAttNormal, ESortByName, dir);
+ CleanupStack::PushL(dir);
+ for (i = 0; i < dir->Count(); i++)
+ {
+ ReadFileL(iFs, (*dir)[i].iName, cert);
+ aCertChain.AppendL(cert);
+ }
+ CleanupStack::PopAndDestroy(); // dir
+ LOG(_L("CDrmStdKeyStorage::GetCertificateChainL <-"));
+ }
+
+// -----------------------------------------------------------------------------
+// CDrmStdKeyStorage::RsaSignL
+// -----------------------------------------------------------------------------
+//
+HBufC8* CDrmStdKeyStorage::RsaSignL(
+ const TDesC8& aInput)
+ {
+ return ModularExponentiateWithKeyL(aInput);
+ }
+
+// -----------------------------------------------------------------------------
+// CDrmStdKeyStorage::RsaDecryptL
+// -----------------------------------------------------------------------------
+//
+HBufC8* CDrmStdKeyStorage::RsaDecryptL(
+ const TDesC8& aInput)
+ {
+ return ModularExponentiateWithKeyL(aInput);
+ }
+
+// -----------------------------------------------------------------------------
+// CDrmStdKeyStorage::ImportDataL
+// -----------------------------------------------------------------------------
+//
+void CDrmStdKeyStorage::ImportDataL(
+ const TDesC8& aPrivateKey,
+ const RArray<TPtrC8>& aCertificateChain)
+ {
+ TInt i;
+ TInt n;
+ HBufC8* publicKey = NULL;
+ CX509Certificate* cert = NULL;
+ CSHA1* hasher = NULL;
+ TBuf8<SHA1_HASH> publicKeyHash;
+ TFileName fileName;
+
+ LOG(_L("CDrmStdKeyStorage::ImportDataL ->"));
+ n = aCertificateChain.Count();
+ cert = CX509Certificate::NewLC(aCertificateChain[n - 1]);
+ publicKey = cert->DataElementEncoding(
+ CX509Certificate::ESubjectPublicKeyInfo)->AllocL();
+ CleanupStack::PushL(publicKey);
+ hasher = CSHA1::NewL();
+ CleanupStack::PushL(hasher);
+ hasher->Update(*publicKey);
+ publicKeyHash.Copy(hasher->Final());
+
+#ifndef RD_MULTIPLE_DRIVE
+
+ fileName.Copy(KKeyStoragePath);
+
+#else //RD_MULTIPLE_DRIVE
+
+ TInt driveNumber( -1 );
+ TChar driveLetter;
+ DriveInfo::GetDefaultDrive( DriveInfo::EDefaultSystem, driveNumber );
+ iFs.DriveToChar( driveNumber, driveLetter );
+
+ TFileName keyStorageDir;
+ keyStorageDir.Format( KKeyStoragePath, (TUint)driveLetter );
+
+ fileName.Copy(keyStorageDir);
+
+#endif
+
+ for (i = 0; i < SHA1_HASH; i++)
+ {
+ fileName.AppendNumFixedWidth(publicKeyHash[i], EHex, 2);
+ }
+ fileName.Append('\\');
+ iFileMan->Delete(fileName, CFileMan::ERecurse);
+ iFs.MkDirAll(fileName);
+ iFs.SetSessionPath(fileName);
+ WriteFileL(iFs, KDeviceKeyFileName, aPrivateKey);
+ fileName.Copy(fileName);
+ WriteFileL(iFs, KDeviceCertFileName, aCertificateChain[0]);
+ for (i = 1; i < n; i++)
+ {
+ fileName.SetLength(0);
+ fileName.AppendFormat(KSingingCertFmt, i - 1);
+ WriteFileL(iFs, fileName, aCertificateChain[i]);
+ }
+ CleanupStack::PopAndDestroy(3); // hasher, publicKey, cert
+ LOG(_L("CDrmStdKeyStorage::ImportDataL <-"));
+ }
+
+// -----------------------------------------------------------------------------
+// CDrmStdKeyStorage::GetDeviceSpecificKeyL
+// -----------------------------------------------------------------------------
+//
+void CDrmStdKeyStorage::GetDeviceSpecificKeyL(
+ TBuf8<KDeviceSpecificKeyLength>& aKey)
+ {
+
+ HBufC8* key = NULL;
+ TInt n;
+ CSHA1* hasher = NULL;
+ TBuf8<SHA1_HASH> hash;
+
+ if (iDeviceSpecificKey.Compare(KDefaultKey) == 0)
+ {
+
+ GetImeiL();
+
+ HBufC8* buf = HBufC8::NewLC( iImei->Size() + sizeof(VID_DEFAULT) );
+ TPtr8 ptr( buf->Des() );
+ ptr.Copy( *iImei );
+ ptr.Append(VID_DEFAULT);
+
+ hasher = CSHA1::NewL();
+ CleanupStack::PushL(hasher);
+ hasher->Update(ptr);
+ hash.Copy(hasher->Final());
+ key=hash.AllocL();
+ CleanupStack::PopAndDestroy(2,buf); // hasher,buf;
+
+ n = Min(key->Length(), KDeviceSpecificKeyLength);
+ iDeviceSpecificKey.Copy(key->Right(n));
+ delete key;
+ n = KDeviceSpecificKeyLength - n;
+ while (n > 0)
+ {
+ iDeviceSpecificKey.Append(0);
+ n--;
+ }
+ }
+
+ aKey.Copy(iDeviceSpecificKey);
+ }
+
+// -----------------------------------------------------------------------------
+// CDrmStdKeyStorage::InitializeKeyL
+// -----------------------------------------------------------------------------
+//
+void CDrmStdKeyStorage::InitializeKeyL()
+ {
+ HBufC8* key = NULL;
+ TASN1DecInteger encInt;
+ TInt pos = 0;
+
+ LOG(_L("CDrmStdKeyStorage::InitializeKeyL ->"));
+ delete iKey;
+ iKey = NULL;
+ ReadFileL(iFs, KDeviceKeyFileName, key);
+ CleanupStack::PushL(key);
+ TASN1DecGeneric gen(*key);
+ gen.InitL();
+ pos += gen.LengthDERHeader();
+ if (gen.Tag() != EASN1Sequence)
+ {
+ User::Leave(KErrArgument);
+ }
+ encInt.DecodeDERShortL(*key, pos); // version
+ RInteger modulus = encInt.DecodeDERLongL(*key, pos);
+ CleanupStack::PushL(modulus);
+ RInteger publicExponent = encInt.DecodeDERLongL(*key, pos);
+ CleanupStack::PushL(publicExponent);
+ RInteger privateExponent = encInt.DecodeDERLongL(*key, pos);
+ CleanupStack::PushL(privateExponent);
+ iKey = CRSAPrivateKeyStandard::NewL(modulus, privateExponent);
+ CleanupStack::Pop(); // privateExponent
+ CleanupStack::PopAndDestroy();// publicExponent
+ CleanupStack::Pop(); // modulus
+ CleanupStack::PopAndDestroy(); // key
+ LOG(_L("CDrmStdKeyStorage::InitializeKeyL <-"));
+ }
+
+// -----------------------------------------------------------------------------
+// CDrmStdKeyStorage::ModularExponentiateWithKeyL
+// -----------------------------------------------------------------------------
+//
+HBufC8* CDrmStdKeyStorage::ModularExponentiateWithKeyL(
+ const TDesC8& aInput)
+ {
+ RInteger result;
+ RInteger input;
+ HBufC8* output;
+ TInt keyLength = KKeyLength;
+
+ LOG(_L("CDrmStdKeyStorage::ModularExponentiateWithKeyL ->"));
+ input = OS2IPL(aInput);
+ CleanupClosePushL(input);
+ result = TInteger::ModularExponentiateL(input,iKey->D(), iKey->N());
+ CleanupClosePushL(result);
+ output = I2OSPL(result, keyLength);
+ CleanupStack::PopAndDestroy(2); // result, input
+ LOG(_L("CDrmStdKeyStorage::ModularExponentiateWithKeyL <-"));
+ return output;
+ }
+
+// -----------------------------------------------------------------------------
+// CDrmStdKeyStorage::CheckRootForCmlaL
+// -----------------------------------------------------------------------------
+//
+void CDrmStdKeyStorage::CheckRootForCmlaL()
+ {
+ CDir* dir = NULL;
+ HBufC8* buffer = NULL;
+ HBufC* name = NULL;
+ CX509Certificate* cert = NULL;
+
+ LOG(_L("CDrmStdKeyStorage::CheckRootForCmlaL ->"));
+ __UHEAP_MARK;
+ iFs.GetDir(KSingingCertPattern, KEntryAttNormal, ESortByName, dir);
+ CleanupStack::PushL(dir);
+ ReadFileL(iFs, (*dir)[dir->Count() - 1].iName, buffer);
+ CleanupStack::PushL(buffer);
+ cert = CX509Certificate::NewL(*buffer);
+ CleanupStack::PushL(cert);
+ name = cert->SubjectName().DisplayNameL();
+ CleanupStack::PushL(name);
+ if (name->Find(KCmla) != KErrNotFound)
+ {
+ iRootIsCmla = ETrue;
+ }
+ else
+ {
+ iRootIsCmla = EFalse;
+ }
+ CleanupStack::PopAndDestroy(4); // name, cert, buffer, dir
+ LOG(_L("CDrmStdKeyStorage::CheckRootForCmlaL <-"));
+ __UHEAP_MARKEND;
+ }
+
+// -----------------------------------------------------------------------------
+// CDrmStdKeyStorage::GetRdbSerialNumberL
+// -----------------------------------------------------------------------------
+//
+void CDrmStdKeyStorage::GetRdbSerialNumberL(
+ TBuf8<KRdbSerialNumberLength>& aSerialNumber)
+ {
+ HBufC8* buffer = NULL;
+ TUint att;
+
+#ifndef RD_MULTIPLE_DRIVE
+
+ if (iFs.Att(KSerialNumberFile, att) != KErrNone)
+
+#else //RD_MULTIPLE_DRIVE
+
+ TInt driveNumber( -1 );
+ TChar driveLetter;
+ DriveInfo::GetDefaultDrive( DriveInfo::EDefaultSystem, driveNumber );
+ iFs.DriveToChar( driveNumber, driveLetter );
+
+ TFileName serialNoFile;
+ serialNoFile.Format( KSerialNumberFile, (TUint)driveLetter );
+
+ if (iFs.Att(serialNoFile, att) != KErrNone)
+
+#endif
+ {
+ GenerateNewRdbSerialNumberL();
+ }
+
+#ifndef RD_MULTIPLE_DRIVE
+
+ ReadFileL(iFs, KSerialNumberFile, buffer);
+
+#else //RD_MULTIPLE_DRIVE
+
+ ReadFileL(iFs, serialNoFile, buffer);
+
+#endif
+
+ aSerialNumber.Copy(*buffer);
+ delete buffer;
+ }
+
+// -----------------------------------------------------------------------------
+// CDrmStdKeyStorage::GenerateNewRdbSerialNumberL
+// -----------------------------------------------------------------------------
+//
+void CDrmStdKeyStorage::GenerateNewRdbSerialNumberL()
+ {
+ TBuf8<KRdbSerialNumberLength> serialNumber;
+ TPtr8 random( const_cast<TUint8*>(serialNumber.Ptr()),
+ KRdbSerialNumberLength,
+ KRdbSerialNumberLength );
+
+ RandomDataGetL(random,KRdbSerialNumberLength);
+
+#ifndef RD_MULTIPLE_DRIVE
+
+ WriteFileL(iFs, KSerialNumberFile, random);
+
+#else //RD_MULTIPLE_DRIVE
+
+ TInt driveNumber( -1 );
+ TChar driveLetter;
+ DriveInfo::GetDefaultDrive( DriveInfo::EDefaultSystem, driveNumber );
+ iFs.DriveToChar( driveNumber, driveLetter );
+
+ TFileName serialNoFile;
+ serialNoFile.Format( KSerialNumberFile, (TUint)driveLetter );
+
+ WriteFileL(iFs, serialNoFile, random);
+
+#endif
+
+ }
+
+// -----------------------------------------------------------------------------
+// CDrmStdKeyStorage::UdtEncryptL
+// -----------------------------------------------------------------------------
+//
+HBufC8* CDrmStdKeyStorage::UdtEncryptL(
+ const TDesC8& aInput)
+ {
+ HBufC8* buffer = NULL;
+ HBufC8* output = HBufC8::NewMaxLC( 256 );
+ CX509Certificate* cert = NULL;
+ CRSAPublicKey* key = NULL;
+ TX509KeyFactory factory;
+ CRSAPKCS1v15Encryptor* encryptor = NULL;
+ TPtr8 result(const_cast<TUint8*>(output->Ptr()), 0, 256);
+
+#ifndef RD_MULTIPLE_DRIVE
+
+ ReadFileL(iFs, KUdtCertFileName, buffer);
+
+#else //RD_MULTIPLE_DRIVE
+
+ TInt driveNumber( -1 );
+ TChar driveLetter;
+ DriveInfo::GetDefaultDrive( DriveInfo::EDefaultRom, driveNumber );
+ iFs.DriveToChar( driveNumber, driveLetter );
+
+ TFileName udtCertFile;
+ udtCertFile.Format( KUdtCertFileName, (TUint)driveLetter );
+
+ ReadFileL(iFs, udtCertFile, buffer);
+
+#endif
+
+ CleanupStack::PushL(buffer);
+ cert = CX509Certificate::NewL(*buffer);
+ CleanupStack::PushL(cert);
+ key = factory.RSAPublicKeyL(cert->PublicKey().KeyData());
+ CleanupStack::PushL(key);
+
+ encryptor = CRSAPKCS1v15Encryptor::NewLC(*key);
+ encryptor->EncryptL(aInput, result);
+
+ CleanupStack::PopAndDestroy(4); // encryptor, key, cert, buffer
+ CleanupStack::Pop();// output
+ return output;
+ };
+
+// -----------------------------------------------------------------------------
+// CDrmStdKeyStorage::GetRootCertificatesL
+// -----------------------------------------------------------------------------
+//
+void CDrmStdKeyStorage::GetRootCertificatesL(
+ RPointerArray<HBufC8>& aRootCerts)
+ {
+ CDir* dir = NULL;
+ CDir* rootCerts = NULL;
+ TFileName dirName;
+ HBufC8* cert = NULL;
+ TInt i = 0;
+ TBuf<256> path;
+
+ iFs.SessionPath( path );
+
+#ifndef RD_MULTIPLE_DRIVE
+
+ if (iFs.GetDir(KKeyStoragePath, KEntryAttDir, ESortByName, dir) == KErrNone)
+
+#else //RD_MULTIPLE_DRIVE
+
+ TFileName tempPath;
+ TInt driveNumber( -1 );
+ TChar driveLetter;
+ DriveInfo::GetDefaultDrive( DriveInfo::EDefaultSystem, driveNumber );
+ iFs.DriveToChar( driveNumber, driveLetter );
+
+ tempPath.Format( KKeyStoragePath, (TUint)driveLetter );
+
+ if (iFs.GetDir(tempPath, KEntryAttDir, ESortByName, dir) == KErrNone)
+
+#endif
+ {
+ CleanupStack::PushL(dir);
+ for(i = 0; i < dir->Count(); i++)
+ {
+ if ((*dir)[i].IsDir())
+ {
+
+#ifndef RD_MULTIPLE_DRIVE
+
+ dirName.Copy(KKeyStoragePath);
+
+#else //RD_MULTIPLE_DRIVE
+
+ dirName.Copy(tempPath);
+
+#endif
+
+ dirName.Append((*dir)[i].iName);
+ dirName.Append('\\');
+ User::LeaveIfError(iFs.SetSessionPath(dirName));
+ User::LeaveIfError(iFs.GetDir(KSingingCertPattern, KEntryAttNormal, ESortByName, rootCerts));
+ CleanupStack::PushL(rootCerts);
+ ReadFileL(iFs, (*rootCerts)[rootCerts->Count() - 1].iName, cert);
+ CleanupStack::PushL(cert);
+ aRootCerts.AppendL(cert);
+ CleanupStack::Pop(cert);
+ CleanupStack::PopAndDestroy(); // rootCerts
+ }
+ }
+ CleanupStack::PopAndDestroy(dir);
+ }
+
+#ifndef RD_MULTIPLE_DRIVE
+
+ if (iFs.GetDir(KRomKeyStoragePath, KEntryAttDir, ESortByName, dir) == KErrNone)
+
+#else //RD_MULTIPLE_DRIVE
+
+ DriveInfo::GetDefaultDrive( DriveInfo::EDefaultRom, driveNumber );
+ iFs.DriveToChar( driveNumber, driveLetter );
+
+ tempPath.Format( KRomKeyStoragePath, (TUint)driveLetter );
+
+ if (iFs.GetDir(tempPath, KEntryAttDir, ESortByName, dir) == KErrNone)
+
+#endif
+ {
+ CleanupStack::PushL(dir);
+ for(i = 0; i < dir->Count(); i++)
+ {
+ if ((*dir)[i].IsDir())
+ {
+
+#ifndef RD_MULTIPLE_DRIVE
+
+ dirName.Copy(KRomKeyStoragePath);
+
+#else //RD_MULTIPLE_DRIVE
+
+ dirName.Copy(tempPath);
+
+#endif
+
+ dirName.Append((*dir)[i].iName);
+ dirName.Append('\\');
+ User::LeaveIfError(iFs.SetSessionPath(dirName));
+ User::LeaveIfError(iFs.GetDir(KSingingCertPattern, KEntryAttNormal, ESortByName, rootCerts));
+ CleanupStack::PushL(rootCerts);
+ ReadFileL(iFs, (*rootCerts)[rootCerts->Count() - 1].iName, cert);
+ CleanupStack::PushL(cert);
+ aRootCerts.AppendL(cert);
+ CleanupStack::Pop(cert);
+ CleanupStack::PopAndDestroy(); // rootCerts
+ }
+ }
+ CleanupStack::PopAndDestroy(dir);
+ }
+ iFs.SetSessionPath( path );
+ }
+
+// -----------------------------------------------------------------------------
+// CDrmStdKeyStorage::GetIMEIL
+// -----------------------------------------------------------------------------
+//
+const TDesC& CDrmStdKeyStorage::GetImeiL()
+ {
+ if ( iImei )
+ {
+ return *iImei;
+ }
+
+#if (defined __WINS__ || defined WINSCW)
+ // Default IMEI used for emulator
+ _LIT( KDefaultSerialNumber, "123456789123456789" );
+ iImei = KDefaultSerialNumber().AllocL();
+
+ return *iImei;
+#else
+
+ TInt error( KErrNone );
+ TInt count( 0 );
+ TInt count2( 0 );
+ TUint32 caps( 0 );
+ TBool found (EFalse);
+
+ RTelServer etelServer;
+ RMobilePhone phone;
+
+ TUint KMaxImeiTries = 5;
+
+ for ( TUint8 i = 0; i < KMaxImeiTries; ++i )
+ {
+ error = etelServer.Connect();
+ if ( error )
+ {
+ User::After( TTimeIntervalMicroSeconds32( KWaitingTime ) );
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ User::LeaveIfError( error );
+ CleanupClosePushL( etelServer );
+
+ User::LeaveIfError( etelServer.LoadPhoneModule( KMmTsyModuleName ) );
+
+ TUnloadModule unload;
+ unload.iServer = &etelServer;
+ unload.iName = &KMmTsyModuleName;
+
+ TCleanupItem item( DoUnloadPhoneModule, &unload );
+ CleanupStack::PushL( item );
+ User::LeaveIfError( etelServer.EnumeratePhones( count ) );
+
+ for ( count2 = 0; count2 < count && !found; ++count2 )
+ {
+ RTelServer::TPhoneInfo phoneInfo;
+ User::LeaveIfError( etelServer.GetTsyName( count2, phoneInfo.iName ) );
+
+ if ( phoneInfo.iName.CompareF(KMmTsyModuleName()) == 0 )
+ {
+ User::LeaveIfError( etelServer.GetPhoneInfo( count2, phoneInfo ) );
+ User::LeaveIfError( phone.Open( etelServer, phoneInfo.iName ) );
+ CleanupClosePushL( phone );
+ found = ETrue;
+ }
+ }
+
+ if ( !found )
+ {
+ // Not found.
+ User::Leave( KErrNotFound );
+ }
+
+ User::LeaveIfError( phone.GetIdentityCaps( caps ) );
+ if (!( caps & RMobilePhone::KCapsGetSerialNumber ))
+ {
+ User::Leave( KErrNotFound );
+ }
+
+ RMobilePhone::TMobilePhoneIdentityV1 id;
+ TRequestStatus status;
+
+ phone.GetPhoneId( status, id );
+
+ User::WaitForRequest( status );
+
+ User::LeaveIfError( status.Int() );
+
+ iImei = id.iSerialNumber.AllocL();
+
+ CleanupStack::PopAndDestroy( 3 ); // phone, item, etelServer
+
+ HBufC8* buf = HBufC8::NewL( iImei->Size() );
+ TPtr8 ptr( buf->Des() );
+ ptr.Copy( *iImei );
+
+ LOG(_L("IMEI:"));
+ LOGHEX(ptr);
+ delete buf;
+
+ return *iImei;
+#endif /* __WINS__ , WINSCW */
+
+ }
+
+
+// -----------------------------------------------------------------------------
+// CDrmStdKeyStorage::RandomDataGetL
+// -----------------------------------------------------------------------------
+//
+
+void CDrmStdKeyStorage::RandomDataGetL( TDes8& aData, const TInt aLength )
+ {
+ if ( aLength <= 0 )
+ {
+ User::Leave(KErrArgument);
+ }
+
+ TInt size = aData.MaxSize();
+
+ if( size < aLength )
+ {
+ User::Leave(KErrOverflow);
+ }
+
+ TRandom::Random( aData );
+ }
+
+// end of file