diff -r 000000000000 -r 094583676ce7 wvsettings20/IMPSSrc/CIMPSSAPSecurer.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wvsettings20/IMPSSrc/CIMPSSAPSecurer.cpp Thu Dec 17 08:41:52 2009 +0200 @@ -0,0 +1,320 @@ +/* +* Copyright (c) 2005 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: IMPS SAP Settings Store implementation. +* +*/ + + +// INCLUDES +#include "CIMPSSAPSecurer.h" +#include "IMPSSAPSettingsStoreDefinitions.h" + +#include <3des.h> //3des encryption/decryption +#include // for getting the IMEI +#include +#include + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CIMPSSAPSecurer::CIMPSSAPSecurer +// C++ default constructor can NOT contain any code, that +// might leave. +// ----------------------------------------------------------------------------- +// +CIMPSSAPSecurer::CIMPSSAPSecurer() + { + } + +// ----------------------------------------------------------------------------- +// CIMPSSAPSecurer::ConstructL +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +// +void CIMPSSAPSecurer::ConstructL() + { + // Get the encryption key + iEncryptionKey = HBufC8::NewL( KSSS3DESKeySize ); + TPtr8 keyPtr( iEncryptionKey->Des() ); + GetPwdKeyL( keyPtr ); + + // Create encryptor and decryptor + iEncryptor = C3DESEncryptor::NewL( keyPtr ); + iDecryptor = C3DESDecryptor::NewL( keyPtr ); + + iTransformBlock = HBufC8::NewMaxL( iEncryptor->BlockSize() ); + } + +// ----------------------------------------------------------------------------- +// CIMPSSAPSecurer::NewL +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +CIMPSSAPSecurer* CIMPSSAPSecurer::NewL() + { + CIMPSSAPSecurer* self = new( ELeave ) CIMPSSAPSecurer(); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop(); + return self; + } + + +// Destructor +CIMPSSAPSecurer::~CIMPSSAPSecurer() + { + delete iTransformBlock; + delete iEncryptionKey; + delete iEncryptor; + delete iDecryptor; + } + +// ----------------------------------------------------------------------------- +// CIMPSSAPSecurer::EncryptPwdL() +// Encrypts password +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +HBufC* CIMPSSAPSecurer::EncryptPwdL( const TDesC& aPwdBuffer ) + { + HBufC* encrypted; + // first check for 0 length buffers + if ( aPwdBuffer.Length() == 0 ) + { + encrypted = HBufC::NewMaxL( 0 ); + return encrypted; + } + + // character for padding + TChar KPad( 0x00 ); + + TUint8* tempPtr = ( TUint8* ) aPwdBuffer.Ptr(); + TPtr8 buf( tempPtr, aPwdBuffer.Size(), aPwdBuffer.Size() ); + TInt bufSize = aPwdBuffer.Size(); + + const TInt blocksize = iEncryptor->BlockSize(); + const TInt remainder = bufSize % blocksize; + + // make the result buffer big enough for the padding ==> + // round upwards to next multiple of blocksize + if ( remainder == 0 ) + { + encrypted = HBufC::NewMaxLC( bufSize / 2 ); + } + else + { + encrypted = HBufC::NewMaxLC( ( bufSize + ( blocksize - remainder ) ) / 2 ); + } + + TUint8* tempEncPtr = ( TUint8* ) encrypted->Ptr(); + TPtr8 encPtr( tempEncPtr, NULL, encrypted->Des().MaxSize() ); + TPtr8 transformPtr( iTransformBlock->Des() ); + + TInt offset( 0 ); + while ( offset <= bufSize - blocksize ) + { + transformPtr = buf.Mid( offset, blocksize ); + iEncryptor->Transform( transformPtr ); + encPtr.Append( transformPtr ); + offset += blocksize; + } + + // Handle last block. If last block is not 8 characters long add padding + // nulls to end of it. + if ( remainder != 0 ) + { + transformPtr = buf.Mid( offset ); + transformPtr.AppendFill( KPad, blocksize - remainder ); + iEncryptor->Transform( transformPtr ); + encPtr.Append( transformPtr ); + } + + CleanupStack::Pop( encrypted ); + return encrypted; + } + +// ----------------------------------------------------------------------------- +// CIMPSSAPSecurer::DecryptPwdL() +// Decrypts password +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +HBufC* CIMPSSAPSecurer::DecryptPwdL( const TDesC& aPwdBuffer ) + { + HBufC* decrypted; + // first check for 0 length buffers + if ( aPwdBuffer.Length() == 0 ) + { + decrypted = HBufC::NewMaxL( 0 ); + return decrypted; + } + // character for padding + TChar KPad( 0x00 ); + + TUint8* tempPtr = ( TUint8* ) aPwdBuffer.Ptr(); + TPtr8 buf( tempPtr, aPwdBuffer.Size(), aPwdBuffer.Size() ); + TInt bufSize = aPwdBuffer.Size(); + + const TInt blocksize = iEncryptor->BlockSize(); + const TInt remainder = bufSize % blocksize; + + // make the result buffer big enough for the padding ==> + // round upwards to next multiple of blocksize + if ( remainder == 0 ) + { + decrypted = HBufC::NewMaxLC( bufSize / 2 ); + } + else + { + decrypted = HBufC::NewMaxLC( ( bufSize + ( blocksize - remainder ) ) / 2 ); + } + + TUint8* tempDecPtr = ( TUint8* ) decrypted->Ptr(); + TPtr8 decPtr( tempDecPtr, NULL, decrypted->Des().MaxSize() ); + TPtr8 transformPtr( iTransformBlock->Des() ); + + TInt offset( 0 ); + while ( offset <= bufSize - blocksize ) + { + transformPtr = buf.Mid( offset, blocksize ); + iDecryptor->Transform( transformPtr ); + decPtr.Append( transformPtr ); + offset += blocksize; + } + + // Remove padding nulls from end of the decrypted password + if ( remainder != 0 ) + { + transformPtr = buf.Mid( offset ); + transformPtr.AppendFill( KPad, blocksize - remainder ); + iDecryptor->Transform( transformPtr ); + decPtr.Append( transformPtr ); + } + + TInt padStart( decrypted->Des().Locate( KPad ) ); + if ( padStart != KErrNotFound ) + { + decrypted->Des().SetLength( padStart ); + } + + CleanupStack::Pop( decrypted ); + return decrypted; + } + +// ----------------------------------------------------------------------------- +// CIMPSSAPSecurer::FetchIMEI() +// +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CIMPSSAPSecurer::FetchIMEI( TPtr8& aImei ) + { + + // Create a fake serial number for emulator or for fallback if + // we're unable to get the real IMEI from hardware + TBuf fakeSerialNumber( KSAPFakeIMEI ); + aImei.Copy( fakeSerialNumber ); + + +#ifndef __WINS__ + RMobilePhone::TMobilePhoneIdentityV1 phoneIdentity; + // initializations + RMobilePhone phone; + RTelServer server; + + TRAPD( err, + { + err = server.Connect(); + User::LeaveIfError( err ); + CleanupClosePushL( server ); + + err = server.LoadPhoneModule( KMmTsyModuleName ); + if ( err != KErrNone && err != KErrAlreadyExists ) + { + User::Leave( err ); + } + err = phone.Open( server, KMmTsyPhoneName ); + User::LeaveIfError( err ); + CleanupClosePushL( phone ); + + TUint32 identityCaps; + err = phone.GetIdentityCaps( identityCaps ); + User::LeaveIfError( err ); + + if ( identityCaps & RMobilePhone::KCapsGetModel ) + { + TRequestStatus status; + phone.GetPhoneId( status, phoneIdentity ); + // No choice but to wait for the request to complete. + User::WaitForRequest( status ); // CSI: 94 # + User::LeaveIfError( status.Int() ); // CSI: 42 # + // Inside trap + } + else // In case we didn't have capabilities to get real IMEI + { + User::Leave( KErrNotSupported ); // CSI: 42 # + // Inside trap + } + + CleanupStack::PopAndDestroy( 2 ); // server, phone + } ); + + // Fetching the IMEI went fine. + if ( err == KErrNone ) + { + aImei.Copy( phoneIdentity.iSerialNumber ); + } + +#endif // __WINS__ + + } + + +// ----------------------------------------------------------------------------- +// CIMPSSAPSecurer::GetPwdKeyL() +// Generates new the encryption key +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +void CIMPSSAPSecurer::GetPwdKeyL( TPtr8& aKey ) + { + // Copy the defined key + aKey.Copy( KSAPPwdDefinedKey ); + + // Fetch the IMEI + HBufC8* imeiBuf = HBufC8::NewLC( RMobilePhone::KPhoneSerialNumberSize ); + TPtr8 imeiPtr = imeiBuf->Des(); + FetchIMEI( imeiPtr ); + + // XOR defined key with IMEI + TText8* character = ( TText8* ) aKey.Ptr(); + TText8* characterEnd = aKey.Length() + ( TText8* ) aKey.Ptr(); + TText8 asNumber; + + const TInt imeiLen = imeiPtr.Length(); + TInt encryptCharIndex = 0; + for ( ; character < characterEnd; character++ ) + { + asNumber = *character; + TInt imeiIndex( encryptCharIndex % imeiLen ); + asNumber ^= imeiPtr[ imeiIndex ]; + *character = asNumber; + + encryptCharIndex++; + } + + CleanupStack::PopAndDestroy( imeiBuf ); + } + + +// End of File