os/security/cryptoservices/asnpkcs/source/asnpkcs8enc.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
/*
sl@0
     2
* Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     3
* All rights reserved.
sl@0
     4
* This component and the accompanying materials are made available
sl@0
     5
* under the terms of the License "Eclipse Public License v1.0"
sl@0
     6
* which accompanies this distribution, and is available
sl@0
     7
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     8
*
sl@0
     9
* Initial Contributors:
sl@0
    10
* Nokia Corporation - initial contribution.
sl@0
    11
*
sl@0
    12
* Contributors:
sl@0
    13
*
sl@0
    14
* Description: 
sl@0
    15
*
sl@0
    16
*/
sl@0
    17
sl@0
    18
sl@0
    19
#include <asn1enc.h>
sl@0
    20
#include <pbe.h>
sl@0
    21
#include <asymmetrickeys.h>
sl@0
    22
#include <bigint.h>
sl@0
    23
#include "asnpkcs.h"
sl@0
    24
sl@0
    25
const TInt KPkcs8Version = 0;      // PKCS#8 version 0 
sl@0
    26
const TInt KPkcs8RSATwoPrime = 0;  // We support only two-prime RSA. 
sl@0
    27
sl@0
    28
sl@0
    29
/*static*/ void TASN1EncPKCS8::AddAttributesL(CASN1EncSequence& aSeq, const TDesC8& aAttribute)
sl@0
    30
	{
sl@0
    31
	if (aAttribute != KNullDesC8)
sl@0
    32
		{
sl@0
    33
		CASN1EncEncoding* encoded = CASN1EncEncoding::NewLC(aAttribute);
sl@0
    34
		aSeq.AddAndPopChildL(encoded);		
sl@0
    35
		}
sl@0
    36
	}
sl@0
    37
sl@0
    38
/**
sl@0
    39
 * Given a ASN1 sequence representing a private key and a CPBEncryptor object,
sl@0
    40
 * it returns an ASN1 octet string containing the key sequence encrypted by
sl@0
    41
 * the given encryptor.
sl@0
    42
 *
sl@0
    43
 * @param aKeySeq The key sequence to be encrypted.
sl@0
    44
 * @param aEncryptor The CPBEncryptor object used to encrypt the given key.
sl@0
    45
 * @return An ASN1 octet string containing the encrypted key.
sl@0
    46
 */
sl@0
    47
/*static*/ CASN1EncOctetString* TASN1EncPKCS8::EncryptKeySequenceL(CASN1EncSequence& aKeySeq, CPBEncryptor& aEncryptor)
sl@0
    48
	{
sl@0
    49
	//	Make an octet string of the key sequence
sl@0
    50
	TUint seqLen = aKeySeq.LengthDER();
sl@0
    51
	HBufC8* octetData = HBufC8::NewMaxLC(seqLen);
sl@0
    52
	TPtr8 oct(octetData->Des());
sl@0
    53
	oct.FillZ();
sl@0
    54
	TUint writePos = 0;
sl@0
    55
	aKeySeq.WriteDERL(oct, writePos);
sl@0
    56
	
sl@0
    57
	// Encrypt it
sl@0
    58
        HBufC8* encryptedData = HBufC8::NewLC(aEncryptor.MaxFinalOutputLength(seqLen)); 
sl@0
    59
        TPtr8 encrypted(encryptedData->Des());  
sl@0
    60
sl@0
    61
	aEncryptor.ProcessFinalL(*octetData, encrypted);
sl@0
    62
		
sl@0
    63
	CASN1EncOctetString* octet = CASN1EncOctetString::NewL(encrypted);
sl@0
    64
	
sl@0
    65
	CleanupStack::PopAndDestroy(2, octetData); // encryptedData, octetData
sl@0
    66
	
sl@0
    67
	return octet;
sl@0
    68
	}
sl@0
    69
sl@0
    70
sl@0
    71
/*static*/ CASN1EncOctetString* TASN1EncPKCS8::ElementToOctetL(CASN1EncBase& aAsnElement)
sl@0
    72
	{
sl@0
    73
	//	Make an octet string from the structure
sl@0
    74
	HBufC8* octetData = HBufC8::NewMaxLC(aAsnElement.LengthDER());
sl@0
    75
	TPtr8 oct(octetData->Des());
sl@0
    76
	oct.FillZ();
sl@0
    77
sl@0
    78
	TUint writePos = 0;
sl@0
    79
	aAsnElement.WriteDERL(oct, writePos);
sl@0
    80
	
sl@0
    81
	CASN1EncOctetString* octet = CASN1EncOctetString::NewL(oct);
sl@0
    82
	CleanupStack::PopAndDestroy(octetData);
sl@0
    83
	return octet;
sl@0
    84
	}
