os/security/cryptoservices/certificateandkeymgmt/pkcs10/keyhelper.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200 (2012-06-15)
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 /*
     2 * Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
     3 * All rights reserved.
     4 * This component and the accompanying materials are made available
     5 * under the terms of the License "Eclipse Public License v1.0"
     6 * which accompanies this distribution, and is available
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
     8 *
     9 * Initial Contributors:
    10 * Nokia Corporation - initial contribution.
    11 *
    12 * Contributors:
    13 *
    14 * Description: 
    15 *
    16 */
    17 
    18 
    19 #include "keyhelper.h"
    20 #include <asn1enc.h>
    21 #include <asymmetric.h>
    22 #include <x509cert.h>
    23 
    24 // CPKCS10KeyHelper ////////////////////////////////////////////////////////////
    25 
    26 CPKCS10KeyHelper* CPKCS10KeyHelper::CreateKeyHelperL(MCTKeyStore& aKeyStore,
    27 													 const CCTKeyInfo& aKeyInfo,
    28 													 const TDesC8& aExportedKey,
    29 													 const TAlgorithmId aDigestId)
    30 	{
    31 	CPKCS10KeyHelper* result = NULL;
    32 	
    33 	switch (aKeyInfo.Algorithm())
    34 		{
    35 		case CCTKeyInfo::ERSA:
    36 			result = new (ELeave) CPKCS10RSAKeyHelper(aKeyStore, aKeyInfo);
    37 			break;
    38 
    39 		case CCTKeyInfo::EDSA:
    40 			result = new (ELeave) CPKCS10DSAKeyHelper(aKeyStore, aKeyInfo);
    41 			break;
    42 
    43 		default:
    44 			User::Leave(KErrArgument);
    45 		}
    46 
    47 	CleanupStack::PushL(result);
    48 	result->CreateKeyEncoderL(aExportedKey, aDigestId);
    49 	CleanupStack::Pop(result);
    50 
    51 	return result;
    52 	}
    53 
    54 CPKCS10KeyHelper::CPKCS10KeyHelper(MCTKeyStore& aKeyStore, const CCTKeyInfo& aKeyInfo) :
    55 	iKeyStore(aKeyStore),
    56 	iKeyInfo(aKeyInfo)
    57 	{
    58 	}
    59 
    60 CPKCS10KeyHelper::~CPKCS10KeyHelper()
    61 	{
    62 	delete iKeyEncoder;
    63 	}
    64 
    65 CASN1EncBase* CPKCS10KeyHelper::EncodeKeyLC()
    66 	{
    67 	return iKeyEncoder->EncodeKeyLC();
    68 	}
    69 
    70 CASN1EncBase* CPKCS10KeyHelper::DigestInfoLC(const TDesC8& digest)
    71 	{
    72 	CASN1EncSequence* seq = CASN1EncSequence::NewLC();
    73 	
    74 	// DigestAlgorithmIdentifier
    75 	CASN1EncSequence* digestAlgID =iKeyEncoder-> EncodeDigestAlgorithmLC();
    76 
    77 	seq->AddAndPopChildL(digestAlgID); 
    78 	
    79 	// Actual message digest	
    80 	CASN1EncOctetString* octet = CASN1EncOctetString::NewLC(digest);
    81 	seq->AddAndPopChildL(octet);
    82 	
    83 	return seq;
    84 	}
    85 
    86 
    87 CASN1EncSequence* CPKCS10KeyHelper::EncodeSignatureAlgorithmLC()
    88 	{
    89 	return iKeyEncoder->EncodeSignatureAlgorithmLC();
    90 	}
    91 
    92 // CPKCS10RSAKeyHelper /////////////////////////////////////////////////////////
    93 
    94 CPKCS10RSAKeyHelper::CPKCS10RSAKeyHelper(MCTKeyStore& aKeyStore, const CCTKeyInfo& aKeyInfo) :
    95 	CPKCS10KeyHelper(aKeyStore, aKeyInfo)
    96 	{
    97 	}
    98 
    99 CPKCS10RSAKeyHelper::~CPKCS10RSAKeyHelper()
   100 	{
   101 	if (iRSASigner)
   102 		{
   103 		iRSASigner->Release();		
   104 		}
   105 	if (iDigestBuf) 
   106 		{
   107 		delete iDigestBuf;
   108 		}
   109 	delete iRSASignature;
   110 	delete iPublicKey;	
   111 	}
   112 
   113 void CPKCS10RSAKeyHelper::OpenSigner(TRequestStatus& aStatus)
   114 	{
   115 	iKeyStore.Open(iKeyInfo, iRSASigner, aStatus);
   116 	}
   117 
   118 void CPKCS10RSAKeyHelper::CancelOpenSigner()
   119 	{
   120 	iKeyStore.CancelOpen();
   121 	}
   122 
   123 void CPKCS10RSAKeyHelper::SignDigestL(const TDesC8& aDigest, TRequestStatus& aStatus)
   124 	{
   125 	CASN1EncBase* digestInfo = DigestInfoLC(aDigest);
   126 	
   127 	// DER encode it!
   128 	iDigestBuf = HBufC8::NewMaxL(digestInfo->LengthDER());
   129 	TPtr8 oct(iDigestBuf->Des());
   130 	oct.FillZ();
   131 
   132 	TUint writePos = 0;
   133 	digestInfo->WriteDERL(oct, writePos);
   134 	
   135 	// Sign the DER encoded digest info
   136 	iRSASigner->Sign(*iDigestBuf, iRSASignature, aStatus);
   137 
   138 	//CleanupStack::PopAndDestroy(octetData);	
   139 	CleanupStack::PopAndDestroy(digestInfo);		
   140 	}
   141 
   142 void CPKCS10RSAKeyHelper::CancelSignDigest()
   143 	{
   144 	iRSASigner->CancelSign();
   145 	}
   146 
   147 void CPKCS10RSAKeyHelper::CreateKeyEncoderL(const TDesC8& aExportedKey, TAlgorithmId aDigestId)
   148 	{
   149 	CX509SubjectPublicKeyInfo* ki = CX509SubjectPublicKeyInfo::NewLC(aExportedKey);
   150 	TX509KeyFactory factory; 
   151 	iPublicKey = factory.RSAPublicKeyL(ki->KeyData());
   152 	CleanupStack::PopAndDestroy(ki);
   153 	iKeyEncoder = new (ELeave) TX509RSAKeyEncoder(*iPublicKey, aDigestId);
   154 	}
   155 
   156 
   157 CASN1EncBitString* CPKCS10RSAKeyHelper::EncodeSignatureLC()
   158 	{
   159 	// Get raw signature data
   160 	HBufC8* sigData = iRSASignature->S().BufferLC();
   161 
   162 	// Create ASN.1 bit string from the signature and return it.
   163 	CASN1EncBitString* encSig = CASN1EncBitString::NewL(*sigData);
   164 	CleanupStack::PopAndDestroy(sigData);
   165 	CleanupStack::PushL(encSig);
   166 
   167 	return encSig;
   168 	}
   169 
   170 // CPKCS10DSAKeyHelper /////////////////////////////////////////////////////////
   171 
   172 CPKCS10DSAKeyHelper::CPKCS10DSAKeyHelper(MCTKeyStore& aKeyStore, const CCTKeyInfo& aKeyInfo) :
   173 	CPKCS10KeyHelper(aKeyStore, aKeyInfo)
   174 	{
   175 	}
   176 
   177 CPKCS10DSAKeyHelper::~CPKCS10DSAKeyHelper()
   178 	{
   179 	if (iDSASigner)
   180 		iDSASigner->Release();
   181 	delete iDSASignature;
   182 	delete iPublicKey;
   183 	}
   184 
   185 void CPKCS10DSAKeyHelper::OpenSigner(TRequestStatus& aStatus)
   186 	{
   187 	iKeyStore.Open(iKeyInfo, iDSASigner, aStatus);
   188 	}
   189 
   190 void CPKCS10DSAKeyHelper::CancelOpenSigner()
   191 	{
   192 	iKeyStore.CancelOpen();
   193 	}
   194 
   195 void CPKCS10DSAKeyHelper::SignDigestL(const TDesC8& aDigest, TRequestStatus& aStatus)
   196 	{
   197 	iDSASigner->Sign(aDigest, iDSASignature, aStatus);
   198 	}
   199 
   200 void CPKCS10DSAKeyHelper::CancelSignDigest()
   201 	{
   202 	iDSASigner->CancelSign();
   203 	}
   204 
   205 void CPKCS10DSAKeyHelper::CreateKeyEncoderL(const TDesC8& aExportedKey, TAlgorithmId aDigestId)
   206 	{
   207 	CX509SubjectPublicKeyInfo* ki = CX509SubjectPublicKeyInfo::NewLC(aExportedKey);
   208 	TX509KeyFactory factory; 
   209 	iPublicKey = factory.DSAPublicKeyL(ki->EncodedParams(), ki->KeyData());
   210 	CleanupStack::PopAndDestroy(ki);
   211 	iKeyEncoder = new (ELeave) TX509DSAKeyEncoder(*iPublicKey, aDigestId);
   212 	}
   213 
   214 /**
   215  * Override default implementation - leave DSA parameters out of the
   216  * AlgorithmIdentifier when it appears outside of SubjectPublicKeyInfo.  
   217  */
   218 CASN1EncSequence* CPKCS10DSAKeyHelper::EncodeSignatureAlgorithmLC()
   219 	{
   220 	CASN1EncSequence* seq = CASN1EncSequence::NewLC();
   221 	// Assume only SHA1 with DSA
   222 	CASN1EncObjectIdentifier* oid = CASN1EncObjectIdentifier::NewLC(KDSAWithSHA1);
   223 	seq->AddAndPopChildL(oid);
   224 
   225 	// Don't add parameters!
   226 
   227 	return seq;	
   228 	}
   229 
   230 CASN1EncBitString* CPKCS10DSAKeyHelper::EncodeSignatureLC()
   231 	{
   232 	// Create sequence that will hold the two bit integers.
   233 	CASN1EncSequence* sigSeq = CASN1EncSequence::NewLC();
   234 	// Stuff two signature integers into the sequence.
   235 
   236 	CASN1EncBigInt* r = CASN1EncBigInt::NewLC(iDSASignature->R());
   237 	sigSeq->AddAndPopChildL(r);
   238 	CASN1EncBigInt* s = CASN1EncBigInt::NewLC(iDSASignature->S());
   239 	sigSeq->AddAndPopChildL(s);
   240 
   241 	// Wrap the sequence into a bit string
   242 	// Create ASN.1 encoding from the signature and return it.
   243 	CASN1EncBitString* sigDer = CASN1EncBitString::NewL(*sigSeq);
   244 
   245 	CleanupStack::PopAndDestroy(sigSeq);
   246 	CleanupStack::PushL(sigDer);
   247 
   248 	return sigDer;
   249 	}
   250