Add support for APK signing certificate SHA-256 digest and detecting APK release type and add them to App Info reports

The `TermuxConstants` class has been updated to `v0.21.0`. Check its Changelog sections for info on changes.
This commit is contained in:
agnostic-apollo
2021-05-13 15:40:09 +05:00
parent 4629276500
commit 1e30022ce7
4 changed files with 107 additions and 4 deletions

View File

@@ -10,6 +10,8 @@ public class DataUtils {
public static final int TRANSACTION_SIZE_LIMIT_IN_BYTES = 100 * 1024; // 100KB public static final int TRANSACTION_SIZE_LIMIT_IN_BYTES = 100 * 1024; // 100KB
private static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();
public static String getTruncatedCommandOutput(String text, int maxLength, boolean fromEnd, boolean onNewline, boolean addPrefix) { public static String getTruncatedCommandOutput(String text, int maxLength, boolean fromEnd, boolean onNewline, boolean addPrefix) {
if (text == null) return null; if (text == null) return null;
@@ -43,7 +45,7 @@ public class DataUtils {
/** /**
* Get the {@code float} from a {@link String}. * Get the {@code float} from a {@link String}.
* *
* @param value The {@link String value. * @param value The {@link String} value.
* @param def The default value if failed to read a valid value. * @param def The default value if failed to read a valid value.
* @return Returns the {@code float} value after parsing the {@link String} value, otherwise * @return Returns the {@code float} value after parsing the {@link String} value, otherwise
* returns default if failed to read a valid value, like in case of an exception. * returns default if failed to read a valid value, like in case of an exception.
@@ -62,7 +64,7 @@ public class DataUtils {
/** /**
* Get the {@code int} from a {@link String}. * Get the {@code int} from a {@link String}.
* *
* @param value The {@link String value. * @param value The {@link String} value.
* @param def The default value if failed to read a valid value. * @param def The default value if failed to read a valid value.
* @return Returns the {@code int} value after parsing the {@link String} value, otherwise * @return Returns the {@code int} value after parsing the {@link String} value, otherwise
* returns default if failed to read a valid value, like in case of an exception. * returns default if failed to read a valid value, like in case of an exception.
@@ -78,6 +80,22 @@ public class DataUtils {
} }
} }
/**
* Get the {@code hex string} from a {@link byte[]}.
*
* @param bytes The {@link byte[]} value.
* @return Returns the {@code hex string} value.
*/
public static String bytesToHex(byte[] bytes) {
char[] hexChars = new char[bytes.length * 2];
for (int j = 0; j < bytes.length; j++) {
int v = bytes[j] & 0xFF;
hexChars[j * 2] = HEX_ARRAY[v >>> 4];
hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F];
}
return new String(hexChars);
}
/** /**
* Get an {@code int} from {@link Bundle} that is stored as a {@link String}. * Get an {@code int} from {@link Bundle} that is stored as a {@link String}.
* *

View File

@@ -3,11 +3,15 @@ package com.termux.shared.packages;
import android.content.Context; import android.content.Context;
import android.content.pm.ApplicationInfo; import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo; import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import com.termux.shared.data.DataUtils;
import com.termux.shared.logger.Logger; import com.termux.shared.logger.Logger;
import java.security.MessageDigest;
public class PackageUtils { public class PackageUtils {
/** /**
@@ -32,8 +36,19 @@ public class PackageUtils {
* @return Returns the {@link PackageInfo}. This will be {@code null} if an exception is raised. * @return Returns the {@link PackageInfo}. This will be {@code null} if an exception is raised.
*/ */
public static PackageInfo getPackageInfoForPackage(@NonNull final Context context) { public static PackageInfo getPackageInfoForPackage(@NonNull final Context context) {
return getPackageInfoForPackage(context, 0);
}
/**
* Get the {@link PackageInfo} for the package associated with the {@code context}.
*
* @param context The {@link Context} for the package.
* @param flags The flags to pass to {@link PackageManager#getPackageInfo(String, int)}.
* @return Returns the {@link PackageInfo}. This will be {@code null} if an exception is raised.
*/
public static PackageInfo getPackageInfoForPackage(@NonNull final Context context, final int flags) {
try { try {
return context.getPackageManager().getPackageInfo(context.getPackageName(), 0); return context.getPackageManager().getPackageInfo(context.getPackageName(), flags);
} catch (final Exception e) { } catch (final Exception e) {
return null; return null;
} }
@@ -107,4 +122,21 @@ public class PackageUtils {
} }
} }
/**
* Get the {@code SHA-256 digest} of signing certificate for the package associated with the {@code context}.
*
* @param context The {@link Context} for the package.
* @return Returns the{@code SHA-256 digest}. This will be {@code null} if an exception is raised.
*/
public static String getSigningCertificateSHA256DigestForPackage(@NonNull final Context context) {
try {
PackageInfo packageInfo = getPackageInfoForPackage(context, PackageManager.GET_SIGNATURES);
if (packageInfo == null) return null;
return DataUtils.bytesToHex(MessageDigest.getInstance("SHA-256").digest(packageInfo.signatures[0].toByteArray()));
} catch (final Exception e) {
return null;
}
}
} }

View File

