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