os/security/cryptoservices/certificateandkeymgmt/x509/x509CertExt_v2.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     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 * X509CERTEXT.CPP
    16 *
    17 */
    18 
    19 
    20 #include <s32strm.h>
    21 #include <x509certext.h>
    22 #include <asn1dec.h>
    23 #include "x509bitstring.h"
    24 
    25 void CX509ExtensionBase::ConstructL(const TDesC8& aBinaryData, TInt& aPos)
    26 	{
    27 	TASN1DecGeneric dec(aBinaryData.Right(aBinaryData.Length() - aPos));
    28 	dec.InitL();
    29 	if (dec.Tag() != EASN1OctetString)
    30 		{
    31 		User::Leave(KErrArgument);
    32 		}
    33 	TInt end = aPos + dec.LengthDER();
    34 	aPos += dec.LengthDERHeader();//add on header for octet string here
    35 //pass in binary data with aPos set to start of contents octets of octet string
    36 //we cheat a little here; since we know an octet string is just the contents octets, 
    37 //we just pass in a reference to the contents octets, and save alloc'ing the whole thang
    38 	DoConstructL(aBinaryData, aPos);	
    39 	if (aPos != end)
    40 		{
    41 		User::Leave(KErrArgument);
    42 		}
    43 	}
    44 
    45 //1) basic constraints...
    46 EXPORT_C CX509BasicConstraintsExt* CX509BasicConstraintsExt::NewL(const TDesC8& aBinaryData)
    47 	{
    48 	TInt pos = 0;
    49 	return CX509BasicConstraintsExt::NewL(aBinaryData, pos);
    50 	}
    51 
    52 EXPORT_C CX509BasicConstraintsExt* CX509BasicConstraintsExt::NewLC(const TDesC8& aBinaryData)
    53 	{
    54 	TInt pos = 0;
    55 	return CX509BasicConstraintsExt::NewLC(aBinaryData, pos);
    56 	}
    57 
    58 EXPORT_C CX509BasicConstraintsExt* CX509BasicConstraintsExt::NewL(const TDesC8& aBinaryData, TInt& aPos)
    59 	{
    60 	CX509BasicConstraintsExt* self = CX509BasicConstraintsExt::NewLC(aBinaryData, aPos);
    61 	CleanupStack::Pop();
    62 	return self;
    63 	}
    64 
    65 EXPORT_C CX509BasicConstraintsExt* CX509BasicConstraintsExt::NewLC(const TDesC8& aBinaryData, TInt& aPos)
    66 	{
    67 	CX509BasicConstraintsExt* self = new(ELeave) CX509BasicConstraintsExt;
    68 	CleanupStack::PushL(self);
    69 	self->ConstructL(aBinaryData, aPos);
    70 	return self;
    71 	}
    72 
    73 void CX509BasicConstraintsExt::DoConstructL(const TDesC8& aBinaryData, TInt& aPos)
    74 	{
    75 //sequence of 2 optional components, a bool and an int
    76 	TASN1DecSequence encSeq;
    77 	CArrayPtrFlat<TASN1DecGeneric>* seq = encSeq.DecodeDERLC(aBinaryData, aPos);
    78 	TInt count = seq->Count();
    79 	TInt pos = 0;
    80 	if (pos < count)
    81 		{
    82 		TBool doneInt = EFalse;
    83 		TASN1DecGeneric* curr = seq->At(pos);
    84 		pos++;
    85 		if (curr->Tag() == EASN1Boolean)
    86 			{
    87 			TASN1DecBoolean encBool;
    88 			iIsCA = encBool.DecodeDERL(*curr);
    89 			}
    90 		else
    91 			{
    92 			TASN1DecInteger encInt;
    93 			iMaxChainLen = encInt.DecodeDERShortL(*curr);
    94 			doneInt = ETrue;
    95 			}
    96 		if (pos < count)
    97 			{
    98 			if (doneInt)
    99 				{
   100 				User::Leave(KErrArgument);
   101 				}
   102 			curr = seq->At(pos);
   103 			pos++;
   104 			TASN1DecInteger encInt;
   105 			iMaxChainLen = encInt.DecodeDERShortL(*curr);
   106 			if (iMaxChainLen < 0)
   107 				{
   108 				User::Leave(KErrArgument);
   109 				}
   110 			}
   111 		}
   112 	if (pos != count)
   113 		{
   114 		User::Leave(KErrArgument);
   115 		}
   116 	CleanupStack::PopAndDestroy();//seq
   117 	}
   118 
   119 CX509BasicConstraintsExt::CX509BasicConstraintsExt()
   120 	:iIsCA(EFalse), iMaxChainLen(KMaxTInt)
   121 	{
   122 	}
   123 
   124 CX509BasicConstraintsExt::~CX509BasicConstraintsExt()
   125 	{
   126 	}
   127 
   128 EXPORT_C TBool CX509BasicConstraintsExt::IsCA() const
   129 	{
   130 	return iIsCA;
   131 	}
   132 
   133 EXPORT_C TInt CX509BasicConstraintsExt::MaxChainLength() const
   134 	{
   135 	return iMaxChainLen;
   136 	}
   137 	
   138 //2) alt name
   139 //#pragma message ("creating empty CX509AltNameExt and destroying it kills process")
   140 EXPORT_C CX509AltNameExt* CX509AltNameExt::NewL(const TDesC8& aBinaryData)
   141 	{
   142 	TInt pos = 0;
   143 	return CX509AltNameExt::NewL(aBinaryData, pos);
   144 	}
   145 
   146 EXPORT_C CX509AltNameExt* CX509AltNameExt::NewLC(const TDesC8& aBinaryData)
   147 	{
   148 	TInt pos = 0;
   149 	return CX509AltNameExt::NewLC(aBinaryData, pos);
   150 	}
   151 
   152 EXPORT_C CX509AltNameExt* CX509AltNameExt::NewL(const TDesC8& aBinaryData, TInt& aPos)
   153 	{
   154 	CX509AltNameExt* self = CX509AltNameExt::NewLC(aBinaryData, aPos);
   155 	CleanupStack::Pop();
   156 	return self;
   157 	}
   158 
   159 EXPORT_C CX509AltNameExt* CX509AltNameExt::NewLC(const TDesC8& aBinaryData, TInt& aPos)
   160 	{
   161 	CX509AltNameExt* self = new(ELeave) CX509AltNameExt;
   162 	CleanupStack::PushL(self);
   163 	self->ConstructL(aBinaryData, aPos);
   164 	return self;
   165 	}
   166 
   167 void CX509AltNameExt::DoConstructL(const TDesC8& aBinaryData, TInt& aPos)
   168 	{
   169 	// The sequence should have at least 1 name here, previously this was checked
   170 	// but now zero lengths sequences are tolerated.
   171 	//
   172 	// RFC 3280 requires that CAs ensure that the SubjectAltName is not empty if it exists. The 
   173 	// behaviour of the client is undefined if this condition occurs. Since this code will 
   174 	// normally be used as a client (i.e. not the CA) and there should be no need to validate 
   175 	// the SubjectAltName we do not enfore a minimum sequence length.
   176 	// This avoids TLS connections being dropped unecessarily.
   177 
   178 	TASN1DecSequence encSeq;
   179 	CArrayPtrFlat<TASN1DecGeneric>* seq = encSeq.DecodeDERLC(aBinaryData, aPos, 0, KMaxTInt);
   180 	TInt count = seq->Count();
   181 	iAuthorityName = new(ELeave) CArrayPtrFlat<CX509GeneralName> (1);
   182 	TASN1DecGeneric* gen;
   183 	for (TInt i = 0; i < count; i++)
   184 		{
   185 		gen = seq->At(i);
   186 		CX509GeneralName* gn = CX509GeneralName::NewLC(gen->Encoding());
   187 		iAuthorityName->AppendL(gn);
   188 		CleanupStack::Pop();//gn
   189 		}
   190 	CleanupStack::PopAndDestroy();
   191 	}
   192 
   193 CX509AltNameExt::~CX509AltNameExt()
   194 	{
   195 	if (iAuthorityName != NULL)
   196 		{
   197 		iAuthorityName->ResetAndDestroy();
   198 		delete iAuthorityName;
   199 		}
   200 	}
   201 
   202 EXPORT_C const CArrayPtrFlat<CX509GeneralName>& CX509AltNameExt::AltName() const
   203 	{
   204 	return *iAuthorityName;
   205 	}
   206 
   207 EXPORT_C TBool CX509AltNameExt::Match(const CX509AltNameExt& aExt) const
   208 	{
   209 	TBool res = EFalse;
   210 	const CArrayPtrFlat<CX509GeneralName>& otherGNs = aExt.AltName();
   211 	TInt otherGNCount = otherGNs.Count();
   212 	TInt thisGNCount = iAuthorityName->Count();
   213 	if (otherGNCount != thisGNCount)
   214 		{
   215 		}
   216 	else
   217 		{
   218 		res = ETrue;
   219 		for (TInt j = 0; j < otherGNCount; j++)
   220 				{
   221 				const CX509GeneralName* otherGN = otherGNs.At(j);
   222 				const CX509GeneralName* thisGN = iAuthorityName->At(j);
   223 				if (!thisGN->ExactMatch(*otherGN))
   224 					{
   225 					res = EFalse;
   226 					}
   227 				}
   228 		}
   229 	return res;
   230 	}
   231 
   232 CX509AltNameExt::CX509AltNameExt()
   233 	{
   234 	}
   235 
   236 //3) key usage
   237 CX509BitString::~CX509BitString()
   238 	{
   239 	delete iData;
   240 	}
   241 
   242 TBool CX509BitString::IsSet(TInt aBit) const
   243 	{
   244 	if (aBit < iLength)//offset from zero
   245 		{
   246 		TPtrC8 d(iData->Des());
   247 		TUint8 oct = d[(aBit/8)];
   248 		TUint mask = (1 << (7-(aBit % 8)));
   249 		return (oct & mask);
   250 		}
   251 	return EFalse;
   252 	}
   253 
   254 CX509BitString::CX509BitString(HBufC8* aData, TInt aLength)
   255 	:iData(aData), iLength(aLength)
   256 	{
   257 	}
   258 
   259 EXPORT_C CX509KeyUsageExt* CX509KeyUsageExt::NewL(const TDesC8& aBinaryData)
   260 	{
   261 	TInt pos = 0;
   262 	return CX509KeyUsageExt::NewL(aBinaryData, pos);
   263 	}
   264 
   265 EXPORT_C CX509KeyUsageExt* CX509KeyUsageExt::NewLC(const TDesC8& aBinaryData)
   266 	{
   267 	TInt pos = 0;
   268 	return CX509KeyUsageExt::NewLC(aBinaryData, pos);
   269 	}
   270 
   271 EXPORT_C CX509KeyUsageExt* CX509KeyUsageExt::NewL(const TDesC8& aBinaryData, TInt& aPos)
   272 	{
   273 	CX509KeyUsageExt* self = CX509KeyUsageExt::NewLC(aBinaryData, aPos);
   274 	CleanupStack::Pop();
   275 	return self;
   276 	}
   277 
   278 EXPORT_C CX509KeyUsageExt* CX509KeyUsageExt::NewLC(const TDesC8& aBinaryData, TInt& aPos)
   279 	{
   280 	CX509KeyUsageExt* self = new(ELeave) CX509KeyUsageExt;
   281 	CleanupStack::PushL(self);
   282 	self->ConstructL(aBinaryData, aPos);
   283 	return self;
   284 	}
   285 
   286 void CX509KeyUsageExt::DoConstructL(const TDesC8& aBinaryData, TInt& aPos)
   287 	{
   288 	TASN1DecGeneric gen(aBinaryData.Right(aBinaryData.Length() - aPos));
   289 	gen.InitL();
   290 	if (gen.Tag() != EASN1BitString)
   291 		{
   292 		User::Leave(KErrArgument);
   293 		}
   294 	TPtrC8 p(gen.GetContentDER());
   295 	if (p.Length() < 2)
   296 		{
   297 		User::Leave(KErrArgument);
   298 		}
   299 	TPtrC8 pData(p.Right(p.Length() - 1));
   300 	TInt paddingLength = p[0];
   301 	TInt bitStringLength = (pData.Length() * 8) - paddingLength;
   302 	HBufC8* bitString = pData.AllocL();
   303 	CleanupStack::PushL(bitString);
   304 	iData = new(ELeave) CX509BitString(bitString, bitStringLength);
   305 	CleanupStack::Pop();//bitstring
   306 	aPos += gen.LengthDER();
   307 	}
   308 
   309 CX509KeyUsageExt::CX509KeyUsageExt()
   310 	{
   311 	}
   312 
   313 CX509KeyUsageExt::~CX509KeyUsageExt()
   314 	{
   315 	delete iData;
   316 	}
   317 
   318 EXPORT_C TBool CX509KeyUsageExt::IsSet(TX509KeyUsage aUsage) const
   319 	{
   320 	return iData->IsSet(aUsage);
   321 	}
   322 
   323 //4) name constraints
   324 CX509GeneralSubtree* CX509GeneralSubtree::NewL(const TDesC8& aBinaryData)
   325 	{
   326 	TInt pos = 0;
   327 	return CX509GeneralSubtree::NewL(aBinaryData, pos);
   328 	}
   329 
   330 CX509GeneralSubtree* CX509GeneralSubtree::NewLC(const TDesC8& aBinaryData)
   331 	{
   332 	TInt pos = 0;
   333 	return CX509GeneralSubtree::NewLC(aBinaryData, pos);
   334 	}
   335 
   336 CX509GeneralSubtree* CX509GeneralSubtree::NewL(const TDesC8& aBinaryData, TInt& aPos)
   337 	{
   338 	CX509GeneralSubtree* self = CX509GeneralSubtree::NewLC(aBinaryData, aPos);
   339 	CleanupStack::Pop();
   340 	return self;
   341 	}
   342 
   343 CX509GeneralSubtree* CX509GeneralSubtree::NewLC(const TDesC8& aBinaryData, TInt& aPos)
   344 	{
   345 	CX509GeneralSubtree* self = new(ELeave) CX509GeneralSubtree;
   346 	CleanupStack::PushL(self);
   347 	self->ConstructL(aBinaryData, aPos);
   348 	return self;
   349 	}
   350 
   351 void CX509GeneralSubtree::ConstructL(const TDesC8& aBinaryData, TInt& aPos)
   352 	{
   353 	TASN1DecSequence encSeq;
   354 	CArrayPtrFlat<TASN1DecGeneric>* seq = encSeq.DecodeDERLC(aBinaryData, aPos, 1, KMaxTInt);//(seq here must have at least 1 name)
   355 	TInt count = seq->Count();
   356 	TInt pos = 0;
   357 	TASN1DecGeneric* curr = seq->At(pos);
   358 	pos++;
   359 	iName = CX509GeneralName::NewL(curr->Encoding());
   360 	if (pos < count)
   361 		{
   362 		TBool doneMax = EFalse;
   363 		curr = seq->At(pos);
   364 		pos++;
   365 		if (curr->Class() != EContextSpecific)
   366 				{
   367 				User::Leave(KErrArgument);
   368 				}
   369 			switch(curr->Tag())
   370 				{
   371 				case 0:
   372 					{
   373 					TASN1DecInteger encInt;
   374 					iMinDist = encInt.DecodeDERShortL(*curr);
   375 					break;
   376 					}
   377 				case 1:
   378 					{
   379 					TASN1DecInteger encInt;
   380 					iMaxDist = encInt.DecodeDERShortL(*curr);
   381 					doneMax = ETrue;
   382 					break;
   383 					}
   384 				}
   385 			if (pos < count)
   386 				{
   387 				curr = seq->At(pos);
   388 				if ((doneMax) || (curr->Class() != EContextSpecific) || (curr->Tag() != 1))
   389 					{
   390 					User::Leave(KErrArgument);
   391 					}
   392 				TASN1DecInteger encInt;
   393 				iMaxDist = encInt.DecodeDERShortL(*curr);
   394 				}
   395 		}
   396 	if (pos != count)
   397 		{
   398 		User::Leave(KErrArgument);
   399 		}
   400 	CleanupStack::PopAndDestroy();
   401 	}
   402 
   403 CX509GeneralSubtree::~CX509GeneralSubtree()
   404 	{
   405 	delete iName;
   406 	}
   407 
   408 EXPORT_C const CX509GeneralName& CX509GeneralSubtree::Name() const
   409 	{
   410 	return *iName;
   411 	}
   412 
   413 EXPORT_C TInt CX509GeneralSubtree::MinDistance() const
   414 	{
   415 	return iMinDist;
   416 	}
   417 
   418 EXPORT_C TInt CX509GeneralSubtree::MaxDistance() const
   419 	{
   420 	return iMaxDist;
   421 	}
   422 
   423 CX509GeneralSubtree::CX509GeneralSubtree()
   424 	:iMaxDist(KMaxTInt), iMinDist(0)
   425 	{
   426 	}
   427 
   428 //
   429 EXPORT_C CX509NameConstraintsExt* CX509NameConstraintsExt::NewL(const TDesC8& aBinaryData)
   430 	{
   431 	TInt pos = 0;
   432 	return CX509NameConstraintsExt::NewL(aBinaryData, pos);
   433 	}
   434 
   435 EXPORT_C CX509NameConstraintsExt* CX509NameConstraintsExt::NewLC(const TDesC8& aBinaryData)
   436 	{
   437 	TInt pos = 0;
   438 	return CX509NameConstraintsExt::NewLC(aBinaryData, pos);
   439 	}
   440 
   441 EXPORT_C CX509NameConstraintsExt* CX509NameConstraintsExt::NewL(const TDesC8& aBinaryData, TInt& aPos)
   442 	{
   443 	CX509NameConstraintsExt* self = CX509NameConstraintsExt::NewLC(aBinaryData, aPos);
   444 	CleanupStack::Pop();
   445 	return self;
   446 	}
   447 
   448 EXPORT_C CX509NameConstraintsExt* CX509NameConstraintsExt::NewLC(const TDesC8& aBinaryData, TInt& aPos)
   449 	{
   450 	CX509NameConstraintsExt* self = new(ELeave) CX509NameConstraintsExt;
   451 	CleanupStack::PushL(self);
   452 	self->ConstructL(aBinaryData, aPos);
   453 	return self;
   454 	}
   455 
   456 void CX509NameConstraintsExt::DoConstructL(const TDesC8& aBinaryData, TInt& aPos)
   457 	{
   458 	TASN1DecSequence encSeq;
   459 	CArrayPtrFlat<TASN1DecGeneric>* seq = encSeq.DecodeDERLC(aBinaryData, aPos);
   460 	TInt count = seq->Count();
   461 	TInt pos = 0;
   462 
   463 	iExcludedSubtrees = new(ELeave) CArrayPtrFlat<CX509GeneralSubtree> (1);
   464 	iPermittedSubtrees = new(ELeave) CArrayPtrFlat<CX509GeneralSubtree> (1);
   465 	TBool doneExcluded = EFalse;
   466 	
   467 	if (pos < count)
   468 		{
   469 		TASN1DecGeneric* curr = seq->At(pos);
   470 		pos++;
   471 		if (curr->Class() != EContextSpecific)
   472 			{
   473 			User::Leave(KErrArgument);
   474 			}
   475 		switch (curr->Tag())
   476 			{
   477 			case 0:
   478 				{
   479 				AddSubtreesL(*iPermittedSubtrees, curr->Encoding());
   480 				break;
   481 				}
   482 			case 1:
   483 				{
   484 				AddSubtreesL(*iExcludedSubtrees, curr->Encoding());
   485 				doneExcluded = ETrue;
   486 				break;
   487 				}
   488 			default:
   489 				{
   490 				User::Leave(KErrArgument);
   491 				}
   492 			}
   493 		if (pos < count)
   494 			{
   495 			curr = seq->At(pos);
   496 			pos++;
   497 			if ((curr->Class() != EContextSpecific) || (curr->Tag() != 1) || (doneExcluded))
   498 				{
   499 				User::Leave(KErrArgument);
   500 				}
   501 			AddSubtreesL(*iExcludedSubtrees, curr->Encoding());
   502 			}
   503 		}
   504 	CleanupStack::PopAndDestroy();//seq
   505 	}
   506 
   507 void CX509NameConstraintsExt::AddSubtreesL(	CArrayPtrFlat<CX509GeneralSubtree>& aSubtrees,
   508 											const TDesC8& aBinaryData)
   509 	{
   510 	TASN1DecSequence encSeq;
   511 	TInt pos = 0;
   512 	CArrayPtrFlat<TASN1DecGeneric>* seq = encSeq.DecodeDERLC(aBinaryData, pos, 1, KMaxTInt);
   513 	TInt count = seq->Count();
   514 	TASN1DecGeneric* gen;
   515 	for(TInt i = 0; i < count; i++)
   516 		{
   517 		gen = seq->At(i);
   518 		CX509GeneralSubtree* subtree = CX509GeneralSubtree::NewLC(gen->Encoding());
   519 		aSubtrees.AppendL(subtree);
   520 		CleanupStack::Pop();
   521 		}
   522 	CleanupStack::PopAndDestroy();
   523 	}
   524 
   525 EXPORT_C CX509NameConstraintsExt::~CX509NameConstraintsExt()
   526 	{
   527 	if (iExcludedSubtrees != NULL)
   528 		{
   529 		iExcludedSubtrees->ResetAndDestroy();
   530 		delete iExcludedSubtrees;
   531 		}
   532 	if (iPermittedSubtrees != NULL)
   533 		{
   534 		iPermittedSubtrees->ResetAndDestroy();
   535 		delete iPermittedSubtrees;
   536 		}
   537 	}
   538 
   539 EXPORT_C const CArrayPtrFlat<CX509GeneralSubtree>& CX509NameConstraintsExt::ExcludedSubtrees() const
   540 	{
   541 	return *iExcludedSubtrees;
   542 	}
   543 
   544 EXPORT_C const CArrayPtrFlat<CX509GeneralSubtree>& CX509NameConstraintsExt::PermittedSubtrees() const
   545 	{
   546 	return *iPermittedSubtrees;
   547 	}
   548 
   549 CX509NameConstraintsExt::CX509NameConstraintsExt()
   550 	{
   551 	}
   552 
   553 //5) policy constraints
   554 TX509PolicyConstraint::TX509PolicyConstraint(TBool aRequired, TInt aCountdown)
   555 	:iRequired(aRequired), iCountdown(aCountdown)
   556 	{
   557 	}
   558 
   559 TX509PolicyConstraint::TX509PolicyConstraint()
   560 	:iRequired(EFalse), iCountdown(0)
   561 	{
   562 	}
   563 
   564 //
   565 EXPORT_C CX509PolicyConstraintsExt* CX509PolicyConstraintsExt::NewL(const TDesC8& aBinaryData)
   566 	{
   567 	TInt pos = 0;
   568 	return CX509PolicyConstraintsExt::NewL(aBinaryData, pos);
   569 	}
   570 
   571 EXPORT_C CX509PolicyConstraintsExt* CX509PolicyConstraintsExt::NewLC(const TDesC8& aBinaryData)
   572 	{
   573 	TInt pos = 0;
   574 	return CX509PolicyConstraintsExt::NewLC(aBinaryData, pos);
   575 	}
   576 
   577 EXPORT_C CX509PolicyConstraintsExt* CX509PolicyConstraintsExt::NewL(const TDesC8& aBinaryData, TInt& aPos)
   578 	{
   579 	CX509PolicyConstraintsExt* self = CX509PolicyConstraintsExt::NewLC(aBinaryData, aPos);
   580 	CleanupStack::Pop();
   581 	return self;
   582 	}
   583 
   584 EXPORT_C CX509PolicyConstraintsExt* CX509PolicyConstraintsExt::NewLC(const TDesC8& aBinaryData, TInt& aPos)
   585 	{
   586 	CX509PolicyConstraintsExt* self = new(ELeave) CX509PolicyConstraintsExt;
   587 	CleanupStack::PushL(self);
   588 	self->ConstructL(aBinaryData, aPos);
   589 	return self;
   590 	}
   591 
   592 void CX509PolicyConstraintsExt::DoConstructL(const TDesC8& aBinaryData, TInt& aPos)
   593 	{
   594 	TASN1DecSequence encSeq;
   595 	CArrayPtrFlat<TASN1DecGeneric>* seq = encSeq.DecodeDERLC(aBinaryData, aPos);
   596 	TInt count = seq->Count();
   597 	TInt pos = 0;
   598 	TASN1DecGeneric* curr;
   599 	if (pos < count)
   600 		{
   601 		curr = seq->At(pos);
   602 		pos++;
   603 		if (curr->Class() != EContextSpecific)
   604 			{
   605 			User::Leave(KErrArgument);
   606 			}
   607 		switch (curr->Tag())
   608 			{
   609 			case 0:
   610 				{
   611 				iRequirePolicy.iRequired = ETrue;
   612 				TASN1DecInteger encInt;
   613 				iRequirePolicy.iCountdown = encInt.DecodeDERShortL(*curr);
   614 				break;
   615 				}
   616 			case 1:
   617 				{
   618 				iInhibitPolicyMapping.iRequired = ETrue;
   619 				TASN1DecInteger encInt;
   620 				iInhibitPolicyMapping.iCountdown = encInt.DecodeDERShortL(*curr);
   621 				break;
   622 				}
   623 			default:
   624 				{
   625 				User::Leave(KErrArgument);
   626 				}
   627 			}
   628 		if(pos < count)
   629 			{
   630 			curr = seq->At(pos);
   631 			pos++;
   632 			if ((iInhibitPolicyMapping.iRequired) || (curr->Class() != EContextSpecific) || (curr->Tag() != 1))
   633 				{
   634 				User::Leave(KErrArgument);
   635 				}
   636 			iInhibitPolicyMapping.iRequired = ETrue;
   637 			TASN1DecInteger encInt;
   638 			iInhibitPolicyMapping.iCountdown = encInt.DecodeDERShortL(*curr);
   639 			}
   640 		}
   641 	if (pos != count)
   642 		{
   643 		User::Leave(KErrArgument);
   644 		}
   645 	CleanupStack::PopAndDestroy();
   646 	}
   647 
   648 CX509PolicyConstraintsExt::CX509PolicyConstraintsExt()
   649 	{
   650 	}
   651 
   652 EXPORT_C CX509PolicyConstraintsExt::~CX509PolicyConstraintsExt()
   653 	{
   654 	}
   655 
   656 EXPORT_C TX509PolicyConstraint CX509PolicyConstraintsExt::ExplicitPolicyRequired() const
   657 	{
   658 	return iRequirePolicy;
   659 	}
   660 
   661 EXPORT_C TX509PolicyConstraint CX509PolicyConstraintsExt::InhibitPolicyMapping() const
   662 	{
   663 	return iInhibitPolicyMapping;
   664 	}
   665 
   666 //6) policies
   667 CX509PolicyQualifierInfo* CX509PolicyQualifierInfo::NewL(const TDesC8& aBinaryData)
   668 	{
   669 	TInt pos = 0;
   670 	return CX509PolicyQualifierInfo::NewL(aBinaryData, pos);
   671 	}
   672 
   673 CX509PolicyQualifierInfo* CX509PolicyQualifierInfo::NewLC(const TDesC8& aBinaryData)
   674 	{
   675 	TInt pos = 0;
   676 	return CX509PolicyQualifierInfo::NewLC(aBinaryData, pos);
   677 	}
   678 
   679 CX509PolicyQualifierInfo* CX509PolicyQualifierInfo::NewL(const TDesC8& aBinaryData, TInt& aPos)
   680 	{
   681 	CX509PolicyQualifierInfo* self = CX509PolicyQualifierInfo::NewLC(aBinaryData, aPos);
   682 	CleanupStack::Pop();
   683 	return self;
   684 	}
   685 
   686 CX509PolicyQualifierInfo* CX509PolicyQualifierInfo::NewLC(const TDesC8& aBinaryData, TInt& aPos)
   687 	{
   688 	CX509PolicyQualifierInfo* self = new(ELeave) CX509PolicyQualifierInfo;
   689 	CleanupStack::PushL(self);
   690 	self->ConstructL(aBinaryData, aPos);
   691 	return self;
   692 	}
   693 
   694 CX509PolicyQualifierInfo* CX509PolicyQualifierInfo::NewL(const CX509PolicyQualifierInfo& aQualifier)
   695 	{
   696 	CX509PolicyQualifierInfo* self = CX509PolicyQualifierInfo::NewLC(aQualifier);
   697 	CleanupStack::Pop();//self
   698 	return self;
   699 	}
   700 
   701 CX509PolicyQualifierInfo* CX509PolicyQualifierInfo::NewLC(const CX509PolicyQualifierInfo& aQualifier)
   702 	{
   703 	CX509PolicyQualifierInfo* self = new(ELeave) CX509PolicyQualifierInfo;
   704 	CleanupStack::PushL(self);
   705 	self->ConstructL(aQualifier);
   706 	return self;
   707 	}
   708 
   709 CX509PolicyQualifierInfo* CX509PolicyQualifierInfo::NewL(RReadStream& aStream)
   710 	{
   711 	CX509PolicyQualifierInfo* self = CX509PolicyQualifierInfo::NewLC(aStream);
   712 	CleanupStack::Pop();
   713 	return self;
   714 	}
   715 
   716 CX509PolicyQualifierInfo* CX509PolicyQualifierInfo::NewLC(RReadStream& aStream)
   717 	{
   718 	CX509PolicyQualifierInfo* self = new(ELeave) CX509PolicyQualifierInfo();
   719 	CleanupStack::PushL(self);
   720 	self->ConstructL(aStream);
   721 	return self;
   722 	}
   723 
   724 void CX509PolicyQualifierInfo::ConstructL(RReadStream& aStream)
   725 	{
   726 	InternalizeL(aStream);
   727 	}
   728 
   729 void CX509PolicyQualifierInfo::ConstructL(const CX509PolicyQualifierInfo& aQualifier)
   730 	{
   731 	iPolicyQualifierId = aQualifier.iPolicyQualifierId->Des().AllocL();//must be a better way to do this!!
   732 	iData = aQualifier.iData->Des().AllocL();//must be a better way to do this!!
   733 	}
   734 
   735 void CX509PolicyQualifierInfo::ConstructL(const TDesC8& aBinaryData, TInt& aPos)
   736 	{
   737 	TASN1DecSequence encSeq;
   738 	CArrayPtrFlat<TASN1DecGeneric>* seq = encSeq.DecodeDERLC(aBinaryData, aPos, 1, KMaxTInt);
   739 	TInt count = seq->Count();
   740 	TInt pos = 0;
   741 	TASN1DecGeneric* curr = seq->At(pos);
   742 	pos++;
   743 	TASN1DecObjectIdentifier encOID;
   744 	iPolicyQualifierId = encOID.DecodeDERL(*curr);
   745 	if (pos < count)
   746 		{
   747 		iData = curr->Encoding().AllocL();
   748 		pos++;
   749 		}
   750 	else
   751 		{
   752 		iData = HBufC8::NewL(1);
   753 		*iData = KNullDesC8;
   754 		}
   755 	if (pos != count)
   756 		{
   757 		User::Leave(KErrArgument);
   758 		}
   759 	CleanupStack::PopAndDestroy();
   760 	}
   761 
   762 CX509PolicyQualifierInfo::CX509PolicyQualifierInfo()
   763 	{
   764 	}
   765 
   766 CX509PolicyQualifierInfo::~CX509PolicyQualifierInfo()
   767 	{
   768 	delete iPolicyQualifierId;
   769 	delete iData;
   770 	}
   771 
   772 EXPORT_C TPtrC CX509PolicyQualifierInfo::Id() const
   773 	{
   774 	return iPolicyQualifierId->Des();
   775 	}
   776 
   777 EXPORT_C TPtrC8 CX509PolicyQualifierInfo::Data() const
   778 	{
   779 	return iData->Des();
   780 	}
   781 
   782 void CX509PolicyQualifierInfo::ExternalizeL(RWriteStream& aStream) const
   783 	{
   784 	//iPolicyQualifierId
   785 	aStream << *iPolicyQualifierId;
   786 
   787 	//iData
   788 	aStream << *iData;
   789 	}
   790 
   791 void CX509PolicyQualifierInfo::InternalizeL(RReadStream& aStream)
   792 	{
   793 	//iPolicyQualifierId
   794 	delete iPolicyQualifierId;
   795 	iPolicyQualifierId=0;
   796 	iPolicyQualifierId=HBufC::NewL(aStream, KMaxTInt);
   797 
   798 	//iData
   799 	delete iData;
   800 	iData=0;
   801 	iData=HBufC8::NewL(aStream, KMaxTInt);
   802 	}
   803 
   804 
   805 CX509CertPolicyInfo* CX509CertPolicyInfo::NewL(const TDesC8& aBinaryData)
   806 	{
   807 	TInt pos = 0;
   808 	return CX509CertPolicyInfo::NewL(aBinaryData, pos);
   809 	}
   810 
   811 CX509CertPolicyInfo* CX509CertPolicyInfo::NewLC(const TDesC8& aBinaryData)
   812 	{
   813 	TInt pos = 0;
   814 	return CX509CertPolicyInfo::NewLC(aBinaryData, pos);
   815 	}
   816 
   817 CX509CertPolicyInfo* CX509CertPolicyInfo::NewL(const TDesC8& aBinaryData, TInt& aPos)
   818 	{
   819 	CX509CertPolicyInfo* self = CX509CertPolicyInfo::NewLC(aBinaryData, aPos);
   820 	CleanupStack::Pop();
   821 	return self;
   822 	}
   823 
   824 CX509CertPolicyInfo* CX509CertPolicyInfo::NewLC(const TDesC8& aBinaryData, TInt& aPos)
   825 	{
   826 	CX509CertPolicyInfo* self = new(ELeave) CX509CertPolicyInfo;
   827 	CleanupStack::PushL(self);
   828 	self->ConstructL(aBinaryData, aPos);
   829 	return self;
   830 	}
   831 
   832 
   833 EXPORT_C CX509CertPolicyInfo* CX509CertPolicyInfo::NewL(RReadStream& aStream)
   834 	{
   835 	CX509CertPolicyInfo* self = CX509CertPolicyInfo::NewLC(aStream);
   836 	CleanupStack::Pop();
   837 	return self;
   838 	}
   839  
   840 EXPORT_C CX509CertPolicyInfo* CX509CertPolicyInfo::NewLC(RReadStream& aStream)
   841 	{
   842 	CX509CertPolicyInfo* self = new(ELeave) CX509CertPolicyInfo();
   843 	CleanupStack::PushL(self);
   844 	self->ConstructL(aStream);
   845 	return self;
   846 	}
   847 
   848 EXPORT_C CX509CertPolicyInfo* CX509CertPolicyInfo::NewL(const CX509CertPolicyInfo& aInfo)
   849 	{
   850 	CX509CertPolicyInfo* self = CX509CertPolicyInfo::NewLC(aInfo);
   851 	CleanupStack::Pop();//self
   852 	return self;
   853 	}
   854 
   855 EXPORT_C CX509CertPolicyInfo* CX509CertPolicyInfo::NewLC(const CX509CertPolicyInfo& aInfo)
   856 	{
   857 	CX509CertPolicyInfo* self = new(ELeave) CX509CertPolicyInfo;
   858 	CleanupStack::PushL(self);
   859 	self->ConstructL(aInfo);
   860 	return self;
   861 	}
   862 
   863 void CX509CertPolicyInfo::ConstructL(RReadStream& aStream)
   864 	{
   865 	InternalizeL(aStream);
   866 	}
   867 
   868 void CX509CertPolicyInfo::ConstructL(const CX509CertPolicyInfo& aInfo)
   869 	{
   870 	iCertPolicyId = aInfo.iCertPolicyId->Des().AllocL();//must be a better way to do this!!
   871 	iQualifiers = new(ELeave) CArrayPtrFlat<CX509PolicyQualifierInfo> (1);
   872 	TInt count = aInfo.iQualifiers->Count();
   873 	for (TInt i = 0; i < count; i++)
   874 		{
   875 		CX509PolicyQualifierInfo* q = CX509PolicyQualifierInfo::NewLC(*(aInfo.iQualifiers->At(i)));
   876 		iQualifiers->AppendL(q);
   877 		CleanupStack::Pop();//q
   878 		}
   879 	}
   880 
   881 void CX509CertPolicyInfo::ConstructL(const TDesC8& aBinaryData, TInt& aPos)
   882 	{
   883 	TASN1DecSequence encSeq;
   884 	CArrayPtrFlat<TASN1DecGeneric>* seq = encSeq.DecodeDERLC(aBinaryData, aPos, 1, KMaxTInt);
   885 	TInt count = seq->Count();
   886 	TInt pos = 0;
   887 	TASN1DecGeneric* curr = seq->At(pos);
   888 	pos++;
   889 
   890 	TASN1DecObjectIdentifier encOID;
   891 	iCertPolicyId = encOID.DecodeDERL(*curr);
   892 	iQualifiers = new(ELeave) CArrayPtrFlat<CX509PolicyQualifierInfo> (1);
   893 	if (pos < count)
   894 		{
   895 		curr = seq->At(pos);
   896 		pos++;
   897 		TASN1DecSequence encSeqQualifier;
   898 		CArrayPtrFlat<TASN1DecGeneric>* seqQualifier = encSeqQualifier.DecodeDERLC(*curr);
   899 		TInt qCount = seqQualifier->Count();
   900 		for(TInt i = 0; i < qCount; i++)
   901 			{
   902 			TASN1DecGeneric* qGen = seqQualifier->At(i);
   903 			CX509PolicyQualifierInfo* qualifier = CX509PolicyQualifierInfo::NewLC(qGen->Encoding());
   904 			iQualifiers->AppendL(qualifier);
   905 			CleanupStack::Pop();//qualifier
   906 			}
   907 		CleanupStack::PopAndDestroy();
   908 		}
   909 	if (pos != count)
   910 		{
   911 		User::Leave(KErrArgument);
   912 		}
   913 	CleanupStack::PopAndDestroy();
   914 	}
   915 
   916 CX509CertPolicyInfo::~CX509CertPolicyInfo()
   917 	{
   918 	if (iQualifiers != NULL)
   919 		{
   920 		iQualifiers->ResetAndDestroy();
   921 		delete iQualifiers;
   922 		}
   923 	delete iCertPolicyId;
   924 	}
   925 
   926 EXPORT_C const CArrayPtrFlat<CX509PolicyQualifierInfo>& CX509CertPolicyInfo::Qualifiers() const
   927 	{
   928 	return *iQualifiers;
   929 	}
   930 
   931 EXPORT_C TPtrC CX509CertPolicyInfo::Id() const
   932 	{
   933 	return iCertPolicyId->Des();
   934 	}
   935 
   936 CX509CertPolicyInfo::CX509CertPolicyInfo()
   937 	{
   938 	}
   939 
   940 EXPORT_C void CX509CertPolicyInfo::ExternalizeL(RWriteStream& aStream) const
   941 	{
   942 	//iCertPolicyId
   943  	aStream << *iCertPolicyId;
   944 
   945  	// iQualifiers
   946 	aStream.WriteInt32L(iQualifiers->Count());
   947 	for (TInt32 i=0;i < iQualifiers->Count(); ++i)
   948 		{
   949 		(*iQualifiers)[i]->ExternalizeL(aStream);
   950 		}
   951 	}
   952 
   953 EXPORT_C void CX509CertPolicyInfo::InternalizeL(RReadStream& aStream)
   954 	{
   955 	//iCertPolicyId
   956 	delete iCertPolicyId;
   957 	iCertPolicyId=0;
   958 	iCertPolicyId=HBufC::NewL(aStream, KMaxTInt);
   959 
   960 	// iQualifiers
   961 	if (iQualifiers != NULL)
   962 		{
   963 		iQualifiers->ResetAndDestroy();
   964 		}
   965 	else
   966 		{
   967 		iQualifiers = new(ELeave) CArrayPtrFlat<CX509PolicyQualifierInfo> (1);
   968 		}
   969 
   970 	TInt32 count=aStream.ReadInt32L();
   971 	for (TInt32 i=0;i < count; ++i)
   972 		{
   973 		CX509PolicyQualifierInfo* policyQualifierInfo=CX509PolicyQualifierInfo::NewLC(aStream);
   974 		iQualifiers->AppendL(policyQualifierInfo);
   975 		CleanupStack::Pop(policyQualifierInfo);
   976 		}
   977 	}
   978 
   979 EXPORT_C CX509CertPoliciesExt* CX509CertPoliciesExt::NewL(const TDesC8& aBinaryData)
   980 	{
   981 	TInt pos = 0;
   982 	return CX509CertPoliciesExt::NewL(aBinaryData, pos);
   983 	}
   984 
   985 EXPORT_C CX509CertPoliciesExt* CX509CertPoliciesExt::NewLC(const TDesC8& aBinaryData)
   986 	{
   987 	TInt pos = 0;
   988 	return CX509CertPoliciesExt::NewLC(aBinaryData, pos);
   989 	}
   990 
   991 EXPORT_C CX509CertPoliciesExt* CX509CertPoliciesExt::NewL(const TDesC8& aBinaryData, TInt& aPos)
   992 	{
   993 	CX509CertPoliciesExt* self = CX509CertPoliciesExt::NewLC(aBinaryData, aPos);
   994 	CleanupStack::Pop();
   995 	return self;
   996 	}
   997 
   998 EXPORT_C CX509CertPoliciesExt* CX509CertPoliciesExt::NewLC(const TDesC8& aBinaryData, TInt& aPos)
   999 	{
  1000 	CX509CertPoliciesExt* self = new(ELeave) CX509CertPoliciesExt;
  1001 	CleanupStack::PushL(self);
  1002 	self->ConstructL(aBinaryData, aPos);
  1003 	return self;
  1004 	}
  1005 
  1006 void CX509CertPoliciesExt::DoConstructL(const TDesC8& aBinaryData, TInt& aPos)
  1007 	{
  1008 	TASN1DecSequence encSeq;
  1009 	CArrayPtrFlat<TASN1DecGeneric>* seq = encSeq.DecodeDERLC(aBinaryData, aPos, 1, KMaxTInt);
  1010 	TInt count = seq->Count();
  1011 	iPolicies = new(ELeave) CArrayPtrFlat<CX509CertPolicyInfo> (1);
  1012 	TASN1DecGeneric* gen;
  1013 	for (TInt i = 0; i < count; i++)
  1014 		{
  1015 		gen = seq->At(i);
  1016 		CX509CertPolicyInfo* policy = CX509CertPolicyInfo::NewLC(gen->Encoding());
  1017 		iPolicies->AppendL(policy);
  1018 		CleanupStack::Pop();//policy
  1019 		}
  1020 	CleanupStack::PopAndDestroy();
  1021 	}
  1022 
  1023 CX509CertPoliciesExt::~CX509CertPoliciesExt()
  1024 	{
  1025 	if (iPolicies != NULL)
  1026 		{
  1027 		iPolicies->ResetAndDestroy();
  1028 		delete iPolicies;
  1029 		}
  1030 	}
  1031 
  1032 EXPORT_C const CArrayPtrFlat<CX509CertPolicyInfo>& CX509CertPoliciesExt::Policies() const
  1033 	{
  1034 	return *iPolicies;
  1035 	}
  1036 
  1037 CX509CertPoliciesExt::CX509CertPoliciesExt()
  1038 	{
  1039 	}
  1040 
  1041 //7) policy mapping
  1042 CX509PolicyMapping* CX509PolicyMapping::NewL(const TDesC8& aBinaryData)
  1043 	{
  1044 	TInt pos = 0;
  1045 	return CX509PolicyMapping::NewL(aBinaryData, pos);
  1046 	}
  1047 
  1048 CX509PolicyMapping* CX509PolicyMapping::NewLC(const TDesC8& aBinaryData)
  1049 	{
  1050 	TInt pos = 0;
  1051 	return CX509PolicyMapping::NewLC(aBinaryData, pos);
  1052 	}
  1053 
  1054 CX509PolicyMapping* CX509PolicyMapping::NewL(const TDesC8& aBinaryData, TInt& aPos)
  1055 	{
  1056 	CX509PolicyMapping* self = CX509PolicyMapping::NewLC(aBinaryData, aPos);
  1057 	CleanupStack::Pop();
  1058 	return self;
  1059 	}
  1060 
  1061 CX509PolicyMapping* CX509PolicyMapping::NewLC(const TDesC8& aBinaryData, TInt& aPos)
  1062 	{
  1063 	CX509PolicyMapping* self = new(ELeave) CX509PolicyMapping;
  1064 	CleanupStack::PushL(self);
  1065 	self->ConstructL(aBinaryData, aPos);
  1066 	return self;
  1067 	}
  1068 
  1069 EXPORT_C CX509PolicyMapping* CX509PolicyMapping::NewL(const CX509PolicyMapping& aMapping)
  1070 	{
  1071 	CX509PolicyMapping* self = CX509PolicyMapping::NewLC(aMapping);
  1072 	CleanupStack::Pop();
  1073 	return self;
  1074 	}
  1075 
  1076 EXPORT_C CX509PolicyMapping* CX509PolicyMapping::NewLC(const CX509PolicyMapping& aMapping)
  1077 	{
  1078 	CX509PolicyMapping* self = new(ELeave) CX509PolicyMapping;
  1079 	CleanupStack::PushL(self);
  1080 	self->ConstructL(aMapping);
  1081 	return self;
  1082 	}
  1083 
  1084 void CX509PolicyMapping::ConstructL(const CX509PolicyMapping& aMapping)
  1085 	{
  1086 	iIssuerPolicy = aMapping.iIssuerPolicy->AllocL();
  1087 	iSubjectPolicy = aMapping.iSubjectPolicy->AllocL();
  1088 	}
  1089 
  1090 void CX509PolicyMapping::ConstructL(const TDesC8& aBinaryData, TInt& aPos)
  1091 	{
  1092 	TASN1DecSequence encSeq;
  1093 	CArrayPtrFlat<TASN1DecGeneric>* seq = encSeq.DecodeDERLC(aBinaryData, aPos);
  1094 	if (seq->Count() < 2)
  1095 		{
  1096 		User::Leave(KErrArgument);
  1097 		}
  1098 	TASN1DecObjectIdentifier encOID;
  1099 	iIssuerPolicy = encOID.DecodeDERL(*(seq->At(0)));
  1100 	iSubjectPolicy = encOID.DecodeDERL(*(seq->At(1)));
  1101 	CleanupStack::PopAndDestroy();
  1102 	}
  1103 
  1104 CX509PolicyMapping::~CX509PolicyMapping()
  1105 	{
  1106 	delete iIssuerPolicy;
  1107 	delete iSubjectPolicy;
  1108 	}
  1109 
  1110 EXPORT_C TPtrC CX509PolicyMapping::IssuerPolicy() const
  1111 	{
  1112 	return iIssuerPolicy->Des();
  1113 	}
  1114 
  1115 EXPORT_C TPtrC CX509PolicyMapping::SubjectPolicy() const
  1116 	{
  1117 	return iSubjectPolicy->Des();
  1118 	}
  1119 
  1120 CX509PolicyMapping::CX509PolicyMapping()
  1121 	{
  1122 	}
  1123 
  1124 EXPORT_C CX509PolicyMappingExt* CX509PolicyMappingExt::NewL(const TDesC8& aBinaryData)
  1125 	{
  1126 	TInt pos = 0;
  1127 	return CX509PolicyMappingExt::NewL(aBinaryData, pos);
  1128 	}
  1129 
  1130 EXPORT_C CX509PolicyMappingExt* CX509PolicyMappingExt::NewLC(const TDesC8& aBinaryData)
  1131 	{
  1132 	TInt pos = 0;
  1133 	return CX509PolicyMappingExt::NewLC(aBinaryData, pos);
  1134 	}
  1135 
  1136 EXPORT_C CX509PolicyMappingExt* CX509PolicyMappingExt::NewL(const TDesC8& aBinaryData, TInt& aPos)
  1137 	{
  1138 	CX509PolicyMappingExt* self = CX509PolicyMappingExt::NewLC(aBinaryData, aPos);
  1139 	CleanupStack::Pop();
  1140 	return self;
  1141 	}
  1142 
  1143 EXPORT_C CX509PolicyMappingExt* CX509PolicyMappingExt::NewLC(const TDesC8& aBinaryData, TInt& aPos)
  1144 	{
  1145 	CX509PolicyMappingExt* self = new(ELeave) CX509PolicyMappingExt;
  1146 	CleanupStack::PushL(self);
  1147 	self->ConstructL(aBinaryData, aPos);
  1148 	return self;
  1149 	}
  1150 
  1151 void CX509PolicyMappingExt::DoConstructL(const TDesC8& aBinaryData, TInt& aPos)
  1152 	{
  1153 	TASN1DecSequence encSeq;
  1154 	CArrayPtrFlat<TASN1DecGeneric>* seq = encSeq.DecodeDERLC(aBinaryData, aPos, 1, KMaxTInt);
  1155 	TInt count = seq->Count();
  1156 
  1157 	iPolicies = new(ELeave) CArrayPtrFlat<CX509PolicyMapping> (1);
  1158 	TASN1DecGeneric* gen;
  1159 	for (TInt i = 0; i < count; i++)
  1160 		{
  1161 		gen = seq->At(i);
  1162 		CX509PolicyMapping* policy = CX509PolicyMapping::NewLC(gen->Encoding());
  1163 		iPolicies->AppendL(policy);
  1164 		CleanupStack::Pop();//policy
  1165 		}
  1166 	CleanupStack::PopAndDestroy();
  1167 	}
  1168 
  1169 CX509PolicyMappingExt::~CX509PolicyMappingExt()
  1170 	{
  1171 	if (iPolicies != NULL)
  1172 		{
  1173 		iPolicies->ResetAndDestroy();
  1174 		delete iPolicies;
  1175 		}
  1176 	}
  1177 
  1178 EXPORT_C const CArrayPtrFlat<CX509PolicyMapping>& CX509PolicyMappingExt::Mappings() const
  1179 	{
  1180 	return *iPolicies;
  1181 	}
  1182 
  1183 CX509PolicyMappingExt::CX509PolicyMappingExt()
  1184 	{
  1185 	}
  1186 
  1187 //8) authority key ID
  1188 EXPORT_C CX509AuthorityKeyIdExt* CX509AuthorityKeyIdExt::NewL(const TDesC8& aBinaryData)
  1189 	{
  1190 	TInt pos = 0;
  1191 	return CX509AuthorityKeyIdExt::NewL(aBinaryData, pos);
  1192 	}
  1193 
  1194 EXPORT_C CX509AuthorityKeyIdExt* CX509AuthorityKeyIdExt::NewLC(const TDesC8& aBinaryData)
  1195 	{
  1196 	TInt pos = 0;
  1197 	return CX509AuthorityKeyIdExt::NewLC(aBinaryData, pos);
  1198 	}
  1199 
  1200 EXPORT_C CX509AuthorityKeyIdExt* CX509AuthorityKeyIdExt::NewL(const TDesC8& aBinaryData, TInt& aPos)
  1201 	{
  1202 	CX509AuthorityKeyIdExt* self = CX509AuthorityKeyIdExt::NewLC(aBinaryData, aPos);
  1203 	CleanupStack::Pop();
  1204 	return self;
  1205 	}
  1206 
  1207 EXPORT_C CX509AuthorityKeyIdExt* CX509AuthorityKeyIdExt::NewLC(const TDesC8& aBinaryData, TInt& aPos)
  1208 	{
  1209 	CX509AuthorityKeyIdExt* self = new(ELeave) CX509AuthorityKeyIdExt;
  1210 	CleanupStack::PushL(self);
  1211 	self->ConstructL(aBinaryData, aPos);
  1212 	return self;
  1213 	}
  1214 
  1215 void CX509AuthorityKeyIdExt::DoConstructL(const TDesC8& aBinaryData, TInt& aPos)
  1216 	{
  1217 	TASN1DecSequence encSeq;
  1218 	CArrayPtrFlat<TASN1DecGeneric>* seq = encSeq.DecodeDERLC(aBinaryData, aPos);
  1219 	TInt count = seq->Count();
  1220 	TInt pos = 0;
  1221 
  1222 	iAuthorityName = new(ELeave) CArrayPtrFlat<CX509GeneralName> (1);
  1223 	TASN1DecGeneric* curr;
  1224 	if (pos < count)
  1225 		{
  1226 		curr = seq->At(pos);
  1227 		pos++;
  1228 		if (curr->Class() != EContextSpecific)
  1229 			{
  1230 			User::Leave(KErrArgument);
  1231 			}
  1232 		switch(curr->Tag())
  1233 			{
  1234 			case 0:
  1235 				{
  1236 				DecodeKeyIdL(curr->Encoding());
  1237 				break;
  1238 				}
  1239 			case 1:
  1240 				{
  1241 				DecodeNameL(curr->Encoding());
  1242 				break;
  1243 				}
  1244 			case 2:
  1245 				{
  1246 				DecodeSerialNoL(curr->Encoding());
  1247 				break;
  1248 				}
  1249 			default:
  1250 				{
  1251 				User::Leave(KErrArgument);
  1252 				}
  1253 			}
  1254 		if (pos < count)
  1255 			{
  1256 			curr = seq->At(pos);
  1257 			pos++;
  1258 			if (curr->Class() != EContextSpecific)
  1259 				{
  1260 				User::Leave(KErrArgument);
  1261 				}
  1262 			switch(curr->Tag())
  1263 				{
  1264 				case 1:
  1265 					{
  1266 					DecodeNameL(curr->Encoding());
  1267 					break;
  1268 					}
  1269 				case 2:
  1270 					{
  1271 					DecodeSerialNoL(curr->Encoding());
  1272 					break;
  1273 					}
  1274 				default:
  1275 					{
  1276 					User::Leave(KErrArgument);
  1277 					}
  1278 				}
  1279 			if (pos < count)
  1280 				{
  1281 				curr = seq->At(pos);
  1282 				pos++;
  1283 				if ((curr->Class() != EContextSpecific) || (curr->Tag() != 2))
  1284 					{
  1285 					User::Leave(KErrArgument);
  1286 					}
  1287 				DecodeSerialNoL(curr->Encoding());
  1288 				}
  1289 			}
  1290 		}
  1291 	if (!iKeyIdentifier)
  1292 		{
  1293 		iKeyIdentifier = HBufC8::NewL(1);
  1294 		*iKeyIdentifier = KNullDesC8;
  1295 		}
  1296 	if (!iAuthorityCertSerialNumber)
  1297 		{
  1298 		iAuthorityCertSerialNumber = HBufC8::NewL(1);
  1299 		*iAuthorityCertSerialNumber = KNullDesC8;
  1300 		}
  1301 	CleanupStack::PopAndDestroy();
  1302 	}
  1303 
  1304 void CX509AuthorityKeyIdExt::DecodeNameL(const TDesC8& aBinaryData)
  1305 	{
  1306 	TASN1DecSequence encSeq;
  1307 	TInt pos = 0;
  1308 	CArrayPtrFlat<TASN1DecGeneric>* seq = encSeq.DecodeDERLC(aBinaryData, pos, 1, KMaxTInt);
  1309 	TInt count = seq->Count();
  1310 	TASN1DecGeneric* gen;
  1311 	for (TInt i = 0; i < count; i++)
  1312 		{
  1313 		gen = seq->At(i);
  1314 		CX509GeneralName* gn = CX509GeneralName::NewLC(gen->Encoding());
  1315 		iAuthorityName->AppendL(gn);
  1316 		CleanupStack::Pop();//gn
  1317 		}
  1318 	CleanupStack::PopAndDestroy();
  1319 	}
  1320 
  1321 void CX509AuthorityKeyIdExt::DecodeKeyIdL(const TDesC8& aBinaryData)
  1322 	{
  1323 	TASN1DecGeneric gen(aBinaryData);
  1324 	gen.InitL();
  1325 	if (iKeyIdentifier != NULL)
  1326 		{
  1327 		User::Leave(KErrArgument);
  1328 		}
  1329 	iKeyIdentifier = gen.GetContentDER().AllocL();
  1330 	}
  1331 
  1332 void CX509AuthorityKeyIdExt::DecodeSerialNoL(const TDesC8& aBinaryData)
  1333 	{
  1334 	TASN1DecGeneric gen(aBinaryData);
  1335 	gen.InitL();
  1336 	if (iAuthorityCertSerialNumber != NULL)
  1337 		{
  1338 		User::Leave(KErrArgument);
  1339 		}
  1340 	iAuthorityCertSerialNumber = gen.GetContentDER().AllocL();
  1341 	}
  1342 
  1343 CX509AuthorityKeyIdExt::~CX509AuthorityKeyIdExt()
  1344 	{
  1345 	if (iAuthorityName != NULL)
  1346 		{
  1347 		iAuthorityName->ResetAndDestroy();
  1348 		}
  1349 	delete iAuthorityName;
  1350 	delete iAuthorityCertSerialNumber;
  1351 	delete iKeyIdentifier;
  1352 	}
  1353 
  1354 EXPORT_C const CArrayPtrFlat<CX509GeneralName>& CX509AuthorityKeyIdExt::AuthorityName() const
  1355 	{
  1356 	return *iAuthorityName;
  1357 	}
  1358 
  1359 EXPORT_C TPtrC8 CX509AuthorityKeyIdExt::AuthorityCertSerialNumber() const
  1360 	{
  1361 	return iAuthorityCertSerialNumber->Des();
  1362 	}
  1363 
  1364 EXPORT_C TPtrC8 CX509AuthorityKeyIdExt::KeyId() const
  1365 	{
  1366 	return iKeyIdentifier->Des();
  1367 	}
  1368 
  1369 CX509AuthorityKeyIdExt::CX509AuthorityKeyIdExt()
  1370 	{
  1371 	}
  1372 
  1373 //9) subject key ID
  1374 EXPORT_C CX509SubjectKeyIdExt* CX509SubjectKeyIdExt::NewL(const TDesC8& aBinaryData)
  1375 	{
  1376 	TInt pos = 0;
  1377 	return CX509SubjectKeyIdExt::NewL(aBinaryData, pos);
  1378 	}
  1379 
  1380 EXPORT_C CX509SubjectKeyIdExt* CX509SubjectKeyIdExt::NewLC(const TDesC8& aBinaryData)
  1381 	{
  1382 	TInt pos = 0;
  1383 	return CX509SubjectKeyIdExt::NewLC(aBinaryData, pos);
  1384 	}
  1385 
  1386 EXPORT_C CX509SubjectKeyIdExt* CX509SubjectKeyIdExt::NewL(const TDesC8& aBinaryData, TInt& aPos)
  1387 	{
  1388 	CX509SubjectKeyIdExt* self = CX509SubjectKeyIdExt::NewLC(aBinaryData, aPos);
  1389 	CleanupStack::Pop();
  1390 	return self;
  1391 	}
  1392 
  1393 EXPORT_C CX509SubjectKeyIdExt* CX509SubjectKeyIdExt::NewLC(const TDesC8& aBinaryData, TInt& aPos)
  1394 	{
  1395 	CX509SubjectKeyIdExt* self = new(ELeave) CX509SubjectKeyIdExt;
  1396 	CleanupStack::PushL(self);
  1397 	self->ConstructL(aBinaryData, aPos);
  1398 	return self;
  1399 	}
  1400 
  1401 void CX509SubjectKeyIdExt::DoConstructL(const TDesC8& aBinaryData, TInt& aPos)
  1402 	{
  1403 	TASN1DecOctetString octetStr;
  1404 	iKeyIdentifier = octetStr.DecodeDERL(aBinaryData, aPos);
  1405 	}
  1406 
  1407 EXPORT_C CX509SubjectKeyIdExt::~CX509SubjectKeyIdExt()
  1408 	{
  1409 	delete iKeyIdentifier;
  1410 	}
  1411 
  1412 EXPORT_C TPtrC8 CX509SubjectKeyIdExt::KeyId() const
  1413 	{
  1414 	return iKeyIdentifier->Des();
  1415 	}
  1416 
  1417 CX509SubjectKeyIdExt::CX509SubjectKeyIdExt()
  1418 	{
  1419 	}
  1420 
  1421 //10) extended key usage
  1422 EXPORT_C CX509ExtendedKeyUsageExt* CX509ExtendedKeyUsageExt::NewL(const TDesC8& aBinaryData)
  1423 	{
  1424 	TInt pos = 0;
  1425 	return CX509ExtendedKeyUsageExt::NewL(aBinaryData, pos);
  1426 	}
  1427 
  1428 EXPORT_C CX509ExtendedKeyUsageExt* CX509ExtendedKeyUsageExt::NewLC(const TDesC8& aBinaryData)
  1429 	{
  1430 	TInt pos = 0;
  1431 	return CX509ExtendedKeyUsageExt::NewLC(aBinaryData, pos);
  1432 	}
  1433 
  1434 EXPORT_C CX509ExtendedKeyUsageExt* CX509ExtendedKeyUsageExt::NewL(const TDesC8& aBinaryData, TInt& aPos)
  1435 	{
  1436 	CX509ExtendedKeyUsageExt* self = CX509ExtendedKeyUsageExt::NewLC(aBinaryData, aPos);
  1437 	CleanupStack::Pop();
  1438 	return self;
  1439 	}
  1440 
  1441 EXPORT_C CX509ExtendedKeyUsageExt* CX509ExtendedKeyUsageExt::NewLC(const TDesC8& aBinaryData, TInt& aPos)
  1442 	{
  1443 	CX509ExtendedKeyUsageExt* self = new(ELeave) CX509ExtendedKeyUsageExt;
  1444 	CleanupStack::PushL(self);
  1445 	self->ConstructL(aBinaryData, aPos);
  1446 	return self;
  1447 	}
  1448 
  1449 void CX509ExtendedKeyUsageExt::DoConstructL(const TDesC8& aBinaryData, TInt& aPos)
  1450 	{
  1451 	TASN1DecSequence encSeq;
  1452 	CArrayPtrFlat<TASN1DecGeneric>* seq = encSeq.DecodeDERLC(aBinaryData, aPos, 1, KMaxTInt);
  1453 	TInt count = seq->Count();
  1454 
  1455 	iKeyUsages = new(ELeave) CArrayPtrFlat<HBufC> (1);
  1456 	TASN1DecGeneric* gen;
  1457 	for (TInt i = 0; i < count; i++)
  1458 		{
  1459 		gen = seq->At(i);
  1460 		TASN1DecObjectIdentifier encOID;
  1461 		HBufC* usage = encOID.DecodeDERL(*gen);
  1462 		CleanupStack::PushL(usage);
  1463 		iKeyUsages->AppendL(usage);
  1464 		CleanupStack::Pop();
  1465 		}
  1466 	CleanupStack::PopAndDestroy();
  1467 	}
  1468 
  1469 EXPORT_C CX509ExtendedKeyUsageExt::~CX509ExtendedKeyUsageExt()
  1470 	{
  1471 	if (iKeyUsages != NULL)
  1472 		{
  1473 		iKeyUsages->ResetAndDestroy();
  1474 		delete iKeyUsages;
  1475 		}
  1476 	}
  1477 
  1478 EXPORT_C const CArrayPtrFlat<HBufC>& CX509ExtendedKeyUsageExt::KeyUsages() const
  1479 	{
  1480 	return *iKeyUsages;
  1481 	}
  1482 
  1483 CX509ExtendedKeyUsageExt::CX509ExtendedKeyUsageExt()
  1484 	{
  1485 	}
  1486 
  1487 //12) authority information access - CX509AccessDescription
  1488 
  1489 CX509AccessDescription* CX509AccessDescription::NewL(const TDesC8& aBinaryData)
  1490 	{
  1491 	TInt pos = 0;
  1492 	return NewL(aBinaryData, pos);
  1493 	}
  1494 
  1495 CX509AccessDescription* CX509AccessDescription::NewLC(const TDesC8& aBinaryData)
  1496 	{
  1497 	TInt pos = 0;
  1498 	return NewLC(aBinaryData, pos);
  1499 	}
  1500 
  1501 CX509AccessDescription* CX509AccessDescription::NewL(const TDesC8& aBinaryData, TInt& aPos)
  1502 	{
  1503 	CX509AccessDescription* self = NewLC(aBinaryData, aPos);
  1504 	CleanupStack::Pop(self);
  1505 	return self;
  1506 	}
  1507 
  1508 CX509AccessDescription* CX509AccessDescription::NewLC(const TDesC8& aBinaryData, TInt& aPos)
  1509 	{
  1510 	CX509AccessDescription* self = new (ELeave) CX509AccessDescription;
  1511 	CleanupStack::PushL(self);
  1512 	self->ConstructL(aBinaryData, aPos);
  1513 	return self;
  1514 	}
  1515 
  1516 CX509AccessDescription::CX509AccessDescription()
  1517 	{
  1518 	// empty
  1519 	}
  1520 
  1521 void CX509AccessDescription::ConstructL(const TDesC8& aBinaryData, TInt& aPos)
  1522 	{
  1523 	TASN1DecSequence encSeq;
  1524 	CArrayPtrFlat<TASN1DecGeneric>* seq = encSeq.DecodeDERLC(aBinaryData, aPos, 2, 2);
  1525 
  1526 	TASN1DecGeneric* curr = seq->At(0);
  1527 	TASN1DecObjectIdentifier encOID;
  1528 	iMethodId = encOID.DecodeDERL(*curr);
  1529 
  1530 	curr = seq->At(1);
  1531 	iLocation = CX509GeneralName::NewL(curr->Encoding());	
  1532 
  1533 	CleanupStack::PopAndDestroy(seq);
  1534 	}
  1535 
  1536 CX509AccessDescription::~CX509AccessDescription()
  1537 	{
  1538 	delete iMethodId;
  1539 	delete iLocation;
  1540 	}
  1541 
  1542 EXPORT_C TPtrC CX509AccessDescription::Method() const
  1543 	{
  1544 	return *iMethodId;
  1545 	}
  1546 
  1547 EXPORT_C const CX509GeneralName& CX509AccessDescription::Location() const
  1548 	{
  1549 	return *iLocation;
  1550 	}
  1551 
  1552 //12) authority information access - CX509AuthInfoAccessExt
  1553 
  1554 EXPORT_C CX509AuthInfoAccessExt* CX509AuthInfoAccessExt::NewL(const TDesC8& aBinaryData)
  1555 	{
  1556 	TInt pos = 0;
  1557 	return NewL(aBinaryData, pos);
  1558 	}
  1559 
  1560 EXPORT_C CX509AuthInfoAccessExt* CX509AuthInfoAccessExt::NewLC(const TDesC8& aBinaryData)
  1561 	{
  1562 	TInt pos = 0;
  1563 	return NewLC(aBinaryData, pos);
  1564 	}
  1565 
  1566 EXPORT_C CX509AuthInfoAccessExt* CX509AuthInfoAccessExt::NewL(const TDesC8& aBinaryData, TInt& aPos)
  1567 	{
  1568 	CX509AuthInfoAccessExt* self = NewLC(aBinaryData, aPos);
  1569 	CleanupStack::Pop(self);
  1570 	return self;
  1571 	}
  1572 
  1573 EXPORT_C CX509AuthInfoAccessExt* CX509AuthInfoAccessExt::NewLC(const TDesC8& aBinaryData, TInt& aPos)
  1574 	{
  1575 	CX509AuthInfoAccessExt* self = new (ELeave) CX509AuthInfoAccessExt;
  1576 	CleanupStack::PushL(self);
  1577 	self->ConstructL(aBinaryData, aPos);
  1578 	return self;
  1579 	}
  1580 
  1581 CX509AuthInfoAccessExt::CX509AuthInfoAccessExt()
  1582 	{
  1583 	// empty
  1584 	}
  1585 
  1586 void CX509AuthInfoAccessExt::DoConstructL(const TDesC8& aBinaryData, TInt& aPos)
  1587  	{
  1588 	TASN1DecSequence encSeq;
  1589 	CArrayPtrFlat<TASN1DecGeneric>* seq = encSeq.DecodeDERLC(aBinaryData, aPos, 1, KMaxTInt);
  1590 	TInt count = seq->Count();
  1591 
  1592 	iAccessDescs = new (ELeave) CArrayPtrFlat<CX509AccessDescription>(1);
  1593 
  1594 	for (TInt i = 0 ; i < count ; ++i)
  1595 		{
  1596 		TASN1DecGeneric* curr = seq->At(i);
  1597 		CX509AccessDescription* desc = CX509AccessDescription::NewLC(curr->Encoding());
  1598 		iAccessDescs->AppendL(desc);
  1599 		CleanupStack::Pop(desc);
  1600 		}
  1601 
  1602 	CleanupStack::PopAndDestroy(seq);
  1603 	}
  1604 
  1605 EXPORT_C CX509AuthInfoAccessExt::~CX509AuthInfoAccessExt()
  1606 	{
  1607 	if (iAccessDescs)
  1608 		{
  1609 		iAccessDescs->ResetAndDestroy();
  1610 		delete iAccessDescs;
  1611 		}
  1612 	}
  1613 
  1614 EXPORT_C const CArrayPtrFlat<CX509AccessDescription>& CX509AuthInfoAccessExt::AccessDescriptions() const
  1615 	{
  1616 	return *iAccessDescs;
  1617 	}