--- 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 <x509keys.h>
-#include <asn1dec.h>
-#include <asn1enc.h>
-#include <x509cert.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;
- }
+/*
+* 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 <x509keys.h>
+#include <asn1dec.h>
+#include <asn1enc.h>
+#include <x509cert.h>
+#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;
+ }