sl@0
    85
sl@0
    86
sl@0
    87
/*static*/ CASN1EncSequence* TASN1EncPKCS8::EncryptedSequenceL(CASN1EncSequence& aPrivateKeySequence, 
sl@0
    88
                                                               CPBEncryptor& aEncryptor, CPBEncryptParms& aData)
sl@0
    89
	{
sl@0
    90
	// Main ASN1 sequence
sl@0
    91
	CASN1EncSequence* seq = CASN1EncSequence::NewLC();
sl@0
    92
	
sl@0
    93
	// PKCS#5 PBE sequence
sl@0
    94
	CASN1EncSequence* pkcs5Seq = TASN1EncPKCS5::EncodeDERL(aData);
sl@0
    95
	 
sl@0
    96
	CleanupStack::PushL(pkcs5Seq);
sl@0
    97
	seq->AddAndPopChildL(pkcs5Seq);
sl@0
    98
	
sl@0
    99
	// Encrypt the Private Key Sequence
sl@0
   100
	CASN1EncOctetString* octet = EncryptKeySequenceL(aPrivateKeySequence, aEncryptor);
sl@0
   101
	CleanupStack::PushL(octet);
sl@0
   102
	seq->AddAndPopChildL(octet);
sl@0
   103
sl@0
   104
	CleanupStack::Pop(seq);
sl@0
   105
sl@0
   106
	return seq;
sl@0
   107
	}
sl@0
   108
sl@0
   109
sl@0
   110
/*static*/ const RInteger TASN1EncPKCS8::CalculateRSAPrivExpL(const CRSAPrivateKeyCRT& aPrivateKey, const CRSAPublicKey& aPublicKey)
sl@0
   111
	{
sl@0
   112
	const TInteger& e = aPublicKey.E();
sl@0
   113
sl@0
   114
	RInteger pTemp = RInteger::NewL(aPrivateKey.P());
sl@0
   115
	CleanupStack::PushL(pTemp);
sl@0
   116
	RInteger qTemp = RInteger::NewL(aPrivateKey.Q());
sl@0
   117
	CleanupStack::PushL(qTemp);
sl@0
   118
	
sl@0
   119
  	--pTemp;
sl@0
   120
    	--qTemp;
sl@0
   121
 
sl@0
   122
	//phi = (p-1)(q-1)
sl@0
   123
	RInteger phi = pTemp.TimesL(qTemp);
sl@0
   124
sl@0
   125
	CleanupStack::PopAndDestroy(2, &pTemp);  // qTemp, pTemp
sl@0
   126
 	CleanupStack::PushL(phi);
sl@0
   127
    	
sl@0
   128
    	//d = e^(-1) mod ((p-1)(q-1))
sl@0
   129
   	 RInteger d = e.InverseModL(phi);
sl@0
   130
    	CleanupStack::PopAndDestroy(&phi); 
sl@0
   131
	return d;	
sl@0
   132
	}
sl@0
   133
sl@0
   134
/**
sl@0
   135
 * Encodes the given private key using the pkcs#8 standard.
sl@0
   136
 *
sl@0
   137
 * The returned ASN1 sequence respects the following grammar:
sl@0
   138
 * 
sl@0
   139
 *	PrivateKeyInfo ::= SEQUENCE {
sl@0
   140
 *	version Version,
sl@0
   141
 *	privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
sl@0
   142
 *	privateKey PrivateKey,
sl@0
   143
 *	attributes [0] IMPLICIT Attributes OPTIONAL }
sl@0
   144
 *	
sl@0
   145
 *	Version ::= INTEGER
sl@0
   146
 *	PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier
sl@0
   147
 *	PrivateKey ::= OCTET STRING
sl@0
   148
 *	Attributes ::= SET OF Attribute
sl@0
   149
 *
sl@0
   150
 *
sl@0
   151
 * @param aKeyPair A key pair containing the private key we wish to encode.
sl@0
   152
 * @return A CASN1EncSequence encoding the private key. The sequence
sl@0
   153
 *         follows the grammar specified above. 
sl@0
   154
 * @internalComponent
sl@0
   155
 * @released
sl@0
   156
 */
