mirror of
https://github.com/github/codeql.git
synced 2026-04-25 16:55:19 +02:00
Merge pull request #15481 from joefarebrother/android-local-auth
Java: Add query for insecure local authentication
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
/** Definitions for the insecure local authentication query. */
|
||||
|
||||
import java
|
||||
|
||||
/** A base class that is used as a callback for biometric authentication. */
|
||||
private class AuthenticationCallbackClass extends Class {
|
||||
AuthenticationCallbackClass() {
|
||||
this.hasQualifiedName("android.hardware.fingerprint",
|
||||
"FingerprintManager$AuthenticationCallback")
|
||||
or
|
||||
this.hasQualifiedName("android.hardware.biometrics", "BiometricPrompt$AuthenticationCallback")
|
||||
or
|
||||
this.hasQualifiedName("androidx.biometric", "BiometricPrompt$AuthenticationCallback")
|
||||
}
|
||||
}
|
||||
|
||||
/** An implementation of the `onAuthenticationSucceeded` method for an authentication callback. */
|
||||
class AuthenticationSuccessCallback extends Method {
|
||||
AuthenticationSuccessCallback() {
|
||||
this.getDeclaringType().getASupertype+() instanceof AuthenticationCallbackClass and
|
||||
this.hasName("onAuthenticationSucceeded")
|
||||
}
|
||||
|
||||
/** Gets the parameter containing the `authenticationResult`. */
|
||||
Parameter getResultParameter() { result = this.getParameter(0) }
|
||||
|
||||
/** Gets a use of the result parameter that's used in a `super` call to the base `AuthenticationCallback` class. */
|
||||
private VarAccess getASuperResultUse() {
|
||||
exists(SuperMethodCall sup |
|
||||
sup.getEnclosingCallable() = this and
|
||||
result = sup.getArgument(0) and
|
||||
result = this.getResultParameter().getAnAccess() and
|
||||
this.getDeclaringType().getASupertype() instanceof AuthenticationCallbackClass
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets a use of the result parameter, other than one used in a `super` call. */
|
||||
VarAccess getAResultUse() {
|
||||
result = this.getResultParameter().getAnAccess() and
|
||||
not result = this.getASuperResultUse()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
|
||||
<overview>
|
||||
<p>
|
||||
Biometric local authentication such as fingerprint recognition can be used to protect sensitive data or actions within an application.
|
||||
However, if this authentication does not use a <code>KeyStore</code>-backed key, it can be bypassed by a privileged malicious application, or by an attacker with physical access using application hooking tools such as Frida.
|
||||
</p>
|
||||
</overview>
|
||||
|
||||
<recommendation>
|
||||
<p>
|
||||
Generate a secure key in the Android <code>KeyStore</code>. Ensure that the <code>onAuthenticationSuccess</code> callback for a biometric prompt uses it
|
||||
in a way that is required for the sensitive parts of the application to function, such as by using it to decrypt sensitive data or credentials.
|
||||
</p>
|
||||
</recommendation>
|
||||
|
||||
<example>
|
||||
<p>In the following (bad) case, no <code>CryptoObject</code> is required for the biometric prompt to grant access, so it can be bypassed.</p>
|
||||
<sample src="AndroidInsecureLocalAuthenticationBad.java" />
|
||||
<p>In the following (good) case, a secret key is generated in the Android <code>KeyStore</code>. The application requires this secret key for access, using it to decrypt data.</p>
|
||||
<sample src="AndroidInsecureLocalAuthenticationGood.java" />
|
||||
</example>
|
||||
|
||||
<references>
|
||||
<li>
|
||||
OWASP Mobile Application Security: <a href="https://mas.owasp.org/MASTG/Android/0x05f-Testing-Local-Authentication/">Android Local Authentication</a>
|
||||
</li>
|
||||
<li>
|
||||
OWASP Mobile Application Security: <a href="https://mas.owasp.org/MASTG/tests/android/MASVS-AUTH/MASTG-TEST-0018/">Testing Biometric Authentication</a>
|
||||
</li>
|
||||
<li>
|
||||
WithSecure: <a href="https://labs.withsecure.com/publications/how-secure-is-your-android-keystore-authentication">How Secure is your Android Keystore Authentication?</a>
|
||||
</li>
|
||||
<li>
|
||||
Android Developers: <a href="https://developer.android.com/training/sign-in/biometric-auth">Biometric Authentication</a>
|
||||
</li>
|
||||
|
||||
</references>
|
||||
</qhelp>
|
||||
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* @name Insecure local authentication
|
||||
* @description Local authentication that does not make use of a `CryptoObject` can be bypassed.
|
||||
* @kind problem
|
||||
* @problem.severity warning
|
||||
* @security-severity 4.4
|
||||
* @precision high
|
||||
* @id java/android/insecure-local-authentication
|
||||
* @tags security
|
||||
* external/cwe/cwe-287
|
||||
*/
|
||||
|
||||
import java
|
||||
import semmle.code.java.security.AndroidLocalAuthQuery
|
||||
|
||||
from AuthenticationSuccessCallback c
|
||||
where not exists(c.getAResultUse())
|
||||
select c, "This authentication callback does not use its result for a cryptographic operation."
|
||||
@@ -0,0 +1,11 @@
|
||||
biometricPrompt.authenticate(
|
||||
cancellationSignal,
|
||||
executor,
|
||||
new BiometricPrompt.AuthenticationCallback {
|
||||
@Override
|
||||
// BAD: This authentication callback does not make use of a `CryptoObject` from the `result`.
|
||||
public void onAuthenticationSucceeded(BiometricPrompt.AuthenticationResult result) {
|
||||
grantAccess()
|
||||
}
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,48 @@
|
||||
private void generateSecretKey() {
|
||||
KeyGenParameterSpec keyGenParameterSpec = new KeyGenParameterSpec.Builder(
|
||||
"MySecretKey",
|
||||
KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
|
||||
.setBlockModes(KeyProperties.BLOCK_MODE_CBC)
|
||||
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
|
||||
.setUserAuthenticationRequired(true)
|
||||
.setInvalidatedByBiometricEnrollment(true)
|
||||
.build();
|
||||
KeyGenerator keyGenerator = KeyGenerator.getInstance(
|
||||
KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");
|
||||
keyGenerator.init(keyGenParameterSpec);
|
||||
keyGenerator.generateKey();
|
||||
}
|
||||
|
||||
|
||||
private SecretKey getSecretKey() {
|
||||
KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
|
||||
keyStore.load(null);
|
||||
return ((SecretKey)keyStore.getKey("MySecretKey", null));
|
||||
}
|
||||
|
||||
private Cipher getCipher() {
|
||||
return Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/"
|
||||
+ KeyProperties.BLOCK_MODE_CBC + "/"
|
||||
+ KeyProperties.ENCRYPTION_PADDING_PKCS7);
|
||||
}
|
||||
|
||||
public prompt(byte[] encryptedData) {
|
||||
Cipher cipher = getCipher();
|
||||
SecretKey secretKey = getSecretKey();
|
||||
cipher.init(Cipher.DECRYPT_MODE, secretKey);
|
||||
|
||||
biometricPrompt.authenticate(
|
||||
new BiometricPrompt.CryptoObject(cipher),
|
||||
cancellationSignal,
|
||||
executor,
|
||||
new BiometricPrompt.AuthenticationCallback() {
|
||||
@Override
|
||||
// GOOD: This authentication callback uses the result to decrypt some data.
|
||||
public void onAuthenticationSucceeded(BiometricPrompt.AuthenticationResult result) {
|
||||
Cipher cipher = result.getCryptoObject().getCipher();
|
||||
byte[] decryptedData = cipher.doFinal(encryptedData);
|
||||
grantAccessWithData(decryptedData);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
|
||||
---
|
||||
category: newQuery
|
||||
---
|
||||
* Added a new query `java/android/insecure-local-authentication` for finding uses of biometric authentication APIs that do not make use of a `KeyStore`-backed key and thus may be bypassed.
|
||||
@@ -0,0 +1,2 @@
|
||||
testFailures
|
||||
failures
|
||||
@@ -0,0 +1,19 @@
|
||||
import java
|
||||
import TestUtilities.InlineExpectationsTest
|
||||
import semmle.code.java.dataflow.DataFlow
|
||||
import semmle.code.java.security.AndroidLocalAuthQuery
|
||||
|
||||
module InsecureAuthTest implements TestSig {
|
||||
string getARelevantTag() { result = "insecure-auth" }
|
||||
|
||||
predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
tag = "insecure-auth" and
|
||||
exists(AuthenticationSuccessCallback cb | not exists(cb.getAResultUse()) |
|
||||
cb.getLocation() = location and
|
||||
element = cb.toString() and
|
||||
value = ""
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
import MakeTest<InsecureAuthTest>
|
||||
94
java/ql/test/query-tests/security/CWE-287/Test.java
Normal file
94
java/ql/test/query-tests/security/CWE-287/Test.java
Normal file
@@ -0,0 +1,94 @@
|
||||
import android.hardware.biometrics.BiometricPrompt;
|
||||
import android.hardware.fingerprint.FingerprintManager;
|
||||
|
||||
class TestA {
|
||||
public static void useKey(BiometricPrompt.CryptoObject key) {}
|
||||
|
||||
|
||||
// GOOD: result is used
|
||||
class Test1 extends BiometricPrompt.AuthenticationCallback {
|
||||
@Override
|
||||
public void onAuthenticationSucceeded(BiometricPrompt.AuthenticationResult result) {
|
||||
TestA.useKey(result.getCryptoObject());
|
||||
}
|
||||
}
|
||||
|
||||
// BAD: result is not used
|
||||
class Test2 extends BiometricPrompt.AuthenticationCallback {
|
||||
@Override
|
||||
public void onAuthenticationSucceeded(BiometricPrompt.AuthenticationResult result) { // $insecure-auth
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// BAD: result is only used in a super call
|
||||
class Test3 extends BiometricPrompt.AuthenticationCallback {
|
||||
@Override
|
||||
public void onAuthenticationSucceeded(BiometricPrompt.AuthenticationResult result) { // $insecure-auth
|
||||
super.onAuthenticationSucceeded(result);
|
||||
}
|
||||
}
|
||||
|
||||
// GOOD: result is used
|
||||
class Test4 extends BiometricPrompt.AuthenticationCallback {
|
||||
@Override
|
||||
public void onAuthenticationSucceeded(BiometricPrompt.AuthenticationResult result) {
|
||||
super.onAuthenticationSucceeded(result);
|
||||
TestA.useKey(result.getCryptoObject());
|
||||
}
|
||||
}
|
||||
|
||||
// GOOD: result is used in a super call to a class other than the base class
|
||||
class Test5 extends Test1 {
|
||||
@Override
|
||||
public void onAuthenticationSucceeded(BiometricPrompt.AuthenticationResult result) {
|
||||
super.onAuthenticationSucceeded(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class TestB {
|
||||
public static void useKey(FingerprintManager.CryptoObject key) {}
|
||||
|
||||
|
||||
// GOOD: result is used
|
||||
class Test1 extends FingerprintManager.AuthenticationCallback {
|
||||
@Override
|
||||
public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) {
|
||||
TestB.useKey(result.getCryptoObject());
|
||||
}
|
||||
}
|
||||
|
||||
// BAD: result is not used
|
||||
class Test2 extends FingerprintManager.AuthenticationCallback {
|
||||
@Override
|
||||
public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) { // $insecure-auth
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// BAD: result is only used in a super call
|
||||
class Test3 extends FingerprintManager.AuthenticationCallback {
|
||||
@Override
|
||||
public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) { // $insecure-auth
|
||||
super.onAuthenticationSucceeded(result);
|
||||
}
|
||||
}
|
||||
|
||||
// GOOD: result is used
|
||||
class Test4 extends FingerprintManager.AuthenticationCallback {
|
||||
@Override
|
||||
public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) {
|
||||
super.onAuthenticationSucceeded(result);
|
||||
TestB.useKey(result.getCryptoObject());
|
||||
}
|
||||
}
|
||||
|
||||
// GOOD: result is used in a super call to a class other than the base class
|
||||
class Test5 extends Test1 {
|
||||
@Override
|
||||
public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) {
|
||||
super.onAuthenticationSucceeded(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
47
java/ql/test/query-tests/security/CWE-287/Test2.java
Normal file
47
java/ql/test/query-tests/security/CWE-287/Test2.java
Normal file
@@ -0,0 +1,47 @@
|
||||
import androidx.biometric.BiometricPrompt;
|
||||
|
||||
class TestC {
|
||||
public static void useKey(BiometricPrompt.CryptoObject key) {}
|
||||
|
||||
|
||||
// GOOD: result is used
|
||||
class Test1 extends BiometricPrompt.AuthenticationCallback {
|
||||
@Override
|
||||
public void onAuthenticationSucceeded(BiometricPrompt.AuthenticationResult result) {
|
||||
TestC.useKey(result.getCryptoObject());
|
||||
}
|
||||
}
|
||||
|
||||
// BAD: result is not used
|
||||
class Test2 extends BiometricPrompt.AuthenticationCallback {
|
||||
@Override
|
||||
public void onAuthenticationSucceeded(BiometricPrompt.AuthenticationResult result) { // $insecure-auth
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// BAD: result is only used in a super call
|
||||
class Test3 extends BiometricPrompt.AuthenticationCallback {
|
||||
@Override
|
||||
public void onAuthenticationSucceeded(BiometricPrompt.AuthenticationResult result) { // $insecure-auth
|
||||
super.onAuthenticationSucceeded(result);
|
||||
}
|
||||
}
|
||||
|
||||
// GOOD: result is used
|
||||
class Test4 extends BiometricPrompt.AuthenticationCallback {
|
||||
@Override
|
||||
public void onAuthenticationSucceeded(BiometricPrompt.AuthenticationResult result) {
|
||||
super.onAuthenticationSucceeded(result);
|
||||
TestC.useKey(result.getCryptoObject());
|
||||
}
|
||||
}
|
||||
|
||||
// GOOD: result is used in a super call to a class other than the base class
|
||||
class Test5 extends Test1 {
|
||||
@Override
|
||||
public void onAuthenticationSucceeded(BiometricPrompt.AuthenticationResult result) {
|
||||
super.onAuthenticationSucceeded(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
1
java/ql/test/query-tests/security/CWE-287/options
Normal file
1
java/ql/test/query-tests/security/CWE-287/options
Normal file
@@ -0,0 +1 @@
|
||||
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/google-android-9.0.0
|
||||
69
java/ql/test/stubs/google-android-9.0.0/android/hardware/biometrics/BiometricPrompt.java
generated
Normal file
69
java/ql/test/stubs/google-android-9.0.0/android/hardware/biometrics/BiometricPrompt.java
generated
Normal file
@@ -0,0 +1,69 @@
|
||||
// Generated automatically from android.hardware.biometrics.BiometricPrompt for testing purposes
|
||||
|
||||
package android.hardware.biometrics;
|
||||
|
||||
import android.os.CancellationSignal;
|
||||
import android.security.identity.IdentityCredential;
|
||||
import java.security.Signature;
|
||||
import java.util.concurrent.Executor;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.Mac;
|
||||
|
||||
public class BiometricPrompt
|
||||
{
|
||||
protected BiometricPrompt() {}
|
||||
abstract static public class AuthenticationCallback
|
||||
{
|
||||
public AuthenticationCallback(){}
|
||||
public void onAuthenticationError(int p0, CharSequence p1){}
|
||||
public void onAuthenticationFailed(){}
|
||||
public void onAuthenticationHelp(int p0, CharSequence p1){}
|
||||
public void onAuthenticationSucceeded(BiometricPrompt.AuthenticationResult p0){}
|
||||
}
|
||||
public CharSequence getDescription(){ return null; }
|
||||
public CharSequence getNegativeButtonText(){ return null; }
|
||||
public CharSequence getSubtitle(){ return null; }
|
||||
public CharSequence getTitle(){ return null; }
|
||||
public boolean isConfirmationRequired(){ return false; }
|
||||
public int getAllowedAuthenticators(){ return 0; }
|
||||
public static int AUTHENTICATION_RESULT_TYPE_BIOMETRIC = 0;
|
||||
public static int AUTHENTICATION_RESULT_TYPE_DEVICE_CREDENTIAL = 0;
|
||||
public static int BIOMETRIC_ACQUIRED_GOOD = 0;
|
||||
public static int BIOMETRIC_ACQUIRED_IMAGER_DIRTY = 0;
|
||||
public static int BIOMETRIC_ACQUIRED_INSUFFICIENT = 0;
|
||||
public static int BIOMETRIC_ACQUIRED_PARTIAL = 0;
|
||||
public static int BIOMETRIC_ACQUIRED_TOO_FAST = 0;
|
||||
public static int BIOMETRIC_ACQUIRED_TOO_SLOW = 0;
|
||||
public static int BIOMETRIC_ERROR_CANCELED = 0;
|
||||
public static int BIOMETRIC_ERROR_HW_NOT_PRESENT = 0;
|
||||
public static int BIOMETRIC_ERROR_HW_UNAVAILABLE = 0;
|
||||
public static int BIOMETRIC_ERROR_LOCKOUT = 0;
|
||||
public static int BIOMETRIC_ERROR_LOCKOUT_PERMANENT = 0;
|
||||
public static int BIOMETRIC_ERROR_NO_BIOMETRICS = 0;
|
||||
public static int BIOMETRIC_ERROR_NO_DEVICE_CREDENTIAL = 0;
|
||||
public static int BIOMETRIC_ERROR_NO_SPACE = 0;
|
||||
public static int BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED = 0;
|
||||
public static int BIOMETRIC_ERROR_TIMEOUT = 0;
|
||||
public static int BIOMETRIC_ERROR_UNABLE_TO_PROCESS = 0;
|
||||
public static int BIOMETRIC_ERROR_USER_CANCELED = 0;
|
||||
public static int BIOMETRIC_ERROR_VENDOR = 0;
|
||||
public void authenticate(BiometricPrompt.CryptoObject p0, CancellationSignal p1, Executor p2, BiometricPrompt.AuthenticationCallback p3){}
|
||||
public void authenticate(CancellationSignal p0, Executor p1, BiometricPrompt.AuthenticationCallback p2){}
|
||||
static public class AuthenticationResult
|
||||
{
|
||||
public BiometricPrompt.CryptoObject getCryptoObject(){ return null; }
|
||||
public int getAuthenticationType(){ return 0; }
|
||||
}
|
||||
static public class CryptoObject
|
||||
{
|
||||
protected CryptoObject() {}
|
||||
public Cipher getCipher(){ return null; }
|
||||
public CryptoObject(Cipher p0){}
|
||||
public CryptoObject(IdentityCredential p0){}
|
||||
public CryptoObject(Mac p0){}
|
||||
public CryptoObject(Signature p0){}
|
||||
public IdentityCredential getIdentityCredential(){ return null; }
|
||||
public Mac getMac(){ return null; }
|
||||
public Signature getSignature(){ return null; }
|
||||
}
|
||||
}
|
||||
55
java/ql/test/stubs/google-android-9.0.0/android/hardware/fingerprint/FingerprintManager.java
generated
Normal file
55
java/ql/test/stubs/google-android-9.0.0/android/hardware/fingerprint/FingerprintManager.java
generated
Normal file
@@ -0,0 +1,55 @@
|
||||
// Generated automatically from android.hardware.fingerprint.FingerprintManager for testing purposes
|
||||
|
||||
package android.hardware.fingerprint;
|
||||
|
||||
import android.os.CancellationSignal;
|
||||
import android.os.Handler;
|
||||
import java.security.Signature;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.Mac;
|
||||
|
||||
public class FingerprintManager
|
||||
{
|
||||
abstract static public class AuthenticationCallback
|
||||
{
|
||||
public AuthenticationCallback(){}
|
||||
public void onAuthenticationError(int p0, CharSequence p1){}
|
||||
public void onAuthenticationFailed(){}
|
||||
public void onAuthenticationHelp(int p0, CharSequence p1){}
|
||||
public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult p0){}
|
||||
}
|
||||
public boolean hasEnrolledFingerprints(){ return false; }
|
||||
public boolean isHardwareDetected(){ return false; }
|
||||
public static int FINGERPRINT_ACQUIRED_GOOD = 0;
|
||||
public static int FINGERPRINT_ACQUIRED_IMAGER_DIRTY = 0;
|
||||
public static int FINGERPRINT_ACQUIRED_INSUFFICIENT = 0;
|
||||
public static int FINGERPRINT_ACQUIRED_PARTIAL = 0;
|
||||
public static int FINGERPRINT_ACQUIRED_TOO_FAST = 0;
|
||||
public static int FINGERPRINT_ACQUIRED_TOO_SLOW = 0;
|
||||
public static int FINGERPRINT_ERROR_CANCELED = 0;
|
||||
public static int FINGERPRINT_ERROR_HW_NOT_PRESENT = 0;
|
||||
public static int FINGERPRINT_ERROR_HW_UNAVAILABLE = 0;
|
||||
public static int FINGERPRINT_ERROR_LOCKOUT = 0;
|
||||
public static int FINGERPRINT_ERROR_LOCKOUT_PERMANENT = 0;
|
||||
public static int FINGERPRINT_ERROR_NO_FINGERPRINTS = 0;
|
||||
public static int FINGERPRINT_ERROR_NO_SPACE = 0;
|
||||
public static int FINGERPRINT_ERROR_TIMEOUT = 0;
|
||||
public static int FINGERPRINT_ERROR_UNABLE_TO_PROCESS = 0;
|
||||
public static int FINGERPRINT_ERROR_USER_CANCELED = 0;
|
||||
public static int FINGERPRINT_ERROR_VENDOR = 0;
|
||||
public void authenticate(FingerprintManager.CryptoObject p0, CancellationSignal p1, int p2, FingerprintManager.AuthenticationCallback p3, Handler p4){}
|
||||
static public class AuthenticationResult
|
||||
{
|
||||
public FingerprintManager.CryptoObject getCryptoObject(){ return null; }
|
||||
}
|
||||
static public class CryptoObject
|
||||
{
|
||||
protected CryptoObject() {}
|
||||
public Cipher getCipher(){ return null; }
|
||||
public CryptoObject(Cipher p0){}
|
||||
public CryptoObject(Mac p0){}
|
||||
public CryptoObject(Signature p0){}
|
||||
public Mac getMac(){ return null; }
|
||||
public Signature getSignature(){ return null; }
|
||||
}
|
||||
}
|
||||
@@ -15,9 +15,9 @@ import java.util.ArrayList;
|
||||
|
||||
public class Bundle extends BaseBundle implements Cloneable, Parcelable
|
||||
{
|
||||
public <T extends Parcelable> ArrayList<T> getParcelableArrayList(String p0){ return null; }
|
||||
public <T extends Parcelable> SparseArray<T> getSparseParcelableArray(String p0){ return null; }
|
||||
public <T extends Parcelable> T getParcelable(String p0){ return null; }
|
||||
public <T extends Parcelable> android.util.SparseArray<T> getSparseParcelableArray(String p0){ return null; }
|
||||
public <T extends Parcelable> java.util.ArrayList<T> getParcelableArrayList(String p0){ return null; }
|
||||
public ArrayList<CharSequence> getCharSequenceArrayList(String p0){ return null; }
|
||||
public ArrayList<Integer> getIntegerArrayList(String p0){ return null; }
|
||||
public ArrayList<String> getStringArrayList(String p0){ return null; }
|
||||
|
||||
@@ -24,24 +24,24 @@ public class Parcel
|
||||
{
|
||||
protected Parcel() {}
|
||||
protected void finalize(){}
|
||||
public <T extends Parcelable> ArrayMap<String, T> createTypedArrayMap(Parcelable.Creator<T> p0){ return null; }
|
||||
public <T extends Parcelable> List<T> readParcelableList(List<T> p0, ClassLoader p1){ return null; }
|
||||
public <T extends Parcelable> SparseArray<T> createTypedSparseArray(Parcelable.Creator<T> p0){ return null; }
|
||||
public <T extends Parcelable> T readParcelable(ClassLoader p0){ return null; }
|
||||
public <T extends Parcelable> android.util.ArrayMap<String, T> createTypedArrayMap(Parcelable.Creator<T> p0){ return null; }
|
||||
public <T extends Parcelable> android.util.SparseArray<T> createTypedSparseArray(Parcelable.Creator<T> p0){ return null; }
|
||||
public <T extends Parcelable> java.util.List<T> readParcelableList(java.util.List<T> p0, ClassLoader p1){ return null; }
|
||||
public <T extends Parcelable> void writeParcelableArray(T[] p0, int p1){}
|
||||
public <T extends Parcelable> void writeParcelableList(List<T> p0, int p1){}
|
||||
public <T extends Parcelable> void writeParcelableList(java.util.List<T> p0, int p1){}
|
||||
public <T extends Parcelable> void writeTypedArray(T[] p0, int p1){}
|
||||
public <T extends Parcelable> void writeTypedArrayMap(ArrayMap<String, T> p0, int p1){}
|
||||
public <T extends Parcelable> void writeTypedList(List<T> p0){}
|
||||
public <T extends Parcelable> void writeTypedArrayMap(android.util.ArrayMap<String, T> p0, int p1){}
|
||||
public <T extends Parcelable> void writeTypedList(java.util.List<T> p0){}
|
||||
public <T extends Parcelable> void writeTypedObject(T p0, int p1){}
|
||||
public <T extends Parcelable> void writeTypedSparseArray(SparseArray<T> p0, int p1){}
|
||||
public <T> ArrayList<T> createTypedArrayList(Parcelable.Creator<T> p0){ return null; }
|
||||
public <T> SparseArray<T> readSparseArray(ClassLoader p0){ return null; }
|
||||
public <T extends Parcelable> void writeTypedSparseArray(android.util.SparseArray<T> p0, int p1){}
|
||||
public <T> T readTypedObject(Parcelable.Creator<T> p0){ return null; }
|
||||
public <T> T[] createTypedArray(Parcelable.Creator<T> p0){ return null; }
|
||||
public <T> android.util.SparseArray<T> readSparseArray(ClassLoader p0){ return null; }
|
||||
public <T> java.util.ArrayList<T> createTypedArrayList(Parcelable.Creator<T> p0){ return null; }
|
||||
public <T> void readTypedArray(T[] p0, Parcelable.Creator<T> p1){}
|
||||
public <T> void readTypedList(List<T> p0, Parcelable.Creator<T> p1){}
|
||||
public <T> void writeSparseArray(SparseArray<T> p0){}
|
||||
public <T> void readTypedList(java.util.List<T> p0, Parcelable.Creator<T> p1){}
|
||||
public <T> void writeSparseArray(android.util.SparseArray<T> p0){}
|
||||
public ArrayList readArrayList(ClassLoader p0){ return null; }
|
||||
public ArrayList<IBinder> createBinderArrayList(){ return null; }
|
||||
public ArrayList<String> createStringArrayList(){ return null; }
|
||||
|
||||
32
java/ql/test/stubs/google-android-9.0.0/android/security/identity/IdentityCredential.java
generated
Normal file
32
java/ql/test/stubs/google-android-9.0.0/android/security/identity/IdentityCredential.java
generated
Normal file
@@ -0,0 +1,32 @@
|
||||
// Generated automatically from android.security.identity.IdentityCredential for testing purposes
|
||||
|
||||
package android.security.identity;
|
||||
|
||||
import android.security.identity.PersonalizationData;
|
||||
import android.security.identity.ResultData;
|
||||
import java.security.KeyPair;
|
||||
import java.security.PublicKey;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.time.Instant;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
abstract public class IdentityCredential
|
||||
{
|
||||
public abstract Collection<X509Certificate> getAuthKeysNeedingCertification();
|
||||
public abstract Collection<X509Certificate> getCredentialKeyCertificateChain();
|
||||
public abstract KeyPair createEphemeralKeyPair();
|
||||
public abstract ResultData getEntries(byte[] p0, Map<String, Collection<String>> p1, byte[] p2, byte[] p3);
|
||||
public abstract byte[] decryptMessageFromReader(byte[] p0);
|
||||
public abstract byte[] encryptMessageToReader(byte[] p0);
|
||||
public abstract int[] getAuthenticationDataUsageCount();
|
||||
public abstract void setAllowUsingExhaustedKeys(boolean p0);
|
||||
public abstract void setAvailableAuthenticationKeys(int p0, int p1);
|
||||
public abstract void setReaderEphemeralPublicKey(PublicKey p0);
|
||||
public abstract void storeStaticAuthenticationData(X509Certificate p0, byte[] p1);
|
||||
public byte[] delete(byte[] p0){ return null; }
|
||||
public byte[] proveOwnership(byte[] p0){ return null; }
|
||||
public byte[] update(PersonalizationData p0){ return null; }
|
||||
public void setAllowUsingExpiredKeys(boolean p0){}
|
||||
public void storeStaticAuthenticationData(X509Certificate p0, Instant p1, byte[] p2){}
|
||||
}
|
||||
9
java/ql/test/stubs/google-android-9.0.0/android/security/identity/PersonalizationData.java
generated
Normal file
9
java/ql/test/stubs/google-android-9.0.0/android/security/identity/PersonalizationData.java
generated
Normal file
@@ -0,0 +1,9 @@
|
||||
// Generated automatically from android.security.identity.PersonalizationData for testing purposes
|
||||
|
||||
package android.security.identity;
|
||||
|
||||
|
||||
public class PersonalizationData
|
||||
{
|
||||
protected PersonalizationData() {}
|
||||
}
|
||||
9
java/ql/test/stubs/google-android-9.0.0/android/security/identity/PresentationSession.java
generated
Normal file
9
java/ql/test/stubs/google-android-9.0.0/android/security/identity/PresentationSession.java
generated
Normal file
@@ -0,0 +1,9 @@
|
||||
// Generated automatically from android.security.identity.PresentationSession for testing purposes
|
||||
|
||||
package android.security.identity;
|
||||
|
||||
|
||||
public class PresentationSession
|
||||
{
|
||||
protected PresentationSession() {}
|
||||
}
|
||||
24
java/ql/test/stubs/google-android-9.0.0/android/security/identity/ResultData.java
generated
Normal file
24
java/ql/test/stubs/google-android-9.0.0/android/security/identity/ResultData.java
generated
Normal file
@@ -0,0 +1,24 @@
|
||||
// Generated automatically from android.security.identity.ResultData for testing purposes
|
||||
|
||||
package android.security.identity;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
abstract public class ResultData
|
||||
{
|
||||
public abstract Collection<String> getEntryNames(String p0);
|
||||
public abstract Collection<String> getNamespaces();
|
||||
public abstract Collection<String> getRetrievedEntryNames(String p0);
|
||||
public abstract byte[] getAuthenticatedData();
|
||||
public abstract byte[] getEntry(String p0, String p1);
|
||||
public abstract byte[] getMessageAuthenticationCode();
|
||||
public abstract byte[] getStaticAuthenticationData();
|
||||
public abstract int getStatus(String p0, String p1);
|
||||
public static int STATUS_NOT_IN_REQUEST_MESSAGE = 0;
|
||||
public static int STATUS_NOT_REQUESTED = 0;
|
||||
public static int STATUS_NO_ACCESS_CONTROL_PROFILES = 0;
|
||||
public static int STATUS_NO_SUCH_ENTRY = 0;
|
||||
public static int STATUS_OK = 0;
|
||||
public static int STATUS_READER_AUTHENTICATION_FAILED = 0;
|
||||
public static int STATUS_USER_AUTHENTICATION_FAILED = 0;
|
||||
}
|
||||
@@ -6,15 +6,12 @@ import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class ArrayMap<K, V> implements Map<K, V>
|
||||
public class ArrayMap<K, V> implements java.util.Map<K, V>
|
||||
{
|
||||
public ArrayMap(){}
|
||||
public ArrayMap(ArrayMap<K, V> p0){}
|
||||
public ArrayMap(int p0){}
|
||||
public Collection<V> values(){ return null; }
|
||||
public K keyAt(int p0){ return null; }
|
||||
public Set<K> keySet(){ return null; }
|
||||
public Set<Map.Entry<K, V>> entrySet(){ return null; }
|
||||
public String toString(){ return null; }
|
||||
public V get(Object p0){ return null; }
|
||||
public V put(K p0, V p1){ return null; }
|
||||
@@ -33,8 +30,11 @@ public class ArrayMap<K, V> implements Map<K, V>
|
||||
public int indexOfKey(Object p0){ return 0; }
|
||||
public int indexOfValue(Object p0){ return 0; }
|
||||
public int size(){ return 0; }
|
||||
public java.util.Collection<V> values(){ return null; }
|
||||
public java.util.Set<K> keySet(){ return null; }
|
||||
public java.util.Set<Map.Entry<K, V>> entrySet(){ return null; }
|
||||
public void clear(){}
|
||||
public void ensureCapacity(int p0){}
|
||||
public void putAll(ArrayMap<? extends K, ? extends V> p0){}
|
||||
public void putAll(Map<? extends K, ? extends V> p0){}
|
||||
public void putAll(java.util.Map<? extends K, ? extends V> p0){}
|
||||
}
|
||||
|
||||
79
java/ql/test/stubs/google-android-9.0.0/androidx/biometric/BiometricPrompt.java
generated
Normal file
79
java/ql/test/stubs/google-android-9.0.0/androidx/biometric/BiometricPrompt.java
generated
Normal file
@@ -0,0 +1,79 @@
|
||||
// Generated automatically from androidx.biometric.BiometricPrompt for testing purposes
|
||||
|
||||
package androidx.biometric;
|
||||
|
||||
import android.security.identity.IdentityCredential;
|
||||
import android.security.identity.PresentationSession;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
import java.security.Signature;
|
||||
import java.util.concurrent.Executor;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.Mac;
|
||||
|
||||
public class BiometricPrompt
|
||||
{
|
||||
protected BiometricPrompt() {}
|
||||
abstract static public class AuthenticationCallback
|
||||
{
|
||||
public AuthenticationCallback(){}
|
||||
public void onAuthenticationError(int p0, CharSequence p1){}
|
||||
public void onAuthenticationFailed(){}
|
||||
public void onAuthenticationSucceeded(BiometricPrompt.AuthenticationResult p0){}
|
||||
}
|
||||
public BiometricPrompt(Fragment p0, BiometricPrompt.AuthenticationCallback p1){}
|
||||
public BiometricPrompt(Fragment p0, Executor p1, BiometricPrompt.AuthenticationCallback p2){}
|
||||
public BiometricPrompt(FragmentActivity p0, BiometricPrompt.AuthenticationCallback p1){}
|
||||
public BiometricPrompt(FragmentActivity p0, Executor p1, BiometricPrompt.AuthenticationCallback p2){}
|
||||
public static int AUTHENTICATION_RESULT_TYPE_BIOMETRIC = 0;
|
||||
public static int AUTHENTICATION_RESULT_TYPE_DEVICE_CREDENTIAL = 0;
|
||||
public static int AUTHENTICATION_RESULT_TYPE_UNKNOWN = 0;
|
||||
public static int ERROR_CANCELED = 0;
|
||||
public static int ERROR_HW_NOT_PRESENT = 0;
|
||||
public static int ERROR_HW_UNAVAILABLE = 0;
|
||||
public static int ERROR_LOCKOUT = 0;
|
||||
public static int ERROR_LOCKOUT_PERMANENT = 0;
|
||||
public static int ERROR_NEGATIVE_BUTTON = 0;
|
||||
public static int ERROR_NO_BIOMETRICS = 0;
|
||||
public static int ERROR_NO_DEVICE_CREDENTIAL = 0;
|
||||
public static int ERROR_NO_SPACE = 0;
|
||||
public static int ERROR_SECURITY_UPDATE_REQUIRED = 0;
|
||||
public static int ERROR_TIMEOUT = 0;
|
||||
public static int ERROR_UNABLE_TO_PROCESS = 0;
|
||||
public static int ERROR_USER_CANCELED = 0;
|
||||
public static int ERROR_VENDOR = 0;
|
||||
public void authenticate(BiometricPrompt.PromptInfo p0){}
|
||||
public void authenticate(BiometricPrompt.PromptInfo p0, BiometricPrompt.CryptoObject p1){}
|
||||
public void cancelAuthentication(){}
|
||||
static public class AuthenticationResult
|
||||
{
|
||||
protected AuthenticationResult() {}
|
||||
public BiometricPrompt.CryptoObject getCryptoObject(){ return null; }
|
||||
public int getAuthenticationType(){ return 0; }
|
||||
}
|
||||
static public class CryptoObject
|
||||
{
|
||||
protected CryptoObject() {}
|
||||
public Cipher getCipher(){ return null; }
|
||||
public CryptoObject(Cipher p0){}
|
||||
public CryptoObject(IdentityCredential p0){}
|
||||
public CryptoObject(Mac p0){}
|
||||
public CryptoObject(PresentationSession p0){}
|
||||
public CryptoObject(Signature p0){}
|
||||
public IdentityCredential getIdentityCredential(){ return null; }
|
||||
public Mac getMac(){ return null; }
|
||||
public PresentationSession getPresentationSession(){ return null; }
|
||||
public Signature getSignature(){ return null; }
|
||||
}
|
||||
static public class PromptInfo
|
||||
{
|
||||
protected PromptInfo() {}
|
||||
public CharSequence getDescription(){ return null; }
|
||||
public CharSequence getNegativeButtonText(){ return null; }
|
||||
public CharSequence getSubtitle(){ return null; }
|
||||
public CharSequence getTitle(){ return null; }
|
||||
public boolean isConfirmationRequired(){ return false; }
|
||||
public boolean isDeviceCredentialAllowed(){ return false; }
|
||||
public int getAllowedAuthenticators(){ return 0; }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user