diff -r 000000000000 -r 1bce908db942 multimediacommsengine/mmcesrv/mmcemediamanager/src/mcesecuremediasession.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/multimediacommsengine/mmcesrv/mmcemediamanager/src/mcesecuremediasession.cpp Tue Feb 02 01:04:58 2010 +0200 @@ -0,0 +1,622 @@ +/* +* Copyright (c) 2005 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 +#include + +#include +#include +#include +#include +#include +#include +#include "mcesrvstream.h" +#include "mcecomcodec.h" +#include "mcemmlogs.h" +#include "mcesecuremediasession.h" +#include "mcesecuredesstream.h" +#include "mceclientserver.h" + + +// ================= MEMBER FUNCTIONS ========================================== + +// ----------------------------------------------------------------------------- +// CMceSecureMediaSession::CMceSecureMediaSession +// ----------------------------------------------------------------------------- +CMceSecureMediaSession::CMceSecureMediaSession( CMceComSession& aSession, + CMceMediaManager& aManager, + CMccSecureInterface& aSecureInterface) + : iManager( aManager ), + iSession( aSession ), + iSecureInterface(aSecureInterface), + iKeyNeedUpdated( ETrue ), + iCryptoContextUpdate (EFalse), + iLSReadyToBind ( ETrue ), + iStringTable( NULL ) + { + + } + +// ----------------------------------------------------------------------------- +// CMceSecureMediaSession::ConstructL +// ----------------------------------------------------------------------------- +void CMceSecureMediaSession::ConstructL() + { + } + + +// ----------------------------------------------------------------------------- +// CMceSecureMediaSession::NewL +// ----------------------------------------------------------------------------- + CMceSecureMediaSession* CMceSecureMediaSession::NewL( CMceComSession& aSession, + CMceMediaManager& aManager, + CMccSecureInterface& aSecureInterface ) + { + CMceSecureMediaSession* self = NewLC( aSession, aManager, aSecureInterface ); + CleanupStack::Pop( self ); + return self; + } + + +// ----------------------------------------------------------------------------- +// CMceSecureMediaSession::NewLC +// ----------------------------------------------------------------------------- + CMceSecureMediaSession* CMceSecureMediaSession::NewLC( CMceComSession& aSession, + CMceMediaManager& aManager, + CMccSecureInterface& aSecureInterface ) + { + CMceSecureMediaSession* self = new ( ELeave ) CMceSecureMediaSession( aSession, + aManager, + aSecureInterface ); + CleanupStack::PushL( self ); + self->ConstructL(); + return self; + } + + +// ----------------------------------------------------------------------------- +// CMceSecureMediaSession::~CMceSecureMediaSession +// ----------------------------------------------------------------------------- + CMceSecureMediaSession::~CMceSecureMediaSession() + { + //Remove secure streams + iMceSecureDesStreams.ResetAndDestroy(); + } + + +// ----------------------------------------------------------------------------- +// CMceSecureMediaSession:: +// ----------------------------------------------------------------------------- +// +void CMceSecureMediaSession::EncodeSecureDesSdpOfferL( + CMceComMediaStream& aStream, + CSdpMediaField& aMediaLine) + { + + MCEMM_DEBUG("CMceSecureMediaSession::(), Entry "); + User::LeaveIfNull( &aMediaLine ); + + // find media lines and create sec stream and add security attribute + CMceSecureDesStream* secStream=NULL; + + if ( iMceSecureDesStreams.Count()!=0 ) + { + //find sec stream + TInt secStreamCount = iMceSecureDesStreams.Count(); + for (TInt j=0; jRemvoeSecureSdp(aMediaLine); + } + } + } + if (!secStream) + { + //create sec stream depends on how many media lines + /*RFC 4568 7.1.1 + The inline parameter conveys the SRTP master key used by an endpoint + to encrypt the SRTP and SRTCP streams transmitted by that endpoint. + The same key is used by the recipient to decrypt those streams. + */ + secStream = CMceSecureDesStream::NewL( + *this, + aMediaLine, + iSecureInterface, + aStream); + CleanupStack::PushL(secStream); + iMceSecureDesStreams.AppendL(secStream); + CleanupStack::Pop(secStream); + } + //Encode sdp + if (secStream) + { + secStream->EncodeSecureSdpL(aMediaLine, EFalse); + } + + MCEMM_DEBUG("CMceSecureMediaSession::(), Exit "); + + } + +// ----------------------------------------------------------------------------- +// CMceSecureMediaSession::DecodeSecureDesSdpAnswerL +// ----------------------------------------------------------------------------- +// +void CMceSecureMediaSession::DecodeSecureDesSdpAnswerL( CMceComMediaStream& aStream, + CSdpMediaField& aMediaLine) + { + MCEMM_DEBUG("CMceSecureMediaSession::DecodeSecureDesSdpAnswerL(), Entry "); + // decode media lines for answer + + User::LeaveIfNull( &aMediaLine ); + + if ( IsSecureSdpMsgL( aMediaLine ) ) + { + TBool foundCryptoIn=EFalse; + + CMceSecureDesStream* secStream=NULL; + //one uplink stream for this codec must be set already + TInt secStreamCount = iMceSecureDesStreams.Count(); + for (TInt i=0; iDecodeSecureSdpAnswerL( aMediaLine ) ); + if ( err ) + { + TInt index = iMceSecureDesStreams.Find( secStream ); + if ( KErrNotFound != index ) + { + iMceSecureDesStreams.Remove( index ); + } + delete secStream; + secStream = NULL; + User::Leave( err ); + } + } + } + else + { + RemoveSecureCrypto( ); + //Expected secure sdp answer but not found. leave to end the sesssion + User::Leave( KErrArgument ); + } + + MCEMM_DEBUG("CMceSecureMediaSession::DecodeSecureDesSdpAnswerL(), Exit "); + + } + +// ----------------------------------------------------------------------------- +// CMceSecureMediaSession::DecodeSecureDesSdpOfferL +// ----------------------------------------------------------------------------- + +void CMceSecureMediaSession::DecodeSecureDesSdpOfferL( CMceComMediaStream& aStream, + CSdpMediaField& aMediaLine) + { + MCEMM_DEBUG("CMceSecureMediaSession::DecodeSecureDesSdpOfferL(), Entry "); + + User::LeaveIfNull( &aMediaLine ); + + TBool foundCryptoIn = EFalse; + + if ( IsSecureSdpMsgL( aMediaLine ) ) + { + CMceSecureDesStream* secStream=NULL; + /*RFC 4568 7.1.1 + The inline parameter conveys the SRTP master key used by an endpoint + to encrypt the SRTP and SRTCP streams transmitted by that endpoint. + The same key is used by the recipient to decrypt those streams. + */ + TInt secStreamCount = iMceSecureDesStreams.Count(); + for (TInt i=0; iDecodeSecureSdpL( aMediaLine ) ); + if ( err ) + { + TInt index = iMceSecureDesStreams.Find( secStream ); + if ( KErrNotFound != index ) + { + iMceSecureDesStreams.Remove( index ); + } + delete secStream; + secStream = NULL; + User::Leave( err ); + } + } + } + else + { + RemoveSecureCrypto( ); + } + + MCEMM_DEBUG("CMceSecureMediaSession::DecodeSecureDesSdpOfferL(), Exit " ); + } + +// ----------------------------------------------------------------------------- +// CMceSecureMediaSession::DecodeSecureDesSdpOfferL +// ----------------------------------------------------------------------------- + +void CMceSecureMediaSession::DecodeSecureDesSdpUpdateL( CMceComMediaStream& aStream, + CSdpMediaField& aMediaLine) + { + MCEMM_DEBUG("CMceSecureMediaSession::DecodeSecureDesSdpOfferL(), Entry "); + + User::LeaveIfNull( &aMediaLine ); + if ( IsSecureSdpMsgL( aMediaLine ) ) + { + + // find media lines and create sec stream and add security attribute + + CMceSecureDesStream* secStream=NULL; + + //one uplink stream for this codec must be set already + TInt secStreamCount = iMceSecureDesStreams.Count(); + for (TInt i=0; iDecodeSecureSdpL( aMediaLine ); + + } + + } + } + else + { + RemoveSecureCrypto( ); + } + + MCEMM_DEBUG("CMceSecureMediaSession::DecodeSecureDesSdpOfferL(), Exit "); + } + +// ----------------------------------------------------------------------------- +// CMceSecureMediaSession::EncodeSecureDesSdpAnswerL +// ----------------------------------------------------------------------------- +void CMceSecureMediaSession::EncodeSecureDesSdpAnswerL( CMceComMediaStream& aStream, + CSdpMediaField& aMediaLine ) + { + MCEMM_DEBUG("CMceSecureMediaSession::EncodeSecureDesSdpAnswerL(), Entry "); + User::LeaveIfNull( &aMediaLine); + + TBool foundCryptoOut=EFalse; + + // find media lines and create sec stream and add security attribute + CMceSecureDesStream* secStream=NULL; + + TInt secStreamCount = iMceSecureDesStreams.Count(); + for (TInt i=0; iRemvoeSecureSdp(aMediaLine); + + foundCryptoOut=ETrue; + } + + } + //create sec stream depends on how many media lines + if (!foundCryptoOut) + { + secStream = CMceSecureDesStream::NewL(*this, + aMediaLine, + iSecureInterface, + aStream); + CleanupStack::PushL( secStream); + iMceSecureDesStreams.AppendL(secStream); + CleanupStack::Pop(secStream); + + } + + //Decode sdp + if (secStream) + { + secStream->EncodeSecureSdpL(aMediaLine, ETrue); + } + + MCEMM_DEBUG("CMceSecureMediaSession::EncodeSecureDesSdpAnswerL(), Exit "); + } + + +// ----------------------------------------------------------------------------- +// CMceSecureMediaSession:: CleanSecureCryptoInfo() +// ----------------------------------------------------------------------------- +void CMceSecureMediaSession:: CleanSecureCryptoInfoL(CSdpMediaField& aMediaLine) + { + MCEMM_DEBUG("CMceSecureMediaSession::CleanSecureCryptoInfoL(), Entry "); + User::LeaveIfNull( &aMediaLine ); + + // find media lines and create sec stream and add security attribute + CMceSecureDesStream* secStream=NULL; + + //find sec stream + TInt secStreamCount = iMceSecureDesStreams.Count(); + for (TInt j=0; jMediaStream(), *secDesStream, aMediaLine)) + { + //out of loop + j=secStreamCount; + secStream = secDesStream; + secStream->RemvoeSecureSdp(aMediaLine ); + } + } + + User::LeaveIfError( aMediaLine.IsValid() ); + MCEMM_DEBUG("CMceSecureMediaSession::CleanSecureCryptoInfoL(), Exit "); + + } + +// ----------------------------------------------------------------------------- +// CMceSecureMediaSession::Bind() +// ----------------------------------------------------------------------------- +TInt CMceSecureMediaSession::BindStreamCrypto( ) + + { + MCEMM_DEBUG("CMceSecureDesStream::BindStreamCrypto(), Entry"); + TInt err(KErrNone); + if (iSession.iClientCryptoSuites.Count()) + { + for (TInt i=0; iData().Id().iAppId ); + TInt secStreamCount = iMceSecureDesStreams.Count(); + for (TInt j=0; jMediaStream().Id().iId); + MCEMM_DEBUG_DVALUE(" App id in SecureStream ", secureStream->MediaStream().Id().iAppId); + if (stream->Data().Id()== secureStream->MediaStream().Id() || + ( stream->Data().BoundStream() && + stream->Data().iLinkedStream->Id() == secureStream->MediaStream().Id() ) ) + { + //bind + secureStream->BindCrypto(*stream); + + } + } + } + } + MCEMM_DEBUG("CMceSecureDesStream::BindStreamCrypto(), Exit"); + return err; + } + + +// ----------------------------------------------------------------------------- +// CMceSecureMediaSession::ContextNeedUpdated +// ----------------------------------------------------------------------------- + +void CMceSecureMediaSession::ContextNeedUpdated( TUint32 aContextId ) + { + TInt secStreamCount = iMceSecureDesStreams.Count(); + for (TInt j=0; jCompareContextId(aContextId)) + { + secDesStream->iCryptoUpdateNeeded = ETrue; + } + } + } + +// ----------------------------------------------------------------------------- +// CMceSecureMediaSession::IfStreamMatchMedia +// ----------------------------------------------------------------------------- + +TBool CMceSecureMediaSession::IfStreamMatchMedia( CMceComMediaStream& aMediaStream, + CMceSecureDesStream& aStream, + CSdpMediaField& aMediaLine) + { + TBool match=EFalse; + if (aStream.MediaField().Media()== aMediaLine.Media() && + aStream.MediaStream().iLocalMediaPort==aMediaStream.iLocalMediaPort && + aStream.MediaStream().iRemoteMediaPort==aMediaStream.iRemoteMediaPort ) + { + match =ETrue; + + if (aMediaStream.iLocalMediaPort != aMediaLine.Port()&& + aMediaStream.iRemoteMediaPort !=aMediaLine.Port()) + { + match=EFalse; + } + } + return match; + } +// ----------------------------------------------------------------------------- +// CMceSecureMediaSession::CloneStreams +// ----------------------------------------------------------------------------- + +void CMceSecureMediaSession::CopyStreamsL(CMceSecureMediaSession& aSession) + { + iKeyNeedUpdated = aSession.iKeyNeedUpdated; + TInt secStreamCount = aSession.iMceSecureDesStreams.Count(); + for (TInt j=0; j (iSession.Streams()[i]); + + if (mediaStream->iLocalMediaPort == copyFrom->MediaStream().iLocalMediaPort && + mediaStream->iRemoteMediaPort == copyFrom->MediaStream().iRemoteMediaPort) + { + CMceSecureDesStream* copy = CMceSecureDesStream::NewL(*this, + copyFrom->MediaField(), + iSecureInterface, + *mediaStream); + CleanupStack::PushL( copy); + copy->CopyStreamCryptoL(*copyFrom); + iMceSecureDesStreams.AppendL(copy); + CleanupStack::Pop( copy ); + } + } + + + } + } + + +//----------------------------------------------------------------------------- +// CMceSecureMediaSession::IsSecureSdpMsg () +// +// ----------------------------------------------------------------------------- +// +TBool CMceSecureMediaSession::IsSecureSdpMsgL( CSdpMediaField& aMediaLine ) + { + //answer or offer/update or refresh + TInt findSAVP = aMediaLine.Protocol().DesC().Find( KProtocolSAVP ); + TInt findSAVPF = aMediaLine.Protocol().DesC().Find( KProtocolSAVPF ); + TInt findAVP = aMediaLine.Protocol().DesC().Find( KProtocolAVP ); + TBool isSecureMsg = ETrue; + TInt attrCount = SdpCryptoAttributeCount( aMediaLine ); + + + if ( findAVP != KErrNotFound && attrCount ) + { + iSession.Modifier( KMceSecureSession ) = KMceSecurePlainAVP; + } + else if ( ( findSAVP != KErrNotFound || findSAVPF != KErrNotFound ) && + attrCount ) + { + iSession.Modifier( KMceSecureSession ) = KMceSecureNormal; + } + else if ( ( findSAVP != KErrNotFound || findSAVPF != KErrNotFound ) && + !attrCount ) + { + User::Leave( KErrArgument ); + } + else + { + return !isSecureMsg; + } + + + return isSecureMsg; + } + +// ----------------------------------------------------------------------------- +// CMceSecureMediaSession::SdpCryptoAttributeCount() +// +// ----------------------------------------------------------------------------- +// +TInt CMceSecureMediaSession::SdpCryptoAttributeCount( CSdpMediaField& aMediaLine) + { + MCEMM_DEBUG("CMceSecureMediaSession::SdpCryptoAttributeCount(), Entry"); + RPointerArray< CSdpAttributeField > attrList = aMediaLine.AttributeFields(); + CSdpAttributeField* attributeField = NULL; + TInt attrCount = attrList.Count(); + TInt attrbuiteCryptoCount = 0; + for (TInt j = 0; j < attrCount; j++ ) + { + attributeField = attrList[j]; + + RStringF attribute = attributeField->Attribute(); + + // check if attribute is 'crypto' + if ( KErrNotFound != attribute.DesC().Match( KCrypto ) ) + { + attrbuiteCryptoCount++; + } + } + + MCEMM_DEBUG("CMceSecureMediaSession::SdpCryptoAttributeCount(), Exit"); + return attrbuiteCryptoCount; + } + +// ----------------------------------------------------------------------------- +// CMceSecureMediaSession::SdpCryptoAttributeCount() +// +// ----------------------------------------------------------------------------- +// +void CMceSecureMediaSession::RemoveSecureCrypto( ) + { + //clear comsession crypto + TInt count = iSession.iClientCryptoSuites.Count(); + for (TInt i = count; i > 0; i--) + { + iSession.iClientCryptoSuites.Remove( i-1 ); + iSession.iIsSecureSession = EFalse; + } + } +// End of File