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