os/security/cryptoservices/certificateandkeymgmt/x509/x509keysDSA.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) 1998-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 <x509keys.h>
sl@0
    20
#include <asn1dec.h>
sl@0
    21
#include <asn1enc.h>
sl@0
    22
#include <x509cert.h>
sl@0
    23
#include "x509keyencoder.h"
sl@0
    24
sl@0
    25
//DSA public key
sl@0
    26
CX509DSAPublicKey::CX509DSAPublicKey()
sl@0
    27
{}
sl@0
    28
sl@0
    29
//dsa public key
sl@0
    30
EXPORT_C CX509DSAPublicKey* CX509DSAPublicKey::NewL(const TDesC8& aParamsData, const TDesC8& aBinaryData)
sl@0
    31
	{
sl@0
    32
	TInt pos = 0;
sl@0
    33
	return CX509DSAPublicKey::NewL(aParamsData, aBinaryData, pos);
sl@0
    34
	}
sl@0
    35
sl@0
    36
EXPORT_C CX509DSAPublicKey* CX509DSAPublicKey::NewLC(const TDesC8& aParamsData, const TDesC8& aBinaryData)
sl@0
    37
	{
sl@0
    38
	TInt pos = 0;
sl@0
    39
	return CX509DSAPublicKey::NewLC(aParamsData, aBinaryData, pos);
sl@0
    40
	}
sl@0
    41
sl@0
    42
EXPORT_C CX509DSAPublicKey* CX509DSAPublicKey::NewL(const TDesC8& aParamsData, const TDesC8& aBinaryData, TInt& aPos)
sl@0
    43
	{
sl@0
    44
	CX509DSAPublicKey* self = CX509DSAPublicKey::NewLC(aParamsData, aBinaryData, aPos);
sl@0
    45
	CleanupStack::Pop();
sl@0
    46
	return self;
sl@0
    47
	}
sl@0
    48
sl@0
    49
EXPORT_C CX509DSAPublicKey* CX509DSAPublicKey::NewLC(const TDesC8& aParamsData, const TDesC8& aBinaryData, TInt& aPos)
sl@0
    50
	{
sl@0
    51
	CX509DSAPublicKey* self = new(ELeave) CX509DSAPublicKey;
sl@0
    52
	CleanupStack::PushL(self);
sl@0
    53
	self->ConstructL(aParamsData, aBinaryData, aPos);
sl@0
    54
	return self;
sl@0
    55
	}
sl@0
    56
sl@0
    57
EXPORT_C CX509DSAPublicKey* CX509DSAPublicKey::NewL(const CDSAParameters& aParams, const TDesC8& aBinaryData)
sl@0
    58
{
sl@0
    59
	TInt pos = 0;
sl@0
    60
	CX509DSAPublicKey* self = CX509DSAPublicKey::NewLC(aParams, aBinaryData, pos);
sl@0
    61
	CleanupStack::Pop();
sl@0
    62
	return self;
sl@0
    63
}
sl@0
    64
sl@0
    65
EXPORT_C CX509DSAPublicKey* CX509DSAPublicKey::NewLC(const CDSAParameters& aParams, const TDesC8& aBinaryData)
sl@0
    66
{
sl@0
    67
	TInt pos = 0;
sl@0
    68
	CX509DSAPublicKey* self = new(ELeave) CX509DSAPublicKey;
sl@0
    69
	CleanupStack::PushL(self);
sl@0
    70
	self->ConstructL(aParams, aBinaryData, pos);
sl@0
    71
	return self;
sl@0
    72
}
sl@0
    73
sl@0
    74
EXPORT_C CX509DSAPublicKey* CX509DSAPublicKey::NewL(const CDSAParameters& aParams, const TDesC8& aBinaryData, TInt& aPos)
sl@0
    75
{
sl@0
    76
	CX509DSAPublicKey* self = CX509DSAPublicKey::NewLC(aParams, aBinaryData, aPos);
sl@0
    77
	CleanupStack::Pop();
sl@0
    78
	return self;
sl@0
    79
}
sl@0
    80
sl@0
    81
EXPORT_C CX509DSAPublicKey* CX509DSAPublicKey::NewLC(const CDSAParameters& aParams, const TDesC8& aBinaryData, TInt& aPos)
sl@0
    82
{
sl@0
    83
	CX509DSAPublicKey* self = new(ELeave) CX509DSAPublicKey;
sl@0
    84
	CleanupStack::PushL(self);
sl@0
    85
	self->ConstructL(aParams, aBinaryData, aPos);
sl@0
    86
	return self;
sl@0
    87
}
sl@0
    88
