multimediacommsengine/mmcesrv/mmcemediamanager/src/mcesecuremediasession.cpp
changeset 0 1bce908db942
child 3 513a8b745b2f
--- /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 <e32base.h>
+#include <e32std.h>
+
+#include <sdporiginfield.h>
+#include <sdpconnectionfield.h>
+#include <sdpmediafield.h>
+#include <sdpattributefield.h>
+#include <sdpcodecstringpool.h>
+#include <sdpdocument.h>
+#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; j<secStreamCount; j++)
+	    	{
+	    	CMceSecureDesStream* secDesStream = iMceSecureDesStreams[j];
+	    	if (IfStreamMatchMedia(aStream, *secDesStream, aMediaLine) )
+	    		{
+	    		//out of loop
+	    		j=secStreamCount;
+	    		secStream = secDesStream;
+	    		//remove or clean secure sdp params if any 
+	    		secStream->RemvoeSecureSdp(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; i<secStreamCount; i++)
+	    	{
+	    	CMceSecureDesStream* secDesStream = iMceSecureDesStreams[i];
+	    	if (IfStreamMatchMedia(aStream, *secDesStream, aMediaLine))
+	    		{
+	    		i=secStreamCount;
+	    		secStream = secDesStream;
+	    		foundCryptoIn=ETrue;
+	    		}
+	    	}
+	    	//create sec stream depends on how many media lines
+		if (!foundCryptoIn && (aStream.iLocalMediaPort == aMediaLine.Port()||
+				aStream.iRemoteMediaPort ==aMediaLine.Port()) )
+			{
+			secStream = CMceSecureDesStream::NewL(*this,
+										aMediaLine,
+									iSecureInterface,
+									aStream);
+							
+			iMceSecureDesStreams.Append(secStream);						
+			}
+
+		//Decode sdp
+		if (secStream)
+			{
+            TRAPD( err, secStream->DecodeSecureSdpAnswerL( 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; i<secStreamCount; i++)
+			{
+			
+	    	CMceSecureDesStream* secDesStream = iMceSecureDesStreams[i];
+	    	if (IfStreamMatchMedia(aStream, *secDesStream, aMediaLine))
+	    		{
+	    		i=secStreamCount;
+	    		secStream = secDesStream;
+	    		foundCryptoIn=ETrue;
+	    		}
+	    			
+			}
+	    
+	    	//create sec stream depends on how many media lines
+		if (!foundCryptoIn)
+			{
+			secStream = CMceSecureDesStream::NewL( *this,
+													aMediaLine,
+													iSecureInterface,
+													aStream);
+									
+			iMceSecureDesStreams.Append( secStream );						
+			}
+		
+			//Decode sdp
+		if (secStream)
+			{
+            TRAPD( err, secStream->DecodeSecureSdpL( 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; i<secStreamCount; i++ )
+	    	{
+	    	secStream = iMceSecureDesStreams[i];
+	    	if (IfStreamMatchMedia(	aStream, *secStream,aMediaLine))
+	    		{
+	    		secStream->DecodeSecureSdpL( 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; i<secStreamCount; i++)
+    	{
+    	CMceSecureDesStream* secDesStream = iMceSecureDesStreams[i];
+    	if (IfStreamMatchMedia(aStream, *secDesStream, aMediaLine))
+    		{
+    		//HARDCode here as refresh first later on should also know when to 
+			// set as updated mode 	
+		
+			i=secStreamCount;
+    		secStream = secDesStream;
+    		//remove or clean secure sdp params if any 
+    		secStream->RemvoeSecureSdp(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; j<secStreamCount; j++)
+    	{
+    	CMceSecureDesStream* secDesStream = iMceSecureDesStreams[j];
+    	if (IfStreamMatchMedia(secDesStream->MediaStream(), *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; i<iSession.MccStreams().Count(); i++)
+			{
+			CMceSrvStream* stream = iSession.MccStreams()[i];
+			MCEMM_DEBUG_DVALUE("	CMceSrvStream id =", stream->Data().Id().iId );	
+			MCEMM_DEBUG_DVALUE("	App id", stream->Data().Id().iAppId );		
+			TInt secStreamCount = iMceSecureDesStreams.Count();
+    		for (TInt j=0; j<secStreamCount; j++)
+				{
+				CMceSecureDesStream* secureStream=iMceSecureDesStreams[j]; 
+				MCEMM_DEBUG_DVALUE("	SrvStream id in SecureStream ", secureStream->MediaStream().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; j<secStreamCount; j++)
+    	{
+    	CMceSecureDesStream* secDesStream = iMceSecureDesStreams[j];
+    	if (secDesStream->CompareContextId(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<secStreamCount; j++)
+    	{
+    	CMceSecureDesStream* copyFrom =aSession.iMceSecureDesStreams[j];
+    	CMceComMediaStream* mediaStream=NULL;
+    	for (TInt i=0; i<iSession.Streams().Count();i++)
+    		{
+    		mediaStream =  static_cast <CMceComMediaStream*> (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