os/security/cryptoservices/certificateandkeymgmt/tcertstore/t_retrieve.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) 2004-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 "t_retrieve.h"
    20 #include "t_certstoreout.h"
    21 #include "t_input.h"
    22 #include "t_certstoredefs.h"
    23 #include "t_concurrentcertstore.h"
    24 #include <ccertattributefilter.h>
    25 
    26 ///////////////////////////////////////////////////////////////////////////////
    27 //CRetrieveCertificate
    28 ///////////////////////////////////////////////////////////////////////////////
    29 
    30 CTestAction* CRetrieveCertificate::NewL(RFs& aFs,
    31 										CConsoleBase& aConsole,
    32 										Output& aOut,
    33 										const TTestActionSpec& aTestActionSpec)
    34 	{
    35 	CRetrieveCertificate* self = new (ELeave) CRetrieveCertificate(aFs, aConsole, aOut);
    36 	CleanupStack::PushL(self);
    37 	self->ConstructL(aTestActionSpec);
    38 	CleanupStack::Pop(self);
    39 	return self;
    40 	}
    41 
    42 CRetrieveCertificate::CRetrieveCertificate(RFs& aFs,
    43 										   CConsoleBase& aConsole, 
    44 										   Output& aOut) :
    45 	CCertStoreTestAction(aFs, aConsole, aOut), iDataPtr(NULL, 0),
    46 	iFormat(EUnknownCertificate), iDeletable(EFalse), iTestForDeletable(EFalse)
    47 	{
    48 	}
    49 
    50 void CRetrieveCertificate::ConstructL(const TTestActionSpec& aTestActionSpec)
    51 	{
    52 	CCertStoreTestAction::ConstructL(aTestActionSpec);
    53 	
    54 	iFilter = CCertAttributeFilter::NewL();
    55 
    56 	HBufC* result = HBufC::NewLC(aTestActionSpec.iActionResult.Length());
    57 	TPtr(result->Des()).Copy(aTestActionSpec.iActionResult);
    58 	Input::GetExpectedResultL(Input::ParseElement(*result, KReturnStart, KReturnEnd), iExpectedResult);
    59 	CleanupStack::PopAndDestroy(result);
    60 
    61 	iLabel.Copy(Input::ParseElement(aTestActionSpec.iActionBody, KCertLabelStart));
    62 	if (iLabel.Length() == 0)
    63 		{
    64 		User::Leave(KErrArgument);
    65 		}
    66 
    67 	// check for a possible deletable flag value for the certificate
    68 	TInt err = KErrNone;
    69 	TInt pos = 0;
    70 	const TDesC8& deletableStr = Input::ParseElement(aTestActionSpec.iActionResult, 
    71 														KDeletableStart,
    72 														KDeletableEnd,
    73 														pos,
    74 														err);
    75 
    76 	// set the deletable attribute if a value was found for the certificate
    77 	if (err == KErrNone)
    78 		{
    79 		SetDeletable(deletableStr);
    80 		
    81 		// if deletable is found then format value must also be present
    82 		SetFormatL(Input::ParseElement(aTestActionSpec.iActionResult, KCertFormatStart));
    83 		}
    84 	}
    85 
    86 CRetrieveCertificate::~CRetrieveCertificate()
    87 	{
    88 	Reset();
    89 	delete iFilter;
    90 	}
    91 
    92 void CRetrieveCertificate::SetDeletable(const TDesC8& aDeletableString)
    93 	{
    94 	iTestForDeletable = ETrue;
    95 	if (aDeletableString.Compare(KTrue)==0)
    96 		{
    97 		iDeletable = ETrue;
    98 		}
    99 	else
   100 		{
   101 		iDeletable = EFalse;
   102 		}
   103 	}
   104 
   105 void CRetrieveCertificate::SetFormatL(const TDesC8& aFormatString)
   106 	{
   107 	if (aFormatString == KNullDesC8)
   108 		{
   109 		User::Leave(KErrArgument);
   110 		}
   111 	if (aFormatString == KWTLS)
   112 		{
   113 		iFormat = EWTLSCertificate;
   114 		}
   115 	else if (aFormatString == KX509)
   116 		{
   117 		iFormat = EX509Certificate;
   118 		}
   119 	else if (aFormatString == KWTLSURL)
   120 		{
   121 		iFormat = EWTLSCertificateUrl;
   122 		}
   123 	else if (aFormatString == KX509URL)
   124 		{
   125 		iFormat = EX509CertificateUrl;
   126 		}
   127 	else
   128 		{
   129 		iOut.write(_L("Unknown cert format: "));
   130 		iOut.writeString(aFormatString);
   131 		iOut.writeNewLine();		   
   132 		User::Leave(KErrNotSupported);
   133 		}
   134 	}
   135 
   136 void CRetrieveCertificate::PerformAction(TRequestStatus& aStatus)
   137 	{
   138 	if (aStatus != KErrNone && iState != ECheckRetrieve)
   139 		{
   140 		iState = EFinished;
   141 		}
   142 	
   143 	switch (iState)
   144 		{
   145 		case EList:
   146 			CertStore().List(iCertInfos, *iFilter, aStatus);
   147 			iState = ERetrieveData;
   148 			break;
   149 
   150 		case ERetrieveData:
   151 			{
   152 			for (TInt i = 0 ; i < iCertInfos.Count() ; ++i)
   153 				{
   154 				CCTCertInfo* certInfo = iCertInfos[i];
   155 				if (certInfo->Label() == iLabel)
   156 					{
   157 					iCertInfo = certInfo;
   158 					break;
   159 					}
   160 				}
   161 			
   162 			if (!iCertInfo)
   163 				{
   164 				iState = EFinished;			
   165 				TRequestStatus* status = &aStatus;
   166 				User::RequestComplete(status, KErrNotFound);
   167 				}
   168 			else
   169 				{
   170 				TRAPD(err, iData = HBufC8::NewL(iCertInfo->Size()));
   171 				if (err != KErrNone)
   172 					{
   173 					iState = EFinished;
   174 					TRequestStatus* status = &aStatus;
   175 					User::RequestComplete(status, err);
   176 					}
   177 				else
   178 					{
   179 					iState = EParseData;
   180 					// iDataPtr has to be be a member as it's passed to asyc retrieve operation
   181 					iDataPtr.Set(iData->Des());  
   182 					CertStore().Retrieve(*iCertInfo, iDataPtr, aStatus);
   183 					}
   184 				}
   185 			}
   186 			break;
   187 
   188 		case EParseData:
   189 			{
   190 			switch (iCertInfo->CertificateFormat())
   191 				{
   192 				case EX509Certificate:
   193 					{
   194 					CX509Certificate* cert = CX509Certificate::NewLC(*iData);
   195 					X509CertWriter writer(iOut);
   196 					writer.WriteCert(*cert);
   197 					CleanupStack::PopAndDestroy();
   198 					iOut.writeNewLine();
   199 					}
   200 					break;
   201 
   202 				case EWTLSCertificate:
   203 					{
   204 					CWTLSCertificate* cert = CWTLSCertificate::NewLC(*iData);
   205 					WTLSCertWriter writer(iOut);
   206 					writer.WriteCert(*cert);
   207 					CleanupStack::PopAndDestroy(cert);
   208 					iOut.writeNewLine();
   209 					}
   210 					break;
   211 				
   212 				default:
   213 					break;
   214 				}
   215 			
   216 			iState = ERetrieveCert;
   217 			TRequestStatus* status = &aStatus;
   218 			User::RequestComplete(status, KErrNone);
   219 			}
   220 			break;
   221 
   222 		case ERetrieveCert:
   223 			if (CertStoreType() != EUnifiedCertStore)
   224 				{
   225 				iState = EFinished;
   226 				TRequestStatus* status = &aStatus;
   227 				User::RequestComplete(status, KErrNone);
   228 				}
   229 			else
   230 				{
   231 				iState = ECheckRetrieve;
   232 				UnifiedCertStore().Retrieve(*iCertInfo, iCert, aStatus);
   233 				}
   234 			break;
   235 
   236 		case ECheckRetrieve:
   237 			{
   238 			TCertificateFormat format = iCertInfo->CertificateFormat();
   239 			TInt expectedErr = KErrNotSupported;
   240 			if (format == EX509Certificate || format == EWTLSCertificate)
   241 				{
   242 				expectedErr = KErrNone;
   243 				}
   244 			TInt err = (aStatus.Int() == expectedErr) ? KErrNone : KErrGeneral;
   245 			iState = EFinished;
   246 			TRequestStatus* status = &aStatus;
   247 			User::RequestComplete(status, err);
   248 			}
   249 			break;
   250 
   251 		case EFinished:
   252 			{
   253 			iActionState = EPostrequisite;
   254 			iFinished = ETrue;
   255 			TRequestStatus* status = &aStatus;
   256 			User::RequestComplete(status, aStatus.Int());
   257 			}
   258 			break;
   259 			
   260 		default:
   261 			User::Invariant();
   262 		}
   263 	}
   264 
   265 void CRetrieveCertificate::PerformCancel()
   266 	{
   267 	switch (iState)
   268 		{
   269 		case ERetrieveData:
   270 			CertStore().CancelList();
   271 			break;
   272 
   273 		case EParseData:
   274 		case ECheckRetrieve:
   275 			CertStore().CancelRetrieve();
   276 			break;
   277 
   278 		default:
   279 			break;
   280 		}
   281 	}
   282 
   283 void CRetrieveCertificate::Reset()
   284 	{
   285 	iState = EList;
   286 	iCertInfos.Close();
   287 	delete iCert;
   288 	iCert = NULL;
   289 	delete iData;
   290 	iData = NULL;
   291 	}
   292 
   293 void CRetrieveCertificate::DoReportAction()
   294 	{
   295 	iOut.write(_L("Retrieving certificate...\n"));
   296 	iOut.write(_L("\tLabel: %S\n"), &iLabel);
   297 	if (iTestForDeletable)
   298 		{
   299 		iOut.writeString(_L("\tDeletable = "));
   300 		iDeletable ? iOut.writeString(KTrue) : iOut.writeString(KFalse);
   301 		iOut.writeNewLine();
   302 		}
   303 	}
   304 
   305 void CRetrieveCertificate::DoPerformPostrequisite(TRequestStatus& aStatus)
   306 	{
   307 	iFinished = ETrue;
   308 	TRequestStatus* status = &aStatus;
   309 	User::RequestComplete(status, aStatus.Int());
   310 	}
   311 
   312 TBool CRetrieveCertificate::ValidCertInfo()
   313 	{
   314 	// check iFormat and deletable flag of the cert info object
   315 	return ((iCertInfo->IsDeletable() == iDeletable) &&
   316 		    (iFormat == iCertInfo->CertificateFormat()));
   317 	}
   318 	
   319 void CRetrieveCertificate::DoCheckResult(TInt aError)
   320 	{
   321 	if (iFinished)
   322 		{
   323 		iResult = (aError == iExpectedResult); 
   324 		
   325 		if (iResult)
   326 			{
   327 			if (iTestForDeletable)
   328 				{
   329 				iResult = iResult && ValidCertInfo();
   330 				
   331 				if (iResult)
   332 					{
   333 					iOut.writeString(_L("\tRetrieved certificate info successfully - \n\n"));
   334 					
   335 					}
   336 				}
   337 			else
   338 				{
   339 				iOut.writeString(_L("\tRetrieved certificate successfully\n\n"));
   340 				}
   341 			}
   342 		else
   343 			{
   344 			iOut.writeString(_L("\tRetrieve certificate failed\n\n"));
   345 			//	If running tests with multiple threads, failure may be expected
   346 			// need to add this back in when we get concurrent tests working
   347 			//CConcurrentTester::SanitizeTestResult(iOut, iResult);
   348 			}
   349 		}
   350 	}