sl@0
    89
void CX509DSAPublicKey::ConstructL(const TDesC8& aParamsData, const TDesC8& aBinaryData, TInt& aPos)
sl@0
    90
	{
sl@0
    91
	TASN1DecGeneric genParams(aParamsData.Right(aParamsData.Length() - aPos));
sl@0
    92
	genParams.InitL();
sl@0
    93
	TInt end = aPos + genParams.LengthDER();
sl@0
    94
	aPos += genParams.LengthDERHeader();
sl@0
    95
	if (genParams.Tag() != EASN1Sequence)
sl@0
    96
		{
sl@0
    97
		User::Leave(KErrArgument);
sl@0
    98
		}
sl@0
    99
	TASN1DecInteger encInt;
sl@0
   100
	iP = encInt.DecodeDERLongL(aParamsData, aPos);
sl@0
   101
	iQ = encInt.DecodeDERLongL(aParamsData, aPos);
sl@0
   102
	iG = encInt.DecodeDERLongL(aParamsData, aPos);
sl@0
   103
	if (aPos != end)
sl@0
   104
		{
sl@0
   105
		User::Leave(KErrArgument);
sl@0
   106
		}
sl@0
   107
sl@0
   108
	aPos = 0;
sl@0
   109
	TASN1DecGeneric gen(aBinaryData.Right(aBinaryData.Length() - aPos));
sl@0
   110
	gen.InitL();
sl@0
   111
	end = aPos + gen.LengthDER();
sl@0
   112
	iY = encInt.DecodeDERLongL(aBinaryData, aPos);
sl@0
   113
	if (aPos != end)
sl@0
   114
		{
sl@0
   115
		User::Leave(KErrArgument);
sl@0
   116
		}
sl@0
   117
	}
sl@0
   118
sl@0
   119
void CX509DSAPublicKey::ConstructL(const CDSAParameters& aParams, const TDesC8& aBinaryData, TInt& aPos)
sl@0
   120
	{
sl@0
   121
	iP = RInteger::NewL(aParams.P());
sl@0
   122
	iQ = RInteger::NewL(aParams.Q());
sl@0
   123
	iG = RInteger::NewL(aParams.G());
sl@0
   124
	
sl@0
   125
	TASN1DecGeneric gen(aBinaryData.Right(aBinaryData.Length() - aPos));
sl@0
   126
	gen.InitL();
sl@0
   127
	TInt end = aPos + gen.LengthDER();
sl@0
   128
	TASN1DecInteger encInt;
sl@0
   129
	iY = encInt.DecodeDERLongL(aBinaryData, aPos);
sl@0
   130
	if (aPos != end)
sl@0
   131
		{
sl@0
   132
		User::Leave(KErrArgument);
sl@0
   133
		}
sl@0
   134
	}
sl@0
   135
sl@0
   136
sl@0
   137
EXPORT_C CDSAParameters* CX509DSAPublicKey::DSAParametersL(const TDesC8& aParamsData)
sl@0
   138
{
sl@0
   139
	TInt pos = 0;
sl@0
   140
	TASN1DecGeneric genParams(aParamsData.Right(aParamsData.Length() - pos));
sl@0
   141
	genParams.InitL();
sl@0
   142
	TInt end = pos + genParams.LengthDER();
sl@0
   143
	pos += genParams.LengthDERHeader();
sl@0
   144
	if (genParams.Tag() != EASN1Sequence)
sl@0
   145
		{
sl@0
   146
		User::Leave(KErrArgument);
sl@0
   147
		}
sl@0
   148
	TASN1DecInteger encInt;
sl@0
   149
	RInteger P = encInt.DecodeDERLongL(aParamsData, pos);
sl@0
   150
	CleanupStack::PushL(P);
sl@0
   151
	RInteger Q = encInt.DecodeDERLongL(aParamsData, pos);
sl@0
   152
	CleanupStack::PushL(Q);
sl@0
   153
	RInteger G = encInt.DecodeDERLongL(aParamsData, pos);
sl@0
   154
	CleanupStack::PushL(G);
sl@0
   155
	if (pos != end)
sl@0
   156
		{
sl@0
   157
		User::Leave(KErrArgument);
sl@0
   158
		}
sl@0
   159
	
sl@0
   160
	CDSAParameters* theDSAParams = CDSAParameters::NewL(P, Q, G);
sl@0
   161
	CleanupStack::Pop(3, &P);
sl@0
   162
	return (theDSAParams);
sl@0
   163
}
sl@0
   164
