sl@0: /*
sl@0: * Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0: * All rights reserved.
sl@0: * This component and the accompanying materials are made available
sl@0: * under the terms of the License "Eclipse Public License v1.0"
sl@0: * which accompanies this distribution, and is available
sl@0: * at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0: *
sl@0: * Initial Contributors:
sl@0: * Nokia Corporation - initial contribution.
sl@0: *
sl@0: * Contributors:
sl@0: *
sl@0: * Description: 
sl@0: *
sl@0: */
sl@0: 
sl@0: 
sl@0: #include "keyhelper.h"
sl@0: #include <asn1enc.h>
sl@0: #include <asymmetric.h>
sl@0: #include <x509cert.h>
sl@0: 
sl@0: // CPKCS10KeyHelper ////////////////////////////////////////////////////////////
sl@0: 
sl@0: CPKCS10KeyHelper* CPKCS10KeyHelper::CreateKeyHelperL(MCTKeyStore& aKeyStore,
sl@0: 													 const CCTKeyInfo& aKeyInfo,
sl@0: 													 const TDesC8& aExportedKey,
sl@0: 													 const TAlgorithmId aDigestId)
sl@0: 	{
sl@0: 	CPKCS10KeyHelper* result = NULL;
sl@0: 	
sl@0: 	switch (aKeyInfo.Algorithm())
sl@0: 		{
sl@0: 		case CCTKeyInfo::ERSA:
sl@0: 			result = new (ELeave) CPKCS10RSAKeyHelper(aKeyStore, aKeyInfo);
sl@0: 			break;
sl@0: 
sl@0: 		case CCTKeyInfo::EDSA:
sl@0: 			result = new (ELeave) CPKCS10DSAKeyHelper(aKeyStore, aKeyInfo);
sl@0: 			break;
sl@0: 
sl@0: 		default:
sl@0: 			User::Leave(KErrArgument);
sl@0: 		}
sl@0: 
sl@0: 	CleanupStack::PushL(result);
sl@0: 	result->CreateKeyEncoderL(aExportedKey, aDigestId);
sl@0: 	CleanupStack::Pop(result);
sl@0: 
sl@0: 	return result;
sl@0: 	}
sl@0: 
sl@0: CPKCS10KeyHelper::CPKCS10KeyHelper(MCTKeyStore& aKeyStore, const CCTKeyInfo& aKeyInfo) :
sl@0: 	iKeyStore(aKeyStore),
sl@0: 	iKeyInfo(aKeyInfo)
sl@0: 	{
sl@0: 	}
sl@0: 
sl@0: CPKCS10KeyHelper::~CPKCS10KeyHelper()
sl@0: 	{
sl@0: 	delete iKeyEncoder;
sl@0: 	}
sl@0: 
sl@0: CASN1EncBase* CPKCS10KeyHelper::EncodeKeyLC()
sl@0: 	{
sl@0: 	return iKeyEncoder->EncodeKeyLC();
sl@0: 	}
sl@0: 
sl@0: CASN1EncBase* CPKCS10KeyHelper::DigestInfoLC(const TDesC8& digest)
sl@0: 	{
sl@0: 	CASN1EncSequence* seq = CASN1EncSequence::NewLC();
sl@0: 	
sl@0: 	// DigestAlgorithmIdentifier
sl@0: 	CASN1EncSequence* digestAlgID =iKeyEncoder-> EncodeDigestAlgorithmLC();
sl@0: 
sl@0: 	seq->AddAndPopChildL(digestAlgID); 
sl@0: 	
sl@0: 	// Actual message digest	
sl@0: 	CASN1EncOctetString* octet = CASN1EncOctetString::NewLC(digest);
sl@0: 	seq->AddAndPopChildL(octet);
sl@0: 	
sl@0: 	return seq;
sl@0: 	}
sl@0: 
sl@0: 
sl@0: CASN1EncSequence* CPKCS10KeyHelper::EncodeSignatureAlgorithmLC()
sl@0: 	{
sl@0: 	return iKeyEncoder->EncodeSignatureAlgorithmLC();
sl@0: 	}
sl@0: 
sl@0: // CPKCS10RSAKeyHelper /////////////////////////////////////////////////////////
sl@0: 
sl@0: CPKCS10RSAKeyHelper::CPKCS10RSAKeyHelper(MCTKeyStore& aKeyStore, const CCTKeyInfo& aKeyInfo) :
sl@0: 	CPKCS10KeyHelper(aKeyStore, aKeyInfo)
sl@0: 	{
sl@0: 	}
sl@0: 
sl@0: CPKCS10RSAKeyHelper::~CPKCS10RSAKeyHelper()
sl@0: 	{
sl@0: 	if (iRSASigner)
sl@0: 		{
sl@0: 		iRSASigner->Release();		
sl@0: 		}
sl@0: 	if (iDigestBuf) 
sl@0: 		{
sl@0: 		delete iDigestBuf;
sl@0: 		}
sl@0: 	delete iRSASignature;
sl@0: 	delete iPublicKey;	
sl@0: 	}
sl@0: 
sl@0: void CPKCS10RSAKeyHelper::OpenSigner(TRequestStatus& aStatus)
sl@0: 	{
sl@0: 	iKeyStore.Open(iKeyInfo, iRSASigner, aStatus);
sl@0: 	}
sl@0: 
sl@0: void CPKCS10RSAKeyHelper::CancelOpenSigner()
sl@0: 	{
sl@0: 	iKeyStore.CancelOpen();
sl@0: 	}
sl@0: 
sl@0: void CPKCS10RSAKeyHelper::SignDigestL(const TDesC8& aDigest, TRequestStatus& aStatus)
sl@0: 	{
sl@0: 	CASN1EncBase* digestInfo = DigestInfoLC(aDigest);
sl@0: 	
sl@0: 	// DER encode it!
sl@0: 	iDigestBuf = HBufC8::NewMaxL(digestInfo->LengthDER());
sl@0: 	TPtr8 oct(iDigestBuf->Des());
sl@0: 	oct.FillZ();
sl@0: 
sl@0: 	TUint writePos = 0;
sl@0: 	digestInfo->WriteDERL(oct, writePos);
sl@0: 	
sl@0: 	// Sign the DER encoded digest info
sl@0: 	iRSASigner->Sign(*iDigestBuf, iRSASignature, aStatus);
sl@0: 
sl@0: 	//CleanupStack::PopAndDestroy(octetData);	
sl@0: 	CleanupStack::PopAndDestroy(digestInfo);		
sl@0: 	}
sl@0: 
sl@0: void CPKCS10RSAKeyHelper::CancelSignDigest()
sl@0: 	{
sl@0: 	iRSASigner->CancelSign();
sl@0: 	}
sl@0: 
sl@0: void CPKCS10RSAKeyHelper::CreateKeyEncoderL(const TDesC8& aExportedKey, TAlgorithmId aDigestId)
sl@0: 	{
sl@0: 	CX509SubjectPublicKeyInfo* ki = CX509SubjectPublicKeyInfo::NewLC(aExportedKey);
sl@0: 	TX509KeyFactory factory; 
sl@0: 	iPublicKey = factory.RSAPublicKeyL(ki->KeyData());
sl@0: 	CleanupStack::PopAndDestroy(ki);
sl@0: 	iKeyEncoder = new (ELeave) TX509RSAKeyEncoder(*iPublicKey, aDigestId);
sl@0: 	}
sl@0: 
sl@0: 
sl@0: CASN1EncBitString* CPKCS10RSAKeyHelper::EncodeSignatureLC()
sl@0: 	{
sl@0: 	// Get raw signature data
sl@0: 	HBufC8* sigData = iRSASignature->S().BufferLC();
sl@0: 
sl@0: 	// Create ASN.1 bit string from the signature and return it.
sl@0: 	CASN1EncBitString* encSig = CASN1EncBitString::NewL(*sigData);
sl@0: 	CleanupStack::PopAndDestroy(sigData);
sl@0: 	CleanupStack::PushL(encSig);
sl@0: 
sl@0: 	return encSig;
sl@0: 	}
sl@0: 
sl@0: // CPKCS10DSAKeyHelper /////////////////////////////////////////////////////////
sl@0: 
sl@0: CPKCS10DSAKeyHelper::CPKCS10DSAKeyHelper(MCTKeyStore& aKeyStore, const CCTKeyInfo& aKeyInfo) :
sl@0: 	CPKCS10KeyHelper(aKeyStore, aKeyInfo)
sl@0: 	{
sl@0: 	}
sl@0: 
sl@0: CPKCS10DSAKeyHelper::~CPKCS10DSAKeyHelper()
sl@0: 	{
sl@0: 	if (iDSASigner)
sl@0: 		iDSASigner->Release();
sl@0: 	delete iDSASignature;
sl@0: 	delete iPublicKey;
sl@0: 	}
sl@0: 
sl@0: void CPKCS10DSAKeyHelper::OpenSigner(TRequestStatus& aStatus)
sl@0: 	{
sl@0: 	iKeyStore.Open(iKeyInfo, iDSASigner, aStatus);
sl@0: 	}
sl@0: 
sl@0: void CPKCS10DSAKeyHelper::CancelOpenSigner()
sl@0: 	{
sl@0: 	iKeyStore.CancelOpen();
sl@0: 	}
sl@0: 
sl@0: void CPKCS10DSAKeyHelper::SignDigestL(const TDesC8& aDigest, TRequestStatus& aStatus)
sl@0: 	{
sl@0: 	iDSASigner->Sign(aDigest, iDSASignature, aStatus);
sl@0: 	}
sl@0: 
sl@0: void CPKCS10DSAKeyHelper::CancelSignDigest()
sl@0: 	{
sl@0: 	iDSASigner->CancelSign();
sl@0: 	}
sl@0: 
sl@0: void CPKCS10DSAKeyHelper::CreateKeyEncoderL(const TDesC8& aExportedKey, TAlgorithmId aDigestId)
sl@0: 	{
sl@0: 	CX509SubjectPublicKeyInfo* ki = CX509SubjectPublicKeyInfo::NewLC(aExportedKey);
sl@0: 	TX509KeyFactory factory; 
sl@0: 	iPublicKey = factory.DSAPublicKeyL(ki->EncodedParams(), ki->KeyData());
sl@0: 	CleanupStack::PopAndDestroy(ki);
sl@0: 	iKeyEncoder = new (ELeave) TX509DSAKeyEncoder(*iPublicKey, aDigestId);
sl@0: 	}
sl@0: 
sl@0: /**
sl@0:  * Override default implementation - leave DSA parameters out of the
sl@0:  * AlgorithmIdentifier when it appears outside of SubjectPublicKeyInfo.  
sl@0:  */
sl@0: CASN1EncSequence* CPKCS10DSAKeyHelper::EncodeSignatureAlgorithmLC()
sl@0: 	{
sl@0: 	CASN1EncSequence* seq = CASN1EncSequence::NewLC();
sl@0: 	// Assume only SHA1 with DSA
sl@0: 	CASN1EncObjectIdentifier* oid = CASN1EncObjectIdentifier::NewLC(KDSAWithSHA1);
sl@0: 	seq->AddAndPopChildL(oid);
sl@0: 
sl@0: 	// Don't add parameters!
sl@0: 
sl@0: 	return seq;	
sl@0: 	}
sl@0: 
sl@0: CASN1EncBitString* CPKCS10DSAKeyHelper::EncodeSignatureLC()
sl@0: 	{
sl@0: 	// Create sequence that will hold the two bit integers.
sl@0: 	CASN1EncSequence* sigSeq = CASN1EncSequence::NewLC();
sl@0: 	// Stuff two signature integers into the sequence.
sl@0: 
sl@0: 	CASN1EncBigInt* r = CASN1EncBigInt::NewLC(iDSASignature->R());
sl@0: 	sigSeq->AddAndPopChildL(r);
sl@0: 	CASN1EncBigInt* s = CASN1EncBigInt::NewLC(iDSASignature->S());
sl@0: 	sigSeq->AddAndPopChildL(s);
sl@0: 
sl@0: 	// Wrap the sequence into a bit string
sl@0: 	// Create ASN.1 encoding from the signature and return it.
sl@0: 	CASN1EncBitString* sigDer = CASN1EncBitString::NewL(*sigSeq);
sl@0: 
sl@0: 	CleanupStack::PopAndDestroy(sigSeq);
sl@0: 	CleanupStack::PushL(sigDer);
sl@0: 
sl@0: 	return sigDer;
sl@0: 	}
sl@0: