First public contribution.
2 * Copyright (c) 2005-2010 Nokia Corporation and/or its subsidiary(-ies).
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".
9 * Initial Contributors:
10 * Nokia Corporation - initial contribution.
19 #include "x509constraintext.h"
20 #include "extensiontest.h"
23 _LIT(KFileNameStart, "<filename>");
24 _LIT(KExpectedDeviceIdList, "<device_id_list>");
25 _LIT(KExpectedDevice, "<device_id>");
26 _LIT(KExpectedSidList, "<sid_list>");
27 _LIT(KExpectedSid, "<sid>");
28 _LIT(KExpectedVidList, "<vid_list>");
29 _LIT(KExpectedVid, "<vid>");
30 _LIT(KExpectedCapabilities, "<capabilities>");
31 _LIT(KCorrupt, "<corrupt>");
32 _LIT(KMatch, "<match>");
34 CTestAction* CExtensionTest::NewL(RFs& aFs, CConsoleBase& aConsole,
35 Output& aOut, const TTestActionSpec& aTestActionSpec)
37 CTestAction* self = CExtensionTest::NewLC(aFs, aConsole, aOut, aTestActionSpec);
38 CleanupStack::Pop(self);
42 CTestAction* CExtensionTest::NewLC(RFs& aFs, CConsoleBase& aConsole,
43 Output& aOut, const TTestActionSpec& aTestActionSpec)
45 CExtensionTest* self = new(ELeave) CExtensionTest(aFs, aConsole, aOut);
46 CleanupStack::PushL(self);
47 self->ConstructL(aTestActionSpec);
51 CExtensionTest::CExtensionTest(RFs& aFs, CConsoleBase& aConsole, Output& aOut)
52 : CTestAction(aConsole, aOut),
57 CExtensionTest::~CExtensionTest()
59 iExpectedDeviceIdList.ResetAndDestroy();
60 iExpectedDeviceIdList.Close();
61 iExpectedSidList.Close();
62 iExpectedVidList.Close();
65 void CExtensionTest::ConstructL(const TTestActionSpec& aTestActionSpec)
67 CTestAction::ConstructL(aTestActionSpec);
71 HBufC* aBody = HBufC::NewLC(aTestActionSpec.iActionBody.Length());
72 aBody->Des().Copy(aTestActionSpec.iActionBody);
74 // Filename of the certificate file
75 TPtrC fileNameStart = Input::ParseElement(*aBody, KFileNameStart);
76 iCertFileName.Copy(fileNameStart);
78 // Whether we expect at least on of the extensions to be corrupt
79 TPtrC corruptStart = Input::ParseElement(*aBody, KCorrupt);
80 if (corruptStart.CompareF(_L("True")) == 0)
82 iExpectedCorrupt = ETrue;
85 // We expect the certificate to match the constraints
86 TPtrC matchStart = Input::ParseElement(*aBody, KMatch);
87 if (matchStart.CompareF(_L("True")) == 0)
89 iExpectedMatch = ETrue;
92 // Extract the lists of constraints that are expected to be present
94 TPtrC deviceListStart = Input::ParseElement(*aBody, KExpectedDeviceIdList, startPos, err);
97 BuildStringListL(iExpectedDeviceIdList, deviceListStart, KExpectedDevice);
98 iDeviceIdsPresent = ETrue;
102 TPtrC sidListStart = Input::ParseElement(*aBody, KExpectedSidList, startPos, err);
105 BuildIntList(iExpectedSidList, sidListStart, KExpectedSid);
106 iSidsPresent = ETrue;
110 TPtrC vidListStart = Input::ParseElement(*aBody, KExpectedVidList, startPos, err);
113 BuildIntList(iExpectedVidList, vidListStart, KExpectedVid);
114 iVidsPresent = ETrue;
118 TPtrC capabilities = Input::ParseElement(*aBody, KExpectedCapabilities, startPos, err);
121 BuildCapabilitySet(iExpectedCapabilities, capabilities);
122 iCapabilitiesPresent = ETrue;
125 CleanupStack::PopAndDestroy(aBody);
128 void CExtensionTest::BuildStringListL(RPointerArray<HBufC>& aStrings, const TDesC& aBuf, const TDesC& aTag)
134 // Find next value for the specified tag and add it to the string array
136 TPtrC str = Input::ParseElement(aBuf, aTag, pos, err);
139 HBufC* string = str.AllocLC();
140 aStrings.AppendL(string);
141 CleanupStack::Pop(string);
147 void CExtensionTest::BuildIntList(RArray<TInt>& aInts, const TDesC& aBuf, const TDesC& aTag)
153 // Attempt to convert the contents of val to an int and store in
154 // the aInts array if it is a valid integer.
155 TInt n = Input::ParseIntElement(aBuf, aTag, pos, err);
158 // This append should not fail as the parsing went fine.
159 // So, ignoring the leave just to satisfy non leaving method convention.
160 TRAP_IGNORE(aInts.AppendL(n));
166 void CExtensionTest::BuildCapabilitySet(TCapabilitySet& aCapabilitySet, const TDesC& aBuf)
168 aCapabilitySet.SetEmpty();
169 TUint length = aBuf.Length();
170 for (TUint i = 0; i < length && i < ECapability_Limit; i++)
174 aCapabilitySet.AddCapability(static_cast<TCapability>(i));
179 void CExtensionTest::PerformAction(TRequestStatus& aStatus)
184 TRAP(err, buf = Input::ReadFileL(iCertFileName, iFs));
185 if (err == KErrNotFound)
189 SetScriptError(EFileNotFound, iCertFileName);
190 TRequestStatus* status = &aStatus;
191 iActionState = EPostrequisite;
192 User::RequestComplete(status, KErrNone);
195 else if (err != KErrNone)
200 CleanupStack::PushL(buf);
201 CX509Certificate* cert = CX509Certificate::NewLC(buf->Des());
203 Print(_L("Checking certificate extensions in file "));
204 PrintLine(iCertFileName);
206 TBool match = EFalse;
207 TBool corrupt = EFalse;
208 CheckExtensionsL(*cert, match, corrupt);
211 iResult = iExpectedCorrupt;
214 Print(_L("Found unexpected corrupt extension."));
219 // no error. test whether the certificate matched the
221 iResult = (match == iExpectedMatch);
223 CleanupStack::PopAndDestroy(2, buf); // cert, buf
225 TRequestStatus* status = &aStatus;
226 iActionState = EPostrequisite;
227 User::RequestComplete(status, KErrNone);
230 void CExtensionTest::CheckExtensionsL(const CX509Certificate& cert,
231 TBool& match, TBool& corrupt)
238 TRAP(err, match &= CheckDeviceIdListL(cert));
239 if (err == KErrArgument)
241 PrintLine(_L("The device id constraint is corrupt."));
244 else if (err != KErrNone)
249 TRAP(err, match &= CheckSidListL(cert));
250 if (err == KErrArgument)
252 PrintLine(_L("The secure id constraint is corrupt."));
255 else if (err != KErrNone)
260 TRAP(err, match &= CheckVidListL(cert));
261 if (err == KErrArgument)
263 PrintLine(_L("The vendor id constraint is corrupt."));
266 else if (err != KErrNone)
271 TRAP(err, match &= CheckCapabilitiesL(cert));
272 if (err == KErrArgument)
274 PrintLine(_L("The capabilities constraint is corrupt."));
277 else if (err != KErrNone)
283 TBool CExtensionTest::CheckDeviceIdListL(const CX509Certificate& cert)
286 const CX509CertExtension* ext = cert.Extension(KDeviceIdListConstraint);
289 // use NewL because this covers NewLC as well
290 CX509Utf8StringListExt* stringListExt = CX509Utf8StringListExt::NewL(ext->Data());
291 CleanupStack::PushL(stringListExt);
292 if (! IsEqual(stringListExt->StringArray(), iExpectedDeviceIdList))
294 PrintLine(_L("Device Id list is different."));
297 CleanupStack::PopAndDestroy(stringListExt);
299 else if (iDeviceIdsPresent)
301 PrintLine(_L("Device Id constraint is missing."));
307 TBool CExtensionTest::CheckSidListL(const CX509Certificate& cert)
309 const CX509CertExtension* ext = cert.Extension(KSidListConstraint);
313 // use NewL because this covers NewLC as well
314 CX509IntListExt* intListExt = CX509IntListExt::NewL(ext->Data());
315 CleanupStack::PushL(intListExt);
316 if (! IsEqual(intListExt->IntArray(), iExpectedSidList))
318 PrintLine(_L("SID list is different"));
321 CleanupStack::PopAndDestroy(intListExt);
323 else if (iSidsPresent)
325 PrintLine(_L("SID constraint is missing."));
331 TBool CExtensionTest::CheckVidListL(const CX509Certificate& cert)
333 const CX509CertExtension* ext = cert.Extension(KVidListConstraint);
337 // use NewL because this covers NewLC as well
338 CX509IntListExt* intListExt = CX509IntListExt::NewL(ext->Data());
339 CleanupStack::PushL(intListExt);
341 if (! IsEqual(intListExt->IntArray(), iExpectedVidList))
343 PrintLine(_L("VID list is different"));
346 CleanupStack::PopAndDestroy(intListExt);
348 else if (iVidsPresent)
350 PrintLine(_L("VID constraint is missing."));
356 TBool CExtensionTest::CheckCapabilitiesL(const CX509Certificate& cert)
358 const CX509CertExtension* ext = cert.Extension(KCapabilitiesConstraint);
362 // use NewL because this covers NewLC as well
363 CX509CapabilitySetExt* capabilitySetExt = CX509CapabilitySetExt::NewL(ext->Data());
364 CleanupStack::PushL(capabilitySetExt);
366 const TCapabilitySet& capabilitySet = capabilitySetExt->CapabilitySet();
368 if (! (capabilitySet.HasCapabilities(iExpectedCapabilities)
369 && iExpectedCapabilities.HasCapabilities(capabilitySet)))
371 PrintLine(_L("Capability constraints are different."));
374 CleanupStack::PopAndDestroy(capabilitySetExt);
376 else if (iCapabilitiesPresent)
378 PrintLine(_L("Capability constraint is missing."));
384 TBool CExtensionTest::IsEqual(const RArray<TInt>& aArray1, const RArray<TInt>& aArray2)
386 if (aArray1.Count() == aArray2.Count())
388 TInt count = aArray1.Count();
389 for (TInt i = 0; i < count; i++)
391 if (aArray1[i] != aArray2[i])
401 TBool CExtensionTest::IsEqual(const RPointerArray<HBufC>& aArray1, const RPointerArray<HBufC>& aArray2)
403 if (aArray1.Count() == aArray2.Count())
405 TInt count = aArray1.Count();
406 for (TInt i = 0; i < count; i++)
408 if (aArray1[i]->Compare(*aArray2[i]) != 0)
418 void CExtensionTest::DoReportAction()
422 void CExtensionTest::DoCheckResult(TInt /*aError*/)
426 void CExtensionTest::Print(const TDesC& aText)
428 iConsole.Printf(aText);
429 iOut.writeString(aText);
431 void CExtensionTest::PrintLine(const TDesC& aText)
433 iConsole.Printf(aText);
434 iConsole.Printf(_L("\n"));
436 iOut.writeString(aText);