cryptoservices/certificateandkeymgmt/pkcs12/pkcs12bags.cpp
changeset 8 35751d3474b7
parent 0 2c201484c85f
--- a/cryptoservices/certificateandkeymgmt/pkcs12/pkcs12bags.cpp	Tue Jul 21 01:04:32 2009 +0100
+++ b/cryptoservices/certificateandkeymgmt/pkcs12/pkcs12bags.cpp	Thu Sep 10 14:01:51 2009 +0300
@@ -1,406 +1,407 @@
-/*
-* 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: 
-*
-*/
-
-
-#include "pkcs12bags.h"
-
-using namespace PKCS12;
-///////////////////////// KeyBag ////////////////////////////////	
-
-CDecPkcs12KeyBag::CDecPkcs12KeyBag()
-	{
-	}
-	
-EXPORT_C CDecPkcs12KeyBag* CDecPkcs12KeyBag::NewL(const TDesC8& aSafeBagData)
-	{
-	CDecPkcs12KeyBag* self = new(ELeave) CDecPkcs12KeyBag;
-	CleanupStack::PushL(self);
-	self->ConstructL(aSafeBagData);
-	CleanupStack::Pop(self);
-	return self;
-	}
-
-CDecPkcs12KeyBag::~CDecPkcs12KeyBag()
-	{		
-	}
-	
-void CDecPkcs12KeyBag::ConstructL(const TDesC8& aSafeBagData)
-	{
-	CDecPkcs12SafeBag::ConstructL(aSafeBagData);	
-	}
-	
-EXPORT_C CDecPKCS8Data* CDecPkcs12KeyBag::PrivateKeyInfoL() const
-	{
-	TASN1DecGeneric seqGen(iBagValue);
-	seqGen.InitL();
-	if (seqGen.Tag() != EASN1Sequence || seqGen.Class() != EUniversal)
-		{
-		User::Leave(KErrArgument);
-		}
-			
-	return TASN1DecPKCS8::DecodeDERL(seqGen.Encoding());
-	}
-		
-////////////////////////// ShroudedKeyBag ////////////////////////	
-CDecPkcs12ShroudedKeyBag::CDecPkcs12ShroudedKeyBag()
-	{
-	}
-
-EXPORT_C CDecPkcs12ShroudedKeyBag* CDecPkcs12ShroudedKeyBag::NewL(const TDesC8& aSafeBagData)
-	{
-	CDecPkcs12ShroudedKeyBag* self = new(ELeave) CDecPkcs12ShroudedKeyBag;
-	CleanupStack::PushL(self);
-	self->ConstructL(aSafeBagData);
-	CleanupStack::Pop(self);
-	return self;
-	}
-
-CDecPkcs12ShroudedKeyBag::~CDecPkcs12ShroudedKeyBag()
-	{
-	}
-	
-void CDecPkcs12ShroudedKeyBag::ConstructL(const TDesC8& aSafeBagData)
-	{
-	CDecPkcs12SafeBag::ConstructL(aSafeBagData);
-	TASN1DecGeneric seqGen(iBagValue);
-	seqGen.InitL();
-	if (seqGen.Tag() != EASN1Sequence || seqGen.Class() != EUniversal)
-		{
-		User::Leave(KErrArgument);
-		}
-	
-	TASN1DecSequence dec;
-	CArrayPtrFlat<TASN1DecGeneric>* shroudedKeyBagSeq = dec.DecodeDERLC(seqGen);
-	TInt seqIndex = 0;
-	TInt shroudedKeyBagSeqCount = shroudedKeyBagSeq->Count();
-	if (seqIndex >= shroudedKeyBagSeqCount)
-		{
-		User::Leave(KErrArgument);		
-		}
-	CleanupStack::PopAndDestroy(shroudedKeyBagSeq);
-	}
-
-EXPORT_C CDecPKCS8Data* CDecPkcs12ShroudedKeyBag::PrivateKeyInfoL(TDesC& aPassword) const
-	{
-	TASN1DecGeneric seqGen(iBagValue);
-	seqGen.InitL();
-	TASN1DecSequence dec;
-	CArrayPtrFlat<TASN1DecGeneric>* shroudedKeyBagSeq = dec.DecodeDERLC(seqGen);
-	// Get the first part of the sequence -> PKCS5 data
-	const TASN1DecGeneric* shroudedKeyBagSeqAt0 = shroudedKeyBagSeq->At(0);
-	TPtrC8 theContent(shroudedKeyBagSeqAt0->Encoding());//	expect this to be a sequence
-	CPBEncryptParms* encryptParams =  TASN1DecPKCS5::DecodeDERL(theContent);
-	CleanupStack::PushL(encryptParams);
-	
-	CPBEncryptElement* encryptElement;
-	HBufC8* pkcs12Pwd = PKCS12KDF::GeneratePasswordLC(aPassword);
-	if(encryptParams->Kdf() == CPBEncryptParms::EKdfPkcs12)
-		{
-	 	TPtrC8 iv = encryptParams->IV();
-	    HBufC8* ivValue = HBufC8::NewMaxLC(iv.Length());
-	    TPtr8 encryptKeyBuf = ivValue->Des();
-	 		 
-	 	switch(encryptParams->Cipher())	
-	 		{
-	 		case ECipherARC4_128:
-	 		case ECipherARC4_40:
-				{
-	 		    //derive only key it is unnecessary to derive an IV for RC4
-				break;
-				}
-			case ECipher3DES_CBC:
-			case ECipher2Key3DES_CBC:
-			case ECipherRC2_CBC_128_16:	 
-			case ECipherRC2_CBC_40_5:	
-				{
-			    PKCS12KDF::DeriveKeyL(encryptKeyBuf, PKCS12KDF::EIDByteIV, *pkcs12Pwd, encryptParams->Salt(), encryptParams->Iterations());
-				encryptParams->SetIV(encryptKeyBuf);
-			    break;
-				}
-			default:
-				{
-			    User::Leave(KErrNotSupported);
-			    break;
-				}
-	 		}
-	 	CleanupStack::PopAndDestroy(ivValue);
-		// Create the decryptor	
-		encryptElement = CPBEncryptElement::NewLC(*pkcs12Pwd, *encryptParams);
-		}
-	else
-		{
-		TPBPassword password(aPassword);
-		// Create the decryptor	
-		encryptElement = CPBEncryptElement::NewLC(password.Password(), *encryptParams);	
-		}
-	CPBDecryptor* decryptor = encryptElement->NewDecryptLC();
-	// Decrypt the final part of the sequence -> encrypted PKCS8 object
-	const TASN1DecGeneric* shroudedKeyBagSeqAt1 = shroudedKeyBagSeq->At(1);
-	if (shroudedKeyBagSeqAt1->Tag() != EASN1OctetString || shroudedKeyBagSeqAt1->Class() != EUniversal)
-		{
-		User::Leave(KErrArgument);
-		}
-	TPtrC8 encryptedKey(shroudedKeyBagSeqAt1->GetContentDER());
-	TUint encryptLength = encryptedKey.Length();
-	TUint maxDecryptLength = decryptor->MaxOutputLength(encryptLength);
-	if ( maxDecryptLength <= 0 )
-		{
-		User::Leave(KErrGeneral);		
-		}
-	HBufC8* decryptedContent = HBufC8::NewLC(encryptLength);
-	TPtr8 dcDes(decryptedContent->Des());
-	decryptor->Process(encryptedKey, dcDes);
-	
-	CDecPKCS8Data* privateKeyInfo = TASN1DecPKCS8::DecodeDERL(dcDes);	
-		
-	CleanupStack::PopAndDestroy(6,shroudedKeyBagSeq);//shroudedKeyBagSeq, encryptParams,pkcs12Pwd
-													// encryptElement, decryptor, decryptedContent.
-	return privateKeyInfo;
-	}
-	
-///////////////////////////// CertBag ///////////////////////////////
-
-CDecPkcs12CertBag::CDecPkcs12CertBag()
-	{
-	}
-	
-EXPORT_C CDecPkcs12CertBag* CDecPkcs12CertBag::NewL(const TDesC8& aSafeBagData) 
-    {
-    CDecPkcs12CertBag* self = new (ELeave) CDecPkcs12CertBag;
-	CleanupStack::PushL(self);
-	self->ConstructL(aSafeBagData);
-	CleanupStack::Pop(self);
-	return self;
-	}
-
-CDecPkcs12CertBag::~CDecPkcs12CertBag()
-	{	
-	delete iCertId;
-	}
-
-void CDecPkcs12CertBag::ConstructL(const TDesC8& aSafeBagData)
-	{
-	CDecPkcs12SafeBag::ConstructL(aSafeBagData);
-	
-	TASN1DecGeneric seqGen(iBagValue);
-	seqGen.InitL();
-		if (seqGen.Tag() != EASN1Sequence || seqGen.Class() != EUniversal)
-		{
-		User::Leave(KErrArgument);
-		}
-	
-    TASN1DecSequence seq;
-	CArrayPtr<TASN1DecGeneric>* certBagSequence = seq.DecodeDERLC(seqGen);
-  	const TASN1DecGeneric* certBagSequenceAt0 = certBagSequence->At(0);
-  	if (certBagSequenceAt0->Tag() != EASN1ObjectIdentifier || certBagSequenceAt0->Class() != EUniversal)
-  		{
-		User::Leave(KErrArgument);
-		}
-	  			
-  	// Obtain the CertId		
-  	TASN1DecObjectIdentifier oid;
-  	iCertId = oid.DecodeDERL(*certBagSequenceAt0);
-
-	const TASN1DecGeneric* certBagSequenceAt1 = certBagSequence->At(1);
-	if (certBagSequenceAt1->Tag() != EASN1EOC || certBagSequenceAt1->Class() != EContextSpecific)
-  		{
-		User::Leave(KErrArgument);
-		}
-	
-	TASN1DecGeneric certBagSeq(certBagSequenceAt1->GetContentDER());
-	certBagSeq.InitL();
-	if (certBagSeq.Tag() != EASN1OctetString || certBagSeq.Class() != EUniversal)
-		{
-		User::Leave(KErrArgument);
-		}
-	else 
-		{
-		iCertValue.Set(certBagSeq.GetContentDER());
-		}
-    CleanupStack::PopAndDestroy(certBagSequence);
-	}
-	
-EXPORT_C const TDesC& CDecPkcs12CertBag::CertId() const
-	{
-	return *iCertId;	
-   	}
-
-EXPORT_C const TDesC8& CDecPkcs12CertBag::CertValue() const
-   	{
-   	return iCertValue;		
-   	}
-   	
-EXPORT_C CX509Certificate* CDecPkcs12CertBag::X509CertificateL() const
-	{
-	return (*iCertId == KX509CertificateOID) ? CX509Certificate::NewL(iCertValue) : NULL;
-	}
-
-/////////////////////// SafeContentsBag ///////////////////////
-
-CDecPkcs12SafeContentsBag::CDecPkcs12SafeContentsBag()
-	{
-	}
-	
-EXPORT_C CDecPkcs12SafeContentsBag* CDecPkcs12SafeContentsBag::NewL(const TDesC8& aSafeContentsBagData)
-	{
-	CDecPkcs12SafeContentsBag* self = new(ELeave) CDecPkcs12SafeContentsBag;
-	CleanupStack::PushL(self);
-	self->ConstructL(aSafeContentsBagData);
-	CleanupStack::Pop(self);
-	return self;
-	}
-
-CDecPkcs12SafeContentsBag::~CDecPkcs12SafeContentsBag()
-	{
-	iSafeBags.ResetAndDestroy();
-	iSafeBags.Close();
-	}
-
-void CDecPkcs12SafeContentsBag::ConstructL(const TDesC8& aSafeBagData)
-	{
-	CDecPkcs12SafeBag::ConstructL(aSafeBagData);
-	// This is SafeBag Sequence containing a SafeContents Bag
-	TASN1DecGeneric seqGen(iBagValue);
-	seqGen.InitL();
-	
-	// Check if this is a Sequence
-	if (seqGen.Tag() != EASN1Sequence || seqGen.Class() != EUniversal)
-		{
-		User::Leave(KErrArgument);
-		}
-	
-	TASN1DecSequence seq;
-	CArrayPtrFlat<TASN1DecGeneric>* safeContentsBagSeq = seq.DecodeDERLC(seqGen);
-			        
-    // Find out the number of SafeBags present in the SafeContents Bag
-    TInt safeContentsBagCount = safeContentsBagSeq->Count();
-    const TASN1DecGeneric* safeContentsBagSeqAtPos;
-    for (TInt index = 0; index < safeContentsBagCount; index++)
-   		{
-   		safeContentsBagSeqAtPos = safeContentsBagSeq->At(index);
-   	 	if (safeContentsBagSeqAtPos->Tag() != EASN1Sequence || safeContentsBagSeqAtPos->Class() != EUniversal)
-			{
-			User::Leave(KErrArgument);
-			}
-					
-		const TDesC8& safeBag(safeContentsBagSeqAtPos->Encoding());
-  		// Decode this sequence, This is a SafeBag.
-  		CDecPkcs12SafeBag* safeBagObject = CDecPkcs12SafeBag::NewL(safeBag);
-  		CleanupStack::PushL(safeBagObject);
-   	 	iSafeBags.AppendL(safeBagObject);
-   	 	CleanupStack::Pop(safeBagObject);
-   		}
-   	CleanupStack::PopAndDestroy(safeContentsBagSeq);
-    }
-
-EXPORT_C const RPointerArray<CDecPkcs12SafeBag>& CDecPkcs12SafeContentsBag::SafeBags() const
-	 {
-	 return iSafeBags;
-	 } 
-	 
-///////////////////////////// Safe Contents ///////////////////////////////
-CDecPkcs12SafeContents::CDecPkcs12SafeContents()
-	{
-	}
-
-CDecPkcs12SafeContents::~CDecPkcs12SafeContents()
-	{
-	delete iDecryptedData;
-	iSafeBags.ResetAndDestroy();
-	iSafeBags.Close();
-	}
-
-EXPORT_C CDecPkcs12SafeContents* CDecPkcs12SafeContents::NewL(const CPKCS7ContentInfo& aSafeContentsBagData)
-	{
-	CDecPkcs12SafeContents* self = new(ELeave) CDecPkcs12SafeContents;
-	CleanupStack::PushL(self);
-	self->ConstructL(aSafeContentsBagData.ContentData());
-	CleanupStack::Pop(self);
-	return self;
-	}
-
-EXPORT_C CDecPkcs12SafeContents* CDecPkcs12SafeContents::NewL(const CPKCS7ContentInfo& aSafeContentsBagData, const TDesC& aPassword)
-	{
-	CDecPkcs12SafeContents* self = new(ELeave) CDecPkcs12SafeContents;
-	CleanupStack::PushL(self);
-	self->DecodeEncryptedDataL(aSafeContentsBagData,aPassword);
-	CleanupStack::Pop(self);
-	return self;
-	}
-	
-EXPORT_C CDecPkcs12SafeContents* CDecPkcs12SafeContents::NewL(const TDesC8& aSafeContent)
-	{
-	CDecPkcs12SafeContents* self = new(ELeave) CDecPkcs12SafeContents;
-	CleanupStack::PushL(self);
-	self->ConstructL(aSafeContent);
-	CleanupStack::Pop(self);
-	return self;
-	}
-
-void CDecPkcs12SafeContents::ConstructL(const TDesC8& aSafeContent)
-	{
-	TASN1DecGeneric decGen(aSafeContent);
-    decGen.InitL(); 
-			
-	if(decGen.Tag() != EASN1Sequence || decGen.Class() != EUniversal)      
-		{
-		User::Leave(KErrArgument);
-		}
-          		 
-    TASN1DecGeneric decGen2(decGen.GetContentDER());
-	decGen2.InitL(); 
-			
-	if(decGen2.Tag() != EASN1Sequence || decGen.Class() != EUniversal)      
-		{
-		User ::Leave(KErrArgument);
-	    }
-				
-	// Decode sequence
-	TASN1DecSequence seq;
- 	CArrayPtr<TASN1DecGeneric>* safeBagSequences = seq.DecodeDERLC(decGen);
- 	
- 	// A Sequence of SafeBags are present within the SafeContents Bag Sequence
- 	TInt safeBagCount = safeBagSequences->Count();
- 	
- 	for(TInt index = 0; index < safeBagCount; index++)
- 	  	{
- 	  	CDecPkcs12SafeBag* safeBag = CDecPkcs12SafeBag::NewL(safeBagSequences->At(index)->Encoding());
- 	  	CleanupStack::PushL(safeBag);
- 	   	iSafeBags.AppendL(safeBag);
- 	   	CleanupStack::Pop(safeBag);
- 	   	}	
- 	CleanupStack::PopAndDestroy(safeBagSequences); // safeBagSequences
-	}
-
-void CDecPkcs12SafeContents::DecodeEncryptedDataL(const CPKCS7ContentInfo& aContentInfo, const TDesC& aPassword)
-	{
-	CPKCS7EncryptedDataObject* pkcs7EncryptedData = CPKCS7EncryptedDataObject::NewL(aContentInfo);
-	CleanupStack::PushL(pkcs7EncryptedData);
-	iDecryptedData = pkcs7EncryptedData->DecryptDataL(aPassword);	
-	ConstructL(iDecryptedData->Des());
-	CleanupStack::PopAndDestroy(pkcs7EncryptedData); 
-	}
-
-EXPORT_C const RPointerArray<CDecPkcs12SafeBag>& CDecPkcs12SafeContents::SafeContentsBags() const
-	{
-	return iSafeBags;
-	}
-
-EXPORT_C const TDesC8* CDecPkcs12SafeContents::DecryptedData() const
-	{
-	return iDecryptedData;	
-	}
+/*
+* 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: 
+*
+*/
+
+
+#include "pkcs12bags.h"
+
+using namespace PKCS12;
+///////////////////////// KeyBag ////////////////////////////////	
+
+CDecPkcs12KeyBag::CDecPkcs12KeyBag()
+	{
+	}
+	
+EXPORT_C CDecPkcs12KeyBag* CDecPkcs12KeyBag::NewL(const TDesC8& aSafeBagData)
+	{
+	CDecPkcs12KeyBag* self = new(ELeave) CDecPkcs12KeyBag;
+	CleanupStack::PushL(self);
+	self->ConstructL(aSafeBagData);
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+CDecPkcs12KeyBag::~CDecPkcs12KeyBag()
+	{		
+	}
+	
+void CDecPkcs12KeyBag::ConstructL(const TDesC8& aSafeBagData)
+	{
+	CDecPkcs12SafeBag::ConstructL(aSafeBagData);	
+	}
+	
+EXPORT_C CDecPKCS8Data* CDecPkcs12KeyBag::PrivateKeyInfoL() const
+	{
+	TASN1DecGeneric seqGen(iBagValue);
+	seqGen.InitL();
+	if (seqGen.Tag() != EASN1Sequence || seqGen.Class() != EUniversal)
+		{
+		User::Leave(KErrArgument);
+		}
+			
+	return TASN1DecPKCS8::DecodeDERL(seqGen.Encoding());
+	}
+		
+////////////////////////// ShroudedKeyBag ////////////////////////	
+CDecPkcs12ShroudedKeyBag::CDecPkcs12ShroudedKeyBag()
+	{
+	}
+
+EXPORT_C CDecPkcs12ShroudedKeyBag* CDecPkcs12ShroudedKeyBag::NewL(const TDesC8& aSafeBagData)
+	{
+	CDecPkcs12ShroudedKeyBag* self = new(ELeave) CDecPkcs12ShroudedKeyBag;
+	CleanupStack::PushL(self);
+	self->ConstructL(aSafeBagData);
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+CDecPkcs12ShroudedKeyBag::~CDecPkcs12ShroudedKeyBag()
+	{
+	}
+	
+void CDecPkcs12ShroudedKeyBag::ConstructL(const TDesC8& aSafeBagData)
+	{
+	CDecPkcs12SafeBag::ConstructL(aSafeBagData);
+	TASN1DecGeneric seqGen(iBagValue);
+	seqGen.InitL();
+	if (seqGen.Tag() != EASN1Sequence || seqGen.Class() != EUniversal)
+		{
+		User::Leave(KErrArgument);
+		}
+	
+	TASN1DecSequence dec;
+	CArrayPtrFlat<TASN1DecGeneric>* shroudedKeyBagSeq = dec.DecodeDERLC(seqGen);
+	TInt seqIndex = 0;
+	TInt shroudedKeyBagSeqCount = shroudedKeyBagSeq->Count();
+	if (seqIndex >= shroudedKeyBagSeqCount)
+		{
+		User::Leave(KErrArgument);		
+		}
+	CleanupStack::PopAndDestroy(shroudedKeyBagSeq);
+	}
+
+EXPORT_C CDecPKCS8Data* CDecPkcs12ShroudedKeyBag::PrivateKeyInfoL(TDesC& aPassword) const
+	{
+	TASN1DecGeneric seqGen(iBagValue);
+	seqGen.InitL();
+	TASN1DecSequence dec;
+	CArrayPtrFlat<TASN1DecGeneric>* shroudedKeyBagSeq = dec.DecodeDERLC(seqGen);
+	// Get the first part of the sequence -> PKCS5 data
+	const TASN1DecGeneric* shroudedKeyBagSeqAt0 = shroudedKeyBagSeq->At(0);
+	TPtrC8 theContent(shroudedKeyBagSeqAt0->Encoding());//	expect this to be a sequence
+	CPBEncryptParms* encryptParams =  TASN1DecPKCS5::DecodeDERL(theContent);
+	CleanupStack::PushL(encryptParams);
+	
+	CPBEncryptElement* encryptElement;
+	HBufC8* pkcs12Pwd = PKCS12KDF::GeneratePasswordLC(aPassword);
+	if(encryptParams->Kdf() == CPBEncryptParms::EKdfPkcs12)
+		{
+	 	TPtrC8 iv = encryptParams->IV();
+	    HBufC8* ivValue = HBufC8::NewMaxLC(iv.Length());
+	    TPtr8 encryptKeyBuf = ivValue->Des();
+	 		 
+	 	switch(encryptParams->Cipher())	
+	 		{
+	 		case ECipherARC4_128:
+	 		case ECipherARC4_40:
+				{
+	 		    //derive only key it is unnecessary to derive an IV for RC4
+				break;
+				}
+			case ECipher3DES_CBC:
+			case ECipher2Key3DES_CBC:
+			case ECipherRC2_CBC_128_16:	 
+			case ECipherRC2_CBC_40_5:	
+				{
+			    PKCS12KDF::DeriveKeyL(encryptKeyBuf, PKCS12KDF::EIDByteIV, *pkcs12Pwd, encryptParams->Salt(), encryptParams->Iterations());
+				encryptParams->SetIV(encryptKeyBuf);
+			    break;
+				}
+			default:
+				{
+			    User::Leave(KErrNotSupported);
+			    break;
+				}
+	 		}
+	 	CleanupStack::PopAndDestroy(ivValue);
+		// Create the decryptor	
+		encryptElement = CPBEncryptElement::NewLC(*pkcs12Pwd, *encryptParams);
+		}
+	else
+		{
+		TPBPassword password(aPassword);
+		// Create the decryptor	
+		encryptElement = CPBEncryptElement::NewLC(password.Password(), *encryptParams);	
+		}
+	CPBDecryptor* decryptor = encryptElement->NewDecryptLC();
+	// Decrypt the final part of the sequence -> encrypted PKCS8 object
+	const TASN1DecGeneric* shroudedKeyBagSeqAt1 = shroudedKeyBagSeq->At(1);
+	if (shroudedKeyBagSeqAt1->Tag() != EASN1OctetString || shroudedKeyBagSeqAt1->Class() != EUniversal)
+		{
+		User::Leave(KErrArgument);
+		}
+	TPtrC8 encryptedKey(shroudedKeyBagSeqAt1->GetContentDER());
+	TUint encryptLength = encryptedKey.Length();
+	TUint maxDecryptLength = decryptor->MaxOutputLength(encryptLength);
+	if ( maxDecryptLength <= 0 )
+		{
+		User::Leave(KErrGeneral);		
+		}
+	HBufC8* decryptedContent = HBufC8::NewLC(encryptLength);
+	TPtr8 dcDes(decryptedContent->Des());
+	decryptor->Process(encryptedKey, dcDes);
+	
+	CDecPKCS8Data* privateKeyInfo = TASN1DecPKCS8::DecodeDERL(dcDes);	
+		
+	CleanupStack::PopAndDestroy(6,shroudedKeyBagSeq);//shroudedKeyBagSeq, encryptParams,pkcs12Pwd
+													// encryptElement, decryptor, decryptedContent.
+	return privateKeyInfo;
+	}
+	
+///////////////////////////// CertBag ///////////////////////////////
+
+CDecPkcs12CertBag::CDecPkcs12CertBag()
+	{
+	}
+	
+EXPORT_C CDecPkcs12CertBag* CDecPkcs12CertBag::NewL(const TDesC8& aSafeBagData) 
+    {
+    CDecPkcs12CertBag* self = new (ELeave) CDecPkcs12CertBag;
+	CleanupStack::PushL(self);
+	self->ConstructL(aSafeBagData);
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+CDecPkcs12CertBag::~CDecPkcs12CertBag()
+	{	
+	delete iCertId;
+	}
+
+void CDecPkcs12CertBag::ConstructL(const TDesC8& aSafeBagData)
+	{
+	CDecPkcs12SafeBag::ConstructL(aSafeBagData);
+	
+	TASN1DecGeneric seqGen(iBagValue);
+	seqGen.InitL();
+		if (seqGen.Tag() != EASN1Sequence || seqGen.Class() != EUniversal)
+		{
+		User::Leave(KErrArgument);
+		}
+	
+    TASN1DecSequence seq;
+	CArrayPtr<TASN1DecGeneric>* certBagSequence = seq.DecodeDERLC(seqGen);
+  	const TASN1DecGeneric* certBagSequenceAt0 = certBagSequence->At(0);
+  	if (certBagSequenceAt0->Tag() != EASN1ObjectIdentifier || certBagSequenceAt0->Class() != EUniversal)
+  		{
+		User::Leave(KErrArgument);
+		}
+	  			
+  	// Obtain the CertId		
+  	TASN1DecObjectIdentifier oid;
+  	iCertId = oid.DecodeDERL(*certBagSequenceAt0);
+
+	const TASN1DecGeneric* certBagSequenceAt1 = certBagSequence->At(1);
+	if (certBagSequenceAt1->Tag() != EASN1EOC || certBagSequenceAt1->Class() != EContextSpecific)
+  		{
+		User::Leave(KErrArgument);
+		}
+	
+	TASN1DecGeneric certBagSeq(certBagSequenceAt1->GetContentDER());
+	certBagSeq.InitL();
+	if (certBagSeq.Tag() != EASN1OctetString || certBagSeq.Class() != EUniversal)
+		{
+		User::Leave(KErrArgument);
+		}
+	else 
+		{
+		iCertValue.Set(certBagSeq.GetContentDER());
+		}
+    CleanupStack::PopAndDestroy(certBagSequence);
+	}
+	
+EXPORT_C const TDesC& CDecPkcs12CertBag::CertId() const
+	{
+	return *iCertId;	
+   	}
+
+EXPORT_C const TDesC8& CDecPkcs12CertBag::CertValue() const
+   	{
+   	return iCertValue;		
+   	}
+   	
+EXPORT_C CX509Certificate* CDecPkcs12CertBag::X509CertificateL() const
+	{
+	return (*iCertId == KX509CertificateOID) ? CX509Certificate::NewL(iCertValue) : NULL;
+	}
+
+/////////////////////// SafeContentsBag ///////////////////////
+
+CDecPkcs12SafeContentsBag::CDecPkcs12SafeContentsBag()
+	{
+	}
+	
+EXPORT_C CDecPkcs12SafeContentsBag* CDecPkcs12SafeContentsBag::NewL(const TDesC8& aSafeContentsBagData)
+	{
+	CDecPkcs12SafeContentsBag* self = new(ELeave) CDecPkcs12SafeContentsBag;
+	CleanupStack::PushL(self);
+	self->ConstructL(aSafeContentsBagData);
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+CDecPkcs12SafeContentsBag::~CDecPkcs12SafeContentsBag()
+	{
+	iSafeBags.ResetAndDestroy();
+	iSafeBags.Close();
+	}
+
+void CDecPkcs12SafeContentsBag::ConstructL(const TDesC8& aSafeBagData)
+	{
+	CDecPkcs12SafeBag::ConstructL(aSafeBagData);
+	// This is SafeBag Sequence containing a SafeContents Bag
+	TASN1DecGeneric seqGen(iBagValue);
+	seqGen.InitL();
+	
+	// Check if this is a Sequence
+	if (seqGen.Tag() != EASN1Sequence || seqGen.Class() != EUniversal)
+		{
+		User::Leave(KErrArgument);
+		}
+	
+	TASN1DecSequence seq;
+	CArrayPtrFlat<TASN1DecGeneric>* safeContentsBagSeq = seq.DecodeDERLC(seqGen);
+			        
+    // Find out the number of SafeBags present in the SafeContents Bag
+    TInt safeContentsBagCount = safeContentsBagSeq->Count();
+    const TASN1DecGeneric* safeContentsBagSeqAtPos;
+    for (TInt index = 0; index < safeContentsBagCount; index++)
+   		{
+   		safeContentsBagSeqAtPos = safeContentsBagSeq->At(index);
+   	 	if (safeContentsBagSeqAtPos->Tag() != EASN1Sequence || safeContentsBagSeqAtPos->Class() != EUniversal)
+			{
+			User::Leave(KErrArgument);
+			}
+					
+		const TDesC8& safeBag(safeContentsBagSeqAtPos->Encoding());
+  		// Decode this sequence, This is a SafeBag.
+  		CDecPkcs12SafeBag* safeBagObject = CDecPkcs12SafeBag::NewL(safeBag);
+  		CleanupStack::PushL(safeBagObject);
+   	 	iSafeBags.AppendL(safeBagObject);
+   	 	CleanupStack::Pop(safeBagObject);
+   		}
+   	CleanupStack::PopAndDestroy(safeContentsBagSeq);
+    }
+
+EXPORT_C const RPointerArray<CDecPkcs12SafeBag>& CDecPkcs12SafeContentsBag::SafeBags() const
+	 {
+	 return iSafeBags;
+	 } 
+	 
+///////////////////////////// Safe Contents ///////////////////////////////
+CDecPkcs12SafeContents::CDecPkcs12SafeContents()
+	{
+	}
+
+CDecPkcs12SafeContents::~CDecPkcs12SafeContents()
+	{
+	delete iDecryptedData;
+	iSafeBags.ResetAndDestroy();
+	iSafeBags.Close();
+	}
+
+EXPORT_C CDecPkcs12SafeContents* CDecPkcs12SafeContents::NewL(const CPKCS7ContentInfo& aSafeContentsBagData)
+	{
+	CDecPkcs12SafeContents* self = new(ELeave) CDecPkcs12SafeContents;
+	CleanupStack::PushL(self);
+	self->ConstructL(aSafeContentsBagData.ContentData());
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+EXPORT_C CDecPkcs12SafeContents* CDecPkcs12SafeContents::NewL(const CPKCS7ContentInfo& aSafeContentsBagData, const TDesC& aPassword)
+	{
+	CDecPkcs12SafeContents* self = new(ELeave) CDecPkcs12SafeContents;
+	CleanupStack::PushL(self);
+	self->DecodeEncryptedDataL(aSafeContentsBagData,aPassword);
+	CleanupStack::Pop(self);
+	return self;
+	}
+	
+EXPORT_C CDecPkcs12SafeContents* CDecPkcs12SafeContents::NewL(const TDesC8& aSafeContent)
+	{
+	CDecPkcs12SafeContents* self = new(ELeave) CDecPkcs12SafeContents;
+	CleanupStack::PushL(self);
+	self->ConstructL(aSafeContent);
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+void CDecPkcs12SafeContents::ConstructL(const TDesC8& aSafeContent)
+	{
+	TASN1DecGeneric decGen(aSafeContent);
+    decGen.InitL(); 
+			
+	if(decGen.Tag() != EASN1Sequence || decGen.Class() != EUniversal)      
+		{
+		User::Leave(KErrArgument);
+		}
+          		 
+    TASN1DecGeneric decGen2(decGen.GetContentDER());
+	decGen2.InitL(); 
+			
+	if(decGen2.Tag() != EASN1Sequence || decGen.Class() != EUniversal)      
+		{
+		User ::Leave(KErrArgument);
+	    }
+				
+	// Decode sequence
+	TASN1DecSequence seq;
+ 	CArrayPtr<TASN1DecGeneric>* safeBagSequences = seq.DecodeDERLC(decGen);
+ 	
+ 	// A Sequence of SafeBags are present within the SafeContents Bag Sequence
+ 	TInt safeBagCount = safeBagSequences->Count();
+ 	
+ 	for(TInt index = 0; index < safeBagCount; index++)
+ 	  	{
+ 	  	CDecPkcs12SafeBag* safeBag = CDecPkcs12SafeBag::NewL(safeBagSequences->At(index)->Encoding());
+ 	  	CleanupStack::PushL(safeBag);
+ 	   	iSafeBags.AppendL(safeBag);
+ 	   	CleanupStack::Pop(safeBag);
+ 	   	}	
+ 	CleanupStack::PopAndDestroy(safeBagSequences); // safeBagSequences
+	}
+
+void CDecPkcs12SafeContents::DecodeEncryptedDataL(const CPKCS7ContentInfo& aContentInfo, const TDesC& aPassword)
+	{
+	CPKCS7EncryptedDataObject* pkcs7EncryptedData = CPKCS7EncryptedDataObject::NewL(aContentInfo);
+	CleanupStack::PushL(pkcs7EncryptedData);
+	iDecryptedData = pkcs7EncryptedData->DecryptDataL(aPassword);	
+	ConstructL(iDecryptedData->Des());
+	CleanupStack::PopAndDestroy(pkcs7EncryptedData); 
+	}
+
+EXPORT_C const RPointerArray<CDecPkcs12SafeBag>& CDecPkcs12SafeContents::SafeContentsBags() const
+	{
+	return iSafeBags;
+	}
+
+EXPORT_C const TDesC8* CDecPkcs12SafeContents::DecryptedData() const
+	{
+	return iDecryptedData;	
+	}
+