--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cms/src/CCMSSignerInfo.cpp Tue Jan 26 15:20:08 2010 +0200
@@ -0,0 +1,662 @@
+/*
+* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "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 FILES
+#include "CCMSSignerInfo.h"
+#include "TCMSTimeUtil.h"
+
+#include <x500dn.h>
+#include <asn1dec.h>
+#include <asn1enc.h>
+#include <signed.h>
+
+// CONSTANTS
+const TInt KMinNumberOfSubModules = 5;
+const TInt KMaxNumberOfSubModules = 7;
+const TInt KDefaultGranularity = 2;
+const TInt KCMSVersion1 = 1;
+const TInt KCMSVersion3 = 3;
+const TInt KSignedAttrsTag = 0;
+const TInt KUnsignedAttrsTag = 1;
+
+// CMS SignedAttributes useful types
+_LIT( KContentTypeOID, "1.2.840.113549.1.9.3" );
+_LIT( KMessageDigestOID, "1.2.840.113549.1.9.4" );
+_LIT( KSignTimeOID, "1.2.840.113549.1.9.5" );
+
+// Additional oid for adding certificates
+_LIT( KPKCS9SigCertOID, "1.2.840.113549.1.9.16.2.12" );
+
+// X509 URL certificate OID
+_LIT( KURLCertificateOID, "2.23.43.2.1" );
+
+// Defaulta id-data oid
+_LIT( KIDDataOID, "1.2.840.113549.1.7.1" );
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// Destructor
+CCMSSignerInfo::CSignerInfoData::~CSignerInfoData()
+ {
+ delete iIssuerAndSerial;
+ delete iSubjectKeyIdentifier;
+
+ if( iSignedAttributes )
+ {
+ iSignedAttributes->ResetAndDestroy();
+ delete iSignedAttributes;
+ }
+
+ if( iUnsignedAttributes )
+ {
+ iUnsignedAttributes->ResetAndDestroy();
+ delete iUnsignedAttributes;
+ }
+
+ delete iDigestAI;
+ delete iSignatureAI;
+ delete iSignatureValue;
+ }
+
+// -----------------------------------------------------------------------------
+// CCMSSignerInfo::CCMSSignerInfo
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CCMSSignerInfo::CCMSSignerInfo()
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CCMSSignerInfo::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CCMSSignerInfo::ConstructL(
+ const TDesC8& aCertificateUrl,
+ const TDesC8& aSubjectKeyID,
+ const TDesC8& aMessageDigest )
+ {
+ iData = new(ELeave) CSignerInfoData();
+ BaseConstructL( aMessageDigest );
+ SetCertificateUrlL( aCertificateUrl, aSubjectKeyID );
+ }
+
+// -----------------------------------------------------------------------------
+// CCMSSignerInfo::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CCMSSignerInfo::ConstructL(
+ const CCMSX509Certificate& aCertificate,
+ const TDesC8& aMessageDigest )
+ {
+ iData = new(ELeave) CSignerInfoData();
+ BaseConstructL( aMessageDigest );
+ SetCertificateL( aCertificate );
+ }
+
+void CCMSSignerInfo::BaseConstructL( const TDesC8& aMessageDigest )
+ {
+ iData->iDigestAI = CCMSX509AlgorithmIdentifier::NewL( ESHA1 );
+ iData->iSignatureAI = CCMSX509AlgorithmIdentifier::NewL();
+ TTime time;
+ time.UniversalTime();
+ iData->iSignedAttributes = new(ELeave)CArrayPtrFlat<CCMSAttribute>( KDefaultGranularity );
+ SetSignedAttributesL( KIDDataOID(),
+ aMessageDigest,
+ time,
+ NULL );
+ iData->iUnsignedAttributes = new(ELeave)CArrayPtrFlat<CCMSAttribute>( KDefaultGranularity );
+ SetSignatureValueL( aMessageDigest );
+ }
+
+// -----------------------------------------------------------------------------
+// CCMSSignerInfo::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CCMSSignerInfo* CCMSSignerInfo::NewL()
+ {
+ // creating with empty values
+ CCMSSignerInfo* self = NewL( KNullDesC8(),
+ KNullDesC8(),
+ KNullDesC8() );
+
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CCMSSignerInfo::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CCMSSignerInfo* CCMSSignerInfo::NewL(
+ const TDesC8& aCertificateUrl,
+ const TDesC8& aSubjectKeyID,
+ const TDesC8& aMessageDigest )
+ {
+ CCMSSignerInfo* self = new( ELeave ) CCMSSignerInfo();
+ CleanupStack::PushL( self );
+ self->ConstructL( aCertificateUrl, aSubjectKeyID, aMessageDigest );
+ CleanupStack::Pop();
+
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CCMSSignerInfo::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CCMSSignerInfo* CCMSSignerInfo::NewL(
+ const CCMSX509Certificate& aCertificate,
+ const TDesC8& aMessageDigest )
+ {
+ CCMSSignerInfo* self = new( ELeave ) CCMSSignerInfo();
+ CleanupStack::PushL( self );
+ self->ConstructL( aCertificate, aMessageDigest );
+ CleanupStack::Pop();
+
+ return self;
+ }
+
+// Destructor
+CCMSSignerInfo::~CCMSSignerInfo()
+ {
+ delete iData;
+ }
+
+// -----------------------------------------------------------------------------
+// CCMSSignerInfo::DecodeL
+// Decrypts raw data to this instance
+// -----------------------------------------------------------------------------
+void CCMSSignerInfo::DecodeL( const TDesC8& aRawData )
+ {
+ CSignerInfoData* tmpData = new(ELeave) CSignerInfoData();
+ CleanupStack::PushL( tmpData );
+ CArrayPtr<TASN1DecGeneric>* signerInfo = DecodeSequenceLC( aRawData,
+ KMinNumberOfSubModules,
+ KMaxNumberOfSubModules );
+ // we would not get this far if there is not min 5 elements
+ TInt pos = 0;
+ // decode Version
+ TASN1DecInteger version;
+ tmpData->iVersion = version.DecodeDERShortL( *signerInfo->At( pos++ ) );
+
+ if( tmpData->iVersion == KCMSVersion1 )
+ {
+ // decode IssuerAndSerialNumber
+ tmpData->iIssuerAndSerial =
+ CCMSIssuerAndSerialNumber::NewL();
+ tmpData->iIssuerAndSerial->DecodeL( signerInfo->At( pos++ )->Encoding() );
+ }
+ else
+ {
+ // decode SubjectKeyIdentifier
+ TASN1DecOctetString subjectKey;
+ tmpData->iSubjectKeyIdentifier =
+ subjectKey.DecodeDERL( *signerInfo->At( pos++ ) );
+ }
+
+ // decode DigestAlgorithIdentifier
+ tmpData->iDigestAI = CCMSX509AlgorithmIdentifier::NewL();
+ tmpData->iDigestAI->DecodeL( signerInfo->At( pos++ )->Encoding() );
+
+ // decode possible SignedAttributes
+ tmpData->iSignedAttributes =
+ new( ELeave )CArrayPtrFlat<CCMSAttribute>( KDefaultGranularity );
+ if( signerInfo->At( pos )->Tag() == KSignedAttrsTag )
+ {
+ DecodeAttributesL( signerInfo->At( pos++ )->Encoding(),
+ tmpData->iSignedAttributes );
+ }
+
+ // decode SignatureAlgorithIdentifier
+ tmpData->iSignatureAI = CCMSX509AlgorithmIdentifier::NewL();
+ tmpData->iSignatureAI->DecodeL( signerInfo->At( pos++ )->Encoding() );
+
+ // check that we have enough parameters for mandatory fields
+ if( pos >= signerInfo->Count() )
+ {
+ User::Leave( KErrArgument );
+ }
+
+ // decode SignatureValue
+ TASN1DecOctetString signValue;
+ tmpData->iSignatureValue = signValue.DecodeDERL( *signerInfo->At( pos++ ) );
+
+ // decode possible UnsignedAttributes
+ tmpData->iUnsignedAttributes =
+ new( ELeave )CArrayPtrFlat<CCMSAttribute>( KDefaultGranularity );
+ if( ( pos < signerInfo->Count() ) &&
+ ( signerInfo->At( pos )->Tag() == KUnsignedAttrsTag ) )
+ {
+ DecodeAttributesL( signerInfo->At( pos++ )->Encoding(),
+ tmpData->iUnsignedAttributes );
+ }
+
+ CleanupStack::PopAndDestroy( signerInfo );
+
+ delete iData;
+ iData = tmpData;
+ CleanupStack::Pop( tmpData );
+ }
+
+// -----------------------------------------------------------------------------
+// CCMSSignerInfo::EncoderLC
+// Returns ASN1 encoder for this instance
+// -----------------------------------------------------------------------------
+
+CASN1EncBase* CCMSSignerInfo::EncoderLC() const
+ {
+ CASN1EncSequence* root = CASN1EncSequence::NewLC();
+
+ // Add version
+ CASN1EncInt* version = CASN1EncInt::NewLC( iData->iVersion );
+ root->AddAndPopChildL( version );
+
+ // Add IssuerAndSerialNumber or SubjectKeyIdentifier
+ if( iData->iIssuerAndSerial )
+ {
+ CASN1EncBase* issuer = iData->iIssuerAndSerial->EncoderLC();
+ root->AddAndPopChildL( issuer );
+ }
+ else
+ {
+ CASN1EncOctetString* subjectKey =
+ CASN1EncOctetString::NewLC( *iData->iSubjectKeyIdentifier );
+ root->AddAndPopChildL( subjectKey );
+ }
+
+ // Add DigestAlgorithmIdentifier
+ CASN1EncBase* digestAlg = iData->iDigestAI->EncoderLC();
+ root->AddAndPopChildL( digestAlg );
+
+ // Add SignedAttributes if they exists
+ TInt signedAttributes = iData->iSignedAttributes->Count();
+ if( signedAttributes > 0 )
+ {
+ CASN1EncSequence* signedAttributesSet
+ = CASN1EncSequence::NewLC();
+ signedAttributesSet->SetTag( KSignedAttrsTag );
+
+ for( TInt i = 0; i < signedAttributes; i++ )
+ {
+ CASN1EncBase* attribute = iData->iSignedAttributes->At( i )->EncoderLC();
+ signedAttributesSet->AddAndPopChildL( attribute );
+ }
+ root->AddAndPopChildL( signedAttributesSet );
+ }
+
+ // Add SignatureAlgorithmIdentifier
+ CASN1EncBase* signatureAlg = iData->iSignatureAI->EncoderLC();
+ root->AddAndPopChildL( signatureAlg );
+
+ // Add SignatureValue
+ CASN1EncOctetString* signValue =
+ CASN1EncOctetString::NewLC( *iData->iSignatureValue );
+ root->AddAndPopChildL( signValue );
+
+ // Add UnsignedAttributes if they exists
+ TInt unsignedAttributes = iData->iUnsignedAttributes->Count();
+ if( unsignedAttributes > 0 )
+ {
+ CASN1EncSequence* unsignedAttributesSet
+ = CASN1EncSequence::NewLC();
+ unsignedAttributesSet->SetTag( KUnsignedAttrsTag );
+
+ for( TInt i = 0; i < unsignedAttributes; i++ )
+ {
+ CASN1EncBase* attribute = iData->iUnsignedAttributes->At( i )->EncoderLC();
+ unsignedAttributesSet->AddAndPopChildL( attribute );
+ }
+ root->AddAndPopChildL( unsignedAttributesSet );
+ }
+
+ return root;
+ }
+
+// -----------------------------------------------------------------------------
+// CCMSSignerInfo::CMSVersion()
+// Getter for Version
+// -----------------------------------------------------------------------------
+EXPORT_C TInt CCMSSignerInfo::CMSVersion() const
+ {
+ return iData->iVersion;
+ }
+
+// -----------------------------------------------------------------------------
+// CCMSSignerInfo::IssuerAndSerialNumber()
+// Getter for IssuerAndSerialNumber
+// -----------------------------------------------------------------------------
+EXPORT_C const CCMSIssuerAndSerialNumber* CCMSSignerInfo::IssuerAndSerialNumber() const
+ {
+ return iData->iIssuerAndSerial;
+ }
+
+// -----------------------------------------------------------------------------
+// CCMSSignerInfo::SubjectKeyIdentifier()
+// Getter for SubjectKeyIdentifier
+// -----------------------------------------------------------------------------
+EXPORT_C const TDesC8* CCMSSignerInfo::SubjectKeyIdentifier() const
+ {
+ return iData->iSubjectKeyIdentifier;
+ }
+
+// -----------------------------------------------------------------------------
+// CCMSSignerInfo::DigestAlgorithmIdentifier()
+// Getter for DigestAlgorithmIdentifier
+// -----------------------------------------------------------------------------
+EXPORT_C const CCMSX509AlgorithmIdentifier& CCMSSignerInfo::DigestAlgorithmIdentifier() const
+ {
+ return *iData->iDigestAI;
+ }
+
+// -----------------------------------------------------------------------------
+// CCMSSignerInfo::SignedAttributes()
+// Getter for SignedAttributes
+// -----------------------------------------------------------------------------
+EXPORT_C const CArrayPtrFlat<CCMSAttribute>& CCMSSignerInfo::SignedAttributes() const
+ {
+ return *iData->iSignedAttributes;
+ }
+
+// -----------------------------------------------------------------------------
+// CCMSSignerInfo::SignedAttributesEncodedL()
+// Getter for encoded SignedAttributes
+// -----------------------------------------------------------------------------
+EXPORT_C HBufC8* CCMSSignerInfo::SignedAttributesEncodedL() const
+ {
+ HBufC8* retVal = NULL;
+ TInt signedAttributes = iData->iSignedAttributes->Count();
+ if( signedAttributes > 0 )
+ {
+ CASN1EncSequence* signedAttributesSet
+ = CASN1EncSequence::NewLC();
+ signedAttributesSet->SetTag( EASN1Set, EUniversal );
+
+ for( TInt i = 0; i < signedAttributes; i++ )
+ {
+ CASN1EncBase* attribute = iData->iSignedAttributes->At( i )->EncoderLC();
+ signedAttributesSet->AddAndPopChildL( attribute );
+ }
+ retVal = CreateDerEncodingL( signedAttributesSet );
+ CleanupStack::PopAndDestroy( signedAttributesSet );
+ }
+ return retVal;
+ }
+
+// -----------------------------------------------------------------------------
+// CCMSSignerInfo::SignatureAlgorithmIdentifier()
+// Getter for SignatureAlgorithmIdentifier
+// -----------------------------------------------------------------------------
+EXPORT_C const CCMSX509AlgorithmIdentifier& CCMSSignerInfo::SignatureAlgorithmIdentifier() const
+ {
+ return *iData->iSignatureAI;
+ }
+
+// -----------------------------------------------------------------------------
+// CCMSSignerInfo::SignatureValue()
+// Getter for SignatureValue
+// -----------------------------------------------------------------------------
+EXPORT_C const TDesC8& CCMSSignerInfo::SignatureValue() const
+ {
+ return *iData->iSignatureValue;
+ }
+
+// -----------------------------------------------------------------------------
+// CCMSSignerInfo::UnsignedAttributes()
+// Getter for UnsignedAttributes
+// -----------------------------------------------------------------------------
+EXPORT_C const CArrayPtrFlat<CCMSAttribute>& CCMSSignerInfo::UnsignedAttributes() const
+ {
+ return *iData->iUnsignedAttributes;
+ }
+
+// -----------------------------------------------------------------------------
+// CCMSSignerInfo::SetCertificateL()
+// Setter for Certificate
+// -----------------------------------------------------------------------------
+EXPORT_C void CCMSSignerInfo::SetCertificateL( const CCMSX509Certificate& aCertificate )
+ {
+ // creating Issuer and serial
+ CCMSIssuerAndSerialNumber* tmpIssuer = CCMSIssuerAndSerialNumber::NewL(
+ aCertificate.Issuer(),
+ aCertificate.SerialNumber() );
+
+ delete iData->iIssuerAndSerial;
+ iData->iIssuerAndSerial = tmpIssuer;
+
+ // setting normal certificate, deleting possible certificate url
+ // and subject key identifier
+ TInt unsignedAttCount = iData->iUnsignedAttributes->Count();
+ for( TInt i = 0; i < unsignedAttCount; i++ )
+ {
+ CCMSAttribute* att = iData->iUnsignedAttributes->At( i );
+ if( att->AttributeType() == KURLCertificateOID() )
+ {
+ iData->iUnsignedAttributes->Delete( i );
+ delete att;
+ }
+ }
+ delete iData->iSubjectKeyIdentifier;
+ iData->iSubjectKeyIdentifier = NULL;
+
+ // changing version to 1
+ iData->iVersion = KCMSVersion1;
+ }
+
+// -----------------------------------------------------------------------------
+// CCMSSignerInfo::SetCertificateUrlL()
+// Setter for certificate URL
+// -----------------------------------------------------------------------------
+EXPORT_C void CCMSSignerInfo::SetCertificateUrlL( const TDesC8& aCertificateUrl,
+ const TDesC8& aSubjectKeyID )
+ {
+ CCMSAttribute* certUrl = CreateCertificateUrlLC( aCertificateUrl );
+
+ // remove possible URL from unsigned attributes
+ TInt unsignedAttCount = iData->iUnsignedAttributes->Count();
+ for( TInt i = 0; i < unsignedAttCount; i++ )
+ {
+ CCMSAttribute* att = iData->iUnsignedAttributes->At( i );
+ if( att->AttributeType() == KURLCertificateOID() )
+ {
+ iData->iUnsignedAttributes->Delete( i );
+ delete att;
+ }
+ }
+ iData->iUnsignedAttributes->AppendL( certUrl );
+ CleanupStack::Pop( certUrl );
+
+ // taking copy of subject key identifier
+ HBufC8* tmpSubjectKeyID = aSubjectKeyID.AllocL();
+
+ delete iData->iSubjectKeyIdentifier;
+ iData->iSubjectKeyIdentifier = tmpSubjectKeyID;
+
+ // Issuer and serial is only for real certificates
+ delete iData->iIssuerAndSerial;
+ iData->iIssuerAndSerial = NULL;
+
+ // changing version to 3
+ iData->iVersion = KCMSVersion3;
+ }
+
+// -----------------------------------------------------------------------------
+// CCMSSignerInfo::SetDigestAlgorithmIdentifier()
+// Setter for DigestAlgorithmIdentifier
+// -----------------------------------------------------------------------------
+EXPORT_C void CCMSSignerInfo::SetDigestAlgorithmIdentifier(
+ CCMSX509AlgorithmIdentifier& aDigestAI )
+ {
+ delete iData->iDigestAI;
+ iData->iDigestAI = &aDigestAI;
+ }
+
+// -----------------------------------------------------------------------------
+// CCMSSignerInfo::SetSignatureAlgorithmIdentifier()
+// Setter for SignatureAlgorithmIdentifier
+// -----------------------------------------------------------------------------
+EXPORT_C void CCMSSignerInfo::SetSignatureAlgorithmIdentifier(
+ CCMSX509AlgorithmIdentifier& aSignatureAI )
+ {
+ delete iData->iSignatureAI;
+ iData->iSignatureAI = &aSignatureAI;
+ }
+
+// -----------------------------------------------------------------------------
+// CCMSSignerInfo::SetSignatureValueL()
+// Setter for SignatureValue
+// -----------------------------------------------------------------------------
+EXPORT_C void CCMSSignerInfo::SetSignatureValueL( const TDesC8& aSignatureValue )
+ {
+ HBufC8* tmpSignValue = aSignatureValue.AllocL();
+ delete iData->iSignatureValue;
+ iData->iSignatureValue = tmpSignValue;
+ }
+
+// -----------------------------------------------------------------------------
+// CCMSSignerInfo::SetSignedAttributesL()
+// Setter for Signed attributes
+// -----------------------------------------------------------------------------
+EXPORT_C void CCMSSignerInfo::SetSignedAttributesL( const TDesC& aContentType,
+ const TDesC8& aMessageDigest,
+ const TTime& aSigningTime,
+ const TDesC8* aCertHash )
+ {
+ CArrayPtrFlat<CCMSAttribute>* tmpAttributes =
+ new(ELeave)CArrayPtrFlat<CCMSAttribute>( KDefaultGranularity );
+ CleanupStack::PushL( tmpAttributes );
+ CleanupResetAndDestroy< CArrayPtrFlat<CCMSAttribute> >::PushL( *tmpAttributes );
+
+
+ if( aContentType != KNullDesC() )
+ {
+ // creating content type
+ CASN1EncObjectIdentifier* contOid =
+ CASN1EncObjectIdentifier::NewLC( aContentType );
+ HBufC8* contentType = CreateDerEncodingL( contOid );
+ CleanupStack::PushL( contentType );
+ CCMSAttribute* contType = CCMSAttribute::NewLC( KContentTypeOID, *contentType );
+ tmpAttributes->AppendL( contType );
+ CleanupStack::Pop( contType );
+ CleanupStack::PopAndDestroy( contentType );
+ CleanupStack::PopAndDestroy( contOid );
+ }
+
+ if( aMessageDigest != KNullDesC8() )
+ {
+ // creating MessageDigest
+ CASN1EncOctetString* signature =
+ CASN1EncOctetString::NewLC( aMessageDigest );
+ HBufC8* messageDigest = CreateDerEncodingL( signature );
+ CleanupStack::PushL( messageDigest );
+ CCMSAttribute* mDigest = CCMSAttribute::NewLC( KMessageDigestOID, *messageDigest );
+ tmpAttributes->AppendL( mDigest );
+ CleanupStack::Pop( mDigest );
+ CleanupStack::PopAndDestroy( messageDigest );
+ CleanupStack::PopAndDestroy( signature );
+ }
+
+ // creating Signing time
+ CASN1EncBase* signTimeDER = TCMSTimeUtil::ConvertToEncoderLC( aSigningTime );
+ HBufC8* signTime = CreateDerEncodingL( signTimeDER );
+ CleanupStack::PushL( signTime );
+ CCMSAttribute* sTime = CCMSAttribute::NewLC( KSignTimeOID, *signTime );
+ tmpAttributes->AppendL( sTime );
+ CleanupStack::Pop( sTime );
+ CleanupStack::PopAndDestroy( signTime );
+ CleanupStack::PopAndDestroy( signTimeDER );
+
+ // are we adding certificates
+ if( aCertHash )
+ {
+ CCMSAttribute* signingCert =
+ CCMSAttribute::NewLC( KPKCS9SigCertOID, *aCertHash );
+ tmpAttributes->AppendL( signingCert );
+ CleanupStack::Pop( signingCert );
+ }
+
+ iData->iSignedAttributes->ResetAndDestroy();
+ delete iData->iSignedAttributes;
+ iData->iSignedAttributes = tmpAttributes;
+ CleanupStack::Pop( tmpAttributes ); // ResetAndDestroy
+ CleanupStack::Pop( tmpAttributes );
+ }
+
+// -----------------------------------------------------------------------------
+// CCMSSignerInfo::SetUnsignedAttributesL()
+// Setter for Unsigned attributes
+// -----------------------------------------------------------------------------
+EXPORT_C void CCMSSignerInfo::SetUnsignedAttributesL(
+ CArrayPtrFlat<CCMSAttribute>& aUnsignedAttributes )
+ {
+ iData->iUnsignedAttributes->ResetAndDestroy();
+ delete iData->iUnsignedAttributes;
+ iData->iUnsignedAttributes = &aUnsignedAttributes;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CCMSSignerInfo::DecodeAttributesL()
+// Decodes Attributes to array
+// -----------------------------------------------------------------------------
+void CCMSSignerInfo::DecodeAttributesL(
+ const TDesC8& aRawData,
+ CArrayPtrFlat<CCMSAttribute>* aAttributes )
+ {
+ TASN1DecSet attributeDec;
+ TInt pos = 0;
+ CArrayPtrFlat<TASN1DecGeneric>* attributes =
+ attributeDec.DecodeDERLC( aRawData, pos );
+
+ TInt numOfAttributes = attributes->Count();
+ for( TInt i = 0; i < numOfAttributes; i++ )
+ {
+ CCMSAttribute* att = CCMSAttribute::NewLC();
+ att->DecodeL( attributes->At( i )->Encoding() );
+ aAttributes->AppendL( att );
+ CleanupStack::Pop( att );
+ }
+ CleanupStack::PopAndDestroy( attributes );
+ }
+
+// -----------------------------------------------------------------------------
+// CCMSSignerInfo::CreateCertificateUrlLC()
+// Creates certificate url attribute
+// -----------------------------------------------------------------------------
+CCMSAttribute* CCMSSignerInfo::CreateCertificateUrlLC( const TDesC8& aCertificateUrl )
+ {
+ // Add certificate URL to unsigned attributes
+ CASN1EncOctetString* certificateUrlEnc =
+ CASN1EncOctetString::NewLC( aCertificateUrl );
+ //change tag to IA5
+ certificateUrlEnc->SetTag( EASN1IA5String );
+
+ HBufC8* certificateURL = CreateDerEncodingL( certificateUrlEnc );
+ CleanupStack::PushL( certificateURL );
+ CCMSAttribute* certUrl = CCMSAttribute::NewL( KURLCertificateOID, *certificateURL );
+ CleanupStack::PopAndDestroy( certificateURL );
+ CleanupStack::PopAndDestroy( certificateUrlEnc );
+ CleanupStack::PushL( certUrl );
+ return certUrl;
+ }
+// End of File