sl@0
   157
/*static*/ EXPORT_C CASN1EncSequence* TASN1EncPKCS8::EncodeL(const CRSAPrivateKeyCRT& aPrivateKey, 
sl@0
   158
														  const CRSAPublicKey& aPublicKey, 
sl@0
   159
														  const TDesC8& aAttributes)
sl@0
   160
	{
sl@0
   161
	// Main ASN1 sequence
sl@0
   162
	CASN1EncSequence* seq = CASN1EncSequence::NewLC();
sl@0
   163
sl@0
   164
	// Start with PKCS#8 header
sl@0
   165
	CASN1EncInt* version = CASN1EncInt::NewLC(KPkcs8Version); 
sl@0
   166
	seq->AddAndPopChildL(version);
sl@0
   167
	
sl@0
   168
	//	Algorithm sequence
sl@0
   169
	CASN1EncSequence* algSeq = CASN1EncSequence::NewLC();
sl@0
   170
sl@0
   171
	CASN1EncObjectIdentifier* oid = CASN1EncObjectIdentifier::NewLC(KRSA);
sl@0
   172
	algSeq->AddAndPopChildL(oid);
sl@0
   173
sl@0
   174
	//	No other parameters
sl@0
   175
	CASN1EncNull* nullparams = CASN1EncNull::NewLC();
sl@0
   176
	algSeq->AddAndPopChildL(nullparams);
sl@0
   177
sl@0
   178
	seq->AddAndPopChildL(algSeq);
sl@0
   179
	
sl@0
   180
	// The actual private key sequence		
sl@0
   181
	CASN1EncSequence* keySeq = CASN1EncSequence::NewLC();
sl@0
   182
sl@0
   183
	//	TASN1DecGeneric* versionData = theData->operator[](seqIndex);
sl@0
   184
	CASN1EncInt* rsaVersion = CASN1EncInt::NewLC(KPkcs8RSATwoPrime); 
sl@0
   185
	keySeq->AddAndPopChildL(rsaVersion);
sl@0
   186
	
sl@0
   187
	//	The modulus	
sl@0
   188
	const TInteger& modulus = aPrivateKey.N();
sl@0
   189
	CASN1EncBigInt* mod = CASN1EncBigInt::NewLC(modulus);
sl@0
   190
	keySeq->AddAndPopChildL(mod);
sl@0
   191
sl@0
   192
	//	The public exponent
sl@0
   193
	const TInteger& e = aPublicKey.E();
sl@0
   194
	CASN1EncBigInt* publicExp = CASN1EncBigInt::NewLC(e);
sl@0
   195
	keySeq->AddAndPopChildL(publicExp);
sl@0
   196
sl@0
   197
	// The private exponent
sl@0
   198
	RInteger d = CalculateRSAPrivExpL(aPrivateKey, aPublicKey);
sl@0
   199
	CleanupStack::PushL(d);
sl@0
   200
sl@0
   201
	CASN1EncBigInt* privateExp = CASN1EncBigInt::NewLC(d);
sl@0
   202
sl@0
   203
	keySeq->AddAndPopChildL(privateExp);
sl@0
   204
	CleanupStack::PopAndDestroy(&d);  // RSA Private Exponent 
sl@0
   205
sl@0
   206
	//	The prime1
sl@0
   207
	const TInteger& p = aPrivateKey.P();
sl@0
   208
	CASN1EncBigInt* prime1 = CASN1EncBigInt::NewLC(p);
sl@0
   209
	keySeq->AddAndPopChildL(prime1);
sl@0
   210
sl@0
   211
	//	The prime2
sl@0
   212
	const TInteger& q = aPrivateKey.Q();
sl@0
   213
	CASN1EncBigInt* prime2 = CASN1EncBigInt::NewLC(q);
sl@0
   214
	keySeq->AddAndPopChildL(prime2);
sl@0
   215
sl@0
   216
	//	The exponent 1	
sl@0
   217
	const TInteger& dp = aPrivateKey.DP();
sl@0
   218
	CASN1EncBigInt* theExp1 = CASN1EncBigInt::NewLC(dp);
sl@0
   219
	keySeq->AddAndPopChildL(theExp1);
sl@0
   220
sl@0
   221
	//	The exponent 2
sl@0
   222
	const TInteger& dq = aPrivateKey.DQ();
sl@0
   223
	CASN1EncBigInt* theExp2 = CASN1EncBigInt::NewLC(dq);
sl@0
   224
	keySeq->AddAndPopChildL(theExp2);
sl@0
   225
sl@0
   226
	//	The coefficient
sl@0
   227
	const TInteger& coeff = aPrivateKey.QInv();
sl@0
   228
	CASN1EncBigInt* coefficient = CASN1EncBigInt::NewLC(coeff);
sl@0
   229
	keySeq->AddAndPopChildL(coefficient);
sl@0
   230
	
sl@0
   231
	CASN1EncOctetString* octet = ElementToOctetL(*keySeq);
sl@0
   232
	CleanupStack::PushL(octet);
sl@0
   233
	
sl@0
   234
	//	Now add the octet of the key sequence to the sequence
sl@0
   235
	seq->AddAndPopChildL(octet);
sl@0
   236
	
sl@0
   237
  	CleanupStack::PopAndDestroy(keySeq);
sl@0
   238
sl@0
   239
	AddAttributesL(*seq, aAttributes);
sl@0
   240
sl@0
   241
  	CleanupStack::Pop(seq);
sl@0
   242
					
sl@0
   243
	return seq;
sl@0
   244
	}
