Loading services/core/java/com/android/server/locksettings/LockSettingsService.java +18 −9 Original line number Diff line number Diff line Loading @@ -420,7 +420,7 @@ public class LockSettingsService extends ILockSettings.Stub { try (LockscreenCredential unifiedProfilePassword = generateRandomProfilePassword()) { setLockCredentialInternal(unifiedProfilePassword, profileUserPassword, profileUserId, /* isLockTiedToParent= */ true); tieProfileLockToParent(profileUserId, unifiedProfilePassword); tieProfileLockToParent(profileUserId, parentId, unifiedProfilePassword); mManagedProfilePasswordCache.storePassword(profileUserId, unifiedProfilePassword); } } Loading Loading @@ -1887,34 +1887,43 @@ public class LockSettingsService extends ILockSettings.Stub { } @VisibleForTesting /** Note: this method is overridden in unit tests */ protected void tieProfileLockToParent(int userId, LockscreenCredential password) { if (DEBUG) Slog.v(TAG, "tieProfileLockToParent for user: " + userId); protected void tieProfileLockToParent(int profileUserId, int parentUserId, LockscreenCredential password) { if (DEBUG) Slog.v(TAG, "tieProfileLockToParent for user: " + profileUserId); final byte[] iv; final byte[] ciphertext; final long parentSid; try { parentSid = getGateKeeperService().getSecureUserId(parentUserId); } catch (RemoteException e) { throw new IllegalStateException("Failed to talk to GateKeeper service", e); } try { KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES); keyGenerator.init(new SecureRandom()); SecretKey secretKey = keyGenerator.generateKey(); try { mJavaKeyStore.setEntry( PROFILE_KEY_NAME_ENCRYPT + userId, PROFILE_KEY_NAME_ENCRYPT + profileUserId, new java.security.KeyStore.SecretKeyEntry(secretKey), new KeyProtection.Builder(KeyProperties.PURPOSE_ENCRYPT) .setBlockModes(KeyProperties.BLOCK_MODE_GCM) .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE) .build()); mJavaKeyStore.setEntry( PROFILE_KEY_NAME_DECRYPT + userId, PROFILE_KEY_NAME_DECRYPT + profileUserId, new java.security.KeyStore.SecretKeyEntry(secretKey), new KeyProtection.Builder(KeyProperties.PURPOSE_DECRYPT) .setBlockModes(KeyProperties.BLOCK_MODE_GCM) .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE) .setUserAuthenticationRequired(true) .setBoundToSpecificSecureUserId(parentSid) .setUserAuthenticationValidityDurationSeconds(30) .build()); // Key imported, obtain a reference to it. SecretKey keyStoreEncryptionKey = (SecretKey) mJavaKeyStore.getKey( PROFILE_KEY_NAME_ENCRYPT + userId, null); PROFILE_KEY_NAME_ENCRYPT + profileUserId, null); Cipher cipher = Cipher.getInstance( KeyProperties.KEY_ALGORITHM_AES + "/" + KeyProperties.BLOCK_MODE_GCM + "/" + KeyProperties.ENCRYPTION_PADDING_NONE); Loading @@ -1923,7 +1932,7 @@ public class LockSettingsService extends ILockSettings.Stub { iv = cipher.getIV(); } finally { // The original key can now be discarded. mJavaKeyStore.deleteEntry(PROFILE_KEY_NAME_ENCRYPT + userId); mJavaKeyStore.deleteEntry(PROFILE_KEY_NAME_ENCRYPT + profileUserId); } } catch (UnrecoverableKeyException | BadPaddingException | IllegalBlockSizeException | KeyStoreException Loading @@ -1933,7 +1942,7 @@ public class LockSettingsService extends ILockSettings.Stub { if (iv.length != PROFILE_KEY_IV_SIZE) { throw new IllegalArgumentException("Invalid iv length: " + iv.length); } mStorage.writeChildProfileLock(userId, ArrayUtils.concat(iv, ciphertext)); mStorage.writeChildProfileLock(profileUserId, ArrayUtils.concat(iv, ciphertext)); } private void setUserKeyProtection(@UserIdInt int userId, byte[] secret) { Loading Loading @@ -2045,7 +2054,7 @@ public class LockSettingsService extends ILockSettings.Stub { LockscreenCredential piUserDecryptedPassword = profileUserDecryptedPasswords.get(i); if (piUserId != -1 && piUserDecryptedPassword != null) { if (DEBUG) Slog.v(TAG, "Restore tied profile lock"); tieProfileLockToParent(piUserId, piUserDecryptedPassword); tieProfileLockToParent(piUserId, userId, piUserDecryptedPassword); } if (piUserDecryptedPassword != null) { piUserDecryptedPassword.zeroize(); Loading services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java +3 −2 Original line number Diff line number Diff line Loading @@ -165,10 +165,11 @@ public class LockSettingsServiceTestable extends LockSettingsService { } @Override protected void tieProfileLockToParent(int userId, LockscreenCredential password) { protected void tieProfileLockToParent(int profileUserId, int parentUserId, LockscreenCredential password) { Parcel parcel = Parcel.obtain(); parcel.writeParcelable(password, 0); mStorage.writeChildProfileLock(userId, parcel.marshall()); mStorage.writeChildProfileLock(profileUserId, parcel.marshall()); parcel.recycle(); } Loading Loading
services/core/java/com/android/server/locksettings/LockSettingsService.java +18 −9 Original line number Diff line number Diff line Loading @@ -420,7 +420,7 @@ public class LockSettingsService extends ILockSettings.Stub { try (LockscreenCredential unifiedProfilePassword = generateRandomProfilePassword()) { setLockCredentialInternal(unifiedProfilePassword, profileUserPassword, profileUserId, /* isLockTiedToParent= */ true); tieProfileLockToParent(profileUserId, unifiedProfilePassword); tieProfileLockToParent(profileUserId, parentId, unifiedProfilePassword); mManagedProfilePasswordCache.storePassword(profileUserId, unifiedProfilePassword); } } Loading Loading @@ -1887,34 +1887,43 @@ public class LockSettingsService extends ILockSettings.Stub { } @VisibleForTesting /** Note: this method is overridden in unit tests */ protected void tieProfileLockToParent(int userId, LockscreenCredential password) { if (DEBUG) Slog.v(TAG, "tieProfileLockToParent for user: " + userId); protected void tieProfileLockToParent(int profileUserId, int parentUserId, LockscreenCredential password) { if (DEBUG) Slog.v(TAG, "tieProfileLockToParent for user: " + profileUserId); final byte[] iv; final byte[] ciphertext; final long parentSid; try { parentSid = getGateKeeperService().getSecureUserId(parentUserId); } catch (RemoteException e) { throw new IllegalStateException("Failed to talk to GateKeeper service", e); } try { KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES); keyGenerator.init(new SecureRandom()); SecretKey secretKey = keyGenerator.generateKey(); try { mJavaKeyStore.setEntry( PROFILE_KEY_NAME_ENCRYPT + userId, PROFILE_KEY_NAME_ENCRYPT + profileUserId, new java.security.KeyStore.SecretKeyEntry(secretKey), new KeyProtection.Builder(KeyProperties.PURPOSE_ENCRYPT) .setBlockModes(KeyProperties.BLOCK_MODE_GCM) .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE) .build()); mJavaKeyStore.setEntry( PROFILE_KEY_NAME_DECRYPT + userId, PROFILE_KEY_NAME_DECRYPT + profileUserId, new java.security.KeyStore.SecretKeyEntry(secretKey), new KeyProtection.Builder(KeyProperties.PURPOSE_DECRYPT) .setBlockModes(KeyProperties.BLOCK_MODE_GCM) .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE) .setUserAuthenticationRequired(true) .setBoundToSpecificSecureUserId(parentSid) .setUserAuthenticationValidityDurationSeconds(30) .build()); // Key imported, obtain a reference to it. SecretKey keyStoreEncryptionKey = (SecretKey) mJavaKeyStore.getKey( PROFILE_KEY_NAME_ENCRYPT + userId, null); PROFILE_KEY_NAME_ENCRYPT + profileUserId, null); Cipher cipher = Cipher.getInstance( KeyProperties.KEY_ALGORITHM_AES + "/" + KeyProperties.BLOCK_MODE_GCM + "/" + KeyProperties.ENCRYPTION_PADDING_NONE); Loading @@ -1923,7 +1932,7 @@ public class LockSettingsService extends ILockSettings.Stub { iv = cipher.getIV(); } finally { // The original key can now be discarded. mJavaKeyStore.deleteEntry(PROFILE_KEY_NAME_ENCRYPT + userId); mJavaKeyStore.deleteEntry(PROFILE_KEY_NAME_ENCRYPT + profileUserId); } } catch (UnrecoverableKeyException | BadPaddingException | IllegalBlockSizeException | KeyStoreException Loading @@ -1933,7 +1942,7 @@ public class LockSettingsService extends ILockSettings.Stub { if (iv.length != PROFILE_KEY_IV_SIZE) { throw new IllegalArgumentException("Invalid iv length: " + iv.length); } mStorage.writeChildProfileLock(userId, ArrayUtils.concat(iv, ciphertext)); mStorage.writeChildProfileLock(profileUserId, ArrayUtils.concat(iv, ciphertext)); } private void setUserKeyProtection(@UserIdInt int userId, byte[] secret) { Loading Loading @@ -2045,7 +2054,7 @@ public class LockSettingsService extends ILockSettings.Stub { LockscreenCredential piUserDecryptedPassword = profileUserDecryptedPasswords.get(i); if (piUserId != -1 && piUserDecryptedPassword != null) { if (DEBUG) Slog.v(TAG, "Restore tied profile lock"); tieProfileLockToParent(piUserId, piUserDecryptedPassword); tieProfileLockToParent(piUserId, userId, piUserDecryptedPassword); } if (piUserDecryptedPassword != null) { piUserDecryptedPassword.zeroize(); Loading
services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java +3 −2 Original line number Diff line number Diff line Loading @@ -165,10 +165,11 @@ public class LockSettingsServiceTestable extends LockSettingsService { } @Override protected void tieProfileLockToParent(int userId, LockscreenCredential password) { protected void tieProfileLockToParent(int profileUserId, int parentUserId, LockscreenCredential password) { Parcel parcel = Parcel.obtain(); parcel.writeParcelable(password, 0); mStorage.writeChildProfileLock(userId, parcel.marshall()); mStorage.writeChildProfileLock(profileUserId, parcel.marshall()); parcel.recycle(); } Loading