cryptoservices/certificateandkeymgmt/pkcs12/pkcs12bags.cpp
changeset 0 2c201484c85f
child 8 35751d3474b7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cryptoservices/certificateandkeymgmt/pkcs12/pkcs12bags.cpp	Wed Jul 08 11:25:26 2009 +0100
@@ -0,0 +1,406 @@
+/*
+* 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;	
+	}