|
16 | 16 | import static org.mockito.Mockito.times; |
17 | 17 | import static org.mockito.Mockito.when; |
18 | 18 |
|
19 | | -import android.app.KeyguardManager; |
20 | 19 | import android.content.Context; |
21 | | -import android.content.Intent; |
22 | | -import android.security.KeyPairGeneratorSpec; |
23 | 20 | import android.security.keystore.KeyGenParameterSpec; |
24 | 21 | import android.security.keystore.KeyProperties; |
25 | 22 | import android.text.TextUtils; |
|
72 | 69 | /** |
73 | 70 | * This test class uses MockedStatic for static method mocking (KeyStore, Cipher, KeyGenerator, |
74 | 71 | * KeyPairGenerator, Base64, TextUtils) and relies on Robolectric shadows for Android SDK |
75 | | - * builder classes like KeyGenParameterSpec.Builder and KeyPairGeneratorSpec.Builder. |
| 72 | + * builder classes like KeyGenParameterSpec.Builder. |
76 | 73 | * Note: Robolectric 4.x requires SDK 21+ (Android 5.0+). |
77 | 74 | */ |
78 | 75 | @RunWith(RobolectricTestRunner.class) |
@@ -172,139 +169,7 @@ public void shouldThrowWhenRSAKeyAliasIsInvalid() { |
172 | 169 | } |
173 | 170 |
|
174 | 171 | @Test |
175 | | - @Config(sdk = 21) |
176 | | - public void shouldNotCreateProtectedRSAKeyPairIfMissingAndLockScreenEnabled() throws Exception { |
177 | | - Mockito.when(keyStore.containsAlias(KEY_ALIAS)).thenReturn(false); |
178 | | - KeyStore.PrivateKeyEntry expectedEntry = Mockito.mock(KeyStore.PrivateKeyEntry.class); |
179 | | - Mockito.when(keyStore.getEntry(KEY_ALIAS, null)).thenReturn(expectedEntry); |
180 | | - |
181 | | - ArgumentCaptor<AlgorithmParameterSpec> specCaptor = ArgumentCaptor.forClass(AlgorithmParameterSpec.class); |
182 | | - |
183 | | - //Set LockScreen as Enabled but with null device credential intent |
184 | | - KeyguardManager kService = Mockito.mock(KeyguardManager.class); |
185 | | - Mockito.when(context.getSystemService(Context.KEYGUARD_SERVICE)).thenReturn(kService); |
186 | | - Mockito.when(kService.isKeyguardSecure()).thenReturn(true); |
187 | | - Mockito.when(kService.createConfirmDeviceCredentialIntent(nullable(CharSequence.class), nullable(CharSequence.class))).thenReturn(null); |
188 | | - |
189 | | - final KeyStore.PrivateKeyEntry entry = cryptoUtil.getRSAKeyEntry(); |
190 | | - |
191 | | - Mockito.verify(keyPairGenerator).initialize(specCaptor.capture()); |
192 | | - Mockito.verify(keyPairGenerator).generateKeyPair(); |
193 | | - |
194 | | - // Verify the spec properties directly (Robolectric shadows the real builder) |
195 | | - KeyPairGeneratorSpec spec = (KeyPairGeneratorSpec) specCaptor.getValue(); |
196 | | - assertThat(spec.getKeySize(), is(2048)); |
197 | | - assertThat(spec.getKeystoreAlias(), is(KEY_ALIAS)); |
198 | | - assertThat(spec.getSerialNumber(), is(BigInteger.ONE)); |
199 | | - // Note: setEncryptionRequired was NOT called since authIntent is null |
200 | | - |
201 | | - assertThat(spec.getSubjectDN(), is(notNullValue())); |
202 | | - assertThat(spec.getSubjectDN().getName(), is(CERTIFICATE_PRINCIPAL)); |
203 | | - |
204 | | - assertThat(spec.getStartDate(), is(notNullValue())); |
205 | | - long diffMillis = spec.getStartDate().getTime() - new Date().getTime(); |
206 | | - long days = TimeUnit.MILLISECONDS.toDays(diffMillis); |
207 | | - assertThat(days, is(0L)); //Date is Today |
208 | | - |
209 | | - assertThat(spec.getEndDate(), is(notNullValue())); |
210 | | - diffMillis = spec.getEndDate().getTime() - new Date().getTime(); |
211 | | - days = TimeUnit.MILLISECONDS.toDays(diffMillis); |
212 | | - assertThat(days, is(greaterThan(25 * 365L))); //Date more than 25 Years in days |
213 | | - |
214 | | - assertThat(entry, is(expectedEntry)); |
215 | | - } |
216 | | - |
217 | | - @Test |
218 | | - @Config(sdk = 21) |
219 | | - public void shouldCreateUnprotectedRSAKeyPairIfMissingAndLockScreenDisabledOnAPI21() throws Exception { |
220 | | - |
221 | | - Mockito.when(keyStore.containsAlias(KEY_ALIAS)).thenReturn(false); |
222 | | - KeyStore.PrivateKeyEntry expectedEntry = Mockito.mock(KeyStore.PrivateKeyEntry.class); |
223 | | - Mockito.when(keyStore.getEntry(KEY_ALIAS, null)).thenReturn(expectedEntry); |
224 | | - |
225 | | - ArgumentCaptor<AlgorithmParameterSpec> specCaptor = ArgumentCaptor.forClass(AlgorithmParameterSpec.class); |
226 | | - |
227 | | - //Set LockScreen as Disabled |
228 | | - KeyguardManager kService = Mockito.mock(KeyguardManager.class); |
229 | | - Mockito.when(context.getSystemService(Context.KEYGUARD_SERVICE)).thenReturn(kService); |
230 | | - Mockito.when(kService.isKeyguardSecure()).thenReturn(false); |
231 | | - Mockito.when(kService.createConfirmDeviceCredentialIntent(any(CharSequence.class), any(CharSequence.class))).thenReturn(null); |
232 | | - |
233 | | - final KeyStore.PrivateKeyEntry entry = cryptoUtil.getRSAKeyEntry(); |
234 | | - |
235 | | - Mockito.verify(keyPairGenerator).initialize(specCaptor.capture()); |
236 | | - Mockito.verify(keyPairGenerator).generateKeyPair(); |
237 | | - |
238 | | - // Verify the spec properties directly |
239 | | - KeyPairGeneratorSpec spec = (KeyPairGeneratorSpec) specCaptor.getValue(); |
240 | | - assertThat(spec.getKeySize(), is(2048)); |
241 | | - assertThat(spec.getKeystoreAlias(), is(KEY_ALIAS)); |
242 | | - assertThat(spec.getSerialNumber(), is(BigInteger.ONE)); |
243 | | - |
244 | | - assertThat(spec.getSubjectDN(), is(notNullValue())); |
245 | | - assertThat(spec.getSubjectDN().getName(), is(CERTIFICATE_PRINCIPAL)); |
246 | | - |
247 | | - assertThat(spec.getStartDate(), is(notNullValue())); |
248 | | - long diffMillis = spec.getStartDate().getTime() - new Date().getTime(); |
249 | | - long days = TimeUnit.MILLISECONDS.toDays(diffMillis); |
250 | | - assertThat(days, is(0L)); //Date is Today |
251 | | - |
252 | | - assertThat(spec.getEndDate(), is(notNullValue())); |
253 | | - diffMillis = spec.getEndDate().getTime() - new Date().getTime(); |
254 | | - days = TimeUnit.MILLISECONDS.toDays(diffMillis); |
255 | | - assertThat(days, is(greaterThan(25 * 365L))); //Date more than 25 Years in days |
256 | | - |
257 | | - assertThat(entry, is(expectedEntry)); |
258 | | - } |
259 | | - |
260 | | - @Test |
261 | | - @Config(sdk = 21) |
262 | | - public void shouldCreateProtectedRSAKeyPairIfMissingAndLockScreenEnabledOnAPI21() throws Exception { |
263 | | - |
264 | | - Mockito.when(keyStore.containsAlias(KEY_ALIAS)).thenReturn(false); |
265 | | - KeyStore.PrivateKeyEntry expectedEntry = Mockito.mock(KeyStore.PrivateKeyEntry.class); |
266 | | - Mockito.when(keyStore.getEntry(KEY_ALIAS, null)).thenReturn(expectedEntry); |
267 | | - |
268 | | - ArgumentCaptor<AlgorithmParameterSpec> specCaptor = ArgumentCaptor.forClass(AlgorithmParameterSpec.class); |
269 | | - |
270 | | - //Set LockScreen as Enabled |
271 | | - KeyguardManager kService = Mockito.mock(KeyguardManager.class); |
272 | | - Mockito.when(context.getSystemService(Context.KEYGUARD_SERVICE)).thenReturn(kService); |
273 | | - Mockito.when(kService.isKeyguardSecure()).thenReturn(true); |
274 | | - Mockito.when(kService.createConfirmDeviceCredentialIntent(any(), any())).thenReturn(new Intent()); |
275 | | - |
276 | | - final KeyStore.PrivateKeyEntry entry = cryptoUtil.getRSAKeyEntry(); |
277 | | - |
278 | | - Mockito.verify(keyPairGenerator).initialize(specCaptor.capture()); |
279 | | - Mockito.verify(keyPairGenerator).generateKeyPair(); |
280 | | - |
281 | | - // Verify the spec properties directly |
282 | | - KeyPairGeneratorSpec spec = (KeyPairGeneratorSpec) specCaptor.getValue(); |
283 | | - assertThat(spec.getKeySize(), is(2048)); |
284 | | - assertThat(spec.getKeystoreAlias(), is(KEY_ALIAS)); |
285 | | - assertThat(spec.getSerialNumber(), is(BigInteger.ONE)); |
286 | | - // Note: setEncryptionRequired WAS called since lock screen is enabled with valid authIntent |
287 | | - assertThat(spec.isEncryptionRequired(), is(true)); |
288 | | - |
289 | | - assertThat(spec.getSubjectDN(), is(notNullValue())); |
290 | | - assertThat(spec.getSubjectDN().getName(), is(CERTIFICATE_PRINCIPAL)); |
291 | | - |
292 | | - assertThat(spec.getStartDate(), is(notNullValue())); |
293 | | - long diffMillis = spec.getStartDate().getTime() - new Date().getTime(); |
294 | | - long days = TimeUnit.MILLISECONDS.toDays(diffMillis); |
295 | | - assertThat(days, is(0L)); //Date is Today |
296 | | - |
297 | | - assertThat(spec.getEndDate(), is(notNullValue())); |
298 | | - diffMillis = spec.getEndDate().getTime() - new Date().getTime(); |
299 | | - days = TimeUnit.MILLISECONDS.toDays(diffMillis); |
300 | | - assertThat(days, is(greaterThan(25 * 365L))); //Date more than 25 Years in days |
301 | | - |
302 | | - assertThat(entry, is(expectedEntry)); |
303 | | - } |
304 | | - |
305 | | - @Test |
306 | | - @Config(sdk = 23) |
307 | | - public void shouldCreateRSAKeyPairIfMissingOnAPI23AndUp() throws Exception { |
| 172 | + public void shouldCreateRSAKeyPairIfMissing() throws Exception { |
308 | 173 |
|
309 | 174 | Mockito.when(keyStore.containsAlias(KEY_ALIAS)).thenReturn(false); |
310 | 175 | KeyStore.PrivateKeyEntry expectedEntry = Mockito.mock(KeyStore.PrivateKeyEntry.class); |
|
0 commit comments