sl@0
   165
// Decodes DSA keys from DER-encoded buffer
sl@0
   166
EXPORT_C void TASN1DecDSAKeyPair::DecodeDERL(const TDesC8& aDER, TInt& aPos, 
sl@0
   167
													CDSAPublicKey*& aPublicKey, 
sl@0
   168
													CDSAPrivateKey*& aPrivateKey)
sl@0
   169
	{
sl@0
   170
	__UHEAP_MARK;
sl@0
   171
	aPublicKey = NULL;
sl@0
   172
	aPrivateKey = NULL;
sl@0
   173
sl@0
   174
	// Enter into the containing SEQUENCE and verify if it is 
sl@0
   175
	// indeed there
sl@0
   176
	TASN1DecGeneric gen(aDER.Right(aDER.Length() - aPos));
sl@0
   177
	gen.InitL();
sl@0
   178
	TInt end = aPos + gen.LengthDER();
sl@0
   179
	aPos += gen.LengthDERHeader();
sl@0
   180
	if (gen.Tag() != EASN1Sequence)
sl@0
   181
		User::Leave(KErrArgument);
sl@0
   182
sl@0
   183
	TASN1DecInteger encInt;
sl@0
   184
	
sl@0
   185
	// Decode and discard version, which is an integer
sl@0
   186
	encInt.DecodeDERShortL(aDER, aPos);
sl@0
   187
sl@0
   188
	// Decode parameters
sl@0
   189
	// Decode p parameter
sl@0
   190
	RInteger p = encInt.DecodeDERLongL(aDER, aPos);
sl@0
   191
	CleanupStack::PushL(p);
sl@0
   192
	RInteger p1 = RInteger::NewL(p);
sl@0
   193
	CleanupStack::PushL(p1);
sl@0
   194
	
sl@0
   195
	// Decode q parameter
sl@0
   196
	RInteger q = encInt.DecodeDERLongL(aDER, aPos);
sl@0
   197
	CleanupStack::PushL(q);
sl@0
   198
	RInteger q1 = RInteger::NewL(q);
sl@0
   199
	CleanupStack::PushL(q1);
sl@0
   200
sl@0
   201
	// Decode g parameter
sl@0
   202
	RInteger g = encInt.DecodeDERLongL(aDER, aPos);
sl@0
   203
	CleanupStack::PushL(g);
sl@0
   204
	RInteger g1 = RInteger::NewL(g);
sl@0
   205
	CleanupStack::PushL(g1);
sl@0
   206
sl@0
   207
	// Decode private key x
sl@0
   208
	RInteger x = encInt.DecodeDERLongL(aDER, aPos);
sl@0
   209
	CleanupStack::PushL(x);
sl@0
   210
	// Decode public key y
sl@0
   211
	RInteger y = encInt.DecodeDERLongL(aDER, aPos);
sl@0
   212
	CleanupStack::PushL(y);
sl@0
   213
sl@0
   214
	// We now should be at the end of the encoding. If not, the 
sl@0
   215
	// input encoding contains extra fields, and they are not 
sl@0
   216
	// supported.
sl@0
   217
	if (aPos != end)
sl@0
   218
		User::Leave(KErrArgument);
sl@0
   219
sl@0
   220
	// Construct DSA public key
sl@0
   221
	CDSAPublicKey* dsaPublic = CDSAPublicKey::NewL(p, q, g, y);
sl@0
   222
	CleanupStack::PushL(dsaPublic);
sl@0
   223
sl@0
   224
	// Construct DSA key pair
sl@0
   225
	CDSAPrivateKey* dsaPrivate = CDSAPrivateKey::NewL(p1, q1, g1, x);
sl@0
   226
	CleanupStack::Pop(10, &p);	//	dsaPublic...p	
sl@0
   227
	
sl@0
   228
	aPublicKey = dsaPublic;
sl@0
   229
	aPrivateKey = dsaPrivate;
sl@0
   230
	__UHEAP_MARKEND;
sl@0
   231
	}
sl@0
   232
sl@0
   233
// Encodes DSA public key to DER
sl@0
   234
EXPORT_C CASN1EncSequence* TASN1EncDSAPublicKey::EncodeDERL(const CDSAPublicKey& aKey) const
sl@0
   235
	{
sl@0
   236
	// Produce ASN.1 structure of DSA key parameters in the right order
sl@0
   237
	CASN1EncSequence* keySequence = CASN1EncSequence::NewLC();
sl@0
   238
	CASN1EncSequence* encParams = EncodeParamsLC(aKey);
sl@0
   239
	keySequence->AddAndPopChildL(encParams);
sl@0
   240
	// encode public key as a bit string
sl@0
   241
	CASN1EncBitString* pubKeyBitString = EncodePublicValueLC(aKey);
sl@0
   242
	keySequence->AddAndPopChildL(pubKeyBitString);
sl@0
   243
	CleanupStack::Pop(keySequence);
sl@0
   244
	return keySequence;
sl@0
   245
	}