@@ -7,7 +7,7 @@ import java.util.Arrays;
import java.util.List; import java.util.List;
/* /*
* Version: v0.20.0 * Version: v0.21.0
* *
* Changelog * Changelog
* *
@@ -142,6 +142,11 @@ import java.util.List;
* - Added `TERMUX_WIKI`, `TERMUX_WIKI_URL`, `TERMUX_PLUGIN_APP_NAMES_LIST`, `TERMUX_PLUGIN_APP_PACKAGE_NAMES_LIST`. * - Added `TERMUX_WIKI`, `TERMUX_WIKI_URL`, `TERMUX_PLUGIN_APP_NAMES_LIST`, `TERMUX_PLUGIN_APP_PACKAGE_NAMES_LIST`.
* - Added `TERMUX_SETTINGS_ACTIVITY_NAME`. * - Added `TERMUX_SETTINGS_ACTIVITY_NAME`.
* *
* - 0.21.0 (2021-05-13)
* - Added `APK_RELEASE_FDROID`, `APK_RELEASE_FDROID_SIGNING_CERTIFICATE_SHA256_DIGEST`,
* - Added `APK_RELEASE_GITHUB_DEBUG_BUILD`, `APK_RELEASE_GITHUB_DEBUG_BUILD_SIGNING_CERTIFICATE_SHA256_DIGEST`,
* - Added `APK_RELEASE_GOOGLE_PLAYSTORE`, `APK_RELEASE_GOOGLE_PLAYSTORE_SIGNING_CERTIFICATE_SHA256_DIGEST`.
*
*/ */
/** /**
@@ -351,6 +356,32 @@ public final class TermuxConstants {
/*
* Termux APK releases.
*/
/** F-Droid APK release */
public static final String APK_RELEASE_FDROID = "F-Droid"; // Default: "F-Droid"
/** F-Droid APK release signing certificate SHA-256 digest */
public static final String APK_RELEASE_FDROID_SIGNING_CERTIFICATE_SHA256_DIGEST = "228FB2CFE90831C1499EC3CCAF61E96E8E1CE70766B9474672CE427334D41C42"; // Default: "228FB2CFE90831C1499EC3CCAF61E96E8E1CE70766B9474672CE427334D41C42"
/** Github Debug Build APK release */
public static final String APK_RELEASE_GITHUB_DEBUG_BUILD = "Github Debug Build"; // Default: "Github Debug Build"
/** Github Debug Build APK release signing certificate SHA-256 digest */
public static final String APK_RELEASE_GITHUB_DEBUG_BUILD_SIGNING_CERTIFICATE_SHA256_DIGEST = "B6DA01480EEFD5FBF2CD3771B8D1021EC791304BDD6C4BF41D3FAABAD48EE5E1"; // Default: "B6DA01480EEFD5FBF2CD3771B8D1021EC791304BDD6C4BF41D3FAABAD48EE5E1"
/** Google Play Store APK release */
public static final String APK_RELEASE_GOOGLE_PLAYSTORE = "Google Play Store"; // Default: "Google Play Store"
/** Google Play Store APK release signing certificate SHA-256 digest */
public static final String APK_RELEASE_GOOGLE_PLAYSTORE_SIGNING_CERTIFICATE_SHA256_DIGEST = "738F0A30A04D3C8A1BE304AF18D0779BCF3EA88FB60808F657A3521861C2EBF9"; // Default: "738F0A30A04D3C8A1BE304AF18D0779BCF3EA88FB60808F657A3521861C2EBF9"
/* /*
* Termux packages urls. * Termux packages urls.
*/ */

View File

@@ -227,6 +227,13 @@ public class TermuxUtils {
appendPropertyToMarkdown(markdownString,"TARGET_SDK", PackageUtils.getTargetSDKForPackage(context)); appendPropertyToMarkdown(markdownString,"TARGET_SDK", PackageUtils.getTargetSDKForPackage(context));
appendPropertyToMarkdown(markdownString,"IS_DEBUG_BUILD", PackageUtils.isAppForPackageADebugBuild(context)); appendPropertyToMarkdown(markdownString,"IS_DEBUG_BUILD", PackageUtils.isAppForPackageADebugBuild(context));
String signingCertificateSHA256Digest = PackageUtils.getSigningCertificateSHA256DigestForPackage(context);
Logger.logError("'" + signingCertificateSHA256Digest + "'");
if (signingCertificateSHA256Digest != null) {
appendPropertyToMarkdown(markdownString,"APK_RELEASE", getAPKRelease(signingCertificateSHA256Digest));
appendPropertyToMarkdown(markdownString,"SIGNING_CERTIFICATE_SHA256_DIGEST", signingCertificateSHA256Digest);
}
return markdownString.toString(); return markdownString.toString();
} }
@@ -490,4 +497,19 @@ public class TermuxUtils {
return df.format(new Date()); return df.format(new Date());
} }
public static String getAPKRelease(String signingCertificateSHA256Digest) {
if (signingCertificateSHA256Digest == null) return "null";
switch (signingCertificateSHA256Digest.toUpperCase()) {
case TermuxConstants.APK_RELEASE_FDROID_SIGNING_CERTIFICATE_SHA256_DIGEST:
return TermuxConstants.APK_RELEASE_FDROID;
case TermuxConstants.APK_RELEASE_GITHUB_DEBUG_BUILD_SIGNING_CERTIFICATE_SHA256_DIGEST:
return TermuxConstants.APK_RELEASE_GITHUB_DEBUG_BUILD;
case TermuxConstants.APK_RELEASE_GOOGLE_PLAYSTORE_SIGNING_CERTIFICATE_SHA256_DIGEST:
return TermuxConstants.APK_RELEASE_GOOGLE_PLAYSTORE;
default:
return "Unknown";
}
}
} }