1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/security/cryptoservices/certificateandkeymgmt/x509/x509keysDSA.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,381 @@
1.4 +/*
1.5 +* Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
1.6 +* All rights reserved.
1.7 +* This component and the accompanying materials are made available
1.8 +* under the terms of the License "Eclipse Public License v1.0"
1.9 +* which accompanies this distribution, and is available
1.10 +* at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.11 +*
1.12 +* Initial Contributors:
1.13 +* Nokia Corporation - initial contribution.
1.14 +*
1.15 +* Contributors:
1.16 +*
1.17 +* Description:
1.18 +*
1.19 +*/
1.20 +
1.21 +
1.22 +#include <x509keys.h>
1.23 +#include <asn1dec.h>
1.24 +#include <asn1enc.h>
1.25 +#include <x509cert.h>
1.26 +#include "x509keyencoder.h"
1.27 +
1.28 +//DSA public key
1.29 +CX509DSAPublicKey::CX509DSAPublicKey()
1.30 +{}
1.31 +
1.32 +//dsa public key
1.33 +EXPORT_C CX509DSAPublicKey* CX509DSAPublicKey::NewL(const TDesC8& aParamsData, const TDesC8& aBinaryData)
1.34 + {
1.35 + TInt pos = 0;
1.36 + return CX509DSAPublicKey::NewL(aParamsData, aBinaryData, pos);
1.37 + }
1.38 +
1.39 +EXPORT_C CX509DSAPublicKey* CX509DSAPublicKey::NewLC(const TDesC8& aParamsData, const TDesC8& aBinaryData)
1.40 + {
1.41 + TInt pos = 0;
1.42 + return CX509DSAPublicKey::NewLC(aParamsData, aBinaryData, pos);
1.43 + }
1.44 +
1.45 +EXPORT_C CX509DSAPublicKey* CX509DSAPublicKey::NewL(const TDesC8& aParamsData, const TDesC8& aBinaryData, TInt& aPos)
1.46 + {
1.47 + CX509DSAPublicKey* self = CX509DSAPublicKey::NewLC(aParamsData, aBinaryData, aPos);
1.48 + CleanupStack::Pop();
1.49 + return self;
1.50 + }
1.51 +
1.52 +EXPORT_C CX509DSAPublicKey* CX509DSAPublicKey::NewLC(const TDesC8& aParamsData, const TDesC8& aBinaryData, TInt& aPos)
1.53 + {
1.54 + CX509DSAPublicKey* self = new(ELeave) CX509DSAPublicKey;
1.55 + CleanupStack::PushL(self);
1.56 + self->ConstructL(aParamsData, aBinaryData, aPos);
1.57 + return self;
1.58 + }
1.59 +
1.60 +EXPORT_C CX509DSAPublicKey* CX509DSAPublicKey::NewL(const CDSAParameters& aParams, const TDesC8& aBinaryData)
1.61 +{
1.62 + TInt pos = 0;
1.63 + CX509DSAPublicKey* self = CX509DSAPublicKey::NewLC(aParams, aBinaryData, pos);
1.64 + CleanupStack::Pop();
1.65 + return self;
1.66 +}
1.67 +
1.68 +EXPORT_C CX509DSAPublicKey* CX509DSAPublicKey::NewLC(const CDSAParameters& aParams, const TDesC8& aBinaryData)
1.69 +{
1.70 + TInt pos = 0;
1.71 + CX509DSAPublicKey* self = new(ELeave) CX509DSAPublicKey;
1.72 + CleanupStack::PushL(self);
1.73 + self->ConstructL(aParams, aBinaryData, pos);
1.74 + return self;
1.75 +}
1.76 +
1.77 +EXPORT_C CX509DSAPublicKey* CX509DSAPublicKey::NewL(const CDSAParameters& aParams, const TDesC8& aBinaryData, TInt& aPos)
1.78 +{
1.79 + CX509DSAPublicKey* self = CX509DSAPublicKey::NewLC(aParams, aBinaryData, aPos);
1.80 + CleanupStack::Pop();
1.81 + return self;
1.82 +}
1.83 +
1.84 +EXPORT_C CX509DSAPublicKey* CX509DSAPublicKey::NewLC(const CDSAParameters& aParams, const TDesC8& aBinaryData, TInt& aPos)
1.85 +{
1.86 + CX509DSAPublicKey* self = new(ELeave) CX509DSAPublicKey;
1.87 + CleanupStack::PushL(self);
1.88 + self->ConstructL(aParams, aBinaryData, aPos);
1.89 + return self;
1.90 +}
1.91 +
1.92 +void CX509DSAPublicKey::ConstructL(const TDesC8& aParamsData, const TDesC8& aBinaryData, TInt& aPos)
1.93 + {
1.94 + TASN1DecGeneric genParams(aParamsData.Right(aParamsData.Length() - aPos));
1.95 + genParams.InitL();
1.96 + TInt end = aPos + genParams.LengthDER();
1.97 + aPos += genParams.LengthDERHeader();
1.98 + if (genParams.Tag() != EASN1Sequence)
1.99 + {
1.100 + User::Leave(KErrArgument);
1.101 + }
1.102 + TASN1DecInteger encInt;
1.103 + iP = encInt.DecodeDERLongL(aParamsData, aPos);
1.104 + iQ = encInt.DecodeDERLongL(aParamsData, aPos);
1.105 + iG = encInt.DecodeDERLongL(aParamsData, aPos);
1.106 + if (aPos != end)
1.107 + {
1.108 + User::Leave(KErrArgument);
1.109 + }
1.110 +
1.111 + aPos = 0;
1.112 + TASN1DecGeneric gen(aBinaryData.Right(aBinaryData.Length() - aPos));
1.113 + gen.InitL();
1.114 + end = aPos + gen.LengthDER();
1.115 + iY = encInt.DecodeDERLongL(aBinaryData, aPos);
1.116 + if (aPos != end)
1.117 + {
1.118 + User::Leave(KErrArgument);
1.119 + }
1.120 + }
1.121 +
1.122 +void CX509DSAPublicKey::ConstructL(const CDSAParameters& aParams, const TDesC8& aBinaryData, TInt& aPos)
1.123 + {
1.124 + iP = RInteger::NewL(aParams.P());
1.125 + iQ = RInteger::NewL(aParams.Q());
1.126 + iG = RInteger::NewL(aParams.G());
1.127 +
1.128 + TASN1DecGeneric gen(aBinaryData.Right(aBinaryData.Length() - aPos));
1.129 + gen.InitL();
1.130 + TInt end = aPos + gen.LengthDER();
1.131 + TASN1DecInteger encInt;
1.132 + iY = encInt.DecodeDERLongL(aBinaryData, aPos);
1.133 + if (aPos != end)
1.134 + {
1.135 + User::Leave(KErrArgument);
1.136 + }
1.137 + }
1.138 +
1.139 +
1.140 +EXPORT_C CDSAParameters* CX509DSAPublicKey::DSAParametersL(const TDesC8& aParamsData)
1.141 +{
1.142 + TInt pos = 0;
1.143 + TASN1DecGeneric genParams(aParamsData.Right(aParamsData.Length() - pos));
1.144 + genParams.InitL();
1.145 + TInt end = pos + genParams.LengthDER();
1.146 + pos += genParams.LengthDERHeader();
1.147 + if (genParams.Tag() != EASN1Sequence)
1.148 + {
1.149 + User::Leave(KErrArgument);
1.150 + }
1.151 + TASN1DecInteger encInt;
1.152 + RInteger P = encInt.DecodeDERLongL(aParamsData, pos);
1.153 + CleanupStack::PushL(P);
1.154 + RInteger Q = encInt.DecodeDERLongL(aParamsData, pos);
1.155 + CleanupStack::PushL(Q);
1.156 + RInteger G = encInt.DecodeDERLongL(aParamsData, pos);
1.157 + CleanupStack::PushL(G);
1.158 + if (pos != end)
1.159 + {
1.160 + User::Leave(KErrArgument);
1.161 + }
1.162 +
1.163 + CDSAParameters* theDSAParams = CDSAParameters::NewL(P, Q, G);
1.164 + CleanupStack::Pop(3, &P);
1.165 + return (theDSAParams);
1.166 +}
1.167 +
1.168 +// Decodes DSA keys from DER-encoded buffer
1.169 +EXPORT_C void TASN1DecDSAKeyPair::DecodeDERL(const TDesC8& aDER, TInt& aPos,
1.170 + CDSAPublicKey*& aPublicKey,
1.171 + CDSAPrivateKey*& aPrivateKey)
1.172 + {
1.173 + __UHEAP_MARK;
1.174 + aPublicKey = NULL;
1.175 + aPrivateKey = NULL;
1.176 +
1.177 + // Enter into the containing SEQUENCE and verify if it is
1.178 + // indeed there
1.179 + TASN1DecGeneric gen(aDER.Right(aDER.Length() - aPos));
1.180 + gen.InitL();
1.181 + TInt end = aPos + gen.LengthDER();
1.182 + aPos += gen.LengthDERHeader();
1.183 + if (gen.Tag() != EASN1Sequence)
1.184 + User::Leave(KErrArgument);
1.185 +
1.186 + TASN1DecInteger encInt;
1.187 +
1.188 + // Decode and discard version, which is an integer
1.189 + encInt.DecodeDERShortL(aDER, aPos);
1.190 +
1.191 + // Decode parameters
1.192 + // Decode p parameter
1.193 + RInteger p = encInt.DecodeDERLongL(aDER, aPos);
1.194 + CleanupStack::PushL(p);
1.195 + RInteger p1 = RInteger::NewL(p);
1.196 + CleanupStack::PushL(p1);
1.197 +
1.198 + // Decode q parameter
1.199 + RInteger q = encInt.DecodeDERLongL(aDER, aPos);
1.200 + CleanupStack::PushL(q);
1.201 + RInteger q1 = RInteger::NewL(q);
1.202 + CleanupStack::PushL(q1);
1.203 +
1.204 + // Decode g parameter
1.205 + RInteger g = encInt.DecodeDERLongL(aDER, aPos);
1.206 + CleanupStack::PushL(g);
1.207 + RInteger g1 = RInteger::NewL(g);
1.208 + CleanupStack::PushL(g1);
1.209 +
1.210 + // Decode private key x
1.211 + RInteger x = encInt.DecodeDERLongL(aDER, aPos);
1.212 + CleanupStack::PushL(x);
1.213 + // Decode public key y
1.214 + RInteger y = encInt.DecodeDERLongL(aDER, aPos);
1.215 + CleanupStack::PushL(y);
1.216 +
1.217 + // We now should be at the end of the encoding. If not, the
1.218 + // input encoding contains extra fields, and they are not
1.219 + // supported.
1.220 + if (aPos != end)
1.221 + User::Leave(KErrArgument);
1.222 +
1.223 + // Construct DSA public key
1.224 + CDSAPublicKey* dsaPublic = CDSAPublicKey::NewL(p, q, g, y);
1.225 + CleanupStack::PushL(dsaPublic);
1.226 +
1.227 + // Construct DSA key pair
1.228 + CDSAPrivateKey* dsaPrivate = CDSAPrivateKey::NewL(p1, q1, g1, x);
1.229 + CleanupStack::Pop(10, &p); // dsaPublic...p
1.230 +
1.231 + aPublicKey = dsaPublic;
1.232 + aPrivateKey = dsaPrivate;
1.233 + __UHEAP_MARKEND;
1.234 + }
1.235 +
1.236 +// Encodes DSA public key to DER
1.237 +EXPORT_C CASN1EncSequence* TASN1EncDSAPublicKey::EncodeDERL(const CDSAPublicKey& aKey) const
1.238 + {
1.239 + // Produce ASN.1 structure of DSA key parameters in the right order
1.240 + CASN1EncSequence* keySequence = CASN1EncSequence::NewLC();
1.241 + CASN1EncSequence* encParams = EncodeParamsLC(aKey);
1.242 + keySequence->AddAndPopChildL(encParams);
1.243 + // encode public key as a bit string
1.244 + CASN1EncBitString* pubKeyBitString = EncodePublicValueLC(aKey);
1.245 + keySequence->AddAndPopChildL(pubKeyBitString);
1.246 + CleanupStack::Pop(keySequence);
1.247 + return keySequence;
1.248 + }
1.249 +
1.250 +// Encodes DSA parameters into ASN.1 sequence
1.251 +EXPORT_C CASN1EncSequence* TASN1EncDSAPublicKey::EncodeParamsLC(const CDSAPublicKey& aKey) const
1.252 + {
1.253 + CASN1EncSequence* sequence = CASN1EncSequence::NewLC();
1.254 + CASN1EncBigInt* encParamP = CASN1EncBigInt::NewLC(aKey.P());
1.255 + sequence->AddAndPopChildL(encParamP);
1.256 + CASN1EncBigInt* encParamQ = CASN1EncBigInt::NewLC(aKey.Q());
1.257 + sequence->AddAndPopChildL(encParamQ);
1.258 + CASN1EncBigInt* encParamG = CASN1EncBigInt::NewLC(aKey.G());
1.259 + sequence->AddAndPopChildL(encParamG);
1.260 + return sequence;
1.261 + }
1.262 +
1.263 +EXPORT_C CASN1EncBitString* TASN1EncDSAPublicKey::EncodePublicValueLC(const CDSAPublicKey& aKey) const
1.264 + {
1.265 + CASN1EncBigInt* bigint = CASN1EncBigInt::NewLC(aKey.Y());
1.266 + CASN1EncBitString* pubKeyBitString = CASN1EncBitString::NewL(*bigint);
1.267 + CleanupStack::PopAndDestroy(bigint);
1.268 + CleanupStack::PushL(pubKeyBitString);
1.269 + return pubKeyBitString;
1.270 + }
1.271 +
1.272 +CX509DSASignature::CX509DSASignature()
1.273 +{}
1.274 +
1.275 +//DSA signature
1.276 +EXPORT_C CX509DSASignature* CX509DSASignature::NewL(const TDesC8& aBinaryData)
1.277 + {
1.278 + TInt pos = 0;
1.279 + return CX509DSASignature::NewL(aBinaryData, pos);
1.280 + }
1.281 +
1.282 +EXPORT_C CX509DSASignature* CX509DSASignature::NewLC(const TDesC8& aBinaryData)
1.283 + {
1.284 + TInt pos = 0;
1.285 + return CX509DSASignature::NewLC(aBinaryData, pos);
1.286 + }
1.287 +
1.288 +EXPORT_C CX509DSASignature* CX509DSASignature::NewL(const TDesC8& aBinaryData, TInt& aPos)
1.289 + {
1.290 + CX509DSASignature* self = CX509DSASignature::NewLC(aBinaryData, aPos);
1.291 + CleanupStack::Pop();
1.292 + return self;
1.293 + }
1.294 +
1.295 +EXPORT_C CX509DSASignature* CX509DSASignature::NewLC(const TDesC8& aBinaryData, TInt& aPos)
1.296 + {
1.297 + CX509DSASignature* self = new(ELeave) CX509DSASignature;
1.298 + CleanupStack::PushL(self);
1.299 + self->ConstructL(aBinaryData, aPos);
1.300 + return self;
1.301 + }
1.302 +
1.303 +void CX509DSASignature::ConstructL(const TDesC8& aBinaryData, TInt& aPos)
1.304 + {
1.305 + TASN1DecGeneric gen(aBinaryData.Right(aBinaryData.Length() - aPos));
1.306 + gen.InitL();
1.307 + TInt end = aPos + gen.LengthDER();
1.308 + aPos += gen.LengthDERHeader();
1.309 + if (gen.Tag() != EASN1Sequence)
1.310 + {
1.311 + User::Leave(KErrArgument);
1.312 + }
1.313 + TASN1DecInteger encInt;
1.314 + iR = encInt.DecodeDERLongL(aBinaryData, aPos);
1.315 + iS = encInt.DecodeDERLongL(aBinaryData, aPos);
1.316 + if (aPos != end)
1.317 + {
1.318 + User::Leave(KErrArgument);
1.319 + }
1.320 + }
1.321 +
1.322 +//
1.323 +// TX509DSAKeyEncoder Class Implementation
1.324 +//
1.325 +
1.326 +EXPORT_C TX509DSAKeyEncoder::TX509DSAKeyEncoder(const CDSAPublicKey& aKeyPublic,
1.327 + const TAlgorithmId aDigestAlg)
1.328 + : TX509KeyEncoder(aDigestAlg),
1.329 + iPublicKey(aKeyPublic)
1.330 + {}
1.331 +
1.332 +EXPORT_C CASN1EncBase* TX509DSAKeyEncoder::EncodeKeyLC() const
1.333 + {
1.334 + // Create higher-level sequence that will contain OID and the public key
1.335 + CASN1EncSequence* subjectPubKeyInfo = CASN1EncSequence::NewLC();
1.336 +
1.337 + CASN1EncSequence* seq = CASN1EncSequence::NewLC();
1.338 + CASN1EncObjectIdentifier* oid = CASN1EncObjectIdentifier::NewLC(KDSA);
1.339 + seq->AddAndPopChildL(oid);
1.340 +
1.341 + // the next sequence will contain DSA parameters
1.342 + TASN1EncDSAPublicKey keyEnc;
1.343 + CASN1EncSequence* seqParams = keyEnc.EncodeParamsLC(iPublicKey);
1.344 + seq->AddAndPopChildL(seqParams);
1.345 + subjectPubKeyInfo->AddAndPopChildL(seq);
1.346 +
1.347 + // Add the key itself to the higher-level sequence as a bit string
1.348 + CASN1EncBigInt* pubPart = CASN1EncBigInt::NewLC(iPublicKey.Y());
1.349 + HBufC8* encoding = HBufC8::NewMaxLC(pubPart->LengthDER());
1.350 + TPtr8 encodingPtr = encoding->Des();
1.351 + TUint pos = 0;
1.352 + pubPart->WriteDERL(encodingPtr, pos);
1.353 + CASN1EncBitString* pubkeyenc = CASN1EncBitString::NewLC(*encoding);
1.354 + subjectPubKeyInfo->AddAndPopChildL(pubkeyenc);
1.355 + CleanupStack::PopAndDestroy(2); // encoding, pubPart
1.356 + return subjectPubKeyInfo;
1.357 + }
1.358 +
1.359 +EXPORT_C CASN1EncSequence* TX509DSAKeyEncoder::EncodeSignatureAlgorithmLC() const
1.360 + {
1.361 + CASN1EncSequence* seq = CASN1EncSequence::NewLC();
1.362 + CASN1EncObjectIdentifier* oid = NULL;
1.363 +
1.364 + // Determine OID string for the current combination of algorithms.
1.365 + switch(iDigestAlg)
1.366 + {
1.367 + default:
1.368 + User::Leave(KErrNotSupported);
1.369 + break;
1.370 +
1.371 + case ESHA1:
1.372 + oid = CASN1EncObjectIdentifier::NewLC(KDSAWithSHA1);
1.373 + break;
1.374 + }
1.375 +
1.376 + // Add algorithm OID to the sequence.
1.377 + seq->AddAndPopChildL(oid);
1.378 + // Insert p, q, and g big parameters into the sequence
1.379 + TASN1EncDSAPublicKey keyEnc;
1.380 + CASN1EncSequence* params = keyEnc.EncodeParamsLC(iPublicKey);
1.381 + seq->AddAndPopChildL(params);
1.382 +
1.383 + return seq;
1.384 + }