multimediacommsengine/mmcesrv/mmcemediamanager/src/mcesecuredesstream.cpp
changeset 0 1bce908db942
child 3 513a8b745b2f
equal deleted inserted replaced
-1:000000000000 0:1bce908db942
       
     1 /*
       
     2 * Copyright (c) 2002-2007 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:    Provides services for SDP Security Descriptions.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 
       
    21 // INCLUDE FILES
       
    22 #include    "mcesecuredesstream.h"
       
    23 #include	"mcemmlogs.h"
       
    24 #include    <tconvbase64.h> // TImCodecB64
       
    25 #include    <random.h> 
       
    26 #include    <e32math.h>
       
    27 #include 	<sdpdocument.h>
       
    28 #include    <sdpcodecstringconstants.h>
       
    29 #include    <sdpcodecstringpool.h>
       
    30 #include    <sdpmediafield.h>
       
    31 #include    <sdpfmtattributefield.h>
       
    32 #include    <sdpattributefield.h>
       
    33 #include    <mmccsrtpmasterkey.h>
       
    34 #include    <mmccsrtpmastersalt.h>
       
    35 #include 	<mmccsecureinterface.h>
       
    36 #include 	"mcesecuresession.h"
       
    37 #include 	"mcecomsession.h"
       
    38 #include 	"mcecommediastream.h"
       
    39 #include 	"mcesip.h"
       
    40 #define MSG_IGNORE_RETURN( )\
       
    41     if( iGnoreSdpMsg ){ iSecureSession.RemoveSecureCrypto(); return; }
       
    42         
       
    43 // ============================ MEMBER FUNCTIONS ===============================
       
    44 
       
    45 // -----------------------------------------------------------------------------
       
    46 // CMceSecureDesStream::ConstructL
       
    47 // Symbian 2nd phase constructor can leave.
       
    48 // -----------------------------------------------------------------------------
       
    49 //
       
    50 void CMceSecureDesStream::ConstructL(CSdpMediaField& aMediaField)
       
    51     {
       
    52    	iCryptoOuts = new ( ELeave ) CArrayFixFlat< TMceSecureCryptoInfo >( KCryptoGranularity );
       
    53     iCryptoIns = new ( ELeave ) CArrayFixFlat< TMceSecureCryptoInfo >( KCryptoGranularity );
       
    54 
       
    55     iMediaField=aMediaField.CloneL();
       
    56     }
       
    57 
       
    58 // -----------------------------------------------------------------------------
       
    59 // CMceSecureDesStream::NewL
       
    60 // Two-phased constructor.
       
    61 // -----------------------------------------------------------------------------
       
    62 //
       
    63 CMceSecureDesStream* CMceSecureDesStream::NewL( CMceSecureMediaSession& aSecureSession,
       
    64 												CSdpMediaField& aMediaField,
       
    65 											CMccSecureInterface& aSecureInterface,
       
    66 											CMceComMediaStream& aMediaStream)
       
    67     {
       
    68     CMceSecureDesStream* self = new (ELeave) CMceSecureDesStream(aSecureSession,
       
    69     															aSecureInterface,
       
    70     															aMediaStream);
       
    71     CleanupStack::PushL( self );
       
    72     self->ConstructL(aMediaField);
       
    73     CleanupStack::Pop( self );
       
    74     return self;
       
    75     }
       
    76 
       
    77 // -----------------------------------------------------------------------------
       
    78 // CMceSecureDesStream::CMceSecureDesStream
       
    79 // Two-phased constructor.
       
    80 // -----------------------------------------------------------------------------
       
    81 //
       
    82 CMceSecureDesStream::CMceSecureDesStream(	CMceSecureMediaSession& aSecureSession,
       
    83 											CMccSecureInterface& aSecureInterface,
       
    84         									CMceComMediaStream& aMediaStream
       
    85         									):
       
    86 	
       
    87 	iSecureSession(aSecureSession),
       
    88 	iSecInf(aSecureInterface),
       
    89 	iMediaStream(aMediaStream),
       
    90 	iIsSAVP(ETrue),
       
    91 	iWaitingBinding(EFalse),
       
    92 	iCryptoContextOutId(0),
       
    93 	iCryptoContextInId(0),
       
    94 	iOldLocalMediaPort(0)
       
    95 	{
       
    96 	
       
    97     }
       
    98 
       
    99 // -----------------------------------------------------------------------------
       
   100 // CMceSecureDesStream::CMceSecureDesStream
       
   101 // Destructor
       
   102 // -----------------------------------------------------------------------------
       
   103 //
       
   104 CMceSecureDesStream::~CMceSecureDesStream()
       
   105     {
       
   106     if(iCryptoOuts!=NULL)
       
   107         {
       
   108     	if ( iCryptoOuts->Count() )
       
   109     		{
       
   110     		iCryptoOuts->Reset();
       
   111     		}
       
   112         }
       
   113     if(iCryptoIns!=NULL)
       
   114         {
       
   115 	    if ( iCryptoIns->Count() )
       
   116     		{
       
   117     		iCryptoIns->Reset();
       
   118     		}
       
   119         }
       
   120     delete iCryptoOuts;
       
   121     delete iCryptoIns;
       
   122     iCryptoOut.iMasterKeys.Close();
       
   123     iCryptoIn.iMasterKeys.Close();
       
   124     iCryptoOut.iSaltKeys.Close();
       
   125     iCryptoIn.iSaltKeys.Close();
       
   126     iCryptoOut.iEncodedKeys.Close();
       
   127     iCryptoIn.iEncodedKeys.Close();
       
   128    	iCryptoOut.CryptoDestruct();
       
   129    	iCryptoIn.CryptoDestruct();
       
   130    	delete iMediaField;
       
   131    	delete iMKIBuf;
       
   132     }
       
   133     
       
   134 
       
   135 // -----------------------------------------------------------------------------
       
   136 // CMceSecureDesStream::GenerateRandomKeys
       
   137 // Generates security keys
       
   138 // -----------------------------------------------------------------------------
       
   139 //
       
   140 void CMceSecureDesStream::GenerateRandomKeys( TMceSecureCryptoInfo& aCrypto )
       
   141     {
       
   142     MCEMM_DEBUG("CMceSecureDesStream::GenerateRandomKeys, Entry ")
       
   143     
       
   144     MCEMM_DEBUG("Generate Keys")
       
   145 	TBuf8< KMasterKeyAndSaltLength > random;
       
   146 	RandomString( random );
       
   147 
       
   148 	// Encode random string
       
   149 	TBuf8< KEncodedStringLength > encoded;
       
   150 	Base64Encode( random, encoded );
       
   151 	aCrypto.ResetKeys();
       
   152 	aCrypto.iEncodedKey = encoded;
       
   153 	//added generated masterkey
       
   154 	aCrypto.iSetMasterKey = random.Mid( 0, KMasterKeyLength );
       
   155 
       
   156 	//added generated salt key
       
   157 	aCrypto.iSetSaltKey = random.Mid( KMasterKeyLength );
       
   158 	aCrypto.iKeysCreated = ETrue;
       
   159 	random.Zero();
       
   160 	
       
   161     MCEMM_DEBUG("CMceSecureDesStream::GenerateRandomKeys, Exit ")   
       
   162     }
       
   163     
       
   164 // -----------------------------------------------------------------------------
       
   165 // CMceSecureDesStream::EncodeSecureSdpL()
       
   166 // Generates security key to SDP offer/Answer.
       
   167 // -----------------------------------------------------------------------------
       
   168 //
       
   169 void CMceSecureDesStream::EncodeSecureSdpL( 
       
   170     CSdpMediaField& aMediaField,
       
   171     TBool aIsAnswer )
       
   172     {
       
   173    	MCEMM_DEBUG("CMceSecureDesStream::EncodeSecureSdpL(), Entry ")
       
   174     
       
   175     iGnoreSdpMsg = EFalse;
       
   176     
       
   177     const TUint8 KCryptoTag = 1;
       
   178     
       
   179    	TInt authCount = ClientCrytoCount();
       
   180    	authCount = authCount ? authCount : KAuthTagLengthTypeCount;
       
   181    	MCEMM_DEBUG_DVALUE("iKeyNeedUpdated", iSecureSession.iKeyNeedUpdated )
       
   182   	TBuf8< KCryptoLineMaxLength > cryptoLine;
       
   183   	
       
   184     if ( aIsAnswer ) 
       
   185     	{
       
   186     	MCEMM_DEBUG("Encode Secure Answer")
       
   187 		if ( iSecureSession.iCryptoContextUpdate )
       
   188 		    {
       
   189 		    iCryptoOuts->Reset();
       
   190 		    iSecureSession.iCryptoContextUpdate = EFalse;	
       
   191 		    }
       
   192 
       
   193     	iCryptoOut.iTag = KCryptoTag;
       
   194        	GenerateCryptoLineL( cryptoLine, iCryptoOut.iTag, aIsAnswer );
       
   195 
       
   196     	if ( !iGnoreSdpMsg && 
       
   197     	     KCryptoAttributeValueMinLength <= cryptoLine.Length() &&
       
   198              iCryptoOut.iEncodedKey.Length() > 0 )
       
   199             {
       
   200     		AppendCryptoAttributeL(	cryptoLine, aMediaField );    
       
   201     		}
       
   202         cryptoLine.Zero();                        
       
   203     	}
       
   204     else if ( iSecureSession.iKeyNeedUpdated && 
       
   205               iSecureSession.iCryptoContextUpdate )
       
   206     	{
       
   207     	MCEMM_DEBUG("Encode Secure Offer; Crypto Update Required")		
       
   208     	iSecureSession.iCryptoContextUpdate = EFalse;
       
   209     	TInt tagIndex = 0;
       
   210     	TInt tag;
       
   211     	iCryptoOuts->Reset();
       
   212    		for ( tagIndex = 0; tagIndex < authCount; tagIndex++ )
       
   213 			{
       
   214 			tag = tagIndex+1;
       
   215 			GenerateCryptoLineL( cryptoLine, tag, aIsAnswer );	
       
   216 
       
   217 		    if ( !iGnoreSdpMsg && 
       
   218 		         KCryptoAttributeValueMinLength <= cryptoLine.Length() )
       
   219 		        {
       
   220 		        AppendCryptoAttributeL(	cryptoLine, aMediaField );  
       
   221 		        }
       
   222 			cryptoLine.Zero();
       
   223 			}
       
   224     	}     	
       
   225    	else 
       
   226    		{ 
       
   227    		MCEMM_DEBUG("Encode Updated Offer; No Crypto Update Required")	
       
   228    		iCryptoOut.iTag = KCryptoTag;
       
   229        	GenerateCryptoLineL( cryptoLine, iCryptoOut.iTag, aIsAnswer );	
       
   230 	
       
   231 		if ( !iGnoreSdpMsg && 
       
   232 		      KCryptoAttributeValueMinLength <= cryptoLine.Length() &&
       
   233               iCryptoOut.iEncodedKey.Length() > 0 )
       
   234             {
       
   235 		    AppendCryptoAttributeL(	cryptoLine, aMediaField );    
       
   236 		    }	
       
   237        	cryptoLine.Zero();                        
       
   238    		}       	    
       
   239     	
       
   240     if ( !iGnoreSdpMsg )
       
   241     	{
       
   242     	SetSecureProtocolL( aMediaField );
       
   243     	iCryptoUpdateNeeded = 
       
   244     	    iCryptoUpdateNeeded ? EFalse : iCryptoUpdateNeeded;
       
   245     	MCEMM_DEBUG("Encode Secure Crypto Succeeded")
       
   246     	}
       
   247    	
       
   248    	if ( !aMediaField.IsValid() )
       
   249    	    {
       
   250    	    User::Leave( KErrCorrupt );
       
   251    	    }
       
   252     
       
   253     MCEMM_DEBUG("CMceSecureDesStream::EncodeSecureSdpL(), Exit")	
       
   254     }
       
   255 
       
   256 
       
   257 // -----------------------------------------------------------------------------
       
   258 // CMceSecureDesStream::StoreKeys()
       
   259 // Store security keys
       
   260 // -----------------------------------------------------------------------------
       
   261 //
       
   262 void CMceSecureDesStream::StoreKeys( TDesC8& aData )
       
   263     {
       
   264     //DecodeAnswer or Offer
       
   265     //multiple tag
       
   266     	/*a=crypto:1 AES_CM_128_HMAC_SHA1_80
       
   267        inline:WVNfX19zZW1jdGwgKCkgewkyMjA7fQp9CnVubGVz|2^20|1:4
       
   268        FEC_ORDER=FEC_SRTP
       
   269       a=crypto:2 F8_128_HMAC_SHA1_80
       
   270        inline:MTIzNDU2Nzg5QUJDREUwMTIzNDU2Nzg5QUJjZGVm|2^20|1:4;
       
   271        inline:QUJjZGVmMTIzNDU2Nzg5QUJDREUwMTIzNDU2Nzg5|2^20|2:4
       
   272        FEC_ORDER=FEC_SRTP
       
   273 	*/
       
   274     
       
   275     TBuf8 < KMasterKeyAndSaltLength > masterKeyAndSalt;
       
   276     Base64Decode( aData, masterKeyAndSalt );
       
   277     
       
   278 	//it should be validate already so it is our prefered key
       
   279 	iCryptoIn.iEncodedKey = aData;
       
   280 	iCryptoIn.iSetMasterKey = masterKeyAndSalt.Mid( 0, KMasterKeyLength );
       
   281 	iCryptoIn.iSetSaltKey = masterKeyAndSalt.Mid( KMasterKeyLength );
       
   282 	iCryptoIn.iKeysCreated = ETrue;
       
   283     }
       
   284         
       
   285 
       
   286 // -----------------------------------------------------------------------------
       
   287 // CMceSecureDesStream::DecodeSecureSdpL()
       
   288 // Decode Secure Sdp Offer / Update
       
   289 // -----------------------------------------------------------------------------
       
   290 //
       
   291 void CMceSecureDesStream::DecodeSecureSdpL( CSdpMediaField& aMediaField )
       
   292     {
       
   293     MCEMM_DEBUG("CMceSecureDesStream::DecodeSecureSdpL(), Entry")
       
   294     MCEMM_DEBUG_DVALUE("iKeyNeedUpdated", iSecureSession.iKeyNeedUpdated )
       
   295     iGnoreSdpMsg = EFalse;
       
   296     CSdpAttributeField* attributeField = NULL;    
       
   297     
       
   298 	RPointerArray< CSdpAttributeField > attrList =  
       
   299                 aMediaField.AttributeFields();
       
   300     TInt attrCount = attrList.Count();
       
   301     TInt cryptoAttrCount =
       
   302         iSecureSession.SdpCryptoAttributeCount( aMediaField );
       
   303     iCryptoIns->Reset();
       
   304     RemoveClientCrypto();
       
   305 
       
   306     for (TInt j = 0; j < attrCount; j++ )
       
   307         {
       
   308        	attributeField = attrList[ j ];
       
   309 
       
   310         RStringF attribute = attributeField->Attribute();
       
   311 
       
   312         // check if attribute is 'crypto'
       
   313         if ( attribute.DesC().Match(KCrypto)!= KErrNotFound )
       
   314             {
       
   315            	--cryptoAttrCount;
       
   316            	//check how many inline
       
   317            	ValidateOfferByAnswerL( attributeField->Value() );
       
   318            	if ( !cryptoAttrCount && iGnoreSdpMsg && !iCryptoIns->Count() )
       
   319            		{
       
   320            		//Last attribute ignored and no valid attributes found
       
   321            		User::Leave ( KErrArgument );
       
   322            		}
       
   323 		    if ( !cryptoAttrCount )
       
   324 		        {
       
   325 		        break;
       
   326 		        }
       
   327 		    }
       
   328         }
       
   329 	if ( iCryptoIns->Count() )
       
   330 	    {
       
   331 	    //acceptable crypto suite found, not to be ignored
       
   332 	    iGnoreSdpMsg = EFalse;
       
   333 	    }
       
   334     if ( !iGnoreSdpMsg && SetMediaProfile ( aMediaField ) == KErrNone )
       
   335     	{
       
   336     	SetMultipleClientCryptoL( *iCryptoIns );
       
   337     	MCEMM_DEBUG(" Set Multiple Client Cryptoto")
       
   338     	User::LeaveIfError ( CountCryptoInOffer( aMediaField ) );
       
   339     	Session().iIsSecureSession =  !iGnoreSdpMsg ? ETrue : EFalse;
       
   340     	}
       
   341     MCEMM_DEBUG("CMceSecureDesStream::DecodeSecureSdpL(), Exit")      
       
   342     MSG_IGNORE_RETURN()
       
   343     }
       
   344 
       
   345 // -----------------------------------------------------------------------------
       
   346 // CMceSecureDesStream::DecodeSecureSdpAnswerL()
       
   347 // Decode Secure Sdp Offer/Answer
       
   348 // -----------------------------------------------------------------------------
       
   349 //
       
   350 void CMceSecureDesStream::DecodeSecureSdpAnswerL( CSdpMediaField& aMediaField)
       
   351     {
       
   352     MCEMM_DEBUG("CMceSecureDesStream::DecodeSecureSdpAnswerL(), Entry")  
       
   353     MCEMM_DEBUG_DVALUE("iKeyNeedUpdated", iSecureSession.iKeyNeedUpdated)
       
   354     TInt cryptoCount = iSecureSession.SdpCryptoAttributeCount(aMediaField);
       
   355     
       
   356     if ( cryptoCount != KCryptoAnswerCount )
       
   357     	{
       
   358     	User::Leave( KErrArgument );
       
   359     	}
       
   360 	
       
   361 	CSdpAttributeField* attr = MediaFieldAttrMatch( aMediaField, KCrypto);    
       
   362     
       
   363     // check if attribute is 'crypto' 
       
   364     if ( attr )
       
   365         {
       
   366         ValidateAnswerByOfferL( attr->Value() );
       
   367         
       
   368     	if ( !iGnoreSdpMsg  && SetMediaProfile ( aMediaField ) == KErrNone )
       
   369 			{
       
   370 			if ( iSecureSession.iKeyNeedUpdated )
       
   371 				{
       
   372 				Session().iIsSecureSession = ETrue;
       
   373 				
       
   374 				Session().iClientCryptoSuites.Reset();
       
   375 				
       
   376 				SetClientCryptoL( iCryptoIn );
       
   377 				}
       
   378 			if ( iSecureSession.iLSReadyToBind )
       
   379 				{
       
   380 				SetCryptoContextL();
       
   381 				}
       
   382 			MSG_IGNORE_RETURN()
       
   383 			if ( !iCryptoIn.iCryptoSuite.Length() )
       
   384 				{
       
   385 				User::Leave( KErrArgument );
       
   386 				}
       
   387 			MCEMM_DEBUG("Set Crypto Context succeed")  	
       
   388 			
       
   389 			}
       
   390 	
       
   391 		else
       
   392 			{
       
   393 			MCEMM_DEBUG("No suitable crypto or malformate crypto session reject")      
       
   394     
       
   395 			User::Leave( KErrArgument );
       
   396 			}
       
   397 		}
       
   398     MCEMM_DEBUG("CMceSecureDesStream::DecodeSecureSdpAnswerL(), Exit")    
       
   399   	MSG_IGNORE_RETURN()
       
   400     }
       
   401 
       
   402 // -----------------------------------------------------------------------------
       
   403 // CMceSecureDesStream::RemvoeSecureSdpL
       
   404 // Remove Secure Sdp Offer/Answer
       
   405 // -----------------------------------------------------------------------------
       
   406 //
       
   407 void CMceSecureDesStream::RemvoeSecureSdp(CSdpMediaField& aMediaField)
       
   408 	{
       
   409 	MCEMM_DEBUG("CMceSecureDesStream::RemvoeSecureSdpL(), Entry") 
       
   410     
       
   411     RStringF mediaType = aMediaField.Media();
       
   412     
       
   413     RPointerArray< CSdpAttributeField> attrList =  
       
   414                     aMediaField.AttributeFields();
       
   415 	
       
   416 	TInt attrCount = attrList.Count();
       
   417     
       
   418     for (TInt index = attrCount; index >0 ; index-- )
       
   419         {
       
   420         CSdpAttributeField* attributeField = attrList[index-1];
       
   421         RStringF attribute = attributeField->Attribute();
       
   422                  // check if attribute is 'crypto' 
       
   423         if ( KErrNotFound != attribute.DesC().Find( KCrypto ) )
       
   424             {   
       
   425             TInt removing =aMediaField.AttributeFields().Find(attributeField);
       
   426             aMediaField.AttributeFields().Remove(removing);
       
   427             delete attributeField;
       
   428             attributeField=NULL;
       
   429             }
       
   430         }
       
   431 	mediaType.Close();
       
   432 	MCEMM_DEBUG("CMceSecureDesStream::RemvoeSecureSdpL(), Exit")     
       
   433     
       
   434 	}
       
   435 
       
   436 // -----------------------------------------------------------------------------
       
   437 // CMceSecureDesStream::SetCryptoContext( )
       
   438 // Sets crypto context to MCC
       
   439 // -----------------------------------------------------------------------------
       
   440 //
       
   441 void CMceSecureDesStream::SetCryptoContextL( )
       
   442     {
       
   443     MCEMM_DEBUG("SetCryptoContext(), Entry")   
       
   444     TBool storedIgnoreSdpMsg = EFalse;
       
   445     //Check state first if the crypto has been set
       
   446     if ( !iCryptoIn.iIfCryptoContextIdSet && 
       
   447     	!iCryptoOut.iIfCryptoContextIdSet &&
       
   448     	iCryptoIn.iSetMasterKey.Length() && 
       
   449     	iCryptoIn.iSetSaltKey.Length() &&
       
   450     	iCryptoOut.iSetMasterKey.Length() &&
       
   451     	iCryptoOut.iSetSaltKey.Length() )
       
   452     	{
       
   453     	MCEMM_DEBUG("First Time Bind")
       
   454     	CreateCryptoContextL( iCryptoIn );
       
   455     	CreateCryptoContextL( iCryptoOut ); 
       
   456     	MCEMM_DEBUG_DVALUE( "iCryptoContextOutId", iCryptoIn.iCryptoContextId )
       
   457 		MCEMM_DEBUG_DVALUE( "iCryptoContextInId", iCryptoOut.iCryptoContextId )
       
   458 
       
   459     	iCryptoOuts->Reset();
       
   460     	
       
   461     
       
   462     	}
       
   463     else if ( iCryptoIn.iSetMasterKey.Length() && 
       
   464     		iCryptoIn.iSetSaltKey.Length() &&
       
   465     	  	iCryptoOut.iSetMasterKey.Length() &&
       
   466     	 	iCryptoOut.iSetSaltKey.Length() )
       
   467 		{
       
   468 		MCEMM_DEBUG("Bind has done before so this is for updated")  
       
   469 		if ( iCryptoContextInId != 0  && iCryptoContextOutId != 0 )
       
   470 			{
       
   471 			iCryptoIn.iCryptoContextId = iCryptoContextInId;
       
   472 			iCryptoOut.iCryptoContextId =  iCryptoContextOutId;
       
   473 			}
       
   474 		MCEMM_DEBUG_DVALUE( "Updated iCryptoContextOutId", iCryptoIn.iCryptoContextId )
       
   475 		MCEMM_DEBUG_DVALUE( "Updated iCryptoContextInId", iCryptoOut.iCryptoContextId )
       
   476     	if ( iSecureSession.iKeyNeedUpdated )
       
   477     		{
       
   478     		UpdateCryptoContextL( iCryptoIn ); 
       
   479     		storedIgnoreSdpMsg = iGnoreSdpMsg;
       
   480     		UpdateCryptoContextL( iCryptoOut ); 
       
   481     		iGnoreSdpMsg = iGnoreSdpMsg && storedIgnoreSdpMsg;
       
   482     		}
       
   483     	else
       
   484     		{
       
   485     		iWaitingBinding = ETrue;	
       
   486     		}
       
   487     	iCryptoOuts->Reset(); 
       
   488     	}
       
   489     iGnoreSdpMsg = (iCryptoIn.iIfCryptoContextIdSet && 
       
   490     				iCryptoOut.iIfCryptoContextIdSet ) &&
       
   491     				!iGnoreSdpMsg ? EFalse : ETrue;		
       
   492     if ( iWaitingBinding )
       
   493     	{
       
   494     	iSecureSession.BindStreamCrypto();
       
   495     	}
       
   496     	
       
   497     MCEMM_DEBUG("SetCryptoContext(), Exit")
       
   498     }
       
   499 
       
   500 
       
   501 // -----------------------------------------------------------------------------
       
   502 // CMceSecureDesStream::CreateCryptoContextL()
       
   503 // 
       
   504 // -----------------------------------------------------------------------------
       
   505 //     
       
   506 void CMceSecureDesStream::CreateCryptoContextL( TMceSecureCryptoInfo& aCrypto )
       
   507     {
       
   508     MCEMM_DEBUG("CMceSecureDesStream::CreateCryptoContextL Entry")
       
   509     // if  ESrtpNullAlg == iEncAlgms Fallback to RTP, set NULL policy
       
   510     // Create phony master and salt from local values 
       
   511     // since remote keys not available
       
   512     iWaitingBinding = EFalse;
       
   513     TInt err(KErrNone);
       
   514     FormMKIL(aCrypto);
       
   515     TBuf8<KMKILength> mki;
       
   516     mki.Copy( KNullDesC8 );
       
   517    	TMccSrtpMasterKey masterKey(aCrypto.iSetMasterKey, mki); 
       
   518    
       
   519     if (aCrypto.iMKIUsed && iMKIBuf)
       
   520     	{
       
   521     	masterKey.iMKI.Copy(iMKIBuf->Des()); 
       
   522     	masterKey.iMKI.SetLength(aCrypto.iMKILength);
       
   523     	}
       
   524     TMccSrtpMasterSalt saltKey( aCrypto.iSetSaltKey);
       
   525 	TMccSrtpCryptoParams params;
       
   526     
       
   527     params.iSrtpEncAlg = aCrypto.iEncAlgms; 
       
   528     params.iSrtcpEncAlg = aCrypto.iEncAlgms; 
       
   529     params.iSrtpAuthAlg = aCrypto.iAuthAlgms; 
       
   530     params.iSrtcpAuthAlg = aCrypto.iAuthAlgms; 
       
   531     params.iSrtpAuthTagLen = aCrypto.iTagLen;
       
   532     params.iSrtcpAuthTagLen = aCrypto.iTagLen;
       
   533     if ( aCrypto.iMKLifeTime )
       
   534     	{
       
   535     	params.iMasterKeysLifeTime = aCrypto.iMKLifeTime;
       
   536     	}
       
   537     
       
   538     
       
   539     TMccSrtpMasterKeyPckg masterKeyPckg(masterKey); 
       
   540     const TDesC8& masterKeyDes = masterKeyPckg;
       
   541     
       
   542     TMccSrtpMasterSaltPckg masterSaltPckg( saltKey );  
       
   543     const TDesC8& saltKeyDes = masterSaltPckg;                      
       
   544    	
       
   545    	TMccSrtpCryptoParamsPckg cryptoParamsPckg ( params );
       
   546    	const TDesC8& cryptoParamsDes = cryptoParamsPckg;   
       
   547    	//remember to handle and pass the keys
       
   548    	err = iSecInf.CreateContext(masterKeyDes, saltKeyDes,
       
   549 	                                 aCrypto.iCryptoContextId, cryptoParamsDes );  
       
   550 	if ( err == KErrNone )
       
   551 		{
       
   552 		MCEMM_DEBUG("Create Crypto Succeed")
       
   553 		aCrypto.iIfCryptoContextIdSet = ETrue;
       
   554 		iWaitingBinding = ETrue;
       
   555 		}
       
   556 	
       
   557 	MCEMM_DEBUG_DVALUE( "createContext error", err )		
       
   558 	MCEMM_DEBUG("CMceSecureDesStream::CreateCryptoContextL Exit")
       
   559     }
       
   560 
       
   561 // -----------------------------------------------------------------------------
       
   562 // CMceSecureDesStream::UpdateCryptoContext()
       
   563 // 
       
   564 // -----------------------------------------------------------------------------
       
   565 //     
       
   566 void CMceSecureDesStream::UpdateCryptoContextL( TMceSecureCryptoInfo& aCrypto )
       
   567     {
       
   568     MCEMM_DEBUG("CMceSecureDesStream::UpdateCryptoContextL Entry")	
       
   569     TInt err(KErrNone);
       
   570     iWaitingBinding = EFalse;
       
   571    
       
   572     aCrypto.iIfBinded = EFalse;
       
   573     FormMKIL(aCrypto);
       
   574     TBuf8<KMKILength> mki;
       
   575     mki.Copy( KNullDesC8 );
       
   576    	TMccSrtpMasterKey masterKey( aCrypto.iSetMasterKey, mki ); 
       
   577    
       
   578     if ( aCrypto.iMKIUsed && iMKIBuf )
       
   579     	{
       
   580     	masterKey.iMKI.Copy(iMKIBuf->Des()); 
       
   581     	}
       
   582     TMccSrtpMasterSalt saltKey( aCrypto.iSetSaltKey);
       
   583 	TMccSrtpCryptoParams params;
       
   584     
       
   585     params.iSrtpEncAlg = aCrypto.iEncAlgms; 
       
   586     params.iSrtcpEncAlg = aCrypto.iEncAlgms; 
       
   587     params.iSrtpAuthAlg = aCrypto.iAuthAlgms; 
       
   588     params.iSrtcpAuthAlg = aCrypto.iAuthAlgms; 
       
   589     params.iSrtpAuthTagLen = aCrypto.iTagLen;
       
   590     params.iSrtcpAuthTagLen = aCrypto.iTagLen;
       
   591     if ( aCrypto.iMKLifeTime )
       
   592     	{
       
   593     	params.iMasterKeysLifeTime = aCrypto.iMKLifeTime;
       
   594     	}
       
   595     
       
   596     
       
   597     TMccSrtpMasterKeyPckg masterKeyPckg(masterKey); 
       
   598     const TDesC8& masterKeyDes = masterKeyPckg;
       
   599     
       
   600     TMccSrtpMasterSaltPckg masterSaltPckg( saltKey );  
       
   601     const TDesC8& saltKeyDes = masterSaltPckg;                      
       
   602    	
       
   603    	TMccSrtpCryptoParamsPckg cryptoParamsPckg ( params );
       
   604    	const TDesC8& cryptoParamsDes = cryptoParamsPckg;  
       
   605 
       
   606 	err = iSecInf.UpdateContext( masterKeyDes, saltKeyDes,
       
   607                              aCrypto.iCryptoContextId, cryptoParamsDes );
       
   608 
       
   609 	if ( err==KErrNone)
       
   610 		{
       
   611 		MCEMM_DEBUG("Updated Crypto Succeed")
       
   612 		aCrypto.iIfCryptoContextIdSet = ETrue;
       
   613 		iWaitingBinding = ETrue;
       
   614 		}
       
   615 	//This is to check if the crypto Id after update can be found
       
   616 	// if not found, context Id maybe wrong	
       
   617 	iGnoreSdpMsg = err == KErrNotFound ? ETrue : EFalse;	
       
   618 	MCEMM_DEBUG_DVALUE( "UpdateContext error", err )
       
   619 	MCEMM_DEBUG("CMceSecureDesStream::UpdateCryptoContextL Exit")	
       
   620 	}
       
   621 
       
   622 // -----------------------------------------------------------------------------
       
   623 // CMceSecureDesStream::FormMKIL()
       
   624 // 
       
   625 // -----------------------------------------------------------------------------
       
   626 //     
       
   627 void CMceSecureDesStream::FormMKIL( TMceSecureCryptoInfo& aCrypto )
       
   628     {
       
   629     delete iMKIBuf;
       
   630     iMKIBuf=NULL;
       
   631     if ( aCrypto.iMKILength > 0 && 
       
   632          aCrypto.iMKILength%4 == 0 &&
       
   633          aCrypto.iMKIUsed )
       
   634     	{
       
   635     	__ASSERT_ALWAYS( aCrypto.iMKILength <= KMKIMaxLength,
       
   636     	                 User::Leave( KErrOverflow ) );
       
   637     	
       
   638     	iMKIBuf = HBufC8::NewL( aCrypto.iMKILength );
       
   639     	TUint8* mkiData = const_cast<TUint8*>( iMKIBuf->Des().Ptr() );
       
   640     	Mem::FillZ( mkiData, aCrypto.iMKILength );
       
   641     	if (aCrypto.iMKILength > KMKILength)
       
   642     		{
       
   643     		mkiData+= ( aCrypto.iMKILength - KMKILength );
       
   644     		}
       
   645 		TUint32 mkiValue=aCrypto.iMKIValue;
       
   646 		BigEndian::Put32(mkiData, mkiValue);
       
   647     	mkiData += KMKILength;
       
   648     	iMKIBuf->Des().SetLength( aCrypto.iMKILength );
       
   649     	}
       
   650     
       
   651     }
       
   652 // -----------------------------------------------------------------------------
       
   653 // CMceSecureDesStream::BindCrypto( )
       
   654 // -----------------------------------------------------------------------------
       
   655 //
       
   656 
       
   657 TInt CMceSecureDesStream::BindCrypto( CMceSrvStream& aStream )
       
   658     					
       
   659 	{
       
   660 	MCEMM_DEBUG("CMceSecureDesStream::BindCrypto(), Entry")				
       
   661 	
       
   662 	MCEMM_DEBUG_DVALUE("	BindStreamId", aStream.Id() )	
       
   663 	MCEMM_DEBUG_DVALUE("	BindLinkId", aStream.LinkId() )	
       
   664 	MCEMM_DEBUG_DVALUE("	iCryptoIn.iIfBinded", iCryptoIn.iIfBinded )
       
   665 	MCEMM_DEBUG_DVALUE("	iCryptoOut.iIfBinded", iCryptoOut.iIfBinded )
       
   666 	
       
   667 	TInt err(KErrNotFound);
       
   668 	if (iCryptoIn.iEncodedKey.Length() && 
       
   669 		iCryptoIn.iIfCryptoContextIdSet &&
       
   670 		IS_RECEIVESTREAM(&aStream.Data()) )
       
   671 		{
       
   672 		MCEMM_DEBUG_DVALUE("	BindContext In Id", iCryptoIn.iCryptoContextId )	
       
   673 		MCEMM_DEBUG_DVALUE("	BindSourceId", aStream.Source().Id() )
       
   674 	
       
   675 		err = iSecInf.Bind( aStream.SessionId(), 
       
   676 								aStream.LinkId(),
       
   677 								aStream.Id(), 
       
   678 								aStream.Source().Id(), 
       
   679 								iCryptoIn.iCryptoContextId );	
       
   680 		
       
   681 		MCEMM_DEBUG_DVALUE("	BindSource result=", err)
       
   682 		
       
   683 		if ( err == KErrNone )
       
   684 			{
       
   685 			iCryptoIn.iIfBinded = ETrue;
       
   686 			MCEMM_DEBUG("Bind Downlink Source Successful")
       
   687 			}
       
   688 					
       
   689 		}
       
   690 
       
   691 
       
   692 	if (iCryptoOut.iEncodedKey.Length() && 
       
   693 		iCryptoOut.iIfCryptoContextIdSet &&
       
   694 		IS_SENDSTREAM(&aStream.Data())  )
       
   695 		{
       
   696 	
       
   697 		MCEMM_DEBUG_DVALUE("	BindContext Out Id", iCryptoOut.iCryptoContextId )	
       
   698 	    MCEMM_DEBUG_DVALUE("	BindSinkId", aStream.Sink().Id() )
       
   699 	
       
   700 		err =iSecInf.Bind( aStream.SessionId(), 
       
   701 								aStream.LinkId(),
       
   702 								aStream.Id(), 
       
   703 								aStream.Sink().Id(), 
       
   704 								iCryptoOut.iCryptoContextId );	
       
   705 		
       
   706 		MCEMM_DEBUG_DVALUE("	BindSink result=", err)				
       
   707 
       
   708 		if (err == KErrNone)
       
   709 			{
       
   710 			iCryptoOut.iIfBinded=ETrue;
       
   711 			MCEMM_DEBUG("	Bind Uplink Sink Successful")
       
   712 			}
       
   713 		
       
   714 		}							
       
   715 
       
   716 	if (iCryptoIn.iIfBinded && iCryptoOut.iIfBinded)
       
   717 		{
       
   718 		MCEMM_DEBUG("	Bind Successful for Downlink and Uplink")
       
   719 		iWaitingBinding=EFalse;	
       
   720 		}
       
   721 	err = iWaitingBinding? KErrNotFound : KErrNone;
       
   722 		
       
   723 	MCEMM_DEBUG("CMceSecureDesStream::BindCrypto(), Exit")			
       
   724 	
       
   725 	return err;	
       
   726    }
       
   727 			
       
   728 
       
   729 // -----------------------------------------------------------------------------
       
   730 // CMceSecureDesStream::Base64Encode
       
   731 // Base64 encoding.
       
   732 // -----------------------------------------------------------------------------
       
   733 //
       
   734 void CMceSecureDesStream::Base64Encode( const TDesC8& aData, TDes8& aEncoded )
       
   735     {
       
   736     TBase64 encode;
       
   737     encode.Encode( aData, aEncoded );
       
   738     }
       
   739 
       
   740 // -----------------------------------------------------------------------------
       
   741 // CMceSecureDesStream::Base64Decode
       
   742 // Base64 decode.
       
   743 // -----------------------------------------------------------------------------
       
   744 //
       
   745 void CMceSecureDesStream::Base64Decode( const TDesC8& aData, TDes8& aDecoded )
       
   746     {
       
   747     TBase64 decode;
       
   748     decode.Decode( aData, aDecoded );
       
   749     }
       
   750 
       
   751 // -----------------------------------------------------------------------------
       
   752 // CMceSecureDesStream::ValidateSecurityDescriptions
       
   753 // Check if security description is valid
       
   754 // -----------------------------------------------------------------------------
       
   755 //    
       
   756 TBool CMceSecureDesStream::ValidateSecurityDescriptions( TDesC8& aData )
       
   757     {
       
   758     TBool valid( ETrue );
       
   759     
       
   760     TBuf8< KCryptoLineMaxLength > masterKeyAndSalt;
       
   761     Base64Decode( aData, masterKeyAndSalt );
       
   762     TInt countChar=0;
       
   763     // Check that encoded string is right sized
       
   764     // Validate length of master key and salt 
       
   765     if ( KEncodedStringLength != aData.Length() || 
       
   766          KMasterKeyAndSaltLength != masterKeyAndSalt.Length() )
       
   767         {
       
   768         return !valid ;
       
   769         }
       
   770           
       
   771     // Validate Base64 Encoding characters
       
   772     TBool charFound( EFalse );
       
   773     for ( TInt i = 0; i < aData.Length(); i++ )
       
   774         {
       
   775         
       
   776         for (TInt j = 0; j < KRandomStringCount; j++ )
       
   777             {
       
   778             if ( aData[i] == KBase64Chars[j] )
       
   779                 {
       
   780                 charFound = ETrue;
       
   781                 countChar++;
       
   782                 }
       
   783             }
       
   784         
       
   785         if ( !charFound )
       
   786             {
       
   787             // invalid character has been found
       
   788             valid = EFalse;
       
   789             }
       
   790             
       
   791         charFound = EFalse;
       
   792         }
       
   793     if (countChar!=aData.Length())
       
   794     	{
       
   795     	valid=EFalse; 
       
   796     	}
       
   797     return valid;
       
   798     }
       
   799 
       
   800 // -----------------------------------------------------------------------------
       
   801 // CMceSecureDesStream::RandomString
       
   802 // Generates random string
       
   803 // -----------------------------------------------------------------------------
       
   804 //    
       
   805 void CMceSecureDesStream::RandomString( TDes8& aRandom )
       
   806     {
       
   807     TTime time;
       
   808     time.UniversalTime();
       
   809     TInt64 seed = time.Int64();
       
   810     TUint32 random= Math::Random();
       
   811     seed += random;
       
   812     TInt randomNumber(0);
       
   813         
       
   814     for( TInt i = 0; i < aRandom.MaxSize(); i++ )
       
   815         {
       
   816         randomNumber = Math::Rand( seed ) % KRandomStringCount;
       
   817         aRandom.Append( KRandomChars[ randomNumber ] );
       
   818         }
       
   819 
       
   820     }
       
   821 
       
   822 // -----------------------------------------------------------------------------
       
   823 // CMceSecureDesStream::GenerateCryptoLineL()
       
   824 // Cryptoline creation
       
   825 // -----------------------------------------------------------------------------
       
   826 //    
       
   827 void CMceSecureDesStream::GenerateCryptoLineL( 
       
   828     TDes8& aResult,
       
   829     TInt aCryptoCount,
       
   830     TBool aAnswer )
       
   831     {
       
   832     MCEMM_DEBUG("CMceSecureDesStream::GenerateCryptoLineL Entry")
       
   833     SetClientCryptoL( aCryptoCount );
       
   834     if ( aAnswer ) 
       
   835         {
       
   836         //Compare with crypto In and create cryptoOut
       
   837         MCEMM_DEBUG("GenerateCryptoLineL for Answer")
       
   838         if ( iSecureSession.iKeyNeedUpdated )
       
   839         	{
       
   840        		User::LeaveIfError ( CompareCryptosForAnswer() );
       
   841         	GenerateRandomKeys( iCryptoOut );
       
   842         	MCEMM_DEBUG("GenerateRandomKeys Key is updated")
       
   843         	iOldLocalMediaPort = iMediaStream.iLocalMediaPort;
       
   844         	}
       
   845         else
       
   846         	{
       
   847         	if(iOldLocalMediaPort != iMediaStream.iLocalMediaPort)
       
   848         		{
       
   849         	    GenerateRandomKeys( iCryptoOut );
       
   850         	    MCEMM_DEBUG("GenerateRandomKeys Key is updated when oldport is different from newport")
       
   851         	    iOldLocalMediaPort = iMediaStream.iLocalMediaPort;
       
   852         	    }
       
   853         	}
       
   854         aResult.AppendNum( iCryptoOut.iTag );
       
   855 		aResult.Append( KSpace );
       
   856         GenerateCryptoSuiteLineL( aResult, iCryptoOut );
       
   857         MSG_IGNORE_RETURN()
       
   858       	if ( iSecureSession.iLSReadyToBind )
       
   859       		{
       
   860       		SetCryptoContextL();
       
   861       		}
       
   862         MSG_IGNORE_RETURN()
       
   863         }
       
   864 	 else
       
   865     	{
       
   866     	MCEMM_DEBUG("GenerateCryptoLineL for Offer")
       
   867     	
       
   868     	if ( iSecureSession.iKeyNeedUpdated )
       
   869     		{
       
   870     		iGnoreSdpMsg = !iCryptoOuts->Count() ? ETrue : EFalse;
       
   871     		iGnoreSdpMsg = aCryptoCount - 1 >= iCryptoOuts->Count() ? ETrue : EFalse;
       
   872     		MSG_IGNORE_RETURN()
       
   873     		TMceSecureCryptoInfo crypto = iCryptoOuts->At( aCryptoCount-1 );
       
   874     		GenerateRandomKeys( crypto );
       
   875     		crypto.iTag = aCryptoCount;
       
   876     		aResult.AppendNum( aCryptoCount );
       
   877 			aResult.Append( KSpace );
       
   878 			GenerateCryptoSuiteLineL( aResult, crypto );
       
   879 			MSG_IGNORE_RETURN()
       
   880 			iCryptoOuts->At( aCryptoCount-1 ).Copy( crypto );
       
   881             iOldLocalMediaPort = iMediaStream.iLocalMediaPort;			
       
   882     		}
       
   883 		else
       
   884 			{
       
   885 		    aResult.AppendNum( iCryptoOut.iTag );
       
   886 			aResult.Append( KSpace );
       
   887         	GenerateCryptoSuiteLineL( aResult, iCryptoOut );
       
   888 			}    		
       
   889     	
       
   890 		}
       
   891 	MCEMM_DEBUG("CMceSecureDesStream::GenerateCryptoLineL Exit")	
       
   892    	MSG_IGNORE_RETURN()	
       
   893     }
       
   894 
       
   895 // -----------------------------------------------------------------------------
       
   896 // CMceSecureDesStream::GenerateCryptoSuiteLine
       
   897 // Cryptoline creation
       
   898 // -----------------------------------------------------------------------------
       
   899 //    
       
   900 void CMceSecureDesStream::GenerateCryptoSuiteLineL( TDes8& aResult, 
       
   901 										TMceSecureCryptoInfo& aCrypto )
       
   902     {
       
   903     switch ( aCrypto.iEncAlgms )
       
   904         {
       
   905         case ESrtpEncAES_CM:
       
   906             {
       
   907             if ( aCrypto.iTagLen == KAuthTagLength32 )
       
   908                 {
       
   909                 aResult.Append( KAES_SHA1_32 );
       
   910                 }
       
   911             else
       
   912                 {
       
   913                 aResult.Append( KAES_SHA1_80 );
       
   914                 }
       
   915             break;
       
   916             }
       
   917         default:
       
   918             {
       
   919             iGnoreSdpMsg = ETrue;
       
   920             break;
       
   921             }
       
   922         }
       
   923    
       
   924     MSG_IGNORE_RETURN()
       
   925     aResult.Append( KSpace );
       
   926     aResult.Append( KInline );
       
   927     if (aCrypto.iEncodedKey.Length() > 0)
       
   928     	{
       
   929     	aResult.Append( aCrypto.iEncodedKey );
       
   930     // Append MKI and lifetime if needed, MKI as default
       
   931     	if ( aCrypto.iMKIUsed && aCrypto.iMKI.Length() > 0 )
       
   932         	{
       
   933         	aResult.Append( KSeparator );
       
   934        	 	aResult.Append( aCrypto.iMKI );
       
   935         	}
       
   936         //set default masterkeyLT
       
   937         aCrypto.iMKLifeTime = KDefalutMaterKeysLifeTime;
       
   938     	}
       
   939     else
       
   940     	{
       
   941     	User::Leave( KErrArgument ); 	
       
   942     	}
       
   943     }
       
   944 
       
   945 
       
   946 // -----------------------------------------------------------------------------
       
   947 // CMceSecureDesStream::MediaField()
       
   948 // Return this MediaField
       
   949 // -----------------------------------------------------------------------------
       
   950 //	
       
   951 CSdpMediaField& CMceSecureDesStream::MediaField()
       
   952 	{
       
   953 	return *iMediaField;
       
   954 	}
       
   955 
       
   956 // -----------------------------------------------------------------------------
       
   957 // CMceSecureDesStream::Codec()
       
   958 // Return this related codec
       
   959 // -----------------------------------------------------------------------------
       
   960 //
       
   961 CMceComMediaStream& CMceSecureDesStream::MediaStream() const
       
   962     {
       
   963     return iMediaStream;
       
   964     }
       
   965     
       
   966 
       
   967 // -----------------------------------------------------------------------------
       
   968 // CMceSecureDesStream::CompareContextId
       
   969 // Return TBool
       
   970 // -----------------------------------------------------------------------------
       
   971 //    
       
   972 TBool CMceSecureDesStream::CompareContextId( TUint32 aContextId )
       
   973 	{
       
   974 	TBool equal = EFalse;
       
   975 	if (aContextId == iCryptoIn.iCryptoContextId ||
       
   976 			aContextId == iCryptoOut.iCryptoContextId)
       
   977 		{
       
   978 		equal = ETrue;
       
   979 		}
       
   980 	return equal;	
       
   981 	}	
       
   982 	
       
   983 // -----------------------------------------------------------------------------
       
   984 // CMceSecureDesStream::DecodeMKLifeTime
       
   985 // 
       
   986 // -----------------------------------------------------------------------------
       
   987 //    
       
   988 void CMceSecureDesStream::DecodeMKLifeTimeL(const TDesC8& aSecDec,
       
   989 											TMceSecureCryptoInfo& aCrypto )
       
   990 	{
       
   991 	/*
       
   992 	RFC 4568 6.1         
       
   993 	*/
       
   994 	// aSecDec is CSdpAttributeField value
       
   995 	//By Type we know it is offer or answer so we know crypto In/Out should be
       
   996 	// assign
       
   997 	//Note that no matter how many inline the MKI will be same in the one cryptosute
       
   998 	_LIT8( KMatchMKLTPowerTwo,"*|*^*|*:*" );
       
   999 	_LIT8( KMatchMKLTDigit,"*|*|*:*" );
       
  1000     _LIT8 ( KMatchMKLT, "*|2^*");
       
  1001     _LIT8 ( KOnlyMKI, "*|*:*");
       
  1002    
       
  1003     TChar separator = '|';
       
  1004     const TUint8 KMatchMKLToffset = 3;
       
  1005     const TReal mkiPowerBase = 2;
       
  1006     TBool found=EFalse;
       
  1007 	TInt totalLen = aSecDec.Length();
       
  1008 	TUint32 unitMKLT = 0;
       
  1009 	TPtrC8 mkLT( NULL,0 );
       
  1010 	TPtrC8 sec( NULL,0 );
       
  1011 	TReal powerResult = 0;
       
  1012 	TInt posSemi= aSecDec.Find( KSemiColon );
       
  1013 	sec.Set( aSecDec.Ptr(), aSecDec.Length() );
       
  1014 	if ( posSemi != KErrNotFound )
       
  1015 		{
       
  1016 		sec.Set(aSecDec.Left(posSemi).Ptr(), posSemi);
       
  1017 		}
       
  1018 	//sec is now only before semicolon
       
  1019 	// make sure if there is MKLT
       
  1020 	if ( sec.Match ( KMatchMKLTPowerTwo ) != KErrNotFound ) 
       
  1021     	{
       
  1022         
       
  1023         TInt firstSep = SearchChar( sec, separator, 0 );
       
  1024         TInt sndSep = SearchChar( sec, separator, firstSep );
       
  1025     	mkLT.Set( sec.Mid( firstSep + 1, sndSep - firstSep -1 ) );
       
  1026     	TInt posInvol = mkLT.Find( KInvolute );
       
  1027 		TLex8 lexMKL( mkLT.Mid( posInvol+1 ) );
       
  1028 		User::LeaveIfError( lexMKL.Val(unitMKLT, EDecimal ));
       
  1029 		Math::Pow( powerResult, mkiPowerBase, (TReal)unitMKLT );
       
  1030 		unitMKLT = (TUint32)powerResult;
       
  1031 
       
  1032 		found = ETrue;	
       
  1033         }
       
  1034     else if (sec.Match ( KMatchMKLTDigit ) != KErrNotFound )
       
  1035     	{
       
  1036     	found= ETrue;
       
  1037 		//only Decimal case
       
  1038 		TInt first = sec.Find( KSeparator );
       
  1039 		TInt second = sec.LocateReverse( separator );
       
  1040 		mkLT.Set( aSecDec.Mid( first+1, second - first - 1  ));
       
  1041 		TLex8 lexMKL(mkLT);
       
  1042 		
       
  1043 		User::LeaveIfError( lexMKL.Val(unitMKLT, EDecimal ));
       
  1044     	}
       
  1045 	else if( sec.Match( KMatchMKLT ) != KErrNotFound )	
       
  1046 		{
       
  1047 		found = ETrue;
       
  1048 		//onlyMKLT with power 2 no MasterKeyIdentifier
       
  1049 		TInt posSeparator = sec.Match( KMatchMKLT );
       
  1050 		TInt remainLen = sec.Length() - ( posSeparator + KMatchMKLToffset );
       
  1051 		//only number after power
       
  1052 		mkLT.Set( sec.Mid( posSeparator + KMatchMKLToffset, remainLen ) );
       
  1053 	
       
  1054 		TLex8 lexMKL( mkLT );
       
  1055 		
       
  1056 		User::LeaveIfError( lexMKL.Val(unitMKLT, EDecimal ));
       
  1057 		Math::Pow( powerResult, mkiPowerBase, (TReal)unitMKLT );
       
  1058 		mkLT.Set( sec.Mid( posSeparator + 1 ));// ex 2^32
       
  1059 		
       
  1060 		unitMKLT = (TUint32)powerResult;
       
  1061 		}
       
  1062      else if ( sec.Match(KOnlyMKI) == KErrNotFound  && totalLen > 0
       
  1063 			&& sec.Find(KSeparator) != KErrNotFound )
       
  1064 		{
       
  1065 		found= ETrue;
       
  1066 		//only Decimal case
       
  1067 		TInt posfirst = sec.Find( KSeparator );
       
  1068 		TInt mkltpos = posfirst +1;
       
  1069 		TInt remainLen = totalLen - ( mkltpos );
       
  1070 		mkLT.Set( aSecDec.Mid( mkltpos, remainLen ));
       
  1071 		TLex8 lexMKL(mkLT);
       
  1072 		User::LeaveIfError( lexMKL.Val(unitMKLT, EDecimal ));
       
  1073 		}  
       
  1074     
       
  1075 	if (found )
       
  1076 		{
       
  1077 		//It is decode so only for cryptoIn
       
  1078 		aCrypto.iMKLifeTime = unitMKLT;
       
  1079 		}
       
  1080     }
       
  1081 
       
  1082 // -----------------------------------------------------------------------------
       
  1083 // CMceSecureDesStream::DecodeMKIValue
       
  1084 // 
       
  1085 // -----------------------------------------------------------------------------
       
  1086 //    
       
  1087 void CMceSecureDesStream::DecodeMKIValueL( 	const TDesC8& aSecDec,
       
  1088 											TBool aIsAnswer,
       
  1089     										TMceSecureCryptoInfo& aCrypto )
       
  1090 	{
       
  1091 	/*RFC 4568 6.1
       
  1092 	*/
       
  1093 	// aSecDec is CSdpAttributeField value
       
  1094 	const TInt KMKIMaxLen = 3;
       
  1095     const TInt KMKIColonLen = 1;
       
  1096     const TInt KMKIMaxBytes = 128;
       
  1097     _LIT8 (KOnlyMKI, "*|*:*");
       
  1098 
       
  1099 	TPtrC8 sec(NULL,0);
       
  1100 	TChar separator='|';
       
  1101 	TChar colon=':';
       
  1102 	TChar space = ' ';
       
  1103 	TInt mkifound = aSecDec.Match( KOnlyMKI );
       
  1104 	TInt posSemi= aSecDec.Find( KSemiColon );
       
  1105 	sec.Set( aSecDec.Ptr(),aSecDec.Length() );
       
  1106 	if ( posSemi != KErrNotFound )
       
  1107 		{
       
  1108 		//with secon inline
       
  1109 		sec.Set( aSecDec.Left(posSemi).Ptr(), posSemi );
       
  1110 		}
       
  1111 		
       
  1112 	if ( aIsAnswer )
       
  1113 		{
       
  1114 		//compare with cryptoOut
       
  1115 		if ( !iCryptoOut.iMKIUsed && mkifound != KErrNotFound )
       
  1116 			{
       
  1117 			//should not have MKI field , reject this 
       
  1118 			User::Leave ( KErrArgument );
       
  1119 			}
       
  1120 		}
       
  1121 	if ( mkifound != KErrNotFound )
       
  1122 		{
       
  1123 		//there is MKI
       
  1124 		/*If the MKI length is not given or
       
  1125    		its value exceeds 128 (bytes), then the entire crypto attribute MUST
       
  1126    		be considered invalid.*/
       
  1127 		TInt separator2ndPos = sec.LocateReverse( separator );
       
  1128 		TInt mkiPos = separator2ndPos+1;
       
  1129 		TInt colonPos = sec.LocateReverse( colon );
       
  1130 		TInt mKIoffset = colonPos - mkiPos;
       
  1131 		//mki value
       
  1132 		if ( mKIoffset < 0 )
       
  1133 			{
       
  1134 			//malformate MKI
       
  1135 			User::Leave( KErrArgument );
       
  1136 			}
       
  1137 	
       
  1138 		TPtrC8 mkiValue = sec.Mid(mkiPos, mKIoffset);
       
  1139 		TLex8 lexMKI(mkiValue);
       
  1140 		User::LeaveIfError(lexMKI.Val(aCrypto.iMKIValue, EDecimal) );
       
  1141 		
       
  1142 		//mki length
       
  1143 		TInt mkilenPos = colonPos+1;
       
  1144 		TInt mkilenOffset = sec.Length() - mkilenPos;
       
  1145 		if ( mkilenOffset> KMKIMaxLen )
       
  1146 			{
       
  1147 			//there is extra session parameter behind
       
  1148 			//looking for white space
       
  1149 			TInt spacePos = sec.LocateReverse( space );
       
  1150 			mkilenOffset = spacePos-mkilenPos;
       
  1151 			}
       
  1152 		TPtrC8 mkilen = sec.Mid( mkilenPos, mkilenOffset );
       
  1153 		TLex8 lexMkiLen(mkilen);
       
  1154 		User::LeaveIfError(lexMkiLen.Val(aCrypto.iMKILength, EDecimal, KMKIMaxBytes));
       
  1155     	__ASSERT_ALWAYS( aCrypto.iMKILength <= KMKIMaxLength,
       
  1156     	                 User::Leave( KErrOverflow ) );		
       
  1157 		
       
  1158 		//get whole MKI ( value + length)-> This is for adding SDP only
       
  1159 		TInt total = mKIoffset +  mkilenOffset + KMKIColonLen;
       
  1160 		aCrypto.iMKI = sec.Mid( mkiPos, total ) ;		
       
  1161 		aCrypto.iMKIUsed = ETrue;
       
  1162 		}
       
  1163 	
       
  1164 	return;	
       
  1165 	}
       
  1166 
       
  1167 // -----------------------------------------------------------------------------
       
  1168 // CMceSecureDesStream::ValidateAnswerByOffer
       
  1169 // Validate and Set cryptoIn information
       
  1170 // -----------------------------------------------------------------------------
       
  1171 //    
       
  1172 void CMceSecureDesStream::ValidateAnswerByOfferL(const TDesC8& aSecDec )
       
  1173 	{
       
  1174 	/*
       
  1175 	Vaidata the incoming answer by the original offer
       
  1176 	7.1.3.  Processing of the Initial Answer - Unicast Streams
       
  1177 	*/
       
  1178 	//remember to check how many inlinle later
       
  1179 	MCEMM_DEBUG("CMceSecureDesStream::ValidateAnswerByOfferL, Entry")
       
  1180     if (aSecDec.Length() < KCryptoAttributeValueMinLength)
       
  1181  		{
       
  1182  		User::Leave( KErrArgument );
       
  1183  		}
       
  1184     // Check SRTP crypto-suites
       
  1185     if ( iSecureSession.iKeyNeedUpdated )
       
  1186     	{
       
  1187     	IfMatchLocalCryptoL(aSecDec);
       
  1188     	}
       
  1189     MSG_IGNORE_RETURN()
       
  1190    	//check key param
       
  1191    
       
  1192 	TInt foundInline = aSecDec.Find( KInline );
       
  1193  	TInt foundSeparator = aSecDec.Find( KSeparator);
       
  1194  	TInt foundColon = aSecDec.Find(KColon);
       
  1195  	if ( KErrNotFound != foundInline)
       
  1196  		{
       
  1197     //check key info
       
  1198 	    TInt keyInfoPos = foundColon+1;
       
  1199 	    TInt keyInfoLen = 0;
       
  1200 	    if (foundSeparator != KErrNotFound)
       
  1201 	        	{
       
  1202 	        	keyInfoLen = foundSeparator-keyInfoPos;
       
  1203 	        	}
       
  1204 	        else
       
  1205 	        	{
       
  1206 	        	keyInfoLen = aSecDec.Length()-keyInfoPos;
       
  1207 	        	}
       
  1208     
       
  1209 	    TPtrC8 keyInfo = aSecDec.Mid(keyInfoPos, keyInfoLen);
       
  1210 	    if ( iSecureSession.iKeyNeedUpdated )
       
  1211 	    	{
       
  1212 	    	
       
  1213 		    TBool valid = ValidateSecurityDescriptions( keyInfo );
       
  1214 	   		if ( valid )
       
  1215 	   			{
       
  1216 	   			
       
  1217 		    	// check keyInfo 
       
  1218 			    if (iCryptoOut.iEncodedKey.Compare( keyInfo ) == 0)
       
  1219 			    	{
       
  1220 			    	User::Leave( KErrArgument );
       
  1221 			    	}
       
  1222 		    	//check keyinfo mki 
       
  1223 				DecodeMKIValueL(aSecDec, ETrue, iCryptoIn );     
       
  1224 				MSG_IGNORE_RETURN()
       
  1225 				DecodeMKLifeTimeL( aSecDec, iCryptoIn );		
       
  1226 					//check sessionparam later
       
  1227 				iCryptoIn.iEncodedKey = keyInfo;
       
  1228 				StoreKeys(iCryptoIn.iEncodedKey);
       
  1229 	   			}
       
  1230 	   		else
       
  1231 	   			{
       
  1232 	   			User::Leave( KErrArgument );
       
  1233 	   			}
       
  1234 	    	}
       
  1235 	   	}
       
  1236  	else
       
  1237  		{
       
  1238  		User::Leave( KErrArgument );
       
  1239  		}
       
  1240     MCEMM_DEBUG("CMceSecureDesStream::ValidateAnswerByOfferL, Exit")
       
  1241     }
       
  1242 	
       
  1243 // -----------------------------------------------------------------------------
       
  1244 // CMceSecureDesStream::ValidateOfferByAnswer
       
  1245 // aSecDec is one attribute
       
  1246 // -----------------------------------------------------------------------------
       
  1247 //    
       
  1248 void CMceSecureDesStream::ValidateOfferByAnswerL( const TDesC8& aSecDec )
       
  1249 	{
       
  1250 	/*
       
  1251 	RFC 4568               SDP Security Descriptions               
       
  1252 	7.1.2.  Generating the Initial Answer - Unicast Streams
       
  1253 	*/
       
  1254 	//check client abilities and same time set the Answer crypto but not keys
       
  1255 	MCEMM_DEBUG("CMceSecureDesStream::ValidateOfferByAnswerL, Entry")
       
  1256 
       
  1257  	if ( aSecDec.Length() < KCryptoAttributeValueMinLength )
       
  1258  		{
       
  1259  		User::Leave ( KErrArgument);
       
  1260  		}
       
  1261  	SetPreferedCryptoL();
       
  1262  	TMceSecureCryptoInfo crypto;
       
  1263     StoreCryptoInFromOfferL(aSecDec, crypto);
       
  1264     MSG_IGNORE_RETURN()
       
  1265 	//SetClientCryptoL(crypto);	        
       
  1266 	   //check key param
       
  1267      
       
  1268     TInt foundInline = aSecDec.Find( KInline );
       
  1269     TInt foundSeparator = aSecDec.Find( KSeparator);
       
  1270     TInt foundColon = aSecDec.Find(KColon);
       
  1271     if ( KErrNotFound != foundInline)
       
  1272      	{
       
  1273         //check key info
       
  1274         TInt keyInfoPos=foundColon+1;
       
  1275         TInt keyInfoLen=0;
       
  1276         if (foundSeparator!= KErrNotFound)
       
  1277         	{
       
  1278         	keyInfoLen= foundSeparator-keyInfoPos;
       
  1279         	}
       
  1280         else
       
  1281         	{
       
  1282         	keyInfoLen = aSecDec.Length()-keyInfoPos;
       
  1283         	}
       
  1284         TPtrC8 keyInfo = aSecDec.Mid(keyInfoPos, keyInfoLen);
       
  1285         TBool valid = ValidateSecurityDescriptions( keyInfo );
       
  1286         
       
  1287         if ( valid )
       
  1288         	{
       
  1289         	
       
  1290             //check keyinfo mki 
       
  1291 		     DecodeMKIValueL( aSecDec, EFalse, crypto );   
       
  1292 		     MSG_IGNORE_RETURN()
       
  1293 		     //set MKI value for our local crypto because all MKI in one crypto suite
       
  1294 		     // should be the same
       
  1295 	     
       
  1296 	     	DecodeMKLifeTimeL( aSecDec, crypto );
       
  1297 	     	//StorKey
       
  1298 	     	crypto.iEncodedKey = keyInfo;
       
  1299 	     	TBuf8 < KMasterKeyAndSaltLength > masterKeyAndSalt;
       
  1300 			Base64Decode( crypto.iEncodedKey, masterKeyAndSalt );
       
  1301 
       
  1302 			//it should be validate already so it is our prefered key
       
  1303 		
       
  1304 			crypto.iSetMasterKey = masterKeyAndSalt.Mid( 0, KMasterKeyLength );
       
  1305 			crypto.iSetSaltKey = masterKeyAndSalt.Mid( KMasterKeyLength );
       
  1306 			crypto.iKeysCreated = ETrue;
       
  1307 			iCryptoIns->AppendL( crypto );
       
  1308 	     	//check sessionparam later	
       
  1309 	     		
       
  1310         	}
       
  1311         else
       
  1312         	{
       
  1313         	User::Leave( KErrArgument);
       
  1314         	}
       
  1315      	}
       
  1316    	else
       
  1317    		{
       
  1318  		User::Leave( KErrArgument);
       
  1319  		}
       
  1320 
       
  1321     MCEMM_DEBUG("CMceSecureDesStream::ValidateOfferByAnswerL, Exit")
       
  1322  	}
       
  1323 	
       
  1324 // -----------------------------------------------------------------------------
       
  1325 // CMceSecureDesStream::SetSecureProtocol()
       
  1326 // 
       
  1327 // -----------------------------------------------------------------------------
       
  1328 //    
       
  1329 void CMceSecureDesStream::SetSecureProtocolL(CSdpMediaField& aMediaField)
       
  1330 	{
       
  1331 	MCEMM_DEBUG("CMceSecureDesStream::SetSecureProtocol(), Entry")   
       
  1332 	TPtrC8 protocolName( KProtocolSAVP );
       
  1333 	
       
  1334 	if ( Session().Modifier( KMceSecureSession ) == KMceSecurePlainAVP )
       
  1335 		{
       
  1336 		protocolName.Set ( KProtocolAVP );
       
  1337 		}
       
  1338 	if ( !iIsSAVP )
       
  1339 		{
       
  1340 		protocolName.Set( KProtocolSAVPF );
       
  1341 		Session().Modifier( KMceSecureSession ) = KMceSecureNormal;
       
  1342 		}
       
  1343 		
       
  1344 	RStringF protocol = SdpCodecStringPool::StringPoolL().OpenFStringL( protocolName);		
       
  1345 	CleanupClosePushL( protocol );                            
       
  1346     
       
  1347 	aMediaField.SetProtocolL( protocol );	
       
  1348 	CleanupStack::PopAndDestroy( &protocol );
       
  1349 
       
  1350 	MCEMM_DEBUG("CMceSecureDesStream::SetSecureProtocol(), Exit")  
       
  1351 	}
       
  1352 	
       
  1353 
       
  1354 //-----------------------------------------------------------------------------
       
  1355 // CMceSecureDesStream::SetPreferedCrypto()
       
  1356 // 
       
  1357 // -----------------------------------------------------------------------------
       
  1358 //    
       
  1359 void CMceSecureDesStream::SetPreferedCryptoL()
       
  1360 	{
       
  1361 	MCEMM_DEBUG( "CMceSecureDesStream::SetPreferedCryptoL, entry" )	
       
  1362 	RArray <TMceCryptoContext> clientCryptoSuite = 
       
  1363 					Session().iClientCryptoSuites;
       
  1364 	TInt clientCryptoCount = clientCryptoSuite.Count();
       
  1365 	if ( !iCryptoOuts->Count() )
       
  1366 		{
       
  1367 		AppendEmptyCryptoL( *iCryptoOuts, KTotalCryptoAnswerCount );
       
  1368 		}
       
  1369 	if (!clientCryptoCount )
       
  1370 		{
       
  1371 		MCEMM_DEBUG( "Client has no preference on crypto" )	
       
  1372 		iCryptoOuts->Reset();
       
  1373 		// tag 80 prefered
       
  1374 		SetDefaultCryptoL( *iCryptoOuts );
       
  1375 		}
       
  1376 	else
       
  1377 		{
       
  1378 		iCryptoOuts->Reset();
       
  1379 		SetCryptoByClientL( *iCryptoOuts );
       
  1380 		}
       
  1381 	MCEMM_DEBUG( "CMceSecureDesStream::SetPreferedCryptoL, exit" )		
       
  1382 	}
       
  1383 
       
  1384 //-----------------------------------------------------------------------------
       
  1385 // CMceSecureDesStream::SetClientCrypto()
       
  1386 // 
       
  1387 // -----------------------------------------------------------------------------
       
  1388 //    
       
  1389 void CMceSecureDesStream::SetClientCryptoL( TInt aCryptoCount )
       
  1390 	{
       
  1391 	MCEMM_DEBUG( "CMceSecureDesStream::SetClientCryptoL, entry" )	
       
  1392 	RArray< TMceCryptoContext > clientCryptoSuite = 
       
  1393 	    Session().iClientCryptoSuites;
       
  1394 	TInt clientCryptoSuiteCount = clientCryptoSuite.Count();
       
  1395 	
       
  1396 	if ( iCryptoOuts->Count() == 0 )
       
  1397 		{
       
  1398 		AppendEmptyCryptoL( *iCryptoOuts, KTotalCryptoAnswerCount );
       
  1399 		}
       
  1400 		
       
  1401 	if ( clientCryptoSuiteCount > 0 )
       
  1402 		{	
       
  1403 		for ( TInt index = 0; index < clientCryptoSuiteCount; index++ )
       
  1404 			{
       
  1405 			if ( aCryptoCount-1 == index )
       
  1406 				{
       
  1407 				MCEMM_DEBUG_DVALUE(" index = ", index )
       
  1408 				MCEMM_DEBUG_DVALUE(" iCryptoOuts->Count() ", iCryptoOuts->Count() )	
       
  1409 				iGnoreSdpMsg = index >= iCryptoOuts->Count() ? ETrue : EFalse;
       
  1410 				MSG_IGNORE_RETURN()
       
  1411 				TMceSecureCryptoInfo cryptoOut = iCryptoOuts->At( index );
       
  1412 				
       
  1413 				if ( clientCryptoSuite[index]== EAES_CM_128_HMAC_SHA1_80 )
       
  1414 					{
       
  1415 					SetSHA180( cryptoOut, aCryptoCount );
       
  1416 					}
       
  1417 				if ( clientCryptoSuite[ index ] == EAES_CM_128_HMAC_SHA1_32 )
       
  1418 					{
       
  1419 					//iCrytoOuts has been created in GenerateKey
       
  1420 					SetSHA132( cryptoOut, aCryptoCount );
       
  1421 					}	
       
  1422 				iCryptoOuts->At( index ).Copy( cryptoOut );	
       
  1423 				}
       
  1424 			}
       
  1425 		}
       
  1426 	MCEMM_DEBUG( "CMceSecureDesStream::SetClientCryptoL, exit" )
       
  1427 	}	
       
  1428 
       
  1429 
       
  1430 //-----------------------------------------------------------------------------
       
  1431 // CMceSecureDesStream::ClientCrytoCount()
       
  1432 // 
       
  1433 // -----------------------------------------------------------------------------
       
  1434 //    
       
  1435 TInt CMceSecureDesStream::ClientCrytoCount()
       
  1436 	{
       
  1437 	TInt count = Session().iClientCryptoSuites.Count();
       
  1438 	return count;
       
  1439 	}		
       
  1440 
       
  1441 
       
  1442 //-----------------------------------------------------------------------------
       
  1443 // CMceSecureDesStream::IfMatchLocalCryptoL()
       
  1444 // 
       
  1445 // -----------------------------------------------------------------------------
       
  1446 //
       
  1447 void CMceSecureDesStream::IfMatchLocalCryptoL( const TDesC8& aSecDec )
       
  1448 	{
       
  1449 	MCEMM_DEBUG( "CMceSecureDesStream::IfMatchLocalCryptoL, entry" )
       
  1450 	TMceSecureCryptoInfo crypto;
       
  1451 	TInt foundAes80 = aSecDec.Find( KAES_SHA1_80 );
       
  1452 	TInt foundAes32 = aSecDec.Find( KAES_SHA1_32 );
       
  1453 	if (foundAes80 != KErrNotFound )
       
  1454 		{
       
  1455 		TPtrC8 tagValue = aSecDec.Mid( foundAes80-2, 1);
       
  1456 		TLex8 lexTag(tagValue);
       
  1457 		TUint tag=0;
       
  1458 		User::LeaveIfError( lexTag.Val( tag, EDecimal));
       
  1459 		SetSHA180( crypto, tag );
       
  1460 		}
       
  1461 	else if (foundAes32!= KErrNotFound )
       
  1462 		{
       
  1463 		TPtrC8 tagValue = aSecDec.Mid( foundAes32-2, 1 );
       
  1464 		TLex8 lexTag( tagValue );
       
  1465 		TUint tag = 0;
       
  1466 		User::LeaveIfError( lexTag.Val( tag, EDecimal ));
       
  1467 		SetSHA132( crypto, tag );
       
  1468 		}	
       
  1469 	TInt find = SearchAndSetCrypto( crypto );
       
  1470 	iGnoreSdpMsg = find == KErrNone ? EFalse : ETrue;
       
  1471 	MCEMM_DEBUG( "CMceSecureDesStream::IfMatchLocalCryptoL, exit" )
       
  1472 	return ;
       
  1473 	}
       
  1474 
       
  1475 //-----------------------------------------------------------------------------
       
  1476 // CMceSecureDesStream::SearchAndSetCrypto()
       
  1477 // 
       
  1478 // -----------------------------------------------------------------------------
       
  1479 //
       
  1480 TInt CMceSecureDesStream::SearchAndSetCrypto(TMceSecureCryptoInfo& aCrypto)
       
  1481 	{
       
  1482 	MCEMM_DEBUG( "CMceSecureDesStream::SearchAndSetCrypto, entry" )
       
  1483 	for ( TInt i=0; i < iCryptoOuts->Count(); i++ )
       
  1484 		{
       
  1485 		MCEMM_DEBUG_DVALUE(" iCryptoOuts->Count() ", iCryptoOuts->Count() )	
       
  1486 				
       
  1487 		TMceSecureCryptoInfo cryptoOut = iCryptoOuts->At( i );
       
  1488 		if ( cryptoOut.iTagLen == aCrypto.iTagLen &&
       
  1489 			 cryptoOut.iEncAlgms == aCrypto.iEncAlgms &&
       
  1490 			 cryptoOut.iAuthAlgms == aCrypto.iAuthAlgms &&
       
  1491 			 cryptoOut.iCryptoSuite.Compare(aCrypto.iCryptoSuite) == 0)
       
  1492 			{
       
  1493 			//SEtCrypto
       
  1494 			iCryptoOut.Copy( cryptoOut );
       
  1495 			iCryptoIn.iTag = cryptoOut.iTag;
       
  1496 			iCryptoIn.iEncAlgms = cryptoOut.iEncAlgms;
       
  1497 			iCryptoIn.iAuthAlgms = cryptoOut.iAuthAlgms;
       
  1498 			iCryptoIn.iTagLen = cryptoOut.iTagLen;
       
  1499 			iCryptoIn.iCryptoSuite = cryptoOut.iCryptoSuite ;
       
  1500         	return KErrNone;
       
  1501 			}
       
  1502 		}
       
  1503 	MCEMM_DEBUG( "SearchAndSetCrypto NotFound" )	
       
  1504 	MCEMM_DEBUG( "CMceSecureDesStream::SearchAndSetCrypto, exit" )	
       
  1505 	return KErrNotFound;	
       
  1506 	}	
       
  1507 	
       
  1508 	
       
  1509 //-----------------------------------------------------------------------------
       
  1510 // CMceSecureDesStream::StoreCryptoInFromOffer()
       
  1511 // 
       
  1512 // -----------------------------------------------------------------------------
       
  1513 //
       
  1514 void CMceSecureDesStream::StoreCryptoInFromOfferL( const TDesC8& aSecDec, 
       
  1515                                                    TMceSecureCryptoInfo& aCrypto)
       
  1516 	{
       
  1517 	MCEMM_DEBUG( "CMceSecureDesStream::StoreCryptoInFromOfferL entry" )
       
  1518 	TInt foundAes80 = aSecDec.Find( KAES_SHA1_80 );
       
  1519 	TInt foundAes32 = aSecDec.Find( KAES_SHA1_32 );
       
  1520 	if ( foundAes80 != KErrNotFound )
       
  1521 		{
       
  1522 		TPtrC8 tagValue = aSecDec.Mid( foundAes80-2, 1 );
       
  1523 		TLex8 lexTag( tagValue );
       
  1524 		TUint tag = 0;
       
  1525 		User::LeaveIfError( lexTag.Val( tag, EDecimal ));
       
  1526 		SetSHA180( aCrypto, tag );
       
  1527 		}
       
  1528 	else if (foundAes32!= KErrNotFound )
       
  1529 		{
       
  1530 		TPtrC8 tagValue = aSecDec.Mid( foundAes32-2, 1 );
       
  1531 		TLex8 lexTag( tagValue );
       
  1532 		TUint tag = 0;
       
  1533 		User::LeaveIfError( lexTag.Val( tag, EDecimal ));
       
  1534 		SetSHA132( aCrypto, tag );
       
  1535 		}
       
  1536 			
       
  1537 	if (foundAes32 == KErrNotFound && foundAes80 == KErrNotFound)
       
  1538 		{
       
  1539 		iGnoreSdpMsg = ETrue;
       
  1540 		MCEMM_DEBUG( " Not Found any acceptible Crypto Value in SecureDes" )
       
  1541 		return;
       
  1542 		} 
       
  1543 	
       
  1544 	for ( TInt i=0; i < iCryptoOuts->Count(); i++ )
       
  1545 		{
       
  1546 		MCEMM_DEBUG_DVALUE(" iCryptoOuts->Count() ", iCryptoOuts->Count() )	
       
  1547 				
       
  1548 		TMceSecureCryptoInfo cryptoOut = iCryptoOuts->At( i );
       
  1549 		if ( cryptoOut.iTagLen == aCrypto.iTagLen &&
       
  1550 			 cryptoOut.iEncAlgms == aCrypto.iEncAlgms &&
       
  1551 			 cryptoOut.iAuthAlgms == aCrypto.iAuthAlgms &&
       
  1552 			 cryptoOut.iCryptoSuite.Compare(aCrypto.iCryptoSuite) == 0 )
       
  1553 			{
       
  1554 			MCEMM_DEBUG( " Compare with own crypto OK" )
       
  1555 			return;
       
  1556 			}
       
  1557 		}
       
  1558 	iGnoreSdpMsg = ETrue;
       
  1559 	MCEMM_DEBUG( "CMceSecureDesStream::StoreCryptoInFromOfferL exit" )	
       
  1560 	}	
       
  1561 
       
  1562 	
       
  1563 //-----------------------------------------------------------------------------
       
  1564 // CMceSecureDesStream::StoreCryptoInFromOffer()
       
  1565 // 
       
  1566 // -----------------------------------------------------------------------------
       
  1567 //
       
  1568 TInt CMceSecureDesStream::CompareCryptosForAnswer()
       
  1569 	{
       
  1570 	//check how client wants
       
  1571 	MCEMM_DEBUG( "CMceSecureDesStream::CompareCryptosForAnswer entry" )
       
  1572 	if (iCryptoOuts->Count())
       
  1573 		{
       
  1574 		MCEMM_DEBUG_DVALUE(" iCryptoOuts->Count() ", iCryptoOuts->Count() )	
       
  1575 				
       
  1576 		TInt count = iCryptoOuts->Count();
       
  1577 		for ( TInt i = 0; i< count; i++ )
       
  1578 			{
       
  1579 			for ( TInt j = 0; j < iCryptoIns->Count(); j++ )
       
  1580 				{	
       
  1581 				MCEMM_DEBUG_DVALUE(" iCryptoIns->Count() ", iCryptoIns->Count() )
       
  1582 				if (iCryptoOuts->At( i ).iTagLen == iCryptoIns->At( j ).iTagLen &&
       
  1583 					iCryptoOuts->At( i ).iEncAlgms == iCryptoIns->At( j ).iEncAlgms &&
       
  1584 					iCryptoOuts->At( i ).iAuthAlgms == iCryptoIns->At( j ).iAuthAlgms &&
       
  1585 					iCryptoOuts->At( i ).iCryptoSuite.Compare( iCryptoIns->At( j ).iCryptoSuite) == 0 )
       
  1586 					{
       
  1587 					iCryptoIn.Copy( iCryptoIns->At( j ) );
       
  1588 					//So can set the MKI and MKT
       
  1589 					iCryptoOut.Copy( iCryptoIns->At( j ) );
       
  1590 					MCEMM_DEBUG( "CMceSecureDesStream::CompareCryptosForAnswer exit" )
       
  1591 					return KErrNone;
       
  1592 					}
       
  1593 				}
       
  1594 			}
       
  1595 		}
       
  1596 	MCEMM_DEBUG( "No CryptoOuts Set" )
       
  1597 	MCEMM_DEBUG( "CMceSecureDesStream::CompareCryptosForAnswer exit" )
       
  1598 	return KErrArgument;	
       
  1599 	}
       
  1600 	
       
  1601 //-----------------------------------------------------------------------------
       
  1602 // CMceSecureDesStream::RemoveClientCrypto()
       
  1603 // 
       
  1604 // -----------------------------------------------------------------------------
       
  1605 //
       
  1606 void CMceSecureDesStream::RemoveClientCrypto()
       
  1607 	{
       
  1608 	TInt count = ClientCrytoCount();
       
  1609     for (TInt i = count; i > 0; i--)
       
  1610     	{
       
  1611     	Session().iClientCryptoSuites.Remove( i-1 );	
       
  1612    		}	
       
  1613 	}
       
  1614 
       
  1615 //-----------------------------------------------------------------------------
       
  1616 // CMceSecureDesStream::SetClientCrypto()
       
  1617 // 
       
  1618 // -----------------------------------------------------------------------------
       
  1619 //
       
  1620 void CMceSecureDesStream::SetClientCryptoL( TMceSecureCryptoInfo& aCrypto )
       
  1621 	{
       
  1622     if ( !aCrypto.iCryptoSuite.Compare( KAES_SHA1_32 ))
       
  1623     	{
       
  1624     	User::LeaveIfError( 
       
  1625     		Session().iClientCryptoSuites.Append( EAES_CM_128_HMAC_SHA1_32 ));		
       
  1626     	}
       
  1627     if ( !aCrypto.iCryptoSuite.Compare(KAES_SHA1_80) )
       
  1628     	{
       
  1629     	User::LeaveIfError( 
       
  1630     	    Session().iClientCryptoSuites.Append( EAES_CM_128_HMAC_SHA1_80 ));		
       
  1631     	}
       
  1632 	}
       
  1633 
       
  1634 //-----------------------------------------------------------------------------
       
  1635 // CMceSecureDesStream::SetMultipleClientCrypto()
       
  1636 // 
       
  1637 // -----------------------------------------------------------------------------
       
  1638 //
       
  1639 void CMceSecureDesStream::SetMultipleClientCryptoL( 
       
  1640     CArrayFixFlat< TMceSecureCryptoInfo>& aArray )
       
  1641 	{
       
  1642 	TInt index =0;
       
  1643 	TInt count = aArray.Count();
       
  1644 	for ( index = 0; index < count; index ++ )
       
  1645 		{
       
  1646 		SetClientCryptoL( aArray[index] );
       
  1647 		}
       
  1648     
       
  1649 	}
       
  1650 //-----------------------------------------------------------------------------
       
  1651 // CMceSecureDesStream::CountCrypto()
       
  1652 // 
       
  1653 // -----------------------------------------------------------------------------
       
  1654 //
       
  1655 TInt CMceSecureDesStream::CountCryptoInOffer( CSdpMediaField& aMediaField )
       
  1656 	{
       
  1657 	
       
  1658     if ( !iCryptoIns->Count() && !ClientCrytoCount()  && 
       
  1659     		iSecureSession.SdpCryptoAttributeCount(aMediaField) )
       
  1660     	{
       
  1661     	return KErrArgument;
       
  1662     	}
       
  1663     return KErrNone;	
       
  1664     }				
       
  1665 
       
  1666 //-----------------------------------------------------------------------------
       
  1667 // CMceSecureDesStream::Copy()
       
  1668 // 
       
  1669 // -----------------------------------------------------------------------------
       
  1670 //
       
  1671 void CMceSecureDesStream::CopyStreamCryptoL( CMceSecureDesStream& aCopyFrom ) 
       
  1672 	{
       
  1673 	MCEMM_DEBUG( "CMceSecureDesStream::CopyStreamCryptoL Entry" )
       
  1674 	iCryptoUpdateNeeded = ETrue;
       
  1675     iCryptoOut.Copy(aCopyFrom.iCryptoOut);
       
  1676     MCEMM_DEBUG_DVALUE( "iCryptoContextOutId", aCopyFrom.iCryptoOut.iCryptoContextId )
       
  1677     iCryptoContextOutId = aCopyFrom.iCryptoOut.iCryptoContextId;
       
  1678     iCryptoIn.Copy(aCopyFrom.iCryptoIn);
       
  1679     iCryptoContextInId = aCopyFrom.iCryptoIn.iCryptoContextId;
       
  1680     MCEMM_DEBUG_DVALUE( "iCryptoContextInId", aCopyFrom.iCryptoIn.iCryptoContextId )
       
  1681 
       
  1682 	for (TInt i = 0; i < aCopyFrom.iCryptoOuts->Count(); i++)
       
  1683 		{
       
  1684 		iCryptoOuts->AppendL( aCopyFrom.iCryptoOuts->At( i ) );
       
  1685 		}
       
  1686 		iOldLocalMediaPort = aCopyFrom.iOldLocalMediaPort;
       
  1687  	MCEMM_DEBUG( "CMceSecureDesStream::CopyStreamCryptoL Exit" )
       
  1688 	}
       
  1689 
       
  1690 //-----------------------------------------------------------------------------
       
  1691 // CMceSecureDesStream::Session()
       
  1692 // 
       
  1693 // -----------------------------------------------------------------------------
       
  1694 //
       
  1695 CMceComSession& CMceSecureDesStream::Session()
       
  1696 	{
       
  1697 	return iSecureSession.iSession;
       
  1698 	}
       
  1699 
       
  1700 //-----------------------------------------------------------------------------
       
  1701 // CMceSecureDesStream::MediaFieldAttrMatch()
       
  1702 // 
       
  1703 // -----------------------------------------------------------------------------
       
  1704 //
       
  1705 CSdpAttributeField* CMceSecureDesStream::MediaFieldAttrMatch( 	CSdpMediaField& aMediaField,
       
  1706 																const TDesC8& aMatchString )
       
  1707 	{
       
  1708 	RPointerArray< CSdpAttributeField > attrList =  
       
  1709                 aMediaField.AttributeFields();
       
  1710     
       
  1711     TInt attrCount = attrList.Count();
       
  1712     
       
  1713     for (TInt j = 0; j < attrCount; j++ )
       
  1714         {
       
  1715         RStringF attribute = attrList[ j ]->Attribute();
       
  1716      
       
  1717      	 if ( attribute.DesC().Match( aMatchString )!= KErrNotFound )
       
  1718         	{
       
  1719         	return attrList[ j ];
       
  1720         	}
       
  1721         }
       
  1722     return NULL;    
       
  1723 	}
       
  1724 	
       
  1725 //-----------------------------------------------------------------------------
       
  1726 // CMceSecureDesStream::SetMediaProfile ()
       
  1727 // 
       
  1728 // -----------------------------------------------------------------------------
       
  1729 //
       
  1730 TInt CMceSecureDesStream::SetMediaProfile( CSdpMediaField& aMediaField )
       
  1731 	{
       
  1732 	//answer or offer/update or refresh
       
  1733 	TInt findSAVP = aMediaField.Protocol().DesC().Find( KProtocolSAVP );
       
  1734 	TInt findSAVPF = aMediaField.Protocol().DesC().Find( KProtocolSAVPF );	
       
  1735     TInt findAVP = aMediaField.Protocol().DesC().Find( KProtocolAVP );	
       
  1736     
       
  1737     if ( findSAVP == KErrNotFound && findSAVPF == KErrNotFound &&
       
  1738 		findAVP == KErrNotFound)
       
  1739 		{
       
  1740 		return KErrArgument;
       
  1741 		}
       
  1742 	if ( findAVP != KErrNotFound )
       
  1743 		{
       
  1744         Session().Modifier( KMceSecureSession ) = KMceSecurePlainAVP;
       
  1745 		}
       
  1746 	if ( findSAVP != KErrNotFound || findSAVPF != KErrNotFound )
       
  1747 		{
       
  1748 		Session().Modifier( KMceSecureSession ) = KMceSecureNormal;
       
  1749 		iIsSAVP = findSAVPF != KErrNotFound ? !iIsSAVP : iIsSAVP;	
       
  1750 		}
       
  1751 	
       
  1752 	
       
  1753 	return KErrNone;
       
  1754 	}
       
  1755 
       
  1756 
       
  1757 //-----------------------------------------------------------------------------
       
  1758 // CMceSecureDesStream::AppendCryptoAttributeL ()
       
  1759 // 
       
  1760 // -----------------------------------------------------------------------------
       
  1761 //
       
  1762 void CMceSecureDesStream::AppendCryptoAttributeL( 	TDesC8& aCryptoLine,
       
  1763 													CSdpMediaField& aMediaField )
       
  1764 	{
       
  1765 	RStringF crypto = SdpCodecStringPool::StringPoolL().OpenFStringL( KCrypto );
       
  1766     CleanupClosePushL( crypto );               
       
  1767 	CSdpAttributeField* attribute = NULL;
       
  1768 	attribute = CSdpAttributeField::NewLC( crypto, aCryptoLine );
       
  1769    	User::LeaveIfError ( aMediaField.AttributeFields().Append( attribute ) );
       
  1770     CleanupStack::Pop(attribute);	   
       
  1771     CleanupStack::PopAndDestroy( &crypto ); 
       
  1772 	}
       
  1773 
       
  1774 //-----------------------------------------------------------------------------
       
  1775 // CMceSecureDesStream::AppendCryptoAttributeL ()
       
  1776 // 
       
  1777 // -----------------------------------------------------------------------------
       
  1778 //
       
  1779 TInt CMceSecureDesStream::SearchChar( 	TDesC8& aSearchLine, 
       
  1780 										TChar& aChar, 
       
  1781 										TInt aSearchFrom )
       
  1782 	{
       
  1783 	TInt len = aSearchLine.Length();
       
  1784 	TLex8 search( aSearchLine );
       
  1785 
       
  1786 	for ( TInt offset = 0; offset < len; offset++ )
       
  1787 		{
       
  1788 		if ( search.Peek() == aChar )
       
  1789 			{
       
  1790 			if ( !aSearchFrom )
       
  1791 				return offset;
       
  1792 			if (aSearchFrom && offset > aSearchFrom)
       
  1793 				return offset;
       
  1794 			}
       
  1795 		search.Inc();	
       
  1796 		}
       
  1797 	return KErrNone;
       
  1798 	}	
       
  1799 
       
  1800 //-----------------------------------------------------------------------------
       
  1801 // CMceSecureDesStream::AppendEmptyCryptoL ()
       
  1802 // 
       
  1803 // -----------------------------------------------------------------------------
       
  1804 //
       
  1805 void CMceSecureDesStream::AppendEmptyCryptoL( 
       
  1806 							CArrayFixFlat<TMceSecureCryptoInfo>& aCryptos,
       
  1807 							TInt aCount )
       
  1808 	{
       
  1809 	for ( TInt i = 0; i < aCount; i++)
       
  1810 		{
       
  1811 		TMceSecureCryptoInfo crypto;
       
  1812 		aCryptos.AppendL( crypto );
       
  1813 		}
       
  1814 	}
       
  1815 
       
  1816 //-----------------------------------------------------------------------------
       
  1817 // CMceSecureDesStream::SetSHA132 ()
       
  1818 // 
       
  1819 // -----------------------------------------------------------------------------
       
  1820 //
       
  1821 void CMceSecureDesStream::SetSHA132( TMceSecureCryptoInfo& aCrypto, TInt aTag )
       
  1822 	{
       
  1823 	aCrypto.iTag = aTag;
       
  1824 	aCrypto.iEncAlgms = ESrtpEncAES_CM;
       
  1825     aCrypto.iTagLen = KAuthTagLength32;
       
  1826     aCrypto.iAuthAlgms = ESrtpAuthHMAC_SHA1;
       
  1827 	aCrypto.iCryptoSuite = KAES_SHA1_32;
       
  1828 	}	
       
  1829 
       
  1830 //-----------------------------------------------------------------------------
       
  1831 // CMceSecureDesStream::SetSHA180 ()
       
  1832 // 
       
  1833 // -----------------------------------------------------------------------------
       
  1834 //
       
  1835 void CMceSecureDesStream::SetSHA180( TMceSecureCryptoInfo& aCrypto, TInt aTag )
       
  1836 	{
       
  1837 	aCrypto.iTag = aTag;
       
  1838 	aCrypto.iEncAlgms = ESrtpEncAES_CM;
       
  1839     aCrypto.iTagLen = KAuthTagLength80;
       
  1840     aCrypto.iAuthAlgms = ESrtpAuthHMAC_SHA1;
       
  1841 	aCrypto.iCryptoSuite = KAES_SHA1_80;
       
  1842    	}
       
  1843    	
       
  1844 //-----------------------------------------------------------------------------
       
  1845 // CMceSecureDesStream::SetDefaultCryptoL ()
       
  1846 // 
       
  1847 // -----------------------------------------------------------------------------
       
  1848 //
       
  1849 void CMceSecureDesStream::SetDefaultCryptoL( 
       
  1850 							CArrayFixFlat<TMceSecureCryptoInfo>& aCryptos )
       
  1851 	{
       
  1852 	MCEMM_DEBUG( "CMceSecureDesStream::SetDefaultCryptoL, entry " )
       
  1853 	const TInt tag1 = 1;
       
  1854 	const TInt tag2 = 2;
       
  1855 	const TUint index1 = 0;
       
  1856 	const TInt index2 = 1;
       
  1857 	
       
  1858 	AppendEmptyCryptoL( aCryptos, KTotalCryptoAnswerCount );
       
  1859 	
       
  1860 	MCEMM_DEBUG_DVALUE(" CryptoCount = ", aCryptos.Count() )
       
  1861 	iGnoreSdpMsg = !aCryptos.Count() ? ETrue : EFalse;
       
  1862 	MSG_IGNORE_RETURN()
       
  1863     SetSHA180( aCryptos.At( index1 ), tag1 );
       
  1864     
       
  1865     iGnoreSdpMsg = index2 >= iCryptoOuts->Count() ? ETrue : EFalse;
       
  1866     MSG_IGNORE_RETURN()
       
  1867     SetSHA132( aCryptos.At( index2 ), tag2 );
       
  1868     
       
  1869 	MCEMM_DEBUG( "CMceSecureDesStream::SetDefaultCryptoL, exit " )
       
  1870 	}   
       
  1871 	
       
  1872 //-----------------------------------------------------------------------------
       
  1873 // CMceSecureDesStream::SetCryptoByClientL ()
       
  1874 // 
       
  1875 // -----------------------------------------------------------------------------
       
  1876 //
       
  1877 void CMceSecureDesStream::SetCryptoByClientL( 
       
  1878 							CArrayFixFlat<TMceSecureCryptoInfo>& aCryptos )
       
  1879 	{
       
  1880 	MCEMM_DEBUG( "CMceSecureDesStream::SetCryptoByClientL, entry " )
       
  1881 	RArray <TMceCryptoContext> clientCryptoSuite =  
       
  1882 											Session().iClientCryptoSuites;
       
  1883 	TInt clientCryptoCount = clientCryptoSuite.Count();
       
  1884 	MCEMM_DEBUG_DVALUE(" ClientCryptoCount = ", aCryptos.Count() )											
       
  1885 	for ( TInt i = 0; i < clientCryptoCount; i++ )
       
  1886 			{
       
  1887 			TMceSecureCryptoInfo crypto;
       
  1888 			
       
  1889 			if ( clientCryptoSuite[i] == EAES_CM_128_HMAC_SHA1_32 )
       
  1890 				{
       
  1891 				SetSHA132( crypto, i+1 );
       
  1892 				}
       
  1893 			if ( clientCryptoSuite[i] == EAES_CM_128_HMAC_SHA1_80 )
       
  1894 				{
       
  1895 				SetSHA180( crypto, i+1 );
       
  1896 				}
       
  1897 			aCryptos.AppendL( crypto );		
       
  1898 			}
       
  1899 	MCEMM_DEBUG( "CMceSecureDesStream::SetCryptoByClientL, exit " )
       
  1900 	}   							
       
  1901 //  End of File