--- a/cryptoservices/certificateandkeymgmt/pkcs7/pkcs7signedobject_v2.cpp Tue Jul 21 01:04:32 2009 +0100
+++ b/cryptoservices/certificateandkeymgmt/pkcs7/pkcs7signedobject_v2.cpp Thu Sep 10 14:01:51 2009 +0300
@@ -1,308 +1,308 @@
-/*
-* 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 "pkcs7signedobject.h"
-#include <pkcs7contentinfo_v2.h>
-#include "pkcs7excert.h"
-#include "pkcs7signerinfo.h"
-#include "pkcs7issuerserial.h"
-#include "pkcs7asn1.h"
-#include <asn1dec.h>
-#include <x509cert.h>
-#include <hash.h>
-
-const TInt KSignedDataCertificates = 0;
-const TInt KSignedDataRevocationLists = 1;
-
-EXPORT_C CPKCS7SignedObject::~CPKCS7SignedObject(void)
- {
- iDigestAlgorithms.ResetAndDestroy();
- iCertificates.ResetAndDestroy();
- delete iContentInfo;
- iSignerInfo.ResetAndDestroy();
- for(TInt i = 0; i < KPKCS7MaxDataElements; i++)
- {
- delete iDataElements.At(i);
- }
- }
-
-EXPORT_C CPKCS7SignedObject::CPKCS7SignedObject(void)
- {
- }
-
-
-EXPORT_C CPKCS7SignedObject* CPKCS7SignedObject::NewLC(const CPKCS7ContentInfo& aContentInfo)
- {
- CPKCS7SignedObject* self = new (ELeave) CPKCS7SignedObject();
- CleanupStack::PushL(self);
- self->ConstructL(aContentInfo);
- return self;
- }
-
-EXPORT_C CPKCS7SignedObject* CPKCS7SignedObject::NewL(const CPKCS7ContentInfo& aContentInfo)
- {
- CPKCS7SignedObject* self = NewLC(aContentInfo);
- CleanupStack::Pop(self);
- return self;
- }
-
-EXPORT_C void CPKCS7SignedObject::ConstructL(const CPKCS7ContentInfo& aContentInfo)
- {
- if(aContentInfo.ContentType() != KPkcs7SignedData)
- {
- User::Leave(KErrArgument);
- }
-
- TASN1DecGeneric decGen(aContentInfo.ContentData());
- decGen.InitL();
-
- if(decGen.Tag() == EASN1Sequence)
- {
- InitSignedObjectL(decGen.Encoding());
- DecodeSignedDataL(*iEncoding);
- }
- else
- {
- User::Leave(KErrArgument);
- }
- }
-
-EXPORT_C const TPtrC8 CPKCS7SignedObject::SignedDataL() const
- {
- return iContentInfo->ContentData();
- }
-
-EXPORT_C void CPKCS7SignedObject::InternalizeL(RReadStream& /*aStream*/)
- {
- User::Leave(KErrNotSupported);
- }
-
-EXPORT_C const TPtrC8* CPKCS7SignedObject::DataElementEncoding(const TUint aIndex) const
- {
- return iDataElements.At(aIndex);
- }
-
-
-EXPORT_C const RPointerArray<CX509AlgorithmIdentifier>& CPKCS7SignedObject::DigestAlgorithms() const
- {
- return iDigestAlgorithms;
- }
-
-EXPORT_C TInt CPKCS7SignedObject::Version() const
- {
- return iVersion;
- }
-
-EXPORT_C const CPKCS7ContentInfo& CPKCS7SignedObject::ContentInfo() const
- {
- return *iContentInfo;
- }
-
-EXPORT_C const RPointerArray<CPKCS7ExtendedCertificateOrCertificate>& CPKCS7SignedObject::Certificates() const
- {
- return iCertificates;
- }
-
-EXPORT_C const RPointerArray<CPKCS7SignerInfo>& CPKCS7SignedObject::SignerInfo() const
- {
- return iSignerInfo;
- }
-
-void CPKCS7SignedObject::InitSignedObjectL(const TDesC8& aRawData)
- {
- // Populate CSignedObject data members
- iKeyFactory = new (ELeave) TX509KeyFactory;
- iEncoding = aRawData.AllocL();
-
- CSHA1* hash = CSHA1::NewL();
- CleanupStack::PushL(hash);
- iFingerprint = hash->Hash(Encoding()).AllocL();
- CleanupStack::PopAndDestroy(hash);
- }
-
-void CPKCS7SignedObject::DecodeSignedDataL(const TDesC8& aRawData)
- {
- CArrayPtr<TASN1DecGeneric>* signedData = PKCS7ASN1::DecodeSequenceLC(aRawData, 4, KPKCS7MaxDataElements);
- TInt totalItems = signedData->Count();
- TASN1DecInteger decInt;
-
- // decodes version
- iDataElements.At(EVersionNumber) = new(ELeave) TPtrC8(signedData->At(0)->GetContentDER());
- iVersion = decInt.DecodeDERShortL(*signedData->At(0));
- // decodes algorithms
- iDataElements.At(EDigestAlgorithms) = new(ELeave) TPtrC8(signedData->At(1)->GetContentDER());
- DecodeDigestAlgorithmsL(signedData->At(1)->Encoding());
- // decodes contentinfo
- iDataElements.At(EContentInfo) = new(ELeave) TPtrC8(signedData->At(2)->GetContentDER());
- iContentInfo = CPKCS7ContentInfo::NewL(signedData->At(2)->Encoding());
-
- // Checks for optional fields
- TInt pos = 3; // Skip first non-optional fields
- do
- {
- const TASN1DecGeneric& currentItem = *signedData->At(pos);
- switch(currentItem.Tag())
- {
- case KSignedDataCertificates:
- {
- iDataElements.At(ECertificates) = new(ELeave) TPtrC8(currentItem.GetContentDER());
- DecodeCertificatesL(currentItem.Encoding());
- break;
- }
- case KSignedDataRevocationLists:
- {
-
- iDataElements.At(ERevocationLists) = new(ELeave) TPtrC8(currentItem.GetContentDER());
- DecodeRevocationListsL(currentItem.Encoding());
- break;
- }
- default: // Non-optional field
- {
- break;
- }
- }
- pos++;
- }
- while(pos < totalItems);
-
- iDataElements.At(ESignedInfo) = new(ELeave) TPtrC8(signedData->At(totalItems-1)->GetContentDER());
- DecodeSignerInfoL(signedData->At(totalItems-1)->Encoding());
-
- CleanupStack::PopAndDestroy(signedData);
- }
-
-
-void CPKCS7SignedObject::DecodeDigestAlgorithmsL(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());
- User::LeaveIfError(iDigestAlgorithms.Append(alIdent));
- CleanupStack::Pop(alIdent);
- }
- CleanupStack::PopAndDestroy(algsData);
- }
-
-void CPKCS7SignedObject::DecodeCertificatesL(const TDesC8& aRawData)
- {
- CArrayPtr<TASN1DecGeneric>* items = NULL;
- TASN1DecGeneric decGen(aRawData);
- decGen.InitL();
- TASN1DecSequence decSeq;
- // have to do manual decoding of sequence because field is optional
- items = decSeq.DecodeDERLC(decGen);
- TInt count = items->Count();
-
- CPKCS7ExtendedCertificateOrCertificate* certificate;
-
- for(TInt item = 0; item < count; item++)
- {
- certificate = CPKCS7ExtendedCertificateOrCertificate::NewL(items->At(item)->Encoding());
- CleanupStack::PushL(certificate);
- User::LeaveIfError(iCertificates.Append(certificate));
- CleanupStack::Pop(certificate);
- }
-
- CleanupStack::PopAndDestroy(items);
- }
-
-void CPKCS7SignedObject::DecodeRevocationListsL(const TDesC8& /*aRawData*/)
- {
- // not yet supported
- User::Leave(KErrNotSupported);
- }
-
-void CPKCS7SignedObject::DecodeSignerInfoL(const TDesC8& aRawData)
- {
- CArrayPtr<TASN1DecGeneric>* signerInfo = PKCS7ASN1::DecodeSequenceLC(aRawData);
- TInt total = signerInfo->Count();
- CPKCS7SignerInfo* signer;
-
- for(TInt item = 0; item < total; item ++)
- {
- signer = CPKCS7SignerInfo::NewL(signerInfo->At(item)->Encoding());
- CleanupStack::PushL(signer);
- User::LeaveIfError(iSignerInfo.Append(signer));
- CleanupStack::Pop(signer);
- }
- CleanupStack::PopAndDestroy(signerInfo);
- }
-
-EXPORT_C TBool CPKCS7SignedObject::ValidateSignerL(const CPKCS7SignerInfo& aSignerInfo, HBufC8*& aCertChainEncoding)
- {
- TInt certCount = iCertificates.Count();
- TInt endEntityPos = -1;
- TInt endEncodingSize = 0;
- TPtrC8 endEntityEncoding;
- TInt cert;
- TBool valid = EFalse;
-
- // looks for end entity certificate
- for(cert = 0; cert < certCount; cert++)
- {
- const CX509Certificate& certificate = iCertificates[cert]->Certificate();
-
- endEncodingSize+= certificate.Encoding().Length();
- if(certificate.IssuerName().ExactMatchL(aSignerInfo.IssuerAndSerialNumber().IssuerName()))
- {
- endEntityPos = cert;
- endEntityEncoding.Set(certificate.Encoding());
- valid = ValidateSignatureL(aSignerInfo, certificate);
- }
- }
-
- // checks if end entity was found
- if(endEntityPos != -1)
- {
- // builds the cert chain encoding by putting the end entity first then all remaining
- // certs
- aCertChainEncoding = HBufC8::NewLC(endEncodingSize);
- TPtr8 encodingPtr(aCertChainEncoding->Des());
- encodingPtr.Copy(endEntityEncoding);
- for(cert = 0; cert < certCount; cert++)
- {
- const CX509Certificate& certificate = iCertificates[cert]->Certificate();
-
- if(cert != endEntityPos)
- {
- encodingPtr.Append(certificate.Encoding());
- }
- }
- }
- else
- {
- User::Leave(KErrNotFound);
- }
- return valid;
- }
-
-TBool CPKCS7SignedObject::ValidateSignatureL(const CPKCS7SignerInfo& aSignerInfo, const CX509Certificate& aEndEntityCert)
- {
- iSigningAlgorithm = CX509SigningAlgorithmIdentifier::NewL(aSignerInfo.DigestEncryptionAlgorithm(), aSignerInfo.DigestAlgorithm());
- if(iSignature)
- {
- delete iSignature;
- iSignature = NULL;
- }
- iSignature = aSignerInfo.EncryptedDigest().AllocL();
- return VerifySignatureL(aEndEntityCert.PublicKey().KeyData());
- }
+/*
+* 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 "pkcs7signedobject.h"
+#include <pkcs7contentinfo_v2.h>
+#include "pkcs7excert.h"
+#include "pkcs7signerinfo.h"
+#include "pkcs7issuerserial.h"
+#include "pkcs7asn1.h"
+#include <asn1dec.h>
+#include <x509cert.h>
+#include <hash.h>
+
+const TInt KSignedDataCertificates = 0;
+const TInt KSignedDataRevocationLists = 1;
+
+EXPORT_C CPKCS7SignedObject::~CPKCS7SignedObject(void)
+ {
+ iDigestAlgorithms.ResetAndDestroy();
+ iCertificates.ResetAndDestroy();
+ delete iContentInfo;
+ iSignerInfo.ResetAndDestroy();
+ for(TInt i = 0; i < KPKCS7MaxDataElements; i++)
+ {
+ delete iDataElements.At(i);
+ }
+ }
+
+EXPORT_C CPKCS7SignedObject::CPKCS7SignedObject(void)
+ {
+ }
+
+
+EXPORT_C CPKCS7SignedObject* CPKCS7SignedObject::NewLC(const CPKCS7ContentInfo& aContentInfo)
+ {
+ CPKCS7SignedObject* self = new (ELeave) CPKCS7SignedObject();
+ CleanupStack::PushL(self);
+ self->ConstructL(aContentInfo);
+ return self;
+ }
+
+EXPORT_C CPKCS7SignedObject* CPKCS7SignedObject::NewL(const CPKCS7ContentInfo& aContentInfo)
+ {
+ CPKCS7SignedObject* self = NewLC(aContentInfo);
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+EXPORT_C void CPKCS7SignedObject::ConstructL(const CPKCS7ContentInfo& aContentInfo)
+ {
+ if(aContentInfo.ContentType() != KPkcs7SignedData)
+ {
+ User::Leave(KErrArgument);
+ }
+
+ TASN1DecGeneric decGen(aContentInfo.ContentData());
+ decGen.InitL();
+
+ if(decGen.Tag() == EASN1Sequence)
+ {
+ InitSignedObjectL(decGen.Encoding());
+ DecodeSignedDataL(*iEncoding);
+ }
+ else
+ {
+ User::Leave(KErrArgument);
+ }
+ }
+
+EXPORT_C const TPtrC8 CPKCS7SignedObject::SignedDataL() const
+ {
+ return iContentInfo->ContentData();
+ }
+
+EXPORT_C void CPKCS7SignedObject::InternalizeL(RReadStream& /*aStream*/)
+ {
+ User::Leave(KErrNotSupported);
+ }
+
+EXPORT_C const TPtrC8* CPKCS7SignedObject::DataElementEncoding(const TUint aIndex) const
+ {
+ return iDataElements.At(aIndex);
+ }
+
+
+EXPORT_C const RPointerArray<CX509AlgorithmIdentifier>& CPKCS7SignedObject::DigestAlgorithms() const
+ {
+ return iDigestAlgorithms;
+ }
+
+EXPORT_C TInt CPKCS7SignedObject::Version() const
+ {
+ return iVersion;
+ }
+
+EXPORT_C const CPKCS7ContentInfo& CPKCS7SignedObject::ContentInfo() const
+ {
+ return *iContentInfo;
+ }
+
+EXPORT_C const RPointerArray<CPKCS7ExtendedCertificateOrCertificate>& CPKCS7SignedObject::Certificates() const
+ {
+ return iCertificates;
+ }
+
+EXPORT_C const RPointerArray<CPKCS7SignerInfo>& CPKCS7SignedObject::SignerInfo() const
+ {
+ return iSignerInfo;
+ }
+
+void CPKCS7SignedObject::InitSignedObjectL(const TDesC8& aRawData)
+ {
+ // Populate CSignedObject data members
+ iKeyFactory = new (ELeave) TX509KeyFactory;
+ iEncoding = aRawData.AllocL();
+
+ CSHA1* hash = CSHA1::NewL();
+ CleanupStack::PushL(hash);
+ iFingerprint = hash->Hash(Encoding()).AllocL();
+ CleanupStack::PopAndDestroy(hash);
+ }
+
+void CPKCS7SignedObject::DecodeSignedDataL(const TDesC8& aRawData)
+ {
+ CArrayPtr<TASN1DecGeneric>* signedData = PKCS7ASN1::DecodeSequenceLC(aRawData, 4, KPKCS7MaxDataElements);
+ TInt totalItems = signedData->Count();
+ TASN1DecInteger decInt;
+
+ // decodes version
+ iDataElements.At(EVersionNumber) = new(ELeave) TPtrC8(signedData->At(0)->GetContentDER());
+ iVersion = decInt.DecodeDERShortL(*signedData->At(0));
+ // decodes algorithms
+ iDataElements.At(EDigestAlgorithms) = new(ELeave) TPtrC8(signedData->At(1)->GetContentDER());
+ DecodeDigestAlgorithmsL(signedData->At(1)->Encoding());
+ // decodes contentinfo
+ iDataElements.At(EContentInfo) = new(ELeave) TPtrC8(signedData->At(2)->GetContentDER());
+ iContentInfo = CPKCS7ContentInfo::NewL(signedData->At(2)->Encoding());
+
+ // Checks for optional fields
+ TInt pos = 3; // Skip first non-optional fields
+ do
+ {
+ const TASN1DecGeneric& currentItem = *signedData->At(pos);
+ switch(currentItem.Tag())
+ {
+ case KSignedDataCertificates:
+ {
+ iDataElements.At(ECertificates) = new(ELeave) TPtrC8(currentItem.GetContentDER());
+ DecodeCertificatesL(currentItem.Encoding());
+ break;
+ }
+ case KSignedDataRevocationLists:
+ {
+
+ iDataElements.At(ERevocationLists) = new(ELeave) TPtrC8(currentItem.GetContentDER());
+ DecodeRevocationListsL(currentItem.Encoding());
+ break;
+ }
+ default: // Non-optional field
+ {
+ break;
+ }
+ }
+ pos++;
+ }
+ while(pos < totalItems);
+
+ iDataElements.At(ESignedInfo) = new(ELeave) TPtrC8(signedData->At(totalItems-1)->GetContentDER());
+ DecodeSignerInfoL(signedData->At(totalItems-1)->Encoding());
+
+ CleanupStack::PopAndDestroy(signedData);
+ }
+
+
+void CPKCS7SignedObject::DecodeDigestAlgorithmsL(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());
+ User::LeaveIfError(iDigestAlgorithms.Append(alIdent));
+ CleanupStack::Pop(alIdent);
+ }
+ CleanupStack::PopAndDestroy(algsData);
+ }
+
+void CPKCS7SignedObject::DecodeCertificatesL(const TDesC8& aRawData)
+ {
+ CArrayPtr<TASN1DecGeneric>* items = NULL;
+ TASN1DecGeneric decGen(aRawData);
+ decGen.InitL();
+ TASN1DecSequence decSeq;
+ // have to do manual decoding of sequence because field is optional
+ items = decSeq.DecodeDERLC(decGen);
+ TInt count = items->Count();
+
+ CPKCS7ExtendedCertificateOrCertificate* certificate;
+
+ for(TInt item = 0; item < count; item++)
+ {
+ certificate = CPKCS7ExtendedCertificateOrCertificate::NewL(items->At(item)->Encoding());
+ CleanupStack::PushL(certificate);
+ User::LeaveIfError(iCertificates.Append(certificate));
+ CleanupStack::Pop(certificate);
+ }
+
+ CleanupStack::PopAndDestroy(items);
+ }
+
+void CPKCS7SignedObject::DecodeRevocationListsL(const TDesC8& /*aRawData*/)
+ {
+ // not yet supported
+ User::Leave(KErrNotSupported);
+ }
+
+void CPKCS7SignedObject::DecodeSignerInfoL(const TDesC8& aRawData)
+ {
+ CArrayPtr<TASN1DecGeneric>* signerInfo = PKCS7ASN1::DecodeSequenceLC(aRawData);
+ TInt total = signerInfo->Count();
+ CPKCS7SignerInfo* signer;
+
+ for(TInt item = 0; item < total; item ++)
+ {
+ signer = CPKCS7SignerInfo::NewL(signerInfo->At(item)->Encoding());
+ CleanupStack::PushL(signer);
+ User::LeaveIfError(iSignerInfo.Append(signer));
+ CleanupStack::Pop(signer);
+ }
+ CleanupStack::PopAndDestroy(signerInfo);
+ }
+
+EXPORT_C TBool CPKCS7SignedObject::ValidateSignerL(const CPKCS7SignerInfo& aSignerInfo, HBufC8*& aCertChainEncoding)
+ {
+ TInt certCount = iCertificates.Count();
+ TInt endEntityPos = -1;
+ TInt endEncodingSize = 0;
+ TPtrC8 endEntityEncoding;
+ TInt cert;
+ TBool valid = EFalse;
+
+ // looks for end entity certificate
+ for(cert = 0; cert < certCount; cert++)
+ {
+ const CX509Certificate& certificate = iCertificates[cert]->Certificate();
+
+ endEncodingSize+= certificate.Encoding().Length();
+ if(certificate.IssuerName().ExactMatchL(aSignerInfo.IssuerAndSerialNumber().IssuerName()))
+ {
+ endEntityPos = cert;
+ endEntityEncoding.Set(certificate.Encoding());
+ valid = ValidateSignatureL(aSignerInfo, certificate);
+ }
+ }
+
+ // checks if end entity was found
+ if(endEntityPos != -1)
+ {
+ // builds the cert chain encoding by putting the end entity first then all remaining
+ // certs
+ aCertChainEncoding = HBufC8::NewLC(endEncodingSize);
+ TPtr8 encodingPtr(aCertChainEncoding->Des());
+ encodingPtr.Copy(endEntityEncoding);
+ for(cert = 0; cert < certCount; cert++)
+ {
+ const CX509Certificate& certificate = iCertificates[cert]->Certificate();
+
+ if(cert != endEntityPos)
+ {
+ encodingPtr.Append(certificate.Encoding());
+ }
+ }
+ }
+ else
+ {
+ User::Leave(KErrNotFound);
+ }
+ return valid;
+ }
+
+TBool CPKCS7SignedObject::ValidateSignatureL(const CPKCS7SignerInfo& aSignerInfo, const CX509Certificate& aEndEntityCert)
+ {
+ iSigningAlgorithm = CX509SigningAlgorithmIdentifier::NewL(aSignerInfo.DigestEncryptionAlgorithm(), aSignerInfo.DigestAlgorithm());
+ if(iSignature)
+ {
+ delete iSignature;
+ iSignature = NULL;
+ }
+ iSignature = aSignerInfo.EncryptedDigest().AllocL();
+ return VerifySignatureL(aEndEntityCert.PublicKey().KeyData());
+ }