Update contrib.
2 * Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
4 * This component and the accompanying materials are made available
5 * under the terms of the License "Eclipse Public License v1.0"
6 * which accompanies this distribution, and is available
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
9 * Initial Contributors:
10 * Nokia Corporation - initial contribution.
24 #include "tactionset.h"
27 _LIT8(KSetStart, "<set>");
28 _LIT8(KSetEnd, "</set>");
30 CTestAction* CActionSet::NewL(RFs& aFs,
31 CConsoleBase& aConsole,
33 const TTestActionSpec& aTestActionSpec)
35 CTestAction* self = CActionSet::NewLC(aFs, aConsole,
36 aOut, aTestActionSpec);
41 CTestAction* CActionSet::NewLC(RFs& aFs,
42 CConsoleBase& aConsole,
44 const TTestActionSpec& aTestActionSpec)
46 CActionSet* self = new(ELeave) CActionSet(aFs, aConsole, aOut);
47 CleanupStack::PushL(self);
48 self->ConstructL(aTestActionSpec);
52 CActionSet::~CActionSet()
57 CActionSet::CActionSet(RFs& aFs,
58 CConsoleBase& aConsole,
61 : CTestAction(aConsole, aOut), iFs(aFs)
65 void CActionSet::ConstructL(const TTestActionSpec& aTestActionSpec)
67 CTestAction::ConstructL(aTestActionSpec);
68 iBody = HBufC8::NewL(aTestActionSpec.iActionBody.Length());
69 iBody->Des().Copy(aTestActionSpec.iActionBody);
73 void CActionSet::DoPerformPrerequisite(TRequestStatus& aStatus)
75 TRequestStatus* status = &aStatus;
78 TPtrC8 encryptElement = Input::ParseElement(*iBody, KSetStart,
80 TPtrC8 kdf = Input::ParseElement(*iBody, KKdfStart, KKdfEnd, pos=0, err);
84 TPtrC8 saltLenBytes = Input::ParseElement(*iBody, KSaltLenBytesStart, KSaltLenBytesEnd, pos=0, err);
86 iSaltLenBytes = saltLenBytes.AllocL();
88 TPtrC8 iterCount = Input::ParseElement(*iBody, KIterCountStart, KIterCountEnd, pos=0, err);
90 iIterCount = iterCount.AllocL();
92 TPtrC8 passwdTemp = Input::ParseElement(encryptElement, KPasswdStart,
93 KPasswdEnd, pos=0, err);
94 iPasswd = HBufC::NewL(passwdTemp.Length());
95 TPtr16 passwdTemp3( iPasswd->Des());
96 passwdTemp3.Copy(passwdTemp);
98 TPtrC8 inputTemp = Input::ParseElement(encryptElement, KInputStart,
99 KInputEnd, pos=0, err);
100 iInput = HBufC8::NewL(inputTemp.Length());
103 TPtrC8 cipher = Input::ParseElement(*iBody, KCipherStart, KCipherEnd);
104 if (cipher.Compare(KECipherAES_CBC_128) == 0)
106 iCipher = ECipherAES_CBC_128;
108 else if (cipher.Compare(KECipherAES_CBC_192) == 0)
110 iCipher = ECipherAES_CBC_192;
112 else if (cipher.Compare(KECipherAES_CBC_256) == 0)
114 iCipher = ECipherAES_CBC_256;
116 else if (cipher.Compare(KECipherDES_CBC) == 0)
118 iCipher = ECipherDES_CBC;
120 else if (cipher.Compare(KECipher3DES_CBC) == 0)
122 iCipher = ECipher3DES_CBC;
124 else if (cipher.Compare(KECipherRC2_CBC_40) == 0)
126 iCipher = ECipherRC2_CBC_40;
128 else if (cipher.Compare(KECipherRC2_CBC_128) == 0)
130 iCipher = ECipherRC2_CBC_128;
132 else if (cipher.Compare(KECipherRC2_CBC_40_16) == 0)
134 iCipher = ECipherRC2_CBC_40_16;
136 else if (cipher.Compare(KECipherRC2_CBC_128_16) == 0)
138 iCipher = ECipherRC2_CBC_128_16;
140 else if(cipher.Compare(KECipher2Key3DES_CBC) == 0)
142 iCipher = ECipher2Key3DES_CBC;
144 else if(cipher.Compare(KECipherRC2_CBC_40_5) == 0)
146 iCipher = ECipherRC2_CBC_40_5;
150 iCipher = ECipherAES_CBC_128; // Default value if the <cipher> tag is missing
153 User::RequestComplete(status, KErrNone);
154 iActionState = CTestAction::EAction;
157 void CActionSet::DoPerformPostrequisite(TRequestStatus& aStatus)
159 TRequestStatus* status = &aStatus;
164 delete iSaltLenBytes;
170 User::RequestComplete(status, KErrNone);
173 void CActionSet::DoReportAction(void)
177 void CActionSet::DoCheckResult(TInt)
182 void CActionSet::PerformAction(TRequestStatus& aStatus)
185 TRequestStatus* status = &aStatus;
187 HBufC8* pkcs12Pwd = 0;
189 // default value is NULL to avoid RVCT warning
190 // C2874W: set may be used before being set
191 CPBEncryptSet* set = 0;
194 CleanupStack::PushL(pkcs12Pwd);
195 set = CPBEncryptSet::NewLC(*iPasswd, iCipher);
199 // if supply KDF, must also supply salt len and iteration count
200 ASSERT(iSaltLenBytes != 0 && iIterCount != 0);
202 CPBEncryptParms* ep = CPBEncryptParms::NewLC();
204 ep->SetCipherL(iCipher);
207 TInt r = TLex8(*iSaltLenBytes).Val(saltLenBytes);
208 ASSERT(r == KErrNone);
209 ep->ResizeSaltL(saltLenBytes);
212 r = TLex8(*iIterCount).Val(iterCount);
213 ASSERT(r == KErrNone);
214 ep->SetIterations(iterCount);
216 CleanupStack::PushL((CBase*)0);
217 CleanupStack::Pop((CBase*)0);
219 if (*iKdf == _L8("PKCS#5"))
221 ep->SetKdf(CPBEncryptParms::EKdfPkcs5);
222 set = CPBEncryptSet::NewL(*iPasswd, *ep);
224 else if (*iKdf == _L8("PKCS#12"))
226 pkcs12Pwd = PKCS12KDF::GeneratePasswordLC(*iPasswd);
227 ep->SetKdf(CPBEncryptParms::EKdfPkcs12);
228 set = CPBEncryptSet::NewL(*pkcs12Pwd, *ep);
229 CleanupStack::Pop(pkcs12Pwd);
232 User::Panic(_L("Unrec KDF"), 0);
234 CleanupStack::PopAndDestroy(ep);
235 // encryption could leak here, but for reservation above
236 CleanupStack::PushL(pkcs12Pwd);
237 CleanupStack::PushL(set);
239 CPBEncryptor* encryptor = set->NewEncryptLC();
240 HBufC8* ciphertextTemp = HBufC8::NewLC(encryptor->MaxFinalOutputLength(iInput->Length()));
242 TPtr8 ciphertext = ciphertextTemp->Des();
243 encryptor->ProcessFinalL(*iInput, ciphertext);
244 TBuf<128> newPwdTemp(*iPasswd);
245 newPwdTemp.Append('a');
247 TBuf8<128> newPwdTemp8;
249 TPBPassword newPassword(KNullDesC);
251 new(&newPassword) TPBPassword(newPwdTemp);
254 HBufC8* newPwd = PKCS12KDF::GeneratePasswordLC(newPwdTemp);
255 newPwdTemp8.Copy(*newPwd);
256 new(&newPassword) TPBPassword(newPwdTemp8);
257 CleanupStack::PopAndDestroy(newPwd);
260 set->ChangePasswordL(newPassword);
262 //create a mem buffer store
263 CBufStore* store = CBufStore::NewLC(100);
264 RStoreWriteStream write;
266 //write the encrypted master key to a stream
267 TStreamId keyStreamId = write.CreateLC(*store);
268 write << set->EncryptedMasterKey();
270 CleanupStack::PopAndDestroy(); //CreateLC()
272 //write the encryption data to another stream
273 TStreamId dataStreamId = write.CreateLC(*store);
274 set->EncryptionData().ExternalizeL(write);
276 CleanupStack::PopAndDestroy(); //CreateLC()
278 //prepare to read the streams back in, creating a new TPBEncryptionData
279 RStoreReadStream read;
280 read.OpenLC(*store, dataStreamId);
282 //read in Encryption data
283 CPBEncryptionData* data = CPBEncryptionData::NewL(read);
284 CleanupStack::PopAndDestroy(); //OpenLC()
285 CleanupStack::PushL(data);
287 //read in encrypted master key
288 read.OpenLC(*store, keyStreamId);
289 HBufC8* encryptedMasterKey = HBufC8::NewLC(read, 10000); //some large number
291 //create a new set encryption class
292 CPBEncryptSet* set2 = CPBEncryptSet::NewLC(*data, *encryptedMasterKey, newPassword);
294 HBufC8* plaintextTemp = HBufC8::NewLC(ciphertext.Length());
295 TPtr8 plaintext = plaintextTemp->Des();
297 CPBDecryptor* decryptor = set2->NewDecryptLC();
298 decryptor->Process(ciphertext, plaintext);
300 //this Mid call is due to get rid of the decrypted padding at the end
301 if(plaintext.Mid(0,iInput->Length()) == *iInput)
306 CleanupStack::PopAndDestroy(decryptor);
307 CleanupStack::PopAndDestroy(plaintextTemp);
308 CleanupStack::PopAndDestroy(set2);
309 CleanupStack::PopAndDestroy(encryptedMasterKey);
310 CleanupStack::PopAndDestroy(1); //OpenLC
311 CleanupStack::PopAndDestroy(data);
312 CleanupStack::PopAndDestroy(store);
313 CleanupStack::PopAndDestroy(ciphertextTemp);
314 CleanupStack::PopAndDestroy(encryptor);
315 CleanupStack::PopAndDestroy(set);
316 CleanupStack::PopAndDestroy(pkcs12Pwd);
318 User::RequestComplete(status, KErrNone);
319 iActionState = CTestAction::EPostrequisite;
323 void CActionSet::Hex(HBufC8& aString)
325 TPtr8 ptr=aString.Des();
326 if (aString.Length()%2)
332 for (i=0;i<aString.Length();i+=2)
335 tmp=(TUint8)(aString[i]-(aString[i]>'9'?('A'-10):'0'));
337 tmp|=(TUint8)(aString[i+1]-(aString[i+1]>'9'?('A'-10):'0'));
340 ptr.SetLength(aString.Length()/2);