sl@0
   245
sl@0
   246
/**
sl@0
   247
 * Encodes an RSA key in encrypted format.
sl@0
   248
 * 
sl@0
   249
 * @param aPrivateKey The private key to be encoded (must be in CRT format)
sl@0
   250
 * @param aPublicKey The corresponding public key.
sl@0
   251
 * @param aEncryptor The object used to encrypt the data.
sl@0
   252
 * @param aData The encryption parameters of the given encryptor.
sl@0
   253
 *              These parameters are stored in the resulting sequence.
sl@0
   254
 *
sl@0
   255
 * @return An ASN1 Sequence encoding the encrypted key.
sl@0
   256
 */
sl@0
   257
/*static*/ EXPORT_C CASN1EncSequence* TASN1EncPKCS8::EncodeEncryptedL(const CRSAPrivateKeyCRT& aPrivateKey, const CRSAPublicKey& aPublicKey, 
sl@0
   258
                                                                      CPBEncryptor& aEncryptor, CPBEncryptParms& aData, const TDesC8& aAttributes)
sl@0
   259
	{
sl@0
   260
	// Now generate a PrivateKeyInfo type 
sl@0
   261
	CASN1EncSequence* privKeySeq = EncodeL(aPrivateKey, aPublicKey, aAttributes);
sl@0
   262
	CleanupStack::PushL(privKeySeq);
sl@0
   263
	
sl@0
   264
	CASN1EncSequence* seq = EncryptedSequenceL(*privKeySeq, aEncryptor, aData);
sl@0
   265
	
sl@0
   266
	CleanupStack::PopAndDestroy(privKeySeq);
sl@0
   267
		
sl@0
   268
	return seq;
sl@0
   269
	}
sl@0
   270
sl@0
   271
sl@0
   272
/**
sl@0
   273
 * Return the ASN1 PKCS#8 encoding of a DSA private key.
sl@0
   274
 *
sl@0
   275
 * The private key syntax for this key type is defined in 
sl@0
   276
 * the PKCS#11 document. 
sl@0
   277
 *
sl@0
   278
 * @param aPrivateKey The private key to be encoded (must be in CRT format)
sl@0
   279
 *
sl@0
   280
 * @return An ASN1 Sequence encoding the key.
sl@0
   281
 */	
sl@0
   282
/*static*/ EXPORT_C CASN1EncSequence* TASN1EncPKCS8::EncodeL(const CDSAPrivateKey& aPrivateKey, 
sl@0
   283
													          const TDesC8& aAttributes)