sl@0
   246
sl@0
   247
// Encodes DSA parameters into ASN.1 sequence
sl@0
   248
EXPORT_C CASN1EncSequence* TASN1EncDSAPublicKey::EncodeParamsLC(const CDSAPublicKey& aKey) const
sl@0
   249
	{
sl@0
   250
	CASN1EncSequence* sequence = CASN1EncSequence::NewLC();
sl@0
   251
	CASN1EncBigInt* encParamP = CASN1EncBigInt::NewLC(aKey.P());
sl@0
   252
	sequence->AddAndPopChildL(encParamP);
sl@0
   253
	CASN1EncBigInt* encParamQ = CASN1EncBigInt::NewLC(aKey.Q());
sl@0
   254
	sequence->AddAndPopChildL(encParamQ);
sl@0
   255
	CASN1EncBigInt* encParamG = CASN1EncBigInt::NewLC(aKey.G());
sl@0
   256
	sequence->AddAndPopChildL(encParamG);
sl@0
   257
	return sequence;
sl@0
   258
	}
sl@0
   259
sl@0
   260
EXPORT_C CASN1EncBitString* TASN1EncDSAPublicKey::EncodePublicValueLC(const CDSAPublicKey& aKey) const
sl@0
   261
	{
sl@0
   262
	CASN1EncBigInt* bigint = CASN1EncBigInt::NewLC(aKey.Y());
sl@0
   263
	CASN1EncBitString* pubKeyBitString = CASN1EncBitString::NewL(*bigint);
sl@0
   264
	CleanupStack::PopAndDestroy(bigint);
sl@0
   265
	CleanupStack::PushL(pubKeyBitString);
sl@0
   266
	return pubKeyBitString;
sl@0
   267
	}
sl@0
   268
sl@0
   269
CX509DSASignature::CX509DSASignature()
sl@0
   270
{}
sl@0
   271
sl@0
   272
//DSA signature
sl@0
   273
EXPORT_C CX509DSASignature* CX509DSASignature::NewL(const TDesC8& aBinaryData)
sl@0
   274
	{
sl@0
   275
	TInt pos = 0;
sl@0
   276
	return CX509DSASignature::NewL(aBinaryData, pos);
sl@0
   277
	}
sl@0
   278
sl@0
   279
EXPORT_C CX509DSASignature* CX509DSASignature::NewLC(const TDesC8& aBinaryData)
sl@0
   280
	{
sl@0
   281
	TInt pos = 0;
sl@0
   282
	return CX509DSASignature::NewLC(aBinaryData, pos);
sl@0
   283
	}
sl@0
   284
sl@0
   285
EXPORT_C CX509DSASignature* CX509DSASignature::NewL(const TDesC8& aBinaryData, TInt& aPos)
sl@0
   286
	{
sl@0
   287
	CX509DSASignature* self = CX509DSASignature::NewLC(aBinaryData, aPos);
sl@0
   288
	CleanupStack::Pop();
sl@0
   289
	return self;
sl@0
   290
	}
sl@0
   291
sl@0
   292
EXPORT_C CX509DSASignature* CX509DSASignature::NewLC(const TDesC8& aBinaryData, TInt& aPos)
sl@0
   293
	{
sl@0
   294
	CX509DSASignature* self = new(ELeave) CX509DSASignature;
sl@0
   295
	CleanupStack::PushL(self);
sl@0
   296
	self->ConstructL(aBinaryData, aPos);
sl@0
   297
	return self;
sl@0
   298
	}
sl@0
   299
sl@0
   300
void CX509DSASignature::ConstructL(const TDesC8& aBinaryData, TInt& aPos)
sl@0
   301
	{
sl@0
   302
	TASN1DecGeneric gen(aBinaryData.Right(aBinaryData.Length() - aPos));
sl@0
   303
	gen.InitL();
sl@0
   304
	TInt end = aPos + gen.LengthDER();
sl@0
   305
	aPos += gen.LengthDERHeader();
sl@0
   306
	if (gen.Tag() != EASN1Sequence)
sl@0
   307
		{
sl@0
   308
		User::Leave(KErrArgument);
sl@0
   309
		}
sl@0
   310
	TASN1DecInteger encInt;
sl@0
   311
	iR = encInt.DecodeDERLongL(aBinaryData, aPos);
sl@0
   312
	iS = encInt.DecodeDERLongL(aBinaryData, aPos);
sl@0
   313
	if (aPos != end)
sl@0
   314
		{
sl@0
   315
		User::Leave(KErrArgument);
sl@0
   316
		}
sl@0
   317
	}
