Merge "Added changes for storing PIN length in PasswordData" into udc-dev
This commit is contained in:
@@ -56,6 +56,7 @@ interface ILockSettings {
|
||||
VerifyCredentialResponse verifyGatekeeperPasswordHandle(long gatekeeperPasswordHandle, long challenge, int userId);
|
||||
void removeGatekeeperPasswordHandle(long gatekeeperPasswordHandle);
|
||||
int getCredentialType(int userId);
|
||||
int getPinLength(int userId);
|
||||
byte[] getHashFactor(in LockscreenCredential currentCredential, int userId);
|
||||
void setSeparateProfileChallengeEnabled(int userId, boolean enabled, in LockscreenCredential managedUserPassword);
|
||||
boolean getSeparateProfileChallengeEnabled(int userId);
|
||||
|
||||
@@ -117,9 +117,6 @@ public final class LockPatternChecker {
|
||||
@Override
|
||||
protected void onPostExecute(Boolean result) {
|
||||
callback.onChecked(result, mThrottleTimeout);
|
||||
if (LockPatternUtils.isAutoPinConfirmFeatureAvailable()) {
|
||||
utils.setPinLength(userId, credentialCopy.size());
|
||||
}
|
||||
credentialCopy.zeroize();
|
||||
}
|
||||
|
||||
|
||||
@@ -116,6 +116,12 @@ public class LockPatternUtils {
|
||||
public static final int CREDENTIAL_TYPE_PIN = 3;
|
||||
public static final int CREDENTIAL_TYPE_PASSWORD = 4;
|
||||
|
||||
// This is the value of pin length whenever pin length is not available
|
||||
public static final int PIN_LENGTH_UNAVAILABLE = -1;
|
||||
|
||||
// This is the minimum pin length at which auto confirmation is supported
|
||||
public static final int MIN_AUTO_PIN_REQUIREMENT_LENGTH = 6;
|
||||
|
||||
/**
|
||||
* Header used for the encryption and decryption of the device credential for
|
||||
* remote device lockscreen validation.
|
||||
@@ -177,8 +183,6 @@ public class LockPatternUtils {
|
||||
@Deprecated
|
||||
public final static String LOCKSCREEN_WIDGETS_ENABLED = "lockscreen.widgets_enabled";
|
||||
|
||||
public static final String PIN_LENGTH = "lockscreen.pin_length";
|
||||
|
||||
public final static String PASSWORD_HISTORY_KEY = "lockscreen.passwordhistory";
|
||||
|
||||
private static final String LOCK_SCREEN_OWNER_INFO = Settings.Secure.LOCK_SCREEN_OWNER_INFO;
|
||||
@@ -193,7 +197,7 @@ public class LockPatternUtils {
|
||||
private static final String KNOWN_TRUST_AGENTS = "lockscreen.knowntrustagents";
|
||||
private static final String IS_TRUST_USUALLY_MANAGED = "lockscreen.istrustusuallymanaged";
|
||||
|
||||
private static final String AUTO_PIN_CONFIRM = "lockscreen.auto_pin_confirm";
|
||||
public static final String AUTO_PIN_CONFIRM = "lockscreen.auto_pin_confirm";
|
||||
|
||||
public static final String CURRENT_LSKF_BASED_PROTECTOR_ID_KEY = "sp-handle";
|
||||
public static final String PASSWORD_HISTORY_DELIMITER = ",";
|
||||
@@ -603,24 +607,21 @@ public class LockPatternUtils {
|
||||
return getBoolean(PATTERN_EVER_CHOSEN_KEY, false, userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used for setting the length of the PIN set by a particular user.
|
||||
* @param userId user id of the user whose pin length we save
|
||||
* @param val value of length of pin
|
||||
*/
|
||||
public void setPinLength(int userId, long val) {
|
||||
setLong(PIN_LENGTH, val, userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the length of the PIN set by a particular user.
|
||||
* @param userId user id of the user whose pin length we have to return
|
||||
* @return the length of the pin set by user and -1 if nothing
|
||||
* @return
|
||||
* A. the length of the pin set by user if it is currently available
|
||||
* B. PIN_LENGTH_UNAVAILABLE if it is not available or if an exception occurs
|
||||
*/
|
||||
public long getPinLength(int userId) {
|
||||
return getLong(PIN_LENGTH, -1, userId);
|
||||
public int getPinLength(int userId) {
|
||||
try {
|
||||
return getLockSettings().getPinLength(userId);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Could not fetch PIN length " + e);
|
||||
return PIN_LENGTH_UNAVAILABLE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Records that the user has chosen a pattern at some time, even if the pattern is
|
||||
* currently cleared.
|
||||
|
||||
@@ -36,6 +36,7 @@ import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PASSW
|
||||
import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PIN;
|
||||
import static com.android.internal.widget.LockPatternUtils.CURRENT_LSKF_BASED_PROTECTOR_ID_KEY;
|
||||
import static com.android.internal.widget.LockPatternUtils.EscrowTokenStateChangeCallback;
|
||||
import static com.android.internal.widget.LockPatternUtils.PIN_LENGTH_UNAVAILABLE;
|
||||
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT;
|
||||
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_FOR_UNATTENDED_UPDATE;
|
||||
import static com.android.internal.widget.LockPatternUtils.USER_FRP;
|
||||
@@ -1202,6 +1203,31 @@ public class LockSettingsService extends ILockSettings.Stub {
|
||||
DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, userId);
|
||||
}
|
||||
|
||||
/*
|
||||
* Gets the PIN length for the given user if it is currently available.
|
||||
* Can only be invoked by process/activity that have the right permission.
|
||||
* Returns:
|
||||
* A. Actual PIN length if credential type PIN and auto confirm feature is enabled
|
||||
* for the user or user's PIN has been successfully verified since the device booted
|
||||
* B. PIN_LENGTH_UNAVAILABLE if pin length is not stored/available
|
||||
*/
|
||||
@Override
|
||||
public int getPinLength(int userId) {
|
||||
checkPasswordHavePermission();
|
||||
PasswordMetrics passwordMetrics = getUserPasswordMetrics(userId);
|
||||
if (passwordMetrics != null && passwordMetrics.credType == CREDENTIAL_TYPE_PIN) {
|
||||
return passwordMetrics.length;
|
||||
}
|
||||
synchronized (mSpManager) {
|
||||
final long protectorId = getCurrentLskfBasedProtectorId(userId);
|
||||
if (protectorId == SyntheticPasswordManager.NULL_PROTECTOR_ID) {
|
||||
// Only possible for new users during early boot (before onThirdPartyAppsStarted())
|
||||
return PIN_LENGTH_UNAVAILABLE;
|
||||
}
|
||||
return mSpManager.getPinLength(protectorId, userId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This API is cached; whenever the result would change,
|
||||
* {@link com.android.internal.widget.LockPatternUtils#invalidateCredentialTypeCache}
|
||||
@@ -1683,11 +1709,6 @@ public class LockSettingsService extends ILockSettings.Stub {
|
||||
if (newCredential.isPattern()) {
|
||||
setBoolean(LockPatternUtils.PATTERN_EVER_CHOSEN_KEY, true, userHandle);
|
||||
}
|
||||
if (LockPatternUtils.isAutoPinConfirmFeatureAvailable()) {
|
||||
if (newCredential.isPin()) {
|
||||
setLong(LockPatternUtils.PIN_LENGTH, newCredential.size(), userHandle);
|
||||
}
|
||||
}
|
||||
|
||||
updatePasswordHistory(newCredential, userHandle);
|
||||
mContext.getSystemService(TrustManager.class).reportEnabledTrustAgentsChanged(userHandle);
|
||||
@@ -2229,6 +2250,11 @@ public class LockSettingsService extends ILockSettings.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the PasswordMetrics for the current user
|
||||
* @param userHandle The id of the user for which we return the password metrics object
|
||||
* @return passwordmetrics for the user or null if not available
|
||||
*/
|
||||
@VisibleForTesting
|
||||
PasswordMetrics getUserPasswordMetrics(int userHandle) {
|
||||
if (!isUserSecure(userHandle)) {
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.android.server.locksettings;
|
||||
|
||||
import static com.android.internal.widget.LockPatternUtils.EscrowTokenStateChangeCallback;
|
||||
import static com.android.internal.widget.LockPatternUtils.PIN_LENGTH_UNAVAILABLE;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.NonNull;
|
||||
@@ -150,6 +151,9 @@ class SyntheticPasswordManager {
|
||||
// The security strength of the synthetic password, in bytes
|
||||
private static final int SYNTHETIC_PASSWORD_SECURITY_STRENGTH = 256 / 8;
|
||||
|
||||
public static final short PASSWORD_DATA_V1 = 1;
|
||||
public static final short PASSWORD_DATA_V2 = 2;
|
||||
|
||||
private static final int PASSWORD_SCRYPT_LOG_N = 11;
|
||||
private static final int PASSWORD_SCRYPT_LOG_R = 3;
|
||||
private static final int PASSWORD_SCRYPT_LOG_P = 1;
|
||||
@@ -351,13 +355,19 @@ class SyntheticPasswordManager {
|
||||
// When Weaver is unavailable, this is the Gatekeeper password handle that resulted from
|
||||
// enrolling the stretched LSKF.
|
||||
public byte[] passwordHandle;
|
||||
/**
|
||||
* Pin length field, only stored in version 2 of the password data and when auto confirm
|
||||
* flag is enabled, otherwise this field contains PIN_LENGTH_UNAVAILABLE
|
||||
*/
|
||||
public int pinLength;
|
||||
|
||||
public static PasswordData create(int credentialType) {
|
||||
public static PasswordData create(int credentialType, int pinLength) {
|
||||
PasswordData result = new PasswordData();
|
||||
result.scryptLogN = PASSWORD_SCRYPT_LOG_N;
|
||||
result.scryptLogR = PASSWORD_SCRYPT_LOG_R;
|
||||
result.scryptLogP = PASSWORD_SCRYPT_LOG_P;
|
||||
result.credentialType = credentialType;
|
||||
result.pinLength = pinLength;
|
||||
result.salt = SecureRandomUtils.randomBytes(PASSWORD_SALT_LENGTH);
|
||||
return result;
|
||||
}
|
||||
@@ -367,7 +377,22 @@ class SyntheticPasswordManager {
|
||||
ByteBuffer buffer = ByteBuffer.allocate(data.length);
|
||||
buffer.put(data, 0, data.length);
|
||||
buffer.flip();
|
||||
result.credentialType = buffer.getInt();
|
||||
|
||||
/*
|
||||
* Originally this file did not contain a version number. However, its first field was
|
||||
* 'credentialType' as an 'int'. Since 'credentialType' could only be in the range
|
||||
* [-1, 4] and this file uses big endian byte order, the first two bytes were redundant,
|
||||
* and when interpreted as a 'short' could only contain -1 or 0. Therefore, we've now
|
||||
* reclaimed these two bytes for a 'short' version number and shrunk 'credentialType'
|
||||
* to a 'short'.
|
||||
*/
|
||||
short version = buffer.getShort();
|
||||
if (version == ((short) 0) || version == (short) -1) {
|
||||
version = PASSWORD_DATA_V1;
|
||||
} else if (version != PASSWORD_DATA_V2) {
|
||||
throw new IllegalArgumentException("Unknown PasswordData version: " + version);
|
||||
}
|
||||
result.credentialType = buffer.getShort();
|
||||
result.scryptLogN = buffer.get();
|
||||
result.scryptLogR = buffer.get();
|
||||
result.scryptLogP = buffer.get();
|
||||
@@ -381,15 +406,24 @@ class SyntheticPasswordManager {
|
||||
} else {
|
||||
result.passwordHandle = null;
|
||||
}
|
||||
if (version == PASSWORD_DATA_V2) {
|
||||
result.pinLength = buffer.getInt();
|
||||
} else {
|
||||
result.pinLength = PIN_LENGTH_UNAVAILABLE;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public byte[] toBytes() {
|
||||
|
||||
ByteBuffer buffer = ByteBuffer.allocate(Integer.BYTES + 3 * Byte.BYTES
|
||||
ByteBuffer buffer = ByteBuffer.allocate(2 * Short.BYTES + 3 * Byte.BYTES
|
||||
+ Integer.BYTES + salt.length + Integer.BYTES +
|
||||
(passwordHandle != null ? passwordHandle.length : 0));
|
||||
buffer.putInt(credentialType);
|
||||
(passwordHandle != null ? passwordHandle.length : 0) + Integer.BYTES);
|
||||
if (credentialType < Short.MIN_VALUE || credentialType > Short.MAX_VALUE) {
|
||||
throw new IllegalArgumentException("Unknown credential type: " + credentialType);
|
||||
}
|
||||
buffer.putShort(PASSWORD_DATA_V2);
|
||||
buffer.putShort((short) credentialType);
|
||||
buffer.put(scryptLogN);
|
||||
buffer.put(scryptLogR);
|
||||
buffer.put(scryptLogP);
|
||||
@@ -401,6 +435,7 @@ class SyntheticPasswordManager {
|
||||
} else {
|
||||
buffer.putInt(0);
|
||||
}
|
||||
buffer.putInt(pinLength);
|
||||
return buffer.array();
|
||||
}
|
||||
}
|
||||
@@ -649,6 +684,14 @@ class SyntheticPasswordManager {
|
||||
}
|
||||
}
|
||||
|
||||
int getPinLength(long protectorId, int userId) {
|
||||
byte[] passwordData = loadState(PASSWORD_DATA_NAME, protectorId, userId);
|
||||
if (passwordData == null) {
|
||||
return LockPatternUtils.PIN_LENGTH_UNAVAILABLE;
|
||||
}
|
||||
return PasswordData.fromBytes(passwordData).pinLength;
|
||||
}
|
||||
|
||||
int getCredentialType(long protectorId, int userId) {
|
||||
byte[] passwordData = loadState(PASSWORD_DATA_NAME, protectorId, userId);
|
||||
if (passwordData == null) {
|
||||
@@ -857,8 +900,13 @@ class SyntheticPasswordManager {
|
||||
public long createLskfBasedProtector(IGateKeeperService gatekeeper,
|
||||
LockscreenCredential credential, SyntheticPassword sp, int userId) {
|
||||
long protectorId = generateProtectorId();
|
||||
int pinLength = PIN_LENGTH_UNAVAILABLE;
|
||||
if (LockPatternUtils.isAutoPinConfirmFeatureAvailable()) {
|
||||
pinLength = derivePinLength(credential, userId);
|
||||
}
|
||||
// There's no need to store password data about an empty LSKF.
|
||||
PasswordData pwd = credential.isNone() ? null : PasswordData.create(credential.getType());
|
||||
PasswordData pwd = credential.isNone() ? null :
|
||||
PasswordData.create(credential.getType(), pinLength);
|
||||
byte[] stretchedLskf = stretchLskf(credential, pwd);
|
||||
long sid = GateKeeper.INVALID_SECURE_USER_ID;
|
||||
final byte[] protectorSecret;
|
||||
@@ -930,6 +978,15 @@ class SyntheticPasswordManager {
|
||||
return protectorId;
|
||||
}
|
||||
|
||||
private int derivePinLength(LockscreenCredential credential, int userId) {
|
||||
if (!credential.isPin()
|
||||
|| !mStorage.getBoolean(LockPatternUtils.AUTO_PIN_CONFIRM, false, userId)
|
||||
|| credential.size() < LockPatternUtils.MIN_AUTO_PIN_REQUIREMENT_LENGTH) {
|
||||
return PIN_LENGTH_UNAVAILABLE;
|
||||
}
|
||||
return credential.size();
|
||||
}
|
||||
|
||||
public VerifyCredentialResponse verifyFrpCredential(IGateKeeperService gatekeeper,
|
||||
LockscreenCredential userCredential,
|
||||
ICheckCredentialProgressCallback progressCallback) {
|
||||
@@ -1285,11 +1342,20 @@ class SyntheticPasswordManager {
|
||||
|
||||
// Upgrade case: store the metrics if the device did not have stored metrics before, should
|
||||
// only happen once on old protectors.
|
||||
if (result.syntheticPassword != null && !credential.isNone() &&
|
||||
!hasPasswordMetrics(protectorId, userId)) {
|
||||
if (result.syntheticPassword != null && !credential.isNone()
|
||||
&& !hasPasswordMetrics(protectorId, userId)) {
|
||||
savePasswordMetrics(credential, result.syntheticPassword, protectorId, userId);
|
||||
syncState(userId); // Not strictly needed as the upgrade can be re-done, but be safe.
|
||||
}
|
||||
if (LockPatternUtils.isAutoPinConfirmFeatureAvailable()
|
||||
&& result.syntheticPassword != null && pwd != null) {
|
||||
int expectedPinLength = derivePinLength(credential, userId);
|
||||
if (pwd.pinLength != expectedPinLength) {
|
||||
pwd.pinLength = expectedPinLength;
|
||||
saveState(PASSWORD_DATA_NAME, pwd.toBytes(), protectorId, userId);
|
||||
syncState(userId);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ import static android.content.pm.UserInfo.FLAG_PRIMARY;
|
||||
import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_NONE;
|
||||
import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PASSWORD;
|
||||
import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PASSWORD_OR_PIN;
|
||||
import static com.android.internal.widget.LockPatternUtils.PIN_LENGTH_UNAVAILABLE;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
@@ -579,12 +580,13 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests {
|
||||
data.scryptLogN = 11;
|
||||
data.scryptLogR = 3;
|
||||
data.scryptLogP = 1;
|
||||
data.pinLength = 5;
|
||||
data.salt = "abcdefghijklmnop".getBytes();
|
||||
return data;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPasswordData_serializeDeserialize() {
|
||||
public void testPasswordDataLatestVersion_serializeDeserialize() {
|
||||
PasswordData data = new PasswordData();
|
||||
data.scryptLogN = 11;
|
||||
data.scryptLogR = 22;
|
||||
@@ -592,19 +594,97 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests {
|
||||
data.credentialType = CREDENTIAL_TYPE_PASSWORD;
|
||||
data.salt = PAYLOAD;
|
||||
data.passwordHandle = PAYLOAD2;
|
||||
data.pinLength = 5;
|
||||
|
||||
PasswordData deserialized = PasswordData.fromBytes(data.toBytes());
|
||||
|
||||
assertEquals(11, deserialized.scryptLogN);
|
||||
assertEquals(22, deserialized.scryptLogR);
|
||||
assertEquals(33, deserialized.scryptLogP);
|
||||
assertEquals(5, deserialized.pinLength);
|
||||
assertEquals(CREDENTIAL_TYPE_PASSWORD, deserialized.credentialType);
|
||||
assertArrayEquals(PAYLOAD, deserialized.salt);
|
||||
assertArrayEquals(PAYLOAD2, deserialized.passwordHandle);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPasswordData_deserialize() {
|
||||
public void testPasswordDataV2VersionCredentialTypePin_deserialize() {
|
||||
// Test that we can deserialize existing PasswordData and don't inadvertently change the
|
||||
// wire format.
|
||||
byte[] serialized = new byte[] {
|
||||
0, 2, 0, 2, /* CREDENTIAL_TYPE_PASSWORD_OR_PIN */
|
||||
11, /* scryptLogN */
|
||||
22, /* scryptLogR */
|
||||
33, /* scryptLogP */
|
||||
0, 0, 0, 5, /* salt.length */
|
||||
1, 2, -1, -2, 55, /* salt */
|
||||
0, 0, 0, 6, /* passwordHandle.length */
|
||||
2, 3, -2, -3, 44, 1, /* passwordHandle */
|
||||
0, 0, 0, 5, /* pinLength */
|
||||
};
|
||||
PasswordData deserialized = PasswordData.fromBytes(serialized);
|
||||
|
||||
assertEquals(11, deserialized.scryptLogN);
|
||||
assertEquals(22, deserialized.scryptLogR);
|
||||
assertEquals(33, deserialized.scryptLogP);
|
||||
assertEquals(5, deserialized.pinLength);
|
||||
assertEquals(CREDENTIAL_TYPE_PASSWORD_OR_PIN, deserialized.credentialType);
|
||||
assertArrayEquals(PAYLOAD, deserialized.salt);
|
||||
assertArrayEquals(PAYLOAD2, deserialized.passwordHandle);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPasswordDataV2VersionNegativePinLengthNoCredential_deserialize() {
|
||||
// Test that we can deserialize existing PasswordData and don't inadvertently change the
|
||||
// wire format.
|
||||
byte[] serialized = new byte[] {
|
||||
0, 2, -1, -1, /* CREDENTIAL_TYPE_NONE */
|
||||
11, /* scryptLogN */
|
||||
22, /* scryptLogR */
|
||||
33, /* scryptLogP */
|
||||
0, 0, 0, 5, /* salt.length */
|
||||
1, 2, -1, -2, 55, /* salt */
|
||||
0, 0, 0, 6, /* passwordHandle.length */
|
||||
2, 3, -2, -3, 44, 1, /* passwordHandle */
|
||||
-1, -1, -1, -2, /* pinLength */
|
||||
};
|
||||
PasswordData deserialized = PasswordData.fromBytes(serialized);
|
||||
|
||||
assertEquals(11, deserialized.scryptLogN);
|
||||
assertEquals(22, deserialized.scryptLogR);
|
||||
assertEquals(33, deserialized.scryptLogP);
|
||||
assertEquals(-2, deserialized.pinLength);
|
||||
assertEquals(CREDENTIAL_TYPE_NONE, deserialized.credentialType);
|
||||
assertArrayEquals(PAYLOAD, deserialized.salt);
|
||||
assertArrayEquals(PAYLOAD2, deserialized.passwordHandle);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPasswordDataV1VersionNoCredential_deserialize() {
|
||||
// Test that we can deserialize existing PasswordData and don't inadvertently change the
|
||||
// wire format.
|
||||
byte[] serialized = new byte[] {
|
||||
-1, -1, -1, -1, /* CREDENTIAL_TYPE_NONE */
|
||||
11, /* scryptLogN */
|
||||
22, /* scryptLogR */
|
||||
33, /* scryptLogP */
|
||||
0, 0, 0, 5, /* salt.length */
|
||||
1, 2, -1, -2, 55, /* salt */
|
||||
0, 0, 0, 6, /* passwordHandle.length */
|
||||
2, 3, -2, -3, 44, 1, /* passwordHandle */
|
||||
};
|
||||
PasswordData deserialized = PasswordData.fromBytes(serialized);
|
||||
|
||||
assertEquals(11, deserialized.scryptLogN);
|
||||
assertEquals(22, deserialized.scryptLogR);
|
||||
assertEquals(33, deserialized.scryptLogP);
|
||||
assertEquals(PIN_LENGTH_UNAVAILABLE, deserialized.pinLength);
|
||||
assertEquals(CREDENTIAL_TYPE_NONE, deserialized.credentialType);
|
||||
assertArrayEquals(PAYLOAD, deserialized.salt);
|
||||
assertArrayEquals(PAYLOAD2, deserialized.passwordHandle);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPasswordDataV1VersionCredentialTypePin_deserialize() {
|
||||
// Test that we can deserialize existing PasswordData and don't inadvertently change the
|
||||
// wire format.
|
||||
byte[] serialized = new byte[] {
|
||||
@@ -622,6 +702,7 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests {
|
||||
assertEquals(11, deserialized.scryptLogN);
|
||||
assertEquals(22, deserialized.scryptLogR);
|
||||
assertEquals(33, deserialized.scryptLogP);
|
||||
assertEquals(PIN_LENGTH_UNAVAILABLE, deserialized.pinLength);
|
||||
assertEquals(CREDENTIAL_TYPE_PASSWORD_OR_PIN, deserialized.credentialType);
|
||||
assertArrayEquals(PAYLOAD, deserialized.salt);
|
||||
assertArrayEquals(PAYLOAD2, deserialized.passwordHandle);
|
||||
|
||||
Reference in New Issue
Block a user