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: