os/security/crypto/weakcryptospi/test/tpbe/tactionset.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 /*
     2 * Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
     3 * All rights reserved.
     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".
     8 *
     9 * Initial Contributors:
    10 * Nokia Corporation - initial contribution.
    11 *
    12 * Contributors:
    13 *
    14 * Description: 
    15 *
    16 */
    17 
    18 
    19 #include <pbedata.h>
    20 #include <stdlib.h>
    21 #include <s32mem.h>
    22 #include <s32std.h>
    23 #include "tpbe.h"
    24 #include "tactionset.h"
    25 #include "t_input.h"
    26 
    27 _LIT8(KSetStart, "<set>");
    28 _LIT8(KSetEnd, "</set>");
    29 
    30 CTestAction* CActionSet::NewL(RFs& aFs,
    31 									   CConsoleBase& aConsole,
    32 									   Output& aOut, 
    33 									   const TTestActionSpec& aTestActionSpec)
    34 	{
    35 	CTestAction* self = CActionSet::NewLC(aFs, aConsole,
    36 		aOut, aTestActionSpec);
    37 	CleanupStack::Pop();
    38 	return self;
    39 	}
    40 
    41 CTestAction* CActionSet::NewLC(RFs& aFs,
    42 										CConsoleBase& aConsole,
    43 										Output& aOut, 
    44 										const TTestActionSpec& aTestActionSpec)
    45 	{
    46 	CActionSet* self = new(ELeave) CActionSet(aFs, aConsole, aOut);
    47 	CleanupStack::PushL(self);
    48 	self->ConstructL(aTestActionSpec);
    49 	return self;
    50 	}
    51 
    52 CActionSet::~CActionSet()
    53 	{
    54 	delete iBody;
    55 	}
    56 
    57 CActionSet::CActionSet(RFs& aFs, 
    58 								 CConsoleBase& aConsole,
    59 								 Output& aOut)
    60 								 
    61 : CTestAction(aConsole, aOut), iFs(aFs)
    62 	{
    63 	}
    64 
    65 void CActionSet::ConstructL(const TTestActionSpec& aTestActionSpec)
    66 	{
    67 	CTestAction::ConstructL(aTestActionSpec);
    68 	iBody = HBufC8::NewL(aTestActionSpec.iActionBody.Length());
    69 	iBody->Des().Copy(aTestActionSpec.iActionBody);
    70 	
    71 	}
    72 
    73 void CActionSet::DoPerformPrerequisite(TRequestStatus& aStatus)
    74 	{
    75 	TRequestStatus* status = &aStatus;
    76 	TInt err = KErrNone;
    77 	TInt pos = 0;
    78 	TPtrC8 encryptElement = Input::ParseElement(*iBody, KSetStart,
    79 		KSetEnd, pos, err);
    80 	TPtrC8 kdf = Input::ParseElement(*iBody, KKdfStart, KKdfEnd, pos=0, err);
    81 	if (err == KErrNone)
    82 		iKdf = kdf.AllocL();
    83 	
    84 	TPtrC8 saltLenBytes = Input::ParseElement(*iBody, KSaltLenBytesStart, KSaltLenBytesEnd, pos=0, err);
    85 	if (err == KErrNone)
    86 		iSaltLenBytes = saltLenBytes.AllocL();
    87 	
    88 	TPtrC8 iterCount = Input::ParseElement(*iBody, KIterCountStart, KIterCountEnd, pos=0, err);
    89 	if (err == KErrNone)
    90 		iIterCount = iterCount.AllocL();
    91 	
    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);
    97 
    98 	TPtrC8 inputTemp = Input::ParseElement(encryptElement, KInputStart, 
    99 		KInputEnd, pos=0, err);
   100 	iInput = HBufC8::NewL(inputTemp.Length());
   101 	*iInput = inputTemp;
   102 
   103 	TPtrC8 cipher = Input::ParseElement(*iBody, KCipherStart, KCipherEnd);
   104 	if (cipher.Compare(KECipherAES_CBC_128) == 0)
   105 	{
   106 	   iCipher = ECipherAES_CBC_128;
   107 	}
   108 	else if (cipher.Compare(KECipherAES_CBC_192) == 0)
   109 	{
   110 	   iCipher = ECipherAES_CBC_192;
   111 	}
   112 	else if (cipher.Compare(KECipherAES_CBC_256) == 0)
   113 	{
   114 	   iCipher = ECipherAES_CBC_256;
   115 	}
   116 	else if (cipher.Compare(KECipherDES_CBC) == 0)
   117 	{
   118 	   iCipher = ECipherDES_CBC;
   119 	}
   120 	else if (cipher.Compare(KECipher3DES_CBC) == 0)
   121 	{
   122 	   iCipher = ECipher3DES_CBC;
   123 	}
   124 	else if (cipher.Compare(KECipherRC2_CBC_40) == 0)
   125 	{
   126 	   iCipher = ECipherRC2_CBC_40;
   127 	}
   128 	else if (cipher.Compare(KECipherRC2_CBC_128) == 0)
   129 	{
   130 	   iCipher = ECipherRC2_CBC_128;
   131 	}
   132 	else if (cipher.Compare(KECipherRC2_CBC_40_16) == 0)
   133 	{
   134 	   iCipher = ECipherRC2_CBC_40_16;
   135 	}
   136 	else if (cipher.Compare(KECipherRC2_CBC_128_16) == 0)
   137 	{
   138 	   iCipher = ECipherRC2_CBC_128_16;
   139 	}
   140 	else if(cipher.Compare(KECipher2Key3DES_CBC) == 0)
   141 	{
   142 		iCipher = ECipher2Key3DES_CBC;
   143 	}
   144 	else if(cipher.Compare(KECipherRC2_CBC_40_5) == 0)
   145 	{
   146 		iCipher = ECipherRC2_CBC_40_5;
   147 	}	
   148 	else
   149 	{
   150 	   iCipher = ECipherAES_CBC_128; // Default value if the <cipher> tag is missing
   151 	}
   152 
   153 	User::RequestComplete(status, KErrNone);
   154 	iActionState = CTestAction::EAction;
   155 	}
   156 
   157 void CActionSet::DoPerformPostrequisite(TRequestStatus& aStatus)
   158 	{
   159 	TRequestStatus* status = &aStatus;
   160 	delete iPasswd;
   161 	delete iInput;
   162 	delete iKdf;
   163 	iKdf = 0;
   164 	delete iSaltLenBytes;
   165 	iSaltLenBytes = 0;
   166 	delete iIterCount;
   167 	iIterCount = 0;
   168 
   169 	iFinished = ETrue;
   170 	User::RequestComplete(status, KErrNone);
   171 	}
   172 
   173 void CActionSet::DoReportAction(void)
   174 	{
   175 	}
   176 
   177 void CActionSet::DoCheckResult(TInt)
   178 	{
   179 
   180 	}
   181 
   182 void CActionSet::PerformAction(TRequestStatus& aStatus)
   183 	{
   184 	__UHEAP_MARK;
   185 	TRequestStatus* status = &aStatus;
   186 	iResult = EFalse;
   187 	HBufC8* pkcs12Pwd = 0;
   188 	
   189 	// default value is NULL to avoid RVCT warning
   190 	// C2874W: set may be used before being set
   191 	CPBEncryptSet* set = 0;
   192 	if (iKdf == 0)
   193 		{
   194 		CleanupStack::PushL(pkcs12Pwd);
   195  		set = CPBEncryptSet::NewLC(*iPasswd, iCipher);
   196  		}
   197 	else
   198 		{
   199 		// if supply KDF, must also supply salt len and iteration count
   200 		ASSERT(iSaltLenBytes != 0 && iIterCount != 0);
   201 		
   202 		CPBEncryptParms* ep = CPBEncryptParms::NewLC();
   203 		
   204 		ep->SetCipherL(iCipher);
   205 		
   206 		TInt saltLenBytes;
   207 		TInt r = TLex8(*iSaltLenBytes).Val(saltLenBytes);
   208 		ASSERT(r == KErrNone);
   209 		ep->ResizeSaltL(saltLenBytes);
   210 		
   211 		TInt iterCount;
   212 		r = TLex8(*iIterCount).Val(iterCount);
   213 		ASSERT(r == KErrNone);
   214 		ep->SetIterations(iterCount);
   215 		
   216 		CleanupStack::PushL((CBase*)0);
   217 		CleanupStack::Pop((CBase*)0);
   218 
   219 		if (*iKdf == _L8("PKCS#5"))
   220 			{
   221 			ep->SetKdf(CPBEncryptParms::EKdfPkcs5);
   222 			set = CPBEncryptSet::NewL(*iPasswd, *ep);
   223 			}
   224 		else if (*iKdf == _L8("PKCS#12"))
   225 			{
   226 			pkcs12Pwd = PKCS12KDF::GeneratePasswordLC(*iPasswd);
   227 			ep->SetKdf(CPBEncryptParms::EKdfPkcs12);
   228 			set = CPBEncryptSet::NewL(*pkcs12Pwd, *ep);
   229 			CleanupStack::Pop(pkcs12Pwd);
   230 			}
   231 		else
   232 			User::Panic(_L("Unrec KDF"), 0);
   233 		
   234 		CleanupStack::PopAndDestroy(ep);
   235 		// encryption could leak here, but for reservation above
   236 		CleanupStack::PushL(pkcs12Pwd);
   237 		CleanupStack::PushL(set);
   238 		}
   239 	CPBEncryptor* encryptor = set->NewEncryptLC();
   240 	HBufC8* ciphertextTemp = HBufC8::NewLC(encryptor->MaxFinalOutputLength(iInput->Length())); 
   241 
   242 	TPtr8 ciphertext = ciphertextTemp->Des();	
   243 	encryptor->ProcessFinalL(*iInput, ciphertext);
   244 	TBuf<128> newPwdTemp(*iPasswd);
   245 	newPwdTemp.Append('a');
   246 
   247 	TBuf8<128> newPwdTemp8;
   248 	
   249 	TPBPassword newPassword(KNullDesC);
   250 	if (pkcs12Pwd == 0)
   251 		new(&newPassword) TPBPassword(newPwdTemp);
   252 	else
   253 		{
   254 		HBufC8* newPwd = PKCS12KDF::GeneratePasswordLC(newPwdTemp);
   255 		newPwdTemp8.Copy(*newPwd);
   256 		new(&newPassword) TPBPassword(newPwdTemp8);
   257 		CleanupStack::PopAndDestroy(newPwd);
   258 		}
   259 
   260 	set->ChangePasswordL(newPassword);
   261 	
   262 	//create a mem  buffer store
   263 	CBufStore* store = CBufStore::NewLC(100);
   264 	RStoreWriteStream write;
   265 
   266 	//write the encrypted master key to a stream
   267 	TStreamId keyStreamId = write.CreateLC(*store);
   268 	write << set->EncryptedMasterKey();
   269 	write.CommitL();
   270 	CleanupStack::PopAndDestroy(); //CreateLC()
   271 
   272 	//write the encryption data to another stream
   273 	TStreamId dataStreamId = write.CreateLC(*store);
   274 	set->EncryptionData().ExternalizeL(write);
   275 	write.CommitL();
   276 	CleanupStack::PopAndDestroy(); //CreateLC()
   277 
   278 	//prepare to read the streams back in, creating a new TPBEncryptionData
   279 	RStoreReadStream read;
   280 	read.OpenLC(*store, dataStreamId);
   281 
   282 	//read in Encryption data
   283 	CPBEncryptionData* data = CPBEncryptionData::NewL(read);
   284 	CleanupStack::PopAndDestroy(); //OpenLC()
   285 	CleanupStack::PushL(data);
   286 
   287 	//read in encrypted master key
   288 	read.OpenLC(*store, keyStreamId);
   289 	HBufC8* encryptedMasterKey = HBufC8::NewLC(read, 10000); //some large number
   290 
   291 	//create a new set encryption class
   292 	CPBEncryptSet* set2 = CPBEncryptSet::NewLC(*data, *encryptedMasterKey, newPassword);
   293 
   294 	HBufC8* plaintextTemp = HBufC8::NewLC(ciphertext.Length());
   295 	TPtr8 plaintext = plaintextTemp->Des();	
   296 
   297 	CPBDecryptor* decryptor = set2->NewDecryptLC();
   298 	decryptor->Process(ciphertext, plaintext);
   299 
   300 	//this Mid call is due to get rid of the decrypted padding at the end
   301 	if(plaintext.Mid(0,iInput->Length()) == *iInput)
   302 		{
   303 		iResult = ETrue;			
   304 		}
   305 	
   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);
   317 	
   318 	User::RequestComplete(status, KErrNone);
   319 	iActionState = CTestAction::EPostrequisite;
   320 	__UHEAP_MARKEND;
   321 	}
   322 
   323 void CActionSet::Hex(HBufC8& aString)
   324     {
   325     TPtr8 ptr=aString.Des();
   326     if (aString.Length()%2)
   327         {
   328         ptr.SetLength(0);
   329         return;
   330         }
   331     TInt i;
   332     for (i=0;i<aString.Length();i+=2)
   333         {
   334         TUint8 tmp;
   335         tmp=(TUint8)(aString[i]-(aString[i]>'9'?('A'-10):'0'));
   336         tmp*=16;
   337         tmp|=(TUint8)(aString[i+1]-(aString[i+1]>'9'?('A'-10):'0'));
   338         ptr[i/2]=tmp;
   339         }
   340     ptr.SetLength(aString.Length()/2);
   341     }