cms/src/CCMSKeyAgreeRecipientInfo.cpp
changeset 0 164170e6151a
equal deleted inserted replaced
-1:000000000000 0:164170e6151a
       
     1 /*
       
     2 * Copyright (c) 2004 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 #include    "CCMSKeyAgreeRecipientInfo.h"
       
    21 #include "CCMSX509AlgorithmIdentifier.h"
       
    22 #include "CCMSOriginatorIdentifierOrKey.h"
       
    23 #include "CCMSRecipientEncryptedKey.h"
       
    24 #include <asn1dec.h>
       
    25 #include <asn1enc.h>
       
    26 
       
    27 // CONSTANTS
       
    28 const TInt KMinNumberOfSubModules = 4;
       
    29 const TInt KMaxNumberOfSubModules = 5;
       
    30 const TTagType KOriginatorTag = 0;
       
    31 const TTagType KUkmTag = 1;
       
    32 const TInt KDefaultGranularity = 1;
       
    33 
       
    34 
       
    35 // ============================ MEMBER FUNCTIONS ===============================
       
    36 
       
    37 // -----------------------------------------------------------------------------
       
    38 // CCMSKeyAgreeRecipientInfo::CCMSKeyAgreeRecipientInfo
       
    39 // C++ default constructor can NOT contain any code, that
       
    40 // might leave.
       
    41 // -----------------------------------------------------------------------------
       
    42 //
       
    43 EXPORT_C CCMSKeyAgreeRecipientInfo::CCMSKeyAgreeRecipientInfo( )
       
    44     : CCMSRecipientInfo( KCMSKeyAgreeRecipientInfoVersion )
       
    45     {
       
    46     }
       
    47 
       
    48 // -----------------------------------------------------------------------------
       
    49 // CCMSKeyAgreeRecipientInfo::ConstructL
       
    50 // Symbian 2nd phase constructor can leave.
       
    51 // -----------------------------------------------------------------------------
       
    52 //
       
    53 EXPORT_C void CCMSKeyAgreeRecipientInfo::ConstructL( )
       
    54     {
       
    55     // creates empty/default values
       
    56     CCMSX509AlgorithmIdentifier* algorithm = CCMSX509AlgorithmIdentifier::NewL( );
       
    57     CleanupStack::PushL( algorithm );
       
    58     BaseConstructL( *algorithm );
       
    59     CleanupStack::PopAndDestroy( algorithm );
       
    60 
       
    61     iOriginator = CCMSOriginatorIdentifierOrKey::NewL( );
       
    62     iRecipientEncryptedKeys = new( ELeave )
       
    63         CArrayPtrFlat< CCMSRecipientEncryptedKey >( KDefaultGranularity );
       
    64     }
       
    65 
       
    66 // -----------------------------------------------------------------------------
       
    67 // CCMSKeyAgreeRecipientInfo::ConstructL
       
    68 // Symbian 2nd phase constructor can leave.
       
    69 // -----------------------------------------------------------------------------
       
    70 //
       
    71 EXPORT_C void CCMSKeyAgreeRecipientInfo::ConstructL(
       
    72     const CCMSOriginatorIdentifierOrKey& aOriginator,
       
    73     const CCMSX509AlgorithmIdentifier& aKeyEncryptionAlgorithm,
       
    74     const CArrayPtr< CCMSRecipientEncryptedKey >& aRecipientEncryptedKeys )
       
    75     {
       
    76     BaseConstructL( aKeyEncryptionAlgorithm );
       
    77     SetOriginatorL( aOriginator );
       
    78     SetRecipientEncryptedKeysL( aRecipientEncryptedKeys );
       
    79     }
       
    80 
       
    81 // -----------------------------------------------------------------------------
       
    82 // CCMSKeyAgreeRecipientInfo::ConstructL
       
    83 // Symbian 2nd phase constructor can leave.
       
    84 // -----------------------------------------------------------------------------
       
    85 //
       
    86 EXPORT_C void CCMSKeyAgreeRecipientInfo::ConstructL(
       
    87     const CCMSOriginatorIdentifierOrKey& aOriginator,
       
    88     const TDesC8& aUkm,
       
    89     const CCMSX509AlgorithmIdentifier& aKeyEncryptionAlgorithm,
       
    90     const CArrayPtr< CCMSRecipientEncryptedKey >& aRecipientEncryptedKeys )
       
    91     {
       
    92     ConstructL( aOriginator, aKeyEncryptionAlgorithm, aRecipientEncryptedKeys );
       
    93     SetUserKeyingMaterialL( aUkm );
       
    94     }
       
    95 
       
    96 // -----------------------------------------------------------------------------
       
    97 // CCMSKeyAgreeRecipientInfo::NewLC
       
    98 // Two-phased constructor.
       
    99 // -----------------------------------------------------------------------------
       
   100 //
       
   101 EXPORT_C CCMSKeyAgreeRecipientInfo* CCMSKeyAgreeRecipientInfo::NewLC()
       
   102 	{
       
   103 	// creating with empty/default values
       
   104     CCMSKeyAgreeRecipientInfo* self = new( ELeave ) CCMSKeyAgreeRecipientInfo( );
       
   105     CleanupStack::PushL( self );
       
   106     self->ConstructL( );
       
   107     return self;
       
   108 	}
       
   109 
       
   110 // -----------------------------------------------------------------------------
       
   111 // CCMSKeyAgreeRecipientInfo::NewL
       
   112 // Two-phased constructor.
       
   113 // -----------------------------------------------------------------------------
       
   114 //
       
   115 EXPORT_C CCMSKeyAgreeRecipientInfo* CCMSKeyAgreeRecipientInfo::NewL()
       
   116 	{
       
   117 	// creating with empty/default values
       
   118     CCMSKeyAgreeRecipientInfo* self = NewLC();
       
   119     CleanupStack::Pop( self );
       
   120     return self;
       
   121 	}
       
   122 
       
   123 // -----------------------------------------------------------------------------
       
   124 // CCMSKeyAgreeRecipientInfo::NewL
       
   125 // Two-phased constructor.
       
   126 // -----------------------------------------------------------------------------
       
   127 //
       
   128 EXPORT_C CCMSKeyAgreeRecipientInfo* CCMSKeyAgreeRecipientInfo::NewL(
       
   129     const CCMSOriginatorIdentifierOrKey& aOriginator,
       
   130     const CCMSX509AlgorithmIdentifier& aKeyEncryptionAlgorithm,
       
   131     const CArrayPtr< CCMSRecipientEncryptedKey >& aRecipientEncryptedKeys )
       
   132 	{
       
   133     CCMSKeyAgreeRecipientInfo* self =
       
   134     	new( ELeave ) CCMSKeyAgreeRecipientInfo( );
       
   135 
       
   136     CleanupStack::PushL( self );
       
   137     self->ConstructL( aOriginator, aKeyEncryptionAlgorithm,
       
   138                       aRecipientEncryptedKeys );
       
   139     CleanupStack::Pop( self );
       
   140 	return self;
       
   141 	}
       
   142 
       
   143 // -----------------------------------------------------------------------------
       
   144 // CCMSKeyAgreeRecipientInfo::NewL
       
   145 // Two-phased constructor.
       
   146 // -----------------------------------------------------------------------------
       
   147 //
       
   148 EXPORT_C CCMSKeyAgreeRecipientInfo* CCMSKeyAgreeRecipientInfo::NewL(
       
   149     const CCMSOriginatorIdentifierOrKey& aOriginator,
       
   150     const TDesC8& aUkm,
       
   151     const CCMSX509AlgorithmIdentifier& aKeyEncryptionAlgorithm,
       
   152     const CArrayPtr< CCMSRecipientEncryptedKey >& aRecipientEncryptedKeys )
       
   153 	{
       
   154     CCMSKeyAgreeRecipientInfo* self =
       
   155     	new( ELeave ) CCMSKeyAgreeRecipientInfo( );
       
   156 
       
   157     CleanupStack::PushL( self );
       
   158     self->ConstructL( aOriginator,aUkm, aKeyEncryptionAlgorithm,
       
   159                       aRecipientEncryptedKeys );
       
   160     CleanupStack::Pop( self );
       
   161 	return self;
       
   162 	}
       
   163 
       
   164 
       
   165 // Destructor
       
   166 CCMSKeyAgreeRecipientInfo::~CCMSKeyAgreeRecipientInfo()
       
   167     {
       
   168 	delete iOriginator;
       
   169     delete iKeyEncryptionAlgorithm;
       
   170     if( iRecipientEncryptedKeys )
       
   171         {
       
   172         iRecipientEncryptedKeys->ResetAndDestroy();
       
   173         delete iRecipientEncryptedKeys;
       
   174         }
       
   175     delete iUserKeyingMaterial;
       
   176     }
       
   177 
       
   178 // -----------------------------------------------------------------------------
       
   179 // CCMSKeyAgreeRecipientInfo::DecodeL
       
   180 // Decrypts raw data to this instance
       
   181 // -----------------------------------------------------------------------------
       
   182 void CCMSKeyAgreeRecipientInfo::DecodeL( const TDesC8& aRawData )
       
   183 	{
       
   184     TASN1DecGeneric decGen( aRawData );
       
   185     decGen.InitL();
       
   186     // accept only sequence or implicit [1] tag
       
   187     if( ( decGen.Tag() != EASN1Sequence ) &&
       
   188         ( decGen.Tag() != KCMSKeyAgreeRecipientInfoTag ) )
       
   189         {
       
   190         User::Leave( KErrArgument );
       
   191         }
       
   192     TASN1DecSequence decSeq;
       
   193     CArrayPtr< TASN1DecGeneric >* itemsData = decSeq.DecodeDERLC( decGen );
       
   194     TInt count = itemsData->Count();
       
   195     if( ( count < KMinNumberOfSubModules ) ||
       
   196         ( count > KMaxNumberOfSubModules ) )
       
   197         {
       
   198         User::Leave( KErrArgument );
       
   199         }
       
   200 
       
   201     TInt sequenceCounter = 0;
       
   202 
       
   203     // Decode version
       
   204     TASN1DecGeneric versionDec( *itemsData->At( sequenceCounter++ ) );
       
   205     versionDec.InitL();
       
   206     TASN1DecInteger intDecoder;
       
   207     TInt version = intDecoder.DecodeDERShortL( versionDec );
       
   208 
       
   209     // decode originator [0] EXPLICIT OriginatorIdentifierOrKey
       
   210     TASN1DecGeneric taggedOriginatorDec( *itemsData->At( sequenceCounter++ ) );
       
   211     if( taggedOriginatorDec.Tag() != KOriginatorTag )
       
   212         {
       
   213         User::Leave( KErrArgument );
       
   214         }
       
   215     CCMSOriginatorIdentifierOrKey* originator =
       
   216         CCMSOriginatorIdentifierOrKey::NewL();
       
   217     CleanupStack::PushL( originator );
       
   218     originator->DecodeL( taggedOriginatorDec.GetContentDER() );
       
   219 
       
   220     // decode ukm [1] EXPLICIT UserKeyingMaterial OPTIONAL
       
   221     HBufC8* ukm = NULL;
       
   222     TASN1DecGeneric taggedUkmDec( *itemsData->At( sequenceCounter ) );
       
   223     if( taggedUkmDec.Tag() == KUkmTag )
       
   224         {
       
   225         TASN1DecOctetString octetStringDecoder;
       
   226         TASN1DecGeneric ukmDec( taggedUkmDec.GetContentDER() );
       
   227         ukmDec.InitL();
       
   228         ukm = octetStringDecoder.DecodeDERL( ukmDec );
       
   229         CleanupStack::PushL( ukm );
       
   230         sequenceCounter++;
       
   231         if( itemsData->Count() < KMaxNumberOfSubModules )
       
   232             {
       
   233             User::Leave( KErrArgument );
       
   234             }
       
   235         }
       
   236 
       
   237     // decode keyEncryptionAlgorithm
       
   238     CCMSX509AlgorithmIdentifier* algId = CCMSX509AlgorithmIdentifier::NewL();
       
   239     CleanupStack::PushL( algId );
       
   240     algId->DecodeL( itemsData->At( sequenceCounter++ )->Encoding() );
       
   241 
       
   242     // decode recipientEncryptedKeys
       
   243     CArrayPtr< TASN1DecGeneric >* keysData =
       
   244         DecodeSequenceLC( itemsData->At( sequenceCounter )->Encoding() );
       
   245     TInt keyCount = keysData->Count();
       
   246     CArrayPtr< CCMSRecipientEncryptedKey >* keys = NULL;
       
   247     if( keyCount > 0 )
       
   248         {
       
   249         keys = new( ELeave ) CArrayPtrFlat< CCMSRecipientEncryptedKey >(
       
   250             keyCount );
       
   251         CleanupStack::PushL( keys );
       
   252 
       
   253         for( TInt i = 0; i < keyCount; i++ )
       
   254             {
       
   255             CCMSRecipientEncryptedKey* key = CCMSRecipientEncryptedKey::NewL();
       
   256             CleanupStack::PushL( key );
       
   257             key->DecodeL( keysData->At( i )->Encoding() );
       
   258             keys->AppendL( key );
       
   259             }
       
   260         CleanupStack::Pop( keyCount ); // key
       
   261         }
       
   262     else
       
   263         {
       
   264         keys = new( ELeave ) CArrayPtrFlat< CCMSRecipientEncryptedKey >( 1 );
       
   265         CleanupStack::PushL( keys );
       
   266         }
       
   267 
       
   268     // everything has been decoded, now we can change state
       
   269     iVersion = version;
       
   270     delete iOriginator;
       
   271     iOriginator = originator;
       
   272     delete iUserKeyingMaterial;
       
   273     iUserKeyingMaterial = ukm;
       
   274     delete iKeyEncryptionAlgorithm;
       
   275     iKeyEncryptionAlgorithm = algId;
       
   276     if( iRecipientEncryptedKeys )
       
   277         {
       
   278         iRecipientEncryptedKeys->ResetAndDestroy();
       
   279         delete iRecipientEncryptedKeys;
       
   280         }
       
   281     iRecipientEncryptedKeys = keys;
       
   282 
       
   283     CleanupStack::Pop( keys );
       
   284     CleanupStack::PopAndDestroy( keysData );
       
   285     CleanupStack::Pop( algId );
       
   286     if( ukm )
       
   287         {
       
   288         CleanupStack::Pop( ukm );
       
   289         }
       
   290     CleanupStack::Pop( originator );
       
   291     CleanupStack::PopAndDestroy( itemsData );
       
   292 	}
       
   293 
       
   294 // -----------------------------------------------------------------------------
       
   295 // CCMSKeyAgreeRecipientInfo::EncoderLC
       
   296 // Returns ASN1 encoder for this instance
       
   297 // -----------------------------------------------------------------------------
       
   298 
       
   299 CASN1EncBase* CCMSKeyAgreeRecipientInfo::EncoderLC() const
       
   300 	{
       
   301     CASN1EncSequence* root = CASN1EncSequence::NewLC();
       
   302 
       
   303     // encode version
       
   304     AddVersionL( root );
       
   305 
       
   306     // encode originator [0] EXPLICIT OriginatorIdentifierOrKey,
       
   307     CASN1EncBase* originator = iOriginator->EncoderLC();
       
   308 
       
   309     // CASN1EncExplicitTag takes ownership of originator even when leaving
       
   310     CleanupStack::Pop( originator );
       
   311     CASN1EncExplicitTag* taggedOriginator =
       
   312         CASN1EncExplicitTag::NewLC( originator, KOriginatorTag );
       
   313     root->AddAndPopChildL( taggedOriginator );
       
   314 
       
   315     // encode ukm [1] EXPLICIT UserKeyingMaterial OPTIONAL
       
   316     if( iUserKeyingMaterial )
       
   317         {
       
   318         CASN1EncOctetString* ukm =
       
   319             CASN1EncOctetString::NewL( *iUserKeyingMaterial );
       
   320         CASN1EncExplicitTag* taggedUkm =
       
   321             CASN1EncExplicitTag::NewLC( ukm, KUkmTag );
       
   322         root->AddAndPopChildL( taggedUkm );
       
   323         }
       
   324 
       
   325     // encode keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier
       
   326     AddKeyEncryptionAlgorithmL( root );
       
   327 
       
   328     // encode RecipientEncryptedKeys ::= SEQUENCE OF RecipientEncryptedKey
       
   329     CASN1EncSequence* recipientEncryptedKeys = CASN1EncSequence::NewLC();
       
   330     TInt keyCount = iRecipientEncryptedKeys->Count();
       
   331     for( TInt i = 0; i < keyCount; i++ )
       
   332         {
       
   333         HBufC8* encodedKey = NULL;
       
   334         iRecipientEncryptedKeys->At( i )->EncodeL( encodedKey );
       
   335         CleanupStack::PushL( encodedKey );
       
   336         CASN1EncEncoding* singleKey = CASN1EncEncoding::NewLC( *encodedKey );
       
   337         recipientEncryptedKeys->AddAndPopChildL( singleKey );
       
   338         CleanupStack::PopAndDestroy( encodedKey );
       
   339         }
       
   340     root->AddAndPopChildL( recipientEncryptedKeys );
       
   341 
       
   342     return root;
       
   343 	}
       
   344 
       
   345 // -----------------------------------------------------------------------------
       
   346 // CCMSKeyAgreeRecipientInfo::TaggedEncoderLC
       
   347 // Returns ASN1 encoder for this instance inside tag
       
   348 // -----------------------------------------------------------------------------
       
   349 CASN1EncBase* CCMSKeyAgreeRecipientInfo::TaggedEncoderLC() const
       
   350     {
       
   351     CASN1EncBase* encoder = EncoderLC();
       
   352     encoder->SetTag( KCMSKeyAgreeRecipientInfoTag );
       
   353     return encoder;
       
   354     }
       
   355 
       
   356 // -----------------------------------------------------------------------------
       
   357 // CCMSKeyAgreeRecipientInfo::Originator
       
   358 // Originator getter
       
   359 // -----------------------------------------------------------------------------
       
   360 EXPORT_C const CCMSOriginatorIdentifierOrKey&
       
   361 CCMSKeyAgreeRecipientInfo::Originator() const
       
   362 	{
       
   363 	return *iOriginator;
       
   364 	}
       
   365 
       
   366 // -----------------------------------------------------------------------------
       
   367 // CCMSKeyAgreeRecipientInfo::RecipientEncryptedKeys
       
   368 // RecipientEncryptedKeys getter
       
   369 // -----------------------------------------------------------------------------
       
   370 EXPORT_C const CArrayPtr< CCMSRecipientEncryptedKey >&
       
   371 CCMSKeyAgreeRecipientInfo::RecipientEncryptedKeys() const
       
   372 	{
       
   373 	return *iRecipientEncryptedKeys;
       
   374 	}
       
   375 
       
   376 // -----------------------------------------------------------------------------
       
   377 // CCMSKeyAgreeRecipientInfo::UserKeyingMaterial
       
   378 // UserKeyingMaterial getter
       
   379 // -----------------------------------------------------------------------------
       
   380 EXPORT_C const TDesC8*
       
   381 CCMSKeyAgreeRecipientInfo::UserKeyingMaterial() const
       
   382 	{
       
   383 	return iUserKeyingMaterial;
       
   384 	}
       
   385 
       
   386 // -----------------------------------------------------------------------------
       
   387 // CCMSKeyAgreeRecipientInfo::SetOriginatorL
       
   388 // Originator setter
       
   389 // -----------------------------------------------------------------------------
       
   390 EXPORT_C void CCMSKeyAgreeRecipientInfo::SetOriginatorL(
       
   391 	const CCMSOriginatorIdentifierOrKey& aOriginator )
       
   392 	{
       
   393     CCMSOriginatorIdentifierOrKey* originator = NULL;
       
   394     switch( aOriginator.Type() )
       
   395         {
       
   396         case CCMSOriginatorIdentifierOrKey::ESubjectKeyIdentifier:
       
   397             {
       
   398             originator = CCMSOriginatorIdentifierOrKey::NewL(
       
   399                 aOriginator.SubjectKeyIdentifierL() );
       
   400             break;
       
   401             }
       
   402         case CCMSOriginatorIdentifierOrKey::EOriginatorKey:
       
   403             {
       
   404             originator = CCMSOriginatorIdentifierOrKey::NewL(
       
   405                 aOriginator.OriginatorKeyL() );
       
   406             break;
       
   407             }
       
   408         case CCMSOriginatorIdentifierOrKey::EIssuerAndSerialNumber:
       
   409             {
       
   410             originator = CCMSOriginatorIdentifierOrKey::NewL(
       
   411                 aOriginator.IssuerAndSerialNumberL() );
       
   412             break;
       
   413             }
       
   414         default:
       
   415             {
       
   416             User::Leave( KErrArgument );
       
   417             }
       
   418         }
       
   419     delete iOriginator;
       
   420     iOriginator = originator;
       
   421 	}
       
   422 
       
   423 // -----------------------------------------------------------------------------
       
   424 // CCMSKeyAgreeRecipientInfo::SetRecipientEncryptedKeysL
       
   425 // RecipientEncryptedKeys setter, deep copy
       
   426 // -----------------------------------------------------------------------------
       
   427 EXPORT_C void CCMSKeyAgreeRecipientInfo::SetRecipientEncryptedKeysL(
       
   428 	const CArrayPtr< CCMSRecipientEncryptedKey >& aRecipientEncryptedKeys )
       
   429 	{
       
   430     TInt keyCount = aRecipientEncryptedKeys.Count();
       
   431     CArrayPtr< CCMSRecipientEncryptedKey >* keys = NULL;
       
   432     if( keyCount > 0 )
       
   433         {
       
   434         keys = new( ELeave ) CArrayPtrFlat< CCMSRecipientEncryptedKey >(
       
   435             keyCount );
       
   436         CleanupStack::PushL( keys );
       
   437         for( TInt i = 0; i < keyCount; i++ )
       
   438             {
       
   439             const CCMSRecipientEncryptedKey* key = aRecipientEncryptedKeys[ i ];
       
   440             const CCMSIssuerAndSerialNumber* issuer = key->IssuerAndSerialNumber();
       
   441             const TDesC8& encryptedKey = key->EncryptedKey();
       
   442             CCMSRecipientEncryptedKey* newKey = NULL;
       
   443             if( issuer )
       
   444                 {
       
   445                 newKey = CCMSRecipientEncryptedKey::NewL(
       
   446                     *issuer, encryptedKey );
       
   447                 }
       
   448             else
       
   449                 {
       
   450                 newKey = CCMSRecipientEncryptedKey::NewL( *( key->RKeyId() ),
       
   451                                                           encryptedKey );
       
   452                 }
       
   453             CleanupStack::PushL( newKey );
       
   454             keys->AppendL( newKey );
       
   455             }
       
   456         CleanupStack::Pop( keyCount ); // newKeys
       
   457         CleanupStack::Pop( keys );
       
   458         }
       
   459     else
       
   460         {
       
   461         keys = new( ELeave ) CArrayPtrFlat< CCMSRecipientEncryptedKey >( 1 );
       
   462         }
       
   463     if( iRecipientEncryptedKeys )
       
   464         {
       
   465         iRecipientEncryptedKeys->ResetAndDestroy();
       
   466         delete iRecipientEncryptedKeys;
       
   467         }
       
   468     iRecipientEncryptedKeys = keys;
       
   469     }
       
   470 // -----------------------------------------------------------------------------
       
   471 // CCMSKeyAgreeRecipientInfo::SetUserKeyingMaterialL
       
   472 // UserKeyingMaterial setter.
       
   473 // -----------------------------------------------------------------------------
       
   474 EXPORT_C void CCMSKeyAgreeRecipientInfo::SetUserKeyingMaterialL(
       
   475 	const TDesC8& aUkm )
       
   476 	{
       
   477     HBufC8* ukm = aUkm.AllocL();
       
   478     delete iUserKeyingMaterial;
       
   479     iUserKeyingMaterial = ukm;
       
   480 	}
       
   481 
       
   482 //  End of File