sl@0: /* sl@0: * Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: * All rights reserved. sl@0: * This component and the accompanying materials are made available sl@0: * under the terms of the License "Eclipse Public License v1.0" sl@0: * which accompanies this distribution, and is available sl@0: * at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: * sl@0: * Initial Contributors: sl@0: * Nokia Corporation - initial contribution. sl@0: * sl@0: * Contributors: sl@0: * sl@0: * Description: sl@0: * sl@0: */ sl@0: sl@0: sl@0: #include "tactionderivekey.h" sl@0: #include "t_input.h" sl@0: #include sl@0: #include sl@0: #include sl@0: sl@0: _LIT8(KKdfStart, ""); sl@0: _LIT8(KKdfEnd, ""); sl@0: _LIT8(KPKCS12Kdf, "pkcs#12"); sl@0: _LIT8(KDeriveKeyStart, ""); sl@0: _LIT8(KDeriveKeyEnd, ""); sl@0: _LIT8(KKeyStart, ""); sl@0: _LIT8(KKeyEnd, ""); sl@0: _LIT8(KPasswdStart, ""); sl@0: _LIT8(KPasswdEnd, ""); sl@0: _LIT8(KSaltStart, ""); sl@0: _LIT8(KSaltEnd, ""); sl@0: _LIT8(KIterationsStart, ""); sl@0: _LIT8(KIterationsEnd, ""); sl@0: _LIT8(KLeaveInPerformAction, ""); sl@0: _LIT8(KLeaveInPerformActionEnd, ""); sl@0: sl@0: CTestAction* CActionDeriveKey::NewL(RFs& aFs, sl@0: CConsoleBase& aConsole, sl@0: Output& aOut, sl@0: const TTestActionSpec& aTestActionSpec) sl@0: { sl@0: CTestAction* self = CActionDeriveKey::NewLC(aFs, aConsole, sl@0: aOut, aTestActionSpec); sl@0: CleanupStack::Pop(); sl@0: return self; sl@0: } sl@0: sl@0: CTestAction* CActionDeriveKey::NewLC(RFs& aFs, sl@0: CConsoleBase& aConsole, sl@0: Output& aOut, sl@0: const TTestActionSpec& aTestActionSpec) sl@0: { sl@0: CActionDeriveKey* self = new(ELeave) CActionDeriveKey(aFs, aConsole, aOut); sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(aTestActionSpec); sl@0: return self; sl@0: } sl@0: sl@0: CActionDeriveKey::~CActionDeriveKey() sl@0: { sl@0: delete iBody; sl@0: } sl@0: sl@0: CActionDeriveKey::CActionDeriveKey(RFs& aFs, sl@0: CConsoleBase& aConsole, sl@0: Output& aOut) sl@0: sl@0: : CTestAction(aConsole, aOut), iFs(aFs) sl@0: { sl@0: } sl@0: sl@0: void CActionDeriveKey::ConstructL(const TTestActionSpec& aTestActionSpec) sl@0: { sl@0: CTestAction::ConstructL(aTestActionSpec); sl@0: iBody = HBufC8::NewL(aTestActionSpec.iActionBody.Length()); sl@0: iBody->Des().Copy(aTestActionSpec.iActionBody); sl@0: } sl@0: sl@0: void CActionDeriveKey::DoPerformPrerequisite(TRequestStatus& aStatus) sl@0: { sl@0: TRequestStatus* status = &aStatus; sl@0: TInt err = KErrNone; sl@0: TInt pos = 0; sl@0: TPtrC8 deriveKey = Input::ParseElement(*iBody, KDeriveKeyStart, KDeriveKeyEnd, pos, err); sl@0: sl@0: // KDF is only explicitly specified for PKCS#12 derived keys sl@0: pos = 0; sl@0: TPtrC8 kdfTemp = Input::ParseElement(deriveKey, KKdfStart, KKdfEnd, pos, err); sl@0: if (err == KErrNone) sl@0: iKdf = kdfTemp.AllocL(); sl@0: sl@0: pos = 0; sl@0: TPtrC8 passwdTemp = Input::ParseElement(deriveKey, KPasswdStart, KPasswdEnd, pos, err); sl@0: iPasswd = HBufC8::NewL(passwdTemp.Length()); sl@0: *iPasswd = passwdTemp; sl@0: sl@0: pos = 0; sl@0: TPtrC8 iterationsTemp = Input::ParseElement(deriveKey, KIterationsStart, KIterationsEnd, pos, err); sl@0: iIterations = HBufC8::NewL(iterationsTemp.Length() + 1); //added 1 for the null zero used later sl@0: *iIterations = iterationsTemp; sl@0: sl@0: pos = 0; sl@0: TPtrC8 saltTemp = Input::ParseElement(deriveKey, KSaltStart, KSaltEnd, pos, err); sl@0: iSalt = HBufC8::NewL(saltTemp.Length()); sl@0: *iSalt = saltTemp; sl@0: Hex(*iSalt); sl@0: sl@0: pos = 0; sl@0: TPtrC8 keyTemp = Input::ParseElement(deriveKey, KKeyStart, KKeyEnd, pos, err); sl@0: iKey = HBufC8::NewL(keyTemp.Length()); sl@0: *iKey = keyTemp; sl@0: Hex(*iKey); sl@0: sl@0: iOutput = HBufC8::NewL(iKey->Length()); sl@0: sl@0: pos = 0; sl@0: iLeaveInPerformAction = Input::ParseIntElement(deriveKey, sl@0: KLeaveInPerformAction, KLeaveInPerformActionEnd, pos, err); sl@0: if (err) sl@0: { sl@0: iLeaveInPerformAction = 0; sl@0: } sl@0: User::RequestComplete(status, KErrNone); sl@0: iActionState = CTestAction::EAction; sl@0: } sl@0: sl@0: void CActionDeriveKey::DoPerformPostrequisite(TRequestStatus& aStatus) sl@0: { sl@0: TRequestStatus* status = &aStatus; sl@0: delete iKey; sl@0: delete iSalt; sl@0: delete iIterations; sl@0: delete iPasswd; sl@0: delete iOutput; sl@0: delete iKdf; sl@0: iKdf = 0; sl@0: sl@0: iFinished = ETrue; sl@0: User::RequestComplete(status, KErrNone); sl@0: } sl@0: sl@0: void CActionDeriveKey::DoReportAction(void) sl@0: { sl@0: } sl@0: sl@0: void CActionDeriveKey::DoCheckResult(TInt) sl@0: { sl@0: sl@0: } sl@0: sl@0: void CActionDeriveKey::PerformAction(TRequestStatus& aStatus) sl@0: { sl@0: TRequestStatus* status = &aStatus; sl@0: iResult = EFalse; sl@0: sl@0: if (iLeaveInPerformAction) sl@0: { sl@0: User::Leave(KErrArgument); sl@0: } sl@0: iOutput->Des().SetLength(iKey->Length()); sl@0: sl@0: TUint8* nptr= (TUint8*)(iIterations->Des().PtrZ()); sl@0: TUint32 i = strtoul((char*)nptr, 0, 10); sl@0: sl@0: iConsole.Printf(_L(".")); sl@0: TPtr8 outputActual = iOutput->Des(); sl@0: TPtr8 passwdActual = iPasswd->Des(); sl@0: if (iKdf != 0 && *iKdf == KPKCS12Kdf) sl@0: { sl@0: // convert the password to PKCS#12 password format sl@0: HBufC* pwdNative = HBufC::NewLC(iPasswd->Length()); sl@0: pwdNative->Des().Copy(*iPasswd); sl@0: HBufC8* pwdPKCS12 = PKCS12KDF::GeneratePasswordLC(*pwdNative); sl@0: PKCS12KDF::DeriveKeyL(outputActual, PKCS12KDF::EIDByteEncryptKey, *pwdPKCS12, *iSalt, i); sl@0: CleanupStack::PopAndDestroy(2, pwdNative); sl@0: } sl@0: else // PKCS#5 sl@0: { sl@0: TPtr8 saltActual = iSalt->Des(); sl@0: TPKCS5KDF::DeriveKeyL(outputActual, passwdActual, saltActual,i); sl@0: } sl@0: sl@0: if(*iOutput == *iKey) sl@0: { sl@0: iResult = ETrue; sl@0: } sl@0: sl@0: User::RequestComplete(status, KErrNone); sl@0: iActionState = CTestAction::EPostrequisite; sl@0: } sl@0: sl@0: void CActionDeriveKey::Hex(HBufC8& aString) sl@0: /** sl@0: Convert the supplied hex string into the binary equivalent. sl@0: sl@0: @param aString Hex string. On entry this contains sl@0: a sequence of hexadecimal characters, sl@0: e.g., "3037AFC8EA". On exit it is sl@0: half the original length and each two-digit sl@0: hex number is reduced to the matching sl@0: byte value. sl@0: */ sl@0: { sl@0: TPtr8 ptr=aString.Des(); sl@0: if (aString.Length()%2) sl@0: { sl@0: ptr.SetLength(0); sl@0: return; sl@0: } sl@0: TInt i; sl@0: for (i=0;i'9'?('A'-10):'0')); sl@0: tmp*=16; sl@0: tmp|=(TUint8)(aString[i+1]-(aString[i+1]>'9'?('A'-10):'0')); sl@0: ptr[i/2]=tmp; sl@0: } sl@0: ptr.SetLength(aString.Length()/2); sl@0: } sl@0: