diff -r 000000000000 -r 2c201484c85f cryptoservices/certificateandkeymgmt/tx509/extensiontest.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cryptoservices/certificateandkeymgmt/tx509/extensiontest.cpp Wed Jul 08 11:25:26 2009 +0100 @@ -0,0 +1,434 @@ +/* +* Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +#include "x509constraintext.h" +#include "extensiontest.h" +#include "t_input.h" + +_LIT(KFileNameStart, ""); +_LIT(KExpectedDeviceIdList, ""); +_LIT(KExpectedDevice, ""); +_LIT(KExpectedSidList, ""); +_LIT(KExpectedSid, ""); +_LIT(KExpectedVidList, ""); +_LIT(KExpectedVid, ""); +_LIT(KExpectedCapabilities, ""); +_LIT(KCorrupt, ""); +_LIT(KMatch, ""); + +CTestAction* CExtensionTest::NewL(RFs& aFs, CConsoleBase& aConsole, + Output& aOut, const TTestActionSpec& aTestActionSpec) + { + CTestAction* self = CExtensionTest::NewLC(aFs, aConsole, aOut, aTestActionSpec); + CleanupStack::Pop(self); + return self; + } + +CTestAction* CExtensionTest::NewLC(RFs& aFs, CConsoleBase& aConsole, + Output& aOut, const TTestActionSpec& aTestActionSpec) + { + CExtensionTest* self = new(ELeave) CExtensionTest(aFs, aConsole, aOut); + CleanupStack::PushL(self); + self->ConstructL(aTestActionSpec); + return self; + } + +CExtensionTest::CExtensionTest(RFs& aFs, CConsoleBase& aConsole, Output& aOut) + : CTestAction(aConsole, aOut), + iFs(aFs) + { + } + +CExtensionTest::~CExtensionTest() + { + iExpectedDeviceIdList.ResetAndDestroy(); + iExpectedDeviceIdList.Close(); + iExpectedSidList.Close(); + iExpectedVidList.Close(); + } + +void CExtensionTest::ConstructL(const TTestActionSpec& aTestActionSpec) + { + CTestAction::ConstructL(aTestActionSpec); + TInt startPos = 0; + TInt err = 0; + + HBufC* aBody = HBufC::NewLC(aTestActionSpec.iActionBody.Length()); + aBody->Des().Copy(aTestActionSpec.iActionBody); + + // Filename of the certificate file + TPtrC fileNameStart = Input::ParseElement(*aBody, KFileNameStart); + iCertFileName.Copy(fileNameStart); + + // Whether we expect at least on of the extensions to be corrupt + TPtrC corruptStart = Input::ParseElement(*aBody, KCorrupt); + if (corruptStart.CompareF(_L("True")) == 0) + { + iExpectedCorrupt = ETrue; + } + + // We expect the certificate to match the constraints + TPtrC matchStart = Input::ParseElement(*aBody, KMatch); + if (matchStart.CompareF(_L("True")) == 0) + { + iExpectedMatch = ETrue; + } + + // Extract the lists of constraints that are expected to be present + startPos = 0; + TPtrC deviceListStart = Input::ParseElement(*aBody, KExpectedDeviceIdList, startPos, err); + if (err >= 0) + { + BuildStringListL(iExpectedDeviceIdList, deviceListStart, KExpectedDevice); + iDeviceIdsPresent = ETrue; + } + + startPos = 0; + TPtrC sidListStart = Input::ParseElement(*aBody, KExpectedSidList, startPos, err); + if (err >= 0) + { + BuildIntList(iExpectedSidList, sidListStart, KExpectedSid); + iSidsPresent = ETrue; + } + + startPos = 0; + TPtrC vidListStart = Input::ParseElement(*aBody, KExpectedVidList, startPos, err); + if (err >= 0) + { + BuildIntList(iExpectedVidList, vidListStart, KExpectedVid); + iVidsPresent = ETrue; + } + + startPos = 0; + TPtrC capabilities = Input::ParseElement(*aBody, KExpectedCapabilities, startPos, err); + if (err >= 0) + { + BuildCapabilitySet(iExpectedCapabilities, capabilities); + iCapabilitiesPresent = ETrue; + } + + CleanupStack::PopAndDestroy(aBody); + } + +void CExtensionTest::BuildStringListL(RPointerArray& aStrings, const TDesC& aBuf, const TDesC& aTag) + { + TInt pos = 0; + TInt err = 0; + do + { + // Find next value for the specified tag and add it to the string array + // if it exists. + TPtrC str = Input::ParseElement(aBuf, aTag, pos, err); + if (err >= 0) + { + aStrings.Append(str.AllocL()); + } + } + while (err >= 0); + } + +void CExtensionTest::BuildIntList(RArray& aInts, const TDesC& aBuf, const TDesC& aTag) + { + TInt pos = 0; + TInt err = 0; + do + { + // Attempt to convert the contents of val to an int and store in + // the aInts array if it is a valid integer. + TInt n = Input::ParseIntElement(aBuf, aTag, pos, err); + if (err >= 0) + { + aInts.Append(n); + } + } + while (err >= 0); + } + +void CExtensionTest::BuildCapabilitySet(TCapabilitySet& aCapabilitySet, const TDesC& aBuf) + { + aCapabilitySet.SetEmpty(); + TUint length = aBuf.Length(); + for (TUint i = 0; i < length && i < ECapability_Limit; i++) + { + if (aBuf[i] == '1') + { + aCapabilitySet.AddCapability(static_cast(i)); + } + } + } + +void CExtensionTest::PerformAction(TRequestStatus& aStatus) + { + HBufC8* buf = NULL; + TInt err = KErrNone; + + TRAP(err, buf = Input::ReadFileL(iCertFileName, iFs)); + if (err == KErrNotFound) + { + iResult = EFalse; + iFinished = ETrue; + SetScriptError(EFileNotFound, iCertFileName); + TRequestStatus* status = &aStatus; + iActionState = EPostrequisite; + User::RequestComplete(status, KErrNone); + return; + } + else if (err != KErrNone) + { + User::Leave(err); + } + + CleanupStack::PushL(buf); + CX509Certificate* cert = CX509Certificate::NewLC(buf->Des()); + + Print(_L("Checking certificate extensions in file ")); + PrintLine(iCertFileName); + + TBool match = EFalse; + TBool corrupt = EFalse; + CheckExtensionsL(*cert, match, corrupt); + if (corrupt) + { + iResult = iExpectedCorrupt; + if (!iResult) + { + Print(_L("Found unexpected corrupt extension.")); + } + } + else + { + // no error. test whether the certificate matched the + // test script. + iResult = (match == iExpectedMatch); + } + CleanupStack::PopAndDestroy(2, buf); // cert, buf + + TRequestStatus* status = &aStatus; + iActionState = EPostrequisite; + User::RequestComplete(status, KErrNone); + } + +void CExtensionTest::CheckExtensionsL(const CX509Certificate& cert, + TBool& match, TBool& corrupt) + { + TInt err = KErrNone; + + match = ETrue; + corrupt = EFalse; + + TRAP(err, match &= CheckDeviceIdListL(cert)); + if (err == KErrArgument) + { + PrintLine(_L("The device id constraint is corrupt.")); + corrupt = ETrue; + } + else if (err != KErrNone) + { + User::Leave(err); + } + + TRAP(err, match &= CheckSidListL(cert)); + if (err == KErrArgument) + { + PrintLine(_L("The secure id constraint is corrupt.")); + corrupt = ETrue; + } + else if (err != KErrNone) + { + User::Leave(err); + } + + TRAP(err, match &= CheckVidListL(cert)); + if (err == KErrArgument) + { + PrintLine(_L("The vendor id constraint is corrupt.")); + corrupt = ETrue; + } + else if (err != KErrNone) + { + User::Leave(err); + } + + TRAP(err, match &= CheckCapabilitiesL(cert)); + if (err == KErrArgument) + { + PrintLine(_L("The capabilities constraint is corrupt.")); + corrupt = ETrue; + } + else if (err != KErrNone) + { + User::Leave(err); + } + } + +TBool CExtensionTest::CheckDeviceIdListL(const CX509Certificate& cert) + { + TBool match = ETrue; + const CX509CertExtension* ext = cert.Extension(KDeviceIdListConstraint); + if (ext) + { + // use NewL because this covers NewLC as well + CX509Utf8StringListExt* stringListExt = CX509Utf8StringListExt::NewL(ext->Data()); + CleanupStack::PushL(stringListExt); + if (! IsEqual(stringListExt->StringArray(), iExpectedDeviceIdList)) + { + PrintLine(_L("Device Id list is different.")); + match = EFalse; + } + CleanupStack::PopAndDestroy(stringListExt); + } + else if (iDeviceIdsPresent) + { + PrintLine(_L("Device Id constraint is missing.")); + match = EFalse; + } + return match; + } + +TBool CExtensionTest::CheckSidListL(const CX509Certificate& cert) + { + const CX509CertExtension* ext = cert.Extension(KSidListConstraint); + TBool match = ETrue; + if (ext) + { + // use NewL because this covers NewLC as well + CX509IntListExt* intListExt = CX509IntListExt::NewL(ext->Data()); + CleanupStack::PushL(intListExt); + if (! IsEqual(intListExt->IntArray(), iExpectedSidList)) + { + PrintLine(_L("SID list is different")); + match = EFalse; + } + CleanupStack::PopAndDestroy(intListExt); + } + else if (iSidsPresent) + { + PrintLine(_L("SID constraint is missing.")); + match = EFalse; + } + return match; + } + +TBool CExtensionTest::CheckVidListL(const CX509Certificate& cert) + { + const CX509CertExtension* ext = cert.Extension(KVidListConstraint); + TBool match = ETrue; + if (ext) + { + // use NewL because this covers NewLC as well + CX509IntListExt* intListExt = CX509IntListExt::NewL(ext->Data()); + CleanupStack::PushL(intListExt); + + if (! IsEqual(intListExt->IntArray(), iExpectedVidList)) + { + PrintLine(_L("VID list is different")); + match = EFalse; + } + CleanupStack::PopAndDestroy(intListExt); + } + else if (iVidsPresent) + { + PrintLine(_L("VID constraint is missing.")); + match = EFalse; + } + return match; + } + +TBool CExtensionTest::CheckCapabilitiesL(const CX509Certificate& cert) + { + const CX509CertExtension* ext = cert.Extension(KCapabilitiesConstraint); + TBool match = ETrue; + if (ext) + { + // use NewL because this covers NewLC as well + CX509CapabilitySetExt* capabilitySetExt = CX509CapabilitySetExt::NewL(ext->Data()); + CleanupStack::PushL(capabilitySetExt); + + const TCapabilitySet& capabilitySet = capabilitySetExt->CapabilitySet(); + + if (! (capabilitySet.HasCapabilities(iExpectedCapabilities) + && iExpectedCapabilities.HasCapabilities(capabilitySet))) + { + PrintLine(_L("Capability constraints are different.")); + match = EFalse; + } + CleanupStack::PopAndDestroy(capabilitySetExt); + } + else if (iCapabilitiesPresent) + { + PrintLine(_L("Capability constraint is missing.")); + match = EFalse; + } + return match; + } + +TBool CExtensionTest::IsEqual(const RArray& aArray1, const RArray& aArray2) + { + if (aArray1.Count() == aArray2.Count()) + { + TInt count = aArray1.Count(); + for (TInt i = 0; i < count; i++) + { + if (aArray1[i] != aArray2[i]) + { + return EFalse; + } + } + return ETrue; + } + return EFalse; + } + +TBool CExtensionTest::IsEqual(const RPointerArray& aArray1, const RPointerArray& aArray2) + { + if (aArray1.Count() == aArray2.Count()) + { + TInt count = aArray1.Count(); + for (TInt i = 0; i < count; i++) + { + if (aArray1[i]->Compare(*aArray2[i]) != 0) + { + return EFalse; + } + } + return ETrue; + } + return EFalse; + } + +void CExtensionTest::DoReportAction() + { + } + +void CExtensionTest::DoCheckResult(TInt /*aError*/) + { + } + +void CExtensionTest::Print(const TDesC& aText) + { + iConsole.Printf(aText); + iOut.writeString(aText); + } +void CExtensionTest::PrintLine(const TDesC& aText) + { + iConsole.Printf(aText); + iConsole.Printf(_L("\n")); + + iOut.writeString(aText); + iOut.writeNewLine(); + }