package org.ifsoft.rtp;
import org.ifsoft.*;
import java.util.ArrayList;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Encryptor
{
private EncryptionMode _encryptionMode;
private Byte _localKey[];
private Byte _localSalt[];
private Long _octetCount;
private Long _packetCount;
private Byte _remoteKey[];
private Byte _remoteSalt[];
private static Byte _rTCPAuthLabel = Byte.valueOf((byte)0);
private AESCounter _rTCPDecryption;
private Byte _rTCPDecryptionAuth[];
private AESCounter _rTCPEncryption;
private Byte _rTCPEncryptionAuth[];
private Integer _rTCPIntegritySize;
private static Byte _rTCPKeyLabel = Byte.valueOf((byte)0);
private static Byte _rTCPSaltLabel = Byte.valueOf((byte)0);
private static Byte _rTPAuthLabel = Byte.valueOf((byte)0);
private AESCounter _rTPDecryption;
private Byte _rTPDecryptionAuth[];
private Integer _rTPDecryptionHighestSequenceNumber;
private Long _rTPDecryptionROC;
private AESCounter _rTPEncryption;
private Byte _rTPEncryptionAuth[];
private Long _rTPEncryptionROC;
private Integer _rTPIntegritySize;
private static Byte _rTPKeyLabel = Byte.valueOf((byte)0);
private static Byte _rTPSaltLabel = Byte.valueOf((byte)0);
private Integer _sRTCPIndex;
private static final Logger Log = LoggerFactory.getLogger(Encryptor.class);
static
{
_rTPKeyLabel = new Byte((byte)0);
_rTPAuthLabel = new Byte((byte)1);
_rTPSaltLabel = new Byte((byte)2);
_rTCPKeyLabel = new Byte((byte)3);
_rTCPAuthLabel = new Byte((byte)4);
_rTCPSaltLabel = new Byte((byte)5);
}
private static void copyRTPProperties(RTPPacket source, RTPPacket target)
{
target.setMarker(source.getMarker());
target.setSequenceNumber(source.getSequenceNumber());
target.setSynchronizationSource(source.getSynchronizationSource());
target.setTimestamp(source.getTimestamp());
}
public RTCPPacket[] decryptRTCP(Byte encryptedBytes[])
{
EncryptionMode _var0 = getEncryptionMode();
if(_var0 != null ? _var0.equals(EncryptionMode.Null) : _var0 == EncryptionMode.Null)
{
Log.info("decryptRTCP no encryption found");
return RTCPPacket.parseBytes(encryptedBytes);
}
if(ArrayExtensions.getLength(encryptedBytes).intValue() < 12 + _rTCPIntegritySize.intValue())
{
Log.info("decryptRTCP packet too small");
return null;
}
Byte buffer[] = BitAssistant.subArray(encryptedBytes, Integer.valueOf(0), Integer.valueOf(ArrayExtensions.getLength(encryptedBytes).intValue() - _rTCPIntegritySize.intValue()));
Byte buffer2[] = BitAssistant.subArray(encryptedBytes, Integer.valueOf(ArrayExtensions.getLength(encryptedBytes).intValue() - _rTCPIntegritySize.intValue()), _rTCPIntegritySize);
Byte buffer4[] = BitAssistant.subArray(Crypto.getHmacSha1(_rTCPDecryptionAuth, buffer), Integer.valueOf(0), _rTCPIntegritySize);
if(!BitAssistant.sequencesAreEqual(buffer2, buffer4).booleanValue())
{
Log.info("decryptRTCP sequences Are not Equal");
return null;
}
Long ssrc = BitAssistant.toLongFromIntegerNetwork(buffer, Integer.valueOf(4));
Byte buffer5[] = BitAssistant.subArray(buffer, Integer.valueOf(ArrayExtensions.getLength(buffer).intValue() - 4));
buffer5[0] = new Byte((byte)(buffer5[0].byteValue() & 0x7f));
Integer num2 = BitAssistant.toIntegerNetwork(buffer5, Integer.valueOf(0));
Byte data[] = BitAssistant.subArray(buffer, Integer.valueOf(8), Integer.valueOf(ArrayExtensions.getLength(buffer).intValue() - 12));
Byte buffer7[];
if(_rTCPDecryption == null)
buffer7 = data;
else
buffer7 = _rTCPDecryption.decrypt(data, ssrc, new Long((new Integer(num2.intValue())).longValue()));
ArrayList list = new ArrayList();
ArrayListExtensions.addRange(list, BitAssistant.subArray(buffer, Integer.valueOf(0), Integer.valueOf(8)));
ArrayListExtensions.addRange(list, buffer7);
return RTCPPacket.parseBytes((Byte[])list.toArray(new Byte[0]));
}
public RTPPacket decryptRTP(Byte encryptedBytes[])
throws Exception
{
if(ArrayExtensions.getLength(encryptedBytes).intValue() < 12)
{
Log.info("decryptRTP packet less than 12 bytes");
return null;
}
Integer num = new Integer(encryptedBytes[1].byteValue() & 0x7f);
if(num.intValue() >= 72 && num.intValue() <= 76)
{
Log.info("decryptRTP packet first bye no good " + encryptedBytes[1]);
return null;
}
EncryptionMode _var0 = getEncryptionMode();
if(_var0 != null ? _var0.equals(EncryptionMode.Null) : _var0 == EncryptionMode.Null)
{
Log.info("decryptRTP no encryption found");
return RTPPacket.parseBytes(encryptedBytes);
}
if(ArrayExtensions.getLength(encryptedBytes).intValue() < 12 + _rTPIntegritySize.intValue())
{
Log.info("decryptRTP packet too small");
return null;
}
Byte collection[] = BitAssistant.subArray(encryptedBytes, Integer.valueOf(0), Integer.valueOf(ArrayExtensions.getLength(encryptedBytes).intValue() - _rTPIntegritySize.intValue()));
Byte buffer2[] = BitAssistant.subArray(encryptedBytes, Integer.valueOf(ArrayExtensions.getLength(encryptedBytes).intValue() - _rTPIntegritySize.intValue()), _rTPIntegritySize);
ArrayList list = ArrayListExtensions.createArray(collection);
ArrayListExtensions.addRange(list, BitAssistant.getIntegerBytesFromLongNetwork(_rTPDecryptionROC));
Byte buffer4[] = BitAssistant.subArray(Crypto.getHmacSha1(_rTPDecryptionAuth, (Byte[])list.toArray(new Byte[0])), Integer.valueOf(0), _rTPIntegritySize);
if(!BitAssistant.sequencesAreEqual(buffer2, buffer4).booleanValue())
{
//Log.info("decryptRTP sequences Are not Equal");
//return null;
}
RTPPacket packet = RTPPacket.parseBytes(collection);
if(packet == null)
{
Log.info("decryptRTP collection is bad");
return null;
}
if(_rTPDecryption != null)
packet.setPayload(_rTPDecryption.decrypt(packet.getPayload(), packet.getSynchronizationSource(), getRTPDecryptionPacketIndex(packet.getSequenceNumber())));
return packet;
}
public Byte[] encryptRTCP(RTCPPacket packets[])
throws Exception
{
if(packets == null || ArrayExtensions.getLength(packets).intValue() == 0)
throw new Exception("Cannot encrypt a null RTCP packet.");
if(!(packets[0] instanceof RTCPSRPacket))
throw new Exception("RTCP transmissions must start with a Sender Report (RTCPSRPacket).");
RTCPPacket arr$[] = packets;
int len$ = arr$.length;
for(int i$ = 0; i$ < len$; i$++)
{
RTCPPacket packet = arr$[i$];
if(packet instanceof RTCPSRPacket)
{
RTCPSRPacket packet2 = (RTCPSRPacket)(RTCPSRPacket)packet;
packet2.setPacketCount(_packetCount);
packet2.setOctetCount(_octetCount);
}
}
Byte bytes[] = RTCPPacket.getBytes(packets);
EncryptionMode _var0 = getEncryptionMode();
if(_var0 != null ? _var0.equals(EncryptionMode.Null) : _var0 == EncryptionMode.Null)
return bytes;
Integer rTCPEncryptionPacketIndex = getRTCPEncryptionPacketIndex();
Long ssrc = BitAssistant.toLongFromIntegerNetwork(bytes, Integer.valueOf(4));
Byte data[] = BitAssistant.subArray(bytes, Integer.valueOf(8), Integer.valueOf(ArrayExtensions.getLength(bytes).intValue() - 8));
Byte buffer3[];
if(_rTCPEncryption == null)
buffer3 = data;
else
buffer3 = _rTCPEncryption.encrypt(data, ssrc, new Long((new Integer(rTCPEncryptionPacketIndex.intValue())).longValue()));
ArrayList collection = new ArrayList();
ArrayListExtensions.addRange(collection, BitAssistant.subArray(bytes, Integer.valueOf(0), Integer.valueOf(8)));
ArrayListExtensions.addRange(collection, buffer3);
Byte integerBytesNetwork[] = BitAssistant.getIntegerBytesNetwork(rTCPEncryptionPacketIndex);
integerBytesNetwork[0] = new Byte((byte)(integerBytesNetwork[0].byteValue() | 0x80));
ArrayListExtensions.addRange(collection, integerBytesNetwork);
Byte buffer6[] = BitAssistant.subArray(Crypto.getHmacSha1(_rTCPEncryptionAuth, (Byte[])collection.toArray(new Byte[0])), Integer.valueOf(0), _rTCPIntegritySize);
ArrayList list2 = new ArrayList();
ArrayListExtensions.addRange(list2, collection);
ArrayListExtensions.addRange(list2, buffer6);
return (Byte[])list2.toArray(new Byte[0]);
}
public Byte[] encryptRTP(RTPPacket packet)
throws Exception
{
if(packet == null)
throw new Exception("Cannot encrypt a null RTP packet.");
Long num = Long.valueOf(_packetCount.longValue() + 1L);
Long num2 = Long.valueOf(_octetCount.longValue() + (long)ArrayExtensions.getLength(packet.getPayload()).intValue());
if(num.longValue() >= 0x100000000L)
num = Long.valueOf(num.longValue() - 0x100000000L);
if(num2.longValue() >= 0x100000000L)
num2 = Long.valueOf(num2.longValue() - 0x100000000L);
_packetCount = num;
_octetCount = num2;
EncryptionMode _var0 = getEncryptionMode();
if(_var0 != null ? _var0.equals(EncryptionMode.Null) : _var0 == EncryptionMode.Null)
return packet.getBytes();
Byte buffer[];
if(_rTPEncryption == null)
buffer = packet.getPayload();
else
buffer = _rTPEncryption.encrypt(packet.getPayload(), packet.getSynchronizationSource(), getRTPEncryptionPacketIndex(packet.getSequenceNumber()));
Byte payload[] = packet.getPayload();
packet.setPayload(buffer);
Byte bytes[] = packet.getBytes();
packet.setPayload(payload);
ArrayList list = ArrayListExtensions.createArray(bytes);
ArrayListExtensions.addRange(list, BitAssistant.getIntegerBytesFromLongNetwork(_rTPEncryptionROC));
Byte collection[] = BitAssistant.subArray(Crypto.getHmacSha1(_rTPEncryptionAuth, (Byte[])list.toArray(new Byte[0])), Integer.valueOf(0), _rTPIntegritySize);
ArrayList list2 = new ArrayList();
ArrayListExtensions.addRange(list2, bytes);
ArrayListExtensions.addRange(list2, collection);
return (Byte[])list2.toArray(new Byte[0]);
}
public Encryptor(EncryptionMode encryptionMode, Byte localKey[], Byte localSalt[], Byte remoteKey[], Byte remoteSalt[])
throws Exception
{
_octetCount = Long.valueOf(0L);
_packetCount = Long.valueOf(0L);
_rTCPIntegritySize = Integer.valueOf(0);
_rTPDecryptionHighestSequenceNumber = Integer.valueOf(0);
_rTPDecryptionROC = Long.valueOf(0L);
_rTPEncryptionROC = Long.valueOf(0L);
_rTPIntegritySize = Integer.valueOf(0);
_sRTCPIndex = Integer.valueOf(0);
_rTPEncryptionROC = Long.valueOf(0L);
_rTPDecryptionROC = Long.valueOf(0L);
_rTPDecryptionHighestSequenceNumber = Integer.valueOf(0);
_sRTCPIndex = Integer.valueOf(0);
_packetCount = Long.valueOf(0L);
_octetCount = Long.valueOf(0L);
setEncryptionMode(encryptionMode);
EncryptionMode _var0 = getEncryptionMode();
if(_var0 != null ? !_var0.equals(EncryptionMode.Null) : _var0 != EncryptionMode.Null)
{
AESCounter counter = new AESCounter(localKey, localSalt);
AESCounter counter2 = new AESCounter(remoteKey, remoteSalt);
EncryptionMode _var1 = encryptionMode;
EncryptionMode _var2 = encryptionMode;
if((_var1 != null ? _var1.equals(EncryptionMode.Default) : _var1 == EncryptionMode.Default) || (_var2 != null ? _var2.equals(EncryptionMode.AES128Weak) : _var2 == EncryptionMode.AES128Weak))
{
Byte key[] = counter.generate(_rTPKeyLabel, Integer.valueOf(16));
Byte salt[] = counter.generate(_rTPSaltLabel, Integer.valueOf(14));
_rTPEncryption = new AESCounter(key, salt);
Byte buffer3[] = counter.generate(_rTCPKeyLabel, Integer.valueOf(16));
Byte buffer4[] = counter.generate(_rTCPSaltLabel, Integer.valueOf(14));
_rTCPEncryption = new AESCounter(buffer3, buffer4);
Byte buffer5[] = counter2.generate(_rTPKeyLabel, Integer.valueOf(16));
Byte buffer6[] = counter2.generate(_rTPSaltLabel, Integer.valueOf(14));
_rTPDecryption = new AESCounter(buffer5, buffer6);
Byte buffer7[] = counter2.generate(_rTCPKeyLabel, Integer.valueOf(16));
Byte buffer8[] = counter2.generate(_rTCPSaltLabel, Integer.valueOf(14));
_rTCPDecryption = new AESCounter(buffer7, buffer8);
}
Byte buffer9[] = counter.generate(_rTPAuthLabel, Integer.valueOf(20));
_rTPEncryptionAuth = buffer9;
Byte buffer10[] = counter.generate(_rTCPAuthLabel, Integer.valueOf(20));
_rTCPEncryptionAuth = buffer10;
Byte buffer11[] = counter2.generate(_rTPAuthLabel, Integer.valueOf(20));
_rTPDecryptionAuth = buffer11;
Byte buffer12[] = counter2.generate(_rTCPAuthLabel, Integer.valueOf(20));
_rTCPDecryptionAuth = buffer12;
EncryptionMode _var3 = getEncryptionMode();
if(_var3 == EncryptionMode.Default || _var3 == EncryptionMode.NullStrong)
_rTPIntegritySize = Integer.valueOf(10);
else
if(_var3 == EncryptionMode.AES128Weak || _var3 == EncryptionMode.NullWeak)
_rTPIntegritySize = Integer.valueOf(4);
_rTCPIntegritySize = Integer.valueOf(10);
}
}
public EncryptionMode getEncryptionMode()
{
return _encryptionMode;
}
public Byte[] getLocalKey()
{
return _localKey;
}
public Byte[] getLocalSalt()
{
return _localSalt;
}
public Byte[] getRemoteKey()
{
return _remoteKey;
}
public Byte[] getRemoteSalt()
{
return _remoteSalt;
}
private Integer getRTCPEncryptionPacketIndex()
{
Encryptor encryptor = this;
Integer integer = encryptor._sRTCPIndex;
Integer integer1 = encryptor._sRTCPIndex = Integer.valueOf(encryptor._sRTCPIndex.intValue() + 1);
return integer;
}
private Long getRTPDecryptionPacketIndex(Integer sequenceNumber)
{
Long rTPDecryptionROC;
if(_rTPDecryptionHighestSequenceNumber.intValue() < 32768)
{
if(sequenceNumber.intValue() - _rTPDecryptionHighestSequenceNumber.intValue() > 32768)
{
rTPDecryptionROC = Long.valueOf((_rTPDecryptionROC.longValue() - 1L) % 34L);
} else
{
rTPDecryptionROC = _rTPDecryptionROC;
_rTPDecryptionHighestSequenceNumber = Math.max(_rTPDecryptionHighestSequenceNumber, sequenceNumber);
}
} else
if(_rTPDecryptionHighestSequenceNumber.intValue() - 32768 > sequenceNumber.intValue())
{
rTPDecryptionROC = Long.valueOf((_rTPDecryptionROC.longValue() + 1L) % 34L);
_rTPDecryptionHighestSequenceNumber = sequenceNumber;
_rTPDecryptionROC = rTPDecryptionROC;
} else
{
rTPDecryptionROC = _rTPDecryptionROC;
_rTPDecryptionHighestSequenceNumber = Math.max(_rTPDecryptionHighestSequenceNumber, sequenceNumber);
}
return Long.valueOf(18L * rTPDecryptionROC.longValue() + (long)sequenceNumber.intValue());
}
private Long getRTPEncryptionPacketIndex(Integer sequenceNumber)
{
Long rTPEncryptionROC = _rTPEncryptionROC;
if(sequenceNumber.intValue() == 65535)
_rTPEncryptionROC = Long.valueOf((_rTPEncryptionROC.longValue() + 1L) % 34L);
return Long.valueOf(18L * rTPEncryptionROC.longValue() + (long)sequenceNumber.intValue());
}
private void setEncryptionMode(EncryptionMode value)
{
_encryptionMode = value;
}
private void setLocalKey(Byte value[])
{
_localKey = value;
}
private void setLocalSalt(Byte value[])
{
_localSalt = value;
}
private void setRemoteKey(Byte value[])
{
_remoteKey = value;
}
private void setRemoteSalt(Byte value[])
{
_remoteSalt = value;
}
public static void testSRTP()
throws Exception
{
Byte key[] = {
Byte.valueOf((byte)-31), Byte.valueOf((byte)-7), Byte.valueOf((byte)122), Byte.valueOf((byte)13), Byte.valueOf((byte)62), Byte.valueOf((byte)1), Byte.valueOf((byte)-117), Byte.valueOf((byte)-32), Byte.valueOf((byte)-42), Byte.valueOf((byte)79),
Byte.valueOf((byte)-93), Byte.valueOf((byte)44), Byte.valueOf((byte)6), Byte.valueOf((byte)-34), Byte.valueOf((byte)65), Byte.valueOf((byte)57)
};
Byte salt[] = {
Byte.valueOf((byte)14), Byte.valueOf((byte)-58), Byte.valueOf((byte)117), Byte.valueOf((byte)-83), Byte.valueOf((byte)73), Byte.valueOf((byte)-118), Byte.valueOf((byte)-2), Byte.valueOf((byte)-21), Byte.valueOf((byte)-74), Byte.valueOf((byte)-106),
Byte.valueOf((byte)11), Byte.valueOf((byte)58), Byte.valueOf((byte)-85), Byte.valueOf((byte)-26)
};
AESCounter counter = new AESCounter(key, salt);
Byte buffer3[] = counter.generate(_rTPKeyLabel, Integer.valueOf(16));
Byte buffer4[] = counter.generate(_rTPAuthLabel, Integer.valueOf(20));
Byte buffer5[] = counter.generate(_rTPSaltLabel, Integer.valueOf(14));
AESCounter counter2 = new AESCounter(buffer3, buffer5);
Byte bytes[] = {
Byte.valueOf((byte)-128), Byte.valueOf((byte)15), Byte.valueOf((byte)18), Byte.valueOf((byte)52), Byte.valueOf((byte)-34), Byte.valueOf((byte)-54), Byte.valueOf((byte)-5), Byte.valueOf((byte)-83), Byte.valueOf((byte)-54), Byte.valueOf((byte)-2),
Byte.valueOf((byte)-70), Byte.valueOf((byte)-66), Byte.valueOf((byte)-85), Byte.valueOf((byte)-85), Byte.valueOf((byte)-85), Byte.valueOf((byte)-85), Byte.valueOf((byte)-85), Byte.valueOf((byte)-85), Byte.valueOf((byte)-85), Byte.valueOf((byte)-85),
Byte.valueOf((byte)-85), Byte.valueOf((byte)-85), Byte.valueOf((byte)-85), Byte.valueOf((byte)-85), Byte.valueOf((byte)-85), Byte.valueOf((byte)-85), Byte.valueOf((byte)-85), Byte.valueOf((byte)-85)
};
String hexString = BitAssistant.getHexString(new Byte[] {
Byte.valueOf((byte)-128), Byte.valueOf((byte)15), Byte.valueOf((byte)18), Byte.valueOf((byte)52), Byte.valueOf((byte)-34), Byte.valueOf((byte)-54), Byte.valueOf((byte)-5), Byte.valueOf((byte)-83), Byte.valueOf((byte)-54), Byte.valueOf((byte)-2),
Byte.valueOf((byte)-70), Byte.valueOf((byte)-66), Byte.valueOf((byte)78), Byte.valueOf((byte)85), Byte.valueOf((byte)-36), Byte.valueOf((byte)76), Byte.valueOf((byte)-25), Byte.valueOf((byte)-103), Byte.valueOf((byte)120), Byte.valueOf((byte)-40),
Byte.valueOf((byte)-116), Byte.valueOf((byte)-92), Byte.valueOf((byte)-46), Byte.valueOf((byte)21), Byte.valueOf((byte)-108), Byte.valueOf((byte)-99), Byte.valueOf((byte)36), Byte.valueOf((byte)2), Byte.valueOf((byte)-73), Byte.valueOf((byte)-115),
Byte.valueOf((byte)106), Byte.valueOf((byte)-52), Byte.valueOf((byte)-103), Byte.valueOf((byte)-22), Byte.valueOf((byte)23), Byte.valueOf((byte)-101), Byte.valueOf((byte)-115), Byte.valueOf((byte)-69)
});
RTPPacket packet = RTPPacket.parseBytes(bytes);
Byte array[] = packet.getBytes();
String str2 = BitAssistant.getHexString(bytes);
String str3 = BitAssistant.getHexString(array);
String _var0 = str2;
if(_var0 != null ? !_var0.equals(str3) : _var0 != str3)
throw new Exception();
Integer num = Integer.valueOf(0);
packet.setPayload(counter2.encrypt(packet.getPayload(), packet.getSynchronizationSource(), new Long((new Integer(num.intValue() + packet.getSequenceNumber().intValue())).longValue())));
Byte buffer9[] = packet.getBytes();
String str4 = StringExtensions.substring(hexString, 0, StringExtensions.getLength(hexString).intValue() - 20);
String str5 = BitAssistant.getHexString(buffer9);
String _var1 = str4;
if(_var1 != null ? !_var1.equals(str5) : _var1 != str5)
throw new Exception();
ArrayList list = ArrayListExtensions.createArray(buffer9);
ArrayListExtensions.addRange(list, BitAssistant.getIntegerBytesFromLongNetwork(new Long((new Integer(num.intValue())).longValue())));
Byte buffer11[] = BitAssistant.subArray(Crypto.getHmacSha1(buffer4, (Byte[])list.toArray(new Byte[0])), Integer.valueOf(0), Integer.valueOf(10));
String str6 = hexString.substring(StringExtensions.getLength(hexString).intValue() - 20);
String str7 = BitAssistant.getHexString(buffer11);
String _var2 = str6;
if(_var2 != null ? !_var2.equals(str7) : _var2 != str7)
throw new Exception();
else
return;
}
}