SDES Integration: Incoming calls work

cusax-fix
Ingo Bauersachs 14 years ago
parent 0f09a0cc4e
commit 703c3a49e7

@ -904,7 +904,7 @@
bundle-plugin-icqaccregwizz,bundle-plugin-jabberaccregwizz,
bundle-plugin-msnaccregwizz,bundle-plugin-sipaccregwizz,
bundle-plugin-yahooaccregwizz,bundle-plugin-aimaccregwizz,
bundle-httputil,bundle-plugin-spellcheck,
bundle-commons-codec,bundle-httputil,bundle-plugin-spellcheck,
bundle-version,bundle-version-impl,bundle-shutdown-timeout,
bundle-growlnotification,bundle-swingnotification,bundle-galagonotification,
bundle-sparkle, bundle-plugin-branding,
@ -918,7 +918,7 @@
bundle-jfontchooserlib,bundle-update,bundle-plugin-update,
bundle-plugin-simpleaccreg,bundle-plugin-generalconfig,
bundle-plugin-googletalkaccregwizz,bundle-argdelegation-service,
bundle-argdelegation,bundle-zrtp4j,bundle-json,
bundle-argdelegation,bundle-zrtp4j,bundle-sdes4j,bundle-json,
bundle-filehistory,bundle-metahistory,bundle-metahistory-slick,
bundle-plugin-facebookaccregwizz,bundle-plugin-ippiaccregwizz,
bundle-bouncycastle,bundle-plugin-otr,bundle-plugin-iptelaccregwizz,
@ -2019,6 +2019,18 @@ javax.swing.event, javax.swing.border"/>
</jar>
</target>
<!--BUNDLE-COMMONS-CODEC -->
<target name="bundle-commons-codec">
<jar compress="true" destfile="${bundles.dest}/commons-codec.jar"
filesetmanifest="merge">
<zipfileset src="${lib.noinst}/commons-codec-1.4.jar" prefix=""/>
<manifest>
<attribute name="System-Bundle" value="yes"/>
</manifest>
</jar>
</target>
<!--BUNDLE-HTTPUTIL -->
<target name="bundle-httputil">
<!-- Create the httputil.jar-->
@ -2029,7 +2041,6 @@ javax.swing.event, javax.swing.border"/>
<zipfileset src="${lib.noinst}/httpclient-4.1.1.jar" prefix=""/>
<zipfileset src="${lib.noinst}/httpcore-4.1.jar" prefix=""/>
<zipfileset src="${lib.noinst}/httpmime-4.1.1.jar" prefix=""/>
<zipfileset src="${lib.noinst}/commons-codec-1.4.jar" prefix=""/>
</jar>
</target>
@ -2325,6 +2336,18 @@ javax.swing.event, javax.swing.border"/>
</jar>
</target>
<!--BUNDLE-SDES4J -->
<target name="bundle-sdes4j">
<jar compress="true" destfile="${bundles.dest}/sdes4j.jar"
filesetmanifest="merge">
<zipfileset src="${lib.noinst}/sdes4j.jar" prefix=""/>
<manifest>
<attribute name="System-Bundle" value="yes"/>
</manifest>
</jar>
</target>
<!--BUNDLE-JSON -->
<target name="bundle-json">
<jar compress="true" destfile="${bundles.dest}/json.jar"

@ -78,5 +78,6 @@
<classpathentry kind="lib" path="lib/installer-exclude/libdbus-java-2.7.jar"/>
<classpathentry kind="lib" path="lib/installer-exclude/hexdump-0.2.jar"/>
<classpathentry kind="lib" path="lib/installer-exclude/unix-0.5.jar"/>
<classpathentry kind="lib" path="lib/installer-exclude/sdes4j.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>

