mirror of https://github.com/sipwise/jitsi.git
parent
0f09a0cc4e
commit
703c3a49e7
Binary file not shown.
@ -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)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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();
|
||||||
|
}
|
||||||
@ -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();
|
||||||
|
}
|
||||||
Loading…
Reference in new issue