cryptoservices/certificateandkeymgmt/pkcs10/pkcs10.cpp
changeset 8 35751d3474b7
parent 0 2c201484c85f
--- a/cryptoservices/certificateandkeymgmt/pkcs10/pkcs10.cpp	Tue Jul 21 01:04:32 2009 +0100
+++ b/cryptoservices/certificateandkeymgmt/pkcs10/pkcs10.cpp	Thu Sep 10 14:01:51 2009 +0300
@@ -1,354 +1,356 @@
-/*
-* Copyright (c) 2002-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: 
-* Implements PKCS#10 certificate request class.
-*
-*/
-
-
-#include <pkcs10.h>
-#include <asn1enc.h>
-#include <e32std.h>
-#include <e32def.h>
-#include <x500dn.h>
-#include <x509keys.h>
-#include <hash.h>
-#include <pkcs10attr.h>
-#include "keyhelper.h"
-
-void Panic(TInt aError)
-	{
-	_LIT(KCategory, "PKCS10");
-	User::Panic(KCategory, aError);
-	}
-
-// CPKCS10Request Class Implementation
-
-CPKCS10Request::CPKCS10Request(const CX500DistinguishedName* aDN,
-							   const CCTKeyInfo* aKeyInfo,
-							   CPKCS10Attributes* aAttr) :
-	CActive(EPriorityNormal),
-	iDN(aDN),
-	iKeyInfo(aKeyInfo),
-	iAttributes(aAttr),
-	iDigestId(ESHA1)
-	{
-	CActiveScheduler::Add(this);
-	}
-
-EXPORT_C CPKCS10Request* CPKCS10Request::NewLC(const CX500DistinguishedName& aDN,
-											   const CCTKeyInfo& aKeyInfo,
-											   CPKCS10Attributes* aAttr/* = NULL*/)
-	{
-	// Sanity Check the input parameters
-	if (&aDN == NULL)
-		{
-		User::Leave(KErrArgument);
-		}
-
-	if (&aKeyInfo == NULL)
-		{
-		User::Leave(KErrArgument);
-		}
-
-	CPKCS10Request* self = new (ELeave) CPKCS10Request(&aDN, &aKeyInfo, aAttr);
-	CleanupStack::PushL(self);
-	return self;
-	}
-
-EXPORT_C CPKCS10Request* CPKCS10Request::NewL(const CX500DistinguishedName& aDN,
-											  const CCTKeyInfo& aKeyInfo,
-											  CPKCS10Attributes* aAttr/* = NULL*/)
-	{
-	CPKCS10Request* self = NewLC(aDN, aKeyInfo, aAttr);
-	CleanupStack::Pop(self);
-	return self;
-	}
-
-EXPORT_C CPKCS10Request::~CPKCS10Request()
-	{
-	Cancel();
-	delete iAttributes;
-	Reset();
-	}
-
-void CPKCS10Request::Reset()
-	{
-	delete iExportedKey;
-	iExportedKey = NULL;
-	delete iTBSData;
-	iTBSData = NULL;
-	delete iKeyHelper;
-	iKeyHelper = NULL;
-	if (iKeyStore)
-		{
-		iKeyStore->Release();
-		iKeyStore = NULL;
-		}
-	iState = EIdle;
-	}
-
-EXPORT_C void CPKCS10Request::SetDistinguishedNameL(const CX500DistinguishedName& aDN)
-	{
-	// Sanity check
-	if (&aDN == NULL)
-		{
-		User::Leave(KErrArgument);
-		}
-	iDN = &aDN;
-	}
-
-EXPORT_C void CPKCS10Request::SetKeyInfoL(const CCTKeyInfo& aKeyInfo)
-	{
-	// Sanity check
-	if (&aKeyInfo == NULL)
-		{
-		User::Leave(KErrArgument);
-		}
-	iKeyInfo = &aKeyInfo;
-	}
-
-EXPORT_C void CPKCS10Request::SetAttributes(CPKCS10Attributes* aAttr)
-	{
-	delete iAttributes;
-	iAttributes = aAttr;
-	}
-
-EXPORT_C void CPKCS10Request::SetDigestAlgL(TAlgorithmId aDigestId)
-	{
-	if (aDigestId != EMD2 && aDigestId != EMD5 && aDigestId != ESHA1)
-		{
-		User::Leave(KErrArgument);
-		}
-	if (iKeyInfo->Algorithm() == CCTKeyInfo::EDSA && aDigestId != ESHA1)
-		{
-		User::Leave(KErrArgument);
-		}
-	iDigestId = aDigestId;
-	}
-
-EXPORT_C void CPKCS10Request::CreateEncoding(HBufC8*& aResult, TRequestStatus& aStatus)
-	{
-	ASSERT(iState == EIdle);	
-	iClientStatus = &aStatus;
-	iResult = &aResult;
-	aResult = NULL;	
-	aStatus = KRequestPending;
-	iState = EInitialize;
-	SetActive();
-	TRequestStatus* status = &iStatus;
-	User::RequestComplete(status, KErrNone);
-	}
-
-TInt CPKCS10Request::RunError(TInt aErr)
-	{
-    User::RequestComplete(iClientStatus, aErr);
-	iState = EIdle;
-    return KErrNone;
-	}
-
-void CPKCS10Request::DoCancel()
-	{
-	switch (iState)
-		{
-		case EGetKeyStore:
-			iKeyInfo->Token().CancelGetInterface();
-			break;
-
-		case EGetPublicKey:
-			iKeyStore->CancelExportPublic();
-			break;
-
-		case EOpenSigner:
-			iKeyHelper->CancelOpenSigner();
-			break;
-
-		case ESign:
-			iKeyHelper->CancelSignDigest();
-			break;
-
-		default:
-			// do nothing, keep compiler happy
-			break;			
-		}
-	
-	if (iClientStatus)
-		User::RequestComplete(iClientStatus, KErrCancel);
-
-	iState = EIdle;
-	}	
-
-void CPKCS10Request::RunL()
-	{
-	User::LeaveIfError(iStatus.Int());
-
-	switch (iState)
-		{
-		case EInitialize:
-			// Get keystore interface
-			if (iKeyStore)
-				{
-				iKeyStore->Release();
-				iKeyStore = NULL;
-				}
-			iKeyInfo->Token().GetInterface(TUid::Uid(KInterfaceKeyStore),
-										  *reinterpret_cast<MCTTokenInterface**>(&iKeyStore),
-										  iStatus);
-			iState = EGetKeyStore;
-			SetActive();
-			break;
-
-		case EGetKeyStore:
-			// Fetch the public key
-			delete iExportedKey;
-			iKeyStore->ExportPublic(*iKeyInfo, iExportedKey, iStatus);
-			iState = EGetPublicKey;
-			SetActive();
-			break;
-
-		case EGetPublicKey:
-			// Create key helper object
-			delete iKeyHelper;
-			iKeyHelper = CPKCS10KeyHelper::CreateKeyHelperL(*iKeyStore, *iKeyInfo, *iExportedKey, iDigestId);
-			EncodeTBSDataL();
-
-			// Open signing object
-			iKeyHelper->OpenSigner(iStatus);
-			iState = EOpenSigner;
-			SetActive();
-			break;
-
-		case EOpenSigner:
-			// Create digest
-			{
-			CMessageDigest* digest = NULL;
-			switch (iDigestId)
-				{
-				case EMD2:
-					digest = CMD2::NewL();
-					break;
-				case EMD5:
-					digest = CMD5::NewL();
-					break;
-				case ESHA1:
-					digest = CSHA1::NewL();
-					break;
-				default:
-					User::Invariant();
-				}
-			CleanupStack::PushL(digest);
-
-			// Hash data and sign
-			digest->Update(*iTBSData);
-			
-			iKeyHelper->SignDigestL(digest->Final(), iStatus);
-			CleanupStack::PopAndDestroy(digest); // keystore copies data to be signed
-			iState = ESign;
-			SetActive();
-			}
-			break;
-
-		case ESign:
-			CreateFinalEncodingL();
-			Reset();
-			break;
-		
-		default:
-			User::Invariant();
-		}
-	}
-
-CASN1EncBase* CPKCS10Request::MakeAttrEncLC() 
-	{
-	if (iAttributes)
-		{
-		CASN1EncBase* result = iAttributes->TakeEncodingLC();
-		delete iAttributes;
-		iAttributes = NULL;
-		return result;
-		}
-	else
-		{
-		CASN1EncSequence* contextSpecific = CASN1EncSequence::NewLC();
-		contextSpecific->SetTag(0);
-		return contextSpecific;
-		}
-	}
-
-CASN1EncSequence* CPKCS10Request::MakeCertRequestInfoEncLC()
-	{
-	// Top-level sequence contains distinguished name and other 
-	// stuff. This is what gets signed with the entity's private key.
-	CASN1EncSequence* certRequestInfo = CASN1EncSequence::NewLC();
-
-	// Encode version number, which is 0.
-	CASN1EncInt* version = CASN1EncInt::NewLC(0);
-	certRequestInfo->AddAndPopChildL(version);
-
-	// Encode distinguished name.
-	CASN1EncBase* distinguishedName = iDN->EncodeASN1LC();
-	certRequestInfo->AddAndPopChildL(distinguishedName);
-
-	// Encode SubjectPublicKeyInfo.
-	CASN1EncBase* subjectPubKeyInfo = iKeyHelper->EncodeKeyLC();
-	certRequestInfo->AddAndPopChildL(subjectPubKeyInfo);
-
-	// Encode attributes, if any.
-	CASN1EncBase* attr = MakeAttrEncLC();
-	certRequestInfo->AddAndPopChildL(attr);
-
-	return certRequestInfo;
-	}
-
-void CPKCS10Request::EncodeTBSDataL() 
-	{
-	// The data we provide for signing is the certRequestInfo object.
-	CASN1EncBase* certRequestInfo = MakeCertRequestInfoEncLC();
-	// Write DER of it to the buffer.
-	delete iTBSData;
-	iTBSData = HBufC8::NewMaxL(certRequestInfo->LengthDER());
-	TPtr8 dataPtr = iTBSData->Des();
-	TUint pos = 0;
-	certRequestInfo->WriteDERL(dataPtr, pos);
-	CleanupStack::PopAndDestroy(certRequestInfo);
-	}
-
-void CPKCS10Request::CreateFinalEncodingL()
-	{
-	// the root sequence contains all other components of a X509 signed object
-	CASN1EncSequence* root = CASN1EncSequence::NewLC();
-
-	// wrap data to be signed in a sequence and add it to the root
-	CASN1EncEncoding* encenc = CASN1EncEncoding::NewLC(*iTBSData);
-	root->AddAndPopChildL(encenc);
-
-	// encode signature algorithm and  parameters and add them to the root
-	CASN1EncSequence* sigalg = iKeyHelper->EncodeSignatureAlgorithmLC();
-	root->AddAndPopChildL(sigalg);
-
-	// Create ASN.1 bit string from the signature 
-	CASN1EncBitString* encSig = iKeyHelper->EncodeSignatureLC();
-	root->AddAndPopChildL(encSig);
-
-	// encode the object in a DER encoding
-	HBufC8* der = HBufC8::NewMaxLC(root->LengthDER());
-	TPtr8 pder(der->Des());
-	TUint pos = 0;
-	root->WriteDERL(pder, pos);
-	CleanupStack::Pop(der);
-	CleanupStack::PopAndDestroy(root);
-
-	*iResult = der;
-	User::RequestComplete(iClientStatus, KErrNone);
-	}
+/*
+* Copyright (c) 2002-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: 
+* Implements PKCS#10 certificate request class.
+*
+*/
+
+
+#include <pkcs10.h>
+#include <asn1enc.h>
+#include <e32std.h>
+#include <e32def.h>
+#include <x500dn.h>
+#include <x509keys.h>
+#include <hash.h>
+#include <pkcs10attr.h>
+#include "keyhelper.h"
+#include <mctkeystoreuids.h>
+
+void Panic(TInt aError)
+	{
+	_LIT(KCategory, "PKCS10");
+	User::Panic(KCategory, aError);
+	}
+
+// CPKCS10Request Class Implementation
+
+CPKCS10Request::CPKCS10Request(const CX500DistinguishedName* aDN,
+							   const CCTKeyInfo* aKeyInfo,
+							   CPKCS10Attributes* aAttr) :
+	CActive(EPriorityNormal),
+	iDN(aDN),
+	iKeyInfo(aKeyInfo),
+	iAttributes(aAttr),
+	iDigestId(ESHA1)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+EXPORT_C CPKCS10Request* CPKCS10Request::NewLC(const CX500DistinguishedName& aDN,
+											   const CCTKeyInfo& aKeyInfo,
+											   CPKCS10Attributes* aAttr/* = NULL*/)
+	{
+	// Sanity Check the input parameters
+	if (&aDN == NULL)
+		{
+		User::Leave(KErrArgument);
+		}
+
+	if (&aKeyInfo == NULL)
+		{
+		User::Leave(KErrArgument);
+		}
+
+	CPKCS10Request* self = new (ELeave) CPKCS10Request(&aDN, &aKeyInfo, aAttr);
+	CleanupStack::PushL(self);
+	return self;
+	}
+
+EXPORT_C CPKCS10Request* CPKCS10Request::NewL(const CX500DistinguishedName& aDN,
+											  const CCTKeyInfo& aKeyInfo,
+											  CPKCS10Attributes* aAttr/* = NULL*/)
+	{
+	CPKCS10Request* self = NewLC(aDN, aKeyInfo, aAttr);
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+EXPORT_C CPKCS10Request::~CPKCS10Request()
+	{
+	Cancel();
+	delete iAttributes;
+	Reset();
+	}
+
+void CPKCS10Request::Reset()
+	{
+	delete iExportedKey;
+	iExportedKey = NULL;
+	delete iTBSData;
+	iTBSData = NULL;
+	delete iKeyHelper;
+	iKeyHelper = NULL;
+	if (iKeyStore)
+		{
+		iKeyStore->Release();
+		iKeyStore = NULL;
+		}
+	iState = EIdle;
+	}
+
+EXPORT_C void CPKCS10Request::SetDistinguishedNameL(const CX500DistinguishedName& aDN)
+	{
+	// Sanity check
+	if (&aDN == NULL)
+		{
+		User::Leave(KErrArgument);
+		}
+	iDN = &aDN;
+	}
+
+EXPORT_C void CPKCS10Request::SetKeyInfoL(const CCTKeyInfo& aKeyInfo)
+	{
+	// Sanity check
+	if (&aKeyInfo == NULL)
+		{
+		User::Leave(KErrArgument);
+		}
+	iKeyInfo = &aKeyInfo;
+	}
+
+EXPORT_C void CPKCS10Request::SetAttributes(CPKCS10Attributes* aAttr)
+	{
+	delete iAttributes;
+	iAttributes = aAttr;
+	}
+
+EXPORT_C void CPKCS10Request::SetDigestAlgL(TAlgorithmId aDigestId)
+	{
+	if (aDigestId != EMD2 && aDigestId != EMD5 && aDigestId != ESHA1)
+		{
+		User::Leave(KErrArgument);
+		}
+	if (iKeyInfo->Algorithm() == CCTKeyInfo::EDSA && aDigestId != ESHA1)
+		{
+		User::Leave(KErrArgument);
+		}
+	iDigestId = aDigestId;
+	}
+
+EXPORT_C void CPKCS10Request::CreateEncoding(HBufC8*& aResult, TRequestStatus& aStatus)
+	{
+	ASSERT(iState == EIdle);	
+	iClientStatus = &aStatus;
+	iResult = &aResult;
+	aResult = NULL;	
+	aStatus = KRequestPending;
+	iState = EInitialize;
+	SetActive();
+	TRequestStatus* status = &iStatus;
+	User::RequestComplete(status, KErrNone);
+	}
+
+TInt CPKCS10Request::RunError(TInt aErr)
+	{
+    User::RequestComplete(iClientStatus, aErr);
+	iState = EIdle;
+    return KErrNone;
+	}
+
+void CPKCS10Request::DoCancel()
+	{
+	switch (iState)
+		{
+		case EGetKeyStore:
+			iKeyInfo->Token().CancelGetInterface();
+			break;
+
+		case EGetPublicKey:
+			iKeyStore->CancelExportPublic();
+			break;
+
+		case EOpenSigner:
+			iKeyHelper->CancelOpenSigner();
+			break;
+
+		case ESign:
+			iKeyHelper->CancelSignDigest();
+			break;
+
+		default:
+			// do nothing, keep compiler happy
+			break;			
+		}
+	
+	if (iClientStatus)
+		User::RequestComplete(iClientStatus, KErrCancel);
+
+	iState = EIdle;
+	}	
+
+void CPKCS10Request::RunL()
+	{
+	User::LeaveIfError(iStatus.Int());
+
+	switch (iState)
+		{
+		case EInitialize:
+			// Get keystore interface
+			if (iKeyStore)
+				{
+				iKeyStore->Release();
+				iKeyStore = NULL;
+				}
+			iKeyInfo->Token().GetInterface(TUid::Uid(KInterfaceKeyStore),
+										  *reinterpret_cast<MCTTokenInterface**>(&iKeyStore),
+										  iStatus);
+			iState = EGetKeyStore;
+			SetActive();
+			break;
+
+		case EGetKeyStore:
+			// Fetch the public key
+			delete iExportedKey;
+			iKeyStore->ExportPublic(*iKeyInfo, iExportedKey, iStatus);
+			iState = EGetPublicKey;
+			SetActive();
+			break;
+
+		case EGetPublicKey:
+			// Create key helper object
+			delete iKeyHelper;
+			iKeyHelper = CPKCS10KeyHelper::CreateKeyHelperL(*iKeyStore, *iKeyInfo, *iExportedKey, iDigestId);
+			EncodeTBSDataL();
+
+			// Open signing object
+			iKeyHelper->OpenSigner(iStatus);
+			iState = EOpenSigner;
+			SetActive();
+			break;
+
+		case EOpenSigner:
+			// Create digest
+			{
+			CMessageDigest* digest = NULL;
+			switch (iDigestId)
+				{
+				case EMD2:
+					digest = CMD2::NewL();
+					break;
+				case EMD5:
+					digest = CMD5::NewL();
+					break;
+				case ESHA1:
+					digest = CSHA1::NewL();
+					break;
+				default:
+					User::Invariant();
+				}
+			CleanupStack::PushL(digest);
+
+			// Hash data and sign
+			digest->Update(*iTBSData);
+			
+			iKeyHelper->SignDigestL(digest->Final(), iStatus);
+			CleanupStack::PopAndDestroy(digest); // keystore copies data to be signed
+			iState = ESign;
+			SetActive();
+			}
+			break;
+
+		case ESign:
+			CreateFinalEncodingL();
+			Reset();
+			break;
+		
+		default:
+			User::Invariant();
+		}
+	}
+
+CASN1EncBase* CPKCS10Request::MakeAttrEncLC() 
+	{
+	if (iAttributes)
+		{
+		CASN1EncBase* result = iAttributes->TakeEncodingLC();
+		delete iAttributes;
+		iAttributes = NULL;
+		return result;
+		}
+	else
+		{
+		CASN1EncSequence* contextSpecific = CASN1EncSequence::NewLC();
+		contextSpecific->SetTag(0);
+		return contextSpecific;
+		}
+	}
+
+CASN1EncSequence* CPKCS10Request::MakeCertRequestInfoEncLC()
+	{
+	// Top-level sequence contains distinguished name and other 
+	// stuff. This is what gets signed with the entity's private key.
+	CASN1EncSequence* certRequestInfo = CASN1EncSequence::NewLC();
+
+	// Encode version number, which is 0.
+	CASN1EncInt* version = CASN1EncInt::NewLC(0);
+	certRequestInfo->AddAndPopChildL(version);
+
+	// Encode distinguished name.
+	CASN1EncBase* distinguishedName = iDN->EncodeASN1LC();
+	certRequestInfo->AddAndPopChildL(distinguishedName);
+
+	// Encode SubjectPublicKeyInfo.
+	CASN1EncBase* subjectPubKeyInfo = iKeyHelper->EncodeKeyLC();
+	certRequestInfo->AddAndPopChildL(subjectPubKeyInfo);
+
+	// Encode attributes, if any.
+	CASN1EncBase* attr = MakeAttrEncLC();
+	certRequestInfo->AddAndPopChildL(attr);
+
+	return certRequestInfo;
+	}
+
+void CPKCS10Request::EncodeTBSDataL() 
+	{
+	// The data we provide for signing is the certRequestInfo object.
+	CASN1EncBase* certRequestInfo = MakeCertRequestInfoEncLC();
+	// Write DER of it to the buffer.
+	delete iTBSData;
+	iTBSData = HBufC8::NewMaxL(certRequestInfo->LengthDER());
+	TPtr8 dataPtr = iTBSData->Des();
+	TUint pos = 0;
+	certRequestInfo->WriteDERL(dataPtr, pos);
+	CleanupStack::PopAndDestroy(certRequestInfo);
+	}
+
+void CPKCS10Request::CreateFinalEncodingL()
+	{
+	// the root sequence contains all other components of a X509 signed object
+	CASN1EncSequence* root = CASN1EncSequence::NewLC();
+
+	// wrap data to be signed in a sequence and add it to the root
+	CASN1EncEncoding* encenc = CASN1EncEncoding::NewLC(*iTBSData);
+	root->AddAndPopChildL(encenc);
+
+	// encode signature algorithm and  parameters and add them to the root
+	CASN1EncSequence* sigalg = iKeyHelper->EncodeSignatureAlgorithmLC();
+	root->AddAndPopChildL(sigalg);
+
+	// Create ASN.1 bit string from the signature 
+	CASN1EncBitString* encSig = iKeyHelper->EncodeSignatureLC();
+	root->AddAndPopChildL(encSig);
+
+	// encode the object in a DER encoding
+	HBufC8* der = HBufC8::NewMaxLC(root->LengthDER());
+	TPtr8 pder(der->Des());
+	TUint pos = 0;
+	root->WriteDERL(pder, pos);
+	CleanupStack::Pop(der);
+	CleanupStack::PopAndDestroy(root);
+
+	*iResult = der;
+	User::RequestComplete(iClientStatus, KErrNone);
+	}
+