From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Oliver Scott <olivercscott@gmail.com>
Date: Thu, 5 Jan 2023 19:42:40 -0500
Subject: [PATCH] Always add Briar and Tor Browser to Orbot's lockdown
 allowlist

[tad@spotco.us]: fixup arraylist handling, add logging, ignore missing package
lockdownAllowlist can be either null or immutable, the latter case wasn't handled

Change-Id: I62c2553c8877b946d7e7e1ca4ef113f963d3f8eb
---
 .../com/android/server/connectivity/Vpn.java  | 40 +++++++++++++++++++
 1 file changed, 40 insertions(+)

diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index 8510de4ef201..2cc66fbb871c 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -47,9 +47,11 @@ import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.ServiceConnection;
 import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.ResolveInfo;
+import android.content.pm.Signature;
 import android.content.pm.UserInfo;
 import android.net.ConnectivityManager;
 import android.net.DnsResolver;
@@ -121,6 +123,7 @@ import android.system.keystore2.KeyPermission;
 import android.text.TextUtils;
 import android.util.ArraySet;
 import android.util.Log;
+import android.util.Pair;
 import android.util.Range;
 
 import com.android.internal.R;
@@ -140,6 +143,7 @@ import com.android.server.vcn.util.PersistableBundleUtils;
 
 import libcore.io.IoUtils;
 
+import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FileDescriptor;
 import java.io.IOException;
@@ -891,6 +895,42 @@ public class Vpn {
             return false;
         }
 
