diff -r 675a964f4eb5 -r 35751d3474b7 cryptoservices/certificateandkeymgmt/x509/x509keysRSA.cpp --- a/cryptoservices/certificateandkeymgmt/x509/x509keysRSA.cpp Tue Jul 21 01:04:32 2009 +0100 +++ b/cryptoservices/certificateandkeymgmt/x509/x509keysRSA.cpp Thu Sep 10 14:01:51 2009 +0300 @@ -1,292 +1,293 @@ -/* -* Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies). -* All rights reserved. -* This component and the accompanying materials are made available -* under the terms of the License "Eclipse Public License v1.0" -* which accompanies this distribution, and is available -* at the URL "http://www.eclipse.org/legal/epl-v10.html". -* -* Initial Contributors: -* Nokia Corporation - initial contribution. -* -* Contributors: -* -* Description: -* -*/ - - -#include -#include -#include -#include - -CX509RSAPublicKey::CX509RSAPublicKey() -{} - -//RSA public key -EXPORT_C CX509RSAPublicKey* CX509RSAPublicKey::NewL(const TDesC8& aBinaryData) - { - TInt pos = 0; - return CX509RSAPublicKey::NewL(aBinaryData, pos); - } - -EXPORT_C CX509RSAPublicKey* CX509RSAPublicKey::NewLC(const TDesC8& aBinaryData) - { - TInt pos = 0; - return CX509RSAPublicKey::NewLC(aBinaryData, pos); - } - -EXPORT_C CX509RSAPublicKey* CX509RSAPublicKey::NewL(const TDesC8& aBinaryData, TInt& aPos) - { - CX509RSAPublicKey* self = CX509RSAPublicKey::NewLC(aBinaryData, aPos); - CleanupStack::Pop(); - return self; - } - -EXPORT_C CX509RSAPublicKey* CX509RSAPublicKey::NewLC(const TDesC8& aBinaryData, TInt& aPos) - { - CX509RSAPublicKey* self = new(ELeave) CX509RSAPublicKey(); - CleanupStack::PushL(self); - self->ConstructL(aBinaryData, aPos); - return self; - } - -void CX509RSAPublicKey::ConstructL(const TDesC8& aBinaryData, TInt& aPos) - { - TASN1DecGeneric gen(aBinaryData.Right(aBinaryData.Length() - aPos)); - gen.InitL(); - TInt end = aPos + gen.LengthDER(); - aPos += gen.LengthDERHeader(); - if (gen.Tag() != EASN1Sequence) - { - User::Leave(KErrArgument); - } - TASN1DecInteger encInt; - iN = encInt.DecodeDERLongL(aBinaryData, aPos); - iE = encInt.DecodeDERLongL(aBinaryData, aPos); - - // RSA Public keys, modulus and exponent must be positive integers - if(!iN.IsPositive() || !iE.IsPositive()) - { - User::Leave(KErrArgument); - } - if (aPos != end) - { - User::Leave(KErrArgument); - } - } - -// Encodes public key to DER -EXPORT_C HBufC8* TASN1EncRSAPublicKey::EncodeDERL(const CRSAPublicKey& aKey) const - { - CASN1EncSequence* sequence = CASN1EncSequence::NewLC(); - CASN1EncBigInt* encModulus = CASN1EncBigInt::NewLC(aKey.N()); - sequence->AddAndPopChildL(encModulus); - CASN1EncBigInt* encPublicExponent = CASN1EncBigInt::NewLC(aKey.E()); - sequence->AddAndPopChildL(encPublicExponent); - HBufC8* der = HBufC8::NewMaxLC(sequence->LengthDER()); - TUint pos = 0; - TPtr8 derptr(der->Des()); - sequence->WriteDERL(derptr, pos); - CleanupStack::Pop(der); - CleanupStack::PopAndDestroy(sequence); - return der; - } - -// Decodes public key from DER -EXPORT_C CRSAPublicKey* TASN1DecRSAPublicKey::DecodeDERL(const TDesC8& aDER, - TInt& aPos) const - { - // Enter into the containing SEQUENCE and verify if it is indeed there - TASN1DecGeneric gen(aDER.Right(aDER.Length() - aPos)); - gen.InitL(); - TInt end = aPos + gen.LengthDER(); - aPos += gen.LengthDERHeader(); - if (gen.Tag() != EASN1Sequence) - User::Leave(KErrArgument); - - // Decode modulus and public exponent (two large integers) - TASN1DecInteger encInt; - RInteger modulus = encInt.DecodeDERLongL(aDER, aPos); - CleanupStack::PushL(modulus); - RInteger publicExponent = encInt.DecodeDERLongL(aDER, aPos); - CleanupStack::PushL(publicExponent); - if (aPos != end) - User::Leave(KErrArgument); - - // Construct a new key without copying - CRSAPublicKey* key = CRSAPublicKey::NewL(modulus, publicExponent); - CleanupStack::Pop(2); // modulus, publicExponent - owned by public key - return key; - } - -// Decodes RSA key pair from DER-encoded buffer -EXPORT_C void TASN1DecRSAKeyPair::DecodeDERL(const TDesC8& aDER, - TInt& aPos, - CRSAPublicKey*& aPublicKey, - CRSAPrivateKey*& aPrivateKey, - TRSAPrivateKeyType aKeyType /*=EStandardCRT*/) -{ - aPublicKey = NULL; - aPrivateKey = NULL; - - // Enter into the containing SEQUENCE and verify if it is - // indeed there - TASN1DecGeneric gen(aDER.Right(aDER.Length() - aPos)); - gen.InitL(); - TInt end = aPos + gen.LengthDER(); - aPos += gen.LengthDERHeader(); - if (gen.Tag() != EASN1Sequence) - User::Leave(KErrArgument); - - TASN1DecInteger encInt; - - // Decode and discard version, which is an integer - encInt.DecodeDERShortL(aDER, aPos); - - // Decode public key components - - // Decode modulus - RInteger publicModulus = encInt.DecodeDERLongL(aDER, aPos); - CleanupStack::PushL(publicModulus); - - // Decode public exponent - RInteger publicExponent = encInt.DecodeDERLongL(aDER, aPos); - CleanupStack::PushL(publicExponent); - - // Construct public key - CRSAPublicKey* publicKey = CRSAPublicKey::NewL(publicModulus, publicExponent); - CleanupStack::Pop(2, &publicModulus); // Now owned by publicKey - CleanupStack::PushL(publicKey); - - // Decode private key components - - // Copy modulus - RInteger privateModulus = RInteger::NewL(publicKey->N()); - CleanupStack::PushL(privateModulus); - // Decode private exponent - RInteger privateExponent = encInt.DecodeDERLongL(aDER, aPos); - CleanupStack::PushL(privateExponent); - // Decode prime 1 - RInteger p = encInt.DecodeDERLongL(aDER, aPos); - CleanupStack::PushL(p); - // Decode prime 2 - RInteger q = encInt.DecodeDERLongL(aDER, aPos); - CleanupStack::PushL(q); - // Decode exponent 1 - RInteger dmp1 = encInt.DecodeDERLongL(aDER, aPos); - CleanupStack::PushL(dmp1); - // Decode exponent 2 - RInteger dmq1 = encInt.DecodeDERLongL(aDER, aPos); - CleanupStack::PushL(dmq1); - // Decode coefficient - RInteger the_iqmp = encInt.DecodeDERLongL(aDER, aPos); - CleanupStack::PushL(the_iqmp); - - // We now should be at the end of the encoding. If not, the - // input encoding contains extra fields, and they are not - // supported. - if (aPos != end) - User::Leave(KErrArgument); - -// Construct private key - CRSAPrivateKey* privateKey = NULL; - if (EStandardCRT==aKeyType) - { - privateKey = CRSAPrivateKeyCRT::NewL(privateModulus, p, q, dmp1, dmq1, the_iqmp); - } - else if (EStandard==aKeyType) - { - privateKey = CRSAPrivateKeyStandard::NewL(privateModulus, privateExponent); - } - else - User::Leave(KErrNotSupported); - - CleanupStack::Pop(8,publicKey); // publicKey, privateModulus, privateExponent, - // p, q, dmp1, dmq1, iqmp - -// Cleanup the TIntegers not owned by private key objects - if (EStandard==aKeyType) - { - p.Close(); - q.Close(); - dmp1.Close(); - dmq1.Close(); - the_iqmp.Close(); - } - else - { - privateExponent.Close(); - } - - aPublicKey = publicKey; - aPrivateKey = privateKey; -} - -// TX509RSAKeyEncoder Class Implementation - -EXPORT_C TX509RSAKeyEncoder::TX509RSAKeyEncoder(const CRSAPublicKey& aPublicKey, TAlgorithmId aDigestAlg) - : TX509KeyEncoder(aDigestAlg), - iPublicKey(aPublicKey) - { - } - -EXPORT_C CASN1EncBase* TX509RSAKeyEncoder::EncodeKeyLC() const - { - // Create higher-level sequence that will contain OID and the public key - CASN1EncSequence* subjectPubKeyInfo = CASN1EncSequence::NewLC(); - - // The next-level sequence will contain OID of the algorithm followed by NULL - CASN1EncSequence* seq = CASN1EncSequence::NewLC(); - CASN1EncObjectIdentifier* oid = CASN1EncObjectIdentifier::NewLC(KRSA); - seq->AddAndPopChildL(oid); - CASN1EncNull* null = CASN1EncNull::NewLC(); - seq->AddAndPopChildL(null); - subjectPubKeyInfo->AddAndPopChildL(seq); - - // Add the key itself to the higher-level sequence as a bit string - // Obtain a copy of the entity's public key - TASN1EncRSAPublicKey keyencoder; - HBufC8* encoding = keyencoder.EncodeDERL(iPublicKey); - CleanupStack::PushL(encoding); - CASN1EncBitString* pubkeyenc = CASN1EncBitString::NewLC(*encoding); - subjectPubKeyInfo->AddAndPopChildL(pubkeyenc); - CleanupStack::PopAndDestroy(encoding); - return subjectPubKeyInfo; - } - -// Returns ASN.1 sequence containing encoded signature algorithm. -EXPORT_C CASN1EncSequence* TX509RSAKeyEncoder::EncodeSignatureAlgorithmLC() const - { - CASN1EncSequence* seq = CASN1EncSequence::NewLC(); - CASN1EncObjectIdentifier* oid = NULL; - - // Determine OID string for the current combination of algorithms. - switch(iDigestAlg) - { - default: - User::Leave(KErrNotSupported); - break; - - case EMD2: - oid = CASN1EncObjectIdentifier::NewLC(KMD2WithRSA); - break; - - case EMD5: - oid = CASN1EncObjectIdentifier::NewLC(KMD5WithRSA); - break; - - case ESHA1: - oid = CASN1EncObjectIdentifier::NewLC(KSHA1WithRSA); - break; - } - - // Add algorithm OID to the sequence. - seq->AddAndPopChildL(oid); - // Add NULL after OID. - CASN1EncNull* null = CASN1EncNull::NewLC(); - seq->AddAndPopChildL(null); - - return seq; - } +/* +* Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +#include +#include +#include +#include +#include "x509keyencoder.h" + +CX509RSAPublicKey::CX509RSAPublicKey() +{} + +//RSA public key +EXPORT_C CX509RSAPublicKey* CX509RSAPublicKey::NewL(const TDesC8& aBinaryData) + { + TInt pos = 0; + return CX509RSAPublicKey::NewL(aBinaryData, pos); + } + +EXPORT_C CX509RSAPublicKey* CX509RSAPublicKey::NewLC(const TDesC8& aBinaryData) + { + TInt pos = 0; + return CX509RSAPublicKey::NewLC(aBinaryData, pos); + } + +EXPORT_C CX509RSAPublicKey* CX509RSAPublicKey::NewL(const TDesC8& aBinaryData, TInt& aPos) + { + CX509RSAPublicKey* self = CX509RSAPublicKey::NewLC(aBinaryData, aPos); + CleanupStack::Pop(); + return self; + } + +EXPORT_C CX509RSAPublicKey* CX509RSAPublicKey::NewLC(const TDesC8& aBinaryData, TInt& aPos) + { + CX509RSAPublicKey* self = new(ELeave) CX509RSAPublicKey(); + CleanupStack::PushL(self); + self->ConstructL(aBinaryData, aPos); + return self; + } + +void CX509RSAPublicKey::ConstructL(const TDesC8& aBinaryData, TInt& aPos) + { + TASN1DecGeneric gen(aBinaryData.Right(aBinaryData.Length() - aPos)); + gen.InitL(); + TInt end = aPos + gen.LengthDER(); + aPos += gen.LengthDERHeader(); + if (gen.Tag() != EASN1Sequence) + { + User::Leave(KErrArgument); + } + TASN1DecInteger encInt; + iN = encInt.DecodeDERLongL(aBinaryData, aPos); + iE = encInt.DecodeDERLongL(aBinaryData, aPos); + + // RSA Public keys, modulus and exponent must be positive integers + if(!iN.IsPositive() || !iE.IsPositive()) + { + User::Leave(KErrArgument); + } + if (aPos != end) + { + User::Leave(KErrArgument); + } + } + +// Encodes public key to DER +EXPORT_C HBufC8* TASN1EncRSAPublicKey::EncodeDERL(const CRSAPublicKey& aKey) const + { + CASN1EncSequence* sequence = CASN1EncSequence::NewLC(); + CASN1EncBigInt* encModulus = CASN1EncBigInt::NewLC(aKey.N()); + sequence->AddAndPopChildL(encModulus); + CASN1EncBigInt* encPublicExponent = CASN1EncBigInt::NewLC(aKey.E()); + sequence->AddAndPopChildL(encPublicExponent); + HBufC8* der = HBufC8::NewMaxLC(sequence->LengthDER()); + TUint pos = 0; + TPtr8 derptr(der->Des()); + sequence->WriteDERL(derptr, pos); + CleanupStack::Pop(der); + CleanupStack::PopAndDestroy(sequence); + return der; + } + +// Decodes public key from DER +EXPORT_C CRSAPublicKey* TASN1DecRSAPublicKey::DecodeDERL(const TDesC8& aDER, + TInt& aPos) const + { + // Enter into the containing SEQUENCE and verify if it is indeed there + TASN1DecGeneric gen(aDER.Right(aDER.Length() - aPos)); + gen.InitL(); + TInt end = aPos + gen.LengthDER(); + aPos += gen.LengthDERHeader(); + if (gen.Tag() != EASN1Sequence) + User::Leave(KErrArgument); + + // Decode modulus and public exponent (two large integers) + TASN1DecInteger encInt; + RInteger modulus = encInt.DecodeDERLongL(aDER, aPos); + CleanupStack::PushL(modulus); + RInteger publicExponent = encInt.DecodeDERLongL(aDER, aPos); + CleanupStack::PushL(publicExponent); + if (aPos != end) + User::Leave(KErrArgument); + + // Construct a new key without copying + CRSAPublicKey* key = CRSAPublicKey::NewL(modulus, publicExponent); + CleanupStack::Pop(2); // modulus, publicExponent - owned by public key + return key; + } + +// Decodes RSA key pair from DER-encoded buffer +EXPORT_C void TASN1DecRSAKeyPair::DecodeDERL(const TDesC8& aDER, + TInt& aPos, + CRSAPublicKey*& aPublicKey, + CRSAPrivateKey*& aPrivateKey, + TRSAPrivateKeyType aKeyType /*=EStandardCRT*/) +{ + aPublicKey = NULL; + aPrivateKey = NULL; + + // Enter into the containing SEQUENCE and verify if it is + // indeed there + TASN1DecGeneric gen(aDER.Right(aDER.Length() - aPos)); + gen.InitL(); + TInt end = aPos + gen.LengthDER(); + aPos += gen.LengthDERHeader(); + if (gen.Tag() != EASN1Sequence) + User::Leave(KErrArgument); + + TASN1DecInteger encInt; + + // Decode and discard version, which is an integer + encInt.DecodeDERShortL(aDER, aPos); + + // Decode public key components + + // Decode modulus + RInteger publicModulus = encInt.DecodeDERLongL(aDER, aPos); + CleanupStack::PushL(publicModulus); + + // Decode public exponent + RInteger publicExponent = encInt.DecodeDERLongL(aDER, aPos); + CleanupStack::PushL(publicExponent); + + // Construct public key + CRSAPublicKey* publicKey = CRSAPublicKey::NewL(publicModulus, publicExponent); + CleanupStack::Pop(2, &publicModulus); // Now owned by publicKey + CleanupStack::PushL(publicKey); + + // Decode private key components + + // Copy modulus + RInteger privateModulus = RInteger::NewL(publicKey->N()); + CleanupStack::PushL(privateModulus); + // Decode private exponent + RInteger privateExponent = encInt.DecodeDERLongL(aDER, aPos); + CleanupStack::PushL(privateExponent); + // Decode prime 1 + RInteger p = encInt.DecodeDERLongL(aDER, aPos); + CleanupStack::PushL(p); + // Decode prime 2 + RInteger q = encInt.DecodeDERLongL(aDER, aPos); + CleanupStack::PushL(q); + // Decode exponent 1 + RInteger dmp1 = encInt.DecodeDERLongL(aDER, aPos); + CleanupStack::PushL(dmp1); + // Decode exponent 2 + RInteger dmq1 = encInt.DecodeDERLongL(aDER, aPos); + CleanupStack::PushL(dmq1); + // Decode coefficient + RInteger the_iqmp = encInt.DecodeDERLongL(aDER, aPos); + CleanupStack::PushL(the_iqmp); + + // We now should be at the end of the encoding. If not, the + // input encoding contains extra fields, and they are not + // supported. + if (aPos != end) + User::Leave(KErrArgument); + +// Construct private key + CRSAPrivateKey* privateKey = NULL; + if (EStandardCRT==aKeyType) + { + privateKey = CRSAPrivateKeyCRT::NewL(privateModulus, p, q, dmp1, dmq1, the_iqmp); + } + else if (EStandard==aKeyType) + { + privateKey = CRSAPrivateKeyStandard::NewL(privateModulus, privateExponent); + } + else + User::Leave(KErrNotSupported); + + CleanupStack::Pop(8,publicKey); // publicKey, privateModulus, privateExponent, + // p, q, dmp1, dmq1, iqmp + +// Cleanup the TIntegers not owned by private key objects + if (EStandard==aKeyType) + { + p.Close(); + q.Close(); + dmp1.Close(); + dmq1.Close(); + the_iqmp.Close(); + } + else + { + privateExponent.Close(); + } + + aPublicKey = publicKey; + aPrivateKey = privateKey; +} + +// TX509RSAKeyEncoder Class Implementation + +EXPORT_C TX509RSAKeyEncoder::TX509RSAKeyEncoder(const CRSAPublicKey& aPublicKey, TAlgorithmId aDigestAlg) + : TX509KeyEncoder(aDigestAlg), + iPublicKey(aPublicKey) + { + } + +EXPORT_C CASN1EncBase* TX509RSAKeyEncoder::EncodeKeyLC() const + { + // Create higher-level sequence that will contain OID and the public key + CASN1EncSequence* subjectPubKeyInfo = CASN1EncSequence::NewLC(); + + // The next-level sequence will contain OID of the algorithm followed by NULL + CASN1EncSequence* seq = CASN1EncSequence::NewLC(); + CASN1EncObjectIdentifier* oid = CASN1EncObjectIdentifier::NewLC(KRSA); + seq->AddAndPopChildL(oid); + CASN1EncNull* null = CASN1EncNull::NewLC(); + seq->AddAndPopChildL(null); + subjectPubKeyInfo->AddAndPopChildL(seq); + + // Add the key itself to the higher-level sequence as a bit string + // Obtain a copy of the entity's public key + TASN1EncRSAPublicKey keyencoder; + HBufC8* encoding = keyencoder.EncodeDERL(iPublicKey); + CleanupStack::PushL(encoding); + CASN1EncBitString* pubkeyenc = CASN1EncBitString::NewLC(*encoding); + subjectPubKeyInfo->AddAndPopChildL(pubkeyenc); + CleanupStack::PopAndDestroy(encoding); + return subjectPubKeyInfo; + } + +// Returns ASN.1 sequence containing encoded signature algorithm. +EXPORT_C CASN1EncSequence* TX509RSAKeyEncoder::EncodeSignatureAlgorithmLC() const + { + CASN1EncSequence* seq = CASN1EncSequence::NewLC(); + CASN1EncObjectIdentifier* oid = NULL; + + // Determine OID string for the current combination of algorithms. + switch(iDigestAlg) + { + default: + User::Leave(KErrNotSupported); + break; + + case EMD2: + oid = CASN1EncObjectIdentifier::NewLC(KMD2WithRSA); + break; + + case EMD5: + oid = CASN1EncObjectIdentifier::NewLC(KMD5WithRSA); + break; + + case ESHA1: + oid = CASN1EncObjectIdentifier::NewLC(KSHA1WithRSA); + break; + } + + // Add algorithm OID to the sequence. + seq->AddAndPopChildL(oid); + // Add NULL after OID. + CASN1EncNull* null = CASN1EncNull::NewLC(); + seq->AddAndPopChildL(null); + + return seq; + }