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