diff -r 000000000000 -r 2c201484c85f cryptoservices/certificateandkeymgmt/tpkcs12intgrtn/src/tpkcs12common.cpp --- /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 + +//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& 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& 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& 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(&aSafeBag); + // increment the count + iPkcs12Header->IncrementSafecontentBagCount(); + // parsing code to parse SafeContentsBag + ParseSafeContentBagL(*safeContentsBag, aContentInfo ,aContentType ); + break; + } + case CDecPkcs12SafeBag::EKeyBag: + { + CDecPkcs12KeyBag* keyBag = static_cast(&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(&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(&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& 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& 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(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(&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(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& 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 + } + }