Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ android {
applicationId "io.rtek.rtvoice"
minSdkVersion 21
targetSdkVersion 25
versionCode 4
versionName "1.0.3"
versionCode 12
versionName "1.0.8"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />

<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
Expand Down
Binary file added app/src/main/assets/dialing.wav
Binary file not shown.
65 changes: 48 additions & 17 deletions app/src/main/java/io/rtek/rtvoice/Call.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import android.util.Log;

import java.io.IOException;
import java.math.BigInteger;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
Expand Down Expand Up @@ -57,7 +58,7 @@ public class Call extends Thread {
//Interrupt
private boolean closing = false;
private boolean secure = false;
private String key;
private byte[] key;



Expand All @@ -67,6 +68,16 @@ public Call(ICallListener listener, int localCallerId, int remoteCallerId){
this.remoteCallerId = remoteCallerId;
}

public boolean hasKey(){
return key != null;
}

public byte[] generateKey() throws Exception{
SecureRandom random = new SecureRandom();
this.key = getRawKey(new BigInteger(130, random).toByteArray());
return this.key;
}

public void close(){
this.closing = true;
if (sock != null){
Expand All @@ -87,12 +98,31 @@ public void close(){
listener.callEnded();
}

public void start(String server, String encryptionKey){
//Supply new key
public void start(String server, String encryptionKey) throws Exception{
this.server = server;
if(!encryptionKey.isEmpty()){
secure = true;
this.key = encryptionKey;
if(encryptionKey.isEmpty()){
throw new Exception("No encryption key supplied!");
}
this.secure = true;
this.key = hexStringToByteArray(encryptionKey);
start();
}

//Use previously generated key
public void start(String server) throws Exception{
this.server = server;
if(key == null){
throw new Exception("No encryption key generated!");
}
this.secure = true;
start();
}

//Legacy
public void startWithoutEncryption(String server){
this.server = server;
this.secure = false;
start();
}

Expand Down Expand Up @@ -141,7 +171,7 @@ public void run() {
DatagramPacket receivePacket = new DatagramPacket(receiveBuffer_Encrypted, receiveBuffer_Encrypted.length);
sock.receive(receivePacket);
Log.w("VOICE", "Packet of " + receivePacket.getLength() + " was received from " + receivePacket.getAddress());
receiveBuffer = decrypt(hexStringToByteArray(key), receiveBuffer_Encrypted);
receiveBuffer = decrypt(key, receiveBuffer_Encrypted);
track.write(receiveBuffer, 0, receiveBuffer.length);
}else {
DatagramPacket receivePacket = new DatagramPacket(receiveBuffer, receiveBuffer.length);
Expand Down Expand Up @@ -176,7 +206,7 @@ public void run() {
return;
int read = recorder.read(transmittBuffer, 0, transmittBuffer.length);
if(secure){
transmittBuffer_Encrypted = encrypt(hexStringToByteArray(key), transmittBuffer);
transmittBuffer_Encrypted = encrypt(key, transmittBuffer);
DatagramPacket packet = new DatagramPacket(transmittBuffer_Encrypted, transmittBuffer_Encrypted.length);
sock.send(packet);
}else{
Expand Down Expand Up @@ -210,23 +240,15 @@ private byte[] encrypt(byte[] raw, byte[] clear) throws Exception {
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
byte[] data = cipher.doFinal(clear);
byte[] iv = cipher.getIV();
byte[] packet = new byte[data.length+iv.length];
for (int i = 0; i < iv.length; i++)
packet[i] = iv[i];
for (int i = 0; i < data.length; i++)
packet[iv.length+i] = data[i];
return data;
return cipher.doFinal(clear);
}

private byte[] decrypt(byte[] raw, byte[] encrypted) throws Exception {
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
IvParameterSpec ivspec = new IvParameterSpec(encrypted, 0, 16);
cipher.init(Cipher.DECRYPT_MODE, skeySpec, ivspec);
byte[] decrypted = cipher.doFinal(encrypted, 16, encrypted.length-16);
return decrypted;
return cipher.doFinal(encrypted, 16, encrypted.length-16);
}

public static byte[] hexStringToByteArray(String s) {
Expand All @@ -238,4 +260,13 @@ public static byte[] hexStringToByteArray(String s) {
}
return data;
}
private static byte[] getRawKey(byte[] seed) throws Exception {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
sr.setSeed(seed);
kgen.init(128, sr);
SecretKey skey = kgen.generateKey();
byte[] raw = skey.getEncoded();
return raw;
}
}
Loading