--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/multimediacommsengine/mmcesrv/mmcemediamanager/src/mcesecuredesstream.cpp Tue Feb 02 01:04:58 2010 +0200
@@ -0,0 +1,1901 @@
+/*
+* Copyright (c) 2002-2007 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Provides services for SDP Security Descriptions.
+*
+*/
+
+
+
+
+// INCLUDE FILES
+#include "mcesecuredesstream.h"
+#include "mcemmlogs.h"
+#include <tconvbase64.h> // TImCodecB64
+#include <random.h>
+#include <e32math.h>
+#include <sdpdocument.h>
+#include <sdpcodecstringconstants.h>
+#include <sdpcodecstringpool.h>
+#include <sdpmediafield.h>
+#include <sdpfmtattributefield.h>
+#include <sdpattributefield.h>
+#include <mmccsrtpmasterkey.h>
+#include <mmccsrtpmastersalt.h>
+#include <mmccsecureinterface.h>
+#include "mcesecuresession.h"
+#include "mcecomsession.h"
+#include "mcecommediastream.h"
+#include "mcesip.h"
+#define MSG_IGNORE_RETURN( )\
+ if( iGnoreSdpMsg ){ iSecureSession.RemoveSecureCrypto(); return; }
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CMceSecureDesStream::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CMceSecureDesStream::ConstructL(CSdpMediaField& aMediaField)
+ {
+ iCryptoOuts = new ( ELeave ) CArrayFixFlat< TMceSecureCryptoInfo >( KCryptoGranularity );
+ iCryptoIns = new ( ELeave ) CArrayFixFlat< TMceSecureCryptoInfo >( KCryptoGranularity );
+
+ iMediaField=aMediaField.CloneL();
+ }
+
+// -----------------------------------------------------------------------------
+// CMceSecureDesStream::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CMceSecureDesStream* CMceSecureDesStream::NewL( CMceSecureMediaSession& aSecureSession,
+ CSdpMediaField& aMediaField,
+ CMccSecureInterface& aSecureInterface,
+ CMceComMediaStream& aMediaStream)
+ {
+ CMceSecureDesStream* self = new (ELeave) CMceSecureDesStream(aSecureSession,
+ aSecureInterface,
+ aMediaStream);
+ CleanupStack::PushL( self );
+ self->ConstructL(aMediaField);
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CMceSecureDesStream::CMceSecureDesStream
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CMceSecureDesStream::CMceSecureDesStream( CMceSecureMediaSession& aSecureSession,
+ CMccSecureInterface& aSecureInterface,
+ CMceComMediaStream& aMediaStream
+ ):
+
+ iSecureSession(aSecureSession),
+ iSecInf(aSecureInterface),
+ iMediaStream(aMediaStream),
+ iIsSAVP(ETrue),
+ iWaitingBinding(EFalse),
+ iCryptoContextOutId(0),
+ iCryptoContextInId(0),
+ iOldLocalMediaPort(0)
+ {
+
+ }
+
+// -----------------------------------------------------------------------------
+// CMceSecureDesStream::CMceSecureDesStream
+// Destructor
+// -----------------------------------------------------------------------------
+//
+CMceSecureDesStream::~CMceSecureDesStream()
+ {
+ if(iCryptoOuts!=NULL)
+ {
+ if ( iCryptoOuts->Count() )
+ {
+ iCryptoOuts->Reset();
+ }
+ }
+ if(iCryptoIns!=NULL)
+ {
+ if ( iCryptoIns->Count() )
+ {
+ iCryptoIns->Reset();
+ }
+ }
+ delete iCryptoOuts;
+ delete iCryptoIns;
+ iCryptoOut.iMasterKeys.Close();
+ iCryptoIn.iMasterKeys.Close();
+ iCryptoOut.iSaltKeys.Close();
+ iCryptoIn.iSaltKeys.Close();
+ iCryptoOut.iEncodedKeys.Close();
+ iCryptoIn.iEncodedKeys.Close();
+ iCryptoOut.CryptoDestruct();
+ iCryptoIn.CryptoDestruct();
+ delete iMediaField;
+ delete iMKIBuf;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CMceSecureDesStream::GenerateRandomKeys
+// Generates security keys
+// -----------------------------------------------------------------------------
+//
+void CMceSecureDesStream::GenerateRandomKeys( TMceSecureCryptoInfo& aCrypto )
+ {
+ MCEMM_DEBUG("CMceSecureDesStream::GenerateRandomKeys, Entry ")
+
+ MCEMM_DEBUG("Generate Keys")
+ TBuf8< KMasterKeyAndSaltLength > random;
+ RandomString( random );
+
+ // Encode random string
+ TBuf8< KEncodedStringLength > encoded;
+ Base64Encode( random, encoded );
+ aCrypto.ResetKeys();
+ aCrypto.iEncodedKey = encoded;
+ //added generated masterkey
+ aCrypto.iSetMasterKey = random.Mid( 0, KMasterKeyLength );
+
+ //added generated salt key
+ aCrypto.iSetSaltKey = random.Mid( KMasterKeyLength );
+ aCrypto.iKeysCreated = ETrue;
+ random.Zero();
+
+ MCEMM_DEBUG("CMceSecureDesStream::GenerateRandomKeys, Exit ")
+ }
+
+// -----------------------------------------------------------------------------
+// CMceSecureDesStream::EncodeSecureSdpL()
+// Generates security key to SDP offer/Answer.
+// -----------------------------------------------------------------------------
+//
+void CMceSecureDesStream::EncodeSecureSdpL(
+ CSdpMediaField& aMediaField,
+ TBool aIsAnswer )
+ {
+ MCEMM_DEBUG("CMceSecureDesStream::EncodeSecureSdpL(), Entry ")
+
+ iGnoreSdpMsg = EFalse;
+
+ const TUint8 KCryptoTag = 1;
+
+ TInt authCount = ClientCrytoCount();
+ authCount = authCount ? authCount : KAuthTagLengthTypeCount;
+ MCEMM_DEBUG_DVALUE("iKeyNeedUpdated", iSecureSession.iKeyNeedUpdated )
+ TBuf8< KCryptoLineMaxLength > cryptoLine;
+
+ if ( aIsAnswer )
+ {
+ MCEMM_DEBUG("Encode Secure Answer")
+ if ( iSecureSession.iCryptoContextUpdate )
+ {
+ iCryptoOuts->Reset();
+ iSecureSession.iCryptoContextUpdate = EFalse;
+ }
+
+ iCryptoOut.iTag = KCryptoTag;
+ GenerateCryptoLineL( cryptoLine, iCryptoOut.iTag, aIsAnswer );
+
+ if ( !iGnoreSdpMsg &&
+ KCryptoAttributeValueMinLength <= cryptoLine.Length() &&
+ iCryptoOut.iEncodedKey.Length() > 0 )
+ {
+ AppendCryptoAttributeL( cryptoLine, aMediaField );
+ }
+ cryptoLine.Zero();
+ }
+ else if ( iSecureSession.iKeyNeedUpdated &&
+ iSecureSession.iCryptoContextUpdate )
+ {
+ MCEMM_DEBUG("Encode Secure Offer; Crypto Update Required")
+ iSecureSession.iCryptoContextUpdate = EFalse;
+ TInt tagIndex = 0;
+ TInt tag;
+ iCryptoOuts->Reset();
+ for ( tagIndex = 0; tagIndex < authCount; tagIndex++ )
+ {
+ tag = tagIndex+1;
+ GenerateCryptoLineL( cryptoLine, tag, aIsAnswer );
+
+ if ( !iGnoreSdpMsg &&
+ KCryptoAttributeValueMinLength <= cryptoLine.Length() )
+ {
+ AppendCryptoAttributeL( cryptoLine, aMediaField );
+ }
+ cryptoLine.Zero();
+ }
+ }
+ else
+ {
+ MCEMM_DEBUG("Encode Updated Offer; No Crypto Update Required")
+ iCryptoOut.iTag = KCryptoTag;
+ GenerateCryptoLineL( cryptoLine, iCryptoOut.iTag, aIsAnswer );
+
+ if ( !iGnoreSdpMsg &&
+ KCryptoAttributeValueMinLength <= cryptoLine.Length() &&
+ iCryptoOut.iEncodedKey.Length() > 0 )
+ {
+ AppendCryptoAttributeL( cryptoLine, aMediaField );
+ }
+ cryptoLine.Zero();
+ }
+
+ if ( !iGnoreSdpMsg )
+ {
+ SetSecureProtocolL( aMediaField );
+ iCryptoUpdateNeeded =
+ iCryptoUpdateNeeded ? EFalse : iCryptoUpdateNeeded;
+ MCEMM_DEBUG("Encode Secure Crypto Succeeded")
+ }
+
+ if ( !aMediaField.IsValid() )
+ {
+ User::Leave( KErrCorrupt );
+ }
+
+ MCEMM_DEBUG("CMceSecureDesStream::EncodeSecureSdpL(), Exit")
+ }
+
+
+// -----------------------------------------------------------------------------
+// CMceSecureDesStream::StoreKeys()
+// Store security keys
+// -----------------------------------------------------------------------------
+//
+void CMceSecureDesStream::StoreKeys( TDesC8& aData )
+ {
+ //DecodeAnswer or Offer
+ //multiple tag
+ /*a=crypto:1 AES_CM_128_HMAC_SHA1_80
+ inline:WVNfX19zZW1jdGwgKCkgewkyMjA7fQp9CnVubGVz|2^20|1:4
+ FEC_ORDER=FEC_SRTP
+ a=crypto:2 F8_128_HMAC_SHA1_80
+ inline:MTIzNDU2Nzg5QUJDREUwMTIzNDU2Nzg5QUJjZGVm|2^20|1:4;
+ inline:QUJjZGVmMTIzNDU2Nzg5QUJDREUwMTIzNDU2Nzg5|2^20|2:4
+ FEC_ORDER=FEC_SRTP
+ */
+
+ TBuf8 < KMasterKeyAndSaltLength > masterKeyAndSalt;
+ Base64Decode( aData, masterKeyAndSalt );
+
+ //it should be validate already so it is our prefered key
+ iCryptoIn.iEncodedKey = aData;
+ iCryptoIn.iSetMasterKey = masterKeyAndSalt.Mid( 0, KMasterKeyLength );
+ iCryptoIn.iSetSaltKey = masterKeyAndSalt.Mid( KMasterKeyLength );
+ iCryptoIn.iKeysCreated = ETrue;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CMceSecureDesStream::DecodeSecureSdpL()
+// Decode Secure Sdp Offer / Update
+// -----------------------------------------------------------------------------
+//
+void CMceSecureDesStream::DecodeSecureSdpL( CSdpMediaField& aMediaField )
+ {
+ MCEMM_DEBUG("CMceSecureDesStream::DecodeSecureSdpL(), Entry")
+ MCEMM_DEBUG_DVALUE("iKeyNeedUpdated", iSecureSession.iKeyNeedUpdated )
+ iGnoreSdpMsg = EFalse;
+ CSdpAttributeField* attributeField = NULL;
+
+ RPointerArray< CSdpAttributeField > attrList =
+ aMediaField.AttributeFields();
+ TInt attrCount = attrList.Count();
+ TInt cryptoAttrCount =
+ iSecureSession.SdpCryptoAttributeCount( aMediaField );
+ iCryptoIns->Reset();
+ RemoveClientCrypto();
+
+ for (TInt j = 0; j < attrCount; j++ )
+ {
+ attributeField = attrList[ j ];
+
+ RStringF attribute = attributeField->Attribute();
+
+ // check if attribute is 'crypto'
+ if ( attribute.DesC().Match(KCrypto)!= KErrNotFound )
+ {
+ --cryptoAttrCount;
+ //check how many inline
+ ValidateOfferByAnswerL( attributeField->Value() );
+ if ( !cryptoAttrCount && iGnoreSdpMsg && !iCryptoIns->Count() )
+ {
+ //Last attribute ignored and no valid attributes found
+ User::Leave ( KErrArgument );
+ }
+ if ( !cryptoAttrCount )
+ {
+ break;
+ }
+ }
+ }
+ if ( iCryptoIns->Count() )
+ {
+ //acceptable crypto suite found, not to be ignored
+ iGnoreSdpMsg = EFalse;
+ }
+ if ( !iGnoreSdpMsg && SetMediaProfile ( aMediaField ) == KErrNone )
+ {
+ SetMultipleClientCryptoL( *iCryptoIns );
+ MCEMM_DEBUG(" Set Multiple Client Cryptoto")
+ User::LeaveIfError ( CountCryptoInOffer( aMediaField ) );
+ Session().iIsSecureSession = !iGnoreSdpMsg ? ETrue : EFalse;
+ }
+ MCEMM_DEBUG("CMceSecureDesStream::DecodeSecureSdpL(), Exit")
+ MSG_IGNORE_RETURN()
+ }
+
+// -----------------------------------------------------------------------------
+// CMceSecureDesStream::DecodeSecureSdpAnswerL()
+// Decode Secure Sdp Offer/Answer
+// -----------------------------------------------------------------------------
+//
+void CMceSecureDesStream::DecodeSecureSdpAnswerL( CSdpMediaField& aMediaField)
+ {
+ MCEMM_DEBUG("CMceSecureDesStream::DecodeSecureSdpAnswerL(), Entry")
+ MCEMM_DEBUG_DVALUE("iKeyNeedUpdated", iSecureSession.iKeyNeedUpdated)
+ TInt cryptoCount = iSecureSession.SdpCryptoAttributeCount(aMediaField);
+
+ if ( cryptoCount != KCryptoAnswerCount )
+ {
+ User::Leave( KErrArgument );
+ }
+
+ CSdpAttributeField* attr = MediaFieldAttrMatch( aMediaField, KCrypto);
+
+ // check if attribute is 'crypto'
+ if ( attr )
+ {
+ ValidateAnswerByOfferL( attr->Value() );
+
+ if ( !iGnoreSdpMsg && SetMediaProfile ( aMediaField ) == KErrNone )
+ {
+ if ( iSecureSession.iKeyNeedUpdated )
+ {
+ Session().iIsSecureSession = ETrue;
+
+ Session().iClientCryptoSuites.Reset();
+
+ SetClientCryptoL( iCryptoIn );
+ }
+ if ( iSecureSession.iLSReadyToBind )
+ {
+ SetCryptoContextL();
+ }
+ MSG_IGNORE_RETURN()
+ if ( !iCryptoIn.iCryptoSuite.Length() )
+ {
+ User::Leave( KErrArgument );
+ }
+ MCEMM_DEBUG("Set Crypto Context succeed")
+
+ }
+
+ else
+ {
+ MCEMM_DEBUG("No suitable crypto or malformate crypto session reject")
+
+ User::Leave( KErrArgument );
+ }
+ }
+ MCEMM_DEBUG("CMceSecureDesStream::DecodeSecureSdpAnswerL(), Exit")
+ MSG_IGNORE_RETURN()
+ }
+
+// -----------------------------------------------------------------------------
+// CMceSecureDesStream::RemvoeSecureSdpL
+// Remove Secure Sdp Offer/Answer
+// -----------------------------------------------------------------------------
+//
+void CMceSecureDesStream::RemvoeSecureSdp(CSdpMediaField& aMediaField)
+ {
+ MCEMM_DEBUG("CMceSecureDesStream::RemvoeSecureSdpL(), Entry")
+
+ RStringF mediaType = aMediaField.Media();
+
+ RPointerArray< CSdpAttributeField> attrList =
+ aMediaField.AttributeFields();
+
+ TInt attrCount = attrList.Count();
+
+ for (TInt index = attrCount; index >0 ; index-- )
+ {
+ CSdpAttributeField* attributeField = attrList[index-1];
+ RStringF attribute = attributeField->Attribute();
+ // check if attribute is 'crypto'
+ if ( KErrNotFound != attribute.DesC().Find( KCrypto ) )
+ {
+ TInt removing =aMediaField.AttributeFields().Find(attributeField);
+ aMediaField.AttributeFields().Remove(removing);
+ delete attributeField;
+ attributeField=NULL;
+ }
+ }
+ mediaType.Close();
+ MCEMM_DEBUG("CMceSecureDesStream::RemvoeSecureSdpL(), Exit")
+
+ }
+
+// -----------------------------------------------------------------------------
+// CMceSecureDesStream::SetCryptoContext( )
+// Sets crypto context to MCC
+// -----------------------------------------------------------------------------
+//
+void CMceSecureDesStream::SetCryptoContextL( )
+ {
+ MCEMM_DEBUG("SetCryptoContext(), Entry")
+ TBool storedIgnoreSdpMsg = EFalse;
+ //Check state first if the crypto has been set
+ if ( !iCryptoIn.iIfCryptoContextIdSet &&
+ !iCryptoOut.iIfCryptoContextIdSet &&
+ iCryptoIn.iSetMasterKey.Length() &&
+ iCryptoIn.iSetSaltKey.Length() &&
+ iCryptoOut.iSetMasterKey.Length() &&
+ iCryptoOut.iSetSaltKey.Length() )
+ {
+ MCEMM_DEBUG("First Time Bind")
+ CreateCryptoContextL( iCryptoIn );
+ CreateCryptoContextL( iCryptoOut );
+ MCEMM_DEBUG_DVALUE( "iCryptoContextOutId", iCryptoIn.iCryptoContextId )
+ MCEMM_DEBUG_DVALUE( "iCryptoContextInId", iCryptoOut.iCryptoContextId )
+
+ iCryptoOuts->Reset();
+
+
+ }
+ else if ( iCryptoIn.iSetMasterKey.Length() &&
+ iCryptoIn.iSetSaltKey.Length() &&
+ iCryptoOut.iSetMasterKey.Length() &&
+ iCryptoOut.iSetSaltKey.Length() )
+ {
+ MCEMM_DEBUG("Bind has done before so this is for updated")
+ if ( iCryptoContextInId != 0 && iCryptoContextOutId != 0 )
+ {
+ iCryptoIn.iCryptoContextId = iCryptoContextInId;
+ iCryptoOut.iCryptoContextId = iCryptoContextOutId;
+ }
+ MCEMM_DEBUG_DVALUE( "Updated iCryptoContextOutId", iCryptoIn.iCryptoContextId )
+ MCEMM_DEBUG_DVALUE( "Updated iCryptoContextInId", iCryptoOut.iCryptoContextId )
+ if ( iSecureSession.iKeyNeedUpdated )
+ {
+ UpdateCryptoContextL( iCryptoIn );
+ storedIgnoreSdpMsg = iGnoreSdpMsg;
+ UpdateCryptoContextL( iCryptoOut );
+ iGnoreSdpMsg = iGnoreSdpMsg && storedIgnoreSdpMsg;
+ }
+ else
+ {
+ iWaitingBinding = ETrue;
+ }
+ iCryptoOuts->Reset();
+ }
+ iGnoreSdpMsg = (iCryptoIn.iIfCryptoContextIdSet &&
+ iCryptoOut.iIfCryptoContextIdSet ) &&
+ !iGnoreSdpMsg ? EFalse : ETrue;
+ if ( iWaitingBinding )
+ {
+ iSecureSession.BindStreamCrypto();
+ }
+
+ MCEMM_DEBUG("SetCryptoContext(), Exit")
+ }
+
+
+// -----------------------------------------------------------------------------
+// CMceSecureDesStream::CreateCryptoContextL()
+//
+// -----------------------------------------------------------------------------
+//
+void CMceSecureDesStream::CreateCryptoContextL( TMceSecureCryptoInfo& aCrypto )
+ {
+ MCEMM_DEBUG("CMceSecureDesStream::CreateCryptoContextL Entry")
+ // if ESrtpNullAlg == iEncAlgms Fallback to RTP, set NULL policy
+ // Create phony master and salt from local values
+ // since remote keys not available
+ iWaitingBinding = EFalse;
+ TInt err(KErrNone);
+ FormMKIL(aCrypto);
+ TBuf8<KMKILength> mki;
+ mki.Copy( KNullDesC8 );
+ TMccSrtpMasterKey masterKey(aCrypto.iSetMasterKey, mki);
+
+ if (aCrypto.iMKIUsed && iMKIBuf)
+ {
+ masterKey.iMKI.Copy(iMKIBuf->Des());
+ masterKey.iMKI.SetLength(aCrypto.iMKILength);
+ }
+ TMccSrtpMasterSalt saltKey( aCrypto.iSetSaltKey);
+ TMccSrtpCryptoParams params;
+
+ params.iSrtpEncAlg = aCrypto.iEncAlgms;
+ params.iSrtcpEncAlg = aCrypto.iEncAlgms;
+ params.iSrtpAuthAlg = aCrypto.iAuthAlgms;
+ params.iSrtcpAuthAlg = aCrypto.iAuthAlgms;
+ params.iSrtpAuthTagLen = aCrypto.iTagLen;
+ params.iSrtcpAuthTagLen = aCrypto.iTagLen;
+ if ( aCrypto.iMKLifeTime )
+ {
+ params.iMasterKeysLifeTime = aCrypto.iMKLifeTime;
+ }
+
+
+ TMccSrtpMasterKeyPckg masterKeyPckg(masterKey);
+ const TDesC8& masterKeyDes = masterKeyPckg;
+
+ TMccSrtpMasterSaltPckg masterSaltPckg( saltKey );
+ const TDesC8& saltKeyDes = masterSaltPckg;
+
+ TMccSrtpCryptoParamsPckg cryptoParamsPckg ( params );
+ const TDesC8& cryptoParamsDes = cryptoParamsPckg;
+ //remember to handle and pass the keys
+ err = iSecInf.CreateContext(masterKeyDes, saltKeyDes,
+ aCrypto.iCryptoContextId, cryptoParamsDes );
+ if ( err == KErrNone )
+ {
+ MCEMM_DEBUG("Create Crypto Succeed")
+ aCrypto.iIfCryptoContextIdSet = ETrue;
+ iWaitingBinding = ETrue;
+ }
+
+ MCEMM_DEBUG_DVALUE( "createContext error", err )
+ MCEMM_DEBUG("CMceSecureDesStream::CreateCryptoContextL Exit")
+ }
+
+// -----------------------------------------------------------------------------
+// CMceSecureDesStream::UpdateCryptoContext()
+//
+// -----------------------------------------------------------------------------
+//
+void CMceSecureDesStream::UpdateCryptoContextL( TMceSecureCryptoInfo& aCrypto )
+ {
+ MCEMM_DEBUG("CMceSecureDesStream::UpdateCryptoContextL Entry")
+ TInt err(KErrNone);
+ iWaitingBinding = EFalse;
+
+ aCrypto.iIfBinded = EFalse;
+ FormMKIL(aCrypto);
+ TBuf8<KMKILength> mki;
+ mki.Copy( KNullDesC8 );
+ TMccSrtpMasterKey masterKey( aCrypto.iSetMasterKey, mki );
+
+ if ( aCrypto.iMKIUsed && iMKIBuf )
+ {
+ masterKey.iMKI.Copy(iMKIBuf->Des());
+ }
+ TMccSrtpMasterSalt saltKey( aCrypto.iSetSaltKey);
+ TMccSrtpCryptoParams params;
+
+ params.iSrtpEncAlg = aCrypto.iEncAlgms;
+ params.iSrtcpEncAlg = aCrypto.iEncAlgms;
+ params.iSrtpAuthAlg = aCrypto.iAuthAlgms;
+ params.iSrtcpAuthAlg = aCrypto.iAuthAlgms;
+ params.iSrtpAuthTagLen = aCrypto.iTagLen;
+ params.iSrtcpAuthTagLen = aCrypto.iTagLen;
+ if ( aCrypto.iMKLifeTime )
+ {
+ params.iMasterKeysLifeTime = aCrypto.iMKLifeTime;
+ }
+
+
+ TMccSrtpMasterKeyPckg masterKeyPckg(masterKey);
+ const TDesC8& masterKeyDes = masterKeyPckg;
+
+ TMccSrtpMasterSaltPckg masterSaltPckg( saltKey );
+ const TDesC8& saltKeyDes = masterSaltPckg;
+
+ TMccSrtpCryptoParamsPckg cryptoParamsPckg ( params );
+ const TDesC8& cryptoParamsDes = cryptoParamsPckg;
+
+ err = iSecInf.UpdateContext( masterKeyDes, saltKeyDes,
+ aCrypto.iCryptoContextId, cryptoParamsDes );
+
+ if ( err==KErrNone)
+ {
+ MCEMM_DEBUG("Updated Crypto Succeed")
+ aCrypto.iIfCryptoContextIdSet = ETrue;
+ iWaitingBinding = ETrue;
+ }
+ //This is to check if the crypto Id after update can be found
+ // if not found, context Id maybe wrong
+ iGnoreSdpMsg = err == KErrNotFound ? ETrue : EFalse;
+ MCEMM_DEBUG_DVALUE( "UpdateContext error", err )
+ MCEMM_DEBUG("CMceSecureDesStream::UpdateCryptoContextL Exit")
+ }
+
+// -----------------------------------------------------------------------------
+// CMceSecureDesStream::FormMKIL()
+//
+// -----------------------------------------------------------------------------
+//
+void CMceSecureDesStream::FormMKIL( TMceSecureCryptoInfo& aCrypto )
+ {
+ delete iMKIBuf;
+ iMKIBuf=NULL;
+ if ( aCrypto.iMKILength > 0 &&
+ aCrypto.iMKILength%4 == 0 &&
+ aCrypto.iMKIUsed )
+ {
+ __ASSERT_ALWAYS( aCrypto.iMKILength <= KMKIMaxLength,
+ User::Leave( KErrOverflow ) );
+
+ iMKIBuf = HBufC8::NewL( aCrypto.iMKILength );
+ TUint8* mkiData = const_cast<TUint8*>( iMKIBuf->Des().Ptr() );
+ Mem::FillZ( mkiData, aCrypto.iMKILength );
+ if (aCrypto.iMKILength > KMKILength)
+ {
+ mkiData+= ( aCrypto.iMKILength - KMKILength );
+ }
+ TUint32 mkiValue=aCrypto.iMKIValue;
+ BigEndian::Put32(mkiData, mkiValue);
+ mkiData += KMKILength;
+ iMKIBuf->Des().SetLength( aCrypto.iMKILength );
+ }
+
+ }
+// -----------------------------------------------------------------------------
+// CMceSecureDesStream::BindCrypto( )
+// -----------------------------------------------------------------------------
+//
+
+TInt CMceSecureDesStream::BindCrypto( CMceSrvStream& aStream )
+
+ {
+ MCEMM_DEBUG("CMceSecureDesStream::BindCrypto(), Entry")
+
+ MCEMM_DEBUG_DVALUE(" BindStreamId", aStream.Id() )
+ MCEMM_DEBUG_DVALUE(" BindLinkId", aStream.LinkId() )
+ MCEMM_DEBUG_DVALUE(" iCryptoIn.iIfBinded", iCryptoIn.iIfBinded )
+ MCEMM_DEBUG_DVALUE(" iCryptoOut.iIfBinded", iCryptoOut.iIfBinded )
+
+ TInt err(KErrNotFound);
+ if (iCryptoIn.iEncodedKey.Length() &&
+ iCryptoIn.iIfCryptoContextIdSet &&
+ IS_RECEIVESTREAM(&aStream.Data()) )
+ {
+ MCEMM_DEBUG_DVALUE(" BindContext In Id", iCryptoIn.iCryptoContextId )
+ MCEMM_DEBUG_DVALUE(" BindSourceId", aStream.Source().Id() )
+
+ err = iSecInf.Bind( aStream.SessionId(),
+ aStream.LinkId(),
+ aStream.Id(),
+ aStream.Source().Id(),
+ iCryptoIn.iCryptoContextId );
+
+ MCEMM_DEBUG_DVALUE(" BindSource result=", err)
+
+ if ( err == KErrNone )
+ {
+ iCryptoIn.iIfBinded = ETrue;
+ MCEMM_DEBUG("Bind Downlink Source Successful")
+ }
+
+ }
+
+
+ if (iCryptoOut.iEncodedKey.Length() &&
+ iCryptoOut.iIfCryptoContextIdSet &&
+ IS_SENDSTREAM(&aStream.Data()) )
+ {
+
+ MCEMM_DEBUG_DVALUE(" BindContext Out Id", iCryptoOut.iCryptoContextId )
+ MCEMM_DEBUG_DVALUE(" BindSinkId", aStream.Sink().Id() )
+
+ err =iSecInf.Bind( aStream.SessionId(),
+ aStream.LinkId(),
+ aStream.Id(),
+ aStream.Sink().Id(),
+ iCryptoOut.iCryptoContextId );
+
+ MCEMM_DEBUG_DVALUE(" BindSink result=", err)
+
+ if (err == KErrNone)
+ {
+ iCryptoOut.iIfBinded=ETrue;
+ MCEMM_DEBUG(" Bind Uplink Sink Successful")
+ }
+
+ }
+
+ if (iCryptoIn.iIfBinded && iCryptoOut.iIfBinded)
+ {
+ MCEMM_DEBUG(" Bind Successful for Downlink and Uplink")
+ iWaitingBinding=EFalse;
+ }
+ err = iWaitingBinding? KErrNotFound : KErrNone;
+
+ MCEMM_DEBUG("CMceSecureDesStream::BindCrypto(), Exit")
+
+ return err;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CMceSecureDesStream::Base64Encode
+// Base64 encoding.
+// -----------------------------------------------------------------------------
+//
+void CMceSecureDesStream::Base64Encode( const TDesC8& aData, TDes8& aEncoded )
+ {
+ TBase64 encode;
+ encode.Encode( aData, aEncoded );
+ }
+
+// -----------------------------------------------------------------------------
+// CMceSecureDesStream::Base64Decode
+// Base64 decode.
+// -----------------------------------------------------------------------------
+//
+void CMceSecureDesStream::Base64Decode( const TDesC8& aData, TDes8& aDecoded )
+ {
+ TBase64 decode;
+ decode.Decode( aData, aDecoded );
+ }
+
+// -----------------------------------------------------------------------------
+// CMceSecureDesStream::ValidateSecurityDescriptions
+// Check if security description is valid
+// -----------------------------------------------------------------------------
+//
+TBool CMceSecureDesStream::ValidateSecurityDescriptions( TDesC8& aData )
+ {
+ TBool valid( ETrue );
+
+ TBuf8< KCryptoLineMaxLength > masterKeyAndSalt;
+ Base64Decode( aData, masterKeyAndSalt );
+ TInt countChar=0;
+ // Check that encoded string is right sized
+ // Validate length of master key and salt
+ if ( KEncodedStringLength != aData.Length() ||
+ KMasterKeyAndSaltLength != masterKeyAndSalt.Length() )
+ {
+ return !valid ;
+ }
+
+ // Validate Base64 Encoding characters
+ TBool charFound( EFalse );
+ for ( TInt i = 0; i < aData.Length(); i++ )
+ {
+
+ for (TInt j = 0; j < KRandomStringCount; j++ )
+ {
+ if ( aData[i] == KBase64Chars[j] )
+ {
+ charFound = ETrue;
+ countChar++;
+ }
+ }
+
+ if ( !charFound )
+ {
+ // invalid character has been found
+ valid = EFalse;
+ }
+
+ charFound = EFalse;
+ }
+ if (countChar!=aData.Length())
+ {
+ valid=EFalse;
+ }
+ return valid;
+ }
+
+// -----------------------------------------------------------------------------
+// CMceSecureDesStream::RandomString
+// Generates random string
+// -----------------------------------------------------------------------------
+//
+void CMceSecureDesStream::RandomString( TDes8& aRandom )
+ {
+ TTime time;
+ time.UniversalTime();
+ TInt64 seed = time.Int64();
+ TUint32 random= Math::Random();
+ seed += random;
+ TInt randomNumber(0);
+
+ for( TInt i = 0; i < aRandom.MaxSize(); i++ )
+ {
+ randomNumber = Math::Rand( seed ) % KRandomStringCount;
+ aRandom.Append( KRandomChars[ randomNumber ] );
+ }
+
+ }
+
+// -----------------------------------------------------------------------------
+// CMceSecureDesStream::GenerateCryptoLineL()
+// Cryptoline creation
+// -----------------------------------------------------------------------------
+//
+void CMceSecureDesStream::GenerateCryptoLineL(
+ TDes8& aResult,
+ TInt aCryptoCount,
+ TBool aAnswer )
+ {
+ MCEMM_DEBUG("CMceSecureDesStream::GenerateCryptoLineL Entry")
+ SetClientCryptoL( aCryptoCount );
+ if ( aAnswer )
+ {
+ //Compare with crypto In and create cryptoOut
+ MCEMM_DEBUG("GenerateCryptoLineL for Answer")
+ if ( iSecureSession.iKeyNeedUpdated )
+ {
+ User::LeaveIfError ( CompareCryptosForAnswer() );
+ GenerateRandomKeys( iCryptoOut );
+ MCEMM_DEBUG("GenerateRandomKeys Key is updated")
+ iOldLocalMediaPort = iMediaStream.iLocalMediaPort;
+ }
+ else
+ {
+ if(iOldLocalMediaPort != iMediaStream.iLocalMediaPort)
+ {
+ GenerateRandomKeys( iCryptoOut );
+ MCEMM_DEBUG("GenerateRandomKeys Key is updated when oldport is different from newport")
+ iOldLocalMediaPort = iMediaStream.iLocalMediaPort;
+ }
+ }
+ aResult.AppendNum( iCryptoOut.iTag );
+ aResult.Append( KSpace );
+ GenerateCryptoSuiteLineL( aResult, iCryptoOut );
+ MSG_IGNORE_RETURN()
+ if ( iSecureSession.iLSReadyToBind )
+ {
+ SetCryptoContextL();
+ }
+ MSG_IGNORE_RETURN()
+ }
+ else
+ {
+ MCEMM_DEBUG("GenerateCryptoLineL for Offer")
+
+ if ( iSecureSession.iKeyNeedUpdated )
+ {
+ iGnoreSdpMsg = !iCryptoOuts->Count() ? ETrue : EFalse;
+ iGnoreSdpMsg = aCryptoCount - 1 >= iCryptoOuts->Count() ? ETrue : EFalse;
+ MSG_IGNORE_RETURN()
+ TMceSecureCryptoInfo crypto = iCryptoOuts->At( aCryptoCount-1 );
+ GenerateRandomKeys( crypto );
+ crypto.iTag = aCryptoCount;
+ aResult.AppendNum( aCryptoCount );
+ aResult.Append( KSpace );
+ GenerateCryptoSuiteLineL( aResult, crypto );
+ MSG_IGNORE_RETURN()
+ iCryptoOuts->At( aCryptoCount-1 ).Copy( crypto );
+ iOldLocalMediaPort = iMediaStream.iLocalMediaPort;
+ }
+ else
+ {
+ aResult.AppendNum( iCryptoOut.iTag );
+ aResult.Append( KSpace );
+ GenerateCryptoSuiteLineL( aResult, iCryptoOut );
+ }
+
+ }
+ MCEMM_DEBUG("CMceSecureDesStream::GenerateCryptoLineL Exit")
+ MSG_IGNORE_RETURN()
+ }
+
+// -----------------------------------------------------------------------------
+// CMceSecureDesStream::GenerateCryptoSuiteLine
+// Cryptoline creation
+// -----------------------------------------------------------------------------
+//
+void CMceSecureDesStream::GenerateCryptoSuiteLineL( TDes8& aResult,
+ TMceSecureCryptoInfo& aCrypto )
+ {
+ switch ( aCrypto.iEncAlgms )
+ {
+ case ESrtpEncAES_CM:
+ {
+ if ( aCrypto.iTagLen == KAuthTagLength32 )
+ {
+ aResult.Append( KAES_SHA1_32 );
+ }
+ else
+ {
+ aResult.Append( KAES_SHA1_80 );
+ }
+ break;
+ }
+ default:
+ {
+ iGnoreSdpMsg = ETrue;
+ break;
+ }
+ }
+
+ MSG_IGNORE_RETURN()
+ aResult.Append( KSpace );
+ aResult.Append( KInline );
+ if (aCrypto.iEncodedKey.Length() > 0)
+ {
+ aResult.Append( aCrypto.iEncodedKey );
+ // Append MKI and lifetime if needed, MKI as default
+ if ( aCrypto.iMKIUsed && aCrypto.iMKI.Length() > 0 )
+ {
+ aResult.Append( KSeparator );
+ aResult.Append( aCrypto.iMKI );
+ }
+ //set default masterkeyLT
+ aCrypto.iMKLifeTime = KDefalutMaterKeysLifeTime;
+ }
+ else
+ {
+ User::Leave( KErrArgument );
+ }
+ }
+
+
+// -----------------------------------------------------------------------------
+// CMceSecureDesStream::MediaField()
+// Return this MediaField
+// -----------------------------------------------------------------------------
+//
+CSdpMediaField& CMceSecureDesStream::MediaField()
+ {
+ return *iMediaField;
+ }
+
+// -----------------------------------------------------------------------------
+// CMceSecureDesStream::Codec()
+// Return this related codec
+// -----------------------------------------------------------------------------
+//
+CMceComMediaStream& CMceSecureDesStream::MediaStream() const
+ {
+ return iMediaStream;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CMceSecureDesStream::CompareContextId
+// Return TBool
+// -----------------------------------------------------------------------------
+//
+TBool CMceSecureDesStream::CompareContextId( TUint32 aContextId )
+ {
+ TBool equal = EFalse;
+ if (aContextId == iCryptoIn.iCryptoContextId ||
+ aContextId == iCryptoOut.iCryptoContextId)
+ {
+ equal = ETrue;
+ }
+ return equal;
+ }
+
+// -----------------------------------------------------------------------------
+// CMceSecureDesStream::DecodeMKLifeTime
+//
+// -----------------------------------------------------------------------------
+//
+void CMceSecureDesStream::DecodeMKLifeTimeL(const TDesC8& aSecDec,
+ TMceSecureCryptoInfo& aCrypto )
+ {
+ /*
+ RFC 4568 6.1
+ */
+ // aSecDec is CSdpAttributeField value
+ //By Type we know it is offer or answer so we know crypto In/Out should be
+ // assign
+ //Note that no matter how many inline the MKI will be same in the one cryptosute
+ _LIT8( KMatchMKLTPowerTwo,"*|*^*|*:*" );
+ _LIT8( KMatchMKLTDigit,"*|*|*:*" );
+ _LIT8 ( KMatchMKLT, "*|2^*");
+ _LIT8 ( KOnlyMKI, "*|*:*");
+
+ TChar separator = '|';
+ const TUint8 KMatchMKLToffset = 3;
+ const TReal mkiPowerBase = 2;
+ TBool found=EFalse;
+ TInt totalLen = aSecDec.Length();
+ TUint32 unitMKLT = 0;
+ TPtrC8 mkLT( NULL,0 );
+ TPtrC8 sec( NULL,0 );
+ TReal powerResult = 0;
+ TInt posSemi= aSecDec.Find( KSemiColon );
+ sec.Set( aSecDec.Ptr(), aSecDec.Length() );
+ if ( posSemi != KErrNotFound )
+ {
+ sec.Set(aSecDec.Left(posSemi).Ptr(), posSemi);
+ }
+ //sec is now only before semicolon
+ // make sure if there is MKLT
+ if ( sec.Match ( KMatchMKLTPowerTwo ) != KErrNotFound )
+ {
+
+ TInt firstSep = SearchChar( sec, separator, 0 );
+ TInt sndSep = SearchChar( sec, separator, firstSep );
+ mkLT.Set( sec.Mid( firstSep + 1, sndSep - firstSep -1 ) );
+ TInt posInvol = mkLT.Find( KInvolute );
+ TLex8 lexMKL( mkLT.Mid( posInvol+1 ) );
+ User::LeaveIfError( lexMKL.Val(unitMKLT, EDecimal ));
+ Math::Pow( powerResult, mkiPowerBase, (TReal)unitMKLT );
+ unitMKLT = (TUint32)powerResult;
+
+ found = ETrue;
+ }
+ else if (sec.Match ( KMatchMKLTDigit ) != KErrNotFound )
+ {
+ found= ETrue;
+ //only Decimal case
+ TInt first = sec.Find( KSeparator );
+ TInt second = sec.LocateReverse( separator );
+ mkLT.Set( aSecDec.Mid( first+1, second - first - 1 ));
+ TLex8 lexMKL(mkLT);
+
+ User::LeaveIfError( lexMKL.Val(unitMKLT, EDecimal ));
+ }
+ else if( sec.Match( KMatchMKLT ) != KErrNotFound )
+ {
+ found = ETrue;
+ //onlyMKLT with power 2 no MasterKeyIdentifier
+ TInt posSeparator = sec.Match( KMatchMKLT );
+ TInt remainLen = sec.Length() - ( posSeparator + KMatchMKLToffset );
+ //only number after power
+ mkLT.Set( sec.Mid( posSeparator + KMatchMKLToffset, remainLen ) );
+
+ TLex8 lexMKL( mkLT );
+
+ User::LeaveIfError( lexMKL.Val(unitMKLT, EDecimal ));
+ Math::Pow( powerResult, mkiPowerBase, (TReal)unitMKLT );
+ mkLT.Set( sec.Mid( posSeparator + 1 ));// ex 2^32
+
+ unitMKLT = (TUint32)powerResult;
+ }
+ else if ( sec.Match(KOnlyMKI) == KErrNotFound && totalLen > 0
+ && sec.Find(KSeparator) != KErrNotFound )
+ {
+ found= ETrue;
+ //only Decimal case
+ TInt posfirst = sec.Find( KSeparator );
+ TInt mkltpos = posfirst +1;
+ TInt remainLen = totalLen - ( mkltpos );
+ mkLT.Set( aSecDec.Mid( mkltpos, remainLen ));
+ TLex8 lexMKL(mkLT);
+ User::LeaveIfError( lexMKL.Val(unitMKLT, EDecimal ));
+ }
+
+ if (found )
+ {
+ //It is decode so only for cryptoIn
+ aCrypto.iMKLifeTime = unitMKLT;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CMceSecureDesStream::DecodeMKIValue
+//
+// -----------------------------------------------------------------------------
+//
+void CMceSecureDesStream::DecodeMKIValueL( const TDesC8& aSecDec,
+ TBool aIsAnswer,
+ TMceSecureCryptoInfo& aCrypto )
+ {
+ /*RFC 4568 6.1
+ */
+ // aSecDec is CSdpAttributeField value
+ const TInt KMKIMaxLen = 3;
+ const TInt KMKIColonLen = 1;
+ const TInt KMKIMaxBytes = 128;
+ _LIT8 (KOnlyMKI, "*|*:*");
+
+ TPtrC8 sec(NULL,0);
+ TChar separator='|';
+ TChar colon=':';
+ TChar space = ' ';
+ TInt mkifound = aSecDec.Match( KOnlyMKI );
+ TInt posSemi= aSecDec.Find( KSemiColon );
+ sec.Set( aSecDec.Ptr(),aSecDec.Length() );
+ if ( posSemi != KErrNotFound )
+ {
+ //with secon inline
+ sec.Set( aSecDec.Left(posSemi).Ptr(), posSemi );
+ }
+
+ if ( aIsAnswer )
+ {
+ //compare with cryptoOut
+ if ( !iCryptoOut.iMKIUsed && mkifound != KErrNotFound )
+ {
+ //should not have MKI field , reject this
+ User::Leave ( KErrArgument );
+ }
+ }
+ if ( mkifound != KErrNotFound )
+ {
+ //there is MKI
+ /*If the MKI length is not given or
+ its value exceeds 128 (bytes), then the entire crypto attribute MUST
+ be considered invalid.*/
+ TInt separator2ndPos = sec.LocateReverse( separator );
+ TInt mkiPos = separator2ndPos+1;
+ TInt colonPos = sec.LocateReverse( colon );
+ TInt mKIoffset = colonPos - mkiPos;
+ //mki value
+ if ( mKIoffset < 0 )
+ {
+ //malformate MKI
+ User::Leave( KErrArgument );
+ }
+
+ TPtrC8 mkiValue = sec.Mid(mkiPos, mKIoffset);
+ TLex8 lexMKI(mkiValue);
+ User::LeaveIfError(lexMKI.Val(aCrypto.iMKIValue, EDecimal) );
+
+ //mki length
+ TInt mkilenPos = colonPos+1;
+ TInt mkilenOffset = sec.Length() - mkilenPos;
+ if ( mkilenOffset> KMKIMaxLen )
+ {
+ //there is extra session parameter behind
+ //looking for white space
+ TInt spacePos = sec.LocateReverse( space );
+ mkilenOffset = spacePos-mkilenPos;
+ }
+ TPtrC8 mkilen = sec.Mid( mkilenPos, mkilenOffset );
+ TLex8 lexMkiLen(mkilen);
+ User::LeaveIfError(lexMkiLen.Val(aCrypto.iMKILength, EDecimal, KMKIMaxBytes));
+ __ASSERT_ALWAYS( aCrypto.iMKILength <= KMKIMaxLength,
+ User::Leave( KErrOverflow ) );
+
+ //get whole MKI ( value + length)-> This is for adding SDP only
+ TInt total = mKIoffset + mkilenOffset + KMKIColonLen;
+ aCrypto.iMKI = sec.Mid( mkiPos, total ) ;
+ aCrypto.iMKIUsed = ETrue;
+ }
+
+ return;
+ }
+
+// -----------------------------------------------------------------------------
+// CMceSecureDesStream::ValidateAnswerByOffer
+// Validate and Set cryptoIn information
+// -----------------------------------------------------------------------------
+//
+void CMceSecureDesStream::ValidateAnswerByOfferL(const TDesC8& aSecDec )
+ {
+ /*
+ Vaidata the incoming answer by the original offer
+ 7.1.3. Processing of the Initial Answer - Unicast Streams
+ */
+ //remember to check how many inlinle later
+ MCEMM_DEBUG("CMceSecureDesStream::ValidateAnswerByOfferL, Entry")
+ if (aSecDec.Length() < KCryptoAttributeValueMinLength)
+ {
+ User::Leave( KErrArgument );
+ }
+ // Check SRTP crypto-suites
+ if ( iSecureSession.iKeyNeedUpdated )
+ {
+ IfMatchLocalCryptoL(aSecDec);
+ }
+ MSG_IGNORE_RETURN()
+ //check key param
+
+ TInt foundInline = aSecDec.Find( KInline );
+ TInt foundSeparator = aSecDec.Find( KSeparator);
+ TInt foundColon = aSecDec.Find(KColon);
+ if ( KErrNotFound != foundInline)
+ {
+ //check key info
+ TInt keyInfoPos = foundColon+1;
+ TInt keyInfoLen = 0;
+ if (foundSeparator != KErrNotFound)
+ {
+ keyInfoLen = foundSeparator-keyInfoPos;
+ }
+ else
+ {
+ keyInfoLen = aSecDec.Length()-keyInfoPos;
+ }
+
+ TPtrC8 keyInfo = aSecDec.Mid(keyInfoPos, keyInfoLen);
+ if ( iSecureSession.iKeyNeedUpdated )
+ {
+
+ TBool valid = ValidateSecurityDescriptions( keyInfo );
+ if ( valid )
+ {
+
+ // check keyInfo
+ if (iCryptoOut.iEncodedKey.Compare( keyInfo ) == 0)
+ {
+ User::Leave( KErrArgument );
+ }
+ //check keyinfo mki
+ DecodeMKIValueL(aSecDec, ETrue, iCryptoIn );
+ MSG_IGNORE_RETURN()
+ DecodeMKLifeTimeL( aSecDec, iCryptoIn );
+ //check sessionparam later
+ iCryptoIn.iEncodedKey = keyInfo;
+ StoreKeys(iCryptoIn.iEncodedKey);
+ }
+ else
+ {
+ User::Leave( KErrArgument );
+ }
+ }
+ }
+ else
+ {
+ User::Leave( KErrArgument );
+ }
+ MCEMM_DEBUG("CMceSecureDesStream::ValidateAnswerByOfferL, Exit")
+ }
+
+// -----------------------------------------------------------------------------
+// CMceSecureDesStream::ValidateOfferByAnswer
+// aSecDec is one attribute
+// -----------------------------------------------------------------------------
+//
+void CMceSecureDesStream::ValidateOfferByAnswerL( const TDesC8& aSecDec )
+ {
+ /*
+ RFC 4568 SDP Security Descriptions
+ 7.1.2. Generating the Initial Answer - Unicast Streams
+ */
+ //check client abilities and same time set the Answer crypto but not keys
+ MCEMM_DEBUG("CMceSecureDesStream::ValidateOfferByAnswerL, Entry")
+
+ if ( aSecDec.Length() < KCryptoAttributeValueMinLength )
+ {
+ User::Leave ( KErrArgument);
+ }
+ SetPreferedCryptoL();
+ TMceSecureCryptoInfo crypto;
+ StoreCryptoInFromOfferL(aSecDec, crypto);
+ MSG_IGNORE_RETURN()
+ //SetClientCryptoL(crypto);
+ //check key param
+
+ TInt foundInline = aSecDec.Find( KInline );
+ TInt foundSeparator = aSecDec.Find( KSeparator);
+ TInt foundColon = aSecDec.Find(KColon);
+ if ( KErrNotFound != foundInline)
+ {
+ //check key info
+ TInt keyInfoPos=foundColon+1;
+ TInt keyInfoLen=0;
+ if (foundSeparator!= KErrNotFound)
+ {
+ keyInfoLen= foundSeparator-keyInfoPos;
+ }
+ else
+ {
+ keyInfoLen = aSecDec.Length()-keyInfoPos;
+ }
+ TPtrC8 keyInfo = aSecDec.Mid(keyInfoPos, keyInfoLen);
+ TBool valid = ValidateSecurityDescriptions( keyInfo );
+
+ if ( valid )
+ {
+
+ //check keyinfo mki
+ DecodeMKIValueL( aSecDec, EFalse, crypto );
+ MSG_IGNORE_RETURN()
+ //set MKI value for our local crypto because all MKI in one crypto suite
+ // should be the same
+
+ DecodeMKLifeTimeL( aSecDec, crypto );
+ //StorKey
+ crypto.iEncodedKey = keyInfo;
+ TBuf8 < KMasterKeyAndSaltLength > masterKeyAndSalt;
+ Base64Decode( crypto.iEncodedKey, masterKeyAndSalt );
+
+ //it should be validate already so it is our prefered key
+
+ crypto.iSetMasterKey = masterKeyAndSalt.Mid( 0, KMasterKeyLength );
+ crypto.iSetSaltKey = masterKeyAndSalt.Mid( KMasterKeyLength );
+ crypto.iKeysCreated = ETrue;
+ iCryptoIns->AppendL( crypto );
+ //check sessionparam later
+
+ }
+ else
+ {
+ User::Leave( KErrArgument);
+ }
+ }
+ else
+ {
+ User::Leave( KErrArgument);
+ }
+
+ MCEMM_DEBUG("CMceSecureDesStream::ValidateOfferByAnswerL, Exit")
+ }
+
+// -----------------------------------------------------------------------------
+// CMceSecureDesStream::SetSecureProtocol()
+//
+// -----------------------------------------------------------------------------
+//
+void CMceSecureDesStream::SetSecureProtocolL(CSdpMediaField& aMediaField)
+ {
+ MCEMM_DEBUG("CMceSecureDesStream::SetSecureProtocol(), Entry")
+ TPtrC8 protocolName( KProtocolSAVP );
+
+ if ( Session().Modifier( KMceSecureSession ) == KMceSecurePlainAVP )
+ {
+ protocolName.Set ( KProtocolAVP );
+ }
+ if ( !iIsSAVP )
+ {
+ protocolName.Set( KProtocolSAVPF );
+ Session().Modifier( KMceSecureSession ) = KMceSecureNormal;
+ }
+
+ RStringF protocol = SdpCodecStringPool::StringPoolL().OpenFStringL( protocolName);
+ CleanupClosePushL( protocol );
+
+ aMediaField.SetProtocolL( protocol );
+ CleanupStack::PopAndDestroy( &protocol );
+
+ MCEMM_DEBUG("CMceSecureDesStream::SetSecureProtocol(), Exit")
+ }
+
+
+//-----------------------------------------------------------------------------
+// CMceSecureDesStream::SetPreferedCrypto()
+//
+// -----------------------------------------------------------------------------
+//
+void CMceSecureDesStream::SetPreferedCryptoL()
+ {
+ MCEMM_DEBUG( "CMceSecureDesStream::SetPreferedCryptoL, entry" )
+ RArray <TMceCryptoContext> clientCryptoSuite =
+ Session().iClientCryptoSuites;
+ TInt clientCryptoCount = clientCryptoSuite.Count();
+ if ( !iCryptoOuts->Count() )
+ {
+ AppendEmptyCryptoL( *iCryptoOuts, KTotalCryptoAnswerCount );
+ }
+ if (!clientCryptoCount )
+ {
+ MCEMM_DEBUG( "Client has no preference on crypto" )
+ iCryptoOuts->Reset();
+ // tag 80 prefered
+ SetDefaultCryptoL( *iCryptoOuts );
+ }
+ else
+ {
+ iCryptoOuts->Reset();
+ SetCryptoByClientL( *iCryptoOuts );
+ }
+ MCEMM_DEBUG( "CMceSecureDesStream::SetPreferedCryptoL, exit" )
+ }
+
+//-----------------------------------------------------------------------------
+// CMceSecureDesStream::SetClientCrypto()
+//
+// -----------------------------------------------------------------------------
+//
+void CMceSecureDesStream::SetClientCryptoL( TInt aCryptoCount )
+ {
+ MCEMM_DEBUG( "CMceSecureDesStream::SetClientCryptoL, entry" )
+ RArray< TMceCryptoContext > clientCryptoSuite =
+ Session().iClientCryptoSuites;
+ TInt clientCryptoSuiteCount = clientCryptoSuite.Count();
+
+ if ( iCryptoOuts->Count() == 0 )
+ {
+ AppendEmptyCryptoL( *iCryptoOuts, KTotalCryptoAnswerCount );
+ }
+
+ if ( clientCryptoSuiteCount > 0 )
+ {
+ for ( TInt index = 0; index < clientCryptoSuiteCount; index++ )
+ {
+ if ( aCryptoCount-1 == index )
+ {
+ MCEMM_DEBUG_DVALUE(" index = ", index )
+ MCEMM_DEBUG_DVALUE(" iCryptoOuts->Count() ", iCryptoOuts->Count() )
+ iGnoreSdpMsg = index >= iCryptoOuts->Count() ? ETrue : EFalse;
+ MSG_IGNORE_RETURN()
+ TMceSecureCryptoInfo cryptoOut = iCryptoOuts->At( index );
+
+ if ( clientCryptoSuite[index]== EAES_CM_128_HMAC_SHA1_80 )
+ {
+ SetSHA180( cryptoOut, aCryptoCount );
+ }
+ if ( clientCryptoSuite[ index ] == EAES_CM_128_HMAC_SHA1_32 )
+ {
+ //iCrytoOuts has been created in GenerateKey
+ SetSHA132( cryptoOut, aCryptoCount );
+ }
+ iCryptoOuts->At( index ).Copy( cryptoOut );
+ }
+ }
+ }
+ MCEMM_DEBUG( "CMceSecureDesStream::SetClientCryptoL, exit" )
+ }
+
+
+//-----------------------------------------------------------------------------
+// CMceSecureDesStream::ClientCrytoCount()
+//
+// -----------------------------------------------------------------------------
+//
+TInt CMceSecureDesStream::ClientCrytoCount()
+ {
+ TInt count = Session().iClientCryptoSuites.Count();
+ return count;
+ }
+
+
+//-----------------------------------------------------------------------------
+// CMceSecureDesStream::IfMatchLocalCryptoL()
+//
+// -----------------------------------------------------------------------------
+//
+void CMceSecureDesStream::IfMatchLocalCryptoL( const TDesC8& aSecDec )
+ {
+ MCEMM_DEBUG( "CMceSecureDesStream::IfMatchLocalCryptoL, entry" )
+ TMceSecureCryptoInfo crypto;
+ TInt foundAes80 = aSecDec.Find( KAES_SHA1_80 );
+ TInt foundAes32 = aSecDec.Find( KAES_SHA1_32 );
+ if (foundAes80 != KErrNotFound )
+ {
+ TPtrC8 tagValue = aSecDec.Mid( foundAes80-2, 1);
+ TLex8 lexTag(tagValue);
+ TUint tag=0;
+ User::LeaveIfError( lexTag.Val( tag, EDecimal));
+ SetSHA180( crypto, tag );
+ }
+ else if (foundAes32!= KErrNotFound )
+ {
+ TPtrC8 tagValue = aSecDec.Mid( foundAes32-2, 1 );
+ TLex8 lexTag( tagValue );
+ TUint tag = 0;
+ User::LeaveIfError( lexTag.Val( tag, EDecimal ));
+ SetSHA132( crypto, tag );
+ }
+ TInt find = SearchAndSetCrypto( crypto );
+ iGnoreSdpMsg = find == KErrNone ? EFalse : ETrue;
+ MCEMM_DEBUG( "CMceSecureDesStream::IfMatchLocalCryptoL, exit" )
+ return ;
+ }
+
+//-----------------------------------------------------------------------------
+// CMceSecureDesStream::SearchAndSetCrypto()
+//
+// -----------------------------------------------------------------------------
+//
+TInt CMceSecureDesStream::SearchAndSetCrypto(TMceSecureCryptoInfo& aCrypto)
+ {
+ MCEMM_DEBUG( "CMceSecureDesStream::SearchAndSetCrypto, entry" )
+ for ( TInt i=0; i < iCryptoOuts->Count(); i++ )
+ {
+ MCEMM_DEBUG_DVALUE(" iCryptoOuts->Count() ", iCryptoOuts->Count() )
+
+ TMceSecureCryptoInfo cryptoOut = iCryptoOuts->At( i );
+ if ( cryptoOut.iTagLen == aCrypto.iTagLen &&
+ cryptoOut.iEncAlgms == aCrypto.iEncAlgms &&
+ cryptoOut.iAuthAlgms == aCrypto.iAuthAlgms &&
+ cryptoOut.iCryptoSuite.Compare(aCrypto.iCryptoSuite) == 0)
+ {
+ //SEtCrypto
+ iCryptoOut.Copy( cryptoOut );
+ iCryptoIn.iTag = cryptoOut.iTag;
+ iCryptoIn.iEncAlgms = cryptoOut.iEncAlgms;
+ iCryptoIn.iAuthAlgms = cryptoOut.iAuthAlgms;
+ iCryptoIn.iTagLen = cryptoOut.iTagLen;
+ iCryptoIn.iCryptoSuite = cryptoOut.iCryptoSuite ;
+ return KErrNone;
+ }
+ }
+ MCEMM_DEBUG( "SearchAndSetCrypto NotFound" )
+ MCEMM_DEBUG( "CMceSecureDesStream::SearchAndSetCrypto, exit" )
+ return KErrNotFound;
+ }
+
+
+//-----------------------------------------------------------------------------
+// CMceSecureDesStream::StoreCryptoInFromOffer()
+//
+// -----------------------------------------------------------------------------
+//
+void CMceSecureDesStream::StoreCryptoInFromOfferL( const TDesC8& aSecDec,
+ TMceSecureCryptoInfo& aCrypto)
+ {
+ MCEMM_DEBUG( "CMceSecureDesStream::StoreCryptoInFromOfferL entry" )
+ TInt foundAes80 = aSecDec.Find( KAES_SHA1_80 );
+ TInt foundAes32 = aSecDec.Find( KAES_SHA1_32 );
+ if ( foundAes80 != KErrNotFound )
+ {
+ TPtrC8 tagValue = aSecDec.Mid( foundAes80-2, 1 );
+ TLex8 lexTag( tagValue );
+ TUint tag = 0;
+ User::LeaveIfError( lexTag.Val( tag, EDecimal ));
+ SetSHA180( aCrypto, tag );
+ }
+ else if (foundAes32!= KErrNotFound )
+ {
+ TPtrC8 tagValue = aSecDec.Mid( foundAes32-2, 1 );
+ TLex8 lexTag( tagValue );
+ TUint tag = 0;
+ User::LeaveIfError( lexTag.Val( tag, EDecimal ));
+ SetSHA132( aCrypto, tag );
+ }
+
+ if (foundAes32 == KErrNotFound && foundAes80 == KErrNotFound)
+ {
+ iGnoreSdpMsg = ETrue;
+ MCEMM_DEBUG( " Not Found any acceptible Crypto Value in SecureDes" )
+ return;
+ }
+
+ for ( TInt i=0; i < iCryptoOuts->Count(); i++ )
+ {
+ MCEMM_DEBUG_DVALUE(" iCryptoOuts->Count() ", iCryptoOuts->Count() )
+
+ TMceSecureCryptoInfo cryptoOut = iCryptoOuts->At( i );
+ if ( cryptoOut.iTagLen == aCrypto.iTagLen &&
+ cryptoOut.iEncAlgms == aCrypto.iEncAlgms &&
+ cryptoOut.iAuthAlgms == aCrypto.iAuthAlgms &&
+ cryptoOut.iCryptoSuite.Compare(aCrypto.iCryptoSuite) == 0 )
+ {
+ MCEMM_DEBUG( " Compare with own crypto OK" )
+ return;
+ }
+ }
+ iGnoreSdpMsg = ETrue;
+ MCEMM_DEBUG( "CMceSecureDesStream::StoreCryptoInFromOfferL exit" )
+ }
+
+
+//-----------------------------------------------------------------------------
+// CMceSecureDesStream::StoreCryptoInFromOffer()
+//
+// -----------------------------------------------------------------------------
+//
+TInt CMceSecureDesStream::CompareCryptosForAnswer()
+ {
+ //check how client wants
+ MCEMM_DEBUG( "CMceSecureDesStream::CompareCryptosForAnswer entry" )
+ if (iCryptoOuts->Count())
+ {
+ MCEMM_DEBUG_DVALUE(" iCryptoOuts->Count() ", iCryptoOuts->Count() )
+
+ TInt count = iCryptoOuts->Count();
+ for ( TInt i = 0; i< count; i++ )
+ {
+ for ( TInt j = 0; j < iCryptoIns->Count(); j++ )
+ {
+ MCEMM_DEBUG_DVALUE(" iCryptoIns->Count() ", iCryptoIns->Count() )
+ if (iCryptoOuts->At( i ).iTagLen == iCryptoIns->At( j ).iTagLen &&
+ iCryptoOuts->At( i ).iEncAlgms == iCryptoIns->At( j ).iEncAlgms &&
+ iCryptoOuts->At( i ).iAuthAlgms == iCryptoIns->At( j ).iAuthAlgms &&
+ iCryptoOuts->At( i ).iCryptoSuite.Compare( iCryptoIns->At( j ).iCryptoSuite) == 0 )
+ {
+ iCryptoIn.Copy( iCryptoIns->At( j ) );
+ //So can set the MKI and MKT
+ iCryptoOut.Copy( iCryptoIns->At( j ) );
+ MCEMM_DEBUG( "CMceSecureDesStream::CompareCryptosForAnswer exit" )
+ return KErrNone;
+ }
+ }
+ }
+ }
+ MCEMM_DEBUG( "No CryptoOuts Set" )
+ MCEMM_DEBUG( "CMceSecureDesStream::CompareCryptosForAnswer exit" )
+ return KErrArgument;
+ }
+
+//-----------------------------------------------------------------------------
+// CMceSecureDesStream::RemoveClientCrypto()
+//
+// -----------------------------------------------------------------------------
+//
+void CMceSecureDesStream::RemoveClientCrypto()
+ {
+ TInt count = ClientCrytoCount();
+ for (TInt i = count; i > 0; i--)
+ {
+ Session().iClientCryptoSuites.Remove( i-1 );
+ }
+ }
+
+//-----------------------------------------------------------------------------
+// CMceSecureDesStream::SetClientCrypto()
+//
+// -----------------------------------------------------------------------------
+//
+void CMceSecureDesStream::SetClientCryptoL( TMceSecureCryptoInfo& aCrypto )
+ {
+ if ( !aCrypto.iCryptoSuite.Compare( KAES_SHA1_32 ))
+ {
+ User::LeaveIfError(
+ Session().iClientCryptoSuites.Append( EAES_CM_128_HMAC_SHA1_32 ));
+ }
+ if ( !aCrypto.iCryptoSuite.Compare(KAES_SHA1_80) )
+ {
+ User::LeaveIfError(
+ Session().iClientCryptoSuites.Append( EAES_CM_128_HMAC_SHA1_80 ));
+ }
+ }
+
+//-----------------------------------------------------------------------------
+// CMceSecureDesStream::SetMultipleClientCrypto()
+//
+// -----------------------------------------------------------------------------
+//
+void CMceSecureDesStream::SetMultipleClientCryptoL(
+ CArrayFixFlat< TMceSecureCryptoInfo>& aArray )
+ {
+ TInt index =0;
+ TInt count = aArray.Count();
+ for ( index = 0; index < count; index ++ )
+ {
+ SetClientCryptoL( aArray[index] );
+ }
+
+ }
+//-----------------------------------------------------------------------------
+// CMceSecureDesStream::CountCrypto()
+//
+// -----------------------------------------------------------------------------
+//
+TInt CMceSecureDesStream::CountCryptoInOffer( CSdpMediaField& aMediaField )
+ {
+
+ if ( !iCryptoIns->Count() && !ClientCrytoCount() &&
+ iSecureSession.SdpCryptoAttributeCount(aMediaField) )
+ {
+ return KErrArgument;
+ }
+ return KErrNone;
+ }
+
+//-----------------------------------------------------------------------------
+// CMceSecureDesStream::Copy()
+//
+// -----------------------------------------------------------------------------
+//
+void CMceSecureDesStream::CopyStreamCryptoL( CMceSecureDesStream& aCopyFrom )
+ {
+ MCEMM_DEBUG( "CMceSecureDesStream::CopyStreamCryptoL Entry" )
+ iCryptoUpdateNeeded = ETrue;
+ iCryptoOut.Copy(aCopyFrom.iCryptoOut);
+ MCEMM_DEBUG_DVALUE( "iCryptoContextOutId", aCopyFrom.iCryptoOut.iCryptoContextId )
+ iCryptoContextOutId = aCopyFrom.iCryptoOut.iCryptoContextId;
+ iCryptoIn.Copy(aCopyFrom.iCryptoIn);
+ iCryptoContextInId = aCopyFrom.iCryptoIn.iCryptoContextId;
+ MCEMM_DEBUG_DVALUE( "iCryptoContextInId", aCopyFrom.iCryptoIn.iCryptoContextId )
+
+ for (TInt i = 0; i < aCopyFrom.iCryptoOuts->Count(); i++)
+ {
+ iCryptoOuts->AppendL( aCopyFrom.iCryptoOuts->At( i ) );
+ }
+ iOldLocalMediaPort = aCopyFrom.iOldLocalMediaPort;
+ MCEMM_DEBUG( "CMceSecureDesStream::CopyStreamCryptoL Exit" )
+ }
+
+//-----------------------------------------------------------------------------
+// CMceSecureDesStream::Session()
+//
+// -----------------------------------------------------------------------------
+//
+CMceComSession& CMceSecureDesStream::Session()
+ {
+ return iSecureSession.iSession;
+ }
+
+//-----------------------------------------------------------------------------
+// CMceSecureDesStream::MediaFieldAttrMatch()
+//
+// -----------------------------------------------------------------------------
+//
+CSdpAttributeField* CMceSecureDesStream::MediaFieldAttrMatch( CSdpMediaField& aMediaField,
+ const TDesC8& aMatchString )
+ {
+ RPointerArray< CSdpAttributeField > attrList =
+ aMediaField.AttributeFields();
+
+ TInt attrCount = attrList.Count();
+
+ for (TInt j = 0; j < attrCount; j++ )
+ {
+ RStringF attribute = attrList[ j ]->Attribute();
+
+ if ( attribute.DesC().Match( aMatchString )!= KErrNotFound )
+ {
+ return attrList[ j ];
+ }
+ }
+ return NULL;
+ }
+
+//-----------------------------------------------------------------------------
+// CMceSecureDesStream::SetMediaProfile ()
+//
+// -----------------------------------------------------------------------------
+//
+TInt CMceSecureDesStream::SetMediaProfile( CSdpMediaField& aMediaField )
+ {
+ //answer or offer/update or refresh
+ TInt findSAVP = aMediaField.Protocol().DesC().Find( KProtocolSAVP );
+ TInt findSAVPF = aMediaField.Protocol().DesC().Find( KProtocolSAVPF );
+ TInt findAVP = aMediaField.Protocol().DesC().Find( KProtocolAVP );
+
+ if ( findSAVP == KErrNotFound && findSAVPF == KErrNotFound &&
+ findAVP == KErrNotFound)
+ {
+ return KErrArgument;
+ }
+ if ( findAVP != KErrNotFound )
+ {
+ Session().Modifier( KMceSecureSession ) = KMceSecurePlainAVP;
+ }
+ if ( findSAVP != KErrNotFound || findSAVPF != KErrNotFound )
+ {
+ Session().Modifier( KMceSecureSession ) = KMceSecureNormal;
+ iIsSAVP = findSAVPF != KErrNotFound ? !iIsSAVP : iIsSAVP;
+ }
+
+
+ return KErrNone;
+ }
+
+
+//-----------------------------------------------------------------------------
+// CMceSecureDesStream::AppendCryptoAttributeL ()
+//
+// -----------------------------------------------------------------------------
+//
+void CMceSecureDesStream::AppendCryptoAttributeL( TDesC8& aCryptoLine,
+ CSdpMediaField& aMediaField )
+ {
+ RStringF crypto = SdpCodecStringPool::StringPoolL().OpenFStringL( KCrypto );
+ CleanupClosePushL( crypto );
+ CSdpAttributeField* attribute = NULL;
+ attribute = CSdpAttributeField::NewLC( crypto, aCryptoLine );
+ User::LeaveIfError ( aMediaField.AttributeFields().Append( attribute ) );
+ CleanupStack::Pop(attribute);
+ CleanupStack::PopAndDestroy( &crypto );
+ }
+
+//-----------------------------------------------------------------------------
+// CMceSecureDesStream::AppendCryptoAttributeL ()
+//
+// -----------------------------------------------------------------------------
+//
+TInt CMceSecureDesStream::SearchChar( TDesC8& aSearchLine,
+ TChar& aChar,
+ TInt aSearchFrom )
+ {
+ TInt len = aSearchLine.Length();
+ TLex8 search( aSearchLine );
+
+ for ( TInt offset = 0; offset < len; offset++ )
+ {
+ if ( search.Peek() == aChar )
+ {
+ if ( !aSearchFrom )
+ return offset;
+ if (aSearchFrom && offset > aSearchFrom)
+ return offset;
+ }
+ search.Inc();
+ }
+ return KErrNone;
+ }
+
+//-----------------------------------------------------------------------------
+// CMceSecureDesStream::AppendEmptyCryptoL ()
+//
+// -----------------------------------------------------------------------------
+//
+void CMceSecureDesStream::AppendEmptyCryptoL(
+ CArrayFixFlat<TMceSecureCryptoInfo>& aCryptos,
+ TInt aCount )
+ {
+ for ( TInt i = 0; i < aCount; i++)
+ {
+ TMceSecureCryptoInfo crypto;
+ aCryptos.AppendL( crypto );
+ }
+ }
+
+//-----------------------------------------------------------------------------
+// CMceSecureDesStream::SetSHA132 ()
+//
+// -----------------------------------------------------------------------------
+//
+void CMceSecureDesStream::SetSHA132( TMceSecureCryptoInfo& aCrypto, TInt aTag )
+ {
+ aCrypto.iTag = aTag;
+ aCrypto.iEncAlgms = ESrtpEncAES_CM;
+ aCrypto.iTagLen = KAuthTagLength32;
+ aCrypto.iAuthAlgms = ESrtpAuthHMAC_SHA1;
+ aCrypto.iCryptoSuite = KAES_SHA1_32;
+ }
+
+//-----------------------------------------------------------------------------
+// CMceSecureDesStream::SetSHA180 ()
+//
+// -----------------------------------------------------------------------------
+//
+void CMceSecureDesStream::SetSHA180( TMceSecureCryptoInfo& aCrypto, TInt aTag )
+ {
+ aCrypto.iTag = aTag;
+ aCrypto.iEncAlgms = ESrtpEncAES_CM;
+ aCrypto.iTagLen = KAuthTagLength80;
+ aCrypto.iAuthAlgms = ESrtpAuthHMAC_SHA1;
+ aCrypto.iCryptoSuite = KAES_SHA1_80;
+ }
+
+//-----------------------------------------------------------------------------
+// CMceSecureDesStream::SetDefaultCryptoL ()
+//
+// -----------------------------------------------------------------------------
+//
+void CMceSecureDesStream::SetDefaultCryptoL(
+ CArrayFixFlat<TMceSecureCryptoInfo>& aCryptos )
+ {
+ MCEMM_DEBUG( "CMceSecureDesStream::SetDefaultCryptoL, entry " )
+ const TInt tag1 = 1;
+ const TInt tag2 = 2;
+ const TUint index1 = 0;
+ const TInt index2 = 1;
+
+ AppendEmptyCryptoL( aCryptos, KTotalCryptoAnswerCount );
+
+ MCEMM_DEBUG_DVALUE(" CryptoCount = ", aCryptos.Count() )
+ iGnoreSdpMsg = !aCryptos.Count() ? ETrue : EFalse;
+ MSG_IGNORE_RETURN()
+ SetSHA180( aCryptos.At( index1 ), tag1 );
+
+ iGnoreSdpMsg = index2 >= iCryptoOuts->Count() ? ETrue : EFalse;
+ MSG_IGNORE_RETURN()
+ SetSHA132( aCryptos.At( index2 ), tag2 );
+
+ MCEMM_DEBUG( "CMceSecureDesStream::SetDefaultCryptoL, exit " )
+ }
+
+//-----------------------------------------------------------------------------
+// CMceSecureDesStream::SetCryptoByClientL ()
+//
+// -----------------------------------------------------------------------------
+//
+void CMceSecureDesStream::SetCryptoByClientL(
+ CArrayFixFlat<TMceSecureCryptoInfo>& aCryptos )
+ {
+ MCEMM_DEBUG( "CMceSecureDesStream::SetCryptoByClientL, entry " )
+ RArray <TMceCryptoContext> clientCryptoSuite =
+ Session().iClientCryptoSuites;
+ TInt clientCryptoCount = clientCryptoSuite.Count();
+ MCEMM_DEBUG_DVALUE(" ClientCryptoCount = ", aCryptos.Count() )
+ for ( TInt i = 0; i < clientCryptoCount; i++ )
+ {
+ TMceSecureCryptoInfo crypto;
+
+ if ( clientCryptoSuite[i] == EAES_CM_128_HMAC_SHA1_32 )
+ {
+ SetSHA132( crypto, i+1 );
+ }
+ if ( clientCryptoSuite[i] == EAES_CM_128_HMAC_SHA1_80 )
+ {
+ SetSHA180( crypto, i+1 );
+ }
+ aCryptos.AppendL( crypto );
+ }
+ MCEMM_DEBUG( "CMceSecureDesStream::SetCryptoByClientL, exit " )
+ }
+// End of File