--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cryptoservices/certificateandkeymgmt/tpkcs12intgrtn/src/tpkcs12common.cpp Wed Jul 08 11:25:26 2009 +0100
@@ -0,0 +1,574 @@
+/*
+* Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+* This file contains the implementation of the CPkcs12Parser class, to parse the PKCS#12 file.
+*
+*/
+
+
+
+
+/**
+ @file
+ @internalTechnology
+*/
+
+// System Include
+#include <f32file.h>
+
+//User Include
+#include "tpkcs12common.h"
+using namespace PKCS12;
+/**
+Description:constructor
+@internalTechnology:
+@test
+*/
+CPkcs12Parser::CPkcs12Parser()
+ {
+ }
+/**
+Description:destructor
+@internalTechnology:
+@test
+*/
+CPkcs12Parser::~CPkcs12Parser()
+ {
+ delete iIntegrityPassword;
+ delete iRawData;
+ delete iPkcs12Header;
+ iArraySafecontentBag.ResetAndDestroy();
+ iArrayBagData.ResetAndDestroy();
+ }
+
+/**
+Description:Function is intended to creates a new CPKCS12Parser object.
+@return:CPKCS12Parser* : parser object to parse the PKCS12 file
+@internalTechnology
+@test
+*/
+CPkcs12Parser* CPkcs12Parser::NewL()
+ {
+ CPkcs12Parser* parser = NewLC();
+ CleanupStack::Pop(parser);
+ return parser;
+ }
+/**
+Description:Function is intended to creates a new CPKCS12Parser object.
+@return:CPKCS12Parser* : parser object to parse the PKCS12 file
+@test
+*/
+CPkcs12Parser* CPkcs12Parser::NewLC()
+ {
+ CPkcs12Parser* parser = new (ELeave) CPkcs12Parser();
+ CleanupStack::PushL(parser);
+ return parser;
+ }
+/**
+Description:Function is intended to set the integrity password
+@param aIntegrityPassword, contains the integrity password
+@internalTechnology
+@test
+*/
+void CPkcs12Parser::SetIntegrityPasswordL(const TDesC& aIntegrityPassword)
+ {
+ iIntegrityPassword = aIntegrityPassword.AllocL();
+ }
+
+/**
+Description:Function is intended to set the privacy password(s)
+@param aPrivacyPassword, contains the privacy passwords.The ownership is not transferred
+@internalTechnology
+@test
+*/
+void CPkcs12Parser::SetPrivacyPassword(RPointerArray<TDesC>& aPrivacyPassword)
+ {
+ iPrivacyPassword = &aPrivacyPassword;
+ }
+/**
+Description:Function is intended to set the test data.
+ It opens the data file and stores it in the buffer.
+@param aDatapath, contains the path of the PKCS12 file
+@internalTechnology
+@test
+*/
+void CPkcs12Parser::SetDataL(const TDesC& aDatapath)
+ {
+ if(iRawData)
+ {
+ delete iRawData ;
+ iRawData = NULL;
+ }
+ RFs fs;
+ //connects the file server
+ User::LeaveIfError (fs.Connect());
+ //opens the data file
+ CleanupClosePushL(fs);
+ RFile file;
+ User::LeaveIfError(file.Open(fs, aDatapath, EFileRead)) ;
+ CleanupClosePushL(file);
+
+ TInt fileSize = 0;
+ User::LeaveIfError(file.Size(fileSize));
+
+ iRawData = HBufC8::NewL(fileSize);
+ TPtr8 rawData(iRawData->Des());
+ rawData.SetLength(fileSize);
+ file.Read (rawData);
+
+ CleanupStack::PopAndDestroy(&file);
+ //closes the file session
+ CleanupStack::PopAndDestroy(&fs);
+ }
+/**
+Description:Function is intended to parse the PKCS#12 data
+@leave:- if the number of contentinfos and number of privacy passwords does not match.
+@internalTechnology
+@test
+*/
+void CPkcs12Parser::ParseL()
+ {
+ //creates the CDecPkcs12 object
+ CDecPkcs12* decPkcs12 = NULL;
+ TRAPD(error, decPkcs12 = CDecPkcs12::NewL(*iRawData));
+ if(error == KErrNone)
+ CleanupStack::PushL(decPkcs12);
+
+ //Creates a CPfxHeader object
+ iPkcs12Header = CPfxHeader::NewL(*decPkcs12 , error);
+ if(error != KErrNone)
+ {
+
+ return ;
+ }
+ const CDecPkcs12MacData* macData = decPkcs12->MacData();
+ TRAPD(err,macData->VerifyIntegrityL(iIntegrityPassword->Des()));
+ if(err)
+ {
+ iPkcs12Header->SetPkcs12ActualError(err);
+ CleanupStack::PopAndDestroy(decPkcs12);
+ return;
+ }
+ //get the ContentInfo collection
+ const RPointerArray<CPKCS7ContentInfo>& contentInfos = decPkcs12->AuthenticatedSafeContents();
+ TInt contentInfoCount = contentInfos.Count();
+ //put the content info count in the Header
+ iPkcs12Header->SetContentInfoCount(contentInfoCount) ;
+
+ // start iterate through the contentinfos
+ for(TInt index = 0 ; index < contentInfoCount; index++)
+ {
+ TInt contentType = contentInfos[index]->ContentType() ;
+ TPtrC8 contentData = contentInfos[index]->ContentData();
+ if( contentData == KNullDesC8())
+ {
+ iPkcs12Header->SetPkcs12ActualError(0);
+ continue;
+ }
+ CDecPkcs12SafeContents* pkcs12SafeContents = NULL;
+ switch(contentType)
+ {
+ case CPKCS7ContentInfo::EContentTypeData:
+ {
+ TRAPD(error1,pkcs12SafeContents = CDecPkcs12SafeContents::NewL(*contentInfos[index]));
+ if(error1)
+ {
+ iPkcs12Header->SetPkcs12ActualError(error1);
+ CSafeBagData* bagData = NULL;
+ bagData = CreateBagDataL(index,contentType);
+ iArrayBagData.AppendL(bagData) ;
+ CleanupStack::PopAndDestroy(decPkcs12);
+ return;
+ }
+ CleanupStack::PushL(pkcs12SafeContents);
+ break;
+ }
+ case CPKCS7ContentInfo::EContentTypeEncryptedData:
+ {
+ if(contentInfoCount != iPrivacyPassword->Count())
+ {
+ User::Leave(KErrArgument);
+ }
+
+ TRAPD(error2,pkcs12SafeContents = CDecPkcs12SafeContents::NewL(*contentInfos[index],
+ *((*iPrivacyPassword)[index]) ) );
+ if(error2)
+ {
+ iPkcs12Header->SetPkcs12ActualError(error2);
+ CSafeBagData* bagData = NULL;
+ bagData = CreateBagDataL(index,contentType);
+ iArrayBagData.AppendL(bagData) ;
+ CleanupStack::PopAndDestroy(decPkcs12);
+ return;
+ }
+ CleanupStack::PushL(pkcs12SafeContents);
+ break;
+ }
+ case CPKCS7ContentInfo::EContentTypeEnvelopedData:
+ {
+ //creates a Bagdata object in the heap to store the content type.
+ CSafeBagData* bagData = CreateBagDataL(index+1 ,contentType);
+ iArrayBagData.AppendL(bagData) ;
+ //continue in the loop
+ continue;
+ }
+
+ default:
+ {
+ //continue in the loop
+ continue;
+ }
+ }
+ // Get the safebags count.
+ const RPointerArray<CDecPkcs12SafeBag>& safeBags = pkcs12SafeContents->SafeContentsBags();
+ TInt safeBagCount = safeBags.Count();
+
+
+ //start parsing the bags
+ for (TInt bagsCount=0; bagsCount < safeBagCount; bagsCount++)
+ {
+ TRAPD(error3,ParseSafeBagL(index+1, contentType , *safeBags[bagsCount]));
+ if(error3 != KErrNone)
+ {
+ iPkcs12Header->SetPkcs12ActualError(error3);
+ CSafeBagData* bagData = NULL;
+ bagData = CreateBagDataL(index,contentType);
+ iArrayBagData.AppendL(bagData) ;
+ CleanupStack::PopAndDestroy(2,decPkcs12);
+ return;
+ }
+ }
+ CleanupStack::PopAndDestroy(pkcs12SafeContents);
+ }
+ CleanupStack::PopAndDestroy(decPkcs12);
+
+ }
+
+/**
+Description: Creates a CSafeBagData to store the safebag details
+@param:aContentInfo, the contentinfo number of the safe bag
+@param:aContentType, the content type of the safe contents.
+@return:a pointer to CSafeBagData, which is used to store the safebag details
+@internalTechnology:
+@test:
+*/
+CSafeBagData* CPkcs12Parser::CreateBagDataL(TInt aContentInfo, TInt aContentType)
+ {
+ CSafeBagData* bagData = CSafeBagData::NewL();
+ if ( iPkcs12Header->Pkcs12ActualError() == KErrNone )
+ {
+ //set the contentinfo # and content type in CSafeBagData
+ bagData->SetContentInfoNumber(aContentInfo);
+ bagData->SetBagNumber(++iSafebagNumber );
+ // set the content type in CSafeBagData
+ bagData->SetContentInfoType(aContentType);
+ }
+ return bagData ;
+ }
+
+/**
+Description:To parse the safebags
+@param:aContentInfoIndex content info number
+@param:aContentType contentinfo type
+@param:aSafeBag reference to the CDecPkcs12SafeBag
+@internalTechnology:
+@test:
+*/
+void CPkcs12Parser::ParseSafeBagL(TInt aContentInfo,TInt aContentType,CDecPkcs12SafeBag& aSafeBag)
+ {
+ //get the bag type
+ CDecPkcs12SafeBag::TBagId bagType = aSafeBag.BagID();
+ switch(bagType)
+ {
+ case CDecPkcs12SafeBag::ESafeContentsBag:
+ {
+ CDecPkcs12SafeContentsBag* safeContentsBag = static_cast<CDecPkcs12SafeContentsBag *>(&aSafeBag);
+ // increment the count
+ iPkcs12Header->IncrementSafecontentBagCount();
+ // parsing code to parse SafeContentsBag
+ ParseSafeContentBagL(*safeContentsBag, aContentInfo ,aContentType );
+ break;
+ }
+ case CDecPkcs12SafeBag::EKeyBag:
+ {
+ CDecPkcs12KeyBag* keyBag = static_cast<CDecPkcs12KeyBag *>(&aSafeBag);
+ //create the CSafeBagData object in heap to store the bag details
+ CSafeBagData* bagData = CreateBagDataL(aContentInfo,aContentType);
+ CleanupStack::PushL(bagData);
+ ParseKeyBag(*keyBag , *bagData);
+ //get the safeBag attributes
+ BagAttributesL(*keyBag ,*bagData) ;
+ iArrayBagData.AppendL(bagData) ;
+ CleanupStack::Pop(bagData);
+ break;
+ }
+ case CDecPkcs12SafeBag::EShroudedKeyBag:
+ {
+ CDecPkcs12ShroudedKeyBag* shroudedkeyBag = static_cast<CDecPkcs12ShroudedKeyBag *>(&aSafeBag);
+ //create the CSafeBagData object in heap to store the bag details
+ CSafeBagData* bagData = CreateBagDataL(aContentInfo,aContentType );
+ CleanupStack::PushL(bagData);
+ ParseShroudedKeyBagL(*shroudedkeyBag , *bagData ,aContentInfo );
+ //get the safeBag attributes
+ BagAttributesL(*shroudedkeyBag ,*bagData) ;
+ iArrayBagData.AppendL(bagData) ;
+ CleanupStack::Pop(bagData);
+ break;
+ }
+ case CDecPkcs12SafeBag::ECertBag:
+ {
+ CDecPkcs12CertBag* certBag = static_cast<CDecPkcs12CertBag *>(&aSafeBag);
+ //create the CSafeBagData object in heap to store the bag details
+ CSafeBagData* bagData = CreateBagDataL(aContentInfo,aContentType);
+ CleanupStack::PushL(bagData);
+ ParseCertBag(*certBag , *bagData);
+ // Get the bag Attributes
+ BagAttributesL(*certBag , *bagData) ;
+ iArrayBagData.AppendL(bagData) ;
+ CleanupStack::Pop(bagData);
+ break;
+ }
+ case CDecPkcs12SafeBag::ECrlBag:
+ {
+ //create the CSafeBagData object in heap to store the bag details
+ CSafeBagData* bagData = CreateBagDataL(aContentInfo,aContentType);;
+ CleanupStack::PushL(bagData);
+ //set the bagId in CSafeBagData
+ bagData->SetBagType(bagType) ;
+ //increment the count - unsupported
+ iPkcs12Header->IncrementCrlBagCount();
+ iArrayBagData.AppendL(bagData) ;
+ CleanupStack::Pop(bagData);
+ break;
+ }
+ case CDecPkcs12SafeBag::ESecretBag:
+ {
+ //create the CSafeBagData object in heap to store the bag details
+ CSafeBagData* bagData = CreateBagDataL(aContentInfo,aContentType );
+ CleanupStack::PushL(bagData);
+ //set the iBagId in CSafeBagData
+ bagData->SetBagType(bagType) ;
+ //increment the count - unsupported
+ iPkcs12Header->IncrementSecretBagCount();
+ iArrayBagData.AppendL(bagData) ;
+ CleanupStack::Pop(bagData);
+ break;
+ }
+ default:
+ {
+ }
+ }
+ }
+
+/**
+Description:Function is intended to get the attributes of Safebag
+@param-aSafeBag: reference to the CDecPkcs12SafeBag.
+@param-abagData: reference to the CSafeBagData
+@internalTechnology:
+@test
+*/
+void CPkcs12Parser::BagAttributesL(const CDecPkcs12SafeBag& aSafeBag,CSafeBagData& aBagData )
+ {
+ const RPointerArray<CDecPkcs12Attribute>& safeBagAttributes = aSafeBag.BagAttributes();
+
+ TInt attributeCount = safeBagAttributes.Count() ;
+ for (TInt index = 0;index < attributeCount; index++ )
+ {
+ //get the attribute object pointer
+ CDecPkcs12Attribute* attribute = safeBagAttributes[index];
+ //create the CSafeBagAttribute object in heap.
+ CSafeBagAttribute* bagAttr = CSafeBagAttribute::NewL(*safeBagAttributes[index]);
+ CleanupStack::PushL(bagAttr);
+ //get the attribute values
+ const RPointerArray<TDesC8>& attrValues = attribute->AttributeValue();
+ //append the pointer in the iAttributeIDs array
+ aBagData.iAttributeIDs.AppendL(bagAttr) ;
+ CleanupStack::Pop(bagAttr);
+ //store the attribute values
+ TInt numberOfAttributes = bagAttr->AttributeValueCount();
+ for(TInt attrvalCnt = 0 ; attrvalCnt < numberOfAttributes ; attrvalCnt++)
+ {
+ //get the atribute value and store the it address in the aBagData.iAttributeValues array
+ HBufC8* ptr = attrValues[attrvalCnt]->AllocLC();
+ aBagData.iAttributeValues.AppendL(ptr);
+ CleanupStack::Pop(ptr);
+ }
+ }
+ }
+/**
+Description:Function is intended to parse the keybag
+@param-aKeyBag: reference to the keybag
+@param-abagData: reference to the CSafeBagData
+@internalTechnology:
+@test:
+*/
+void CPkcs12Parser::ParseKeyBag(CDecPkcs12KeyBag& aKeyBag , CSafeBagData& aBagData)
+ {
+ //set the bagID
+ aBagData.SetBagType( CDecPkcs12SafeBag::EKeyBag );
+ // Get the Algorithm(RSA key or DSA key) ID
+ CDecPKCS8Data* pkcs8Data = aKeyBag.PrivateKeyInfoL();
+ aBagData.SetPrivateKeyInfoVersion(pkcs8Data->Version() );
+ TAlgorithmId algorithmId = pkcs8Data->Algorithm();
+ // Set the Algorithm Id in CSafeBagData
+ aBagData.SetKeyType( algorithmId );
+ //set the bag value in CSafeBagData
+ aBagData.SetBagValue( aKeyBag.BagValue());
+ // increment the count
+ iPkcs12Header->IncrementKeyBagCount();
+ delete pkcs8Data;
+ }
+/**
+Description:Function is intended to parse the ShroudedKeyBag
+@param-aShroudedkeyBag: pointer to the CDecPkcs12ShroudedKeyBag
+@param-abagData: reference to the CSafeBagData
+@param- aPassIndex: the index of the array from where the privacy password is to be taken
+@internalTechnology:
+@test
+*/
+void CPkcs12Parser::ParseShroudedKeyBagL(CDecPkcs12ShroudedKeyBag& aShroudedkeyBag , CSafeBagData& aBagData , TInt aPassIndex)
+ {
+ //set the bag Id in CSafeBagData
+ aBagData.SetBagType( CDecPkcs12SafeBag::EShroudedKeyBag );
+ // Get the Algorithm(RSA key or DSA key) ID
+ CDecPKCS8Data* pkcs8Data = aShroudedkeyBag.PrivateKeyInfoL(*(*iPrivacyPassword)[aPassIndex-1]);
+ if(pkcs8Data)
+ {
+ aBagData.SetPrivateKeyInfoVersion(pkcs8Data->Version() );
+ TAlgorithmId algorithm = pkcs8Data->Algorithm();
+ // Set the Algorithm Id in CSafeBagData
+ aBagData.SetKeyType(algorithm);
+
+ CASN1EncSequence* seq = NULL ;
+ switch(algorithm)
+ {
+ case ERSA:
+ {
+
+ CPKCS8KeyPairRSA* keypair = static_cast<CPKCS8KeyPairRSA*>(pkcs8Data->KeyPairData());
+
+ const CRSAPrivateKey& priv = keypair->PrivateKey();
+
+ const CRSAPublicKey& publicKey = keypair->PublicKey();
+
+ TRSAPrivateKeyType keytype = priv.PrivateKeyType();
+
+ switch(keytype)
+ {
+ case EStandardCRT:
+ {
+ const CRSAPrivateKeyCRT* privateKeyCRT = static_cast<const CRSAPrivateKeyCRT*>(&priv);
+ seq = TASN1EncPKCS8::EncodeL(*privateKeyCRT, publicKey,pkcs8Data->PKCS8Attributes());
+
+ break;
+ }
+ case EStandard:
+ {
+ User::Leave(KErrNotSupported);
+ }
+ default:
+ {
+ User::Leave(KErrNotSupported);
+ }
+ }
+
+ break;
+ }
+ case EDSA:
+ {
+
+ CPKCS8KeyPairDSA* keypair = static_cast<CPKCS8KeyPairDSA*>(pkcs8Data->KeyPairData());
+
+ const CDSAPrivateKey& priv = keypair->PrivateKey();
+
+ seq = TASN1EncPKCS8::EncodeL(priv , pkcs8Data->PKCS8Attributes());
+
+ break;
+ }
+ default:
+ User::Leave(KErrNotSupported);
+
+ }
+
+ HBufC8* bufSeq = HBufC8::NewMaxLC(seq->LengthDER());
+ TPtr8 temp(bufSeq->Des());
+
+ TUint pos = 0;
+ seq->WriteDERL(temp ,pos);
+
+ aBagData.SetEncodedShroudedKey(temp);
+ CleanupStack::PopAndDestroy();
+
+ delete pkcs8Data;
+ }
+ //set the bag value in CSafeBagData
+ aBagData.SetBagValue(aShroudedkeyBag.BagValue()) ;
+ // increment the count
+ iPkcs12Header->IncrementShroudedKeyBagCount();
+ }
+
+/**
+Description:Function is intended to parse the certbag
+@param-aCertBag: pointer to the CDecPkcs12CertBag
+@param-abagData: reference to the CSafeBagData
+@internalTechnology:
+@test
+*/
+void CPkcs12Parser::ParseCertBag(CDecPkcs12CertBag& aCertBag , CSafeBagData& aBagData)
+ {
+ //set the bagID
+ aBagData.SetBagType( CDecPkcs12SafeBag::ECertBag );
+ aBagData.SetCertificateId(aCertBag.CertId());
+ //set the bag value in CSafeBagData
+ aBagData.SetBagValue(aCertBag.CertValue());
+
+ //set the X509Certificate
+ aBagData.SetX509Certificate((aCertBag.X509CertificateL()) );
+ // increment the count
+ iPkcs12Header->IncrementCertBagCount();
+ }
+
+/**
+Description:Function is intended to parse the safecontentbag
+@param-safeContentsBag: reference to the CDecPkcs12SafeContentsBag
+@param-aContentinfo: contentinfo number
+@param- aContentType : contentinfo type
+@internalTechnology
+@test
+*/
+void CPkcs12Parser::ParseSafeContentBagL(CDecPkcs12SafeContentsBag& aSafeContntBag, TInt aContentinfo , TInt aContentType )
+ {
+ const RPointerArray<CDecPkcs12SafeBag>& safebags = aSafeContntBag.SafeBags();
+ // Get the safe bag count
+ TInt safeBagCount = safebags.Count();
+ //Create a CSafeContentBag , store the bag number and the number of bags in it,append it in the array
+ CSafeContentBag* safecontentbag = CSafeContentBag::NewL() ;
+ if(safecontentbag)
+ {
+ safecontentbag->SetBagNumber(iPkcs12Header->SafecontentBagCount()) ;
+ safecontentbag->SetSafeBagCount(safeBagCount) ;
+ CleanupStack::PushL(&iArraySafecontentBag);
+ iArraySafecontentBag.AppendL(safecontentbag) ;
+ CleanupStack::Pop(&iArraySafecontentBag);
+ }
+ if(safeBagCount>0)
+ {
+ TInt loopindex = 0 ;
+ while(loopindex < safeBagCount )
+ {
+ ParseSafeBagL(aContentinfo ,aContentType, *(safebags[loopindex]));
+ loopindex++;
+ }//end while
+ }
+ }