1b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu/* 2b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu * Copyright (C) 2017 The Android Open Source Project 3b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu * 4b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu * Licensed under the Apache License, Version 2.0 (the "License"); 5b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu * you may not use this file except in compliance with the License. 6b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu * You may obtain a copy of the License at 7b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu * 8b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu * http://www.apache.org/licenses/LICENSE-2.0 9b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu * 10b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu * Unless required by applicable law or agreed to in writing, software 11b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu * distributed under the License is distributed on an "AS IS" BASIS, 12b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu * See the License for the specific language governing permissions and 14b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu * limitations under the License 15b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu */ 16b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu 17b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xupackage com.android.server.locksettings; 18b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu 19b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xuimport android.os.IProgressListener; 20b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xuimport android.os.RemoteException; 21b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xuimport android.util.ArrayMap; 22b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xuimport android.util.Pair; 23b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu 24b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu 25b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xuimport junit.framework.AssertionFailedError; 26b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu 27b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xuimport java.util.ArrayList; 28b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xuimport java.util.Arrays; 29b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu 30b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xupublic class FakeStorageManager { 31b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu 32b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu private ArrayMap<Integer, ArrayList<Pair<byte[], byte[]>>> mAuth = new ArrayMap<>(); 33b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu private boolean mIgnoreBadUnlock; 34b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu 35b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu public void addUserKeyAuth(int userId, int serialNumber, byte[] token, byte[] secret) { 36b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu getUserAuth(userId).add(new Pair<>(token, secret)); 37b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu } 38b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu 39b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu public void fixateNewestUserKeyAuth(int userId) { 40b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu ArrayList<Pair<byte[], byte[]>> auths = mAuth.get(userId); 41b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu Pair<byte[], byte[]> latest = auths.get(auths.size() - 1); 42b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu auths.clear(); 43b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu auths.add(latest); 44b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu } 45b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu 46b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu private ArrayList<Pair<byte[], byte[]>> getUserAuth(int userId) { 47b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu if (!mAuth.containsKey(userId)) { 48b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu ArrayList<Pair<byte[], byte[]>> auths = new ArrayList<Pair<byte[], byte[]>>(); 49b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu auths.add(new Pair(null, null)); 50b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu mAuth.put(userId, auths); 51b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu } 52b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu return mAuth.get(userId); 53b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu } 54b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu 55b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu public byte[] getUserUnlockToken(int userId) { 56b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu ArrayList<Pair<byte[], byte[]>> auths = getUserAuth(userId); 57b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu if (auths.size() != 1) { 58b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu throw new AssertionFailedError("More than one secret exists"); 59b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu } 60b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu return auths.get(0).second; 61b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu } 62b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu 63b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu public void unlockUser(int userId, byte[] secret, IProgressListener listener) 64b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu throws RemoteException { 65b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu listener.onStarted(userId, null); 66b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu listener.onFinished(userId, null); 67b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu ArrayList<Pair<byte[], byte[]>> auths = getUserAuth(userId); 68b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu if (secret != null) { 69b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu if (auths.size() > 1) { 70b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu throw new AssertionFailedError("More than one secret exists"); 71b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu } 72b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu Pair<byte[], byte[]> auth = auths.get(0); 73b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu if ((!mIgnoreBadUnlock) && auth.second != null && !Arrays.equals(secret, auth.second)) { 74b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu throw new AssertionFailedError("Invalid secret to unlock user"); 75b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu } 76b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu } else { 77b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu if (auths != null && auths.size() > 0) { 78b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu throw new AssertionFailedError("Cannot unlock encrypted user with empty token"); 79b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu } 80b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu } 81b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu } 82b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu 83b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu public void setIgnoreBadUnlock(boolean ignore) { 84b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu mIgnoreBadUnlock = ignore; 85b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu } 86b31be1b157d9633d43e42b200a92c94e318a4e96Rubin Xu} 87