sl@0
   284
	{
sl@0
   285
	// Main ASN1 sequence
sl@0
   286
	CASN1EncSequence* seq = CASN1EncSequence::NewLC();
sl@0
   287
sl@0
   288
	//	version
sl@0
   289
	CASN1EncInt* version = CASN1EncInt::NewLC(KPkcs8Version);
sl@0
   290
	seq->AddAndPopChildL(version);
sl@0
   291
	
sl@0
   292
	//	Algorithm sequence
sl@0
   293
	CASN1EncSequence* algSeq = CASN1EncSequence::NewLC();
sl@0
   294
sl@0
   295
	CASN1EncObjectIdentifier* oid = CASN1EncObjectIdentifier::NewLC(KDSA);
sl@0
   296
	algSeq->AddAndPopChildL(oid);
sl@0
   297
sl@0
   298
	seq->AddAndPopChildL(algSeq);
sl@0
   299
sl@0
   300
	// DSA Parameters	
sl@0
   301
	CASN1EncSequence* keySeq = CASN1EncSequence::NewLC();
sl@0
   302
sl@0
   303
	//	The modulus	P
sl@0
   304
	const TInteger& modulus1 = aPrivateKey.P();
sl@0
   305
sl@0
   306
	CASN1EncBigInt* mod = CASN1EncBigInt::NewLC(modulus1);
sl@0
   307
	keySeq->AddAndPopChildL(mod);
sl@0
   308
sl@0
   309
	//	The modulus	Q
sl@0
   310
	const TInteger& modulus2 = aPrivateKey.Q();
sl@0
   311
	
sl@0
   312
	CASN1EncBigInt* mod2 = CASN1EncBigInt::NewLC(modulus2);
sl@0
   313
	keySeq->AddAndPopChildL(mod2);
sl@0
   314
	
sl@0
   315
	//	The base G 
sl@0
   316
	const TInteger& base = aPrivateKey.G();
sl@0
   317
sl@0
   318
	CASN1EncBigInt* b = CASN1EncBigInt::NewLC(base);
sl@0
   319
	keySeq->AddAndPopChildL(b);
sl@0
   320
	
sl@0
   321
	algSeq->AddAndPopChildL(keySeq);
sl@0
   322
	
sl@0
   323
	//	The private key X
sl@0
   324
	const TInteger& priv = aPrivateKey.X();	
sl@0
   325
	CASN1EncBigInt* x = CASN1EncBigInt::NewLC(priv);
sl@0
   326
sl@0
   327
	CASN1EncOctetString* octet = ElementToOctetL(*x);
sl@0
   328
sl@0
   329
	CleanupStack::PopAndDestroy(x);
sl@0
   330
	CleanupStack::PushL(octet);
sl@0
   331
sl@0
   332
	seq->AddAndPopChildL(octet);
sl@0
   333
sl@0
   334
	AddAttributesL(*seq, aAttributes);
sl@0
   335
	
sl@0
   336
	CleanupStack::Pop(seq);
sl@0
   337
sl@0
   338
	return seq;	
sl@0
   339
	}
sl@0
   340
sl@0
   341
sl@0
   342
/**
sl@0
   343
 * Encodes a DSA key in encrypted format.
sl@0
   344
 * 
sl@0
   345
 * @param aPrivateKey The private key to be encoded.
sl@0
   346
 * @param aEncryptor The object used to encrypt the data.
sl@0
   347
 * @param aData The encryption parameters of the given encryptor.
sl@0
   348
 *              These parameters are stored in the resulting sequence.
sl@0
   349
 *
sl@0
   350
 * @return An ASN1 Sequence encoding the encrypted key.
sl@0
   351
 */
sl@0
   352
/*static*/ EXPORT_C CASN1EncSequence* TASN1EncPKCS8::EncodeEncryptedL(const CDSAPrivateKey& aPrivateKey, CPBEncryptor& aEncryptor, 
sl@0
   353
                                                                      CPBEncryptParms& aData, const TDesC8& aAttributes)
sl@0
   354
	{
sl@0
   355
	// Now generate a PrivateKeyInfo type 
sl@0
   356
	CASN1EncSequence* privKeySeq = EncodeL(aPrivateKey, aAttributes);
sl@0
   357
	CleanupStack::PushL(privKeySeq);
sl@0
   358
	
sl@0
   359
	CASN1EncSequence* seq = EncryptedSequenceL(*privKeySeq, aEncryptor, aData);
sl@0
   360
	
sl@0
   361
	CleanupStack::PopAndDestroy(privKeySeq);
sl@0
   362
		
sl@0
   363
	return seq;
sl@0
   364
	}
sl@0
   365