blob: e6e020dbdb97e84cdbae27ff6c7502073f03f435 [file] [log] [blame]
Rubin Xu3bf722a2016-12-15 16:07:38 +00001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
15 */
16
Andrew Scull507d11c2017-05-03 17:19:01 +010017package com.android.server.locksettings;
Rubin Xu3bf722a2016-12-15 16:07:38 +000018
Adrian Roos7374d3a2017-03-31 14:14:53 -070019import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC;
20import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
21import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
22
23import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PASSWORD;
Rubin Xu3bf722a2016-12-15 16:07:38 +000024import static com.android.internal.widget.LockPatternUtils.SYNTHETIC_PASSWORD_ENABLED_KEY;
25import static com.android.internal.widget.LockPatternUtils.SYNTHETIC_PASSWORD_HANDLE_KEY;
Andrew Scull7f4ff4c2018-01-05 18:33:58 +000026
Andrew Sculle6527c12018-01-05 18:33:58 +000027import static org.mockito.Mockito.any;
28import static org.mockito.Mockito.atLeastOnce;
29import static org.mockito.Mockito.never;
30import static org.mockito.Mockito.reset;
Rubin Xu7cf45092017-08-28 11:47:35 +010031import static org.mockito.Mockito.verify;
Rubin Xu3bf722a2016-12-15 16:07:38 +000032
Rubin Xu7cf45092017-08-28 11:47:35 +010033import android.app.admin.PasswordMetrics;
Rubin Xu3bf722a2016-12-15 16:07:38 +000034import android.os.RemoteException;
35import android.os.UserHandle;
36
37import com.android.internal.widget.LockPatternUtils;
38import com.android.internal.widget.VerifyCredentialResponse;
Andrew Scull507d11c2017-05-03 17:19:01 +010039import com.android.server.locksettings.SyntheticPasswordManager.AuthenticationResult;
40import com.android.server.locksettings.SyntheticPasswordManager.AuthenticationToken;
Adrian Roos7374d3a2017-03-31 14:14:53 -070041import com.android.server.locksettings.SyntheticPasswordManager.PasswordData;
Rubin Xu3bf722a2016-12-15 16:07:38 +000042
Andrew Sculle6527c12018-01-05 18:33:58 +000043import org.mockito.ArgumentCaptor;
44
Lenka Trochtova66c492a2018-12-06 11:29:21 +010045import java.util.ArrayList;
46
Rubin Xu3bf722a2016-12-15 16:07:38 +000047
48/**
Andrew Scull507d11c2017-05-03 17:19:01 +010049 * runtest frameworks-services -c com.android.server.locksettings.SyntheticPasswordTests
Rubin Xu3bf722a2016-12-15 16:07:38 +000050 */
51public class SyntheticPasswordTests extends BaseLockSettingsServiceTests {
52
Adrian Roos7374d3a2017-03-31 14:14:53 -070053 public static final byte[] PAYLOAD = new byte[] {1, 2, -1, -2, 55};
54 public static final byte[] PAYLOAD2 = new byte[] {2, 3, -2, -3, 44, 1};
55
Rubin Xu3bf722a2016-12-15 16:07:38 +000056 @Override
57 protected void setUp() throws Exception {
58 super.setUp();
59 }
60
61 @Override
62 protected void tearDown() throws Exception {
63 super.tearDown();
64 }
65
66 public void testPasswordBasedSyntheticPassword() throws RemoteException {
67 final int USER_ID = 10;
Rich Canningsf64ec632019-02-21 12:40:36 -080068 final byte[] password = "user-password".getBytes();
69 final byte[] badPassword = "bad-password".getBytes();
Adrian Roos2adc2632017-09-05 17:01:42 +020070 MockSyntheticPasswordManager manager = new MockSyntheticPasswordManager(mContext, mStorage,
Adrian Roos7374d3a2017-03-31 14:14:53 -070071 mGateKeeperService, mUserManager);
Rubin Xu3bf722a2016-12-15 16:07:38 +000072 AuthenticationToken authToken = manager.newSyntheticPasswordAndSid(mGateKeeperService, null,
73 null, USER_ID);
Rich Canningsf64ec632019-02-21 12:40:36 -080074 long handle = manager.createPasswordBasedSyntheticPassword(mGateKeeperService,
75 password, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, authToken,
76 PASSWORD_QUALITY_ALPHABETIC, USER_ID);
Rubin Xu3bf722a2016-12-15 16:07:38 +000077
Rubin Xucf326f12017-11-15 11:55:35 +000078 AuthenticationResult result = manager.unwrapPasswordBasedSyntheticPassword(
Rich Canningsf64ec632019-02-21 12:40:36 -080079 mGateKeeperService, handle, password, USER_ID, null);
80 assertArrayEquals(result.authToken.deriveKeyStorePassword(),
81 authToken.deriveKeyStorePassword());
Rubin Xu3bf722a2016-12-15 16:07:38 +000082
Rubin Xucf326f12017-11-15 11:55:35 +000083 result = manager.unwrapPasswordBasedSyntheticPassword(mGateKeeperService, handle,
Rich Canningsf64ec632019-02-21 12:40:36 -080084 badPassword, USER_ID, null);
Rubin Xu3bf722a2016-12-15 16:07:38 +000085 assertNull(result.authToken);
86 }
87
Rubin Xu16c823e2017-06-27 14:44:58 +010088 private void disableSyntheticPassword() throws RemoteException {
Rubin Xu3bf722a2016-12-15 16:07:38 +000089 mService.setLong(SYNTHETIC_PASSWORD_ENABLED_KEY, 0, UserHandle.USER_SYSTEM);
90 }
91
Rubin Xu16c823e2017-06-27 14:44:58 +010092 private void enableSyntheticPassword() throws RemoteException {
Rubin Xu3bf722a2016-12-15 16:07:38 +000093 mService.setLong(SYNTHETIC_PASSWORD_ENABLED_KEY, 1, UserHandle.USER_SYSTEM);
94 }
95
96 private boolean hasSyntheticPassword(int userId) throws RemoteException {
97 return mService.getLong(SYNTHETIC_PASSWORD_HANDLE_KEY, 0, userId) != 0;
98 }
99
100 public void testPasswordMigration() throws RemoteException {
Rich Canningsf64ec632019-02-21 12:40:36 -0800101 final byte[] password = "testPasswordMigration-password".getBytes();
Rubin Xu3bf722a2016-12-15 16:07:38 +0000102
Rubin Xu16c823e2017-06-27 14:44:58 +0100103 disableSyntheticPassword();
Rich Canningsf64ec632019-02-21 12:40:36 -0800104 mService.setLockCredential(password, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
Adrian Roos7374d3a2017-03-31 14:14:53 -0700105 PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
Rubin Xu3bf722a2016-12-15 16:07:38 +0000106 long sid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
107 final byte[] primaryStorageKey = mStorageManager.getUserUnlockToken(PRIMARY_USER_ID);
Rubin Xu16c823e2017-06-27 14:44:58 +0100108 enableSyntheticPassword();
Rubin Xu3bf722a2016-12-15 16:07:38 +0000109 // Performs migration
Andrew Scull7f4ff4c2018-01-05 18:33:58 +0000110 assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(
Rich Canningsf64ec632019-02-21 12:40:36 -0800111 password, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID)
Andrew Scull7f4ff4c2018-01-05 18:33:58 +0000112 .getResponseCode());
Rubin Xu3bf722a2016-12-15 16:07:38 +0000113 assertEquals(sid, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
114 assertTrue(hasSyntheticPassword(PRIMARY_USER_ID));
115
116 // SP-based verification
Rich Canningsf64ec632019-02-21 12:40:36 -0800117 assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(password,
118 LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID)
Andrew Scull7f4ff4c2018-01-05 18:33:58 +0000119 .getResponseCode());
120 assertArrayNotEquals(primaryStorageKey,
121 mStorageManager.getUserUnlockToken(PRIMARY_USER_ID));
Rubin Xu3bf722a2016-12-15 16:07:38 +0000122 }
123
Rich Canningsf64ec632019-02-21 12:40:36 -0800124 protected void initializeCredentialUnderSP(byte[] password, int userId) throws RemoteException {
Rubin Xu16c823e2017-06-27 14:44:58 +0100125 enableSyntheticPassword();
Adrian Roos7374d3a2017-03-31 14:14:53 -0700126 int quality = password != null ? PASSWORD_QUALITY_ALPHABETIC
127 : PASSWORD_QUALITY_UNSPECIFIED;
128 int type = password != null ? LockPatternUtils.CREDENTIAL_TYPE_PASSWORD
129 : LockPatternUtils.CREDENTIAL_TYPE_NONE;
130 mService.setLockCredential(password, type, null, quality, userId);
Rubin Xu3bf722a2016-12-15 16:07:38 +0000131 }
132
133 public void testSyntheticPasswordChangeCredential() throws RemoteException {
Rich Canningsf64ec632019-02-21 12:40:36 -0800134 final byte[] password = "testSyntheticPasswordChangeCredential-password".getBytes();
135 final byte[] newPassword = "testSyntheticPasswordChangeCredential-newpassword".getBytes();
Rubin Xu3bf722a2016-12-15 16:07:38 +0000136
Rich Canningsf64ec632019-02-21 12:40:36 -0800137 initializeCredentialUnderSP(password, PRIMARY_USER_ID);
Rubin Xu3bf722a2016-12-15 16:07:38 +0000138 long sid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
Rich Canningsf64ec632019-02-21 12:40:36 -0800139 mService.setLockCredential(newPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, password,
Adrian Roos7374d3a2017-03-31 14:14:53 -0700140 PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
Andrew Scull7f4ff4c2018-01-05 18:33:58 +0000141 assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(
Rich Canningsf64ec632019-02-21 12:40:36 -0800142 newPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID)
Andrew Scull7f4ff4c2018-01-05 18:33:58 +0000143 .getResponseCode());
Rubin Xu3bf722a2016-12-15 16:07:38 +0000144 assertEquals(sid, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
145 }
146
147 public void testSyntheticPasswordVerifyCredential() throws RemoteException {
Rich Canningsf64ec632019-02-21 12:40:36 -0800148 final byte[] password = "testSyntheticPasswordVerifyCredential-password".getBytes();
149 final byte[] badPassword = "testSyntheticPasswordVerifyCredential-badpassword".getBytes();
Rubin Xu3bf722a2016-12-15 16:07:38 +0000150
Rich Canningsf64ec632019-02-21 12:40:36 -0800151 initializeCredentialUnderSP(password, PRIMARY_USER_ID);
Andrew Scull7f4ff4c2018-01-05 18:33:58 +0000152 assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(
Rich Canningsf64ec632019-02-21 12:40:36 -0800153 password, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID)
Andrew Scull7f4ff4c2018-01-05 18:33:58 +0000154 .getResponseCode());
Rubin Xu3bf722a2016-12-15 16:07:38 +0000155
Andrew Scull7f4ff4c2018-01-05 18:33:58 +0000156 assertEquals(VerifyCredentialResponse.RESPONSE_ERROR, mService.verifyCredential(
Rich Canningsf64ec632019-02-21 12:40:36 -0800157 badPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID)
158 .getResponseCode());
Rubin Xu3bf722a2016-12-15 16:07:38 +0000159 }
160
161 public void testSyntheticPasswordClearCredential() throws RemoteException {
Rich Canningsf64ec632019-02-21 12:40:36 -0800162 final byte[] password = "testSyntheticPasswordClearCredential-password".getBytes();
163 final byte[] badPassword = "testSyntheticPasswordClearCredential-newpassword".getBytes();
Rubin Xu3bf722a2016-12-15 16:07:38 +0000164
Rich Canningsf64ec632019-02-21 12:40:36 -0800165 initializeCredentialUnderSP(password, PRIMARY_USER_ID);
Rubin Xu3bf722a2016-12-15 16:07:38 +0000166 long sid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
167 // clear password
Rich Canningsf64ec632019-02-21 12:40:36 -0800168 mService.setLockCredential(null, LockPatternUtils.CREDENTIAL_TYPE_NONE, password,
Adrian Roos7374d3a2017-03-31 14:14:53 -0700169 PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID);
Rubin Xu3bf722a2016-12-15 16:07:38 +0000170 assertEquals(0 ,mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
171
172 // set a new password
Rich Canningsf64ec632019-02-21 12:40:36 -0800173 mService.setLockCredential(badPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
Adrian Roos7374d3a2017-03-31 14:14:53 -0700174 PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
Andrew Scull7f4ff4c2018-01-05 18:33:58 +0000175 assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(
Rich Canningsf64ec632019-02-21 12:40:36 -0800176 badPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID)
177 .getResponseCode());
Andrew Scull7f4ff4c2018-01-05 18:33:58 +0000178 assertNotEquals(sid, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
Rubin Xu3bf722a2016-12-15 16:07:38 +0000179 }
180
Andrew Sculle6527c12018-01-05 18:33:58 +0000181 public void testSyntheticPasswordChangeCredentialKeepsAuthSecret() throws RemoteException {
Rich Canningsf64ec632019-02-21 12:40:36 -0800182 final byte[] password =
183 "testSyntheticPasswordChangeCredentialKeepsAuthSecret-password".getBytes();
184 final byte[] badPassword =
185 "testSyntheticPasswordChangeCredentialKeepsAuthSecret-new".getBytes();
Andrew Sculle6527c12018-01-05 18:33:58 +0000186
Rich Canningsf64ec632019-02-21 12:40:36 -0800187 initializeCredentialUnderSP(password, PRIMARY_USER_ID);
188 mService.setLockCredential(badPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, password,
Andrew Sculle6527c12018-01-05 18:33:58 +0000189 PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
190 assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(
Rich Canningsf64ec632019-02-21 12:40:36 -0800191 badPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID)
Andrew Sculle6527c12018-01-05 18:33:58 +0000192 .getResponseCode());
193
194 // Check the same secret was passed each time
195 ArgumentCaptor<ArrayList<Byte>> secret = ArgumentCaptor.forClass(ArrayList.class);
196 verify(mAuthSecretService, atLeastOnce()).primaryUserCredential(secret.capture());
197 assertEquals(1, secret.getAllValues().stream().distinct().count());
198 }
199
200 public void testSyntheticPasswordVerifyPassesPrimaryUserAuthSecret() throws RemoteException {
Rich Canningsf64ec632019-02-21 12:40:36 -0800201 final byte[] password =
202 "testSyntheticPasswordVerifyPassesPrimaryUserAuthSecret-password".getBytes();
203 final byte[] newPassword =
204 "testSyntheticPasswordVerifyPassesPrimaryUserAuthSecret-new".getBytes();
Andrew Sculle6527c12018-01-05 18:33:58 +0000205
Rich Canningsf64ec632019-02-21 12:40:36 -0800206 initializeCredentialUnderSP(password, PRIMARY_USER_ID);
Andrew Sculle6527c12018-01-05 18:33:58 +0000207 reset(mAuthSecretService);
Rich Canningsf64ec632019-02-21 12:40:36 -0800208 assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(password,
209 LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID)
Andrew Sculle6527c12018-01-05 18:33:58 +0000210 .getResponseCode());
211 verify(mAuthSecretService).primaryUserCredential(any(ArrayList.class));
212 }
213
214 public void testSecondaryUserDoesNotPassAuthSecret() throws RemoteException {
Rich Canningsf64ec632019-02-21 12:40:36 -0800215 final byte[] password = "testSecondaryUserDoesNotPassAuthSecret-password".getBytes();
Andrew Sculle6527c12018-01-05 18:33:58 +0000216
Rich Canningsf64ec632019-02-21 12:40:36 -0800217 initializeCredentialUnderSP(password, SECONDARY_USER_ID);
Andrew Sculle6527c12018-01-05 18:33:58 +0000218 assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(
Rich Canningsf64ec632019-02-21 12:40:36 -0800219 password, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, SECONDARY_USER_ID)
Andrew Sculle6527c12018-01-05 18:33:58 +0000220 .getResponseCode());
221 verify(mAuthSecretService, never()).primaryUserCredential(any(ArrayList.class));
222 }
223
Andrew Scullf49794b2018-04-13 12:01:25 +0100224 public void testNoSyntheticPasswordOrCredentialDoesNotPassAuthSecret() throws RemoteException {
225 // Setting null doesn't create a synthetic password
226 initializeCredentialUnderSP(null, PRIMARY_USER_ID);
227
228 reset(mAuthSecretService);
229 mService.onUnlockUser(PRIMARY_USER_ID);
230 mService.mHandler.runWithScissors(() -> {}, 0 /*now*/); // Flush runnables on handler
231 verify(mAuthSecretService, never()).primaryUserCredential(any(ArrayList.class));
232 }
233
234 public void testSyntheticPasswordAndCredentialDoesNotPassAuthSecret() throws RemoteException {
Rich Canningsf64ec632019-02-21 12:40:36 -0800235 final byte[] password = "passwordForASyntheticPassword".getBytes();
236 initializeCredentialUnderSP(password, PRIMARY_USER_ID);
Andrew Scullf49794b2018-04-13 12:01:25 +0100237
238 reset(mAuthSecretService);
239 mService.onUnlockUser(PRIMARY_USER_ID);
240 mService.mHandler.runWithScissors(() -> {}, 0 /*now*/); // Flush runnables on handler
241 verify(mAuthSecretService, never()).primaryUserCredential(any(ArrayList.class));
242 }
243
244 public void testSyntheticPasswordButNoCredentialPassesAuthSecret() throws RemoteException {
Rich Canningsf64ec632019-02-21 12:40:36 -0800245 final byte[] password = "getASyntheticPassword".getBytes();
246 initializeCredentialUnderSP(password, PRIMARY_USER_ID);
247 mService.setLockCredential(null, LockPatternUtils.CREDENTIAL_TYPE_NONE, password,
Andrew Scullf49794b2018-04-13 12:01:25 +0100248 PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID);
249
250 reset(mAuthSecretService);
251 mService.onUnlockUser(PRIMARY_USER_ID);
252 mService.mHandler.runWithScissors(() -> {}, 0 /*now*/); // Flush runnables on handler
253 verify(mAuthSecretService).primaryUserCredential(any(ArrayList.class));
254 }
255
Rubin Xu3bf722a2016-12-15 16:07:38 +0000256 public void testManagedProfileUnifiedChallengeMigration() throws RemoteException {
Rich Canningsf64ec632019-02-21 12:40:36 -0800257 final byte[] UnifiedPassword = "testManagedProfileUnifiedChallengeMigration-pwd".getBytes();
Rubin Xu16c823e2017-06-27 14:44:58 +0100258 disableSyntheticPassword();
Adrian Roos7374d3a2017-03-31 14:14:53 -0700259 mService.setLockCredential(UnifiedPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
260 PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
Rubin Xu3bf722a2016-12-15 16:07:38 +0000261 mService.setSeparateProfileChallengeEnabled(MANAGED_PROFILE_USER_ID, false, null);
262 final long primarySid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
263 final long profileSid = mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID);
264 final byte[] primaryStorageKey = mStorageManager.getUserUnlockToken(PRIMARY_USER_ID);
265 final byte[] profileStorageKey = mStorageManager.getUserUnlockToken(MANAGED_PROFILE_USER_ID);
266 assertTrue(primarySid != 0);
267 assertTrue(profileSid != 0);
268 assertTrue(profileSid != primarySid);
269
270 // do migration
Rubin Xu16c823e2017-06-27 14:44:58 +0100271 enableSyntheticPassword();
Andrew Scull7f4ff4c2018-01-05 18:33:58 +0000272 assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(
273 UnifiedPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID)
274 .getResponseCode());
Rubin Xu3bf722a2016-12-15 16:07:38 +0000275
276 // verify
Andrew Scull7f4ff4c2018-01-05 18:33:58 +0000277 assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(
278 UnifiedPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID)
279 .getResponseCode());
Rubin Xu3bf722a2016-12-15 16:07:38 +0000280 assertEquals(primarySid, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
281 assertEquals(profileSid, mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID));
Andrew Scull7f4ff4c2018-01-05 18:33:58 +0000282 assertArrayNotEquals(primaryStorageKey,
283 mStorageManager.getUserUnlockToken(PRIMARY_USER_ID));
284 assertArrayNotEquals(profileStorageKey,
285 mStorageManager.getUserUnlockToken(MANAGED_PROFILE_USER_ID));
Rubin Xu3bf722a2016-12-15 16:07:38 +0000286 assertTrue(hasSyntheticPassword(PRIMARY_USER_ID));
287 assertTrue(hasSyntheticPassword(MANAGED_PROFILE_USER_ID));
288 }
289
290 public void testManagedProfileSeparateChallengeMigration() throws RemoteException {
Rich Canningsf64ec632019-02-21 12:40:36 -0800291 final byte[] primaryPassword =
292 "testManagedProfileSeparateChallengeMigration-primary".getBytes();
293 final byte[] profilePassword =
294 "testManagedProfileSeparateChallengeMigration-profile".getBytes();
Rubin Xu16c823e2017-06-27 14:44:58 +0100295 disableSyntheticPassword();
Adrian Roos7374d3a2017-03-31 14:14:53 -0700296 mService.setLockCredential(primaryPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
297 PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
298 mService.setLockCredential(profilePassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
299 PASSWORD_QUALITY_ALPHABETIC, MANAGED_PROFILE_USER_ID);
Rubin Xu3bf722a2016-12-15 16:07:38 +0000300 final long primarySid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
301 final long profileSid = mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID);
302 final byte[] primaryStorageKey = mStorageManager.getUserUnlockToken(PRIMARY_USER_ID);
303 final byte[] profileStorageKey = mStorageManager.getUserUnlockToken(MANAGED_PROFILE_USER_ID);
304 assertTrue(primarySid != 0);
305 assertTrue(profileSid != 0);
306 assertTrue(profileSid != primarySid);
307
308 // do migration
Rubin Xu16c823e2017-06-27 14:44:58 +0100309 enableSyntheticPassword();
Andrew Scull7f4ff4c2018-01-05 18:33:58 +0000310 assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(
311 primaryPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID)
312 .getResponseCode());
313 assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(
314 profilePassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
315 0, MANAGED_PROFILE_USER_ID).getResponseCode());
Rubin Xu3bf722a2016-12-15 16:07:38 +0000316
317 // verify
Andrew Scull7f4ff4c2018-01-05 18:33:58 +0000318 assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(
319 primaryPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID)
320 .getResponseCode());
321 assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(
322 profilePassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
323 0, MANAGED_PROFILE_USER_ID).getResponseCode());
Rubin Xu3bf722a2016-12-15 16:07:38 +0000324 assertEquals(primarySid, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
325 assertEquals(profileSid, mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID));
Andrew Scull7f4ff4c2018-01-05 18:33:58 +0000326 assertArrayNotEquals(primaryStorageKey,
327 mStorageManager.getUserUnlockToken(PRIMARY_USER_ID));
328 assertArrayNotEquals(profileStorageKey,
329 mStorageManager.getUserUnlockToken(MANAGED_PROFILE_USER_ID));
Rubin Xu3bf722a2016-12-15 16:07:38 +0000330 assertTrue(hasSyntheticPassword(PRIMARY_USER_ID));
331 assertTrue(hasSyntheticPassword(MANAGED_PROFILE_USER_ID));
332 }
Rubin Xuf095f832017-01-31 15:23:34 +0000333
334 public void testTokenBasedResetPassword() throws RemoteException {
Rich Canningsf64ec632019-02-21 12:40:36 -0800335 final byte[] password = "password".getBytes();
336 final byte[] pattern = "123654".getBytes();
337 final byte[] token = "some-high-entropy-secure-token".getBytes();
338 initializeCredentialUnderSP(password, PRIMARY_USER_ID);
Rubin Xuf095f832017-01-31 15:23:34 +0000339 final byte[] storageKey = mStorageManager.getUserUnlockToken(PRIMARY_USER_ID);
340
Rich Canningsf64ec632019-02-21 12:40:36 -0800341 long handle = mLocalService.addEscrowToken(token, PRIMARY_USER_ID);
Rubin Xufcd49f92017-08-24 18:21:52 +0100342 assertFalse(mLocalService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
Rubin Xuf095f832017-01-31 15:23:34 +0000343
Rich Canningsf64ec632019-02-21 12:40:36 -0800344 mService.verifyCredential(password, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0,
Rubin Xu7cf45092017-08-28 11:47:35 +0100345 PRIMARY_USER_ID).getResponseCode();
Rubin Xufcd49f92017-08-24 18:21:52 +0100346 assertTrue(mLocalService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
Rubin Xuf095f832017-01-31 15:23:34 +0000347
Rich Canningsf64ec632019-02-21 12:40:36 -0800348 mLocalService.setLockCredentialWithToken(pattern, LockPatternUtils.CREDENTIAL_TYPE_PATTERN,
349 handle, token, PASSWORD_QUALITY_SOMETHING, PRIMARY_USER_ID);
Rubin Xuf095f832017-01-31 15:23:34 +0000350
Rubin Xu7cf45092017-08-28 11:47:35 +0100351 // Verify DPM gets notified about new device lock
352 mService.mHandler.runWithScissors(() -> {}, 0 /*now*/); // Flush runnables on handler
Rich Canningsf64ec632019-02-21 12:40:36 -0800353 PasswordMetrics metric = PasswordMetrics.computeForPassword(pattern);
Rubin Xu7cf45092017-08-28 11:47:35 +0100354 metric.quality = PASSWORD_QUALITY_SOMETHING;
355 verify(mDevicePolicyManager).setActivePasswordState(metric, PRIMARY_USER_ID);
356
Andrew Scull7f4ff4c2018-01-05 18:33:58 +0000357 assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(
Rich Canningsf64ec632019-02-21 12:40:36 -0800358 pattern, LockPatternUtils.CREDENTIAL_TYPE_PATTERN, 0, PRIMARY_USER_ID)
Andrew Scull7f4ff4c2018-01-05 18:33:58 +0000359 .getResponseCode());
Rubin Xuf095f832017-01-31 15:23:34 +0000360 assertArrayEquals(storageKey, mStorageManager.getUserUnlockToken(PRIMARY_USER_ID));
361 }
362
363 public void testTokenBasedClearPassword() throws RemoteException {
Rich Canningsf64ec632019-02-21 12:40:36 -0800364 final byte[] password = "password".getBytes();
365 final byte[] pattern = "123654".getBytes();
366 final byte[] token = "some-high-entropy-secure-token".getBytes();
367 initializeCredentialUnderSP(password, PRIMARY_USER_ID);
Rubin Xuf095f832017-01-31 15:23:34 +0000368 final byte[] storageKey = mStorageManager.getUserUnlockToken(PRIMARY_USER_ID);
369
Rich Canningsf64ec632019-02-21 12:40:36 -0800370 long handle = mLocalService.addEscrowToken(token, PRIMARY_USER_ID);
Rubin Xufcd49f92017-08-24 18:21:52 +0100371 assertFalse(mLocalService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
Rubin Xuf095f832017-01-31 15:23:34 +0000372
Rich Canningsf64ec632019-02-21 12:40:36 -0800373 mService.verifyCredential(password, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
Andrew Scull7f4ff4c2018-01-05 18:33:58 +0000374 0, PRIMARY_USER_ID).getResponseCode();
Rubin Xufcd49f92017-08-24 18:21:52 +0100375 assertTrue(mLocalService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
Rubin Xuf095f832017-01-31 15:23:34 +0000376
Rubin Xufcd49f92017-08-24 18:21:52 +0100377 mLocalService.setLockCredentialWithToken(null, LockPatternUtils.CREDENTIAL_TYPE_NONE,
Rich Canningsf64ec632019-02-21 12:40:36 -0800378 handle, token, PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID);
379 mLocalService.setLockCredentialWithToken(pattern, LockPatternUtils.CREDENTIAL_TYPE_PATTERN,
380 handle, token, PASSWORD_QUALITY_SOMETHING, PRIMARY_USER_ID);
Rubin Xuf095f832017-01-31 15:23:34 +0000381
Andrew Scull7f4ff4c2018-01-05 18:33:58 +0000382 assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(
Rich Canningsf64ec632019-02-21 12:40:36 -0800383 pattern, LockPatternUtils.CREDENTIAL_TYPE_PATTERN, 0, PRIMARY_USER_ID)
Andrew Scull7f4ff4c2018-01-05 18:33:58 +0000384 .getResponseCode());
Rubin Xuf095f832017-01-31 15:23:34 +0000385 assertArrayEquals(storageKey, mStorageManager.getUserUnlockToken(PRIMARY_USER_ID));
386 }
387
388 public void testTokenBasedResetPasswordAfterCredentialChanges() throws RemoteException {
Rich Canningsf64ec632019-02-21 12:40:36 -0800389 final byte[] password = "password".getBytes();
390 final byte[] pattern = "123654".getBytes();
391 final byte[] newPassword = "password".getBytes();
392 final byte[] token = "some-high-entropy-secure-token".getBytes();
393 initializeCredentialUnderSP(password, PRIMARY_USER_ID);
Rubin Xuf095f832017-01-31 15:23:34 +0000394 final byte[] storageKey = mStorageManager.getUserUnlockToken(PRIMARY_USER_ID);
395
Rich Canningsf64ec632019-02-21 12:40:36 -0800396 long handle = mLocalService.addEscrowToken(token, PRIMARY_USER_ID);
Rubin Xufcd49f92017-08-24 18:21:52 +0100397 assertFalse(mLocalService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
Rubin Xuf095f832017-01-31 15:23:34 +0000398
Rich Canningsf64ec632019-02-21 12:40:36 -0800399 mService.verifyCredential(password, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
Andrew Scull7f4ff4c2018-01-05 18:33:58 +0000400 0, PRIMARY_USER_ID).getResponseCode();
Rubin Xufcd49f92017-08-24 18:21:52 +0100401 assertTrue(mLocalService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
Rubin Xuf095f832017-01-31 15:23:34 +0000402
Rich Canningsf64ec632019-02-21 12:40:36 -0800403 mService.setLockCredential(pattern, LockPatternUtils.CREDENTIAL_TYPE_PATTERN, password,
Adrian Roos7374d3a2017-03-31 14:14:53 -0700404 PASSWORD_QUALITY_SOMETHING, PRIMARY_USER_ID);
Rubin Xuf095f832017-01-31 15:23:34 +0000405
Rich Canningsf64ec632019-02-21 12:40:36 -0800406 mLocalService.setLockCredentialWithToken(newPassword,
407 LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, handle, token,
Rubin Xufcd49f92017-08-24 18:21:52 +0100408 PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
Rubin Xuf095f832017-01-31 15:23:34 +0000409
Andrew Scull7f4ff4c2018-01-05 18:33:58 +0000410 assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(
Rich Canningsf64ec632019-02-21 12:40:36 -0800411 newPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID)
Andrew Scull7f4ff4c2018-01-05 18:33:58 +0000412 .getResponseCode());
Rubin Xuf095f832017-01-31 15:23:34 +0000413 assertArrayEquals(storageKey, mStorageManager.getUserUnlockToken(PRIMARY_USER_ID));
414 }
415
Andrew Scull7f4ff4c2018-01-05 18:33:58 +0000416 public void testEscrowTokenActivatedImmediatelyIfNoUserPasswordNeedsMigration()
417 throws RemoteException {
Rich Canningsf64ec632019-02-21 12:40:36 -0800418 final String token = "some-high-entropy-secure-token";
Rubin Xu16c823e2017-06-27 14:44:58 +0100419 enableSyntheticPassword();
Rich Canningsf64ec632019-02-21 12:40:36 -0800420 long handle = mLocalService.addEscrowToken(token.getBytes(), PRIMARY_USER_ID);
Rubin Xufcd49f92017-08-24 18:21:52 +0100421 assertTrue(mLocalService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
Rubin Xuf095f832017-01-31 15:23:34 +0000422 assertEquals(0, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
423 assertTrue(hasSyntheticPassword(PRIMARY_USER_ID));
424 }
425
Andrew Scull7f4ff4c2018-01-05 18:33:58 +0000426 public void testEscrowTokenActivatedImmediatelyIfNoUserPasswordNoMigration()
427 throws RemoteException {
Rich Canningsf64ec632019-02-21 12:40:36 -0800428 final String token = "some-high-entropy-secure-token";
Rubin Xuf095f832017-01-31 15:23:34 +0000429 initializeCredentialUnderSP(null, PRIMARY_USER_ID);
Rich Canningsf64ec632019-02-21 12:40:36 -0800430 long handle = mLocalService.addEscrowToken(token.getBytes(), PRIMARY_USER_ID);
Rubin Xufcd49f92017-08-24 18:21:52 +0100431 assertTrue(mLocalService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
Rubin Xuf095f832017-01-31 15:23:34 +0000432 assertEquals(0, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
433 assertTrue(hasSyntheticPassword(PRIMARY_USER_ID));
434 }
435
Andrew Scull7f4ff4c2018-01-05 18:33:58 +0000436 public void testEscrowTokenActivatedLaterWithUserPasswordNeedsMigration()
437 throws RemoteException {
Rich Canningsf64ec632019-02-21 12:40:36 -0800438 final byte[] token = "some-high-entropy-secure-token".getBytes();
439 final byte[] password = "password".getBytes();
Rubin Xu128180b2017-04-12 18:02:44 +0100440 // Set up pre-SP user password
Rubin Xu16c823e2017-06-27 14:44:58 +0100441 disableSyntheticPassword();
Rich Canningsf64ec632019-02-21 12:40:36 -0800442 mService.setLockCredential(password, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
Adrian Roos7374d3a2017-03-31 14:14:53 -0700443 PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
Rubin Xu16c823e2017-06-27 14:44:58 +0100444 enableSyntheticPassword();
Rubin Xu128180b2017-04-12 18:02:44 +0100445
Rich Canningsf64ec632019-02-21 12:40:36 -0800446 long handle = mLocalService.addEscrowToken(token, PRIMARY_USER_ID);
Rubin Xu128180b2017-04-12 18:02:44 +0100447 // Token not activated immediately since user password exists
Rubin Xufcd49f92017-08-24 18:21:52 +0100448 assertFalse(mLocalService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
Rubin Xu128180b2017-04-12 18:02:44 +0100449 // Activate token (password gets migrated to SP at the same time)
Andrew Scull7f4ff4c2018-01-05 18:33:58 +0000450 assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(
Rich Canningsf64ec632019-02-21 12:40:36 -0800451 password, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID)
Andrew Scull7f4ff4c2018-01-05 18:33:58 +0000452 .getResponseCode());
Rubin Xu128180b2017-04-12 18:02:44 +0100453 // Verify token is activated
Rubin Xufcd49f92017-08-24 18:21:52 +0100454 assertTrue(mLocalService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
Rubin Xu128180b2017-04-12 18:02:44 +0100455 }
456
Lenka Trochtova66c492a2018-12-06 11:29:21 +0100457 public void testSetLockCredentialWithTokenFailsWithoutLockScreen() throws Exception {
Rich Canningsf64ec632019-02-21 12:40:36 -0800458 final byte[] password = "password".getBytes();
459 final byte[] pattern = "123654".getBytes();
460 final byte[] token = "some-high-entropy-secure-token".getBytes();
Lenka Trochtova66c492a2018-12-06 11:29:21 +0100461
462 mHasSecureLockScreen = false;
463 enableSyntheticPassword();
Rich Canningsf64ec632019-02-21 12:40:36 -0800464 long handle = mLocalService.addEscrowToken(token, PRIMARY_USER_ID);
Lenka Trochtova66c492a2018-12-06 11:29:21 +0100465 assertTrue(mLocalService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
466
467 try {
468 mLocalService.setLockCredentialWithToken(password,
Rich Canningsf64ec632019-02-21 12:40:36 -0800469 LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, handle, token,
Lenka Trochtova66c492a2018-12-06 11:29:21 +0100470 PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
471 fail("An exception should have been thrown.");
472 } catch (UnsupportedOperationException e) {
473 // Success - the exception was expected.
474 }
475 assertFalse(mService.havePassword(PRIMARY_USER_ID));
476
477 try {
478 mLocalService.setLockCredentialWithToken(pattern,
Rich Canningsf64ec632019-02-21 12:40:36 -0800479 LockPatternUtils.CREDENTIAL_TYPE_PATTERN, handle, token,
Lenka Trochtova66c492a2018-12-06 11:29:21 +0100480 PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
481 fail("An exception should have been thrown.");
482 } catch (UnsupportedOperationException e) {
483 // Success - the exception was expected.
484 }
485 assertFalse(mService.havePattern(PRIMARY_USER_ID));
486 }
487
Rubin Xu4ed98982018-05-23 14:27:53 +0100488 public void testgetHashFactorPrimaryUser() throws RemoteException {
Rich Canningsf64ec632019-02-21 12:40:36 -0800489 final byte[] password = "password".getBytes();
Rubin Xu4ed98982018-05-23 14:27:53 +0100490 mService.setLockCredential(password, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
491 PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
492 final byte[] hashFactor = mService.getHashFactor(password, PRIMARY_USER_ID);
493 assertNotNull(hashFactor);
494
Rich Canningsf64ec632019-02-21 12:40:36 -0800495 mService.setLockCredential(null, LockPatternUtils.CREDENTIAL_TYPE_NONE,
496 password, PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID);
Rubin Xu4ed98982018-05-23 14:27:53 +0100497 final byte[] newHashFactor = mService.getHashFactor(null, PRIMARY_USER_ID);
498 assertNotNull(newHashFactor);
499 // Hash factor should never change after password change/removal
500 assertArrayEquals(hashFactor, newHashFactor);
501 }
502
503 public void testgetHashFactorManagedProfileUnifiedChallenge() throws RemoteException {
Rich Canningsf64ec632019-02-21 12:40:36 -0800504 final byte[] pattern = "1236".getBytes();
505 mService.setLockCredential(pattern, LockPatternUtils.CREDENTIAL_TYPE_PATTERN,
506 null, PASSWORD_QUALITY_SOMETHING, PRIMARY_USER_ID);
Rubin Xu4ed98982018-05-23 14:27:53 +0100507 mService.setSeparateProfileChallengeEnabled(MANAGED_PROFILE_USER_ID, false, null);
508 assertNotNull(mService.getHashFactor(null, MANAGED_PROFILE_USER_ID));
509 }
510
511 public void testgetHashFactorManagedProfileSeparateChallenge() throws RemoteException {
Rich Canningsf64ec632019-02-21 12:40:36 -0800512 final byte[] primaryPassword = "primary".getBytes();
513 final byte[] profilePassword = "profile".getBytes();
Rubin Xu4ed98982018-05-23 14:27:53 +0100514 mService.setLockCredential(primaryPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
515 PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
516 mService.setLockCredential(profilePassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
517 PASSWORD_QUALITY_ALPHABETIC, MANAGED_PROFILE_USER_ID);
518 assertNotNull(mService.getHashFactor(profilePassword, MANAGED_PROFILE_USER_ID));
519 }
520
Adrian Roos7374d3a2017-03-31 14:14:53 -0700521 public void testPasswordData_serializeDeserialize() {
522 PasswordData data = new PasswordData();
523 data.scryptN = 11;
524 data.scryptR = 22;
525 data.scryptP = 33;
526 data.passwordType = CREDENTIAL_TYPE_PASSWORD;
527 data.salt = PAYLOAD;
528 data.passwordHandle = PAYLOAD2;
529
530 PasswordData deserialized = PasswordData.fromBytes(data.toBytes());
531
532 assertEquals(11, deserialized.scryptN);
533 assertEquals(22, deserialized.scryptR);
534 assertEquals(33, deserialized.scryptP);
535 assertEquals(CREDENTIAL_TYPE_PASSWORD, deserialized.passwordType);
536 assertArrayEquals(PAYLOAD, deserialized.salt);
537 assertArrayEquals(PAYLOAD2, deserialized.passwordHandle);
538 }
539
540 public void testPasswordData_deserialize() {
541 // Test that we can deserialize existing PasswordData and don't inadvertently change the
542 // wire format.
543 byte[] serialized = new byte[] {
544 0, 0, 0, 2, /* CREDENTIAL_TYPE_PASSWORD */
545 11, /* scryptN */
546 22, /* scryptR */
547 33, /* scryptP */
548 0, 0, 0, 5, /* salt.length */
549 1, 2, -1, -2, 55, /* salt */
550 0, 0, 0, 6, /* passwordHandle.length */
551 2, 3, -2, -3, 44, 1, /* passwordHandle */
552 };
553 PasswordData deserialized = PasswordData.fromBytes(serialized);
554
555 assertEquals(11, deserialized.scryptN);
556 assertEquals(22, deserialized.scryptR);
557 assertEquals(33, deserialized.scryptP);
558 assertEquals(CREDENTIAL_TYPE_PASSWORD, deserialized.passwordType);
559 assertArrayEquals(PAYLOAD, deserialized.salt);
560 assertArrayEquals(PAYLOAD2, deserialized.passwordHandle);
561 }
562
David Anderson6ebc25b2019-02-12 16:25:56 -0800563 public void testGsiDisablesAuthSecret() throws RemoteException {
564 mGsiService.setIsGsiRunning(true);
565
Rich Canningsf64ec632019-02-21 12:40:36 -0800566 final byte[] password = "testGsiDisablesAuthSecret-password".getBytes();
David Anderson6ebc25b2019-02-12 16:25:56 -0800567
568 initializeCredentialUnderSP(password, PRIMARY_USER_ID);
569 assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(
570 password, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID)
571 .getResponseCode());
572 verify(mAuthSecretService, never()).primaryUserCredential(any(ArrayList.class));
573 }
574
Andrew Scull7f4ff4c2018-01-05 18:33:58 +0000575 // b/62213311
Rubin Xu3bf722a2016-12-15 16:07:38 +0000576 //TODO: add non-migration work profile case, and unify/un-unify transition.
577 //TODO: test token after user resets password
578 //TODO: test token based reset after unified work challenge
579 //TODO: test clear password after unified work challenge
580}