sl@0: /* sl@0: * Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: * All rights reserved. sl@0: * This component and the accompanying materials are made available sl@0: * under the terms of the License "Eclipse Public License v1.0" sl@0: * which accompanies this distribution, and is available sl@0: * at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: * sl@0: * Initial Contributors: sl@0: * Nokia Corporation - initial contribution. sl@0: * sl@0: * Contributors: sl@0: * sl@0: * Description: sl@0: * sl@0: */ sl@0: sl@0: sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include "x509keyencoder.h" sl@0: sl@0: //DSA public key sl@0: CX509DSAPublicKey::CX509DSAPublicKey() sl@0: {} sl@0: sl@0: //dsa public key sl@0: EXPORT_C CX509DSAPublicKey* CX509DSAPublicKey::NewL(const TDesC8& aParamsData, const TDesC8& aBinaryData) sl@0: { sl@0: TInt pos = 0; sl@0: return CX509DSAPublicKey::NewL(aParamsData, aBinaryData, pos); sl@0: } sl@0: sl@0: EXPORT_C CX509DSAPublicKey* CX509DSAPublicKey::NewLC(const TDesC8& aParamsData, const TDesC8& aBinaryData) sl@0: { sl@0: TInt pos = 0; sl@0: return CX509DSAPublicKey::NewLC(aParamsData, aBinaryData, pos); sl@0: } sl@0: sl@0: EXPORT_C CX509DSAPublicKey* CX509DSAPublicKey::NewL(const TDesC8& aParamsData, const TDesC8& aBinaryData, TInt& aPos) sl@0: { sl@0: CX509DSAPublicKey* self = CX509DSAPublicKey::NewLC(aParamsData, aBinaryData, aPos); sl@0: CleanupStack::Pop(); sl@0: return self; sl@0: } sl@0: sl@0: EXPORT_C CX509DSAPublicKey* CX509DSAPublicKey::NewLC(const TDesC8& aParamsData, const TDesC8& aBinaryData, TInt& aPos) sl@0: { sl@0: CX509DSAPublicKey* self = new(ELeave) CX509DSAPublicKey; sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(aParamsData, aBinaryData, aPos); sl@0: return self; sl@0: } sl@0: sl@0: EXPORT_C CX509DSAPublicKey* CX509DSAPublicKey::NewL(const CDSAParameters& aParams, const TDesC8& aBinaryData) sl@0: { sl@0: TInt pos = 0; sl@0: CX509DSAPublicKey* self = CX509DSAPublicKey::NewLC(aParams, aBinaryData, pos); sl@0: CleanupStack::Pop(); sl@0: return self; sl@0: } sl@0: sl@0: EXPORT_C CX509DSAPublicKey* CX509DSAPublicKey::NewLC(const CDSAParameters& aParams, const TDesC8& aBinaryData) sl@0: { sl@0: TInt pos = 0; sl@0: CX509DSAPublicKey* self = new(ELeave) CX509DSAPublicKey; sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(aParams, aBinaryData, pos); sl@0: return self; sl@0: } sl@0: sl@0: EXPORT_C CX509DSAPublicKey* CX509DSAPublicKey::NewL(const CDSAParameters& aParams, const TDesC8& aBinaryData, TInt& aPos) sl@0: { sl@0: CX509DSAPublicKey* self = CX509DSAPublicKey::NewLC(aParams, aBinaryData, aPos); sl@0: CleanupStack::Pop(); sl@0: return self; sl@0: } sl@0: sl@0: EXPORT_C CX509DSAPublicKey* CX509DSAPublicKey::NewLC(const CDSAParameters& aParams, const TDesC8& aBinaryData, TInt& aPos) sl@0: { sl@0: CX509DSAPublicKey* self = new(ELeave) CX509DSAPublicKey; sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(aParams, aBinaryData, aPos); sl@0: return self; sl@0: } sl@0: sl@0: void CX509DSAPublicKey::ConstructL(const TDesC8& aParamsData, const TDesC8& aBinaryData, TInt& aPos) sl@0: { sl@0: TASN1DecGeneric genParams(aParamsData.Right(aParamsData.Length() - aPos)); sl@0: genParams.InitL(); sl@0: TInt end = aPos + genParams.LengthDER(); sl@0: aPos += genParams.LengthDERHeader(); sl@0: if (genParams.Tag() != EASN1Sequence) sl@0: { sl@0: User::Leave(KErrArgument); sl@0: } sl@0: TASN1DecInteger encInt; sl@0: iP = encInt.DecodeDERLongL(aParamsData, aPos); sl@0: iQ = encInt.DecodeDERLongL(aParamsData, aPos); sl@0: iG = encInt.DecodeDERLongL(aParamsData, aPos); sl@0: if (aPos != end) sl@0: { sl@0: User::Leave(KErrArgument); sl@0: } sl@0: sl@0: aPos = 0; sl@0: TASN1DecGeneric gen(aBinaryData.Right(aBinaryData.Length() - aPos)); sl@0: gen.InitL(); sl@0: end = aPos + gen.LengthDER(); sl@0: iY = encInt.DecodeDERLongL(aBinaryData, aPos); sl@0: if (aPos != end) sl@0: { sl@0: User::Leave(KErrArgument); sl@0: } sl@0: } sl@0: sl@0: void CX509DSAPublicKey::ConstructL(const CDSAParameters& aParams, const TDesC8& aBinaryData, TInt& aPos) sl@0: { sl@0: iP = RInteger::NewL(aParams.P()); sl@0: iQ = RInteger::NewL(aParams.Q()); sl@0: iG = RInteger::NewL(aParams.G()); sl@0: sl@0: TASN1DecGeneric gen(aBinaryData.Right(aBinaryData.Length() - aPos)); sl@0: gen.InitL(); sl@0: TInt end = aPos + gen.LengthDER(); sl@0: TASN1DecInteger encInt; sl@0: iY = encInt.DecodeDERLongL(aBinaryData, aPos); sl@0: if (aPos != end) sl@0: { sl@0: User::Leave(KErrArgument); sl@0: } sl@0: } sl@0: sl@0: sl@0: EXPORT_C CDSAParameters* CX509DSAPublicKey::DSAParametersL(const TDesC8& aParamsData) sl@0: { sl@0: TInt pos = 0; sl@0: TASN1DecGeneric genParams(aParamsData.Right(aParamsData.Length() - pos)); sl@0: genParams.InitL(); sl@0: TInt end = pos + genParams.LengthDER(); sl@0: pos += genParams.LengthDERHeader(); sl@0: if (genParams.Tag() != EASN1Sequence) sl@0: { sl@0: User::Leave(KErrArgument); sl@0: } sl@0: TASN1DecInteger encInt; sl@0: RInteger P = encInt.DecodeDERLongL(aParamsData, pos); sl@0: CleanupStack::PushL(P); sl@0: RInteger Q = encInt.DecodeDERLongL(aParamsData, pos); sl@0: CleanupStack::PushL(Q); sl@0: RInteger G = encInt.DecodeDERLongL(aParamsData, pos); sl@0: CleanupStack::PushL(G); sl@0: if (pos != end) sl@0: { sl@0: User::Leave(KErrArgument); sl@0: } sl@0: sl@0: CDSAParameters* theDSAParams = CDSAParameters::NewL(P, Q, G); sl@0: CleanupStack::Pop(3, &P); sl@0: return (theDSAParams); sl@0: } sl@0: sl@0: // Decodes DSA keys from DER-encoded buffer sl@0: EXPORT_C void TASN1DecDSAKeyPair::DecodeDERL(const TDesC8& aDER, TInt& aPos, sl@0: CDSAPublicKey*& aPublicKey, sl@0: CDSAPrivateKey*& aPrivateKey) sl@0: { sl@0: __UHEAP_MARK; sl@0: aPublicKey = NULL; sl@0: aPrivateKey = NULL; sl@0: sl@0: // Enter into the containing SEQUENCE and verify if it is sl@0: // indeed there sl@0: TASN1DecGeneric gen(aDER.Right(aDER.Length() - aPos)); sl@0: gen.InitL(); sl@0: TInt end = aPos + gen.LengthDER(); sl@0: aPos += gen.LengthDERHeader(); sl@0: if (gen.Tag() != EASN1Sequence) sl@0: User::Leave(KErrArgument); sl@0: sl@0: TASN1DecInteger encInt; sl@0: sl@0: // Decode and discard version, which is an integer sl@0: encInt.DecodeDERShortL(aDER, aPos); sl@0: sl@0: // Decode parameters sl@0: // Decode p parameter sl@0: RInteger p = encInt.DecodeDERLongL(aDER, aPos); sl@0: CleanupStack::PushL(p); sl@0: RInteger p1 = RInteger::NewL(p); sl@0: CleanupStack::PushL(p1); sl@0: sl@0: // Decode q parameter sl@0: RInteger q = encInt.DecodeDERLongL(aDER, aPos); sl@0: CleanupStack::PushL(q); sl@0: RInteger q1 = RInteger::NewL(q); sl@0: CleanupStack::PushL(q1); sl@0: sl@0: // Decode g parameter sl@0: RInteger g = encInt.DecodeDERLongL(aDER, aPos); sl@0: CleanupStack::PushL(g); sl@0: RInteger g1 = RInteger::NewL(g); sl@0: CleanupStack::PushL(g1); sl@0: sl@0: // Decode private key x sl@0: RInteger x = encInt.DecodeDERLongL(aDER, aPos); sl@0: CleanupStack::PushL(x); sl@0: // Decode public key y sl@0: RInteger y = encInt.DecodeDERLongL(aDER, aPos); sl@0: CleanupStack::PushL(y); sl@0: sl@0: // We now should be at the end of the encoding. If not, the sl@0: // input encoding contains extra fields, and they are not sl@0: // supported. sl@0: if (aPos != end) sl@0: User::Leave(KErrArgument); sl@0: sl@0: // Construct DSA public key sl@0: CDSAPublicKey* dsaPublic = CDSAPublicKey::NewL(p, q, g, y); sl@0: CleanupStack::PushL(dsaPublic); sl@0: sl@0: // Construct DSA key pair sl@0: CDSAPrivateKey* dsaPrivate = CDSAPrivateKey::NewL(p1, q1, g1, x); sl@0: CleanupStack::Pop(10, &p); // dsaPublic...p sl@0: sl@0: aPublicKey = dsaPublic; sl@0: aPrivateKey = dsaPrivate; sl@0: __UHEAP_MARKEND; sl@0: } sl@0: sl@0: // Encodes DSA public key to DER sl@0: EXPORT_C CASN1EncSequence* TASN1EncDSAPublicKey::EncodeDERL(const CDSAPublicKey& aKey) const sl@0: { sl@0: // Produce ASN.1 structure of DSA key parameters in the right order sl@0: CASN1EncSequence* keySequence = CASN1EncSequence::NewLC(); sl@0: CASN1EncSequence* encParams = EncodeParamsLC(aKey); sl@0: keySequence->AddAndPopChildL(encParams); sl@0: // encode public key as a bit string sl@0: CASN1EncBitString* pubKeyBitString = EncodePublicValueLC(aKey); sl@0: keySequence->AddAndPopChildL(pubKeyBitString); sl@0: CleanupStack::Pop(keySequence); sl@0: return keySequence; sl@0: } sl@0: sl@0: // Encodes DSA parameters into ASN.1 sequence sl@0: EXPORT_C CASN1EncSequence* TASN1EncDSAPublicKey::EncodeParamsLC(const CDSAPublicKey& aKey) const sl@0: { sl@0: CASN1EncSequence* sequence = CASN1EncSequence::NewLC(); sl@0: CASN1EncBigInt* encParamP = CASN1EncBigInt::NewLC(aKey.P()); sl@0: sequence->AddAndPopChildL(encParamP); sl@0: CASN1EncBigInt* encParamQ = CASN1EncBigInt::NewLC(aKey.Q()); sl@0: sequence->AddAndPopChildL(encParamQ); sl@0: CASN1EncBigInt* encParamG = CASN1EncBigInt::NewLC(aKey.G()); sl@0: sequence->AddAndPopChildL(encParamG); sl@0: return sequence; sl@0: } sl@0: sl@0: EXPORT_C CASN1EncBitString* TASN1EncDSAPublicKey::EncodePublicValueLC(const CDSAPublicKey& aKey) const sl@0: { sl@0: CASN1EncBigInt* bigint = CASN1EncBigInt::NewLC(aKey.Y()); sl@0: CASN1EncBitString* pubKeyBitString = CASN1EncBitString::NewL(*bigint); sl@0: CleanupStack::PopAndDestroy(bigint); sl@0: CleanupStack::PushL(pubKeyBitString); sl@0: return pubKeyBitString; sl@0: } sl@0: sl@0: CX509DSASignature::CX509DSASignature() sl@0: {} sl@0: sl@0: //DSA signature sl@0: EXPORT_C CX509DSASignature* CX509DSASignature::NewL(const TDesC8& aBinaryData) sl@0: { sl@0: TInt pos = 0; sl@0: return CX509DSASignature::NewL(aBinaryData, pos); sl@0: } sl@0: sl@0: EXPORT_C CX509DSASignature* CX509DSASignature::NewLC(const TDesC8& aBinaryData) sl@0: { sl@0: TInt pos = 0; sl@0: return CX509DSASignature::NewLC(aBinaryData, pos); sl@0: } sl@0: sl@0: EXPORT_C CX509DSASignature* CX509DSASignature::NewL(const TDesC8& aBinaryData, TInt& aPos) sl@0: { sl@0: CX509DSASignature* self = CX509DSASignature::NewLC(aBinaryData, aPos); sl@0: CleanupStack::Pop(); sl@0: return self; sl@0: } sl@0: sl@0: EXPORT_C CX509DSASignature* CX509DSASignature::NewLC(const TDesC8& aBinaryData, TInt& aPos) sl@0: { sl@0: CX509DSASignature* self = new(ELeave) CX509DSASignature; sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(aBinaryData, aPos); sl@0: return self; sl@0: } sl@0: sl@0: void CX509DSASignature::ConstructL(const TDesC8& aBinaryData, TInt& aPos) sl@0: { sl@0: TASN1DecGeneric gen(aBinaryData.Right(aBinaryData.Length() - aPos)); sl@0: gen.InitL(); sl@0: TInt end = aPos + gen.LengthDER(); sl@0: aPos += gen.LengthDERHeader(); sl@0: if (gen.Tag() != EASN1Sequence) sl@0: { sl@0: User::Leave(KErrArgument); sl@0: } sl@0: TASN1DecInteger encInt; sl@0: iR = encInt.DecodeDERLongL(aBinaryData, aPos); sl@0: iS = encInt.DecodeDERLongL(aBinaryData, aPos); sl@0: if (aPos != end) sl@0: { sl@0: User::Leave(KErrArgument); sl@0: } sl@0: } sl@0: sl@0: // sl@0: // TX509DSAKeyEncoder Class Implementation sl@0: // sl@0: sl@0: EXPORT_C TX509DSAKeyEncoder::TX509DSAKeyEncoder(const CDSAPublicKey& aKeyPublic, sl@0: const TAlgorithmId aDigestAlg) sl@0: : TX509KeyEncoder(aDigestAlg), sl@0: iPublicKey(aKeyPublic) sl@0: {} sl@0: sl@0: EXPORT_C CASN1EncBase* TX509DSAKeyEncoder::EncodeKeyLC() const sl@0: { sl@0: // Create higher-level sequence that will contain OID and the public key sl@0: CASN1EncSequence* subjectPubKeyInfo = CASN1EncSequence::NewLC(); sl@0: sl@0: CASN1EncSequence* seq = CASN1EncSequence::NewLC(); sl@0: CASN1EncObjectIdentifier* oid = CASN1EncObjectIdentifier::NewLC(KDSA); sl@0: seq->AddAndPopChildL(oid); sl@0: sl@0: // the next sequence will contain DSA parameters sl@0: TASN1EncDSAPublicKey keyEnc; sl@0: CASN1EncSequence* seqParams = keyEnc.EncodeParamsLC(iPublicKey); sl@0: seq->AddAndPopChildL(seqParams); sl@0: subjectPubKeyInfo->AddAndPopChildL(seq); sl@0: sl@0: // Add the key itself to the higher-level sequence as a bit string sl@0: CASN1EncBigInt* pubPart = CASN1EncBigInt::NewLC(iPublicKey.Y()); sl@0: HBufC8* encoding = HBufC8::NewMaxLC(pubPart->LengthDER()); sl@0: TPtr8 encodingPtr = encoding->Des(); sl@0: TUint pos = 0; sl@0: pubPart->WriteDERL(encodingPtr, pos); sl@0: CASN1EncBitString* pubkeyenc = CASN1EncBitString::NewLC(*encoding); sl@0: subjectPubKeyInfo->AddAndPopChildL(pubkeyenc); sl@0: CleanupStack::PopAndDestroy(2); // encoding, pubPart sl@0: return subjectPubKeyInfo; sl@0: } sl@0: sl@0: EXPORT_C CASN1EncSequence* TX509DSAKeyEncoder::EncodeSignatureAlgorithmLC() const sl@0: { sl@0: CASN1EncSequence* seq = CASN1EncSequence::NewLC(); sl@0: CASN1EncObjectIdentifier* oid = NULL; sl@0: sl@0: // Determine OID string for the current combination of algorithms. sl@0: switch(iDigestAlg) sl@0: { sl@0: default: sl@0: User::Leave(KErrNotSupported); sl@0: break; sl@0: sl@0: case ESHA1: sl@0: oid = CASN1EncObjectIdentifier::NewLC(KDSAWithSHA1); sl@0: break; sl@0: } sl@0: sl@0: // Add algorithm OID to the sequence. sl@0: seq->AddAndPopChildL(oid); sl@0: // Insert p, q, and g big parameters into the sequence sl@0: TASN1EncDSAPublicKey keyEnc; sl@0: CASN1EncSequence* params = keyEnc.EncodeParamsLC(iPublicKey); sl@0: seq->AddAndPopChildL(params); sl@0: sl@0: return seq; sl@0: }