1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/security/crypto/weakcryptospi/test/tpbe/tactionset.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,341 @@
1.4 +/*
1.5 +* Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
1.6 +* All rights reserved.
1.7 +* This component and the accompanying materials are made available
1.8 +* under the terms of the License "Eclipse Public License v1.0"
1.9 +* which accompanies this distribution, and is available
1.10 +* at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.11 +*
1.12 +* Initial Contributors:
1.13 +* Nokia Corporation - initial contribution.
1.14 +*
1.15 +* Contributors:
1.16 +*
1.17 +* Description:
1.18 +*
1.19 +*/
1.20 +
1.21 +
1.22 +#include <pbedata.h>
1.23 +#include <stdlib.h>
1.24 +#include <s32mem.h>
1.25 +#include <s32std.h>
1.26 +#include "tpbe.h"
1.27 +#include "tactionset.h"
1.28 +#include "t_input.h"
1.29 +
1.30 +_LIT8(KSetStart, "<set>");
1.31 +_LIT8(KSetEnd, "</set>");
1.32 +
1.33 +CTestAction* CActionSet::NewL(RFs& aFs,
1.34 + CConsoleBase& aConsole,
1.35 + Output& aOut,
1.36 + const TTestActionSpec& aTestActionSpec)
1.37 + {
1.38 + CTestAction* self = CActionSet::NewLC(aFs, aConsole,
1.39 + aOut, aTestActionSpec);
1.40 + CleanupStack::Pop();
1.41 + return self;
1.42 + }
1.43 +
1.44 +CTestAction* CActionSet::NewLC(RFs& aFs,
1.45 + CConsoleBase& aConsole,
1.46 + Output& aOut,
1.47 + const TTestActionSpec& aTestActionSpec)
1.48 + {
1.49 + CActionSet* self = new(ELeave) CActionSet(aFs, aConsole, aOut);
1.50 + CleanupStack::PushL(self);
1.51 + self->ConstructL(aTestActionSpec);
1.52 + return self;
1.53 + }
1.54 +
1.55 +CActionSet::~CActionSet()
1.56 + {
1.57 + delete iBody;
1.58 + }
1.59 +
1.60 +CActionSet::CActionSet(RFs& aFs,
1.61 + CConsoleBase& aConsole,
1.62 + Output& aOut)
1.63 +
1.64 +: CTestAction(aConsole, aOut), iFs(aFs)
1.65 + {
1.66 + }
1.67 +
1.68 +void CActionSet::ConstructL(const TTestActionSpec& aTestActionSpec)
1.69 + {
1.70 + CTestAction::ConstructL(aTestActionSpec);
1.71 + iBody = HBufC8::NewL(aTestActionSpec.iActionBody.Length());
1.72 + iBody->Des().Copy(aTestActionSpec.iActionBody);
1.73 +
1.74 + }
1.75 +
1.76 +void CActionSet::DoPerformPrerequisite(TRequestStatus& aStatus)
1.77 + {
1.78 + TRequestStatus* status = &aStatus;
1.79 + TInt err = KErrNone;
1.80 + TInt pos = 0;
1.81 + TPtrC8 encryptElement = Input::ParseElement(*iBody, KSetStart,
1.82 + KSetEnd, pos, err);
1.83 + TPtrC8 kdf = Input::ParseElement(*iBody, KKdfStart, KKdfEnd, pos=0, err);
1.84 + if (err == KErrNone)
1.85 + iKdf = kdf.AllocL();
1.86 +
1.87 + TPtrC8 saltLenBytes = Input::ParseElement(*iBody, KSaltLenBytesStart, KSaltLenBytesEnd, pos=0, err);
1.88 + if (err == KErrNone)
1.89 + iSaltLenBytes = saltLenBytes.AllocL();
1.90 +
1.91 + TPtrC8 iterCount = Input::ParseElement(*iBody, KIterCountStart, KIterCountEnd, pos=0, err);
1.92 + if (err == KErrNone)
1.93 + iIterCount = iterCount.AllocL();
1.94 +
1.95 + TPtrC8 passwdTemp = Input::ParseElement(encryptElement, KPasswdStart,
1.96 + KPasswdEnd, pos=0, err);
1.97 + iPasswd = HBufC::NewL(passwdTemp.Length());
1.98 + TPtr16 passwdTemp3( iPasswd->Des());
1.99 + passwdTemp3.Copy(passwdTemp);
1.100 +
1.101 + TPtrC8 inputTemp = Input::ParseElement(encryptElement, KInputStart,
1.102 + KInputEnd, pos=0, err);
1.103 + iInput = HBufC8::NewL(inputTemp.Length());
1.104 + *iInput = inputTemp;
1.105 +
1.106 + TPtrC8 cipher = Input::ParseElement(*iBody, KCipherStart, KCipherEnd);
1.107 + if (cipher.Compare(KECipherAES_CBC_128) == 0)
1.108 + {
1.109 + iCipher = ECipherAES_CBC_128;
1.110 + }
1.111 + else if (cipher.Compare(KECipherAES_CBC_192) == 0)
1.112 + {
1.113 + iCipher = ECipherAES_CBC_192;
1.114 + }
1.115 + else if (cipher.Compare(KECipherAES_CBC_256) == 0)
1.116 + {
1.117 + iCipher = ECipherAES_CBC_256;
1.118 + }
1.119 + else if (cipher.Compare(KECipherDES_CBC) == 0)
1.120 + {
1.121 + iCipher = ECipherDES_CBC;
1.122 + }
1.123 + else if (cipher.Compare(KECipher3DES_CBC) == 0)
1.124 + {
1.125 + iCipher = ECipher3DES_CBC;
1.126 + }
1.127 + else if (cipher.Compare(KECipherRC2_CBC_40) == 0)
1.128 + {
1.129 + iCipher = ECipherRC2_CBC_40;
1.130 + }
1.131 + else if (cipher.Compare(KECipherRC2_CBC_128) == 0)
1.132 + {
1.133 + iCipher = ECipherRC2_CBC_128;
1.134 + }
1.135 + else if (cipher.Compare(KECipherRC2_CBC_40_16) == 0)
1.136 + {
1.137 + iCipher = ECipherRC2_CBC_40_16;
1.138 + }
1.139 + else if (cipher.Compare(KECipherRC2_CBC_128_16) == 0)
1.140 + {
1.141 + iCipher = ECipherRC2_CBC_128_16;
1.142 + }
1.143 + else if(cipher.Compare(KECipher2Key3DES_CBC) == 0)
1.144 + {
1.145 + iCipher = ECipher2Key3DES_CBC;
1.146 + }
1.147 + else if(cipher.Compare(KECipherRC2_CBC_40_5) == 0)
1.148 + {
1.149 + iCipher = ECipherRC2_CBC_40_5;
1.150 + }
1.151 + else
1.152 + {
1.153 + iCipher = ECipherAES_CBC_128; // Default value if the <cipher> tag is missing
1.154 + }
1.155 +
1.156 + User::RequestComplete(status, KErrNone);
1.157 + iActionState = CTestAction::EAction;
1.158 + }
1.159 +
1.160 +void CActionSet::DoPerformPostrequisite(TRequestStatus& aStatus)
1.161 + {
1.162 + TRequestStatus* status = &aStatus;
1.163 + delete iPasswd;
1.164 + delete iInput;
1.165 + delete iKdf;
1.166 + iKdf = 0;
1.167 + delete iSaltLenBytes;
1.168 + iSaltLenBytes = 0;
1.169 + delete iIterCount;
1.170 + iIterCount = 0;
1.171 +
1.172 + iFinished = ETrue;
1.173 + User::RequestComplete(status, KErrNone);
1.174 + }
1.175 +
1.176 +void CActionSet::DoReportAction(void)
1.177 + {
1.178 + }
1.179 +
1.180 +void CActionSet::DoCheckResult(TInt)
1.181 + {
1.182 +
1.183 + }
1.184 +
1.185 +void CActionSet::PerformAction(TRequestStatus& aStatus)
1.186 + {
1.187 + __UHEAP_MARK;
1.188 + TRequestStatus* status = &aStatus;
1.189 + iResult = EFalse;
1.190 + HBufC8* pkcs12Pwd = 0;
1.191 +
1.192 + // default value is NULL to avoid RVCT warning
1.193 + // C2874W: set may be used before being set
1.194 + CPBEncryptSet* set = 0;
1.195 + if (iKdf == 0)
1.196 + {
1.197 + CleanupStack::PushL(pkcs12Pwd);
1.198 + set = CPBEncryptSet::NewLC(*iPasswd, iCipher);
1.199 + }
1.200 + else
1.201 + {
1.202 + // if supply KDF, must also supply salt len and iteration count
1.203 + ASSERT(iSaltLenBytes != 0 && iIterCount != 0);
1.204 +
1.205 + CPBEncryptParms* ep = CPBEncryptParms::NewLC();
1.206 +
1.207 + ep->SetCipherL(iCipher);
1.208 +
1.209 + TInt saltLenBytes;
1.210 + TInt r = TLex8(*iSaltLenBytes).Val(saltLenBytes);
1.211 + ASSERT(r == KErrNone);
1.212 + ep->ResizeSaltL(saltLenBytes);
1.213 +
1.214 + TInt iterCount;
1.215 + r = TLex8(*iIterCount).Val(iterCount);
1.216 + ASSERT(r == KErrNone);
1.217 + ep->SetIterations(iterCount);
1.218 +
1.219 + CleanupStack::PushL((CBase*)0);
1.220 + CleanupStack::Pop((CBase*)0);
1.221 +
1.222 + if (*iKdf == _L8("PKCS#5"))
1.223 + {
1.224 + ep->SetKdf(CPBEncryptParms::EKdfPkcs5);
1.225 + set = CPBEncryptSet::NewL(*iPasswd, *ep);
1.226 + }
1.227 + else if (*iKdf == _L8("PKCS#12"))
1.228 + {
1.229 + pkcs12Pwd = PKCS12KDF::GeneratePasswordLC(*iPasswd);
1.230 + ep->SetKdf(CPBEncryptParms::EKdfPkcs12);
1.231 + set = CPBEncryptSet::NewL(*pkcs12Pwd, *ep);
1.232 + CleanupStack::Pop(pkcs12Pwd);
1.233 + }
1.234 + else
1.235 + User::Panic(_L("Unrec KDF"), 0);
1.236 +
1.237 + CleanupStack::PopAndDestroy(ep);
1.238 + // encryption could leak here, but for reservation above
1.239 + CleanupStack::PushL(pkcs12Pwd);
1.240 + CleanupStack::PushL(set);
1.241 + }
1.242 + CPBEncryptor* encryptor = set->NewEncryptLC();
1.243 + HBufC8* ciphertextTemp = HBufC8::NewLC(encryptor->MaxFinalOutputLength(iInput->Length()));
1.244 +
1.245 + TPtr8 ciphertext = ciphertextTemp->Des();
1.246 + encryptor->ProcessFinalL(*iInput, ciphertext);
1.247 + TBuf<128> newPwdTemp(*iPasswd);
1.248 + newPwdTemp.Append('a');
1.249 +
1.250 + TBuf8<128> newPwdTemp8;
1.251 +
1.252 + TPBPassword newPassword(KNullDesC);
1.253 + if (pkcs12Pwd == 0)
1.254 + new(&newPassword) TPBPassword(newPwdTemp);
1.255 + else
1.256 + {
1.257 + HBufC8* newPwd = PKCS12KDF::GeneratePasswordLC(newPwdTemp);
1.258 + newPwdTemp8.Copy(*newPwd);
1.259 + new(&newPassword) TPBPassword(newPwdTemp8);
1.260 + CleanupStack::PopAndDestroy(newPwd);
1.261 + }
1.262 +
1.263 + set->ChangePasswordL(newPassword);
1.264 +
1.265 + //create a mem buffer store
1.266 + CBufStore* store = CBufStore::NewLC(100);
1.267 + RStoreWriteStream write;
1.268 +
1.269 + //write the encrypted master key to a stream
1.270 + TStreamId keyStreamId = write.CreateLC(*store);
1.271 + write << set->EncryptedMasterKey();
1.272 + write.CommitL();
1.273 + CleanupStack::PopAndDestroy(); //CreateLC()
1.274 +
1.275 + //write the encryption data to another stream
1.276 + TStreamId dataStreamId = write.CreateLC(*store);
1.277 + set->EncryptionData().ExternalizeL(write);
1.278 + write.CommitL();
1.279 + CleanupStack::PopAndDestroy(); //CreateLC()
1.280 +
1.281 + //prepare to read the streams back in, creating a new TPBEncryptionData
1.282 + RStoreReadStream read;
1.283 + read.OpenLC(*store, dataStreamId);
1.284 +
1.285 + //read in Encryption data
1.286 + CPBEncryptionData* data = CPBEncryptionData::NewL(read);
1.287 + CleanupStack::PopAndDestroy(); //OpenLC()
1.288 + CleanupStack::PushL(data);
1.289 +
1.290 + //read in encrypted master key
1.291 + read.OpenLC(*store, keyStreamId);
1.292 + HBufC8* encryptedMasterKey = HBufC8::NewLC(read, 10000); //some large number
1.293 +
1.294 + //create a new set encryption class
1.295 + CPBEncryptSet* set2 = CPBEncryptSet::NewLC(*data, *encryptedMasterKey, newPassword);
1.296 +
1.297 + HBufC8* plaintextTemp = HBufC8::NewLC(ciphertext.Length());
1.298 + TPtr8 plaintext = plaintextTemp->Des();
1.299 +
1.300 + CPBDecryptor* decryptor = set2->NewDecryptLC();
1.301 + decryptor->Process(ciphertext, plaintext);
1.302 +
1.303 + //this Mid call is due to get rid of the decrypted padding at the end
1.304 + if(plaintext.Mid(0,iInput->Length()) == *iInput)
1.305 + {
1.306 + iResult = ETrue;
1.307 + }
1.308 +
1.309 + CleanupStack::PopAndDestroy(decryptor);
1.310 + CleanupStack::PopAndDestroy(plaintextTemp);
1.311 + CleanupStack::PopAndDestroy(set2);
1.312 + CleanupStack::PopAndDestroy(encryptedMasterKey);
1.313 + CleanupStack::PopAndDestroy(1); //OpenLC
1.314 + CleanupStack::PopAndDestroy(data);
1.315 + CleanupStack::PopAndDestroy(store);
1.316 + CleanupStack::PopAndDestroy(ciphertextTemp);
1.317 + CleanupStack::PopAndDestroy(encryptor);
1.318 + CleanupStack::PopAndDestroy(set);
1.319 + CleanupStack::PopAndDestroy(pkcs12Pwd);
1.320 +
1.321 + User::RequestComplete(status, KErrNone);
1.322 + iActionState = CTestAction::EPostrequisite;
1.323 + __UHEAP_MARKEND;
1.324 + }
1.325 +
1.326 +void CActionSet::Hex(HBufC8& aString)
1.327 + {
1.328 + TPtr8 ptr=aString.Des();
1.329 + if (aString.Length()%2)
1.330 + {
1.331 + ptr.SetLength(0);
1.332 + return;
1.333 + }
1.334 + TInt i;
1.335 + for (i=0;i<aString.Length();i+=2)
1.336 + {
1.337 + TUint8 tmp;
1.338 + tmp=(TUint8)(aString[i]-(aString[i]>'9'?('A'-10):'0'));
1.339 + tmp*=16;
1.340 + tmp|=(TUint8)(aString[i+1]-(aString[i+1]>'9'?('A'-10):'0'));
1.341 + ptr[i/2]=tmp;
1.342 + }
1.343 + ptr.SetLength(aString.Length()/2);
1.344 + }