--- a/cryptoservices/certificateandkeymgmt/pkcs7/cmsutils.cpp Tue Jul 21 01:04:32 2009 +0100
+++ b/cryptoservices/certificateandkeymgmt/pkcs7/cmsutils.cpp Thu Sep 10 14:01:51 2009 +0300
@@ -1,417 +1,441 @@
-/*
-* Copyright (c) 2006-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 "cmsutils.h"
-#include <asymmetric.h>
-#include <asn1enc.h>
-#include <asn1dec.h>
-#include <cmsdefs.h>
-#include <pkcs7excert.h>
-#include <x509cert.h>
-#include "pkcs7asn1.h"
-
-
-TInt CmsUtils::DecodeContentTypeL(const TASN1DecGeneric* aASN1DecGeneric)
- {
- TInt type(0);
- if(aASN1DecGeneric->Tag()==EASN1ObjectIdentifier || aASN1DecGeneric->Class() == EUniversal)
- {
- TASN1DecObjectIdentifier oidDec;
- HBufC* oidVal = oidDec.DecodeDERL(*aASN1DecGeneric);
- CleanupStack::PushL(oidVal);
-
- // Checks if it is data OID.
- if(*oidVal == KCmsDataOID)
- {
- // The Content Type is indicated by an Integer.
- // Here if Content Type is equal to Data then,it is represented by 1
- type = EContentTypeData;
- }
- else if(*oidVal == KCmsSignedDataOID)
- {
- // The Content Type is indicated by an Integer.
- // Here if Content Type is equal to SignedData then,it is represented by 2
- type = EContentTypeSignedData;
- }
- else if(*oidVal == KCmsEnvelopedDataOID)
- {
- // The Content Type is indicated by an Integer.
- // Here if Content Type is equal to EnvelopedData then,it is represented by 3.
- type = EContentTypeEnvelopedData;
- }
- else if(*oidVal == KCmsDigestedDataOID)
- {
- // The Content Type is indicated by an Integer.
- // Here if Content Type is equal to DigestedData then,it is represented by 5.
- type = EContentTypeDigestedData;
- }
- else if(*oidVal == KCmsEncryptedDataOID)
- {
- // The Content Type is indicated by an Integer.
- // Here if Content Type is equal to EncryptedData then,it is represented by 6
- type = EContentTypeEncryptedData;
- }
- else if(*oidVal == KCmsAuthenticatedDataOID)
- {
- // The Content Type is indicated by an Integer.
- // Here if Content Type is equal to EncryptedData then,it is represented by 7
- type = EContentTypeAuthenticatedData;
- }
-
- else
- {
- User::Leave(KErrArgument);
- }
- CleanupStack::PopAndDestroy(oidVal);
- }
- else
- {
- User::Leave(KErrArgument);
- }
- return type;
- }
-
-CASN1EncObjectIdentifier* CmsUtils::EncodeContentTypeLC(TInt aContentType)
- {
- TPtrC oidBuf;
- switch (aContentType)
- {
- case EContentTypeData:
- oidBuf.Set(KCmsDataOID());
- break;
-
- case EContentTypeSignedData:
- oidBuf.Set(KCmsSignedDataOID());
- break;
-
- case EContentTypeEnvelopedData:
- oidBuf.Set(KCmsEnvelopedDataOID());
- break;
-
- case EContentTypeDigestedData:
- oidBuf.Set(KCmsDigestedDataOID());
- break;
-
- case EContentTypeEncryptedData:
- oidBuf.Set(KCmsEncryptedDataOID());
- break;
-
- default:
- User::Leave(KErrArgument);
- }
- //Encode the OID
- CASN1EncObjectIdentifier* oid=CASN1EncObjectIdentifier::NewLC(oidBuf);
- return oid;
- }
-
-void CmsUtils::AddCertificateL(RPointerArray<CCmsCertificateChoice>& aCertList, const TDesC8& aCert, CCmsCertificateChoice::TCertificateType aType)
- {
- TInt found(EFalse);
- TInt count=aCertList.Count();
- for (TInt i=0;i<count;i++)
- {
- if (aCertList[i]->CertificateType()==CCmsCertificateChoice::ECertificateAttribute
- && aCert.Compare(*aCertList[i]->AttributeCertificate())==0)
- {
- found=ETrue;
- break;
- }
- }
-
- if (!found)
- {
- CCmsCertificateChoice* cert=CCmsCertificateChoice::NewL(aType, aCert);
- CleanupStack::PushL(cert);
- aCertList.AppendL(cert);
- CleanupStack::Pop(cert);
- }
- }
-
-void CmsUtils::AddCertificateL(RPointerArray<CCmsCertificateChoice>& aCertList, const CX509Certificate& aCert)
- {
-
- TInt found(EFalse);
- TInt count=aCertList.Count();
- for (TInt i=0;i<count;i++)
- {
- if (aCertList[i]->CertificateType()==CCmsCertificateChoice::ECertificateX509
- && aCert.IsEqualL(aCertList[i]->Certificate()))
- {
- found=ETrue;
- break;
- }
- }
-
- if (!found)
- {
- CCmsCertificateChoice* cert=CCmsCertificateChoice::NewL(aCert);
- CleanupStack::PushL(cert);
- aCertList.AppendL(cert);
- CleanupStack::Pop(cert);
- }
-
- }
-
-void CmsUtils::AddAlgorithmIdentifierL(RPointerArray<CX509AlgorithmIdentifier>& aAlgorithmIdList, TAlgorithmId aDigestAlgorithm)
- {
- TInt found(EFalse);
- TInt count=aAlgorithmIdList.Count();
- for (TInt i=0;i<count;i++)
- {
- if (aAlgorithmIdList[i]->Algorithm()==aDigestAlgorithm)
- {
- found=ETrue;
- break;
- }
- }
- if (!found)
- {
- CX509AlgorithmIdentifier* digAlg=CX509AlgorithmIdentifier::NewLC(aDigestAlgorithm, KNullDesC8());
- aAlgorithmIdList.AppendL(digAlg);
- CleanupStack::Pop(digAlg);
- }
- }
-
-void CmsUtils::DecodeDigestAlgorithmsL(RPointerArray<CX509AlgorithmIdentifier>& aDigestAlgorithms, const TDesC8& aRawData)
- {
- CArrayPtr<TASN1DecGeneric>* algsData = PKCS7ASN1::DecodeSequenceLC(aRawData);
- TInt count = algsData->Count();
- CX509AlgorithmIdentifier* alIdent;
-
- for(TInt item = 0; item < count; item++)
- {
- alIdent = CX509AlgorithmIdentifier::NewLC(algsData->At(item)->Encoding());
- aDigestAlgorithms.AppendL(alIdent);
- CleanupStack::Pop(alIdent);
- }
- CleanupStack::PopAndDestroy(algsData);
- }
-
-void CmsUtils::DecodeCertificatesL(RPointerArray<CCmsCertificateChoice>& aCertificates, const TDesC8& aRawData)
- {
- TASN1DecGeneric decGen(aRawData);
- decGen.InitL();
- TASN1DecSequence decSeq;
- // have to do manual decoding of sequence because field is optional
- CArrayPtr<TASN1DecGeneric>* items = NULL;
- items = decSeq.DecodeDERLC(decGen);
- TInt count = items->Count();
-
- CCmsCertificateChoice* certificate;
-
- for(TInt item = 0; item < count; item++)
- {
- certificate = CCmsCertificateChoice::NewL(items->At(item)->Encoding());
- CleanupStack::PushL(certificate);
- aCertificates.AppendL(certificate);
- CleanupStack::Pop(certificate);
- }
-
- CleanupStack::PopAndDestroy(items);
- }
-
-CASN1EncBase* CmsUtils::EncodeCertificatesLC(const RPointerArray<CCmsCertificateChoice>& aCertificates)
- {
- CASN1EncSet* certSet(NULL);
- TInt count=aCertificates.Count();
- if (count>0)
- {
- certSet = CASN1EncSet::NewLC();
- for (TInt i=0;i<count;i++)
- {
- CASN1EncEncoding* cert=aCertificates[i]->EncodeASN1DERLC();
- certSet->AddAndPopChildL(cert);
- }
- // [0] implicit
- certSet->SetTag(0);
- }
- return certSet;
- }
-
-CASN1EncBase* CmsUtils::EncodeDigestAlgorithmsLC(const RPointerArray<CX509AlgorithmIdentifier>& aDigestAlgorithms)
- {
- CASN1EncSet* algorithmSet = CASN1EncSet::NewLC();
- TInt count=aDigestAlgorithms.Count();
-
- for (TInt i=0;i<count;i++)
- {
- CASN1EncSequence* tmp=aDigestAlgorithms[i]->EncodeASN1DERLC();
- algorithmSet->AddAndPopChildL(tmp);
- }
-
- return algorithmSet;
- }
-
-void CmsUtils::DecodeOctetStringL(const TDesC8& aRawData, HBufC8*& aBuf)
- {
- TASN1DecGeneric decGen(aRawData);
- decGen.InitL();
-
- if(decGen.Tag()==EASN1OctetString && decGen.Class()==EUniversal)
- {
- TASN1DecOctetString decOct;
- aBuf = decOct.DecodeDERL(decGen);
- }
- else
- {
- User::Leave(KErrArgument);
- }
- }
-
-
-CMessageDigest* CmsUtils::CreateHashLC(TAlgorithmId aAlgorithm)
- {
- CMessageDigest* hash(NULL);
- switch (aAlgorithm)
- {
- case EMD2:
- hash=CMD2::NewL();
- break;
-
- case EMD5:
- hash=CMD5::NewL();
- break;
-
- case ESHA1:
- hash=CSHA1::NewL();
- break;
-
- default:
- User::Leave(KErrNotSupported);
- }
- CleanupStack::PushL(hash);
- return hash;
- }
-
-
-HBufC8* CmsUtils::CreateSignatureL(const TDesC8& aDataToBeSigned, TBool aIsHash, TAlgorithmId aAlgorithm, const CDSAPrivateKey& aKey)
- {
- HBufC8* signature(NULL);
-
- if (!aIsHash)
- {
- TPtrC8 hashValue;
- // Create hash first
- CMessageDigest* hash=CreateHashLC(aAlgorithm);
- hashValue.Set(hash->Hash(aDataToBeSigned));
- signature=CreateSignatureL(hashValue, aKey);
- CleanupStack::PopAndDestroy(); // hash
- }
- else
- {
- signature=CreateSignatureL(aDataToBeSigned, aKey);
- }
-
- return signature;
- }
-
-HBufC8* CmsUtils::CreateSignatureL(const TDesC8& aDataToBeSigned, TBool aIsHash, TAlgorithmId aAlgorithm, const CRSAPrivateKey& aKey)
- {
- HBufC8* signature(NULL);
- TPtrC8 hashValue;
- if (!aIsHash)
- {
- // Create hash first
- CMessageDigest* hash=CreateHashLC(aAlgorithm);
- hashValue.Set(hash->Hash(aDataToBeSigned));
- }
- else
- {
- hashValue.Set(aDataToBeSigned);
- }
-
- //Build the digestInfo Sequence
- CASN1EncSequence* digestInfoSeq = CASN1EncSequence::NewLC();
-
- //Encode the Algorithm
- CX509AlgorithmIdentifier* digAlg=CX509AlgorithmIdentifier::NewLC(aAlgorithm, KNullDesC8());
- CASN1EncSequence* sigAlg=digAlg->EncodeASN1DERLC();
- digestInfoSeq->AddAndPopChildL(sigAlg);
- CleanupStack::PopAndDestroy(digAlg);
-
- //Encode the digest itself
- CASN1EncOctetString* sigEnc=CASN1EncOctetString::NewLC(hashValue);
- digestInfoSeq->AddAndPopChildL(sigEnc);
-
- //Get the Encoding
- HBufC8* digestInfo=CreateDEREncodingLC(*digestInfoSeq);
- signature=CreateSignatureL(digestInfo->Des(), aKey);
-
- CleanupStack::PopAndDestroy(2, digestInfoSeq); //digestInfo, digestInfoSeq
- if (!aIsHash)
- {
- CleanupStack::PopAndDestroy(); // hash
- }
- return signature;
- }
-
-HBufC8* CmsUtils::CreateSignatureL(const TDesC8& aHash, const CDSAPrivateKey& aKey)
- {
- //Create Signer and sign the hash
- CDSASigner* signer=CDSASigner::NewLC(aKey);
- const CDSASignature* sig=signer->SignL(aHash);
- CDSASignature* signonc=const_cast<CDSASignature*>(sig);
-
- CleanupStack::PushL(signonc);
-
- //The sequence
- CASN1EncSequence* sigSeq = CASN1EncSequence::NewLC();
- CASN1EncBigInt* r = CASN1EncBigInt::NewLC(static_cast<const RInteger&>(sig->R()));
- sigSeq->AddAndPopChildL(r);
- CASN1EncBigInt* s = CASN1EncBigInt::NewLC(static_cast<const RInteger&>(sig->S()));
- sigSeq->AddAndPopChildL(s);
-
- //Write the buffer
- TUint len=sigSeq->LengthDER();
- HBufC8* buf=HBufC8::NewMaxLC(len);
- TPtr8 des=buf->Des();
- TUint pos=0;
- sigSeq->WriteDERL(des, pos);
-
- //Clean up
- CleanupStack::Pop(buf); //buf
- CleanupStack::PopAndDestroy(3, signer); //sigSeq, signonc, signer
- return buf;
- }
-
-HBufC8* CmsUtils::CreateSignatureL(const TDesC8& aHash, const CRSAPrivateKey& aKey)
- {
- //Create Signer and sign the hash
- CRSAPKCS1v15Signer* signer=CRSAPKCS1v15Signer::NewLC(aKey);
- const CRSASignature* sig=signer->SignL(aHash);
- CRSASignature* signonc=const_cast<CRSASignature*>(sig);
-
- CleanupStack::PushL(signonc);
-
- HBufC8* sigData = sig->S().BufferWithNoTruncationLC();
-
- //Clean up
- CleanupStack::Pop(sigData);
- CleanupStack::PopAndDestroy(2, signer);//signonc signer
- return sigData;
- }
-
-HBufC8* CmsUtils::CreateDEREncodingLC(const CASN1EncBase& aEncoding)
- {
- TUint len = aEncoding.LengthDER();
- HBufC8* buf = HBufC8::NewMaxLC(len);
- TUint pos = 0;
- TPtr8 bufptr(buf->Des());
- aEncoding.WriteDERL(bufptr, pos);
- return buf;
- }
+/*
+* Copyright (c) 2006-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 "cmsutils.h"
+#include <asymmetric.h>
+#include <asn1enc.h>
+#include <asn1dec.h>
+#include <cmsdefs.h>
+#include <pkcs7excert.h>
+#include <x509cert.h>
+#include "pkcs7asn1.h"
+
+
+TInt CmsUtils::DecodeContentTypeL(const TASN1DecGeneric* aASN1DecGeneric)
+ {
+ TInt type(0);
+ if(aASN1DecGeneric->Tag()==EASN1ObjectIdentifier || aASN1DecGeneric->Class() == EUniversal)
+ {
+ TASN1DecObjectIdentifier oidDec;
+ HBufC* oidVal = oidDec.DecodeDERL(*aASN1DecGeneric);
+ CleanupStack::PushL(oidVal);
+
+ // Checks if it is data OID.
+ if(*oidVal == KCmsDataOID)
+ {
+ // The Content Type is indicated by an Integer.
+ // Here if Content Type is equal to Data then,it is represented by 1
+ type = EContentTypeData;
+ }
+ else if(*oidVal == KCmsSignedDataOID)
+ {
+ // The Content Type is indicated by an Integer.
+ // Here if Content Type is equal to SignedData then,it is represented by 2
+ type = EContentTypeSignedData;
+ }
+ else if(*oidVal == KCmsEnvelopedDataOID)
+ {
+ // The Content Type is indicated by an Integer.
+ // Here if Content Type is equal to EnvelopedData then,it is represented by 3.
+ type = EContentTypeEnvelopedData;
+ }
+ else if(*oidVal == KCmsDigestedDataOID)
+ {
+ // The Content Type is indicated by an Integer.
+ // Here if Content Type is equal to DigestedData then,it is represented by 5.
+ type = EContentTypeDigestedData;
+ }
+ else if(*oidVal == KCmsEncryptedDataOID)
+ {
+ // The Content Type is indicated by an Integer.
+ // Here if Content Type is equal to EncryptedData then,it is represented by 6
+ type = EContentTypeEncryptedData;
+ }
+ else if(*oidVal == KCmsAuthenticatedDataOID)
+ {
+ // The Content Type is indicated by an Integer.
+ // Here if Content Type is equal to EncryptedData then,it is represented by 7
+ type = EContentTypeAuthenticatedData;
+ }
+
+ else
+ {
+ User::Leave(KErrArgument);
+ }
+ CleanupStack::PopAndDestroy(oidVal);
+ }
+ else
+ {
+ User::Leave(KErrArgument);
+ }
+ return type;
+ }
+
+CASN1EncObjectIdentifier* CmsUtils::EncodeContentTypeLC(TInt aContentType)
+ {
+ TPtrC oidBuf;
+ switch (aContentType)
+ {
+ case EContentTypeData:
+ oidBuf.Set(KCmsDataOID());
+ break;
+
+ case EContentTypeSignedData:
+ oidBuf.Set(KCmsSignedDataOID());
+ break;
+
+ case EContentTypeEnvelopedData:
+ oidBuf.Set(KCmsEnvelopedDataOID());
+ break;
+
+ case EContentTypeDigestedData:
+ oidBuf.Set(KCmsDigestedDataOID());
+ break;
+
+ case EContentTypeEncryptedData:
+ oidBuf.Set(KCmsEncryptedDataOID());
+ break;
+
+ default:
+ User::Leave(KErrArgument);
+ }
+ //Encode the OID
+ CASN1EncObjectIdentifier* oid=CASN1EncObjectIdentifier::NewLC(oidBuf);
+ return oid;
+ }
+
+void CmsUtils::AddCertificateL(RPointerArray<CCmsCertificateChoice>& aCertList, const TDesC8& aCert, CCmsCertificateChoice::TCertificateType aType)
+ {
+ TInt found(EFalse);
+ TInt count=aCertList.Count();
+ for (TInt i=0;i<count;i++)
+ {
+ if (aCertList[i]->CertificateType()==CCmsCertificateChoice::ECertificateAttribute
+ && aCert.Compare(*aCertList[i]->AttributeCertificate())==0)
+ {
+ found=ETrue;
+ break;
+ }
+ }
+
+ if (!found)
+ {
+ CCmsCertificateChoice* cert=CCmsCertificateChoice::NewL(aType, aCert);
+ CleanupStack::PushL(cert);
+ aCertList.AppendL(cert);
+ CleanupStack::Pop(cert);
+ }
+ }
+
+void CmsUtils::AddCertificateL(RPointerArray<CCmsCertificateChoice>& aCertList, const CX509Certificate& aCert)
+ {
+
+ TInt found(EFalse);
+ TInt count=aCertList.Count();
+ for (TInt i=0;i<count;i++)
+ {
+ if (aCertList[i]->CertificateType()==CCmsCertificateChoice::ECertificateX509
+ && aCert.IsEqualL(aCertList[i]->Certificate()))
+ {
+ found=ETrue;
+ break;
+ }
+ }
+
+ if (!found)
+ {
+ CCmsCertificateChoice* cert=CCmsCertificateChoice::NewL(aCert);
+ CleanupStack::PushL(cert);
+ aCertList.AppendL(cert);
+ CleanupStack::Pop(cert);
+ }
+
+ }
+
+void CmsUtils::AddAlgorithmIdentifierL(RPointerArray<CX509AlgorithmIdentifier>& aAlgorithmIdList, TAlgorithmId aDigestAlgorithm)
+ {
+ TInt found(EFalse);
+ TInt count=aAlgorithmIdList.Count();
+ for (TInt i=0;i<count;i++)
+ {
+ if (aAlgorithmIdList[i]->Algorithm()==aDigestAlgorithm)
+ {
+ found=ETrue;
+ break;
+ }
+ }
+ if (!found)
+ {
+ CX509AlgorithmIdentifier* digAlg=CX509AlgorithmIdentifier::NewLC(aDigestAlgorithm, KNullDesC8());
+ aAlgorithmIdList.AppendL(digAlg);
+ CleanupStack::Pop(digAlg);
+ }
+ }
+
+void CmsUtils::DecodeDigestAlgorithmsL(RPointerArray<CX509AlgorithmIdentifier>& aDigestAlgorithms, const TDesC8& aRawData)
+ {
+ CArrayPtr<TASN1DecGeneric>* algsData = PKCS7ASN1::DecodeSequenceLC(aRawData);
+ TInt count = algsData->Count();
+ CX509AlgorithmIdentifier* alIdent;
+
+ for(TInt item = 0; item < count; item++)
+ {
+ alIdent = CX509AlgorithmIdentifier::NewLC(algsData->At(item)->Encoding());
+ aDigestAlgorithms.AppendL(alIdent);
+ CleanupStack::Pop(alIdent);
+ }
+ CleanupStack::PopAndDestroy(algsData);
+ }
+
+void CmsUtils::DecodeCertificatesL(RPointerArray<CCmsCertificateChoice>& aCertificates, const TDesC8& aRawData)
+ {
+ TASN1DecGeneric decGen(aRawData);
+ decGen.InitL();
+ TASN1DecSequence decSeq;
+ // have to do manual decoding of sequence because field is optional
+ CArrayPtr<TASN1DecGeneric>* items = NULL;
+ items = decSeq.DecodeDERLC(decGen);
+ TInt count = items->Count();
+
+ CCmsCertificateChoice* certificate;
+
+ for(TInt item = 0; item < count; item++)
+ {
+ certificate = CCmsCertificateChoice::NewL(items->At(item)->Encoding());
+ CleanupStack::PushL(certificate);
+ aCertificates.AppendL(certificate);
+ CleanupStack::Pop(certificate);
+ }
+
+ CleanupStack::PopAndDestroy(items);
+ }
+
+CASN1EncBase* CmsUtils::EncodeCertificatesLC(const RPointerArray<CCmsCertificateChoice>& aCertificates)
+ {
+ CASN1EncSet* certSet(NULL);
+ TInt count=aCertificates.Count();
+ if (count>0)
+ {
+ certSet = CASN1EncSet::NewLC();
+ for (TInt i=0;i<count;i++)
+ {
+ CASN1EncEncoding* cert=aCertificates[i]->EncodeASN1DERLC();
+ certSet->AddAndPopChildL(cert);
+ }
+ // [0] implicit
+ certSet->SetTag(0);
+ }
+ return certSet;
+ }
+
+CASN1EncBase* CmsUtils::EncodeDigestAlgorithmsLC(const RPointerArray<CX509AlgorithmIdentifier>& aDigestAlgorithms)
+ {
+ CASN1EncSet* algorithmSet = CASN1EncSet::NewLC();
+ TInt count=aDigestAlgorithms.Count();
+
+ for (TInt i=0;i<count;i++)
+ {
+ CASN1EncSequence* tmp=aDigestAlgorithms[i]->EncodeASN1DERLC();
+ algorithmSet->AddAndPopChildL(tmp);
+ }
+
+ return algorithmSet;
+ }
+
+void CmsUtils::DecodeOctetStringL(const TDesC8& aRawData, HBufC8*& aBuf)
+ {
+ TASN1DecGeneric decGen(aRawData);
+ decGen.InitL();
+
+ if(decGen.Tag()==EASN1OctetString && decGen.Class()==EUniversal)
+ {
+ TASN1DecOctetString decOct;
+ aBuf = decOct.DecodeDERL(decGen);
+ }
+ else
+ {
+ User::Leave(KErrArgument);
+ }
+ }
+
+
+CMessageDigest* CmsUtils::CreateHashLC(TAlgorithmId aAlgorithm)
+ {
+ CMessageDigest* hash(NULL);
+ switch (aAlgorithm)
+ {
+ case EMD2:
+ hash=CMD2::NewL();
+ break;
+
+ case EMD5:
+ hash=CMD5::NewL();
+ break;
+
+ case ESHA1:
+ hash=CSHA1::NewL();
+ break;
+
+ default:
+ User::Leave(KErrNotSupported);
+ }
+ CleanupStack::PushL(hash);
+ return hash;
+ }
+
+
+HBufC8* CmsUtils::CreateSignatureL(const TDesC8& aDataToBeSigned, TBool aIsHash, TAlgorithmId aAlgorithm, const CDSAPrivateKey& aKey)
+ {
+ HBufC8* signature(NULL);
+
+ if (!aIsHash)
+ {
+ TPtrC8 hashValue;
+ // Create hash first
+ CMessageDigest* hash=CreateHashLC(aAlgorithm);
+ hashValue.Set(hash->Hash(aDataToBeSigned));
+ signature=CreateSignatureL(hashValue, aKey);
+ CleanupStack::PopAndDestroy(); // hash
+ }
+ else
+ {
+ signature=CreateSignatureL(aDataToBeSigned, aKey);
+ }
+
+ return signature;
+ }
+
+HBufC8* CmsUtils::CreateSignatureL(const TDesC8& aDataToBeSigned, TBool aIsHash, TAlgorithmId aAlgorithm, const CRSAPrivateKey& aKey)
+ {
+ HBufC8* signature(NULL);
+ TPtrC8 hashValue;
+ if (!aIsHash)
+ {
+ // Create hash first
+ CMessageDigest* hash=CreateHashLC(aAlgorithm);
+ hashValue.Set(hash->Hash(aDataToBeSigned));
+ }
+ else
+ {
+ hashValue.Set(aDataToBeSigned);
+ }
+
+ //Build the digestInfo Sequence
+ CASN1EncSequence* digestInfoSeq = CASN1EncSequence::NewLC();
+
+ //Encode the Algorithm
+ CX509AlgorithmIdentifier* digAlg=CX509AlgorithmIdentifier::NewLC(aAlgorithm, KNullDesC8());
+ CASN1EncSequence* sigAlg=digAlg->EncodeASN1DERLC();
+ digestInfoSeq->AddAndPopChildL(sigAlg);
+ CleanupStack::PopAndDestroy(digAlg);
+
+ //Encode the digest itself
+ CASN1EncOctetString* sigEnc=CASN1EncOctetString::NewLC(hashValue);
+ digestInfoSeq->AddAndPopChildL(sigEnc);
+
+ //Get the Encoding
+ HBufC8* digestInfo=CreateDEREncodingLC(*digestInfoSeq);
+ signature=CreateSignatureL(digestInfo->Des(), aKey);
+
+ CleanupStack::PopAndDestroy(2, digestInfoSeq); //digestInfo, digestInfoSeq
+ if (!aIsHash)
+ {
+ CleanupStack::PopAndDestroy(); // hash
+ }
+ return signature;
+ }
+
+HBufC8* CmsUtils::CreateSignatureL(const TDesC8& aHash, const CDSAPrivateKey& aKey)
+ {
+ //Create Signer and sign the hash
+ CDSASigner* signer=CDSASigner::NewLC(aKey);
+ const CDSASignature* sig=signer->SignL(aHash);
+ CDSASignature* signonc=const_cast<CDSASignature*>(sig);
+
+ CleanupStack::PushL(signonc);
+
+ //The sequence
+ CASN1EncSequence* sigSeq = CASN1EncSequence::NewLC();
+ CASN1EncBigInt* r = CASN1EncBigInt::NewLC(static_cast<const RInteger&>(sig->R()));
+ sigSeq->AddAndPopChildL(r);
+ CASN1EncBigInt* s = CASN1EncBigInt::NewLC(static_cast<const RInteger&>(sig->S()));
+ sigSeq->AddAndPopChildL(s);
+
+ //Write the buffer
+ TUint len=sigSeq->LengthDER();
+ HBufC8* buf=HBufC8::NewMaxLC(len);
+ TPtr8 des=buf->Des();
+ TUint pos=0;
+ sigSeq->WriteDERL(des, pos);
+
+ //Clean up
+ CleanupStack::Pop(buf); //buf
+ CleanupStack::PopAndDestroy(3, signer); //sigSeq, signonc, signer
+ return buf;
+ }
+
+HBufC8* CmsUtils::CreateSignatureL(const TDesC8& aHash, const CRSAPrivateKey& aKey)
+ {
+ //Create Signer and sign the hash
+ CRSAPKCS1v15Signer* signer=CRSAPKCS1v15Signer::NewLC(aKey);
+ const CRSASignature* sig=signer->SignL(aHash);
+ CRSASignature* signonc=const_cast<CRSASignature*>(sig);
+
+ CleanupStack::PushL(signonc);
+
+ HBufC8* sigData = sig->S().BufferWithNoTruncationLC();
+
+ //Clean up
+ CleanupStack::Pop(sigData);
+ CleanupStack::PopAndDestroy(2, signer);//signonc signer
+ return sigData;
+ }
+
+HBufC8* CmsUtils::CreateDEREncodingLC(const CASN1EncBase& aEncoding)
+ {
+ TUint len = aEncoding.LengthDER();
+ HBufC8* buf = HBufC8::NewMaxLC(len);
+ TUint pos = 0;
+ TPtr8 bufptr(buf->Des());
+ aEncoding.WriteDERL(bufptr, pos);
+ return buf;
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+