From a65f5f9feefae2d9a2907243c9f9c6f36351a17d Mon Sep 17 00:00:00 2001 From: DrKLO Date: Wed, 25 Dec 2013 02:25:13 +0400 Subject: [PATCH] more security checks --- .../messenger/ConnectionsManager.java | 12 +++ .../org/telegram/messenger/TcpConnection.java | 29 +++--- .../org/telegram/messenger/Utilities.java | 98 +++++++++++++++++-- 3 files changed, 122 insertions(+), 17 deletions(-) diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/ConnectionsManager.java b/TMessagesProj/src/main/java/org/telegram/messenger/ConnectionsManager.java index c9ed98114..753613987 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/ConnectionsManager.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/ConnectionsManager.java @@ -2342,6 +2342,18 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. } set.add(messageId); } + + byte[] realMessageKeyFull = Utilities.computeSHA1(messageData, 0, Math.min(messageLength + 32, messageData.length)); + if (realMessageKeyFull == null) { + return; + } + byte[] realMessageKey = new byte[16]; + System.arraycopy(realMessageKeyFull, realMessageKeyFull.length - 16, realMessageKey, 0, 16); + + if (!Arrays.equals(messageKey, realMessageKey)) { + FileLog.e("tmessages", "***** Error: invalid message key"); + return; + } if (!doNotProcess) { int messageLength = messageIs.readInt32(); diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/TcpConnection.java b/TMessagesProj/src/main/java/org/telegram/messenger/TcpConnection.java index 7711fe471..e4c675548 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/TcpConnection.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/TcpConnection.java @@ -131,6 +131,7 @@ public class TcpConnection extends PyroClientAdapter { } }); } + failedConnectionCount++; if (failedConnectionCount == 1) { if (hasSomeDataSinceLastConnect) { @@ -139,11 +140,13 @@ public class TcpConnection extends PyroClientAdapter { willRetryConnectCount = 1; } } - isNextPort = true; - if (failedConnectionCount > willRetryConnectCount) { - Datacenter datacenter = ConnectionsManager.Instance.datacenterWithId(datacenterId); - datacenter.nextAddressOrPort(); - failedConnectionCount = 0; + if (ConnectionsManager.isNetworkOnline()) { + isNextPort = true; + if (failedConnectionCount > willRetryConnectCount) { + Datacenter datacenter = ConnectionsManager.Instance.datacenterWithId(datacenterId); + datacenter.nextAddressOrPort(); + failedConnectionCount = 0; + } } FileLog.e("tmessages", e); @@ -410,7 +413,9 @@ public class TcpConnection extends PyroClientAdapter { Utilities.stageQueue.postRunnable(new Runnable() { @Override public void run() { - delegate.tcpConnectionClosed(TcpConnection.this); + if (delegate != null) { + delegate.tcpConnectionClosed(TcpConnection.this); + } } }); } @@ -424,11 +429,13 @@ public class TcpConnection extends PyroClientAdapter { willRetryConnectCount = 1; } } - isNextPort = true; - if (failedConnectionCount > willRetryConnectCount) { - Datacenter datacenter = ConnectionsManager.Instance.datacenterWithId(datacenterId); - datacenter.nextAddressOrPort(); - failedConnectionCount = 0; + if (ConnectionsManager.isNetworkOnline()) { + isNextPort = true; + if (failedConnectionCount > willRetryConnectCount) { + Datacenter datacenter = ConnectionsManager.Instance.datacenterWithId(datacenterId); + datacenter.nextAddressOrPort(); + failedConnectionCount = 0; + } } FileLog.d("tmessages", "Reconnect " + hostAddress + ":" + hostPort + " " + TcpConnection.this); try { diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/Utilities.java b/TMessagesProj/src/main/java/org/telegram/messenger/Utilities.java index 912bf2407..af042bf88 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/Utilities.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/Utilities.java @@ -12,6 +12,7 @@ import android.app.Activity; import android.app.ProgressDialog; import android.content.Context; import android.content.Intent; +import android.content.SharedPreferences; import android.graphics.Typeface; import android.net.Uri; import android.os.Environment; @@ -20,6 +21,7 @@ import android.text.Html; import android.text.SpannableStringBuilder; import android.text.format.DateFormat; import android.util.AttributeSet; +import android.util.Base64; import android.view.View; import android.view.inputmethod.InputMethodManager; @@ -42,6 +44,7 @@ import java.security.MessageDigest; import java.security.PublicKey; import java.security.spec.RSAPublicKeySpec; import java.text.SimpleDateFormat; +import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.Hashtable; @@ -55,9 +58,7 @@ public class Utilities { public static int statusBarHeight = 0; private final static Integer lock = 1; - public static String[] goodPrimes = { - "C71CAEB9C6B1C9048E6C522F70F13F73980D40238E3E21C14934D037563D930F48198A0AA7C14058229493D22530F4DBFA336F6E0AC925139543AED44CCE7C3720FD51F69458705AC68CD4FE6B6B13ABDC9746512969328454F18FAF8C595F642477FE96BB2A941D5BCD1D4AC8CC49880708FA9B378E3C4F3A9060BEE67CF9A4A4A695811051907E162753B56B0F6B410DBA74D8A84B2A14B3144E0EF1284754FD17ED950D5965B4B9DD46582DB1178D169C6BC465B0D6FF9CA3928FEF5B9AE4E418FC15E83EBEA0F87FA9FF5EED70050DED2849F47BF959D956850CE929851F0D8115F635B105EE2E4E15D04B2454BF6F4FADF034B10403119CD8E3B92FCC5B" - }; + public static ArrayList goodPrimes = new ArrayList(); public static class TPFactorizedValue { public long p, q; @@ -73,6 +74,26 @@ public class Utilities { public native static byte[] aesIgeEncryption(byte[] _what, byte[] _key, byte[] _iv, boolean encrypt, boolean changeIv); static { + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("primes", Context.MODE_PRIVATE); + String primes = preferences.getString("primes", null); + if (primes == null) { + goodPrimes.add("C71CAEB9C6B1C9048E6C522F70F13F73980D40238E3E21C14934D037563D930F48198A0AA7C14058229493D22530F4DBFA336F6E0AC925139543AED44CCE7C3720FD51F69458705AC68CD4FE6B6B13ABDC9746512969328454F18FAF8C595F642477FE96BB2A941D5BCD1D4AC8CC49880708FA9B378E3C4F3A9060BEE67CF9A4A4A695811051907E162753B56B0F6B410DBA74D8A84B2A14B3144E0EF1284754FD17ED950D5965B4B9DD46582DB1178D169C6BC465B0D6FF9CA3928FEF5B9AE4E418FC15E83EBEA0F87FA9FF5EED70050DED2849F47BF959D956850CE929851F0D8115F635B105EE2E4E15D04B2454BF6F4FADF034B10403119CD8E3B92FCC5B"); + } else { + try { + byte[] bytes = Base64.decode(primes, Base64.DEFAULT); + if (bytes != null) { + SerializedData data = new SerializedData(bytes); + int count = data.readInt32(); + for (int a = 0; a < count; a++) { + goodPrimes.add(data.readString()); + } + } + } catch (Exception e) { + FileLog.e("tmessages", e); + goodPrimes.clear(); + goodPrimes.add("C71CAEB9C6B1C9048E6C522F70F13F73980D40238E3E21C14934D037563D930F48198A0AA7C14058229493D22530F4DBFA336F6E0AC925139543AED44CCE7C3720FD51F69458705AC68CD4FE6B6B13ABDC9746512969328454F18FAF8C595F642477FE96BB2A941D5BCD1D4AC8CC49880708FA9B378E3C4F3A9060BEE67CF9A4A4A695811051907E162753B56B0F6B410DBA74D8A84B2A14B3144E0EF1284754FD17ED950D5965B4B9DD46582DB1178D169C6BC465B0D6FF9CA3928FEF5B9AE4E418FC15E83EBEA0F87FA9FF5EED70050DED2849F47BF959D956850CE929851F0D8115F635B105EE2E4E15D04B2454BF6F4FADF034B10403119CD8E3B92FCC5B"); + } + } System.loadLibrary("tmessages"); } @@ -104,6 +125,11 @@ public class Utilities { if (!(g >= 2 && g <= 7)) { return false; } + + if (prime.length != 256 || prime[0] >= 0) { + return false; + } + String hex = bytesToHex(prime); for (String cached : goodPrimes) { if (cached.equals(hex)) { @@ -111,16 +137,65 @@ public class Utilities { } } - if (prime.length != 256 || prime[0] >= 0) { - return false; + BigInteger dhBI = new BigInteger(1, prime); + + if (g == 2) { // p mod 8 = 7 for g = 2; + BigInteger res = dhBI.mod(BigInteger.valueOf(8)); + if (res.intValue() != 7) { + return false; + } + } else if (g == 3) { // p mod 3 = 2 for g = 3; + BigInteger res = dhBI.mod(BigInteger.valueOf(3)); + if (res.intValue() != 2) { + return false; + } + } else if (g == 5) { // p mod 5 = 1 or 4 for g = 5; + BigInteger res = dhBI.mod(BigInteger.valueOf(5)); + int val = res.intValue(); + if (val != 1 && val != 4) { + return false; + } + } else if (g == 6) { // p mod 24 = 19 or 23 for g = 6; + BigInteger res = dhBI.mod(BigInteger.valueOf(24)); + int val = res.intValue(); + if (val != 19 && val != 23) { + return false; + } + } else if (g == 7) { // p mod 7 = 3, 5 or 6 for g = 7. + BigInteger res = dhBI.mod(BigInteger.valueOf(7)); + int val = res.intValue(); + if (val != 3 && val != 5 && val != 6) { + return false; + } } - BigInteger dhBI = new BigInteger(1, prime); BigInteger dhBI2 = dhBI.subtract(BigInteger.valueOf(1)).divide(BigInteger.valueOf(2)); if (!dhBI.isProbablePrime(30) || !dhBI2.isProbablePrime(30)) { return false; } + goodPrimes.add(hex); + + globalQueue.postRunnable(new Runnable() { + @Override + public void run() { + try { + SerializedData data = new SerializedData(); + data.writeInt32(goodPrimes.size()); + for (String pr : goodPrimes) { + data.writeString(pr); + } + byte[] bytes = data.toByteArray(); + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("primes", Context.MODE_PRIVATE); + SharedPreferences.Editor editor = preferences.edit(); + editor.putString("primes", Base64.encodeToString(bytes, Base64.DEFAULT)); + editor.commit(); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } + }); + return true; } @@ -153,6 +228,17 @@ public class Utilities { } } + public static byte[] computeSHA1(byte[] convertme, int offset, int len) { + try { + MessageDigest md = MessageDigest.getInstance("SHA-1"); + md.update(convertme, offset, len); + return md.digest(); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + return null; + } + public static byte[] computeSHA1(byte[] convertme) { try { MessageDigest md = MessageDigest.getInstance("SHA-1");