diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000000000000000000000000000000000000..acbb55899ff62321fa960154ae1c6b294a1d70f9 --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,135 @@ +<component name="ProjectCodeStyleConfiguration"> + <code_scheme name="Project" version="173"> + <JetCodeStyleSettings> + <option name="PACKAGES_TO_USE_STAR_IMPORTS"> + <value> + <package name="java.util" alias="false" withSubpackages="false" /> + <package name="kotlinx.android.synthetic" alias="false" withSubpackages="true" /> + <package name="io.ktor" alias="false" withSubpackages="true" /> + </value> + </option> + <option name="PACKAGES_IMPORT_LAYOUT"> + <value> + <package name="" alias="false" withSubpackages="true" /> + <package name="java" alias="false" withSubpackages="true" /> + <package name="javax" alias="false" withSubpackages="true" /> + <package name="kotlin" alias="false" withSubpackages="true" /> + <package name="" alias="true" withSubpackages="true" /> + </value> + </option> + </JetCodeStyleSettings> + <codeStyleSettings language="XML"> + <option name="FORCE_REARRANGE_MODE" value="1" /> + <indentOptions> + <option name="CONTINUATION_INDENT_SIZE" value="4" /> + </indentOptions> + <arrangement> + <rules> + <section> + <rule> + <match> + <AND> + <NAME>xmlns:android</NAME> + <XML_ATTRIBUTE /> + <XML_NAMESPACE>^$</XML_NAMESPACE> + </AND> + </match> + </rule> + </section> + <section> + <rule> + <match> + <AND> + <NAME>xmlns:.*</NAME> + <XML_ATTRIBUTE /> + <XML_NAMESPACE>^$</XML_NAMESPACE> + </AND> + </match> + <order>BY_NAME</order> + </rule> + </section> + <section> + <rule> + <match> + <AND> + <NAME>.*:id</NAME> + <XML_ATTRIBUTE /> + <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE> + </AND> + </match> + </rule> + </section> + <section> + <rule> + <match> + <AND> + <NAME>.*:name</NAME> + <XML_ATTRIBUTE /> + <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE> + </AND> + </match> + </rule> + </section> + <section> + <rule> + <match> + <AND> + <NAME>name</NAME> + <XML_ATTRIBUTE /> + <XML_NAMESPACE>^$</XML_NAMESPACE> + </AND> + </match> + </rule> + </section> + <section> + <rule> + <match> + <AND> + <NAME>style</NAME> + <XML_ATTRIBUTE /> + <XML_NAMESPACE>^$</XML_NAMESPACE> + </AND> + </match> + </rule> + </section> + <section> + <rule> + <match> + <AND> + <NAME>.*</NAME> + <XML_ATTRIBUTE /> + <XML_NAMESPACE>^$</XML_NAMESPACE> + </AND> + </match> + <order>BY_NAME</order> + </rule> + </section> + <section> + <rule> + <match> + <AND> + <NAME>.*</NAME> + <XML_ATTRIBUTE /> + <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE> + </AND> + </match> + <order>ANDROID_ATTRIBUTE_ORDER</order> + </rule> + </section> + <section> + <rule> + <match> + <AND> + <NAME>.*</NAME> + <XML_ATTRIBUTE /> + <XML_NAMESPACE>.*</XML_NAMESPACE> + </AND> + </match> + <order>BY_NAME</order> + </rule> + </section> + </rules> + </arrangement> + </codeStyleSettings> + </code_scheme> +</component> \ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 0000000000000000000000000000000000000000..a5102127489e41a3aa6032559e6004353c832776 --- /dev/null +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ +<component name="ProjectCodeStyleConfiguration"> + <state> + <option name="PREFERRED_PROJECT_CODE_STYLE" value="AndroidStyle" /> + </state> +</component> \ No newline at end of file diff --git a/app/src/main/java/com/besendorf/androidsecurityscanner/MainActivity.java b/app/src/main/java/com/besendorf/androidsecurityscanner/MainActivity.java index ef6b83b5ea934a36ca326d4defecad5dbef0a109..cb2315634cdc1471e2915ed65e1403d83a472d6b 100644 --- a/app/src/main/java/com/besendorf/androidsecurityscanner/MainActivity.java +++ b/app/src/main/java/com/besendorf/androidsecurityscanner/MainActivity.java @@ -20,10 +20,9 @@ package com.besendorf.androidsecurityscanner; import android.annotation.SuppressLint; -import androidx.biometric.BiometricManager; -//import androidx.biometric.BiometricPrompt; import android.annotation.TargetApi; import android.content.Intent; +import android.content.pm.PackageManager; import android.drm.DrmInfo; import android.drm.DrmInfoRequest; import android.drm.DrmManagerClient; @@ -39,12 +38,14 @@ import android.util.Base64; import android.util.Log; import android.view.View; import android.widget.TextView; -import android.content.pm.PackageManager; + import androidx.appcompat.app.AppCompatActivity; +import androidx.biometric.BiometricManager; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; + import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; @@ -59,128 +60,22 @@ import java.util.UUID; import javax.crypto.KeyGenerator; -import static android.hardware.biometrics.BiometricManager.Authenticators.BIOMETRIC_STRONG; +//import androidx.biometric.BiometricPrompt; public class MainActivity extends AppCompatActivity { + static final UUID WIDEVINE_UUID = new UUID(0xEDEF8BA979D64ACEL, 0xA3C827DCD51D21EDL); + private static final String TAG = "Collector"; + KeyStore ks; private TextView reportTextView; private FingerprintManager fingerprintManager; private PackageManager pm; private JSONObject json; private String sreport; - KeyStore ks; - static final UUID WIDEVINE_UUID = new UUID(0xEDEF8BA979D64ACEL, 0xA3C827DCD51D21EDL); - private static final String TAG = "Collector"; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_main); - reportTextView = (TextView) findViewById(R.id.reportTextView); - json = new JSONObject(); - pm = getPackageManager(); - } - - public void onBtnClick(View view){ - try { - json.put("MANUFATURER", Build.MANUFACTURER); - json.put("MODEL", Build.MODEL); - json.put("HARDWARE", Build.HARDWARE); //change to DEVICE? - json.put("DEVICE", Build.DEVICE); - json.put("CPU_MANUFACTURER", getCpu()); - json.put("CPU", getProp("ro.board.platform")); - json.put("FINGERPRINT",fingerprint()); - json.put("ro.product.first_api_level",getProp("ro.product.first_api_level")); - json.put("ro.boot.flash.locked",getProp("ro.boot.flash.locked")); - json.put("ro.boot.verifiedbootstate",getProp("ro.boot.verifiedbootstate")); - json.put("ro.boot.veritymode",getProp("ro.boot.veritymode")); //unklar - json.put("KeyStore",keyStorePresence()); - json.put("Strongbox", isStrongbox()); - json.put("FingerprintQuality", biometricQuality()); - json.put("DRM", drmInfo()); - } catch (JSONException e) { - e.printStackTrace(); - } - try { - sreport = json.toString(4); - sreport.replace("\\/","/"); //unsure if needed - } catch (JSONException e) { - sreport = "{}"; - } - reportTextView.setText(sreport); - - } - - private boolean fingerprint(){ - //FingerprintManager needs Android 6.0 - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - //Get an instance of FingerprintManager// - fingerprintManager = (FingerprintManager) getSystemService(FINGERPRINT_SERVICE); - return fingerprintManager.isHardwareDetected(); - } - return false; - } - - private String biometricQuality(){ - //Biometric need to be enrolled or else only CREDENTIAL will be returned - if (BiometricManager.from(this).canAuthenticate(BiometricManager.Authenticators.BIOMETRIC_STRONG) == BiometricManager.BIOMETRIC_SUCCESS) - return "STRONG"; - else if (BiometricManager.from(this).canAuthenticate(BiometricManager.Authenticators.BIOMETRIC_STRONG) == BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED) - return "BIOMETRIC_ERROR_NONE_ENROLLED"; - if (BiometricManager.from(this).canAuthenticate(BiometricManager.Authenticators.BIOMETRIC_WEAK) == BiometricManager.BIOMETRIC_SUCCESS) - return "WEAK"; - else if (BiometricManager.from(this).canAuthenticate(BiometricManager.Authenticators.BIOMETRIC_WEAK) == BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED) - return "BIOMETRIC_ERROR_NONE_ENROLLED"; - if (BiometricManager.from(this).canAuthenticate(BiometricManager.Authenticators.DEVICE_CREDENTIAL) == BiometricManager.BIOMETRIC_SUCCESS) - return "CREDENTIAL"; - return null; - } - - private boolean keyStorePresence(){ - // to check for KeyStore presence we try to get an Instance of KeyStore and if we get the Exception we return false - try { - ks = KeyStore.getInstance(KeyStore.getDefaultType()); - return true; - } catch (KeyStoreException e) { - return false; - } - } - - private boolean isStrongbox(){ - // similar to keyStorePresence we use .setIsStrongBoxBacked to make using Strongbox mandatory for a dummy Key Generation which will result in StrongBoxUnavailableException if Strongbox is not available - - KeyGenerator kg = null; - try { - kg = KeyGenerator.getInstance( - KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore"); - } catch (NoSuchAlgorithmException | NoSuchProviderException e) { - return false; - } - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { - try { - kg.init(new KeyGenParameterSpec.Builder("keystore1", 0) - .setCertificateSerialNumber(BigInteger.valueOf(1L)) - .setIsStrongBoxBacked(true) /* Enable StrongBox */ - .build()); - } catch (InvalidAlgorithmParameterException e) { - e.printStackTrace(); - } - } - else{ - return false; - } - try { - kg.generateKey(); - } catch (StrongBoxUnavailableException e) { - return false; - } - return true; - - - } static String getProp(String s) { - // from https://bitbucket.org/oF2pks/kaltura-device-info-android/src/master/app/src/main/java/com/oF2pks/kalturadeviceinfos/Utils.java licenced under GPLv3 + // from https://bitbucket.org/oF2pks/kaltura-device-info-android/src/master/app/src/main + // /java/com/oF2pks/kalturadeviceinfos/Utils.java licenced under GPLv3 try { @SuppressLint("PrivateApi") Class<?> aClass = Class.forName("android.os.SystemProperties"); @@ -195,7 +90,8 @@ public class MainActivity extends AppCompatActivity { } private static String getCpu() { - // from https://bitbucket.org/oF2pks/kaltura-device-info-android/src/master/app/src/main/java/com/oF2pks/kalturadeviceinfos/Collector.java licenced under GPLv3 + // from https://bitbucket.org/oF2pks/kaltura-device-info-android/src/master/app/src/main + // /java/com/oF2pks/kalturadeviceinfos/Collector.java licenced under GPLv3 try { Process p = Runtime.getRuntime().exec("cat /proc/cpuinfo"); InputStream is = null; @@ -208,10 +104,9 @@ public class MainActivity extends AppCompatActivity { String tmp; String tmp2 = null; - while ((tmp = br.readLine()) != null) - { + while ((tmp = br.readLine()) != null) { if (tmp.contains("Hardware")) return tmp.substring(11); - if (tmp.contains("model name")) tmp2= tmp.substring(13); + if (tmp.contains("model name")) tmp2 = tmp.substring(13); } is.close(); br.close(); @@ -221,7 +116,133 @@ public class MainActivity extends AppCompatActivity { return "ERROR: " + ex.getMessage(); } } - //all following DRM Code from https://bitbucket.org/oF2pks/kaltura-device-info-android/src/master/app/src/main/java/com/oF2pks/kalturadeviceinfos/Collector.java licenced under GPLv3 + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + reportTextView = (TextView) findViewById(R.id.reportTextView); + json = new JSONObject(); + pm = getPackageManager(); + } + + public void onBtnClick(View view) { + try { + json.put("MANUFATURER", Build.MANUFACTURER); + json.put("MODEL", Build.MODEL); + json.put("HARDWARE", Build.HARDWARE); //change to DEVICE? + json.put("DEVICE", Build.DEVICE); + json.put("CPU_MANUFACTURER", getCpu()); + json.put("CPU", getProp("ro.board.platform")); + json.put("FINGERPRINT", fingerprint()); + json.put("ro.product.first_api_level", getProp("ro.product.first_api_level")); + json.put("ro.boot.flash.locked", getProp("ro.boot.flash.locked")); + json.put("ro.boot.verifiedbootstate", getProp("ro.boot.verifiedbootstate")); + json.put("ro.boot.veritymode", getProp("ro.boot.veritymode")); //unklar + json.put("KeyStore", keyStorePresence()); + json.put("Strongbox", isStrongbox()); + json.put("FingerprintQuality", biometricQuality()); + json.put("DRM", drmInfo()); + } catch (JSONException e) { + e.printStackTrace(); + } + try { + sreport = json.toString(4); + sreport.replace("\\/", "/"); //unsure if needed + } catch (JSONException e) { + sreport = "{}"; + } + reportTextView.setText(sreport); + + } + + + private boolean fingerprint() { + //FingerprintManager needs Android 6.0 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + //Get an instance of FingerprintManager// + fingerprintManager = (FingerprintManager) getSystemService(FINGERPRINT_SERVICE); + return fingerprintManager.isHardwareDetected(); + } + return false; + } + + private String biometricQuality() { + //Biometric need to be enrolled or else only CREDENTIAL will be returned + if (BiometricManager.from(this).canAuthenticate( + BiometricManager.Authenticators.BIOMETRIC_STRONG) + == BiometricManager.BIOMETRIC_SUCCESS) { + return "STRONG"; + } else if (BiometricManager.from(this).canAuthenticate( + BiometricManager.Authenticators.BIOMETRIC_STRONG) + == BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED) { + return "BIOMETRIC_ERROR_NONE_ENROLLED"; + } + if (BiometricManager.from(this).canAuthenticate( + BiometricManager.Authenticators.BIOMETRIC_WEAK) + == BiometricManager.BIOMETRIC_SUCCESS) { + return "WEAK"; + } else if (BiometricManager.from(this).canAuthenticate( + BiometricManager.Authenticators.BIOMETRIC_WEAK) + == BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED) { + return "BIOMETRIC_ERROR_NONE_ENROLLED"; + } + if (BiometricManager.from(this).canAuthenticate( + BiometricManager.Authenticators.DEVICE_CREDENTIAL) + == BiometricManager.BIOMETRIC_SUCCESS) { + return "CREDENTIAL"; + } + return null; + } + + private boolean keyStorePresence() { + // to check for KeyStore presence we try to get an Instance of KeyStore and if we get the + // Exception we return false + try { + ks = KeyStore.getInstance(KeyStore.getDefaultType()); + return true; + } catch (KeyStoreException e) { + return false; + } + } + + private boolean isStrongbox() { + // similar to keyStorePresence we use .setIsStrongBoxBacked to make using Strongbox + // mandatory for a dummy Key Generation which will result in + // StrongBoxUnavailableException if Strongbox is not available + + KeyGenerator kg = null; + try { + kg = KeyGenerator.getInstance( + KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore"); + } catch (NoSuchAlgorithmException | NoSuchProviderException e) { + return false; + } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + try { + kg.init(new KeyGenParameterSpec.Builder("keystore1", 0) + .setCertificateSerialNumber(BigInteger.valueOf(1L)) + .setIsStrongBoxBacked(true) /* Enable StrongBox */ + .build()); + } catch (InvalidAlgorithmParameterException e) { + e.printStackTrace(); + } + } else { + return false; + } + try { + kg.generateKey(); + } catch (StrongBoxUnavailableException e) { + return false; + } + return true; + + + } + + //all following DRM Code from https://bitbucket + // .org/oF2pks/kaltura-device-info-android/src/master/app/src/main/java/com/oF2pks + // /kalturadeviceinfos/Collector.java licenced under GPLv3 private JSONObject drmInfo() throws JSONException { return new JSONObject() .put("drm.service.enabled", getProp("drm.service.enabled")) @@ -241,7 +262,8 @@ public class MainActivity extends AppCompatActivity { try { if (drmManagerClient.canHandle("", "video/wvm")) { - DrmInfoRequest request = new DrmInfoRequest(DrmInfoRequest.TYPE_REGISTRATION_INFO, "video/wvm"); + DrmInfoRequest request = new DrmInfoRequest(DrmInfoRequest.TYPE_REGISTRATION_INFO, + "video/wvm"); request.put("WVPortalKey", "OEM"); DrmInfo response = drmManagerClient.acquireDrmInfo(request); String status = (String) response.get("WVDrmInfoRequestStatusKey"); @@ -299,11 +321,13 @@ public class MainActivity extends AppCompatActivity { mediaDrm.setOnEventListener(new MediaDrm.OnEventListener() { @Override - public void onEvent( MediaDrm md, byte[] sessionId, int event, int extra, byte[] data) { + public void onEvent(MediaDrm md, byte[] sessionId, int event, int extra, byte[] data) { try { - String encodedData = data == null ? null : Base64.encodeToString(data, Base64.NO_WRAP); + String encodedData = data == null ? null : Base64.encodeToString(data, + Base64.NO_WRAP); - mediaDrmEvents.put(new JSONObject().put("event", event).put("extra", extra).put("data", encodedData)); + mediaDrmEvents.put(new JSONObject().put("event", event).put("extra", extra).put( + "data", encodedData)); } catch (JSONException e) { Log.e(TAG, "JSONError", e); } @@ -319,8 +343,13 @@ public class MainActivity extends AppCompatActivity { } - String[] stringProps = {MediaDrm.PROPERTY_VENDOR, MediaDrm.PROPERTY_VERSION, MediaDrm.PROPERTY_DESCRIPTION, MediaDrm.PROPERTY_ALGORITHMS, "securityLevel", "systemId", "privacyMode", "sessionSharing", "usageReportingSupport", "appId", "origin", "hdcpLevel", "maxHdcpLevel", "maxNumberOfSessions", "numberOfOpenSessions"}; - String[] byteArrayProps = {MediaDrm.PROPERTY_DEVICE_UNIQUE_ID, "provisioningUniqueId", "serviceCertificate"}; + String[] stringProps = + {MediaDrm.PROPERTY_VENDOR, MediaDrm.PROPERTY_VERSION, MediaDrm.PROPERTY_DESCRIPTION, + MediaDrm.PROPERTY_ALGORITHMS, "securityLevel", "systemId", "privacyMode", + "sessionSharing", "usageReportingSupport", "appId", "origin", "hdcpLevel", + "maxHdcpLevel", "maxNumberOfSessions", "numberOfOpenSessions"}; + String[] byteArrayProps = + {MediaDrm.PROPERTY_DEVICE_UNIQUE_ID, "provisioningUniqueId", "serviceCertificate"}; JSONObject props = new JSONObject();