-
-
Notifications
You must be signed in to change notification settings - Fork 508
/
DecryptionResultHandlerInteractiveBiometricTest.java
176 lines (139 loc) · 7.75 KB
/
DecryptionResultHandlerInteractiveBiometricTest.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
package com.oblador.keychain.decryptionHandler;
import android.Manifest;
import android.app.KeyguardManager;
import android.content.Context;
import android.os.Build;
import androidx.biometric.BiometricPrompt;
import com.facebook.react.bridge.ReactApplicationContext;
import com.oblador.keychain.cipherStorage.CipherStorage;
import com.oblador.keychain.cipherStorage.CipherStorageBase;
import com.oblador.keychain.cipherStorage.CipherStorageKeystoreRsaEcb;
import com.oblador.keychain.exceptions.CryptoFailedException;
import org.hamcrest.Matchers;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.Key;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static androidx.biometric.BiometricPrompt.ERROR_USER_CANCELED;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
@RunWith(RobolectricTestRunner.class)
public class DecryptionResultHandlerInteractiveBiometricTest {
@Test
@Config(sdk = Build.VERSION_CODES.M)
public void testBiometryNotPermitted() {
// GIVEN
final KeyguardManager keyguardManager = mock(KeyguardManager.class);
when(keyguardManager.isKeyguardSecure()).thenReturn(false);
final ReactApplicationContext mockContext = mock(ReactApplicationContext.class);
when(mockContext.getSystemService(Context.KEYGUARD_SERVICE)).thenReturn(keyguardManager);
final CipherStorage storage = mock(CipherStorageBase.class);
final BiometricPrompt.PromptInfo promptInfo = mock(BiometricPrompt.PromptInfo.class);
final CipherStorage.DecryptionContext decryptionContext = mock(CipherStorage.DecryptionContext.class);
// WHEN
DecryptionResultHandlerInteractiveBiometric handler = new DecryptionResultHandlerInteractiveBiometric(mockContext, storage, promptInfo);
handler.askAccessPermissions(decryptionContext);
//THEN
assertThat(handler.getResult(), is(nullValue()));
assertThat(handler.getError(), Matchers.instanceOf(CryptoFailedException.class));
}
@Test(expected= NullPointerException.class)
@Config(sdk = Build.VERSION_CODES.M)
public void testBiometryAuthenticationErrorNoActivity() {
// GIVEN
final KeyguardManager keyguardManager = mock(KeyguardManager.class);
when(keyguardManager.isKeyguardSecure()).thenReturn(true);
final ReactApplicationContext mockContext = mock(ReactApplicationContext.class);
when(mockContext.getSystemService(Context.KEYGUARD_SERVICE)).thenReturn(keyguardManager);
when(mockContext.checkSelfPermission(Manifest.permission.USE_FINGERPRINT)).thenReturn(PERMISSION_GRANTED);
final CipherStorage storage = mock(CipherStorageBase.class);
final BiometricPrompt.PromptInfo promptInfo = mock(BiometricPrompt.PromptInfo.class);
final CipherStorage.DecryptionContext decryptionContext = mock(CipherStorage.DecryptionContext.class);
// WHEN
DecryptionResultHandlerInteractiveBiometric handler = new DecryptionResultHandlerInteractiveBiometric(mockContext, storage, promptInfo);
handler.askAccessPermissions(decryptionContext);
}
@Test
@Config(sdk = Build.VERSION_CODES.M)
public void testBiometryAuthenticationCancelled() {
// GIVEN
final KeyguardManager keyguardManager = mock(KeyguardManager.class);
when(keyguardManager.isKeyguardSecure()).thenReturn(true);
final ReactApplicationContext mockContext = mock(ReactApplicationContext.class);
when(mockContext.getSystemService(Context.KEYGUARD_SERVICE)).thenReturn(keyguardManager);
when(mockContext.checkSelfPermission(Manifest.permission.USE_FINGERPRINT)).thenReturn(PERMISSION_GRANTED);
final CipherStorage storage = mock(CipherStorageBase.class);
final BiometricPrompt.PromptInfo promptInfo = mock(BiometricPrompt.PromptInfo.class);
// WHEN
DecryptionResultHandlerInteractiveBiometric handler = new DecryptionResultHandlerInteractiveBiometric(mockContext, storage, promptInfo);
handler.onAuthenticationError(ERROR_USER_CANCELED, "Authentication cancelled.");
//THEN
assertThat(handler.getResult(), is(nullValue()));
assertThat(handler.getError(), Matchers.instanceOf(CryptoFailedException.class));
}
@Test
@Config(sdk = Build.VERSION_CODES.M)
public void testBiometryAuthenticationSuccessfulNoContext() {
// GIVEN
final KeyguardManager keyguardManager = mock(KeyguardManager.class);
when(keyguardManager.isKeyguardSecure()).thenReturn(true);
final ReactApplicationContext mockContext = mock(ReactApplicationContext.class);
when(mockContext.getSystemService(Context.KEYGUARD_SERVICE)).thenReturn(keyguardManager);
when(mockContext.checkSelfPermission(Manifest.permission.USE_FINGERPRINT)).thenReturn(PERMISSION_GRANTED);
final CipherStorageBase storage = mock(CipherStorageBase.class);
final BiometricPrompt.PromptInfo promptInfo = mock(BiometricPrompt.PromptInfo.class);
final BiometricPrompt.AuthenticationResult mockAuthResult = mock(BiometricPrompt.AuthenticationResult.class);
// WHEN
DecryptionResultHandlerInteractiveBiometric handler = new DecryptionResultHandlerInteractiveBiometric(mockContext, storage, promptInfo);
handler.onAuthenticationSucceeded(mockAuthResult);
//THEN
assertThat(handler.getResult(), is(nullValue()));
assertThat(handler.getError(), Matchers.instanceOf(NullPointerException.class));
}
@Test
@Config(sdk = Build.VERSION_CODES.M)
public void testBiometryAuthenticationSuccessful() throws IOException, GeneralSecurityException {
// GIVEN
final String keyAlias = "key";
final Key key = null;
final String decryptedUsername = "username";
final String decryptedPassword = "password";
final byte[] username = decryptedUsername.getBytes();
final byte[] password = decryptedPassword.getBytes();
final CipherStorage.DecryptionContext decryptionContext = new CipherStorage.DecryptionContext(
keyAlias, key, password, username);
final KeyguardManager keyguardManager = mock(KeyguardManager.class);
when(keyguardManager.isKeyguardSecure()).thenReturn(true);
final ReactApplicationContext mockContext = mock(ReactApplicationContext.class);
when(mockContext.getSystemService(Context.KEYGUARD_SERVICE)).thenReturn(keyguardManager);
when(mockContext.checkSelfPermission(Manifest.permission.USE_FINGERPRINT)).thenReturn(PERMISSION_GRANTED);
final CipherStorageBase storage = mock(CipherStorageKeystoreRsaEcb.class);
when(storage.decryptBytes(key, username)).thenReturn(decryptedUsername);
when(storage.decryptBytes(key, password)).thenReturn(decryptedPassword);
final BiometricPrompt.PromptInfo promptInfo = mock(BiometricPrompt.PromptInfo.class);
final BiometricPrompt.AuthenticationResult mockAuthResult = mock(BiometricPrompt.AuthenticationResult.class);
DecryptionResultHandlerInteractiveBiometric handler = new DecryptionResultHandlerInteractiveBiometric(mockContext, storage, promptInfo);
// WHEN
DecryptionResultHandlerInteractiveBiometric spy = spy(handler);
// Can't mock BiometricPrompt stack at the moment
doNothing().when(spy).startAuthentication();
spy.askAccessPermissions(decryptionContext);
spy.onAuthenticationSucceeded(mockAuthResult);
//THEN
CipherStorage.DecryptionResult result = spy.getResult();
assertThat(result, is(notNullValue()));
assertThat(result.username, is(decryptedUsername));
assertThat(result.password, is(decryptedPassword));
assertThat(spy.getError(), is(nullValue()));
}
}