diff options
author | Ingo Bauersachs <ingo@jitsi.org> | 2011-10-04 12:27:40 +0000 |
---|---|---|
committer | Ingo Bauersachs <ingo@jitsi.org> | 2011-10-04 12:27:40 +0000 |
commit | 81d63ab6722ec556f0ff65f82d53e1de31cc05ce (patch) | |
tree | 8f838c00616c9b414e589e92b714c0458c98fd6d | |
parent | b0ad56ad8277eb51dc42a247d757cafb6cc58c7c (diff) | |
download | jitsi-81d63ab6722ec556f0ff65f82d53e1de31cc05ce.zip jitsi-81d63ab6722ec556f0ff65f82d53e1de31cc05ce.tar.gz jitsi-81d63ab6722ec556f0ff65f82d53e1de31cc05ce.tar.bz2 |
SDES Integration: Enable fallback to ZRTP, add Javadoc, more renames
16 files changed, 578 insertions, 189 deletions
diff --git a/resources/config/defaults.properties b/resources/config/defaults.properties index b2b9764..6e0adae 100644 --- a/resources/config/defaults.properties +++ b/resources/config/defaults.properties @@ -80,3 +80,5 @@ plugin.provisioning.EXIT_ON_FAIL=false net.java.sip.communicator.util.dns.BACKUP_RESOLVER_FALLBACK_IP=8.8.8.8 plugin.jabberaccregwizz.NEW_ACCOUNT_DEFAULT_SERVER=jit.si + +net.java.sip.communicator.service.neomedia.SDES_CIPHER_SUITES=AES_CM_128_HMAC_SHA1_80,AES_CM_128_HMAC_SHA1_32 diff --git a/src/net/java/sip/communicator/impl/neomedia/MediaStreamImpl.java b/src/net/java/sip/communicator/impl/neomedia/MediaStreamImpl.java index af7a864..5fcdbda 100644 --- a/src/net/java/sip/communicator/impl/neomedia/MediaStreamImpl.java +++ b/src/net/java/sip/communicator/impl/neomedia/MediaStreamImpl.java @@ -196,9 +196,9 @@ public class MediaStreamImpl new Hashtable<String, String>(); /** - * The current <tt>ZrtpControl</tt>. + * The current <tt>SrtpControl</tt>. */ - private final SrtpControl zrtpControl; + private final SrtpControl srtpControl; /** * Needed when restarting zrtp control. @@ -256,14 +256,14 @@ public class MediaStreamImpl * @param device the <tt>MediaDevice</tt> the new instance is to use for * both capture and playback of media exchanged via the specified * <tt>StreamConnector</tt> - * @param zrtpControl an existing control instance to control the ZRTP + * @param srtpControl an existing control instance to control the ZRTP * operations or <tt>null</tt> if a new control instance is to be created by * the new <tt>MediaStreamImpl</tt> */ public MediaStreamImpl( StreamConnector connector, MediaDevice device, - SrtpControl zrtpControl) + SrtpControl srtpControl) { /* * XXX Set the device early in order to make sure that it is of the @@ -271,8 +271,9 @@ public class MediaStreamImpl */ setDevice(device); - this.zrtpControl - = (zrtpControl == null) ? new ZrtpControlImpl() : zrtpControl; + //TODO add option to disable ZRTP, e.g. by implementing a NullControl + this.srtpControl + = (srtpControl == null) ? new ZrtpControlImpl() : srtpControl; if (connector != null) setConnector(connector); @@ -351,8 +352,8 @@ public class MediaStreamImpl if (dtmfEngine != null) engineChain.add(dtmfEngine); - // ZRTP - engineChain.add(zrtpControl.getTransformEngine()); + // SRTP + engineChain.add(srtpControl.getTransformEngine()); // RTCP Statistics if(statisticsEngine == null) @@ -506,7 +507,7 @@ public class MediaStreamImpl stop(); closeSendStreams(); - zrtpControl.cleanup(); + srtpControl.cleanup(); zrtpRestarted = false; if(csrcEngine != null) @@ -646,7 +647,7 @@ public class MediaStreamImpl // If a ZRTP engine is available then set the SSRC of this // stream // currently ZRTP supports only one SSRC per engine - TransformEngine engine = zrtpControl.getTransformEngine(); + TransformEngine engine = srtpControl.getTransformEngine(); if (engine != null && engine instanceof ZRTPTransformEngine) ((ZRTPTransformEngine)engine) @@ -1096,13 +1097,13 @@ public class MediaStreamImpl } /** - * Gets the <tt>ZrtpControl</tt> which controls the ZRTP of this stream. + * Gets the <tt>SrtpControl</tt> which controls the SRTP of this stream. * - * @return the <tt>ZrtpControl</tt> which controls the ZRTP of this stream + * @return the <tt>SrtpControl</tt> which controls the SRTP of this stream */ - public SrtpControl getZrtpControl() + public SrtpControl getSrtpControl() { - return zrtpControl; + return srtpControl; } /** @@ -1115,10 +1116,10 @@ public class MediaStreamImpl * If there is no current secure communication, we don't need to do * that. */ - if(!zrtpControl.getSecureCommunicationStatus()) + if(!srtpControl.getSecureCommunicationStatus()) return; - zrtpControl.cleanup(); + srtpControl.cleanup(); /* * As we are recreating this stream and it was obviously secured, it may @@ -1134,7 +1135,7 @@ public class MediaStreamImpl AbstractRTPConnector rtpConnector = getRTPConnector(); - zrtpControl.setConnector(rtpConnector); + srtpControl.setConnector(rtpConnector); if(rtpConnector instanceof RTPTransformUDPConnector) ((RTPTransformUDPConnector)rtpConnector) .setEngine(createTransformEngineChain()); @@ -1250,7 +1251,7 @@ public class MediaStreamImpl AbstractRTPConnector oldValue, AbstractRTPConnector newValue) { - zrtpControl.setConnector(newValue); + srtpControl.setConnector(newValue); if (newValue != null) { diff --git a/src/net/java/sip/communicator/impl/neomedia/SDesControlImpl.java b/src/net/java/sip/communicator/impl/neomedia/SDesControlImpl.java index e105f7a..4ea5e63 100644 --- a/src/net/java/sip/communicator/impl/neomedia/SDesControlImpl.java +++ b/src/net/java/sip/communicator/impl/neomedia/SDesControlImpl.java @@ -1,42 +1,68 @@ package net.java.sip.communicator.impl.neomedia;
+import java.util.*;
+
import ch.imvs.sdes4j.srtp.*;
import net.java.sip.communicator.impl.neomedia.transform.*;
import net.java.sip.communicator.impl.neomedia.transform.sdes.*;
import net.java.sip.communicator.service.neomedia.*;
import net.java.sip.communicator.service.neomedia.event.*;
+import net.java.sip.communicator.service.protocol.event.CallPeerSecurityStatusEvent;
+/**
+ * Default implementation of {@link SDesControl}.
+ *
+ * @author Ingo Bauersachs
+ */
public class SDesControlImpl
implements SDesControl
{
- private String[] supportedCryptoSuites = new String[]
- {
- SrtpCryptoSuite.AES_CM_128_HMAC_SHA1_80,
- //SrtpCryptoSuite.AES_CM_128_HMAC_SHA1_32,
- //SrtpCryptoSuite.F8_128_HMAC_SHA1_80
- };
+ private List<String> enabledCryptoSuites = new ArrayList<String>(3)
+ {{
+ add(SrtpCryptoSuite.AES_CM_128_HMAC_SHA1_80);
+ add(SrtpCryptoSuite.AES_CM_128_HMAC_SHA1_32);
+ add(SrtpCryptoSuite.F8_128_HMAC_SHA1_80);
+ }};
+
+ private final List<String> supportedCryptoSuites = new ArrayList<String>(3)
+ {{
+ add(SrtpCryptoSuite.AES_CM_128_HMAC_SHA1_80);
+ add(SrtpCryptoSuite.AES_CM_128_HMAC_SHA1_32);
+ add(SrtpCryptoSuite.F8_128_HMAC_SHA1_80);
+ }};
+
private SrtpSDesFactory sdesFactory = new SrtpSDesFactory();
private SrtpCryptoAttribute[] attributes;
private SDesTransformEngine engine;
private SrtpCryptoAttribute selectedInAttribute;
private SrtpCryptoAttribute selectedOutAttribute;
+ private SrtpListener srtpListener;
- public SDesControlImpl()
+ public void setEnabledCiphers(Iterable<String> ciphers)
{
+ enabledCryptoSuites.clear();
+ for(String c : ciphers)
+ enabledCryptoSuites.add(c);
+ }
+
+ public Iterable<String> getSupportedCryptoSuites()
+ {
+ return Collections.unmodifiableList(supportedCryptoSuites);
}
public void cleanup()
{
}
- public void setZrtpListener(SrtpListener zrtpListener)
+ public void setSrtpListener(SrtpListener srtpListener)
{
+ this.srtpListener = srtpListener;
}
public SrtpListener getSrtpListener()
{
- return null;
+ return srtpListener;
}
public boolean getSecureCommunicationStatus()
@@ -50,6 +76,11 @@ public class SDesControlImpl public void start(boolean masterSession)
{
+ srtpListener.securityTurnedOn(
+ masterSession ?
+ CallPeerSecurityStatusEvent.AUDIO_SESSION :
+ CallPeerSecurityStatusEvent.VIDEO_SESSION,
+ selectedInAttribute.getCryptoSuite().encode(), null, true, null);
}
public void setMultistream(byte[] multiStreamData)
@@ -65,12 +96,15 @@ public class SDesControlImpl public String[] getInitiatorCryptoAttributes()
{
- attributes = new SrtpCryptoAttribute[supportedCryptoSuites.length];
- for (int i = 0; i < attributes.length; i++)
+ if(attributes == null)
{
- attributes[i] =
- sdesFactory.createCryptoAttribute(i + 1,
- supportedCryptoSuites[i]);
+ attributes = new SrtpCryptoAttribute[enabledCryptoSuites.size()];
+ for (int i = 0; i < attributes.length; i++)
+ {
+ attributes[i] =
+ sdesFactory.createCryptoAttribute(i + 1,
+ enabledCryptoSuites.get(i));
+ }
}
String[] result = new String[attributes.length];
for(int i = 0; i < attributes.length; i++)
@@ -78,9 +112,9 @@ public class SDesControlImpl return result;
}
- public String responderSelectAttribute(String[] peerAttributes)
+ public String responderSelectAttribute(Iterable<String> peerAttributes)
{
- for (String suite : supportedCryptoSuites)
+ for (String suite : enabledCryptoSuites)
{
for (String ea : peerAttributes)
{
@@ -97,7 +131,7 @@ public class SDesControlImpl return null;
}
- public void initiatorSelectAttribute(String[] peerAttributes)
+ public boolean initiatorSelectAttribute(Iterable<String> peerAttributes)
{
for (SrtpCryptoAttribute localCA : attributes)
{
@@ -108,10 +142,11 @@ public class SDesControlImpl {
selectedInAttribute = peerCA;
selectedOutAttribute = localCA;
- return;
+ return true;
}
}
}
+ return false;
}
public SrtpCryptoAttribute getInAttribute()
diff --git a/src/net/java/sip/communicator/impl/neomedia/ZrtpControlImpl.java b/src/net/java/sip/communicator/impl/neomedia/ZrtpControlImpl.java index bafe48b..ae1d8e4 100644 --- a/src/net/java/sip/communicator/impl/neomedia/ZrtpControlImpl.java +++ b/src/net/java/sip/communicator/impl/neomedia/ZrtpControlImpl.java @@ -78,7 +78,7 @@ public class ZrtpControlImpl * * @param zrtpListener the <tt>ZrtpListener</tt> to set */ - public void setZrtpListener(SrtpListener zrtpListener) + public void setSrtpListener(SrtpListener zrtpListener) { this.zrtpListener = zrtpListener; } diff --git a/src/net/java/sip/communicator/impl/neomedia/transform/sdes/SDesTransformEngine.java b/src/net/java/sip/communicator/impl/neomedia/transform/sdes/SDesTransformEngine.java index 92412d6..dba4af1 100644 --- a/src/net/java/sip/communicator/impl/neomedia/transform/sdes/SDesTransformEngine.java +++ b/src/net/java/sip/communicator/impl/neomedia/transform/sdes/SDesTransformEngine.java @@ -6,6 +6,11 @@ import net.java.sip.communicator.impl.neomedia.*; import net.java.sip.communicator.impl.neomedia.transform.*;
import net.java.sip.communicator.impl.neomedia.transform.srtp.*;
+/**
+ * PacketTransformer for SDES based SRTP encryption.
+ *
+ * @author Ingo Bauersachs
+ */
public class SDesTransformEngine
implements TransformEngine, PacketTransformer
{
@@ -14,6 +19,10 @@ public class SDesTransformEngine private SrtpCryptoAttribute inAttribute;
private SrtpCryptoAttribute outAttribute;
+ /**
+ * Creates a new instance of this class.
+ * @param sDesControl The control that supplies the key material.
+ */
public SDesTransformEngine(SDesControlImpl sDesControl)
{
inAttribute = sDesControl.getInAttribute();
@@ -53,11 +62,23 @@ public class SDesTransformEngine return salt;
}
+ /*
+ * (non-Javadoc)
+ *
+ * @see net.java.sip.communicator.impl.neomedia.transform.TransformEngine#
+ * getRTPTransformer()
+ */
public PacketTransformer getRTPTransformer()
{
return this;
}
+ /*
+ * (non-Javadoc)
+ *
+ * @see net.java.sip.communicator.impl.neomedia.transform.TransformEngine#
+ * getRTCPTransformer()
+ */
public PacketTransformer getRTCPTransformer()
{
return null;
@@ -70,23 +91,23 @@ public class SDesTransformEngine SrtpCryptoSuite cs = attribute.getCryptoSuite();
switch (cs.getEncryptionAlgorithm())
{
- case SrtpCryptoSuite.ENCRYPTION_AES128_CM:
- encType = SRTPPolicy.AESCM_ENCRYPTION;
- break;
- case SrtpCryptoSuite.ENCRYPTION_AES128_F8:
- encType = SRTPPolicy.AESF8_ENCRYPTION;
- break;
- default:
- throw new IllegalArgumentException("Unsupported cipher");
+ case SrtpCryptoSuite.ENCRYPTION_AES128_CM:
+ encType = SRTPPolicy.AESCM_ENCRYPTION;
+ break;
+ case SrtpCryptoSuite.ENCRYPTION_AES128_F8:
+ encType = SRTPPolicy.AESF8_ENCRYPTION;
+ break;
+ default:
+ throw new IllegalArgumentException("Unsupported cipher");
}
int authType;
switch (cs.getHashAlgorithm())
{
- case SrtpCryptoSuite.HASH_HMAC_SHA1:
- authType = SRTPPolicy.HMACSHA1_AUTHENTICATION;
- break;
- default:
- throw new IllegalArgumentException("Unsupported hash");
+ case SrtpCryptoSuite.HASH_HMAC_SHA1:
+ authType = SRTPPolicy.HMACSHA1_AUTHENTICATION;
+ break;
+ default:
+ throw new IllegalArgumentException("Unsupported hash");
}
SRTPPolicy policy =
new SRTPPolicy(
@@ -103,6 +124,13 @@ public class SDesTransformEngine );
}
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * net.java.sip.communicator.impl.neomedia.transform.PacketTransformer
+ * #transform(net.java.sip.communicator.impl.neomedia.RawPacket)
+ */
public RawPacket transform(RawPacket pkt)
{
if (outContext == null)
@@ -115,6 +143,12 @@ public class SDesTransformEngine return pkt;
}
+ /*
+ * (non-Javadoc)
+ *
+ * @see net.java.sip.communicator.impl.neomedia.transform.PacketTransformer#
+ * reverseTransform(net.java.sip.communicator.impl.neomedia.RawPacket)
+ */
public RawPacket reverseTransform(RawPacket pkt)
{
long ssrc = pkt.getSSRC();
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/CallPeerMediaHandlerJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/CallPeerMediaHandlerJabberImpl.java index 2293e41..28ca62f 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/CallPeerMediaHandlerJabberImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/jabber/CallPeerMediaHandlerJabberImpl.java @@ -343,12 +343,14 @@ public class CallPeerMediaHandlerJabberImpl // ZRTP if(getPeer().getCall().isSipZrtpAttribute()) { - SrtpControl control = getZrtpControls().get(mediaType); - if(control == null || !(control instanceof ZrtpControl)) + MediaTypeSrtpControl key = + new MediaTypeSrtpControl(mediaType, SrtpControlType.ZRTP); + SrtpControl control = getSrtpControls().get(key); + if(control == null) { control = JabberActivator.getMediaService() .createZrtpControl(); - getZrtpControls().put(mediaType, control); + getSrtpControls().put(key, control); } String helloHash[] = ((ZrtpControl)control).getHelloHashSep(); @@ -550,13 +552,15 @@ public class CallPeerMediaHandlerJabberImpl //ZRTP if(getPeer().getCall().isSipZrtpAttribute()) { - SrtpControl control = getZrtpControls().get(dev.getMediaType()); - - if(control == null || !(control instanceof ZrtpControl)) + MediaTypeSrtpControl key = + new MediaTypeSrtpControl(dev.getMediaType(), + SrtpControlType.ZRTP); + SrtpControl control = getSrtpControls().get(key); + if(control == null) { control = JabberActivator.getMediaService().createZrtpControl(); - getZrtpControls().put(dev.getMediaType(), control); + getSrtpControls().put(key, control); } String helloHash[] = ((ZrtpControl)control).getHelloHashSep(); @@ -689,12 +693,15 @@ public class CallPeerMediaHandlerJabberImpl //ZRTP if(getPeer().getCall().isSipZrtpAttribute()) { - SrtpControl control = getZrtpControls().get(mediaType); - if(control == null || !(control instanceof ZrtpControl)) + MediaTypeSrtpControl key = + new MediaTypeSrtpControl(mediaType, + SrtpControlType.ZRTP); + SrtpControl control = getSrtpControls().get(key); + if(control == null) { control = JabberActivator.getMediaService() .createZrtpControl(); - getZrtpControls().put(mediaType, control); + getSrtpControls().put(key, control); } String helloHash[] = diff --git a/src/net/java/sip/communicator/impl/protocol/sip/CallPeerMediaHandlerSipImpl.java b/src/net/java/sip/communicator/impl/protocol/sip/CallPeerMediaHandlerSipImpl.java index 0798cef..d20a497 100644 --- a/src/net/java/sip/communicator/impl/protocol/sip/CallPeerMediaHandlerSipImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/sip/CallPeerMediaHandlerSipImpl.java @@ -47,12 +47,6 @@ public class CallPeerMediaHandlerSipImpl private SessionDescription localSess = null; /** - * The last ( and maybe only ) session description that we received from - * the remote party. - */ - private SessionDescription remoteSess = null; - - /** * A <tt>URL</tt> pointing to a location with call information or a call * control web interface related to the <tt>CallPeer</tt> that we are * associated with. @@ -179,19 +173,23 @@ public class CallPeerMediaHandlerSipImpl { MediaDevice dev = getDefaultDevice(mediaType); - if (dev != null) - { - MediaDirection direction = dev.getDirection().and( - getDirectionUserPreference(mediaType)); + if (dev == null) + continue; - if(isLocallyOnHold()) - direction = direction.and(MediaDirection.SENDONLY); + MediaDirection direction = dev.getDirection().and( + getDirectionUserPreference(mediaType)); - if(direction != MediaDirection.INACTIVE) + if(isLocallyOnHold()) + direction = direction.and(MediaDirection.SENDONLY); + + if(direction != MediaDirection.INACTIVE) + { + boolean hadSavp = false; + for (String profileName : getRtpTransports()) { MediaDescription md = createMediaDescription( - true, //TODO base on settings + profileName, dev.getSupportedFormats( sendQualityPreset, receiveQualityPreset), @@ -216,10 +214,16 @@ public class CallPeerMediaHandlerSipImpl // do nothing in case of error. } - //updateMediaDescriptionForZrtp(mediaType, md); //TODO: base on setting - updateMediaDescriptionForSDes(mediaType, md, null); + if(!hadSavp) + { + updateMediaDescriptionForZrtp(mediaType, md); + updateMediaDescriptionForSDes(mediaType, md, null); + } mediaDescs.add(md); + + if(!hadSavp && profileName.contains("SAVP")) + hadSavp = true; } } } @@ -321,8 +325,6 @@ public class CallPeerMediaHandlerSipImpl throws OperationFailedException, IllegalArgumentException { - this.remoteSess = offer; - Vector<MediaDescription> answerDescriptions = createMediaDescriptionsForAnswer(offer); @@ -358,8 +360,6 @@ public class CallPeerMediaHandlerSipImpl throws OperationFailedException, IllegalArgumentException { - this.remoteSess = newOffer; - Vector<MediaDescription> answerDescriptions = createMediaDescriptionsForAnswer(newOffer); @@ -403,12 +403,17 @@ public class CallPeerMediaHandlerSipImpl boolean atLeastOneValidDescription = false; + List<MediaType> seenMediaTypes = new ArrayList<MediaType>(); for (MediaDescription mediaDescription : remoteDescriptions) { MediaType mediaType = null; try { mediaType = SdpUtils.getMediaType(mediaDescription); + //don't process a second media of the same type + if(seenMediaTypes.contains(mediaType)) + continue; + seenMediaTypes.add(mediaType); } catch (IllegalArgumentException iae) { @@ -524,11 +529,23 @@ public class CallPeerMediaHandlerSipImpl } } - MediaDescription md = createMediaDescription(true, //TODO base on settings - mutuallySupportedFormats, connector, direction, rtpExtensions); + MediaDescription md; + try + { + md = + createMediaDescription(mediaDescription.getMedia() + .getProtocol(), mutuallySupportedFormats, connector, + direction, rtpExtensions); + } + catch (SdpParseException e) + { + throw new OperationFailedException( + "unable to create the media description", + OperationFailedException.ILLEGAL_ARGUMENT, e); + } - //updateMediaDescriptionForZrtp(mediaType, md); //TODO base on setting - updateMediaDescriptionForSDes(mediaType, md, mediaDescription); + if(!updateMediaDescriptionForSDes(mediaType, md, mediaDescription)) + updateMediaDescriptionForZrtp(mediaType, md); // create the corresponding stream... MediaFormat fmt = findMediaFormat(remoteFormats, @@ -562,12 +579,14 @@ public class CallPeerMediaHandlerSipImpl { try { - SrtpControl scontrol = getZrtpControls().get(mediaType); - if(scontrol == null || !(scontrol instanceof ZrtpControl)) + MediaTypeSrtpControl key = + new MediaTypeSrtpControl(mediaType, SrtpControlType.ZRTP); + SrtpControl scontrol = getSrtpControls().get(key); + if(scontrol == null) { scontrol = SipActivator.getMediaService() .createZrtpControl(); - getZrtpControls().put(mediaType, scontrol); + getSrtpControls().put(key, scontrol); } ZrtpControl zcontrol = (ZrtpControl) scontrol; @@ -587,72 +606,139 @@ public class CallPeerMediaHandlerSipImpl * Updates the supplied description with SDES attributes if necessary. * * @param mediaType the media type. - * @param localMd the description to be updated. - * @param peerMd - * @throws OperationFailedException + * @param localMd the description of the local peer. + * @param peerMd the description of the remote peer. */ @SuppressWarnings("unchecked") //jain-sip legacy - private void updateMediaDescriptionForSDes( + private boolean updateMediaDescriptionForSDes( MediaType mediaType, MediaDescription localMd, MediaDescription peerMd) - throws OperationFailedException { - //if(getPeer().getCall().isSipZrtpAttribute()) //TODO: check SDES config + //check if SDES is enabled at all + if (!getPeer() + .getProtocolProvider() + .getAccountID() + .getAccountPropertyBoolean( + ProtocolProviderServiceSipImpl.SDES_ENABLED, true)) + { + return false; + } + + // get or create the control + MediaTypeSrtpControl key = + new MediaTypeSrtpControl(mediaType, SrtpControlType.SDES); + SrtpControl scontrol = getSrtpControls().get(key); + if (scontrol == null) + { + scontrol = SipActivator.getMediaService().createSDesControl(); + getSrtpControls().put(key, scontrol); + } + + // set the enabled ciphers suites + SDesControl sdcontrol = (SDesControl) scontrol; + String ciphers = + getPeer() + .getProtocolProvider() + .getAccountID() + .getAccountPropertyString( + ProtocolProviderServiceSipImpl.SDES_CIPHER_SUITES); + if (ciphers == null) { - SrtpControl scontrol = getZrtpControls().get(mediaType); - if (scontrol == null || !(scontrol instanceof SDesControl)) + ciphers = + SipActivator.getResources().getSettingsString( + SDesControl.SDES_CIPHER_SUITES); + } + sdcontrol.setEnabledCiphers(Arrays.asList(ciphers.split(","))); + + // act as initiator + if (peerMd == null) + { + Vector<Attribute> atts = localMd.getAttributes(true); + for (String ca : sdcontrol.getInitiatorCryptoAttributes()) { - scontrol = SipActivator.getMediaService().createSDesControl(); - getZrtpControls().put(mediaType, scontrol); + Attribute a = SdpUtils.createAttribute("crypto", ca); + atts.add(a); } - SDesControl sdcontrol = (SDesControl) scontrol; - if (peerMd == null) + return true; + } + // act as responder + else + { + Vector<Attribute> atts = peerMd.getAttributes(true); + List<String> peerAttributes = new LinkedList<String>(); + for (Attribute a : atts) { - Vector<Attribute> atts = localMd.getAttributes(true); - for (String ca : sdcontrol.getInitiatorCryptoAttributes()) + try + { + if (a.getName().equals("crypto")) + { + peerAttributes.add(a.getValue()); + } + } + catch (SdpParseException e) { - Attribute a = SdpUtils.createAttribute("crypto", ca); - atts.add(a); + logger.error("received an uparsable sdp attribute", e); } } - else + if (peerAttributes.size() > 0) { - Vector<Attribute> atts = peerMd.getAttributes(true); - List<String> peerAttributes = new LinkedList<String>(); - for (Attribute a : atts) + String localAttr = + sdcontrol.responderSelectAttribute(peerAttributes); + if (localAttr != null) { try { - if (a.getName().equals("crypto")) - { - peerAttributes.add(a.getValue()); - } + localMd.setAttribute("crypto", localAttr); + return true; } - catch (SdpParseException e) + catch (SdpException e) { - logger.error("received an uparsable sdp attribute", e); + logger.error("unable to add crypto to answer", e); } } - if (peerAttributes.size() > 0) + else { - String localAttr = - sdcontrol.responderSelectAttribute(peerAttributes - .toArray(new String[peerAttributes.size()])); - if(localAttr != null) - { - try - { - localMd.setAttribute("crypto", localAttr); - } - catch (SdpException e) - { - logger.error("unable to add crypto to answer", e); - } - } + // none of the offered suites match, destroy the sdes + // control + getSrtpControls().remove(key); + logger.warn("Received unsupported sdes crypto attribute " + + peerAttributes.toString()); } } + else + { + // peer doesn't offer any SDES attribute, destroy the sdes + // control + getSrtpControls().remove(key); + } + return false; } } + private List<String> getRtpTransports() throws OperationFailedException + { + List<String> result = new ArrayList<String>(2); + int savpOption = + getPeer() + .getProtocolProvider() + .getAccountID() + .getAccountPropertyInt( + ProtocolProviderServiceSipImpl.SAVP_OPTION, + ProtocolProviderServiceSipImpl.SAVP_OFF); + if(savpOption == ProtocolProviderServiceSipImpl.SAVP_MANDATORY) + result.add("RTP/SAVP"); + else if(savpOption == ProtocolProviderServiceSipImpl.SAVP_OFF) + result.add(SdpConstants.RTP_AVP); + else if(savpOption == ProtocolProviderServiceSipImpl.SAVP_OPTIONAL) + { + result.add("RTP/SAVP"); + result.add(SdpConstants.RTP_AVP); + } + else + throw new OperationFailedException("invalid value for SAVP_OPTION", + OperationFailedException.GENERAL_ERROR); + return result; + } + /** * Handles the specified <tt>answer</tt> by creating and initializing the * corresponding <tt>MediaStream</tt>s. @@ -690,19 +776,22 @@ public class CallPeerMediaHandlerSipImpl throws OperationFailedException, IllegalArgumentException { - this.remoteSess = answer; - List<MediaDescription> remoteDescriptions = SdpUtils.extractMediaDescriptions(answer); this.setCallInfoURL(SdpUtils.getCallInfoURL(answer)); - for ( MediaDescription mediaDescription : remoteDescriptions) + List<MediaType> seenMediaTypes = new ArrayList<MediaType>(); + for (MediaDescription mediaDescription : remoteDescriptions) { MediaType mediaType; try { mediaType = SdpUtils.getMediaType(mediaDescription); + //don't process a second media of the same type + if(seenMediaTypes.contains(mediaType)) + continue; + seenMediaTypes.add(mediaType); } catch(IllegalArgumentException iae) { @@ -787,8 +876,10 @@ public class CallPeerMediaHandlerSipImpl } // select the crypto key the peer has chosen from our proposal - SrtpControl scontrol = getZrtpControls().get(mediaType); - if(scontrol != null && scontrol instanceof SDesControl) + MediaTypeSrtpControl key = + new MediaTypeSrtpControl(mediaType, SrtpControlType.SDES); + SrtpControl scontrol = getSrtpControls().get(key); + if(scontrol != null) { List<String> peerAttributes = new LinkedList<String>(); @SuppressWarnings("unchecked") @@ -807,9 +898,28 @@ public class CallPeerMediaHandlerSipImpl logger.error("received an uparsable sdp attribute", e); } } - ((SDesControl) scontrol) - .initiatorSelectAttribute(peerAttributes - .toArray(new String[peerAttributes.size()])); + if(!((SDesControl) scontrol) + .initiatorSelectAttribute(peerAttributes)) + { + getSrtpControls().remove(key); + if(peerAttributes.size() > 0) + logger + .warn("Received unsupported sdes crypto attribute: " + + peerAttributes); + } + else + { + //found an SDES answer, remove all other controls + Iterator<MediaTypeSrtpControl> it = + getSrtpControls().keySet().iterator(); + while (it.hasNext()) + { + MediaTypeSrtpControl mtc = it.next(); + if (mtc.mediaType == mediaType + && mtc.srtpControlType != SrtpControlType.SDES) + it.remove(); + } + } } // create the corresponding stream... @@ -835,7 +945,7 @@ public class CallPeerMediaHandlerSipImpl * taking account the local streaming preference for the corresponding * media type. * - * @param secure when true, the profile is RTP/SAVP instead of RTP/AVP + * @param transport the profile name (RTP/SAVP or RTP/AVP) * @param formats the list of <tt>MediaFormats</tt> that we'd like to * advertise. * @param connector the <tt>StreamConnector</tt> that we will be using @@ -852,14 +962,14 @@ public class CallPeerMediaHandlerSipImpl * <tt>MediaDescription</tt> fails for some reason. */ private MediaDescription createMediaDescription( - boolean secure, + String transport, List<MediaFormat> formats, StreamConnector connector, MediaDirection direction, List<RTPExtension> extensions ) throws OperationFailedException { - return SdpUtils.createMediaDescription(secure, formats, connector, + return SdpUtils.createMediaDescription(transport, formats, connector, direction, extensions, getDynamicPayloadTypes(), getRtpExtensionsRegistry()); } diff --git a/src/net/java/sip/communicator/impl/protocol/sip/ProtocolProviderServiceSipImpl.java b/src/net/java/sip/communicator/impl/protocol/sip/ProtocolProviderServiceSipImpl.java index 940d3a1..dca666f 100644 --- a/src/net/java/sip/communicator/impl/protocol/sip/ProtocolProviderServiceSipImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/sip/ProtocolProviderServiceSipImpl.java @@ -159,7 +159,7 @@ public class ProtocolProviderServiceSipImpl /** * The name of the property under which the user may specify whether to use - * original sip creadetials for the XCAP. + * original sip credentials for the XCAP. */ public static final String XCAP_USE_SIP_CREDETIALS = "XCAP_USE_SIP_CREDETIALS"; @@ -182,6 +182,43 @@ public class ProtocolProviderServiceSipImpl public static final String XCAP_PASSWORD = "XCAP_PASSWORD"; /** + * The name of the property that indicates if SDES is enabled for this + * account. + */ + public static final String SDES_ENABLED = "SDES_ENABLED"; + + /** + * The name of the property that defines the enabled SDES cipher suites. + * Enabled suites are listed as CSV by their RFC name. + */ + public static final String SDES_CIPHER_SUITES = "SDES_CIPHER_SUITES"; + + /** + * The name of the property that indicates the AVP type. + * <ul> + * <li>{@link #SAVP_OPTION_AVP}</li> + * <li>{@link #SAVP_OPTION_SAVP}</li> + * <li>{@link #SAVP_OPTION_AVP_OR_SAVP}</li> + * </ul> + */ + public static final String SAVP_OPTION = "SAVP_OPTION"; + + /** + * Always use RTP/AVP + */ + public static final int SAVP_OFF = 0; + + /** + * Always use RTP/SAVP + */ + public static final int SAVP_MANDATORY = 1; + + /** + * Sends two media description, with RTP/SAVP being first. + */ + public static final int SAVP_OPTIONAL = 2; + + /** * Presence content for image. */ public static final String PRES_CONTENT_IMAGE_NAME = "sip_communicator"; diff --git a/src/net/java/sip/communicator/impl/protocol/sip/sdp/SdpUtils.java b/src/net/java/sip/communicator/impl/protocol/sip/sdp/SdpUtils.java index a3f8c77..7796b1c 100644 --- a/src/net/java/sip/communicator/impl/protocol/sip/sdp/SdpUtils.java +++ b/src/net/java/sip/communicator/impl/protocol/sip/sdp/SdpUtils.java @@ -1284,7 +1284,7 @@ public class SdpUtils * description is determined via from the type of the first * <tt>MediaFormat</tt> in the <tt>formats</tt> list. * - * @param secure when true, the profile is RTP/SAVP instead of RTP/AVP + * @param transport the profile name (RTP/SAVP or RTP/AVP) * @param formats the list of formats that should be advertised in the newly * created <tt>MediaDescription</tt>. * @param connector the socket couple that will be used for the media stream @@ -1307,7 +1307,7 @@ public class SdpUtils * some other reason. */ public static MediaDescription createMediaDescription( - boolean secure, + String transport, List<MediaFormat> formats, StreamConnector connector, MediaDirection direction, @@ -1437,8 +1437,7 @@ public class SdpUtils { mediaDesc = sdpFactory.createMediaDescription(mediaType.toString(), connector.getDataSocket().getLocalPort(), 1, - secure ? "RTP/SAVP" : SdpConstants.RTP_AVP, - payloadTypesArray); + transport, payloadTypesArray); // add all the attributes we have created above mediaDesc.setAttributes(mediaAttributes); diff --git a/src/net/java/sip/communicator/service/neomedia/MediaStream.java b/src/net/java/sip/communicator/service/neomedia/MediaStream.java index 2487a71..5c9b65a 100644 --- a/src/net/java/sip/communicator/service/neomedia/MediaStream.java +++ b/src/net/java/sip/communicator/service/neomedia/MediaStream.java @@ -319,5 +319,5 @@ public interface MediaStream * * @return the <tt>ZrtpControl</tt> which controls the ZRTP for this stream */ - public SrtpControl getZrtpControl(); + public SrtpControl getSrtpControl(); } diff --git a/src/net/java/sip/communicator/service/neomedia/MediaTypeSrtpControl.java b/src/net/java/sip/communicator/service/neomedia/MediaTypeSrtpControl.java new file mode 100644 index 0000000..b4c6bbe --- /dev/null +++ b/src/net/java/sip/communicator/service/neomedia/MediaTypeSrtpControl.java @@ -0,0 +1,65 @@ +package net.java.sip.communicator.service.neomedia;
+
+public class MediaTypeSrtpControl implements Comparable<MediaTypeSrtpControl>
+{
+ public MediaType mediaType;
+ public SrtpControlType srtpControlType;
+
+ public MediaTypeSrtpControl(MediaType mt, SrtpControlType sct)
+ {
+ mediaType = mt;
+ srtpControlType = sct;
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ if(obj == null || obj.getClass() != MediaTypeSrtpControl.class)
+ return false;
+
+ MediaTypeSrtpControl other = (MediaTypeSrtpControl)obj;
+ return mediaType == other.mediaType && srtpControlType == other.srtpControlType;
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return mediaType.hashCode() ^ srtpControlType.hashCode();
+ }
+
+ public int compareTo(MediaTypeSrtpControl o)
+ {
+ return getWeight() == o.getWeight() ?
+ 0 :
+ getWeight() < o.getWeight() ?
+ -1 : 1;
+ }
+
+ private int getWeight()
+ {
+ int mtWeight = 0;
+ switch(mediaType)
+ {
+ case AUDIO:
+ mtWeight = 1;
+ break;
+ case VIDEO:
+ mtWeight = 2;
+ break;
+ }
+ int stWeight = 0;
+ switch(srtpControlType)
+ {
+ case ZRTP:
+ stWeight = 1;
+ break;
+ case MIKEY:
+ stWeight = 2;
+ break;
+ case SDES:
+ stWeight = 3;
+ break;
+ }
+ return mtWeight * 10 + stWeight;
+ }
+}
diff --git a/src/net/java/sip/communicator/service/neomedia/SDesControl.java b/src/net/java/sip/communicator/service/neomedia/SDesControl.java index 6f7e285..d7e6b2c 100644 --- a/src/net/java/sip/communicator/service/neomedia/SDesControl.java +++ b/src/net/java/sip/communicator/service/neomedia/SDesControl.java @@ -2,12 +2,73 @@ package net.java.sip.communicator.service.neomedia; import ch.imvs.sdes4j.srtp.SrtpCryptoAttribute;
+/**
+ * SDES based SRTP MediaStream encryption control.
+ *
+ * @author Ingo Bauersachs
+ */
public interface SDesControl
extends SrtpControl
{
+ /**
+ * Name of the config setting that supplies the default enabled cipher
+ * suites. Cipher suites are comma-separated.
+ */
+ public static final String SDES_CIPHER_SUITES =
+ "net.java.sip.communicator.service.neomedia.SDES_CIPHER_SUITES";
+
+ /**
+ * Set the enabled SDES ciphers.
+ *
+ * @param ciphers The list of enabled ciphers.
+ */
+ public void setEnabledCiphers(Iterable<String> ciphers);
+
+ /**
+ * Gets all supported cipher suites.
+ *
+ * @return all supported cipher suites.
+ */
+ public Iterable<String> getSupportedCryptoSuites();
+
+ /**
+ * Gets the encoded SDES crypto-attributes for all enabled ciphers when the
+ * control is used as the initiator.
+ *
+ * @return the encoded SDES crypto-attributes for all enabled ciphers.
+ */
public String[] getInitiatorCryptoAttributes();
- public String responderSelectAttribute(String[] peerAttributes);
- public void initiatorSelectAttribute(String[] peerAttributes);
+
+ /**
+ * Chooses a supported crypto attribute from the peer's list of supplied
+ * attributes and creates the local crypto attribute. Used when the control
+ * is running in the role as responder.
+ *
+ * @param peerAttributes The peer's crypto attribute offering.
+ * @return The local crypto attribute for the answer of the offer or null if
+ * no matching cipher suite could be found.
+ */
+ public String responderSelectAttribute(Iterable<String> peerAttributes);
+
+ /**
+ * Select the local crypto attribute from the initial offering (@see
+ * {@link #getInitiatorCryptoAttributes()}) based on the peer's first
+ * matching cipher suite.
+ *
+ * @param peerAttributes The peer's crypto offers.
+ * @return True when a matching cipher suite was found, false otherwise.
+ */
+ public boolean initiatorSelectAttribute(Iterable<String> peerAttributes);
+
+ /**
+ * Gets the crypto attribute of the incoming MediaStream.
+ * @return the crypto attribute of the incoming MediaStream.
+ */
public SrtpCryptoAttribute getInAttribute();
+
+ /**
+ * Gets the crypto attribute of the outgoing MediaStream.
+ * @return the crypto attribute of the outgoing MediaStream.
+ */
public SrtpCryptoAttribute getOutAttribute();
}
diff --git a/src/net/java/sip/communicator/service/neomedia/SrtpControl.java b/src/net/java/sip/communicator/service/neomedia/SrtpControl.java index 3df982b..64503a3 100644 --- a/src/net/java/sip/communicator/service/neomedia/SrtpControl.java +++ b/src/net/java/sip/communicator/service/neomedia/SrtpControl.java @@ -11,29 +11,29 @@ import net.java.sip.communicator.impl.neomedia.transform.TransformEngine; import net.java.sip.communicator.service.neomedia.event.*; /** - * Controls zrtp in the MediaStream. + * Controls SRTP encryption in the MediaStream. * * @author Damian Minkov */ public interface SrtpControl { /** - * Cleans up the current zrtp control and its engine. + * Cleans up the current SRTP control and its engine. */ public void cleanup(); /** - * Sets a <tt>ZrtpListener</tt> that will listen for - * zrtp security events. + * Sets a <tt>SrtpListener</tt> that will listen for + * srtp security events. * - * @param zrtpListener the <tt>ZrtpListener</tt> to set + * @param srtpListener the <tt>SrtpListener</tt> to set */ - public void setZrtpListener(SrtpListener zrtpListener); + public void setSrtpListener(SrtpListener srtpListener); /** - * Returns the <tt>ZrtpListener</tt> which listens for security events. + * Returns the <tt>SrtpListener</tt> which listens for security events. * - * @return the <tt>ZrtpListener</tt> which listens for security events + * @return the <tt>SrtpListener</tt> which listens for security events */ public SrtpListener getSrtpListener(); @@ -76,5 +76,11 @@ public interface SrtpControl */ public TransformEngine getTransformEngine(); + /** + * Sets the <tt>RTPConnector</tt> which is to use or uses this SRTP engine. + * + * @param connector the <tt>RTPConnector</tt> which is to use or uses this + * SRTP engine + */ public void setConnector(AbstractRTPConnector newValue); } diff --git a/src/net/java/sip/communicator/service/neomedia/SrtpControlType.java b/src/net/java/sip/communicator/service/neomedia/SrtpControlType.java new file mode 100644 index 0000000..dbaa70c --- /dev/null +++ b/src/net/java/sip/communicator/service/neomedia/SrtpControlType.java @@ -0,0 +1,25 @@ +package net.java.sip.communicator.service.neomedia;
+
+/**
+ * The <tt>SrtpControlType</tt> enumeration contains all currently known
+ * <tt>SrtpControl</tt> implementations.
+ *
+ * @author Ingo Bauersachs
+ */
+public enum SrtpControlType
+{
+ /**
+ * Session Description Protocol (SDP) Security Descriptions for Media Streams (RFC 4568)
+ */
+ SDES,
+
+ /**
+ * ZRTP: Media Path Key Agreement for Unicast Secure RTP (RFC 6189)
+ */
+ ZRTP,
+
+ /**
+ * Multimedia Internet KEYing (RFC 3830)
+ */
+ MIKEY
+}
diff --git a/src/net/java/sip/communicator/service/protocol/media/CallPeerMediaHandler.java b/src/net/java/sip/communicator/service/protocol/media/CallPeerMediaHandler.java index f67b6f0..7d29b8d 100644 --- a/src/net/java/sip/communicator/service/protocol/media/CallPeerMediaHandler.java +++ b/src/net/java/sip/communicator/service/protocol/media/CallPeerMediaHandler.java @@ -94,10 +94,10 @@ public abstract class CallPeerMediaHandler< private final T peer; /** - * A reference to the object that would be responsible for ZRTP control + * A reference to the object that would be responsible for SRTP control * and which most often would be the peer itself. */ - public final SrtpListener zrtpController; + public final SrtpListener srtpListener; /** * The RTP stream that this media handler uses to send audio. @@ -191,10 +191,10 @@ public abstract class CallPeerMediaHandler< = new DynamicRTPExtensionsRegistry(); /** - * Holds the ZRTP controls used for the current call. + * Holds the SRTP controls used for the current call. */ - private Map<MediaType, SrtpControl> srtpControls = - new Hashtable<MediaType, SrtpControl>(); + private SortedMap<MediaTypeSrtpControl, SrtpControl> srtpControls = + new TreeMap<MediaTypeSrtpControl, SrtpControl>(); /** * The <tt>KeyFrameControl</tt> currently known to this @@ -330,14 +330,13 @@ public abstract class CallPeerMediaHandler< * * @param peer that <tt>CallPeer</tt> instance that we will be managing * media for. - * @param zrtpController the object that would be responsible for - * controlling zrtp, and which most often would be the peer itself. + * @param srtpListener the object that receives SRTP security events. */ public CallPeerMediaHandler(T peer, - SrtpListener zrtpController) + SrtpListener srtpListener) { this.peer = peer; - this.zrtpController = zrtpController; + this.srtpListener = srtpListener; } /** @@ -415,20 +414,23 @@ public abstract class CallPeerMediaHandler< */ protected void closeStream(MediaType type) { - if( type == MediaType.AUDIO) + if (type == MediaType.AUDIO) setAudioStream(null); else setVideoStream(null); getTransportManager().closeStreamConnector(type); - // Clear the ZRTP controls used for the associated Call. - SrtpControl zrtpCtrl = srtpControls.get(type); - - if (zrtpCtrl != null) + // Clear the SRTP controls used for the associated Call. + Iterator<MediaTypeSrtpControl> it = srtpControls.keySet().iterator(); + while (it.hasNext()) { - zrtpCtrl.cleanup(); - srtpControls.remove(type); + MediaTypeSrtpControl mct = it.next(); + if (mct.mediaType == type) + { + srtpControls.get(mct).cleanup(); + it.remove(); + } } } @@ -675,10 +677,10 @@ public abstract class CallPeerMediaHandler< public void setSasVerified(boolean isVerified ) { if(audioStream != null) - audioStream.getZrtpControl().setSASVerification(isVerified); + audioStream.getSrtpControl().setSASVerification(isVerified); if(videoStream != null) - videoStream.getZrtpControl().setSASVerification(isVerified); + videoStream.getSrtpControl().setSASVerification(isVerified); } /** @@ -694,14 +696,14 @@ public abstract class CallPeerMediaHandler< */ boolean isAudioSecured = (audioStream == null) - || audioStream.getZrtpControl().getSecureCommunicationStatus(); + || audioStream.getSrtpControl().getSecureCommunicationStatus(); if (!isAudioSecured) return false; boolean isVideoSecured = (videoStream == null) - || videoStream.getZrtpControl().getSecureCommunicationStatus(); + || videoStream.getSrtpControl().getSecureCommunicationStatus(); if (!isVideoSecured) return false; @@ -711,16 +713,16 @@ public abstract class CallPeerMediaHandler< /** * Passes <tt>multiStreamData</tt> to the video stream that we are using - * in this media handler (if any) so that the underlying ZRTP lib could + * in this media handler (if any) so that the underlying SRTP lib could * properly handle stream security. * * @param multiStreamData the data that we are supposed to pass to our * video stream. */ - public void startZrtpMultistream(byte[] multiStreamData) + public void startSrtpMultistream(byte[] multiStreamData) { if(videoStream != null) - videoStream.getZrtpControl().setMultistream(multiStreamData); + videoStream.getSrtpControl().setMultistream(multiStreamData); } /** @@ -1157,11 +1159,11 @@ public abstract class CallPeerMediaHandler< } /** - * Returns the currently valid <tt>ZrtpControls</tt> map. + * Returns the currently valid <tt>SrtpControls</tt> map. * - * @return the currently valid <tt>ZrtpControls</tt> map. + * @return the currently valid <tt>SrtpControls</tt> map. */ - protected Map<MediaType, SrtpControl> getZrtpControls() + protected Map<MediaTypeSrtpControl, SrtpControl> getSrtpControls() { return this.srtpControls; } @@ -1206,16 +1208,21 @@ public abstract class CallPeerMediaHandler< logger.trace("The media types of device and format differ."); // check whether a control already exists - SrtpControl control = srtpControls.get(mediaType); MediaService mediaService = ProtocolMediaActivator.getMediaService(); + SrtpControl control = srtpControls.size() > 0 ? + srtpControls.get(new MediaTypeSrtpControl(mediaType, + srtpControls.firstKey().srtpControlType)) : null; if(control == null) + { + // this creates the default control, currently ZRTP without + // the hello-hash stream = mediaService.createMediaStream(connector, device); + } else { - stream - = mediaService.createMediaStream( + stream = mediaService.createMediaStream( connector, device, control); } } @@ -1281,11 +1288,11 @@ public abstract class CallPeerMediaHandler< if(peer.getCall().isDefaultEncrypted()) { // we use the audio stream for master stream - // when using ZRTP multistreams. - SrtpControl zrtpControl = stream.getZrtpControl(); + // when using SRTP multistreams. + SrtpControl srtpControl = stream.getSrtpControl(); - zrtpControl.setZrtpListener(zrtpController); - zrtpControl.start(stream instanceof AudioMediaStream); + srtpControl.setSrtpListener(srtpListener); + srtpControl.start(stream instanceof AudioMediaStream); } return stream; diff --git a/src/net/java/sip/communicator/service/protocol/media/MediaAwareCallPeer.java b/src/net/java/sip/communicator/service/protocol/media/MediaAwareCallPeer.java index 9f7b9c0..33d25e6 100644 --- a/src/net/java/sip/communicator/service/protocol/media/MediaAwareCallPeer.java +++ b/src/net/java/sip/communicator/service/protocol/media/MediaAwareCallPeer.java @@ -730,7 +730,7 @@ public abstract class MediaAwareCallPeer { if(multiStreamData != null) { - getMediaHandler().startZrtpMultistream(multiStreamData); + getMediaHandler().startSrtpMultistream(multiStreamData); } fireCallPeerSecurityOnEvent( |