wvsettings20/IMPSSrc/CIMPSSAPSecurer.cpp
changeset 0 094583676ce7
--- /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	<etelmm.h> 		// for getting the IMEI
+#include	<mmtsy_names.h>
+#include 	<symmetric.h>
+
+// ============================ 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<RMobilePhone::KPhoneSerialNumberSize> 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