cryptoservices/certificateandkeymgmt/tx509/CorruptionTest.cpp
changeset 0 2c201484c85f
child 8 35751d3474b7
equal deleted inserted replaced
-1:000000000000 0:2c201484c85f
       
     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 "CorruptionTest.h"
       
    20 #include "SyntaxTest.h"
       
    21 #include "wtlscert.h"
       
    22 #include "t_output.h"
       
    23 #include "t_input.h"
       
    24 #include <random.h>
       
    25 #include <asymmetric.h>
       
    26 #include <bigint.h>
       
    27 
       
    28 TInt CCorruptionTest::nInstances = 0;
       
    29 _LIT(KCorruptLogFile, "X509CorruptLog.txt");
       
    30 _LIT(KPathStart, "<path>");
       
    31 _LIT(KIterationsStart, "<iterations>");
       
    32 
       
    33 //////////////////////////////////////////////////////////////////////
       
    34 // Construction/Destruction
       
    35 //////////////////////////////////////////////////////////////////////
       
    36 
       
    37 CTestAction* CCorruptionTest::NewL(RFs& aFs, CConsoleBase& aConsole, 
       
    38 		Output& aOut, const TTestActionSpec& aTestActionSpec)
       
    39 	{
       
    40 	CTestAction* self = CCorruptionTest::NewLC(aFs, aConsole, aOut, aTestActionSpec);
       
    41 	CleanupStack::Pop(self);
       
    42 	return self;
       
    43 	}
       
    44 
       
    45 CTestAction* CCorruptionTest::NewLC(RFs& aFs, CConsoleBase& aConsole, 
       
    46 		Output& aOut, const TTestActionSpec& aTestActionSpec)
       
    47 	{
       
    48 	CCorruptionTest* self = new(ELeave) CCorruptionTest(aFs, aConsole, aOut);
       
    49 	CleanupStack::PushL(self);
       
    50 	self->ConstructL(aTestActionSpec);
       
    51 	return self;
       
    52 	}
       
    53 
       
    54 CCorruptionTest::CCorruptionTest(RFs& aFs, 
       
    55 								 CConsoleBase& aConsole,
       
    56 								 Output& aOut)
       
    57 : CTestAction(aConsole, aOut), iFs(aFs)
       
    58 	{
       
    59 	nFileNumber = 0;
       
    60 	}
       
    61 
       
    62 CCorruptionTest::~CCorruptionTest(void)
       
    63 	{
       
    64 	delete iDirList;
       
    65 	delete iWriter;
       
    66 	iLogFile.Close();
       
    67 	delete iNullOut;
       
    68 	delete iCorruptOut;
       
    69 	};
       
    70 
       
    71 void CCorruptionTest::ConstructL(const TTestActionSpec& aTestActionSpec)
       
    72 	{
       
    73 	CTestAction::ConstructL(aTestActionSpec);
       
    74 
       
    75 	if(nInstances==0)
       
    76 		{
       
    77 		HBufC* body = HBufC::NewLC(aTestActionSpec.iActionBody.Length());
       
    78 		TInt pos=0;
       
    79 
       
    80 		nInstances++;
       
    81 		iNullOut = new(ELeave) NullOutput;
       
    82 		body->Des().Copy(aTestActionSpec.iActionBody);
       
    83 		TPtrC chainBuf = Input::ParseElement(*body, KPathStart, pos);
       
    84 		iPath.Copy(chainBuf);
       
    85 		TPtrC itertaionBuf = Input::ParseElement(*body, KIterationsStart, pos);
       
    86 		TLex itLex(itertaionBuf);
       
    87 
       
    88 		itLex.Val(iIterations);
       
    89 		CleanupStack::PopAndDestroy(); // body
       
    90 		User::LeaveIfError(iLogFile.Replace(iFs,KCorruptLogFile,EFileWrite));
       
    91 		iCorruptOut = new(ELeave) FileOutput(iLogFile);
       
    92 		iWriter = new(ELeave) CertWriter(iCorruptOut);
       
    93 		}
       
    94 	else
       
    95 		{
       
    96 		SetScriptError(ESyntax, _L("Only one corruption test can be run in each script"));
       
    97 		iFinished = ETrue;
       
    98 		}
       
    99 	}
       
   100 
       
   101 
       
   102 void CCorruptionTest::DoPerformPrerequisite(TRequestStatus& aStatus)
       
   103 	{
       
   104 	HBufC *searchPath = HBufC::NewLC(iPath.Size() + 1);
       
   105 	TPtr searchPathPtr(searchPath->Des());
       
   106 	searchPathPtr.Copy(iPath);
       
   107 	searchPathPtr.Append(_L("*"));
       
   108     TInt err = iFs.GetDir(searchPathPtr, KEntryAttMaskSupported, ESortByName, iDirList);
       
   109 	if (err != KErrNone)
       
   110 		{
       
   111 		iConsole.Printf(_L("Error getting directory "));
       
   112 		iConsole.Printf(searchPathPtr);
       
   113 		iConsole.Printf(_L("\n"));
       
   114 		iOut.writeString(_L("Error getting directory "));
       
   115 		iOut.writeString(searchPathPtr);
       
   116 		iOut.writeNewLine();
       
   117 		iFinished = ETrue;
       
   118 		TRequestStatus* status = &aStatus;
       
   119 		User::RequestComplete(status, KErrNone);
       
   120 		SetScriptError(EFileNotFound, searchPathPtr);
       
   121 		}
       
   122 	else
       
   123 		{
       
   124 		iConsole.Printf(_L("Please view "));
       
   125 		iConsole.Printf(KCorruptLogFile);
       
   126 		iConsole.Printf(_L(" for results\n"));
       
   127 		iOut.writeString(_L("Please view "));
       
   128 		iOut.writeString(KCorruptLogFile);
       
   129 		iOut.writeString(_L(" for results"));
       
   130 		iOut.writeNewLine();
       
   131 		iActionState = EAction;
       
   132 		TRequestStatus* status = &aStatus;
       
   133 		User::RequestComplete(status, KErrNone);
       
   134 		iResult = ETrue;
       
   135 		}
       
   136 	CleanupStack::PopAndDestroy();
       
   137 	}
       
   138 
       
   139 void CCorruptionTest::DoPerformPostrequisite(TRequestStatus& aStatus)
       
   140 	{
       
   141 	TRequestStatus* status = &aStatus;
       
   142 	iFinished = ETrue;
       
   143 	User::RequestComplete(status, KErrNone);
       
   144 	}
       
   145 
       
   146 void CCorruptionTest::RunCorruptionTestL(const TDesC &aFilename)
       
   147 	{
       
   148 	__UHEAP_MARK;
       
   149 	for (TInt i = 0; i < iIterations; i++)
       
   150 		{
       
   151 		HBufC8* buf = Input::ReadFileLC(aFilename, iPath, iFs);
       
   152 		TPtr8 pBuf = buf->Des();
       
   153 		TInt len = pBuf.Size();
       
   154 		TInt pos = 0;
       
   155 				//list of positions altered
       
   156 		HBufC* posOctsBuf = HBufC::NewLC(70);
       
   157 		TPtr pPosOctsBuf = posOctsBuf->Des();
       
   158 		pPosOctsBuf.SetLength(0);
       
   159 		pPosOctsBuf.Append(_L("p:"));
       
   160 				//list of octets altered
       
   161 		HBufC8* octsBuf = HBufC8::NewLC(40);
       
   162 		TPtr8 pOctsBuf = octsBuf->Des();
       
   163 		pOctsBuf.SetLength(0);
       
   164 
       
   165 		for (TInt j = 0; j < 10; j++)
       
   166 			{
       
   167 				//randomness
       
   168 			HBufC8* rand = HBufC8::NewLC(5);
       
   169 			TPtr8 pRand = rand->Des();
       
   170 			pRand.SetLength(5);
       
   171 			TRandom::RandomL(pRand);
       
   172 			TUint num = 0;
       
   173 			for (TInt k = 0; k < 4 ; k++)
       
   174 				{
       
   175 				num<<=8;
       
   176 				num+=pRand[k];
       
   177 				}
       
   178 			pos = num % len;
       
   179 			TUint8 newOctet = pRand[4];
       
   180 				//update output lines
       
   181 			pPosOctsBuf.AppendNum(pos);
       
   182 			pPosOctsBuf.Append(_L(" "));
       
   183 			pOctsBuf.Append(pBuf.Mid(pos, 1));
       
   184 			TPtrC8 pNewOct = pRand.Right(1);
       
   185 			pOctsBuf.Append(pNewOct);
       
   186 				//switch the selected octet
       
   187 			pBuf[pos] = newOctet;
       
   188 				//file out
       
   189 			iCorruptOut->writeString(pPosOctsBuf);
       
   190 			iCorruptOut->writeNewLine();
       
   191 			iCorruptOut->writeString(_L("o:"));
       
   192 			iCorruptOut->writeOctetString(pOctsBuf);
       
   193 			iCorruptOut->writeNewLine();
       
   194 				//try to make corrupt cert
       
   195 			CX509Certificate* cert = NULL;
       
   196 			TRAPD(err, cert = CX509Certificate::NewL(pBuf));
       
   197 			CleanupStack::PushL(cert);
       
   198 			if (err == KErrNone)
       
   199 				{
       
   200 				TBool res = EFalse;;
       
   201 			//	Don't bother attempting to verify if public key modulus is even
       
   202 			//	since CMontgomery methods will fail...	
       
   203 				TKeyFactory* theKeyFactory = new (ELeave) TX509KeyFactory();
       
   204 				CleanupStack::PushL(theKeyFactory);
       
   205 				CRSAPublicKey* key = theKeyFactory->RSAPublicKeyL(cert->PublicKey().KeyData());
       
   206 				CleanupStack::Pop(theKeyFactory);
       
   207 				delete theKeyFactory;
       
   208 				
       
   209 				const TInteger& theN = key->N();
       
   210 				if (theN.IsOdd())
       
   211 					{
       
   212 					RInteger input = RInteger::NewL(cert->Signature());
       
   213 					CleanupStack::PushL(input);
       
   214 				//	Check that the signature is not out of bounds for the key
       
   215 				//	Otherwise the crypto library will panic (descriptor out of bounds)
       
   216 					if ( (input < theN) && (input > 0) )
       
   217 						{
       
   218 						TRAP_IGNORE(res = cert->VerifySignatureL(cert->PublicKey().KeyData()));
       
   219 						if (res)
       
   220 							{
       
   221 							iCorruptOut->writeString(_L("!!!"));
       
   222 							iCorruptOut->writeNewLine();
       
   223 							}
       
   224 						}
       
   225 	
       
   226 						CleanupStack::PopAndDestroy(&input);
       
   227 					}
       
   228 
       
   229 					delete key;
       
   230 				}
       
   231 			iCorruptOut->writeString(_L("r:"));
       
   232 			iCorruptOut->writeNum(err);
       
   233 			iCorruptOut->writeNewLine();
       
   234 			CleanupStack::PopAndDestroy(2);// rand, cert
       
   235 			}
       
   236 		CleanupStack::PopAndDestroy(3);//
       
   237 		}
       
   238 	__UHEAP_MARKEND;
       
   239 	}
       
   240 
       
   241 //	These tests are very slow and do not need to be performed on every
       
   242 //	certificate in the x509 test directory.  Corrupt every 10th certificate.
       
   243 void CCorruptionTest::PerformAction(TRequestStatus& aStatus)
       
   244 	{
       
   245 	TBuf<256> filename = (*iDirList)[nFileNumber].iName;
       
   246 	TInt error;
       
   247 	
       
   248 	if( (filename.CompareF(KResultsFile)!=0) && (nFileNumber%10==0) )
       
   249 		{
       
   250 		iCorruptOut->writeString(_L("file:"));
       
   251 		iCorruptOut->writeString(filename);
       
   252 		iCorruptOut->writeNewLine();
       
   253 		iConsole.Printf(_L("file:%S\n"), &filename);
       
   254 		
       
   255 		TRAP(error, RunCorruptionTestL(filename));
       
   256 		if(error == KErrNoMemory)
       
   257 			User::Leave(error);
       
   258 		};
       
   259 
       
   260 	
       
   261 	if(++nFileNumber == iDirList->Count())
       
   262 		{
       
   263 		iActionState = EPostrequisite;
       
   264 		};
       
   265 	TRequestStatus* status = &aStatus;
       
   266 	User::RequestComplete(status, KErrNone);
       
   267 	}
       
   268 
       
   269 void CCorruptionTest::DoReportAction()
       
   270 	{
       
   271 	}
       
   272 
       
   273 void CCorruptionTest::DoCheckResult(TInt /*aError*/)
       
   274 	{
       
   275 	}
       
   276 
       
   277 HBufC8* CCorruptionTest::readCertLC(const TDesC& aFilename)
       
   278 	{
       
   279 	TFileName fullname;
       
   280 	fullname.Append(iPath);
       
   281 	fullname.Append(aFilename);
       
   282 
       
   283 	RFile file;
       
   284 	User::LeaveIfError( file.Open(iFs, fullname, EFileRead) );
       
   285 	
       
   286 	TInt size;
       
   287 	file.Size(size);
       
   288 	file.Close();
       
   289 
       
   290 	HBufC8* res = HBufC8::NewLC(size);
       
   291 	TPtr8 p(res->Des());
       
   292 	p.SetLength(size);
       
   293 
       
   294 	RFileReadStream stream;
       
   295 	User::LeaveIfError(stream.Open(iFs, fullname, EFileStream));
       
   296 	stream.ReadL(p, size);
       
   297 	stream.Close();
       
   298 	return res;
       
   299 	}