@ -122,7 +122,7 @@
<java-data xmlns="http://www.netbeans.org/ns/freeform-project-java/2">
<compilation-unit>
<package-root>src</package-root>
<classpath mode="compile">lib/felix.jar:lib/jdic-all.jar:lib/bundle/commons-logging.jar:lib/bundle/junit.jar:lib/bundle/log4j.jar:lib/installer-exclude/aclibico-2.1.jar:lib/installer-exclude/apache-ant-1.7.0.jar:lib/installer-exclude/concurrent.jar:lib/installer-exclude/dhcp4java-1.00.jar:lib/installer-exclude/dict4j.jar:lib/installer-exclude/dnsjava.jar:lib/installer-exclude/fmj.jar:lib/installer-exclude/forms-1.2.1.jar:lib/installer-exclude/gdata-client-1.0.jar:lib/installer-exclude/gdata-client-meta-1.0.jar:lib/installer-exclude/gdata-contacts-3.0.jar:lib/installer-exclude/gdata-contacts-meta-3.0.jar:lib/installer-exclude/gdata-core-1.0.jar:lib/installer-exclude/google-collect-1.0-rc1.jar:lib/installer-exclude/httpclient-4.1.1.jar:lib/installer-exclude/httpcore-4.1.jar:lib/installer-exclude/httpmime-4.1.1.jar:lib/installer-exclude/ice4j.jar:lib/installer-exclude/jain-sdp.jar:lib/installer-exclude/jain-sip-api.jar:lib/installer-exclude/jain-sip-ri.jar:lib/installer-exclude/jcalendar-1.3.2.jar:lib/installer-exclude/jdic_misc.jar:lib/installer-exclude/jdom.jar:lib/installer-exclude/jfontchooser-1.0.5.jar:lib/installer-exclude/jmdns.jar:lib/installer-exclude/jmf.jar:lib/installer-exclude/jml-1.0b5.jar:lib/installer-exclude/jmyspell-core.jar:lib/installer-exclude/jna.jar:lib/installer-exclude/jnsapi.jar:lib/installer-exclude/joscar-client.jar:lib/installer-exclude/joscar-common.jar:lib/installer-exclude/joscar-protocol.jar:lib/installer-exclude/jsch-0.1.36.jar:lib/installer-exclude/jsocks-klea.jar:lib/installer-exclude/json-20090723.jar:lib/installer-exclude/jspeex.jar:lib/installer-exclude/junit.jar:lib/installer-exclude/laf-widget.jar:lib/installer-exclude/lcrypto-jdk16-143.jar:lib/installer-exclude/libphonenumber-2.4.jar:lib/installer-exclude/log4j-1.2.8.jar:lib/installer-exclude/lti-civil-no_s_w_t.jar:lib/installer-exclude/mac_widgets-0.9.5.jar:lib/installer-exclude/nist-sdp-1.0.jar:lib/installer-exclude/otr4j.jar:lib/installer-exclude/pircbot.jar:lib/installer-exclude/profiler4j-1.0-beta3-SC.jar:lib/installer-exclude/rome-0.9.jar:lib/installer-exclude/smack.jar:lib/installer-exclude/smackx.jar:lib/installer-exclude/swing-worker-1.2.jar:lib/installer-exclude/transparency.jar:lib/installer-exclude/weupnp-0.1.2-SNAPSHOT.jar:lib/installer-exclude/ymsg_network_v0_67.jar:lib/installer-exclude/zrtp4j-light.jar:lib/os-specific/linux/installer-exclude/jmf.jar:lib/os-specific/linux/jdic_stub.jar:lib/os-specific/mac/growl4j.jar:lib/os-specific/mac/jdic_stub.jar:lib/os-specific/mac/OrangeExtensions.jar:lib/os-specific/mac/installer-exclude/dock.jar:lib/os-specific/mac/installer-exclude/jmf.jar:lib/os-specific/solaris/jdic_stub.jar:lib/os-specific/solaris/installer-exclude/jmf.jar:lib/os-specific/windows/jdic_stub.jar:lib/os-specific/windows/installer-exclude/jmf.jar:lib/os-specific/windows/installer-exclude/jna-platform-win32.jar:lib/os-specific/windows/installer-exclude/sound.jar:lib/installer-exclude/libdbus-java-2.7.jar:lib/installer-exclude/hexdump-0.2.jar:lib/installer-exclude/unix-0.5.jar</classpath>
<classpath mode="compile">lib/felix.jar:lib/jdic-all.jar:lib/bundle/commons-logging.jar:lib/bundle/junit.jar:lib/bundle/log4j.jar:lib/installer-exclude/aclibico-2.1.jar:lib/installer-exclude/apache-ant-1.7.0.jar:lib/installer-exclude/concurrent.jar:lib/installer-exclude/dhcp4java-1.00.jar:lib/installer-exclude/dict4j.jar:lib/installer-exclude/dnsjava.jar:lib/installer-exclude/fmj.jar:lib/installer-exclude/forms-1.2.1.jar:lib/installer-exclude/gdata-client-1.0.jar:lib/installer-exclude/gdata-client-meta-1.0.jar:lib/installer-exclude/gdata-contacts-3.0.jar:lib/installer-exclude/gdata-contacts-meta-3.0.jar:lib/installer-exclude/gdata-core-1.0.jar:lib/installer-exclude/google-collect-1.0-rc1.jar:lib/installer-exclude/httpclient-4.1.1.jar:lib/installer-exclude/httpcore-4.1.jar:lib/installer-exclude/httpmime-4.1.1.jar:lib/installer-exclude/ice4j.jar:lib/installer-exclude/jain-sdp.jar:lib/installer-exclude/jain-sip-api.jar:lib/installer-exclude/jain-sip-ri.jar:lib/installer-exclude/jcalendar-1.3.2.jar:lib/installer-exclude/jdic_misc.jar:lib/installer-exclude/jdom.jar:lib/installer-exclude/jfontchooser-1.0.5.jar:lib/installer-exclude/jmdns.jar:lib/installer-exclude/jmf.jar:lib/installer-exclude/jml-1.0b5.jar:lib/installer-exclude/jmyspell-core.jar:lib/installer-exclude/jna.jar:lib/installer-exclude/jnsapi.jar:lib/installer-exclude/joscar-client.jar:lib/installer-exclude/joscar-common.jar:lib/installer-exclude/joscar-protocol.jar:lib/installer-exclude/jsch-0.1.36.jar:lib/installer-exclude/jsocks-klea.jar:lib/installer-exclude/json-20090723.jar:lib/installer-exclude/jspeex.jar:lib/installer-exclude/junit.jar:lib/installer-exclude/laf-widget.jar:lib/installer-exclude/lcrypto-jdk16-143.jar:lib/installer-exclude/libphonenumber-2.4.jar:lib/installer-exclude/log4j-1.2.8.jar:lib/installer-exclude/lti-civil-no_s_w_t.jar:lib/installer-exclude/mac_widgets-0.9.5.jar:lib/installer-exclude/nist-sdp-1.0.jar:lib/installer-exclude/otr4j.jar:lib/installer-exclude/pircbot.jar:lib/installer-exclude/profiler4j-1.0-beta3-SC.jar:lib/installer-exclude/rome-0.9.jar:lib/installer-exclude/smack.jar:lib/installer-exclude/smackx.jar:lib/installer-exclude/swing-worker-1.2.jar:lib/installer-exclude/transparency.jar:lib/installer-exclude/weupnp-0.1.2-SNAPSHOT.jar:lib/installer-exclude/ymsg_network_v0_67.jar:lib/installer-exclude/zrtp4j-light.jar:lib/os-specific/linux/installer-exclude/jmf.jar:lib/os-specific/linux/jdic_stub.jar:lib/os-specific/mac/growl4j.jar:lib/os-specific/mac/jdic_stub.jar:lib/os-specific/mac/OrangeExtensions.jar:lib/os-specific/mac/installer-exclude/dock.jar:lib/os-specific/mac/installer-exclude/jmf.jar:lib/os-specific/solaris/jdic_stub.jar:lib/os-specific/solaris/installer-exclude/jmf.jar:lib/os-specific/windows/jdic_stub.jar:lib/os-specific/windows/installer-exclude/jmf.jar:lib/os-specific/windows/installer-exclude/jna-platform-win32.jar:lib/os-specific/windows/installer-exclude/sound.jar:lib/installer-exclude/libdbus-java-2.7.jar:lib/installer-exclude/hexdump-0.2.jar:lib/installer-exclude/unix-0.5.jar:lib/installer-exclude/sdes4j.jar</classpath>
<built-to>classes</built-to>
<source-level>1.5</source-level>
</compilation-unit>

