cryptoservices/asnpkcs/source/asnpkcs8enc.cpp
changeset 8 35751d3474b7
parent 0 2c201484c85f
--- a/cryptoservices/asnpkcs/source/asnpkcs8enc.cpp	Tue Jul 21 01:04:32 2009 +0100
+++ b/cryptoservices/asnpkcs/source/asnpkcs8enc.cpp	Thu Sep 10 14:01:51 2009 +0300
@@ -1,364 +1,365 @@
-/*
-* Copyright (c) 2004-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 <asn1enc.h>
-#include <pbe.h>
-#include <asymmetrickeys.h>
-#include <bigint.h>
-#include "asnpkcs.h"
-
-const TInt KPkcs8Version = 0;      // PKCS#8 version 0 
-const TInt KPkcs8RSATwoPrime = 0;  // We support only two-prime RSA. 
-
-
-/*static*/ void TASN1EncPKCS8::AddAttributesL(CASN1EncSequence& aSeq, const TDesC8& aAttribute)
-	{
-	if (aAttribute != KNullDesC8)
-		{
-		CASN1EncEncoding* encoded = CASN1EncEncoding::NewLC(aAttribute);
-		aSeq.AddAndPopChildL(encoded);		
-		}
-	}
-
-/**
- * Given a ASN1 sequence representing a private key and a CPBEncryptor object,
- * it returns an ASN1 octet string containing the key sequence encrypted by
- * the given encryptor.
- *
- * @param aKeySeq The key sequence to be encrypted.
- * @param aEncryptor The CPBEncryptor object used to encrypt the given key.
- * @return An ASN1 octet string containing the encrypted key.
- */
-/*static*/ CASN1EncOctetString* TASN1EncPKCS8::EncryptKeySequenceL(CASN1EncSequence& aKeySeq, CPBEncryptor& aEncryptor)
-	{
-	//	Make an octet string of the key sequence
-	TUint seqLen = aKeySeq.LengthDER();
-	HBufC8* octetData = HBufC8::NewMaxLC(seqLen);
-	TPtr8 oct(octetData->Des());
-	oct.FillZ();
-	TUint writePos = 0;
-	aKeySeq.WriteDERL(oct, writePos);
-	
-	// Encrypt it
-        HBufC8* encryptedData = HBufC8::NewLC(aEncryptor.MaxFinalOutputLength(seqLen)); 
-        TPtr8 encrypted(encryptedData->Des());  
-
-	aEncryptor.ProcessFinalL(*octetData, encrypted);
-		
-	CASN1EncOctetString* octet = CASN1EncOctetString::NewL(encrypted);
-	
-	CleanupStack::PopAndDestroy(2, octetData); // encryptedData, octetData
-	
-	return octet;
-	}
-
-
-/*static*/ CASN1EncOctetString* TASN1EncPKCS8::ElementToOctetL(CASN1EncBase& aAsnElement)
-	{
-	//	Make an octet string from the structure
-	HBufC8* octetData = HBufC8::NewMaxLC(aAsnElement.LengthDER());
-	TPtr8 oct(octetData->Des());
-	oct.FillZ();
-
-	TUint writePos = 0;
-	aAsnElement.WriteDERL(oct, writePos);
-	
-	CASN1EncOctetString* octet = CASN1EncOctetString::NewL(oct);
-	CleanupStack::PopAndDestroy(octetData);
-	return octet;
-	}
-
-
-/*static*/ CASN1EncSequence* TASN1EncPKCS8::EncryptedSequenceL(CASN1EncSequence& aPrivateKeySequence, 
-                                                               CPBEncryptor& aEncryptor, CPBEncryptParms& aData)
-	{
-	// Main ASN1 sequence
-	CASN1EncSequence* seq = CASN1EncSequence::NewLC();
-	
-	// PKCS#5 PBE sequence
-	CASN1EncSequence* pkcs5Seq = TASN1EncPKCS5::EncodeDERL(aData);
-	 
-	CleanupStack::PushL(pkcs5Seq);
-	seq->AddAndPopChildL(pkcs5Seq);
-	
-	// Encrypt the Private Key Sequence
-	CASN1EncOctetString* octet = EncryptKeySequenceL(aPrivateKeySequence, aEncryptor);
-	CleanupStack::PushL(octet);
-	seq->AddAndPopChildL(octet);
-
-	CleanupStack::Pop(seq);
-
-	return seq;
-	}
-
-
-/*static*/ const RInteger TASN1EncPKCS8::CalculateRSAPrivExpL(const CRSAPrivateKeyCRT& aPrivateKey, const CRSAPublicKey& aPublicKey)
-	{
-	const TInteger& e = aPublicKey.E();
-
-	RInteger pTemp = RInteger::NewL(aPrivateKey.P());
-	CleanupStack::PushL(pTemp);
-	RInteger qTemp = RInteger::NewL(aPrivateKey.Q());
-	CleanupStack::PushL(qTemp);
-	
-  	--pTemp;
-    	--qTemp;
- 
-	//phi = (p-1)(q-1)
-	RInteger phi = pTemp.TimesL(qTemp);
-
-	CleanupStack::PopAndDestroy(2, &pTemp);  // qTemp, pTemp
- 	CleanupStack::PushL(phi);
-    	
-    	//d = e^(-1) mod ((p-1)(q-1))
-   	 RInteger d = e.InverseModL(phi);
-    	CleanupStack::PopAndDestroy(&phi); 
-	return d;	
-	}
-
-/**
- * Encodes the given private key using the pkcs#8 standard.
- *
- * The returned ASN1 sequence respects the following grammar:
- * 
- *	PrivateKeyInfo ::= SEQUENCE {
- *	version Version,
- *	privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
- *	privateKey PrivateKey,
- *	attributes [0] IMPLICIT Attributes OPTIONAL }
- *	
- *	Version ::= INTEGER
- *	PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier
- *	PrivateKey ::= OCTET STRING
- *	Attributes ::= SET OF Attribute
- *
- *
- * @param aKeyPair A key pair containing the private key we wish to encode.
- * @return A CASN1EncSequence encoding the private key. The sequence
- *         follows the grammar specified above. 
- * @internalComponent
- * @released
- */
-/*static*/ EXPORT_C CASN1EncSequence* TASN1EncPKCS8::EncodeL(const CRSAPrivateKeyCRT& aPrivateKey, 
-														  const CRSAPublicKey& aPublicKey, 
-														  const TDesC8& aAttributes)
-	{
-	// Main ASN1 sequence
-	CASN1EncSequence* seq = CASN1EncSequence::NewLC();
-
-	// Start with PKCS#8 header
-	CASN1EncInt* version = CASN1EncInt::NewLC(KPkcs8Version); 
-	seq->AddAndPopChildL(version);
-	
-	//	Algorithm sequence
-	CASN1EncSequence* algSeq = CASN1EncSequence::NewLC();
-
-	CASN1EncObjectIdentifier* oid = CASN1EncObjectIdentifier::NewLC(KRSA);
-	algSeq->AddAndPopChildL(oid);
-
-	//	No other parameters
-	CASN1EncNull* nullparams = CASN1EncNull::NewLC();
-	algSeq->AddAndPopChildL(nullparams);
-
-	seq->AddAndPopChildL(algSeq);
-	
-	// The actual private key sequence		
-	CASN1EncSequence* keySeq = CASN1EncSequence::NewLC();
-
-	//	TASN1DecGeneric* versionData = theData->operator[](seqIndex);
-	CASN1EncInt* rsaVersion = CASN1EncInt::NewLC(KPkcs8RSATwoPrime); 
-	keySeq->AddAndPopChildL(rsaVersion);
-	
-	//	The modulus	
-	const TInteger& modulus = aPrivateKey.N();
-	CASN1EncBigInt* mod = CASN1EncBigInt::NewLC(modulus);
-	keySeq->AddAndPopChildL(mod);
-
-	//	The public exponent
-	const TInteger& e = aPublicKey.E();
-	CASN1EncBigInt* publicExp = CASN1EncBigInt::NewLC(e);
-	keySeq->AddAndPopChildL(publicExp);
-
-	// The private exponent
-	RInteger d = CalculateRSAPrivExpL(aPrivateKey, aPublicKey);
-	CleanupStack::PushL(d);
-
-	CASN1EncBigInt* privateExp = CASN1EncBigInt::NewLC(d);
-
-	keySeq->AddAndPopChildL(privateExp);
-	CleanupStack::PopAndDestroy(&d);  // RSA Private Exponent 
-
-	//	The prime1
-	const TInteger& p = aPrivateKey.P();
-	CASN1EncBigInt* prime1 = CASN1EncBigInt::NewLC(p);
-	keySeq->AddAndPopChildL(prime1);
-
-	//	The prime2
-	const TInteger& q = aPrivateKey.Q();
-	CASN1EncBigInt* prime2 = CASN1EncBigInt::NewLC(q);
-	keySeq->AddAndPopChildL(prime2);
-
-	//	The exponent 1	
-	const TInteger& dp = aPrivateKey.DP();
-	CASN1EncBigInt* theExp1 = CASN1EncBigInt::NewLC(dp);
-	keySeq->AddAndPopChildL(theExp1);
-
-	//	The exponent 2
-	const TInteger& dq = aPrivateKey.DQ();
-	CASN1EncBigInt* theExp2 = CASN1EncBigInt::NewLC(dq);
-	keySeq->AddAndPopChildL(theExp2);
-
-	//	The coefficient
-	const TInteger& coeff = aPrivateKey.QInv();
-	CASN1EncBigInt* coefficient = CASN1EncBigInt::NewLC(coeff);
-	keySeq->AddAndPopChildL(coefficient);
-	
-	CASN1EncOctetString* octet = ElementToOctetL(*keySeq);
-	CleanupStack::PushL(octet);
-	
-	//	Now add the octet of the key sequence to the sequence
-	seq->AddAndPopChildL(octet);
-	
-  	CleanupStack::PopAndDestroy(keySeq);
-
-	AddAttributesL(*seq, aAttributes);
-
-  	CleanupStack::Pop(seq);
-					
-	return seq;
-	}
-
-/**
- * Encodes an RSA key in encrypted format.
- * 
- * @param aPrivateKey The private key to be encoded (must be in CRT format)
- * @param aPublicKey The corresponding public key.
- * @param aEncryptor The object used to encrypt the data.
- * @param aData The encryption parameters of the given encryptor.
- *              These parameters are stored in the resulting sequence.
- *
- * @return An ASN1 Sequence encoding the encrypted key.
- */
-/*static*/ EXPORT_C CASN1EncSequence* TASN1EncPKCS8::EncodeEncryptedL(const CRSAPrivateKeyCRT& aPrivateKey, const CRSAPublicKey& aPublicKey, 
-                                                                      CPBEncryptor& aEncryptor, CPBEncryptParms& aData, const TDesC8& aAttributes)
-	{
-	// Now generate a PrivateKeyInfo type 
-	CASN1EncSequence* privKeySeq = EncodeL(aPrivateKey, aPublicKey, aAttributes);
-	CleanupStack::PushL(privKeySeq);
-	
-	CASN1EncSequence* seq = EncryptedSequenceL(*privKeySeq, aEncryptor, aData);
-	
-	CleanupStack::PopAndDestroy(privKeySeq);
-		
-	return seq;
-	}
-
-
-/**
- * Return the ASN1 PKCS#8 encoding of a DSA private key.
- *
- * The private key syntax for this key type is defined in 
- * the PKCS#11 document. 
- *
- * @param aPrivateKey The private key to be encoded (must be in CRT format)
- *
- * @return An ASN1 Sequence encoding the key.
- */	
-/*static*/ EXPORT_C CASN1EncSequence* TASN1EncPKCS8::EncodeL(const CDSAPrivateKey& aPrivateKey, 
-													          const TDesC8& aAttributes)
-	{
-	// Main ASN1 sequence
-	CASN1EncSequence* seq = CASN1EncSequence::NewLC();
-
-	//	version
-	CASN1EncInt* version = CASN1EncInt::NewLC(KPkcs8Version);
-	seq->AddAndPopChildL(version);
-	
-	//	Algorithm sequence
-	CASN1EncSequence* algSeq = CASN1EncSequence::NewLC();
-
-	CASN1EncObjectIdentifier* oid = CASN1EncObjectIdentifier::NewLC(KDSA);
-	algSeq->AddAndPopChildL(oid);
-
-	seq->AddAndPopChildL(algSeq);
-
-	// DSA Parameters	
-	CASN1EncSequence* keySeq = CASN1EncSequence::NewLC();
-
-	//	The modulus	P
-	const TInteger& modulus1 = aPrivateKey.P();
-
-	CASN1EncBigInt* mod = CASN1EncBigInt::NewLC(modulus1);
-	keySeq->AddAndPopChildL(mod);
-
-	//	The modulus	Q
-	const TInteger& modulus2 = aPrivateKey.Q();
-	
-	CASN1EncBigInt* mod2 = CASN1EncBigInt::NewLC(modulus2);
-	keySeq->AddAndPopChildL(mod2);
-	
-	//	The base G 
-	const TInteger& base = aPrivateKey.G();
-
-	CASN1EncBigInt* b = CASN1EncBigInt::NewLC(base);
-	keySeq->AddAndPopChildL(b);
-	
-	algSeq->AddAndPopChildL(keySeq);
-	
-	//	The private key X
-	const TInteger& priv = aPrivateKey.X();	
-	CASN1EncBigInt* x = CASN1EncBigInt::NewLC(priv);
-
-	CASN1EncOctetString* octet = ElementToOctetL(*x);
-
-	CleanupStack::PopAndDestroy(x);
-	CleanupStack::PushL(octet);
-
-	seq->AddAndPopChildL(octet);
-
-	AddAttributesL(*seq, aAttributes);
-	
-	CleanupStack::Pop(seq);
-
-	return seq;	
-	}
-
-
-/**
- * Encodes a DSA key in encrypted format.
- * 
- * @param aPrivateKey The private key to be encoded.
- * @param aEncryptor The object used to encrypt the data.
- * @param aData The encryption parameters of the given encryptor.
- *              These parameters are stored in the resulting sequence.
- *
- * @return An ASN1 Sequence encoding the encrypted key.
- */
-/*static*/ EXPORT_C CASN1EncSequence* TASN1EncPKCS8::EncodeEncryptedL(const CDSAPrivateKey& aPrivateKey, CPBEncryptor& aEncryptor, 
-                                                                      CPBEncryptParms& aData, const TDesC8& aAttributes)
-	{
-	// Now generate a PrivateKeyInfo type 
-	CASN1EncSequence* privKeySeq = EncodeL(aPrivateKey, aAttributes);
-	CleanupStack::PushL(privKeySeq);
-	
-	CASN1EncSequence* seq = EncryptedSequenceL(*privKeySeq, aEncryptor, aData);
-	
-	CleanupStack::PopAndDestroy(privKeySeq);
-		
-	return seq;
-	}
+/*
+* Copyright (c) 2004-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 <asn1enc.h>
+#include <pbe.h>
+#include <asymmetrickeys.h>
+#include <bigint.h>
+#include "asnpkcs.h"
+
+const TInt KPkcs8Version = 0;      // PKCS#8 version 0 
+const TInt KPkcs8RSATwoPrime = 0;  // We support only two-prime RSA. 
+
+
+/*static*/ void TASN1EncPKCS8::AddAttributesL(CASN1EncSequence& aSeq, const TDesC8& aAttribute)
+	{
+	if (aAttribute != KNullDesC8)
+		{
+		CASN1EncEncoding* encoded = CASN1EncEncoding::NewLC(aAttribute);
+		aSeq.AddAndPopChildL(encoded);		
+		}
+	}
+
+/**
+ * Given a ASN1 sequence representing a private key and a CPBEncryptor object,
+ * it returns an ASN1 octet string containing the key sequence encrypted by
+ * the given encryptor.
+ *
+ * @param aKeySeq The key sequence to be encrypted.
+ * @param aEncryptor The CPBEncryptor object used to encrypt the given key.
+ * @return An ASN1 octet string containing the encrypted key.
+ */
+/*static*/ CASN1EncOctetString* TASN1EncPKCS8::EncryptKeySequenceL(CASN1EncSequence& aKeySeq, CPBEncryptor& aEncryptor)
+	{
+	//	Make an octet string of the key sequence
+	TUint seqLen = aKeySeq.LengthDER();
+	HBufC8* octetData = HBufC8::NewMaxLC(seqLen);
+	TPtr8 oct(octetData->Des());
+	oct.FillZ();
+	TUint writePos = 0;
+	aKeySeq.WriteDERL(oct, writePos);
+	
+	// Encrypt it
+        HBufC8* encryptedData = HBufC8::NewLC(aEncryptor.MaxFinalOutputLength(seqLen)); 
+        TPtr8 encrypted(encryptedData->Des());  
+
+	aEncryptor.ProcessFinalL(*octetData, encrypted);
+		
+	CASN1EncOctetString* octet = CASN1EncOctetString::NewL(encrypted);
+	
+	CleanupStack::PopAndDestroy(2, octetData); // encryptedData, octetData
+	
+	return octet;
+	}
+
+
+/*static*/ CASN1EncOctetString* TASN1EncPKCS8::ElementToOctetL(CASN1EncBase& aAsnElement)
+	{
+	//	Make an octet string from the structure
+	HBufC8* octetData = HBufC8::NewMaxLC(aAsnElement.LengthDER());
+	TPtr8 oct(octetData->Des());
+	oct.FillZ();
+
+	TUint writePos = 0;
+	aAsnElement.WriteDERL(oct, writePos);
+	
+	CASN1EncOctetString* octet = CASN1EncOctetString::NewL(oct);
+	CleanupStack::PopAndDestroy(octetData);
+	return octet;
+	}
+
+
+/*static*/ CASN1EncSequence* TASN1EncPKCS8::EncryptedSequenceL(CASN1EncSequence& aPrivateKeySequence, 
+                                                               CPBEncryptor& aEncryptor, CPBEncryptParms& aData)
+	{
+	// Main ASN1 sequence
+	CASN1EncSequence* seq = CASN1EncSequence::NewLC();
+	
+	// PKCS#5 PBE sequence
+	CASN1EncSequence* pkcs5Seq = TASN1EncPKCS5::EncodeDERL(aData);
+	 
+	CleanupStack::PushL(pkcs5Seq);
+	seq->AddAndPopChildL(pkcs5Seq);
+	
+	// Encrypt the Private Key Sequence
+	CASN1EncOctetString* octet = EncryptKeySequenceL(aPrivateKeySequence, aEncryptor);
+	CleanupStack::PushL(octet);
+	seq->AddAndPopChildL(octet);
+
+	CleanupStack::Pop(seq);
+
+	return seq;
+	}
+
+
+/*static*/ const RInteger TASN1EncPKCS8::CalculateRSAPrivExpL(const CRSAPrivateKeyCRT& aPrivateKey, const CRSAPublicKey& aPublicKey)
+	{
+	const TInteger& e = aPublicKey.E();
+
+	RInteger pTemp = RInteger::NewL(aPrivateKey.P());
+	CleanupStack::PushL(pTemp);
+	RInteger qTemp = RInteger::NewL(aPrivateKey.Q());
+	CleanupStack::PushL(qTemp);
+	
+  	--pTemp;
+    	--qTemp;
+ 
+	//phi = (p-1)(q-1)
+	RInteger phi = pTemp.TimesL(qTemp);
+
+	CleanupStack::PopAndDestroy(2, &pTemp);  // qTemp, pTemp
+ 	CleanupStack::PushL(phi);
+    	
+    	//d = e^(-1) mod ((p-1)(q-1))
+   	 RInteger d = e.InverseModL(phi);
+    	CleanupStack::PopAndDestroy(&phi); 
+	return d;	
+	}
+
+/**
+ * Encodes the given private key using the pkcs#8 standard.
+ *
+ * The returned ASN1 sequence respects the following grammar:
+ * 
+ *	PrivateKeyInfo ::= SEQUENCE {
+ *	version Version,
+ *	privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
+ *	privateKey PrivateKey,
+ *	attributes [0] IMPLICIT Attributes OPTIONAL }
+ *	
+ *	Version ::= INTEGER
+ *	PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier
+ *	PrivateKey ::= OCTET STRING
+ *	Attributes ::= SET OF Attribute
+ *
+ *
+ * @param aKeyPair A key pair containing the private key we wish to encode.
+ * @return A CASN1EncSequence encoding the private key. The sequence
+ *         follows the grammar specified above. 
+ * @internalComponent
+ * @released
+ */
+/*static*/ EXPORT_C CASN1EncSequence* TASN1EncPKCS8::EncodeL(const CRSAPrivateKeyCRT& aPrivateKey, 
+														  const CRSAPublicKey& aPublicKey, 
+														  const TDesC8& aAttributes)
+	{
+	// Main ASN1 sequence
+	CASN1EncSequence* seq = CASN1EncSequence::NewLC();
+
+	// Start with PKCS#8 header
+	CASN1EncInt* version = CASN1EncInt::NewLC(KPkcs8Version); 
+	seq->AddAndPopChildL(version);
+	
+	//	Algorithm sequence
+	CASN1EncSequence* algSeq = CASN1EncSequence::NewLC();
+
+	CASN1EncObjectIdentifier* oid = CASN1EncObjectIdentifier::NewLC(KRSA);
+	algSeq->AddAndPopChildL(oid);
+
+	//	No other parameters
+	CASN1EncNull* nullparams = CASN1EncNull::NewLC();
+	algSeq->AddAndPopChildL(nullparams);
+
+	seq->AddAndPopChildL(algSeq);
+	
+	// The actual private key sequence		
+	CASN1EncSequence* keySeq = CASN1EncSequence::NewLC();
+
+	//	TASN1DecGeneric* versionData = theData->operator[](seqIndex);
+	CASN1EncInt* rsaVersion = CASN1EncInt::NewLC(KPkcs8RSATwoPrime); 
+	keySeq->AddAndPopChildL(rsaVersion);
+	
+	//	The modulus	
+	const TInteger& modulus = aPrivateKey.N();
+	CASN1EncBigInt* mod = CASN1EncBigInt::NewLC(modulus);
+	keySeq->AddAndPopChildL(mod);
+
+	//	The public exponent
+	const TInteger& e = aPublicKey.E();
+	CASN1EncBigInt* publicExp = CASN1EncBigInt::NewLC(e);
+	keySeq->AddAndPopChildL(publicExp);
+
+	// The private exponent
+	RInteger d = CalculateRSAPrivExpL(aPrivateKey, aPublicKey);
+	CleanupStack::PushL(d);
+
+	CASN1EncBigInt* privateExp = CASN1EncBigInt::NewLC(d);
+
+	keySeq->AddAndPopChildL(privateExp);
+	CleanupStack::PopAndDestroy(&d);  // RSA Private Exponent 
+
+	//	The prime1
+	const TInteger& p = aPrivateKey.P();
+	CASN1EncBigInt* prime1 = CASN1EncBigInt::NewLC(p);
+	keySeq->AddAndPopChildL(prime1);
+
+	//	The prime2
+	const TInteger& q = aPrivateKey.Q();
+	CASN1EncBigInt* prime2 = CASN1EncBigInt::NewLC(q);
+	keySeq->AddAndPopChildL(prime2);
+
+	//	The exponent 1	
+	const TInteger& dp = aPrivateKey.DP();
+	CASN1EncBigInt* theExp1 = CASN1EncBigInt::NewLC(dp);
+	keySeq->AddAndPopChildL(theExp1);
+
+	//	The exponent 2
+	const TInteger& dq = aPrivateKey.DQ();
+	CASN1EncBigInt* theExp2 = CASN1EncBigInt::NewLC(dq);
+	keySeq->AddAndPopChildL(theExp2);
+
+	//	The coefficient
+	const TInteger& coeff = aPrivateKey.QInv();
+	CASN1EncBigInt* coefficient = CASN1EncBigInt::NewLC(coeff);
+	keySeq->AddAndPopChildL(coefficient);
+	
+	CASN1EncOctetString* octet = ElementToOctetL(*keySeq);
+	CleanupStack::PushL(octet);
+	
+	//	Now add the octet of the key sequence to the sequence
+	seq->AddAndPopChildL(octet);
+	
+  	CleanupStack::PopAndDestroy(keySeq);
+
+	AddAttributesL(*seq, aAttributes);
+
+  	CleanupStack::Pop(seq);
+					
+	return seq;
+	}
+
+/**
+ * Encodes an RSA key in encrypted format.
+ * 
+ * @param aPrivateKey The private key to be encoded (must be in CRT format)
+ * @param aPublicKey The corresponding public key.
+ * @param aEncryptor The object used to encrypt the data.
+ * @param aData The encryption parameters of the given encryptor.
+ *              These parameters are stored in the resulting sequence.
+ *
+ * @return An ASN1 Sequence encoding the encrypted key.
+ */
+/*static*/ EXPORT_C CASN1EncSequence* TASN1EncPKCS8::EncodeEncryptedL(const CRSAPrivateKeyCRT& aPrivateKey, const CRSAPublicKey& aPublicKey, 
+                                                                      CPBEncryptor& aEncryptor, CPBEncryptParms& aData, const TDesC8& aAttributes)
+	{
+	// Now generate a PrivateKeyInfo type 
+	CASN1EncSequence* privKeySeq = EncodeL(aPrivateKey, aPublicKey, aAttributes);
+	CleanupStack::PushL(privKeySeq);
+	
+	CASN1EncSequence* seq = EncryptedSequenceL(*privKeySeq, aEncryptor, aData);
+	
+	CleanupStack::PopAndDestroy(privKeySeq);
+		
+	return seq;
+	}
+
+
+/**
+ * Return the ASN1 PKCS#8 encoding of a DSA private key.
+ *
+ * The private key syntax for this key type is defined in 
+ * the PKCS#11 document. 
+ *
+ * @param aPrivateKey The private key to be encoded (must be in CRT format)
+ *
+ * @return An ASN1 Sequence encoding the key.
+ */	
+/*static*/ EXPORT_C CASN1EncSequence* TASN1EncPKCS8::EncodeL(const CDSAPrivateKey& aPrivateKey, 
+													          const TDesC8& aAttributes)
+	{
+	// Main ASN1 sequence
+	CASN1EncSequence* seq = CASN1EncSequence::NewLC();
+
+	//	version
+	CASN1EncInt* version = CASN1EncInt::NewLC(KPkcs8Version);
+	seq->AddAndPopChildL(version);
+	
+	//	Algorithm sequence
+	CASN1EncSequence* algSeq = CASN1EncSequence::NewLC();
+
+	CASN1EncObjectIdentifier* oid = CASN1EncObjectIdentifier::NewLC(KDSA);
+	algSeq->AddAndPopChildL(oid);
+
+	seq->AddAndPopChildL(algSeq);
+
+	// DSA Parameters	
+	CASN1EncSequence* keySeq = CASN1EncSequence::NewLC();
+
+	//	The modulus	P
+	const TInteger& modulus1 = aPrivateKey.P();
+
+	CASN1EncBigInt* mod = CASN1EncBigInt::NewLC(modulus1);
+	keySeq->AddAndPopChildL(mod);
+
+	//	The modulus	Q
+	const TInteger& modulus2 = aPrivateKey.Q();
+	
+	CASN1EncBigInt* mod2 = CASN1EncBigInt::NewLC(modulus2);
+	keySeq->AddAndPopChildL(mod2);
+	
+	//	The base G 
+	const TInteger& base = aPrivateKey.G();
+
+	CASN1EncBigInt* b = CASN1EncBigInt::NewLC(base);
+	keySeq->AddAndPopChildL(b);
+	
+	algSeq->AddAndPopChildL(keySeq);
+	
+	//	The private key X
+	const TInteger& priv = aPrivateKey.X();	
+	CASN1EncBigInt* x = CASN1EncBigInt::NewLC(priv);
+
+	CASN1EncOctetString* octet = ElementToOctetL(*x);
+
+	CleanupStack::PopAndDestroy(x);
+	CleanupStack::PushL(octet);
+
+	seq->AddAndPopChildL(octet);
+
+	AddAttributesL(*seq, aAttributes);
+	
+	CleanupStack::Pop(seq);
+
+	return seq;	
+	}
+
+
+/**
+ * Encodes a DSA key in encrypted format.
+ * 
+ * @param aPrivateKey The private key to be encoded.
+ * @param aEncryptor The object used to encrypt the data.
+ * @param aData The encryption parameters of the given encryptor.
+ *              These parameters are stored in the resulting sequence.
+ *
+ * @return An ASN1 Sequence encoding the encrypted key.
+ */
+/*static*/ EXPORT_C CASN1EncSequence* TASN1EncPKCS8::EncodeEncryptedL(const CDSAPrivateKey& aPrivateKey, CPBEncryptor& aEncryptor, 
+                                                                      CPBEncryptParms& aData, const TDesC8& aAttributes)
+	{
+	// Now generate a PrivateKeyInfo type 
+	CASN1EncSequence* privKeySeq = EncodeL(aPrivateKey, aAttributes);
+	CleanupStack::PushL(privKeySeq);
+	
+	CASN1EncSequence* seq = EncryptedSequenceL(*privKeySeq, aEncryptor, aData);
+	
+	CleanupStack::PopAndDestroy(privKeySeq);
+		
+	return seq;
+	}
+