+        final String ORBOT_PACKAGE_NAME = "org.torproject.android";
+        if (ORBOT_PACKAGE_NAME.equals(packageName)) {
+            if (lockdownAllowlist == null) {
+                lockdownAllowlist = new ArrayList<>();
+                Log.i(TAG, "lockdown allowlist was null, created");
+            } else {
+                lockdownAllowlist = new ArrayList<>(lockdownAllowlist);
+                Log.i(TAG, "lockdown allowlist existed, recreated");
+            }
+            final Set<Pair<String, String>> ORBOT_LOCKDOWN_ALLOWLIST = Set.of(
+                    new Pair<>("org.torproject.torbrowser", "308205953082037DA003020102020900BA2DF613084D2BFD300D06092A864886F70D01010B0500305C3114301206035504030C0B546F722042726F7773657231183016060355040A0C0F54686520546F722050726F6A6563743110300E06035504070C0753656174746C65310B300906035504080C025741310B3009060355040613025553301E170D3139303531383231353834325A170D3334303531343231353834325A305C3114301206035504030C0B546F722042726F7773657231183016060355040A0C0F54686520546F722050726F6A6563743110300E06035504070C0753656174746C65310B300906035504080C025741310B300906035504061302555330820222300D06092A864886F70D01010105000382020F003082020A0282020100F3EE231D69CE435F324AD4AA398AEF3131876AE74563428B61F6AD8C65C522FDDF6EDCC24F6E615AD978598F8C595C632F2D51DF8225EC26742AF7479D8B45EEA379AC7C21E8665BDFB2AC8F0008C0B47A2BA89CAA39C581C0827D35599DA3D6E0FD4045DD4EBDEEDE39790BE6DD630B6BA7908BEB39E20EAA9C42DBCC5BB7B4F7A43F0E2F9DD91E076E2C7CDCC2F8F9B626628F366831EB917D2E54DEF859DF042084460AADCB1D53FF8114F8D666494992B260AF2B7F4CDD80B7733296B79E8831CBC8BA54B028CF3202DFDA84855540567C62AED813F32BAEE137CE3FC149A109B0A36E32FCB28A2A8D2E7C2F67D9B189FFD2E53FFF8EDDADE9D05D3E33560E73ECBF1F8C582077272AE7B5E9D16E0376A0AB39606B2089E78CBC4A37DA4D85F5965DB420CB6D77717348A21B49358F0C34742DA74B69F6746A2988EB815E2910A7F492F52E14DCC17414BE735594E6B6AD62BF0A701D3A3DD27457050101E568CF32536A4E7FD069908BACCF2197BB9C4C2585446DF2BDA23C4EDDA671CF1A881803959951071F8D03AC8DFF38AB00ABF88C87CD3783815032F9288169194EAD8EA0A28A518CD8EC0A0CD5C60800DE1683A0436B09A026524ABEDFF94E0D7AC6EF3E06F8865C780BC1818C64134389FF30D4331053EA2591D65808215C6878D1FB3E4FE7627B926FB9C1031A778F6FFE87BBFE35141B36F271B05075E75F0203010001A35A305830090603551D1304023000300B0603551D0F040403020780301D0603551D0E041604146D96FBE7BED0BD62CBB0C2607B6EDA93EDB69455301F0603551D230418301680146D96FBE7BED0BD62CBB0C2607B6EDA93EDB69455300D06092A864886F70D01010B0500038202010027C7E940533A854AEFCE955438A5344BD366CD2DD8C24E8DDC990D31D3AD5C5331EABCB2F01ED5517A19CC5AD5439DD8193F94D5474D76131762647DAE91EDB59EE90A84CEC2DFC61DDAEB12B88BCC58ED6736AA650AE0DB72372BC70E2651029D240D8993A18482B88881920FD50E023F7FFDE705B723CEB6F5E6AFA969A96B1C9531C9443694BFE504610E208C852E7C0B2CCD063E39DD5CCA83B3E901B1A3372DA55E4C854607D4C35673348A511B5929B825BF058F8BD3ABA2961C4C273AA124D24144D9A24961A6135B3BB8CDE2290A54271BECE02E0CBAF6ABD4AF13FF1D7C4A5192CF577A1DE47A51030308940F900BFBACACAB85F0D08B0606364415070CF851E630C8516656E8324B86DAACF482D571C1FD3865264E091D189D07171695E424E78FE91ABD25A993B6014C5A97647CC963C2A2602632299C471C8E29312592CDBC84E6DD275E8F008651192F197B969701A276DAF0672FCD3B5D734328D53B910F0931FA11A176EC00EAB73C813F30C33BF4E2E347F15BFD30701FBB0353410F991AE2C5B4492E51E0C439F517F4F34791D4CED1A362F3D1FB47AD3EDE2B41C1D038A2DD79B2AB344B2F1C7BEF3E339BA6DCED49461EF7DF58B18090FC1A50DFA3F6F058F561B2C909F61F0FBB351B79ABFFD7553D14B568284A863B5CD373F0F69C23DB81456F3F2F9DCEADDE55670E9D04D870E5A06BEC2BCAEE5D"),
+                    new Pair<>("org.briarproject.briar.android", "308202D5308201BDA00302010202040B7BA025300D06092A864886F70D01010B0500301B31193017060355040A1310627269617270726F6A6563742E6F7267301E170D3138303432353135323735365A170D3435303931303135323735365A301B31193017060355040A1310627269617270726F6A6563742E6F726730820122300D06092A864886F70D01010105000382010F003082010A0282010100887D49815638C3E01B08FA5CD80A62FE2640DAB155E848EBC0CF18ABD61618CE1B17632143D612D3AF282DC6B477E43286E5CD559E0DEB5AE951532A1347E95C2A9BC064FBE06E21528A0DDD3AB734679FEF9E31A49042694BF8C4E2DA66F820F6D2BF1F9D5180C409152F80FFD5EAB39B5423F8F09127A8B89D92B0F588284F783356B8812FC35893A526671573B8DDC3A85BAB46DC60DEA13351A2091728C037F20929DD668E757E905F98CC31D7B8B95E9E5D103A33320C71282CD0C797961C99B65CD33F478551FB28F51D5D2A3D636897AC87C1EB5D25323831526424014719136A7104BF8B60A6A30882C526056FB7D5372EA79371CAEAC7C92BC14B050203010001A321301F301D0603551D0E04160414E76D3580725F8DBD28912FF4DF18375F60B49211300D06092A864886F70D01010B050003820101002BAAA21FDF7301562EC3597705B4989B77114428619E84A8288032DB95251CFBB938DDE28BEACBFC63C6A52DE1520973EF19E8355534732139C374B320BEF56E8EF2CA2129307C589D99912317F57CA8639427B7B20225DAB64D12112B57510081A3E6B33EBEE96CAC80E13CDBC73C41BD1F4E0125B6376B95A71411223C15DD8AA1A5734029713097C27073EBCC325688991EF3A46D4CD03E48FD46749937F641C618B783AC7FF0D428E0443EBE36A3D23D82014EA95758344EBFA2A041253CEB7EE6B687857956EE69840E0DA71A6529D33F3674C78C3BAFFBD9724858EA82CB651B58D4D8A0607E763BD0F37D145C3EE705F7D41322AA1A00D5A36F1275EA")
+            );
+            for (Pair<String, String> pair : ORBOT_LOCKDOWN_ALLOWLIST) {
+                try {
+                    PackageInfo packageInfo = mUserIdContext.getPackageManager()
+                            .getPackageInfo(pair.first, PackageManager.PackageInfoFlags.of(
+                                    PackageManager.GET_SIGNING_CERTIFICATES));
+                    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+                    for (Signature signature : packageInfo.signingInfo.getApkContentsSigners()) {
+                        outputStream.write(signature.toByteArray());
+                    }
+                    if (Signature.areEffectiveMatch(new Signature(outputStream.toByteArray()), new Signature(pair.second))) {
+                        if (!lockdownAllowlist.contains(pair.first)) {
+                            lockdownAllowlist.add(pair.first);
+                            Log.i(TAG, "Added " + pair.first + " to lockdown allowlist");
+                        }
+                    } else {
+                        Log.w(TAG, "Not adding " + pair.first + " to lockdown allowlist due to signature mismatch");
+                    }
+                } catch (NameNotFoundException ignore) { } catch (Exception e) {
+                    Log.w(TAG, "Failed to add " + pair.first + " to lockdown allowlist", e);
+                }
+            }
+        }
+
         if (lockdownAllowlist != null) {
             for (String pkg : lockdownAllowlist) {
                 if (pkg.contains(",")) {