@ -39,6 +39,7 @@ felix.auto.start.30= \
reference:file:sc-bundles/fileaccess.jar
felix.auto.start.35= \
reference:file:sc-bundles/commons-codec.jar \
reference:file:sc-bundles/httputil.jar
felix.auto.start.40= \
@ -73,6 +74,7 @@ felix.auto.start.49= \
reference:file:sc-bundles/provisioning.jar \
reference:file:sc-bundles/bouncycastle.jar \
reference:file:sc-bundles/zrtp4j.jar \
reference:file:sc-bundles/sdes4j.jar \
reference:file:sc-bundles/protocol.jar \
reference:file:sc-bundles/protocol-media.jar \
reference:file:sc-bundles/hid.jar \

Binary file not shown.

@ -92,14 +92,14 @@ public class AudioMediaStreamImpl
* @param device the <tt>MediaDevice</tt> the new instance is to use for
* both capture and playback of audio exchanged via the specified
* <tt>StreamConnector</tt>
* @param zrtpControl a control which is already created, used to control
* the zrtp operations.
* @param srtpControl a control which is already created, used to control
* the srtp operations.
*/
public AudioMediaStreamImpl(StreamConnector connector,
MediaDevice device,
ZrtpControlImpl zrtpControl)
SrtpControl srtpControl)
{
super(connector, device, zrtpControl);
super(connector, device, srtpControl);
if(logger.isTraceEnabled())
logger.trace("Created Audio Stream with hashCode " + hashCode());

@ -193,8 +193,8 @@ public MediaStream createMediaStream(
* @param device the <tt>MediaDevice</tt> that the new <tt>MediaStream</tt>
* instance is to use for both capture and playback of media exchanged via
* the specified <tt>connector</tt>
* @param zrtpControl a control which is already created, used to control
* the zrtp operations.
* @param srtpControl a control which is already created, used to control
* the srtp operations.
*
* @return a new <tt>MediaStream</tt> instance
* @see MediaService#createMediaStream(StreamConnector, MediaDevice)
@ -202,16 +202,14 @@ public MediaStream createMediaStream(
public MediaStream createMediaStream(
StreamConnector connector,
MediaDevice device,
SrtpControl zrtpControl)
SrtpControl srtpControl)
{
switch (device.getMediaType())
{
case AUDIO:
return new AudioMediaStreamImpl(connector, device,
(ZrtpControlImpl)zrtpControl);
return new AudioMediaStreamImpl(connector, device, srtpControl);
case VIDEO:
return new VideoMediaStreamImpl(connector, device,
(ZrtpControlImpl)zrtpControl);
return new VideoMediaStreamImpl(connector, device, srtpControl);
default:
return null;
}
@ -569,11 +567,21 @@ void stop()
*
* @return ZrtpControl instance.
*/
public SrtpControl createZrtpControl()
public ZrtpControl createZrtpControl()
{
return new ZrtpControlImpl();
}
/**
* Creates <tt>SDesControl</tt> used to control all SDes options.
*
* @return SDesControl instance.
*/
public SDesControl createSDesControl()
{
return new SDesControlImpl();
}
/**
* Returns the control that handles current playback levels.
*

@ -198,7 +198,7 @@ else if (MediaDeviceSession.SSRC_LIST.equals(propertyName))
/**
* The current <tt>ZrtpControl</tt>.
*/
private final ZrtpControlImpl zrtpControl;
private final SrtpControl zrtpControl;
/**
* Needed when restarting zrtp control.
@ -236,12 +236,12 @@ else if (MediaDeviceSession.SSRC_LIST.equals(propertyName))
*
* @param device the <tt>MediaDevice</tt> the new instance is to use for
* both capture and playback of media
* @param zrtpControl an existing control instance to control the ZRTP
* @param srtpControl an existing control instance to control the SRTP
* operations
*/
public MediaStreamImpl(MediaDevice device, ZrtpControlImpl zrtpControl)
public MediaStreamImpl(MediaDevice device, SrtpControl srtpControl)
{
this(null, device, zrtpControl);
this(null, device, srtpControl);
}
/**
@ -263,7 +263,7 @@ public MediaStreamImpl(MediaDevice device, ZrtpControlImpl zrtpControl)
public MediaStreamImpl(
StreamConnector connector,
MediaDevice device,
ZrtpControlImpl zrtpControl)
SrtpControl zrtpControl)
{
/*
* XXX Set the device early in order to make sure that it is of the
@ -352,7 +352,7 @@ private TransformEngineChain createTransformEngineChain()
engineChain.add(dtmfEngine);
// ZRTP
engineChain.add(zrtpControl.getZrtpEngine());
engineChain.add(zrtpControl.getTransformEngine());
// RTCP Statistics
if(statisticsEngine == null)
@ -646,10 +646,11 @@ else if (dataSource instanceof PullDataSource)
// If a ZRTP engine is available then set the SSRC of this
// stream
// currently ZRTP supports only one SSRC per engine
ZRTPTransformEngine engine = zrtpControl.getZrtpEngine();
TransformEngine engine = zrtpControl.getTransformEngine();
if (engine != null)
engine.setOwnSSRC(sendStream.getSSRC());
if (engine != null && engine instanceof ZRTPTransformEngine)
((ZRTPTransformEngine)engine)
.setOwnSSRC(sendStream.getSSRC());
}
catch (IOException ioe)
{

@ -0,0 +1,130 @@
package net.java.sip.communicator.impl.neomedia;
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.*;
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 SrtpSDesFactory sdesFactory = new SrtpSDesFactory();
private SrtpCryptoAttribute[] attributes;
private SDesTransformEngine engine;
private SrtpCryptoAttribute selectedInAttribute;
private SrtpCryptoAttribute selectedOutAttribute;
public SDesControlImpl()
{
}
public void cleanup()
{
}
public void setZrtpListener(SrtpListener zrtpListener)
{
}
public SrtpListener getSrtpListener()
{
return null;
}
public boolean getSecureCommunicationStatus()
{
return engine != null;
}
public void setSASVerification(boolean verified)
{
}
public void start(boolean masterSession)
{
}
public void setMultistream(byte[] multiStreamData)
{
}
public TransformEngine getTransformEngine()
{
if(engine == null)
engine = new SDesTransformEngine(this);
return engine;
}
public String[] getInitiatorCryptoAttributes()
{
attributes = new SrtpCryptoAttribute[supportedCryptoSuites.length];
for (int i = 0; i < attributes.length; i++)
{
attributes[i] =
sdesFactory.createCryptoAttribute(i + 1,
supportedCryptoSuites[i]);
}
String[] result = new String[attributes.length];
for(int i = 0; i < attributes.length; i++)
result[i] = attributes[i].encode();
return result;
}
public String responderSelectAttribute(String[] peerAttributes)
{
for (String suite : supportedCryptoSuites)
{
for (String ea : peerAttributes)
{
SrtpCryptoAttribute peerCA = SrtpCryptoAttribute.create(ea);
if (suite.equals(peerCA.getCryptoSuite().encode()))
{
selectedInAttribute = peerCA;
selectedOutAttribute =
sdesFactory.createCryptoAttribute(1, suite);
return selectedOutAttribute.encode();
}
}
}
return null;
}
public void initiatorSelectAttribute(String[] peerAttributes)
{
for (SrtpCryptoAttribute localCA : attributes)
{
for (String ea : peerAttributes)
{
SrtpCryptoAttribute peerCA = SrtpCryptoAttribute.create(ea);
if (localCA.getCryptoSuite().equals(peerCA.getCryptoSuite()))
{
selectedInAttribute = peerCA;
selectedOutAttribute = localCA;
return;
}
}
}
}
public SrtpCryptoAttribute getInAttribute()
{
return selectedInAttribute;
}
public SrtpCryptoAttribute getOutAttribute()
{
return selectedOutAttribute;
}
public void setConnector(AbstractRTPConnector newValue)
{
}
}

@ -259,13 +259,13 @@ public int compare(FormatInfo info0, FormatInfo info1)
* @param device the <tt>MediaDevice</tt> the new instance is to use for
* both capture and playback of video exchanged via the specified
* <tt>StreamConnector</tt>
* @param zrtpControl a control which is already created, used to control
* the zrtp operations.
* @param srtpControl a control which is already created, used to control
* the srtp operations.
*/
public VideoMediaStreamImpl(StreamConnector connector, MediaDevice device,
ZrtpControlImpl zrtpControl)
SrtpControl srtpControl)
{
super(connector, device, zrtpControl);
super(connector, device, srtpControl);
if(logger.isTraceEnabled())
logger.trace("Created Video Stream with hashCode " + hashCode());

@ -20,7 +20,7 @@
* @author Damian Minkov
*/
public class ZrtpControlImpl
implements SrtpControl
implements ZrtpControl
{
/**
* The listener interested in security events about zrtp.
@ -112,7 +112,7 @@ public boolean getSecureCommunicationStatus()
*/
public void setSASVerification(boolean verified)
{
ZRTPTransformEngine engine = getZrtpEngine();
ZRTPTransformEngine engine = getTransformEngine();
if (verified)
engine.SASVerified();
@ -124,7 +124,7 @@ public void setSASVerification(boolean verified)
* Returns the zrtp engine currently used by this stream.
* @return the zrtp engine
*/
public ZRTPTransformEngine getZrtpEngine()
public ZRTPTransformEngine getTransformEngine()
{
if(zrtpEngine == null)
{
@ -151,7 +151,7 @@ public void start(boolean masterSession)
boolean zrtpAutoStart = false;
// ZRTP engine initialization
ZRTPTransformEngine engine = getZrtpEngine();
ZRTPTransformEngine engine = getTransformEngine();
// Decide if this will become the ZRTP Master session:
// - Statement: audio media session will be started before video
@ -209,7 +209,7 @@ public void start(boolean masterSession)
*/
public void setMultistream(byte[] multiStreamData)
{
ZRTPTransformEngine engine = getZrtpEngine();
ZRTPTransformEngine engine = getTransformEngine();
engine.setMultiStrParams(multiStreamData);
engine.setEnableZrtp(true);
@ -222,7 +222,7 @@ public void setMultistream(byte[] multiStreamData)
*/
public String getHelloHash()
{
return getZrtpEngine().getHelloHash();
return getTransformEngine().getHelloHash();
}
/**
@ -235,7 +235,7 @@ public String getHelloHash()
*/
public String[] getHelloHashSep()
{
return getZrtpEngine().getHelloHashSep();
return getTransformEngine().getHelloHashSep();
}
/**

@ -43,7 +43,9 @@ Import-Package: org.bouncycastle.crypto,
gnu.java.zrtp.packets,
gnu.java.zrtp.utils,
gnu.java.zrtp.zidfile,
apple.awt
apple.awt,
ch.imvs.sdes4j,
ch.imvs.sdes4j.srtp
Export-Package: net.java.sip.communicator.service.audionotifier,
net.java.sip.communicator.service.neomedia,
net.java.sip.communicator.service.neomedia.control,

@ -0,0 +1,142 @@
package net.java.sip.communicator.impl.neomedia.transform.sdes;
import ch.imvs.sdes4j.srtp.*;
import net.java.sip.communicator.impl.neomedia.*;
import net.java.sip.communicator.impl.neomedia.transform.*;
import net.java.sip.communicator.impl.neomedia.transform.srtp.*;
public class SDesTransformEngine
implements TransformEngine, PacketTransformer
{
private SRTPCryptoContext inContext;
private SRTPCryptoContext outContext;
private SrtpCryptoAttribute inAttribute;
private SrtpCryptoAttribute outAttribute;
public SDesTransformEngine(SDesControlImpl sDesControl)
{
inAttribute = sDesControl.getInAttribute();
outAttribute = sDesControl.getOutAttribute();
}
private long getKdr(SrtpCryptoAttribute attribute)
{
if(attribute.getSessionParams() != null)
{
for (SrtpSessionParam param : attribute.getSessionParams())
{
if (param instanceof KdrSessionParam)
return ((KdrSessionParam) param).getKeyDerivationRateExpanded();
}
}
return 0;
}
private byte[] getKey(SrtpCryptoAttribute attribute)
{
int length = attribute.getCryptoSuite().getEncKeyLength()/8;
byte[] key = new byte[length];
System.arraycopy(attribute.getKeyParams()[0].getKey(), 0, key, 0, length);
return key;
}
private byte[] getSalt(SrtpCryptoAttribute attribute)
{
int keyLength = attribute.getCryptoSuite().getEncKeyLength()/8;
int saltLength = attribute.getCryptoSuite().getSaltKeyLength()/8;
byte[] salt = new byte[keyLength];
System.arraycopy(attribute.getKeyParams()[0].getKey(), keyLength, salt, 0,
saltLength);
return salt;
}
public PacketTransformer getRTPTransformer()
{
return this;
}
public PacketTransformer getRTCPTransformer()
{
return null;
}
private SRTPCryptoContext createContext(long ssrc, SrtpCryptoAttribute attribute)
{
int encType;
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");
}
int authType;
switch(cs.getHashAlgorithm())
{
case SrtpCryptoSuite.HASH_HMAC_SHA1:
authType = SRTPPolicy.HMACSHA1_AUTHENTICATION;
break;
default:
throw new IllegalArgumentException("Unsupported hash");
}
SRTPPolicy policy = new SRTPPolicy(
encType, cs.getEncKeyLength()/8,
authType, cs.getSrtpAuthKeyLength()/8, cs.getSrtpAuthTagLength()/8,
cs.getSaltKeyLength()/8
);
return new SRTPCryptoContext(
ssrc, 0, getKdr(attribute),
getKey(attribute),
getSalt(attribute),
policy
);
}
public RawPacket transform(RawPacket pkt)
{
if (outContext == null)
{
outContext = createContext(pkt.getSSRC(), outAttribute);
outContext.deriveSrtpKeys(0);
}
outContext.transformPacket(pkt);
return pkt;
}
public RawPacket reverseTransform(RawPacket pkt)
{
long ssrc = pkt.getSSRC();
int seqNum = pkt.getSequenceNumber();
boolean isNewContext = false;
if (inContext == null)
{
inContext = createContext(ssrc, inAttribute);
inContext.deriveSrtpKeys(seqNum);
isNewContext = true;
}
else if(ssrc != inContext.getSSRC())
{
// invalid packet, don't even try to decode
return null;
}
boolean validPacket = inContext.reverseTransformPacket(pkt);
if(!validPacket && isNewContext)
inContext = null;
if (!validPacket)
{
return null;
}
return pkt;
}
}

@ -53,7 +53,7 @@
* Cryptographic related parameters, i.e. encryption mode / authentication mode,
* master encryption key and master salt key are determined outside the scope
* of SRTP implementation. They can be assigned manually, or can be assigned
* automatically using some key management protocol, such as MIKEY (RFC3880) or
* automatically using some key management protocol, such as MIKEY (RFC3830) or
* Phil Zimmermann's ZRTP protocol (draft-zimmermann-avt-zrtp-01).
*
* @author Bing SU (nova.su@gmail.com)

@ -212,7 +212,7 @@ public void showMessage(ZrtpCodes.MessageSeverity sev,
{
securityListener.securityTurnedOn(
sessionType, cipher, sas, isSasVerified,
zrtpControl.getZrtpEngine().getMultiStrParams());
zrtpControl.getTransformEngine().getMultiStrParams());
}
else
{

@ -344,14 +344,14 @@ public void processOffer(List<ContentPacketExtension> offer)
if(getPeer().getCall().isSipZrtpAttribute())
{
SrtpControl control = getZrtpControls().get(mediaType);
if(control == null)
if(control == null || !(control instanceof ZrtpControl))
{
control = JabberActivator.getMediaService()
.createZrtpControl();
getZrtpControls().put(mediaType, control);
}
String helloHash[] = control.getHelloHashSep();
String helloHash[] = ((ZrtpControl)control).getHelloHashSep();
if(helloHash != null && helloHash[1].length() > 0)
{
@ -552,14 +552,14 @@ private ContentPacketExtension createContent(MediaDevice dev)
{
SrtpControl control = getZrtpControls().get(dev.getMediaType());
if(control == null)
if(control == null || !(control instanceof ZrtpControl))
{
control
= JabberActivator.getMediaService().createZrtpControl();
getZrtpControls().put(dev.getMediaType(), control);
}
String helloHash[] = control.getHelloHashSep();
String helloHash[] = ((ZrtpControl)control).getHelloHashSep();
if(helloHash != null && helloHash[1].length() > 0)
{
@ -690,14 +690,15 @@ public List<ContentPacketExtension> createContentList()
if(getPeer().getCall().isSipZrtpAttribute())
{
SrtpControl control = getZrtpControls().get(mediaType);
if(control == null)
if(control == null || !(control instanceof ZrtpControl))
{
control = JabberActivator.getMediaService()
.createZrtpControl();
getZrtpControls().put(mediaType, control);
}
String helloHash[] = control.getHelloHashSep();
String helloHash[] =
((ZrtpControl) control).getHelloHashSep();
if(helloHash != null && helloHash[1].length() > 0)
{

@ -191,12 +191,13 @@ private Vector<MediaDescription> createMediaDescriptions()
{
MediaDescription md =
createMediaDescription(
dev.getSupportedFormats(
sendQualityPreset,
receiveQualityPreset),
getTransportManager().getStreamConnector(mediaType),
direction,
dev.getSupportedExtensions());
true, //TODO base on settings
dev.getSupportedFormats(
sendQualityPreset,
receiveQualityPreset),
getTransportManager().getStreamConnector(mediaType),
direction,
dev.getSupportedExtensions());
try
{
@ -215,7 +216,8 @@ private Vector<MediaDescription> createMediaDescriptions()
// do nothing in case of error.
}
updateMediaDescriptionForZrtp(mediaType, md);
//updateMediaDescriptionForZrtp(mediaType, md); //TODO: base on setting
updateMediaDescriptionForSDes(mediaType, md, null);
mediaDescs.add(md);
}
@ -476,11 +478,6 @@ private Vector<MediaDescription> createMediaDescriptionsForAnswer(
StreamConnector connector
= getTransportManager().getStreamConnector(mediaType);
// create the corresponding stream...
MediaFormat fmt = findMediaFormat(remoteFormats,
mutuallySupportedFormats.get(0));
initStream(connector, dev, fmt, target, direction, rtpExtensions);
// check for options from remote party and set them locally
if(mediaType.equals(MediaType.VIDEO))
{
@ -527,10 +524,16 @@ private Vector<MediaDescription> createMediaDescriptionsForAnswer(
}
}
MediaDescription md = createMediaDescription(
MediaDescription md = createMediaDescription(true, //TODO base on settings
mutuallySupportedFormats, connector, direction, rtpExtensions);
updateMediaDescriptionForZrtp(mediaType, md);
//updateMediaDescriptionForZrtp(mediaType, md); //TODO base on setting
updateMediaDescriptionForSDes(mediaType, md, mediaDescription);
// create the corresponding stream...
MediaFormat fmt = findMediaFormat(remoteFormats,
mutuallySupportedFormats.get(0));
initStream(connector, dev, fmt, target, direction, rtpExtensions);
// create the answer description
answerDescriptions.add(md);
@ -559,26 +562,94 @@ private void updateMediaDescriptionForZrtp(
{
try
{
SrtpControl control
= getZrtpControls().get(mediaType);
if(control == null)
SrtpControl scontrol = getZrtpControls().get(mediaType);
if(scontrol == null || !(scontrol instanceof ZrtpControl))
{
control = SipActivator.getMediaService()
scontrol = SipActivator.getMediaService()
.createZrtpControl();
getZrtpControls().put(mediaType, control);
getZrtpControls().put(mediaType, scontrol);
}
ZrtpControl zcontrol = (ZrtpControl) scontrol;
String helloHash = control.getHelloHash();
String helloHash = zcontrol.getHelloHash();
if(helloHash != null && helloHash.length() > 0)
md.setAttribute("zrtp-hash", helloHash);
} catch (SdpException ex)
}
catch (SdpException ex)
{
logger.error("Cannot add zrtp-hash to sdp", ex);
}
}
}
/**
* 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
*/
@SuppressWarnings("unchecked") //jain-sip legacy
private void updateMediaDescriptionForSDes(
MediaType mediaType, MediaDescription localMd, MediaDescription peerMd)
throws OperationFailedException
{
//if(getPeer().getCall().isSipZrtpAttribute()) //TODO: check SDES config
{
SrtpControl scontrol = getZrtpControls().get(mediaType);
if (scontrol == null || !(scontrol instanceof SDesControl))
{
scontrol = SipActivator.getMediaService().createSDesControl();
getZrtpControls().put(mediaType, scontrol);
}
SDesControl sdcontrol = (SDesControl) scontrol;
if (peerMd == null)
{
Vector<Attribute> atts = localMd.getAttributes(true);
for (String ca : sdcontrol.getInitiatorCryptoAttributes())
{
Attribute a = SdpUtils.createAttribute("crypto", ca);
atts.add(a);
}
}
else
{
Vector<Attribute> atts = peerMd.getAttributes(true);
List<String> peerAttributes = new LinkedList<String>();
for (Attribute a : atts)
{
try
{
if (a.getName().equals("crypto"))
{
peerAttributes.add(a.getValue());
}
}
catch (SdpParseException e)
{
logger.error("received an uparsable sdp attribute", e);
}
}
if (peerAttributes.size() > 0)
{
String localAttr =
sdcontrol.responderSelectAttribute(peerAttributes
.toArray(new String[peerAttributes.size()]));
try
{
localMd.setAttribute("crypto", localAttr);
}
catch (SdpException e)
{
logger.error("unable to add crypto to answer", e);
}
}
}
}
}
/**
* Handles the specified <tt>answer</tt> by creating and initializing the
* corresponding <tt>MediaStream</tt>s.
@ -715,6 +786,32 @@ private synchronized void processAnswer(SessionDescription answer)
supportQualityControls =
SdpUtils.containsAttribute(mediaDescription, "imageattr");
}
// select the crypto key the peer has chosen from our proposal
SrtpControl scontrol = getZrtpControls().get(mediaType);
if(scontrol != null && scontrol instanceof SDesControl)
{
List<String> peerAttributes = new LinkedList<String>();
@SuppressWarnings("unchecked")
Vector<Attribute> attrs = mediaDescription.getAttributes(true);
for (Attribute a : attrs)
{
try
{
if (a.getName().equals("crypto"))
{
peerAttributes.add(a.getValue());
}
}
catch (SdpParseException e)
{
logger.error("received an uparsable sdp attribute", e);
}
}
((SDesControl) scontrol)
.initiatorSelectAttribute(peerAttributes
.toArray(new String[peerAttributes.size()]));
}
}
}
@ -735,6 +832,7 @@ private String getUserName()
* 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 formats the list of <tt>MediaFormats</tt> that we'd like to
* advertise.
* @param connector the <tt>StreamConnector</tt> that we will be using
@ -751,13 +849,14 @@ private String getUserName()
* <tt>MediaDescription</tt> fails for some reason.
*/
private MediaDescription createMediaDescription(
boolean secure,
List<MediaFormat> formats,
StreamConnector connector,
MediaDirection direction,
List<RTPExtension> extensions )
throws OperationFailedException
{
return SdpUtils.createMediaDescription(formats, connector,
return SdpUtils.createMediaDescription(secure, formats, connector,
direction, extensions,
getDynamicPayloadTypes(), getRtpExtensionsRegistry());
}

@ -1284,6 +1284,7 @@ public static URL getCallInfoURL(SessionDescription sessDesc)
* 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 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
@ -1306,6 +1307,7 @@ public static URL getCallInfoURL(SessionDescription sessDesc)
* some other reason.
*/
public static MediaDescription createMediaDescription(
boolean secure,
List<MediaFormat> formats,
StreamConnector connector,
MediaDirection direction,
@ -1435,7 +1437,8 @@ public static MediaDescription createMediaDescription(
{
mediaDesc = sdpFactory.createMediaDescription(mediaType.toString(),
connector.getDataSocket().getLocalPort(), 1,
SdpConstants.RTP_AVP, payloadTypesArray);
secure ? "RTP/SAVP" : SdpConstants.RTP_AVP,
payloadTypesArray);
// add all the attributes we have created above
mediaDesc.setAttributes(mediaAttributes);

@ -135,7 +135,14 @@ public MediaStream createMediaStream(StreamConnector connector,
*
* @return ZrtpControl instance.
*/
public SrtpControl createZrtpControl();
public ZrtpControl createZrtpControl();
/**
* Creates <tt>SDesControl</tt> used to control all SDes options.
*
* @return SDesControl instance.
*/
public SDesControl createSDesControl();
/**
* Returns the control that handles current playback levels.

@ -0,0 +1,13 @@
package net.java.sip.communicator.service.neomedia;
import ch.imvs.sdes4j.srtp.SrtpCryptoAttribute;
public interface SDesControl
extends SrtpControl
{
public String[] getInitiatorCryptoAttributes();
public String responderSelectAttribute(String[] peerAttributes);
public void initiatorSelectAttribute(String[] peerAttributes);
public SrtpCryptoAttribute getInAttribute();
public SrtpCryptoAttribute getOutAttribute();
}

@ -6,6 +6,8 @@
*/
package net.java.sip.communicator.service.neomedia;
import net.java.sip.communicator.impl.neomedia.AbstractRTPConnector;
import net.java.sip.communicator.impl.neomedia.transform.TransformEngine;
import net.java.sip.communicator.service.neomedia.event.*;
/**
@ -68,19 +70,11 @@ public interface SrtpControl
public void setMultistream(byte[] multiStreamData);
/**
* Return the zrtp hello hash String.
*
* @return String the zrtp hello hash.
* Returns the transform engine currently used by this stream.
*
* @return the transofmr engine
*/
public String getHelloHash();
public TransformEngine getTransformEngine();
/**
* Get the ZRTP Hello Hash data - separate strings.
*
* @return String array containing the version string at offset 0, the Hello
* hash value as hex-digits at offset 1. Hello hash is available
* immediately after class instantiation. Returns <code>null</code>
* if ZRTP is not available.
*/
public String[] getHelloHashSep();
public void setConnector(AbstractRTPConnector newValue);
}

@ -0,0 +1,22 @@
package net.java.sip.communicator.service.neomedia;
public interface ZrtpControl
extends SrtpControl
{
/**
* Return the zrtp hello hash String.
*
* @return String the zrtp hello hash.
*/
public String getHelloHash();
/**
* Get the ZRTP Hello Hash data - separate strings.
*
* @return String array containing the version string at offset 0, the Hello
* hash value as hex-digits at offset 1. Hello hash is available
* immediately after class instantiation. Returns <code>null</code>
* if ZRTP is not available.
*/
public String[] getHelloHashSep();
}

@ -193,7 +193,7 @@ public abstract class CallPeerMediaHandler<
/**
* Holds the ZRTP controls used for the current call.
*/
private Map<MediaType, SrtpControl> zrtpControls =
private Map<MediaType, SrtpControl> srtpControls =
new Hashtable<MediaType, SrtpControl>();
/**
@ -423,12 +423,12 @@ protected void closeStream(MediaType type)
getTransportManager().closeStreamConnector(type);
// Clear the ZRTP controls used for the associated Call.
SrtpControl zrtpCtrl = zrtpControls.get(type);
SrtpControl zrtpCtrl = srtpControls.get(type);
if (zrtpCtrl != null)
{
zrtpCtrl.cleanup();
zrtpControls.remove(type);
srtpControls.remove(type);
}
}
@ -1163,7 +1163,7 @@ public void setCsrcAudioLevelListener(
*/
protected Map<MediaType, SrtpControl> getZrtpControls()
{
return this.zrtpControls;
return this.srtpControls;
}
/**
@ -1206,7 +1206,7 @@ protected MediaStream initStream(StreamConnector connector,
logger.trace("The media types of device and format differ.");
// check whether a control already exists
SrtpControl control = zrtpControls.get(mediaType);
SrtpControl control = srtpControls.get(mediaType);
MediaService mediaService
= ProtocolMediaActivator.getMediaService();

Loading…
Cancel
Save