cryptoservices/certificateandkeymgmt/x509/x509keysRSA.cpp
changeset 8 35751d3474b7
parent 0 2c201484c85f
--- a/cryptoservices/certificateandkeymgmt/x509/x509keysRSA.cpp	Tue Jul 21 01:04:32 2009 +0100
+++ b/cryptoservices/certificateandkeymgmt/x509/x509keysRSA.cpp	Thu Sep 10 14:01:51 2009 +0300
@@ -1,292 +1,293 @@
-/*
-* Copyright (c) 1998-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 <x509keys.h>
-#include <asn1dec.h>
-#include <asn1enc.h>
-#include <x509cert.h>
-
-CX509RSAPublicKey::CX509RSAPublicKey()
-{}
-
-//RSA public key
-EXPORT_C CX509RSAPublicKey* CX509RSAPublicKey::NewL(const TDesC8& aBinaryData)
-	{
-	TInt pos = 0;
-	return CX509RSAPublicKey::NewL(aBinaryData, pos);
-	}
-
-EXPORT_C CX509RSAPublicKey* CX509RSAPublicKey::NewLC(const TDesC8& aBinaryData)
-	{
-	TInt pos = 0;
-	return CX509RSAPublicKey::NewLC(aBinaryData, pos);
-	}
-
-EXPORT_C CX509RSAPublicKey* CX509RSAPublicKey::NewL(const TDesC8& aBinaryData, TInt& aPos)
-	{
-	CX509RSAPublicKey* self = CX509RSAPublicKey::NewLC(aBinaryData, aPos);
-	CleanupStack::Pop();
-	return self;
-	}
-
-EXPORT_C CX509RSAPublicKey* CX509RSAPublicKey::NewLC(const TDesC8& aBinaryData, TInt& aPos)
-	{
-	CX509RSAPublicKey* self = new(ELeave) CX509RSAPublicKey();
-	CleanupStack::PushL(self);
-	self->ConstructL(aBinaryData, aPos);
-	return self;
-	}
-
-void CX509RSAPublicKey::ConstructL(const TDesC8& aBinaryData, TInt& aPos)
-	{
-	TASN1DecGeneric gen(aBinaryData.Right(aBinaryData.Length() - aPos));
-	gen.InitL();
-	TInt end = aPos + gen.LengthDER();
-	aPos += gen.LengthDERHeader();
-	if (gen.Tag() != EASN1Sequence)
-		{
-		User::Leave(KErrArgument);
-		}
-	TASN1DecInteger encInt;
-	iN = encInt.DecodeDERLongL(aBinaryData, aPos);
-	iE = encInt.DecodeDERLongL(aBinaryData, aPos);
-
-	// RSA Public keys, modulus and exponent must be positive integers
-	if(!iN.IsPositive() || !iE.IsPositive())
-		{
-		User::Leave(KErrArgument);
-		}
-	if (aPos != end)
-		{
-		User::Leave(KErrArgument);
-		}
-	}
-
-// Encodes public key to DER
-EXPORT_C HBufC8* TASN1EncRSAPublicKey::EncodeDERL(const CRSAPublicKey& aKey) const
-	{
-	CASN1EncSequence* sequence = CASN1EncSequence::NewLC();
-	CASN1EncBigInt* encModulus = CASN1EncBigInt::NewLC(aKey.N());
-	sequence->AddAndPopChildL(encModulus);
-	CASN1EncBigInt* encPublicExponent = CASN1EncBigInt::NewLC(aKey.E());
-	sequence->AddAndPopChildL(encPublicExponent);
-	HBufC8* der = HBufC8::NewMaxLC(sequence->LengthDER());
-	TUint pos = 0;
-	TPtr8 derptr(der->Des());
-	sequence->WriteDERL(derptr, pos);
-	CleanupStack::Pop(der);
-	CleanupStack::PopAndDestroy(sequence);
-	return der;
-	}
-
-// Decodes public key from DER
-EXPORT_C CRSAPublicKey* TASN1DecRSAPublicKey::DecodeDERL(const TDesC8& aDER, 
-														 TInt& aPos) const
-	{
-	// Enter into the containing SEQUENCE and verify if it is indeed there
-	TASN1DecGeneric gen(aDER.Right(aDER.Length() - aPos));
-	gen.InitL();
-	TInt end = aPos + gen.LengthDER();
-	aPos += gen.LengthDERHeader();
-	if (gen.Tag() != EASN1Sequence)
-		User::Leave(KErrArgument);
-
-	// Decode modulus and public exponent (two large integers)
-	TASN1DecInteger encInt;
-	RInteger modulus = encInt.DecodeDERLongL(aDER, aPos);
-	CleanupStack::PushL(modulus);
-	RInteger publicExponent = encInt.DecodeDERLongL(aDER, aPos);
-	CleanupStack::PushL(publicExponent);
-	if (aPos != end)
-		User::Leave(KErrArgument);
-
-	// Construct a new key without copying
-	CRSAPublicKey* key = CRSAPublicKey::NewL(modulus, publicExponent);
-	CleanupStack::Pop(2); // modulus, publicExponent - owned by public key
-	return key;
-	}
-
-// Decodes RSA key pair from DER-encoded buffer
-EXPORT_C void TASN1DecRSAKeyPair::DecodeDERL(const TDesC8& aDER, 
-												TInt& aPos, 
-												CRSAPublicKey*& aPublicKey,
-												CRSAPrivateKey*& aPrivateKey,
-												TRSAPrivateKeyType aKeyType /*=EStandardCRT*/)
-{
-	aPublicKey = NULL;
-	aPrivateKey = NULL;
-
-	// Enter into the containing SEQUENCE and verify if it is 
-	// indeed there
-	TASN1DecGeneric gen(aDER.Right(aDER.Length() - aPos));
-	gen.InitL();
-	TInt end = aPos + gen.LengthDER();
-	aPos += gen.LengthDERHeader();
-	if (gen.Tag() != EASN1Sequence)
-		User::Leave(KErrArgument);
-
-	TASN1DecInteger encInt;
-	
-	// Decode and discard version, which is an integer
-	encInt.DecodeDERShortL(aDER, aPos);
-
-	// Decode public key components
-	
-	// Decode modulus
-	RInteger publicModulus = encInt.DecodeDERLongL(aDER, aPos);
-	CleanupStack::PushL(publicModulus);
-	
-	// Decode public exponent
-	RInteger publicExponent = encInt.DecodeDERLongL(aDER, aPos);
-	CleanupStack::PushL(publicExponent);
-
-	//	Construct public key
-	CRSAPublicKey* publicKey = CRSAPublicKey::NewL(publicModulus, publicExponent);
-	CleanupStack::Pop(2, &publicModulus); // Now owned by publicKey
-	CleanupStack::PushL(publicKey);
-
-	// Decode private key components
-
-	// Copy modulus
-	RInteger privateModulus = RInteger::NewL(publicKey->N());
-	CleanupStack::PushL(privateModulus);					  
-	// Decode private exponent
-	RInteger privateExponent = encInt.DecodeDERLongL(aDER, aPos);
-	CleanupStack::PushL(privateExponent);
-	// Decode prime 1
-	RInteger p = encInt.DecodeDERLongL(aDER, aPos);
-	CleanupStack::PushL(p);
-	// Decode prime 2
-	RInteger q = encInt.DecodeDERLongL(aDER, aPos);
-	CleanupStack::PushL(q);
-	// Decode exponent 1
-	RInteger dmp1 = encInt.DecodeDERLongL(aDER, aPos);
-	CleanupStack::PushL(dmp1);
-	// Decode exponent 2
-	RInteger dmq1 = encInt.DecodeDERLongL(aDER, aPos);
-	CleanupStack::PushL(dmq1);
-	// Decode coefficient
-	RInteger the_iqmp = encInt.DecodeDERLongL(aDER, aPos);
-	CleanupStack::PushL(the_iqmp);
-
-	// We now should be at the end of the encoding. If not, the 
-	// input encoding contains extra fields, and they are not 
-	// supported.
-	if (aPos != end)
-		User::Leave(KErrArgument);
-	
-//	Construct private key
-	CRSAPrivateKey* privateKey = NULL;
-	if (EStandardCRT==aKeyType)
-	{
-		privateKey = CRSAPrivateKeyCRT::NewL(privateModulus, p, q, dmp1, dmq1, the_iqmp);
-	}
-	else if (EStandard==aKeyType)
-	{
-		privateKey = CRSAPrivateKeyStandard::NewL(privateModulus, privateExponent);
-	}
-	else
-		User::Leave(KErrNotSupported);
-	
-	CleanupStack::Pop(8,publicKey);	 // publicKey, privateModulus, privateExponent,
-	                                 // p, q, dmp1, dmq1, iqmp
-	
-//	Cleanup the TIntegers not owned by private key objects
-	if (EStandard==aKeyType)
-	{
-		p.Close();
-		q.Close();
-		dmp1.Close();
-		dmq1.Close();
-		the_iqmp.Close();
-	}
-	else
-	{
-		privateExponent.Close();
-	}
-
-	aPublicKey = publicKey;
-	aPrivateKey = privateKey;	
-}
-
-// TX509RSAKeyEncoder Class Implementation
-
-EXPORT_C TX509RSAKeyEncoder::TX509RSAKeyEncoder(const CRSAPublicKey& aPublicKey, TAlgorithmId aDigestAlg)
-	: TX509KeyEncoder(aDigestAlg),
-	  iPublicKey(aPublicKey)
-	{
-	}
-
-EXPORT_C CASN1EncBase* TX509RSAKeyEncoder::EncodeKeyLC() const
-	{
-	// Create higher-level sequence that will contain OID and the public key
-	CASN1EncSequence* subjectPubKeyInfo = CASN1EncSequence::NewLC();
-
-	// The next-level sequence will contain OID of the algorithm followed by NULL
-	CASN1EncSequence* seq = CASN1EncSequence::NewLC();
-	CASN1EncObjectIdentifier* oid = CASN1EncObjectIdentifier::NewLC(KRSA);
-	seq->AddAndPopChildL(oid);
-	CASN1EncNull* null = CASN1EncNull::NewLC();
-	seq->AddAndPopChildL(null);
-	subjectPubKeyInfo->AddAndPopChildL(seq);
-	
-	// Add the key itself to the higher-level sequence as a bit string
-	// Obtain a copy of the entity's public key
-	TASN1EncRSAPublicKey keyencoder;
-	HBufC8* encoding = keyencoder.EncodeDERL(iPublicKey);
-	CleanupStack::PushL(encoding);
-	CASN1EncBitString* pubkeyenc = CASN1EncBitString::NewLC(*encoding);
-	subjectPubKeyInfo->AddAndPopChildL(pubkeyenc);
-	CleanupStack::PopAndDestroy(encoding);
-	return subjectPubKeyInfo;
-	}
-
-// Returns ASN.1 sequence containing encoded signature algorithm.
-EXPORT_C CASN1EncSequence* TX509RSAKeyEncoder::EncodeSignatureAlgorithmLC() const
-	{
-	CASN1EncSequence* seq = CASN1EncSequence::NewLC();
-	CASN1EncObjectIdentifier* oid = NULL;
-
-	// Determine OID string for the current combination of algorithms.
-	switch(iDigestAlg)
-		{
-		default:
-			User::Leave(KErrNotSupported);
-			break;
-
-		case EMD2:
-			oid = CASN1EncObjectIdentifier::NewLC(KMD2WithRSA);
-			break;
-
-		case EMD5:
-			oid = CASN1EncObjectIdentifier::NewLC(KMD5WithRSA);
-			break;
-
-		case ESHA1:
-			oid = CASN1EncObjectIdentifier::NewLC(KSHA1WithRSA);
-			break;
-		}
-
-	// Add algorithm OID to the sequence.
-	seq->AddAndPopChildL(oid);
-	// Add NULL after OID.
-	CASN1EncNull* null = CASN1EncNull::NewLC();
-	seq->AddAndPopChildL(null);
-	
-	return seq;
-	}
+/*
+* Copyright (c) 1998-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 <x509keys.h>
+#include <asn1dec.h>
+#include <asn1enc.h>
+#include <x509cert.h>
+#include "x509keyencoder.h"
+
+CX509RSAPublicKey::CX509RSAPublicKey()
+{}
+
+//RSA public key
+EXPORT_C CX509RSAPublicKey* CX509RSAPublicKey::NewL(const TDesC8& aBinaryData)
+	{
+	TInt pos = 0;
+	return CX509RSAPublicKey::NewL(aBinaryData, pos);
+	}
+
+EXPORT_C CX509RSAPublicKey* CX509RSAPublicKey::NewLC(const TDesC8& aBinaryData)
+	{
+	TInt pos = 0;
+	return CX509RSAPublicKey::NewLC(aBinaryData, pos);
+	}
+
+EXPORT_C CX509RSAPublicKey* CX509RSAPublicKey::NewL(const TDesC8& aBinaryData, TInt& aPos)
+	{
+	CX509RSAPublicKey* self = CX509RSAPublicKey::NewLC(aBinaryData, aPos);
+	CleanupStack::Pop();
+	return self;
+	}
+
+EXPORT_C CX509RSAPublicKey* CX509RSAPublicKey::NewLC(const TDesC8& aBinaryData, TInt& aPos)
+	{
+	CX509RSAPublicKey* self = new(ELeave) CX509RSAPublicKey();
+	CleanupStack::PushL(self);
+	self->ConstructL(aBinaryData, aPos);
+	return self;
+	}
+
+void CX509RSAPublicKey::ConstructL(const TDesC8& aBinaryData, TInt& aPos)
+	{
+	TASN1DecGeneric gen(aBinaryData.Right(aBinaryData.Length() - aPos));
+	gen.InitL();
+	TInt end = aPos + gen.LengthDER();
+	aPos += gen.LengthDERHeader();
+	if (gen.Tag() != EASN1Sequence)
+		{
+		User::Leave(KErrArgument);
+		}
+	TASN1DecInteger encInt;
+	iN = encInt.DecodeDERLongL(aBinaryData, aPos);
+	iE = encInt.DecodeDERLongL(aBinaryData, aPos);
+
+	// RSA Public keys, modulus and exponent must be positive integers
+	if(!iN.IsPositive() || !iE.IsPositive())
+		{
+		User::Leave(KErrArgument);
+		}
+	if (aPos != end)
+		{
+		User::Leave(KErrArgument);
+		}
+	}
+
+// Encodes public key to DER
+EXPORT_C HBufC8* TASN1EncRSAPublicKey::EncodeDERL(const CRSAPublicKey& aKey) const
+	{
+	CASN1EncSequence* sequence = CASN1EncSequence::NewLC();
+	CASN1EncBigInt* encModulus = CASN1EncBigInt::NewLC(aKey.N());
+	sequence->AddAndPopChildL(encModulus);
+	CASN1EncBigInt* encPublicExponent = CASN1EncBigInt::NewLC(aKey.E());
+	sequence->AddAndPopChildL(encPublicExponent);
+	HBufC8* der = HBufC8::NewMaxLC(sequence->LengthDER());
+	TUint pos = 0;
+	TPtr8 derptr(der->Des());
+	sequence->WriteDERL(derptr, pos);
+	CleanupStack::Pop(der);
+	CleanupStack::PopAndDestroy(sequence);
+	return der;
+	}
+
+// Decodes public key from DER
+EXPORT_C CRSAPublicKey* TASN1DecRSAPublicKey::DecodeDERL(const TDesC8& aDER, 
+														 TInt& aPos) const
+	{
+	// Enter into the containing SEQUENCE and verify if it is indeed there
+	TASN1DecGeneric gen(aDER.Right(aDER.Length() - aPos));
+	gen.InitL();
+	TInt end = aPos + gen.LengthDER();
+	aPos += gen.LengthDERHeader();
+	if (gen.Tag() != EASN1Sequence)
+		User::Leave(KErrArgument);
+
+	// Decode modulus and public exponent (two large integers)
+	TASN1DecInteger encInt;
+	RInteger modulus = encInt.DecodeDERLongL(aDER, aPos);
+	CleanupStack::PushL(modulus);
+	RInteger publicExponent = encInt.DecodeDERLongL(aDER, aPos);
+	CleanupStack::PushL(publicExponent);
+	if (aPos != end)
+		User::Leave(KErrArgument);
+
+	// Construct a new key without copying
+	CRSAPublicKey* key = CRSAPublicKey::NewL(modulus, publicExponent);
+	CleanupStack::Pop(2); // modulus, publicExponent - owned by public key
+	return key;
+	}
+
+// Decodes RSA key pair from DER-encoded buffer
+EXPORT_C void TASN1DecRSAKeyPair::DecodeDERL(const TDesC8& aDER, 
+												TInt& aPos, 
+												CRSAPublicKey*& aPublicKey,
+												CRSAPrivateKey*& aPrivateKey,
+												TRSAPrivateKeyType aKeyType /*=EStandardCRT*/)
+{
+	aPublicKey = NULL;
+	aPrivateKey = NULL;
+
+	// Enter into the containing SEQUENCE and verify if it is 
+	// indeed there
+	TASN1DecGeneric gen(aDER.Right(aDER.Length() - aPos));
+	gen.InitL();
+	TInt end = aPos + gen.LengthDER();
+	aPos += gen.LengthDERHeader();
+	if (gen.Tag() != EASN1Sequence)
+		User::Leave(KErrArgument);
+
+	TASN1DecInteger encInt;
+	
+	// Decode and discard version, which is an integer
+	encInt.DecodeDERShortL(aDER, aPos);
+
+	// Decode public key components
+	
+	// Decode modulus
+	RInteger publicModulus = encInt.DecodeDERLongL(aDER, aPos);
+	CleanupStack::PushL(publicModulus);
+	
+	// Decode public exponent
+	RInteger publicExponent = encInt.DecodeDERLongL(aDER, aPos);
+	CleanupStack::PushL(publicExponent);
+
+	//	Construct public key
+	CRSAPublicKey* publicKey = CRSAPublicKey::NewL(publicModulus, publicExponent);
+	CleanupStack::Pop(2, &publicModulus); // Now owned by publicKey
+	CleanupStack::PushL(publicKey);
+
+	// Decode private key components
+
+	// Copy modulus
+	RInteger privateModulus = RInteger::NewL(publicKey->N());
+	CleanupStack::PushL(privateModulus);					  
+	// Decode private exponent
+	RInteger privateExponent = encInt.DecodeDERLongL(aDER, aPos);
+	CleanupStack::PushL(privateExponent);
+	// Decode prime 1
+	RInteger p = encInt.DecodeDERLongL(aDER, aPos);
+	CleanupStack::PushL(p);
+	// Decode prime 2
+	RInteger q = encInt.DecodeDERLongL(aDER, aPos);
+	CleanupStack::PushL(q);
+	// Decode exponent 1
+	RInteger dmp1 = encInt.DecodeDERLongL(aDER, aPos);
+	CleanupStack::PushL(dmp1);
+	// Decode exponent 2
+	RInteger dmq1 = encInt.DecodeDERLongL(aDER, aPos);
+	CleanupStack::PushL(dmq1);
+	// Decode coefficient
+	RInteger the_iqmp = encInt.DecodeDERLongL(aDER, aPos);
+	CleanupStack::PushL(the_iqmp);
+
+	// We now should be at the end of the encoding. If not, the 
+	// input encoding contains extra fields, and they are not 
+	// supported.
+	if (aPos != end)
+		User::Leave(KErrArgument);
+	
+//	Construct private key
+	CRSAPrivateKey* privateKey = NULL;
+	if (EStandardCRT==aKeyType)
+	{
+		privateKey = CRSAPrivateKeyCRT::NewL(privateModulus, p, q, dmp1, dmq1, the_iqmp);
+	}
+	else if (EStandard==aKeyType)
+	{
+		privateKey = CRSAPrivateKeyStandard::NewL(privateModulus, privateExponent);
+	}
+	else
+		User::Leave(KErrNotSupported);
+	
+	CleanupStack::Pop(8,publicKey);	 // publicKey, privateModulus, privateExponent,
+	                                 // p, q, dmp1, dmq1, iqmp
+	
+//	Cleanup the TIntegers not owned by private key objects
+	if (EStandard==aKeyType)
+	{
+		p.Close();
+		q.Close();
+		dmp1.Close();
+		dmq1.Close();
+		the_iqmp.Close();
+	}
+	else
+	{
+		privateExponent.Close();
+	}
+
+	aPublicKey = publicKey;
+	aPrivateKey = privateKey;	
+}
+
+// TX509RSAKeyEncoder Class Implementation
+
+EXPORT_C TX509RSAKeyEncoder::TX509RSAKeyEncoder(const CRSAPublicKey& aPublicKey, TAlgorithmId aDigestAlg)
+	: TX509KeyEncoder(aDigestAlg),
+	  iPublicKey(aPublicKey)
+	{
+	}
+
+EXPORT_C CASN1EncBase* TX509RSAKeyEncoder::EncodeKeyLC() const
+	{
+	// Create higher-level sequence that will contain OID and the public key
+	CASN1EncSequence* subjectPubKeyInfo = CASN1EncSequence::NewLC();
+
+	// The next-level sequence will contain OID of the algorithm followed by NULL
+	CASN1EncSequence* seq = CASN1EncSequence::NewLC();
+	CASN1EncObjectIdentifier* oid = CASN1EncObjectIdentifier::NewLC(KRSA);
+	seq->AddAndPopChildL(oid);
+	CASN1EncNull* null = CASN1EncNull::NewLC();
+	seq->AddAndPopChildL(null);
+	subjectPubKeyInfo->AddAndPopChildL(seq);
+	
+	// Add the key itself to the higher-level sequence as a bit string
+	// Obtain a copy of the entity's public key
+	TASN1EncRSAPublicKey keyencoder;
+	HBufC8* encoding = keyencoder.EncodeDERL(iPublicKey);
+	CleanupStack::PushL(encoding);
+	CASN1EncBitString* pubkeyenc = CASN1EncBitString::NewLC(*encoding);
+	subjectPubKeyInfo->AddAndPopChildL(pubkeyenc);
+	CleanupStack::PopAndDestroy(encoding);
+	return subjectPubKeyInfo;
+	}
+
+// Returns ASN.1 sequence containing encoded signature algorithm.
+EXPORT_C CASN1EncSequence* TX509RSAKeyEncoder::EncodeSignatureAlgorithmLC() const
+	{
+	CASN1EncSequence* seq = CASN1EncSequence::NewLC();
+	CASN1EncObjectIdentifier* oid = NULL;
+
+	// Determine OID string for the current combination of algorithms.
+	switch(iDigestAlg)
+		{
+		default:
+			User::Leave(KErrNotSupported);
+			break;
+
+		case EMD2:
+			oid = CASN1EncObjectIdentifier::NewLC(KMD2WithRSA);
+			break;
+
+		case EMD5:
+			oid = CASN1EncObjectIdentifier::NewLC(KMD5WithRSA);
+			break;
+
+		case ESHA1:
+			oid = CASN1EncObjectIdentifier::NewLC(KSHA1WithRSA);
+			break;
+		}
+
+	// Add algorithm OID to the sequence.
+	seq->AddAndPopChildL(oid);
+	// Add NULL after OID.
+	CASN1EncNull* null = CASN1EncNull::NewLC();
+	seq->AddAndPopChildL(null);
+	
+	return seq;
+	}