os/security/cryptoservices/certificateandkeymgmt/tpkcs12intgrtn/src/tpkcs12common.cpp
Update contrib.
2 * Copyright (c) 2005-2009 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.
15 * This file contains the implementation of the CPkcs12Parser class, to parse the PKCS#12 file.
29 #include "tpkcs12common.h"
30 using namespace PKCS12;
32 Description:constructor
36 CPkcs12Parser::CPkcs12Parser()
40 Description:destructor
44 CPkcs12Parser::~CPkcs12Parser()
46 delete iIntegrityPassword;
49 iArraySafecontentBag.ResetAndDestroy();
50 iArrayBagData.ResetAndDestroy();
54 Description:Function is intended to creates a new CPKCS12Parser object.
55 @return:CPKCS12Parser* : parser object to parse the PKCS12 file
59 CPkcs12Parser* CPkcs12Parser::NewL()
61 CPkcs12Parser* parser = NewLC();
62 CleanupStack::Pop(parser);
66 Description:Function is intended to creates a new CPKCS12Parser object.
67 @return:CPKCS12Parser* : parser object to parse the PKCS12 file
70 CPkcs12Parser* CPkcs12Parser::NewLC()
72 CPkcs12Parser* parser = new (ELeave) CPkcs12Parser();
73 CleanupStack::PushL(parser);
77 Description:Function is intended to set the integrity password
78 @param aIntegrityPassword, contains the integrity password
82 void CPkcs12Parser::SetIntegrityPasswordL(const TDesC& aIntegrityPassword)
84 iIntegrityPassword = aIntegrityPassword.AllocL();
88 Description:Function is intended to set the privacy password(s)
89 @param aPrivacyPassword, contains the privacy passwords.The ownership is not transferred
93 void CPkcs12Parser::SetPrivacyPassword(RPointerArray<TDesC>& aPrivacyPassword)
95 iPrivacyPassword = &aPrivacyPassword;
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
104 void CPkcs12Parser::SetDataL(const TDesC& aDatapath)
112 //connects the file server
113 User::LeaveIfError (fs.Connect());
114 //opens the data file
115 CleanupClosePushL(fs);
117 User::LeaveIfError(file.Open(fs, aDatapath, EFileRead)) ;
118 CleanupClosePushL(file);
121 User::LeaveIfError(file.Size(fileSize));
123 iRawData = HBufC8::NewL(fileSize);
124 TPtr8 rawData(iRawData->Des());
125 rawData.SetLength(fileSize);
128 CleanupStack::PopAndDestroy(&file);
129 //closes the file session
130 CleanupStack::PopAndDestroy(&fs);
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.
138 void CPkcs12Parser::ParseL()
140 //creates the CDecPkcs12 object
141 CDecPkcs12* decPkcs12 = NULL;
142 TRAPD(error, decPkcs12 = CDecPkcs12::NewL(*iRawData));
143 if(error == KErrNone)
144 CleanupStack::PushL(decPkcs12);
146 //Creates a CPfxHeader object
147 iPkcs12Header = CPfxHeader::NewL(*decPkcs12 , error);
148 if(error != KErrNone)
153 const CDecPkcs12MacData* macData = decPkcs12->MacData();
154 TRAPD(err,macData->VerifyIntegrityL(iIntegrityPassword->Des()));
157 iPkcs12Header->SetPkcs12ActualError(err);
158 CleanupStack::PopAndDestroy(decPkcs12);
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) ;
167 // start iterate through the contentinfos
168 for(TInt index = 0 ; index < contentInfoCount; index++)
170 TInt contentType = contentInfos[index]->ContentType() ;
171 TPtrC8 contentData = contentInfos[index]->ContentData();
172 if( contentData == KNullDesC8())
174 iPkcs12Header->SetPkcs12ActualError(0);
177 CDecPkcs12SafeContents* pkcs12SafeContents = NULL;
180 case CPKCS7ContentInfo::EContentTypeData:
182 TRAPD(error1,pkcs12SafeContents = CDecPkcs12SafeContents::NewL(*contentInfos[index]));
185 iPkcs12Header->SetPkcs12ActualError(error1);
186 CSafeBagData* bagData = NULL;
187 bagData = CreateBagDataL(index,contentType);
188 iArrayBagData.AppendL(bagData) ;
189 CleanupStack::PopAndDestroy(decPkcs12);
192 CleanupStack::PushL(pkcs12SafeContents);
195 case CPKCS7ContentInfo::EContentTypeEncryptedData:
197 if(contentInfoCount != iPrivacyPassword->Count())
199 User::Leave(KErrArgument);
202 TRAPD(error2,pkcs12SafeContents = CDecPkcs12SafeContents::NewL(*contentInfos[index],
203 *((*iPrivacyPassword)[index]) ) );
206 iPkcs12Header->SetPkcs12ActualError(error2);
207 CSafeBagData* bagData = NULL;
208 bagData = CreateBagDataL(index,contentType);
209 iArrayBagData.AppendL(bagData) ;
210 CleanupStack::PopAndDestroy(decPkcs12);
213 CleanupStack::PushL(pkcs12SafeContents);
216 case CPKCS7ContentInfo::EContentTypeEnvelopedData:
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
227 //continue in the loop
231 // Get the safebags count.
232 const RPointerArray<CDecPkcs12SafeBag>& safeBags = pkcs12SafeContents->SafeContentsBags();
233 TInt safeBagCount = safeBags.Count();
236 //start parsing the bags
237 for (TInt bagsCount=0; bagsCount < safeBagCount; bagsCount++)
239 TRAPD(error3,ParseSafeBagL(index+1, contentType , *safeBags[bagsCount]));
240 if(error3 != KErrNone)
242 iPkcs12Header->SetPkcs12ActualError(error3);
243 CSafeBagData* bagData = NULL;
244 bagData = CreateBagDataL(index,contentType);
245 iArrayBagData.AppendL(bagData) ;
246 CleanupStack::PopAndDestroy(2,decPkcs12);
250 CleanupStack::PopAndDestroy(pkcs12SafeContents);
252 CleanupStack::PopAndDestroy(decPkcs12);
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
264 CSafeBagData* CPkcs12Parser::CreateBagDataL(TInt aContentInfo, TInt aContentType)
266 CSafeBagData* bagData = CSafeBagData::NewL();
267 if ( iPkcs12Header->Pkcs12ActualError() == KErrNone )
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);
279 Description:To parse the safebags
280 @param:aContentInfoIndex content info number
281 @param:aContentType contentinfo type
282 @param:aSafeBag reference to the CDecPkcs12SafeBag
286 void CPkcs12Parser::ParseSafeBagL(TInt aContentInfo,TInt aContentType,CDecPkcs12SafeBag& aSafeBag)
289 CDecPkcs12SafeBag::TBagId bagType = aSafeBag.BagID();
292 case CDecPkcs12SafeBag::ESafeContentsBag:
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 );
301 case CDecPkcs12SafeBag::EKeyBag:
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);
314 case CDecPkcs12SafeBag::EShroudedKeyBag:
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);
327 case CDecPkcs12SafeBag::ECertBag:
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);
340 case CDecPkcs12SafeBag::ECrlBag:
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);
353 case CDecPkcs12SafeBag::ESecretBag:
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);
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
379 void CPkcs12Parser::BagAttributesL(const CDecPkcs12SafeBag& aSafeBag,CSafeBagData& aBagData )
381 const RPointerArray<CDecPkcs12Attribute>& safeBagAttributes = aSafeBag.BagAttributes();
383 TInt attributeCount = safeBagAttributes.Count() ;
384 for (TInt index = 0;index < attributeCount; index++ )
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++)
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);
408 Description:Function is intended to parse the keybag
409 @param-aKeyBag: reference to the keybag
410 @param-abagData: reference to the CSafeBagData
414 void CPkcs12Parser::ParseKeyBag(CDecPkcs12KeyBag& aKeyBag , CSafeBagData& aBagData)
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();
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
438 void CPkcs12Parser::ParseShroudedKeyBagL(CDecPkcs12ShroudedKeyBag& aShroudedkeyBag , CSafeBagData& aBagData , TInt aPassIndex)
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]);
446 aBagData.SetPrivateKeyInfoVersion(pkcs8Data->Version() );
447 TAlgorithmId algorithm = pkcs8Data->Algorithm();
448 // Set the Algorithm Id in CSafeBagData
449 aBagData.SetKeyType(algorithm);
451 CASN1EncSequence* seq = NULL ;
457 CPKCS8KeyPairRSA* keypair = static_cast<CPKCS8KeyPairRSA*>(pkcs8Data->KeyPairData());
459 const CRSAPrivateKey& priv = keypair->PrivateKey();
461 const CRSAPublicKey& publicKey = keypair->PublicKey();
463 TRSAPrivateKeyType keytype = priv.PrivateKeyType();
469 const CRSAPrivateKeyCRT* privateKeyCRT = static_cast<const CRSAPrivateKeyCRT*>(&priv);
470 seq = TASN1EncPKCS8::EncodeL(*privateKeyCRT, publicKey,pkcs8Data->PKCS8Attributes());
476 User::Leave(KErrNotSupported);
480 User::Leave(KErrNotSupported);
489 CPKCS8KeyPairDSA* keypair = static_cast<CPKCS8KeyPairDSA*>(pkcs8Data->KeyPairData());
491 const CDSAPrivateKey& priv = keypair->PrivateKey();
493 seq = TASN1EncPKCS8::EncodeL(priv , pkcs8Data->PKCS8Attributes());
498 User::Leave(KErrNotSupported);
502 HBufC8* bufSeq = HBufC8::NewMaxLC(seq->LengthDER());
503 TPtr8 temp(bufSeq->Des());
506 seq->WriteDERL(temp ,pos);
508 aBagData.SetEncodedShroudedKey(temp);
509 CleanupStack::PopAndDestroy();
513 //set the bag value in CSafeBagData
514 aBagData.SetBagValue(aShroudedkeyBag.BagValue()) ;
515 // increment the count
516 iPkcs12Header->IncrementShroudedKeyBagCount();
520 Description:Function is intended to parse the certbag
521 @param-aCertBag: pointer to the CDecPkcs12CertBag
522 @param-abagData: reference to the CSafeBagData
526 void CPkcs12Parser::ParseCertBag(CDecPkcs12CertBag& aCertBag , CSafeBagData& aBagData)
529 aBagData.SetBagType( CDecPkcs12SafeBag::ECertBag );
530 aBagData.SetCertificateId(aCertBag.CertId());
531 //set the bag value in CSafeBagData
532 aBagData.SetBagValue(aCertBag.CertValue());
534 //set the X509Certificate
535 aBagData.SetX509Certificate((aCertBag.X509CertificateL()) );
536 // increment the count
537 iPkcs12Header->IncrementCertBagCount();
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
548 void CPkcs12Parser::ParseSafeContentBagL(CDecPkcs12SafeContentsBag& aSafeContntBag, TInt aContentinfo , TInt aContentType )
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() ;
557 safecontentbag->SetBagNumber(iPkcs12Header->SafecontentBagCount()) ;
558 safecontentbag->SetSafeBagCount(safeBagCount) ;
559 CleanupStack::PushL(&iArraySafecontentBag);
560 iArraySafecontentBag.AppendL(safecontentbag) ;
561 CleanupStack::Pop(&iArraySafecontentBag);
566 while(loopindex < safeBagCount )
568 ParseSafeBagL(aContentinfo ,aContentType, *(safebags[loopindex]));