MockSyntheticPasswordManager.java revision 7374d3a4bca6bfbf7da1ef5dbf0db9f35f0c8315
19439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly/* 28949bfb90c415629dbd0e30d25003fb3e0375fb5Hemant Gupta * Copyright (C) 2017 The Android Open Source Project 39439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * 49439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Licensed under the Apache License, Version 2.0 (the "License"); 59439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * you may not use this file except in compliance with the License. 69439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * You may obtain a copy of the License at 79439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * 89439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * http://www.apache.org/licenses/LICENSE-2.0 99439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * 109439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Unless required by applicable law or agreed to in writing, software 119439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * distributed under the License is distributed on an "AS IS" BASIS, 129439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * See the License for the specific language governing permissions and 149439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * limitations under the License. 159439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 169439a7fe517b858bc5e5c654b459315e4722feb2Nick Pellypackage com.android.server.locksettings; 179439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 189439a7fe517b858bc5e5c654b459315e4722feb2Nick Pellyimport android.hardware.weaver.V1_0.IWeaver; 199439a7fe517b858bc5e5c654b459315e4722feb2Nick Pellyimport android.os.RemoteException; 209439a7fe517b858bc5e5c654b459315e4722feb2Nick Pellyimport android.os.UserManager; 219439a7fe517b858bc5e5c654b459315e4722feb2Nick Pellyimport android.util.ArrayMap; 229439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 239439a7fe517b858bc5e5c654b459315e4722feb2Nick Pellyimport junit.framework.AssertionFailedError; 249439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 259439a7fe517b858bc5e5c654b459315e4722feb2Nick Pellyimport java.nio.ByteBuffer; 269439a7fe517b858bc5e5c654b459315e4722feb2Nick Pellyimport java.security.NoSuchAlgorithmException; 279439a7fe517b858bc5e5c654b459315e4722feb2Nick Pellyimport java.security.spec.InvalidKeySpecException; 289439a7fe517b858bc5e5c654b459315e4722feb2Nick Pellyimport java.util.Arrays; 299439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 309439a7fe517b858bc5e5c654b459315e4722feb2Nick Pellyimport javax.crypto.SecretKeyFactory; 319439a7fe517b858bc5e5c654b459315e4722feb2Nick Pellyimport javax.crypto.spec.PBEKeySpec; 329439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 339439a7fe517b858bc5e5c654b459315e4722feb2Nick Pellypublic class MockSyntheticPasswordManager extends SyntheticPasswordManager { 349439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 359439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly private MockGateKeeperService mGateKeeper; 362e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly private IWeaver mWeaverService; 372e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly 382e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly public MockSyntheticPasswordManager(LockSettingsStorage storage, 3925f2c4cd953764008d04147a14d990c06a8154e5Oscar Montemayor MockGateKeeperService gatekeeper, UserManager userManager) { 409439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly super(storage, userManager); 419439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly mGateKeeper = gatekeeper; 429439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 43238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde 442e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly private ArrayMap<String, byte[]> mBlobs = new ArrayMap<>(); 459439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 469439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly @Override 479439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly protected byte[] decryptSPBlob(String blobKeyName, byte[] blob, byte[] applicationId) { 489439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (mBlobs.containsKey(blobKeyName) && !Arrays.equals(mBlobs.get(blobKeyName), blob)) { 4905ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun throw new AssertionFailedError("blobKeyName content is overwritten: " + blobKeyName); 5005ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun } 519439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly ByteBuffer buffer = ByteBuffer.allocate(blob.length); 529439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly buffer.put(blob, 0, blob.length); 539439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly buffer.flip(); 549439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly int len; 559439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly len = buffer.getInt(); 569439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly byte[] data = new byte[len]; 5705ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun buffer.get(data); 589439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly len = buffer.getInt(); 599439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly byte[] appId = new byte[len]; 609439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly buffer.get(appId); 619439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly long sid = buffer.getLong(); 629439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (!Arrays.equals(appId, applicationId)) { 639439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly throw new AssertionFailedError("Invalid application id"); 6405ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun } 659439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (sid != 0 && mGateKeeper.getAuthTokenForSid(sid) == null) { 669439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly throw new AssertionFailedError("No valid auth token"); 679439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 689439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return data; 699439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 709439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 719439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly @Override 7205ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun protected byte[] createSPBlob(String blobKeyName, byte[] data, byte[] applicationId, long sid) { 739439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly ByteBuffer buffer = ByteBuffer.allocate(Integer.BYTES + data.length + Integer.BYTES 749439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly + applicationId.length + Long.BYTES); 759439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly buffer.putInt(data.length); 769439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly buffer.put(data); 779439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly buffer.putInt(applicationId.length); 789439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly buffer.put(applicationId); 799439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly buffer.putLong(sid); 8005ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun byte[] result = buffer.array(); 8105ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun mBlobs.put(blobKeyName, result); 829439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return result; 839439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 849439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 859439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly @Override 869439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly protected void destroySPBlobKey(String keyAlias) { 879439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 8805ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun 8905ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun @Override 9005ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun protected long sidFromPasswordHandle(byte[] handle) { 919439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return new MockGateKeeperService.VerifyHandle(handle).sid; 929439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 939439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 949439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly @Override 959439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly protected byte[] scrypt(String password, byte[] salt, int N, int r, int p, int outLen) { 969439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly try { 9705ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 10, outLen * 8); 9805ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun SecretKeyFactory f = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); 999439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return f.generateSecret(spec).getEncoded(); 1009439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } catch (InvalidKeySpecException | NoSuchAlgorithmException e) { 1019439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly e.printStackTrace(); 1029439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return null; 1039439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 1049439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 10505ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun 1069439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly @Override 1079439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly protected IWeaver getWeaverService() throws RemoteException { 1089439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return mWeaverService; 1099439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 1109439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1119439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public void enableWeaver() { 1129439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly mWeaverService = new MockWeaverService(); 11305ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun initWeaverService(); 1149439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 1159439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1169439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly} 1179439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly