os/security/cryptoservices/certificateandkeymgmt/tpkcs12intgrtn/src/tpkcs12common.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 /*
     2 * Copyright (c) 2005-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 * This file contains the implementation of the CPkcs12Parser class, to parse the PKCS#12 file.
    16 *
    17 */
    18 
    19 
    20 /**
    21  @file 
    22  @internalTechnology
    23 */
    24 
    25 // System Include
    26 #include <f32file.h>
    27 
    28 //User Include 
    29 #include "tpkcs12common.h"
    30 using namespace PKCS12;
    31 /**
    32 Description:constructor
    33 @internalTechnology:
    34 @test
    35 */
    36 CPkcs12Parser::CPkcs12Parser()
    37 	{
    38 	}
    39 /**
    40 Description:destructor
    41 @internalTechnology:
    42 @test
    43 */
    44 CPkcs12Parser::~CPkcs12Parser()
    45 	{
    46 	delete iIntegrityPassword;	
    47 	delete iRawData;	
    48 	delete iPkcs12Header;
    49 	iArraySafecontentBag.ResetAndDestroy();
    50 	iArrayBagData.ResetAndDestroy();
    51 	}
    52 
    53 /**
    54 Description:Function is intended to creates a new CPKCS12Parser object.	 
    55 @return:CPKCS12Parser* : parser object to parse the PKCS12 file
    56 @internalTechnology
    57 @test
    58 */
    59 CPkcs12Parser* CPkcs12Parser::NewL()
    60 	{	
    61 	CPkcs12Parser* parser = NewLC();
    62 	CleanupStack::Pop(parser);	
    63 	return parser;
    64 	}
    65 /**
    66 Description:Function is intended to creates a new CPKCS12Parser object.	 
    67 @return:CPKCS12Parser* : parser object to parse the PKCS12 file
    68 @test
    69 */
    70 CPkcs12Parser* CPkcs12Parser::NewLC()
    71 	{	
    72 	CPkcs12Parser* parser = new (ELeave) CPkcs12Parser();
    73 	CleanupStack::PushL(parser);	
    74 	return parser;
    75 	}
    76 /**
    77 Description:Function is intended to set the integrity password 
    78 @param	aIntegrityPassword, contains the integrity password
    79 @internalTechnology
    80 @test
    81 */
    82 void CPkcs12Parser::SetIntegrityPasswordL(const TDesC& aIntegrityPassword)
    83 	{
    84 	iIntegrityPassword = aIntegrityPassword.AllocL();
    85 	}
    86 
    87 /**
    88 Description:Function is intended to set the privacy password(s) 
    89 @param aPrivacyPassword, contains  the privacy passwords.The ownership is not transferred
    90 @internalTechnology
    91 @test
    92 */
    93 void CPkcs12Parser::SetPrivacyPassword(RPointerArray<TDesC>& aPrivacyPassword)
    94 	{
    95 	iPrivacyPassword = 	&aPrivacyPassword;
    96 	}
    97 /**
    98 Description:Function is intended to set the test data. 
    99 			It opens the data file and stores it in the buffer.
   100 @param aDatapath, contains the path of the PKCS12 file
   101 @internalTechnology
   102 @test
   103 */
   104 void CPkcs12Parser::SetDataL(const TDesC& aDatapath)
   105 	{ 	
   106 	if(iRawData)
   107 		{
   108 		delete iRawData ;
   109 		iRawData  = NULL;
   110 		}
   111 	RFs fs;
   112 	//connects the file server
   113 	User::LeaveIfError (fs.Connect());
   114 	//opens the data file
   115 	CleanupClosePushL(fs);
   116 	RFile file;
   117 	User::LeaveIfError(file.Open(fs, aDatapath, EFileRead)) ; 
   118 	CleanupClosePushL(file);
   119 	
   120 	TInt fileSize = 0;
   121 	User::LeaveIfError(file.Size(fileSize));	
   122 
   123 	iRawData = HBufC8::NewL(fileSize);
   124 	TPtr8 rawData(iRawData->Des());
   125 	rawData.SetLength(fileSize);	
   126 	file.Read (rawData);
   127 
   128 	CleanupStack::PopAndDestroy(&file);
   129 	//closes the file session
   130 	CleanupStack::PopAndDestroy(&fs);
   131 	}
   132 /**
   133 Description:Function is intended to parse the PKCS#12 data
   134 @leave:- if the number of contentinfos and number of privacy passwords does not match.	
   135 @internalTechnology
   136 @test
   137 */
   138 void CPkcs12Parser::ParseL()
   139 	{
   140 	//creates the CDecPkcs12 object		
   141 	CDecPkcs12* decPkcs12 = NULL;
   142 	TRAPD(error, decPkcs12	= CDecPkcs12::NewL(*iRawData));
   143 	if(error == KErrNone)
   144 		CleanupStack::PushL(decPkcs12);	
   145 
   146 	//Creates a CPfxHeader object
   147 	iPkcs12Header = CPfxHeader::NewL(*decPkcs12 , error);	
   148 	if(error != KErrNone)
   149 		{
   150 		
   151 		return ;	
   152 		}
   153 	const CDecPkcs12MacData* macData = decPkcs12->MacData();
   154 	TRAPD(err,macData->VerifyIntegrityL(iIntegrityPassword->Des()));
   155 	if(err)
   156 		{
   157 		iPkcs12Header->SetPkcs12ActualError(err);
   158 		CleanupStack::PopAndDestroy(decPkcs12);
   159 		return;
   160 		}
   161 	//get the ContentInfo collection
   162 	const RPointerArray<CPKCS7ContentInfo>& contentInfos = decPkcs12->AuthenticatedSafeContents();	
   163 	TInt contentInfoCount = contentInfos.Count();
   164 	//put the content info count in the Header
   165 	iPkcs12Header->SetContentInfoCount(contentInfoCount) ;
   166 
   167 	// start iterate through the contentinfos
   168 	for(TInt index = 0 ; index < contentInfoCount; index++)
   169 		{
   170 		TInt contentType = contentInfos[index]->ContentType() ; 
   171 		TPtrC8 contentData = contentInfos[index]->ContentData();
   172 		if( contentData == KNullDesC8()) 
   173 			{
   174 			iPkcs12Header->SetPkcs12ActualError(0);
   175 			continue;
   176 			}
   177 		CDecPkcs12SafeContents* pkcs12SafeContents = NULL;			
   178 		switch(contentType)
   179 			{
   180 			case CPKCS7ContentInfo::EContentTypeData:
   181 				{
   182 				TRAPD(error1,pkcs12SafeContents = CDecPkcs12SafeContents::NewL(*contentInfos[index]));	
   183 				if(error1)
   184 					{
   185 					iPkcs12Header->SetPkcs12ActualError(error1);
   186 					CSafeBagData* bagData = NULL; 
   187 					bagData = CreateBagDataL(index,contentType);
   188 					iArrayBagData.AppendL(bagData) ;
   189 					CleanupStack::PopAndDestroy(decPkcs12);
   190 					return;
   191 					}	
   192 				CleanupStack::PushL(pkcs12SafeContents);			
   193 				break;
   194 				}
   195 			case CPKCS7ContentInfo::EContentTypeEncryptedData:
   196 				{
   197 				if(contentInfoCount != iPrivacyPassword->Count())	
   198 					{
   199 					User::Leave(KErrArgument);
   200 					}
   201 						
   202 				TRAPD(error2,pkcs12SafeContents = CDecPkcs12SafeContents::NewL(*contentInfos[index],
   203 																	*((*iPrivacyPassword)[index]) ) );
   204 				if(error2)
   205 					{
   206 					iPkcs12Header->SetPkcs12ActualError(error2);
   207 					CSafeBagData* bagData = NULL; 
   208 					bagData = CreateBagDataL(index,contentType);
   209 					iArrayBagData.AppendL(bagData) ;
   210 					CleanupStack::PopAndDestroy(decPkcs12);
   211 					return;
   212 					}							
   213 				CleanupStack::PushL(pkcs12SafeContents);	
   214 				break;							
   215 				}
   216 			case CPKCS7ContentInfo::EContentTypeEnvelopedData:
   217 				{
   218 				//creates a Bagdata object in the heap to store the content type. 
   219 				CSafeBagData* bagData = CreateBagDataL(index+1 ,contentType);
   220 				iArrayBagData.AppendL(bagData) ;
   221 				//continue in the loop
   222 				continue;
   223 				}
   224 
   225 			default:
   226 				{	
   227 				//continue in the loop
   228 				continue;
   229 				}
   230 			}
   231 		// Get the safebags count.
   232 		const RPointerArray<CDecPkcs12SafeBag>& safeBags = pkcs12SafeContents->SafeContentsBags();
   233 		TInt safeBagCount = safeBags.Count();
   234 	
   235 		
   236 		//start parsing the bags
   237 		for (TInt bagsCount=0; bagsCount < safeBagCount; bagsCount++)
   238 			{	
   239 			TRAPD(error3,ParseSafeBagL(index+1, contentType , *safeBags[bagsCount]));
   240 			if(error3 != KErrNone)
   241 				{
   242 				iPkcs12Header->SetPkcs12ActualError(error3);
   243 				CSafeBagData* bagData = NULL; 
   244 				bagData = CreateBagDataL(index,contentType);
   245 				iArrayBagData.AppendL(bagData) ;
   246 				CleanupStack::PopAndDestroy(2,decPkcs12);
   247 				return;
   248 				}	
   249 			}	
   250 			CleanupStack::PopAndDestroy(pkcs12SafeContents);
   251 		}		
   252 	CleanupStack::PopAndDestroy(decPkcs12);	
   253 
   254 	}
   255 
   256 /**
   257 Description: Creates a CSafeBagData to store the safebag details
   258 @param:aContentInfo, the contentinfo number of the safe bag 
   259 @param:aContentType, the content type of the safe contents.
   260 @return:a pointer to CSafeBagData, which is used to store the safebag details 
   261 @internalTechnology:
   262 @test:
   263 */
   264 CSafeBagData* CPkcs12Parser::CreateBagDataL(TInt aContentInfo, TInt aContentType)
   265 	{
   266 	CSafeBagData* bagData = CSafeBagData::NewL();	
   267 	if ( iPkcs12Header->Pkcs12ActualError() == KErrNone )
   268 		{
   269 		//set the contentinfo # and content type in CSafeBagData
   270 		bagData->SetContentInfoNumber(aContentInfo);	
   271 		bagData->SetBagNumber(++iSafebagNumber );	
   272 		// set the content type in CSafeBagData		
   273 		bagData->SetContentInfoType(aContentType);
   274 		}
   275 	return bagData ;
   276 	}
   277 
   278 /**
   279 Description:To parse the safebags
   280 @param:aContentInfoIndex	content info number
   281 @param:aContentType	contentinfo type
   282 @param:aSafeBag	reference to the CDecPkcs12SafeBag 
   283 @internalTechnology:
   284 @test:
   285 */
   286 void CPkcs12Parser::ParseSafeBagL(TInt aContentInfo,TInt aContentType,CDecPkcs12SafeBag& aSafeBag)
   287 	{
   288 	//get the bag type 
   289 	CDecPkcs12SafeBag::TBagId bagType = aSafeBag.BagID();
   290 	switch(bagType)
   291 		{
   292 		case CDecPkcs12SafeBag::ESafeContentsBag:
   293 			{
   294 			CDecPkcs12SafeContentsBag* safeContentsBag = static_cast<CDecPkcs12SafeContentsBag *>(&aSafeBag);
   295 			// increment the count
   296 			iPkcs12Header->IncrementSafecontentBagCount();
   297 			// parsing code to parse SafeContentsBag		
   298 			ParseSafeContentBagL(*safeContentsBag, aContentInfo ,aContentType );
   299 			break;
   300 			}
   301 		case CDecPkcs12SafeBag::EKeyBag:
   302 			{
   303 			CDecPkcs12KeyBag* keyBag = static_cast<CDecPkcs12KeyBag *>(&aSafeBag);					
   304 			//create the CSafeBagData object in heap to store the bag details
   305 			CSafeBagData* bagData = CreateBagDataL(aContentInfo,aContentType);
   306 			CleanupStack::PushL(bagData);			
   307 			ParseKeyBag(*keyBag , *bagData);
   308 			//get the safeBag attributes
   309 			BagAttributesL(*keyBag ,*bagData) ;	
   310 			iArrayBagData.AppendL(bagData) ;
   311 			CleanupStack::Pop(bagData);					
   312 			break;
   313 			}
   314 		case CDecPkcs12SafeBag::EShroudedKeyBag:
   315 			{
   316 			CDecPkcs12ShroudedKeyBag* shroudedkeyBag = static_cast<CDecPkcs12ShroudedKeyBag *>(&aSafeBag);
   317 			//create the CSafeBagData object in heap to store the bag details
   318 			CSafeBagData* bagData = CreateBagDataL(aContentInfo,aContentType );
   319 			CleanupStack::PushL(bagData);			
   320 			ParseShroudedKeyBagL(*shroudedkeyBag , *bagData ,aContentInfo );		
   321 			//get the safeBag attributes
   322 			BagAttributesL(*shroudedkeyBag ,*bagData) ;	
   323 			iArrayBagData.AppendL(bagData) ;	
   324 			CleanupStack::Pop(bagData);			
   325 			break;
   326 			}
   327 		case CDecPkcs12SafeBag::ECertBag:
   328 			{
   329 			CDecPkcs12CertBag* certBag = static_cast<CDecPkcs12CertBag *>(&aSafeBag);					
   330 			//create the CSafeBagData object in heap to store the bag details
   331 			CSafeBagData* bagData = CreateBagDataL(aContentInfo,aContentType);
   332 			CleanupStack::PushL(bagData);		
   333 			ParseCertBag(*certBag , *bagData);
   334 			// Get the bag Attributes
   335 			BagAttributesL(*certBag , *bagData) ;	
   336 			iArrayBagData.AppendL(bagData) ;
   337 			CleanupStack::Pop(bagData);			
   338 			break;
   339 			}
   340 		case CDecPkcs12SafeBag::ECrlBag:
   341 			{
   342 			//create the CSafeBagData object in heap to store the bag details
   343 			CSafeBagData* bagData = CreateBagDataL(aContentInfo,aContentType);;
   344 			CleanupStack::PushL(bagData);				
   345 			//set the bagId in CSafeBagData
   346 			bagData->SetBagType(bagType) ; 
   347 			//increment the count - unsupported
   348 			iPkcs12Header->IncrementCrlBagCount();
   349 			iArrayBagData.AppendL(bagData) ;
   350 			CleanupStack::Pop(bagData);				
   351 			break;
   352 			}
   353 		case CDecPkcs12SafeBag::ESecretBag:
   354 			{
   355 			//create the CSafeBagData object in heap to store the bag details
   356 			CSafeBagData* bagData = CreateBagDataL(aContentInfo,aContentType );	
   357 			CleanupStack::PushL(bagData);
   358 			//set the iBagId in CSafeBagData
   359 			bagData->SetBagType(bagType) ; 
   360 			//increment the count - unsupported
   361 			iPkcs12Header->IncrementSecretBagCount();
   362 			iArrayBagData.AppendL(bagData) ;		
   363 			CleanupStack::Pop(bagData);	
   364 			break;
   365 			}
   366 		default:
   367 			{
   368 			}
   369 		}
   370 	}
   371 
   372 /**
   373 Description:Function is intended to get the attributes of Safebag
   374 @param-aSafeBag: reference to the CDecPkcs12SafeBag.
   375 @param-abagData: reference to the CSafeBagData
   376 @internalTechnology:
   377 @test
   378 */
   379 void CPkcs12Parser::BagAttributesL(const CDecPkcs12SafeBag& aSafeBag,CSafeBagData& aBagData )
   380 	{
   381 	const RPointerArray<CDecPkcs12Attribute>& safeBagAttributes = aSafeBag.BagAttributes();
   382 
   383 	TInt attributeCount = safeBagAttributes.Count() ;
   384 	for (TInt index = 0;index < attributeCount; index++ )
   385 		{						
   386 		//get the attribute object pointer
   387 		CDecPkcs12Attribute* attribute = safeBagAttributes[index];
   388 		//create the CSafeBagAttribute object in heap.	
   389 		CSafeBagAttribute* bagAttr = CSafeBagAttribute::NewL(*safeBagAttributes[index]);
   390 		CleanupStack::PushL(bagAttr);
   391 		//get the attribute values
   392 		const RPointerArray<TDesC8>& attrValues = attribute->AttributeValue();			
   393 		//append the pointer in the iAttributeIDs array
   394 		aBagData.iAttributeIDs.AppendL(bagAttr) ;
   395 		CleanupStack::Pop(bagAttr);	
   396 		//store the attribute values
   397 		TInt numberOfAttributes = bagAttr->AttributeValueCount();
   398 		for(TInt attrvalCnt = 0 ; attrvalCnt < numberOfAttributes ; attrvalCnt++)
   399 			{
   400 			//get the atribute value and store the it address in the aBagData.iAttributeValues array				
   401 			HBufC8* ptr =  attrValues[attrvalCnt]->AllocLC();								
   402 			aBagData.iAttributeValues.AppendL(ptr);
   403 			CleanupStack::Pop(ptr);
   404 			}			
   405 		}	
   406 	}
   407 /**
   408 Description:Function is intended to parse the  keybag
   409 @param-aKeyBag: reference to the keybag
   410 @param-abagData: reference to the CSafeBagData
   411 @internalTechnology:
   412 @test:
   413 */
   414 void CPkcs12Parser::ParseKeyBag(CDecPkcs12KeyBag& aKeyBag , CSafeBagData& aBagData)
   415 	{
   416 	//set the bagID
   417 	aBagData.SetBagType( CDecPkcs12SafeBag::EKeyBag ); 				
   418 	// Get the Algorithm(RSA key or DSA key) ID 
   419 	CDecPKCS8Data* pkcs8Data = aKeyBag.PrivateKeyInfoL();				
   420 	aBagData.SetPrivateKeyInfoVersion(pkcs8Data->Version() );
   421 	TAlgorithmId algorithmId = pkcs8Data->Algorithm();
   422 	// Set the Algorithm Id in CSafeBagData
   423 	aBagData.SetKeyType( algorithmId );
   424 	//set the bag value in CSafeBagData
   425 	aBagData.SetBagValue( aKeyBag.BagValue());				
   426 	// increment the count
   427 	iPkcs12Header->IncrementKeyBagCount();
   428 	delete pkcs8Data;
   429 	}
   430 /**
   431 Description:Function is intended to parse the  ShroudedKeyBag
   432 @param-aShroudedkeyBag: pointer to the CDecPkcs12ShroudedKeyBag
   433 @param-abagData: reference to the CSafeBagData
   434 @param- aPassIndex: the index of the array from where the privacy password is to be taken
   435 @internalTechnology:
   436 @test
   437 */
   438 void CPkcs12Parser::ParseShroudedKeyBagL(CDecPkcs12ShroudedKeyBag& aShroudedkeyBag , CSafeBagData& aBagData , TInt aPassIndex)
   439 	{
   440 	//set the bag Id in CSafeBagData
   441 	aBagData.SetBagType( CDecPkcs12SafeBag::EShroudedKeyBag ); 				
   442 	// Get the Algorithm(RSA key or DSA key) ID 
   443 	CDecPKCS8Data* pkcs8Data = aShroudedkeyBag.PrivateKeyInfoL(*(*iPrivacyPassword)[aPassIndex-1]);
   444 	if(pkcs8Data)
   445 		{
   446 		aBagData.SetPrivateKeyInfoVersion(pkcs8Data->Version() );	
   447 		TAlgorithmId algorithm  = pkcs8Data->Algorithm();	
   448 		// Set the Algorithm Id in CSafeBagData
   449 		aBagData.SetKeyType(algorithm);
   450 	
   451 		CASN1EncSequence* seq = NULL ;
   452 		switch(algorithm)
   453 			{
   454 			case ERSA:
   455 				{	
   456 				
   457 				CPKCS8KeyPairRSA* keypair = static_cast<CPKCS8KeyPairRSA*>(pkcs8Data->KeyPairData());
   458 
   459 				const CRSAPrivateKey& priv = keypair->PrivateKey();
   460 				
   461 				const CRSAPublicKey& publicKey = keypair->PublicKey(); 
   462 				
   463 				TRSAPrivateKeyType keytype = priv.PrivateKeyType();
   464 				
   465 				switch(keytype)
   466 					{
   467 					case EStandardCRT:
   468 						{
   469 						const CRSAPrivateKeyCRT* privateKeyCRT = static_cast<const CRSAPrivateKeyCRT*>(&priv);
   470 						seq =  TASN1EncPKCS8::EncodeL(*privateKeyCRT, publicKey,pkcs8Data->PKCS8Attributes());	
   471 					
   472 						break;
   473 						}					
   474 					case EStandard:		
   475 						{
   476 						User::Leave(KErrNotSupported);
   477 						}
   478 					default:
   479 						{
   480 						User::Leave(KErrNotSupported);	
   481 						}
   482 					}
   483 					
   484 				break;
   485 				}		
   486 			case EDSA:
   487 				{
   488 				
   489 				CPKCS8KeyPairDSA* keypair = static_cast<CPKCS8KeyPairDSA*>(pkcs8Data->KeyPairData());
   490 			
   491 				const CDSAPrivateKey& priv = keypair->PrivateKey();
   492 				
   493 				seq =  TASN1EncPKCS8::EncodeL(priv , pkcs8Data->PKCS8Attributes());
   494 			
   495 				break;
   496 				}			
   497 			default:
   498 				User::Leave(KErrNotSupported);
   499 
   500 			}
   501 	
   502 		HBufC8* bufSeq = HBufC8::NewMaxLC(seq->LengthDER());
   503 		TPtr8 temp(bufSeq->Des());
   504 
   505 		TUint pos = 0;
   506 		seq->WriteDERL(temp ,pos);
   507 			
   508 		aBagData.SetEncodedShroudedKey(temp);
   509 		CleanupStack::PopAndDestroy();
   510 
   511 		delete pkcs8Data;
   512 		}
   513 		//set the bag value in CSafeBagData
   514 		aBagData.SetBagValue(aShroudedkeyBag.BagValue()) ;				
   515 		// increment the count 
   516 		iPkcs12Header->IncrementShroudedKeyBagCount();											
   517 	}
   518 
   519 /**
   520 Description:Function is intended to parse the  certbag
   521 @param-aCertBag: pointer to the CDecPkcs12CertBag
   522 @param-abagData: reference to the CSafeBagData
   523 @internalTechnology:
   524 @test
   525 */
   526 void CPkcs12Parser::ParseCertBag(CDecPkcs12CertBag& aCertBag , CSafeBagData& aBagData)
   527 	{
   528 	//set the bagID 
   529 	aBagData.SetBagType( CDecPkcs12SafeBag::ECertBag );	
   530 	aBagData.SetCertificateId(aCertBag.CertId()); 		
   531 	//set the bag value in CSafeBagData
   532 	aBagData.SetBagValue(aCertBag.CertValue());
   533 	
   534 	//set the X509Certificate
   535 	aBagData.SetX509Certificate((aCertBag.X509CertificateL()) );
   536 	// increment the count 
   537 	iPkcs12Header->IncrementCertBagCount();			 
   538 	}
   539 
   540 /**
   541 Description:Function is intended to parse the  safecontentbag
   542 @param-safeContentsBag: reference to the CDecPkcs12SafeContentsBag
   543 @param-aContentinfo: contentinfo number
   544 @param- aContentType : contentinfo type
   545 @internalTechnology
   546 @test
   547 */
   548 void CPkcs12Parser::ParseSafeContentBagL(CDecPkcs12SafeContentsBag& aSafeContntBag, TInt aContentinfo , TInt aContentType )
   549 	{	
   550 	const RPointerArray<CDecPkcs12SafeBag>& safebags = aSafeContntBag.SafeBags();  
   551 	// Get the safe bag count
   552 	TInt safeBagCount = safebags.Count();
   553 	//Create a CSafeContentBag , store the bag number and the number of bags in it,append it in the array
   554 	CSafeContentBag* safecontentbag = CSafeContentBag::NewL() ;	
   555 	if(safecontentbag)
   556 		{
   557 		safecontentbag->SetBagNumber(iPkcs12Header->SafecontentBagCount()) ; 
   558 		safecontentbag->SetSafeBagCount(safeBagCount) ;
   559 		CleanupStack::PushL(&iArraySafecontentBag);
   560 		iArraySafecontentBag.AppendL(safecontentbag) ;
   561 		CleanupStack::Pop(&iArraySafecontentBag);
   562 		}
   563 	if(safeBagCount>0) 
   564 		{				
   565 		TInt loopindex = 0 ;
   566 		while(loopindex < safeBagCount )
   567 			{
   568 			ParseSafeBagL(aContentinfo ,aContentType, *(safebags[loopindex]));
   569 			loopindex++;
   570 			}//end while
   571 		}
   572 	}
   573