sl@0
   318
sl@0
   319
//
sl@0
   320
// TX509DSAKeyEncoder Class Implementation
sl@0
   321
//
sl@0
   322
sl@0
   323
EXPORT_C TX509DSAKeyEncoder::TX509DSAKeyEncoder(const CDSAPublicKey& aKeyPublic, 
sl@0
   324
												const TAlgorithmId aDigestAlg)
sl@0
   325
	: TX509KeyEncoder(aDigestAlg),
sl@0
   326
	  iPublicKey(aKeyPublic)
sl@0
   327
	{}
sl@0
   328
sl@0
   329
EXPORT_C CASN1EncBase* TX509DSAKeyEncoder::EncodeKeyLC() const
sl@0
   330
	{
sl@0
   331
	// Create higher-level sequence that will contain OID and the public key
sl@0
   332
	CASN1EncSequence* subjectPubKeyInfo = CASN1EncSequence::NewLC();
sl@0
   333
	
sl@0
   334
	CASN1EncSequence* seq = CASN1EncSequence::NewLC();
sl@0
   335
	CASN1EncObjectIdentifier* oid = CASN1EncObjectIdentifier::NewLC(KDSA);
sl@0
   336
	seq->AddAndPopChildL(oid);
sl@0
   337
	
sl@0
   338
	// the next sequence will contain DSA parameters
sl@0
   339
	TASN1EncDSAPublicKey keyEnc;
sl@0
   340
	CASN1EncSequence* seqParams = keyEnc.EncodeParamsLC(iPublicKey);
sl@0
   341
	seq->AddAndPopChildL(seqParams);
sl@0
   342
	subjectPubKeyInfo->AddAndPopChildL(seq);
sl@0
   343
	
sl@0
   344
	// Add the key itself to the higher-level sequence as a bit string
sl@0
   345
	CASN1EncBigInt* pubPart = CASN1EncBigInt::NewLC(iPublicKey.Y());
sl@0
   346
	HBufC8* encoding = HBufC8::NewMaxLC(pubPart->LengthDER());
sl@0
   347
	TPtr8 encodingPtr = encoding->Des();
sl@0
   348
	TUint pos = 0;
sl@0
   349
	pubPart->WriteDERL(encodingPtr, pos);
sl@0
   350
	CASN1EncBitString* pubkeyenc = CASN1EncBitString::NewLC(*encoding);
sl@0
   351
	subjectPubKeyInfo->AddAndPopChildL(pubkeyenc);
sl@0
   352
	CleanupStack::PopAndDestroy(2); // encoding, pubPart
sl@0
   353
	return subjectPubKeyInfo;
sl@0
   354
	}
sl@0
   355
sl@0
   356
EXPORT_C CASN1EncSequence* TX509DSAKeyEncoder::EncodeSignatureAlgorithmLC() const
sl@0
   357
	{
sl@0
   358
	CASN1EncSequence* seq = CASN1EncSequence::NewLC();
sl@0
   359
	CASN1EncObjectIdentifier* oid = NULL;
sl@0
   360
sl@0
   361
	// Determine OID string for the current combination of algorithms.
sl@0
   362
	switch(iDigestAlg)
sl@0
   363
		{
sl@0
   364
		default:
sl@0
   365
			User::Leave(KErrNotSupported);
sl@0
   366
			break;
sl@0
   367
sl@0
   368
		case ESHA1:
sl@0
   369
			oid = CASN1EncObjectIdentifier::NewLC(KDSAWithSHA1);
sl@0
   370
			break;
sl@0
   371
		}
sl@0
   372
sl@0
   373
	// Add algorithm OID to the sequence.
sl@0
   374
	seq->AddAndPopChildL(oid);
sl@0
   375
	// Insert p, q, and g big parameters into the sequence
sl@0
   376
	TASN1EncDSAPublicKey keyEnc;
sl@0
   377
	CASN1EncSequence* params = keyEnc.EncodeParamsLC(iPublicKey);
sl@0
   378
	seq->AddAndPopChildL(params);
sl@0
   379
	
sl@0
   380
	return seq;
sl@0
   381
	}