13bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu/* 23bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu * Copyright (C) 2017 The Android Open Source Project 33bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu * 43bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu * Licensed under the Apache License, Version 2.0 (the "License"); 53bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu * you may not use this file except in compliance with the License. 63bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu * You may obtain a copy of the License at 73bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu * 83bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu * http://www.apache.org/licenses/LICENSE-2.0 93bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu * 103bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu * Unless required by applicable law or agreed to in writing, software 113bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu * distributed under the License is distributed on an "AS IS" BASIS, 123bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu * See the License for the specific language governing permissions and 143bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu * limitations under the License. 153bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu */ 163bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xupackage com.android.server; 173bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu 183bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xuimport android.util.ArrayMap; 193bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu 203bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xuimport junit.framework.AssertionFailedError; 213bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu 223bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xuimport java.nio.ByteBuffer; 233bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xuimport java.security.NoSuchAlgorithmException; 243bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xuimport java.security.spec.InvalidKeySpecException; 253bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xuimport java.util.Arrays; 263bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu 273bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xuimport javax.crypto.SecretKeyFactory; 283bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xuimport javax.crypto.spec.PBEKeySpec; 293bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu 303bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xupublic class MockSyntheticPasswordManager extends SyntheticPasswordManager { 313bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu 323bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu private MockGateKeeperService mGateKeeper; 333bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu 343bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu public MockSyntheticPasswordManager(LockSettingsStorage storage, 353bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu MockGateKeeperService gatekeeper) { 363bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu super(storage); 373bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu mGateKeeper = gatekeeper; 383bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu } 393bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu 403bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu private ArrayMap<String, byte[]> mBlobs = new ArrayMap<>(); 413bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu 423bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu @Override 433bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu protected byte[] decryptSPBlob(String blobKeyName, byte[] blob, byte[] applicationId) { 443bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu if (mBlobs.containsKey(blobKeyName) && !Arrays.equals(mBlobs.get(blobKeyName), blob)) { 453bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu throw new AssertionFailedError("blobKeyName content is overwritten: " + blobKeyName); 463bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu } 473bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu ByteBuffer buffer = ByteBuffer.allocate(blob.length); 483bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu buffer.put(blob, 0, blob.length); 493bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu buffer.flip(); 503bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu int len; 513bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu len = buffer.getInt(); 523bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu byte[] data = new byte[len]; 533bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu buffer.get(data); 543bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu len = buffer.getInt(); 553bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu byte[] appId = new byte[len]; 563bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu buffer.get(appId); 573bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu long sid = buffer.getLong(); 583bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu if (!Arrays.equals(appId, applicationId)) { 593bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu throw new AssertionFailedError("Invalid application id"); 603bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu } 613bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu if (sid != 0 && mGateKeeper.getAuthTokenForSid(sid) == null) { 623bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu throw new AssertionFailedError("No valid auth token"); 633bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu } 643bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu return data; 653bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu } 663bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu 673bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu @Override 683bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu protected byte[] createSPBlob(String blobKeyName, byte[] data, byte[] applicationId, long sid) { 693bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu ByteBuffer buffer = ByteBuffer.allocate(Integer.BYTES + data.length + Integer.BYTES 703bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu + applicationId.length + Long.BYTES); 713bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu buffer.putInt(data.length); 723bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu buffer.put(data); 733bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu buffer.putInt(applicationId.length); 743bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu buffer.put(applicationId); 753bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu buffer.putLong(sid); 763bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu byte[] result = buffer.array(); 773bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu mBlobs.put(blobKeyName, result); 783bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu return result; 793bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu } 803bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu 813bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu @Override 823bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu protected void destroySPBlobKey(String keyAlias) { 833bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu } 843bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu 853bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu @Override 863bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu protected long sidFromPasswordHandle(byte[] handle) { 873bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu return new MockGateKeeperService.VerifyHandle(handle).sid; 883bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu } 893bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu 903bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu @Override 913bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu protected byte[] scrypt(String password, byte[] salt, int N, int r, int p, int outLen) { 923bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu try { 933bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 10, outLen * 8); 943bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu SecretKeyFactory f = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); 953bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu return f.generateSecret(spec).getEncoded(); 963bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu } catch (InvalidKeySpecException | NoSuchAlgorithmException e) { 973bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu e.printStackTrace(); 983bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu return null; 993bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu } 1003bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu } 1013bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu 1023bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu} 103