--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cms/src/CCMSKeyAgreeRecipientInfo.cpp Tue Jan 26 15:20:08 2010 +0200
@@ -0,0 +1,482 @@
+/*
+* Copyright (c) 2004 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 "CCMSKeyAgreeRecipientInfo.h"
+#include "CCMSX509AlgorithmIdentifier.h"
+#include "CCMSOriginatorIdentifierOrKey.h"
+#include "CCMSRecipientEncryptedKey.h"
+#include <asn1dec.h>
+#include <asn1enc.h>
+
+// CONSTANTS
+const TInt KMinNumberOfSubModules = 4;
+const TInt KMaxNumberOfSubModules = 5;
+const TTagType KOriginatorTag = 0;
+const TTagType KUkmTag = 1;
+const TInt KDefaultGranularity = 1;
+
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CCMSKeyAgreeRecipientInfo::CCMSKeyAgreeRecipientInfo
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CCMSKeyAgreeRecipientInfo::CCMSKeyAgreeRecipientInfo( )
+ : CCMSRecipientInfo( KCMSKeyAgreeRecipientInfoVersion )
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CCMSKeyAgreeRecipientInfo::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CCMSKeyAgreeRecipientInfo::ConstructL( )
+ {
+ // creates empty/default values
+ CCMSX509AlgorithmIdentifier* algorithm = CCMSX509AlgorithmIdentifier::NewL( );
+ CleanupStack::PushL( algorithm );
+ BaseConstructL( *algorithm );
+ CleanupStack::PopAndDestroy( algorithm );
+
+ iOriginator = CCMSOriginatorIdentifierOrKey::NewL( );
+ iRecipientEncryptedKeys = new( ELeave )
+ CArrayPtrFlat< CCMSRecipientEncryptedKey >( KDefaultGranularity );
+ }
+
+// -----------------------------------------------------------------------------
+// CCMSKeyAgreeRecipientInfo::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CCMSKeyAgreeRecipientInfo::ConstructL(
+ const CCMSOriginatorIdentifierOrKey& aOriginator,
+ const CCMSX509AlgorithmIdentifier& aKeyEncryptionAlgorithm,
+ const CArrayPtr< CCMSRecipientEncryptedKey >& aRecipientEncryptedKeys )
+ {
+ BaseConstructL( aKeyEncryptionAlgorithm );
+ SetOriginatorL( aOriginator );
+ SetRecipientEncryptedKeysL( aRecipientEncryptedKeys );
+ }
+
+// -----------------------------------------------------------------------------
+// CCMSKeyAgreeRecipientInfo::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CCMSKeyAgreeRecipientInfo::ConstructL(
+ const CCMSOriginatorIdentifierOrKey& aOriginator,
+ const TDesC8& aUkm,
+ const CCMSX509AlgorithmIdentifier& aKeyEncryptionAlgorithm,
+ const CArrayPtr< CCMSRecipientEncryptedKey >& aRecipientEncryptedKeys )
+ {
+ ConstructL( aOriginator, aKeyEncryptionAlgorithm, aRecipientEncryptedKeys );
+ SetUserKeyingMaterialL( aUkm );
+ }
+
+// -----------------------------------------------------------------------------
+// CCMSKeyAgreeRecipientInfo::NewLC
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CCMSKeyAgreeRecipientInfo* CCMSKeyAgreeRecipientInfo::NewLC()
+ {
+ // creating with empty/default values
+ CCMSKeyAgreeRecipientInfo* self = new( ELeave ) CCMSKeyAgreeRecipientInfo( );
+ CleanupStack::PushL( self );
+ self->ConstructL( );
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CCMSKeyAgreeRecipientInfo::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CCMSKeyAgreeRecipientInfo* CCMSKeyAgreeRecipientInfo::NewL()
+ {
+ // creating with empty/default values
+ CCMSKeyAgreeRecipientInfo* self = NewLC();
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CCMSKeyAgreeRecipientInfo::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CCMSKeyAgreeRecipientInfo* CCMSKeyAgreeRecipientInfo::NewL(
+ const CCMSOriginatorIdentifierOrKey& aOriginator,
+ const CCMSX509AlgorithmIdentifier& aKeyEncryptionAlgorithm,
+ const CArrayPtr< CCMSRecipientEncryptedKey >& aRecipientEncryptedKeys )
+ {
+ CCMSKeyAgreeRecipientInfo* self =
+ new( ELeave ) CCMSKeyAgreeRecipientInfo( );
+
+ CleanupStack::PushL( self );
+ self->ConstructL( aOriginator, aKeyEncryptionAlgorithm,
+ aRecipientEncryptedKeys );
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CCMSKeyAgreeRecipientInfo::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CCMSKeyAgreeRecipientInfo* CCMSKeyAgreeRecipientInfo::NewL(
+ const CCMSOriginatorIdentifierOrKey& aOriginator,
+ const TDesC8& aUkm,
+ const CCMSX509AlgorithmIdentifier& aKeyEncryptionAlgorithm,
+ const CArrayPtr< CCMSRecipientEncryptedKey >& aRecipientEncryptedKeys )
+ {
+ CCMSKeyAgreeRecipientInfo* self =
+ new( ELeave ) CCMSKeyAgreeRecipientInfo( );
+
+ CleanupStack::PushL( self );
+ self->ConstructL( aOriginator,aUkm, aKeyEncryptionAlgorithm,
+ aRecipientEncryptedKeys );
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+
+// Destructor
+CCMSKeyAgreeRecipientInfo::~CCMSKeyAgreeRecipientInfo()
+ {
+ delete iOriginator;
+ delete iKeyEncryptionAlgorithm;
+ if( iRecipientEncryptedKeys )
+ {
+ iRecipientEncryptedKeys->ResetAndDestroy();
+ delete iRecipientEncryptedKeys;
+ }
+ delete iUserKeyingMaterial;
+ }
+
+// -----------------------------------------------------------------------------
+// CCMSKeyAgreeRecipientInfo::DecodeL
+// Decrypts raw data to this instance
+// -----------------------------------------------------------------------------
+void CCMSKeyAgreeRecipientInfo::DecodeL( const TDesC8& aRawData )
+ {
+ TASN1DecGeneric decGen( aRawData );
+ decGen.InitL();
+ // accept only sequence or implicit [1] tag
+ if( ( decGen.Tag() != EASN1Sequence ) &&
+ ( decGen.Tag() != KCMSKeyAgreeRecipientInfoTag ) )
+ {
+ User::Leave( KErrArgument );
+ }
+ TASN1DecSequence decSeq;
+ CArrayPtr< TASN1DecGeneric >* itemsData = decSeq.DecodeDERLC( decGen );
+ TInt count = itemsData->Count();
+ if( ( count < KMinNumberOfSubModules ) ||
+ ( count > KMaxNumberOfSubModules ) )
+ {
+ User::Leave( KErrArgument );
+ }
+
+ TInt sequenceCounter = 0;
+
+ // Decode version
+ TASN1DecGeneric versionDec( *itemsData->At( sequenceCounter++ ) );
+ versionDec.InitL();
+ TASN1DecInteger intDecoder;
+ TInt version = intDecoder.DecodeDERShortL( versionDec );
+
+ // decode originator [0] EXPLICIT OriginatorIdentifierOrKey
+ TASN1DecGeneric taggedOriginatorDec( *itemsData->At( sequenceCounter++ ) );
+ if( taggedOriginatorDec.Tag() != KOriginatorTag )
+ {
+ User::Leave( KErrArgument );
+ }
+ CCMSOriginatorIdentifierOrKey* originator =
+ CCMSOriginatorIdentifierOrKey::NewL();
+ CleanupStack::PushL( originator );
+ originator->DecodeL( taggedOriginatorDec.GetContentDER() );
+
+ // decode ukm [1] EXPLICIT UserKeyingMaterial OPTIONAL
+ HBufC8* ukm = NULL;
+ TASN1DecGeneric taggedUkmDec( *itemsData->At( sequenceCounter ) );
+ if( taggedUkmDec.Tag() == KUkmTag )
+ {
+ TASN1DecOctetString octetStringDecoder;
+ TASN1DecGeneric ukmDec( taggedUkmDec.GetContentDER() );
+ ukmDec.InitL();
+ ukm = octetStringDecoder.DecodeDERL( ukmDec );
+ CleanupStack::PushL( ukm );
+ sequenceCounter++;
+ if( itemsData->Count() < KMaxNumberOfSubModules )
+ {
+ User::Leave( KErrArgument );
+ }
+ }
+
+ // decode keyEncryptionAlgorithm
+ CCMSX509AlgorithmIdentifier* algId = CCMSX509AlgorithmIdentifier::NewL();
+ CleanupStack::PushL( algId );
+ algId->DecodeL( itemsData->At( sequenceCounter++ )->Encoding() );
+
+ // decode recipientEncryptedKeys
+ CArrayPtr< TASN1DecGeneric >* keysData =
+ DecodeSequenceLC( itemsData->At( sequenceCounter )->Encoding() );
+ TInt keyCount = keysData->Count();
+ CArrayPtr< CCMSRecipientEncryptedKey >* keys = NULL;
+ if( keyCount > 0 )
+ {
+ keys = new( ELeave ) CArrayPtrFlat< CCMSRecipientEncryptedKey >(
+ keyCount );
+ CleanupStack::PushL( keys );
+
+ for( TInt i = 0; i < keyCount; i++ )
+ {
+ CCMSRecipientEncryptedKey* key = CCMSRecipientEncryptedKey::NewL();
+ CleanupStack::PushL( key );
+ key->DecodeL( keysData->At( i )->Encoding() );
+ keys->AppendL( key );
+ }
+ CleanupStack::Pop( keyCount ); // key
+ }
+ else
+ {
+ keys = new( ELeave ) CArrayPtrFlat< CCMSRecipientEncryptedKey >( 1 );
+ CleanupStack::PushL( keys );
+ }
+
+ // everything has been decoded, now we can change state
+ iVersion = version;
+ delete iOriginator;
+ iOriginator = originator;
+ delete iUserKeyingMaterial;
+ iUserKeyingMaterial = ukm;
+ delete iKeyEncryptionAlgorithm;
+ iKeyEncryptionAlgorithm = algId;
+ if( iRecipientEncryptedKeys )
+ {
+ iRecipientEncryptedKeys->ResetAndDestroy();
+ delete iRecipientEncryptedKeys;
+ }
+ iRecipientEncryptedKeys = keys;
+
+ CleanupStack::Pop( keys );
+ CleanupStack::PopAndDestroy( keysData );
+ CleanupStack::Pop( algId );
+ if( ukm )
+ {
+ CleanupStack::Pop( ukm );
+ }
+ CleanupStack::Pop( originator );
+ CleanupStack::PopAndDestroy( itemsData );
+ }
+
+// -----------------------------------------------------------------------------
+// CCMSKeyAgreeRecipientInfo::EncoderLC
+// Returns ASN1 encoder for this instance
+// -----------------------------------------------------------------------------
+
+CASN1EncBase* CCMSKeyAgreeRecipientInfo::EncoderLC() const
+ {
+ CASN1EncSequence* root = CASN1EncSequence::NewLC();
+
+ // encode version
+ AddVersionL( root );
+
+ // encode originator [0] EXPLICIT OriginatorIdentifierOrKey,
+ CASN1EncBase* originator = iOriginator->EncoderLC();
+
+ // CASN1EncExplicitTag takes ownership of originator even when leaving
+ CleanupStack::Pop( originator );
+ CASN1EncExplicitTag* taggedOriginator =
+ CASN1EncExplicitTag::NewLC( originator, KOriginatorTag );
+ root->AddAndPopChildL( taggedOriginator );
+
+ // encode ukm [1] EXPLICIT UserKeyingMaterial OPTIONAL
+ if( iUserKeyingMaterial )
+ {
+ CASN1EncOctetString* ukm =
+ CASN1EncOctetString::NewL( *iUserKeyingMaterial );
+ CASN1EncExplicitTag* taggedUkm =
+ CASN1EncExplicitTag::NewLC( ukm, KUkmTag );
+ root->AddAndPopChildL( taggedUkm );
+ }
+
+ // encode keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier
+ AddKeyEncryptionAlgorithmL( root );
+
+ // encode RecipientEncryptedKeys ::= SEQUENCE OF RecipientEncryptedKey
+ CASN1EncSequence* recipientEncryptedKeys = CASN1EncSequence::NewLC();
+ TInt keyCount = iRecipientEncryptedKeys->Count();
+ for( TInt i = 0; i < keyCount; i++ )
+ {
+ HBufC8* encodedKey = NULL;
+ iRecipientEncryptedKeys->At( i )->EncodeL( encodedKey );
+ CleanupStack::PushL( encodedKey );
+ CASN1EncEncoding* singleKey = CASN1EncEncoding::NewLC( *encodedKey );
+ recipientEncryptedKeys->AddAndPopChildL( singleKey );
+ CleanupStack::PopAndDestroy( encodedKey );
+ }
+ root->AddAndPopChildL( recipientEncryptedKeys );
+
+ return root;
+ }
+
+// -----------------------------------------------------------------------------
+// CCMSKeyAgreeRecipientInfo::TaggedEncoderLC
+// Returns ASN1 encoder for this instance inside tag
+// -----------------------------------------------------------------------------
+CASN1EncBase* CCMSKeyAgreeRecipientInfo::TaggedEncoderLC() const
+ {
+ CASN1EncBase* encoder = EncoderLC();
+ encoder->SetTag( KCMSKeyAgreeRecipientInfoTag );
+ return encoder;
+ }
+
+// -----------------------------------------------------------------------------
+// CCMSKeyAgreeRecipientInfo::Originator
+// Originator getter
+// -----------------------------------------------------------------------------
+EXPORT_C const CCMSOriginatorIdentifierOrKey&
+CCMSKeyAgreeRecipientInfo::Originator() const
+ {
+ return *iOriginator;
+ }
+
+// -----------------------------------------------------------------------------
+// CCMSKeyAgreeRecipientInfo::RecipientEncryptedKeys
+// RecipientEncryptedKeys getter
+// -----------------------------------------------------------------------------
+EXPORT_C const CArrayPtr< CCMSRecipientEncryptedKey >&
+CCMSKeyAgreeRecipientInfo::RecipientEncryptedKeys() const
+ {
+ return *iRecipientEncryptedKeys;
+ }
+
+// -----------------------------------------------------------------------------
+// CCMSKeyAgreeRecipientInfo::UserKeyingMaterial
+// UserKeyingMaterial getter
+// -----------------------------------------------------------------------------
+EXPORT_C const TDesC8*
+CCMSKeyAgreeRecipientInfo::UserKeyingMaterial() const
+ {
+ return iUserKeyingMaterial;
+ }
+
+// -----------------------------------------------------------------------------
+// CCMSKeyAgreeRecipientInfo::SetOriginatorL
+// Originator setter
+// -----------------------------------------------------------------------------
+EXPORT_C void CCMSKeyAgreeRecipientInfo::SetOriginatorL(
+ const CCMSOriginatorIdentifierOrKey& aOriginator )
+ {
+ CCMSOriginatorIdentifierOrKey* originator = NULL;
+ switch( aOriginator.Type() )
+ {
+ case CCMSOriginatorIdentifierOrKey::ESubjectKeyIdentifier:
+ {
+ originator = CCMSOriginatorIdentifierOrKey::NewL(
+ aOriginator.SubjectKeyIdentifierL() );
+ break;
+ }
+ case CCMSOriginatorIdentifierOrKey::EOriginatorKey:
+ {
+ originator = CCMSOriginatorIdentifierOrKey::NewL(
+ aOriginator.OriginatorKeyL() );
+ break;
+ }
+ case CCMSOriginatorIdentifierOrKey::EIssuerAndSerialNumber:
+ {
+ originator = CCMSOriginatorIdentifierOrKey::NewL(
+ aOriginator.IssuerAndSerialNumberL() );
+ break;
+ }
+ default:
+ {
+ User::Leave( KErrArgument );
+ }
+ }
+ delete iOriginator;
+ iOriginator = originator;
+ }
+
+// -----------------------------------------------------------------------------
+// CCMSKeyAgreeRecipientInfo::SetRecipientEncryptedKeysL
+// RecipientEncryptedKeys setter, deep copy
+// -----------------------------------------------------------------------------
+EXPORT_C void CCMSKeyAgreeRecipientInfo::SetRecipientEncryptedKeysL(
+ const CArrayPtr< CCMSRecipientEncryptedKey >& aRecipientEncryptedKeys )
+ {
+ TInt keyCount = aRecipientEncryptedKeys.Count();
+ CArrayPtr< CCMSRecipientEncryptedKey >* keys = NULL;
+ if( keyCount > 0 )
+ {
+ keys = new( ELeave ) CArrayPtrFlat< CCMSRecipientEncryptedKey >(
+ keyCount );
+ CleanupStack::PushL( keys );
+ for( TInt i = 0; i < keyCount; i++ )
+ {
+ const CCMSRecipientEncryptedKey* key = aRecipientEncryptedKeys[ i ];
+ const CCMSIssuerAndSerialNumber* issuer = key->IssuerAndSerialNumber();
+ const TDesC8& encryptedKey = key->EncryptedKey();
+ CCMSRecipientEncryptedKey* newKey = NULL;
+ if( issuer )
+ {
+ newKey = CCMSRecipientEncryptedKey::NewL(
+ *issuer, encryptedKey );
+ }
+ else
+ {
+ newKey = CCMSRecipientEncryptedKey::NewL( *( key->RKeyId() ),
+ encryptedKey );
+ }
+ CleanupStack::PushL( newKey );
+ keys->AppendL( newKey );
+ }
+ CleanupStack::Pop( keyCount ); // newKeys
+ CleanupStack::Pop( keys );
+ }
+ else
+ {
+ keys = new( ELeave ) CArrayPtrFlat< CCMSRecipientEncryptedKey >( 1 );
+ }
+ if( iRecipientEncryptedKeys )
+ {
+ iRecipientEncryptedKeys->ResetAndDestroy();
+ delete iRecipientEncryptedKeys;
+ }
+ iRecipientEncryptedKeys = keys;
+ }
+// -----------------------------------------------------------------------------
+// CCMSKeyAgreeRecipientInfo::SetUserKeyingMaterialL
+// UserKeyingMaterial setter.
+// -----------------------------------------------------------------------------
+EXPORT_C void CCMSKeyAgreeRecipientInfo::SetUserKeyingMaterialL(
+ const TDesC8& aUkm )
+ {
+ HBufC8* ukm = aUkm.AllocL();
+ delete iUserKeyingMaterial;
+ iUserKeyingMaterial = ukm;
+ }
+
+// End of File