13e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom/*
23e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom * Copyright (C) 2011 The Android Open Source Project
33e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom *
43e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom * Licensed under the Apache License, Version 2.0 (the "License");
53e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom * you may not use this file except in compliance with the License.
63e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom * You may obtain a copy of the License at
73e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom *
83e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom *      http://www.apache.org/licenses/LICENSE-2.0
93e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom *
103e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom * Unless required by applicable law or agreed to in writing, software
113e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom * distributed under the License is distributed on an "AS IS" BASIS,
123e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom * See the License for the specific language governing permissions and
143e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom * limitations under the License.
153e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom */
163e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom
173e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrompackage com.android.keychain.tests.support;
183e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom
193e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstromimport android.app.Service;
203e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstromimport android.content.Intent;
213e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstromimport android.os.IBinder;
22fb2e18e112f9fb9f0620c0c0ff06377f52fe39a4Fred Quintanaimport android.os.RemoteException;
23fb2e18e112f9fb9f0620c0c0ff06377f52fe39a4Fred Quintanaimport android.security.KeyChain;
243e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstromimport android.security.KeyStore;
253e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstromimport android.util.Log;
263e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom
273e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrompublic class KeyChainServiceTestSupport extends Service {
28fb2e18e112f9fb9f0620c0c0ff06377f52fe39a4Fred Quintana    private static final String TAG = "KeyChainServiceTest";
293e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom
303e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom    private final KeyStore mKeyStore = KeyStore.getInstance();
313e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom
323e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom    private final IKeyChainServiceTestSupport.Stub mIKeyChainServiceTestSupport
333e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom            = new IKeyChainServiceTestSupport.Stub() {
343e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom        @Override public boolean keystoreReset() {
353e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom            Log.d(TAG, "keystoreReset");
363e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom            return mKeyStore.reset();
373e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom        }
38060d9e465ea8fff549bdad19c2b51b0cba5563c6Chad Brubaker        @Override public boolean keystoreSetPassword(String password) {
39060d9e465ea8fff549bdad19c2b51b0cba5563c6Chad Brubaker            Log.d(TAG, "keystoreSetPassword");
40060d9e465ea8fff549bdad19c2b51b0cba5563c6Chad Brubaker            return mKeyStore.onUserPasswordChanged(password);
413e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom        }
42e3b3390d3b1c96097c8e7cbd4c0eb51715677739Brian Carlstrom        @Override public boolean keystorePut(String key, byte[] value) {
433e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom            Log.d(TAG, "keystorePut");
442cac355dbc855bdf7c4e729c5c65f63679269a26Kenny Root            return mKeyStore.put(key, value, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED);
453e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom        }
466f1f03bcae70792bbd8bc0aecb90c7b9c43b76b5Kenny Root        @Override public boolean keystoreImportKey(String key, byte[] value) {
476f1f03bcae70792bbd8bc0aecb90c7b9c43b76b5Kenny Root            Log.d(TAG, "keystoreImport");
482cac355dbc855bdf7c4e729c5c65f63679269a26Kenny Root            return mKeyStore.importKey(key, value, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED);
496f1f03bcae70792bbd8bc0aecb90c7b9c43b76b5Kenny Root        }
50fb2e18e112f9fb9f0620c0c0ff06377f52fe39a4Fred Quintana
51fb2e18e112f9fb9f0620c0c0ff06377f52fe39a4Fred Quintana        @Override public void revokeAppPermission(final int uid, final String alias)
52fb2e18e112f9fb9f0620c0c0ff06377f52fe39a4Fred Quintana                throws RemoteException {
533e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom            Log.d(TAG, "revokeAppPermission");
54fb2e18e112f9fb9f0620c0c0ff06377f52fe39a4Fred Quintana            blockingSetGrantPermission(uid, alias, false);
553e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom        }
56fb2e18e112f9fb9f0620c0c0ff06377f52fe39a4Fred Quintana
57fb2e18e112f9fb9f0620c0c0ff06377f52fe39a4Fred Quintana        @Override public void grantAppPermission(final int uid, final String alias)
58fb2e18e112f9fb9f0620c0c0ff06377f52fe39a4Fred Quintana                throws RemoteException {
593e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom            Log.d(TAG, "grantAppPermission");
60fb2e18e112f9fb9f0620c0c0ff06377f52fe39a4Fred Quintana            blockingSetGrantPermission(uid, alias, true);
61fb2e18e112f9fb9f0620c0c0ff06377f52fe39a4Fred Quintana        }
62fb2e18e112f9fb9f0620c0c0ff06377f52fe39a4Fred Quintana
63fb2e18e112f9fb9f0620c0c0ff06377f52fe39a4Fred Quintana        /**
64fb2e18e112f9fb9f0620c0c0ff06377f52fe39a4Fred Quintana         * Binds to the KeyChainService and requests that permission for the sender to
65fb2e18e112f9fb9f0620c0c0ff06377f52fe39a4Fred Quintana         * access the specified alias is granted/revoked.
66fb2e18e112f9fb9f0620c0c0ff06377f52fe39a4Fred Quintana         * This method blocks so it must not be called from the UI thread.
67fb2e18e112f9fb9f0620c0c0ff06377f52fe39a4Fred Quintana         * @param senderUid
68fb2e18e112f9fb9f0620c0c0ff06377f52fe39a4Fred Quintana         * @param alias
69fb2e18e112f9fb9f0620c0c0ff06377f52fe39a4Fred Quintana         */
70fb2e18e112f9fb9f0620c0c0ff06377f52fe39a4Fred Quintana        private void blockingSetGrantPermission(int senderUid, String alias, boolean value)
71fb2e18e112f9fb9f0620c0c0ff06377f52fe39a4Fred Quintana                throws RemoteException {
72fb2e18e112f9fb9f0620c0c0ff06377f52fe39a4Fred Quintana            KeyChain.KeyChainConnection connection = null;
73fb2e18e112f9fb9f0620c0c0ff06377f52fe39a4Fred Quintana            try {
74fb2e18e112f9fb9f0620c0c0ff06377f52fe39a4Fred Quintana                connection = KeyChain.bind(KeyChainServiceTestSupport.this);
75fb2e18e112f9fb9f0620c0c0ff06377f52fe39a4Fred Quintana                connection.getService().setGrant(senderUid, alias, value);
76fb2e18e112f9fb9f0620c0c0ff06377f52fe39a4Fred Quintana            } catch (InterruptedException e) {
77fb2e18e112f9fb9f0620c0c0ff06377f52fe39a4Fred Quintana                // should never happen. if it does we will not grant the requested permission
78fb2e18e112f9fb9f0620c0c0ff06377f52fe39a4Fred Quintana                Log.e(TAG, "interrupted while granting access");
79fb2e18e112f9fb9f0620c0c0ff06377f52fe39a4Fred Quintana                Thread.currentThread().interrupt();
80fb2e18e112f9fb9f0620c0c0ff06377f52fe39a4Fred Quintana            } finally {
81fb2e18e112f9fb9f0620c0c0ff06377f52fe39a4Fred Quintana                if (connection != null) {
82fb2e18e112f9fb9f0620c0c0ff06377f52fe39a4Fred Quintana                    connection.close();
83fb2e18e112f9fb9f0620c0c0ff06377f52fe39a4Fred Quintana                }
84fb2e18e112f9fb9f0620c0c0ff06377f52fe39a4Fred Quintana            }
853e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom        }
863e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom    };
873e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom
883e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom    @Override public IBinder onBind(Intent intent) {
893e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom        if (IKeyChainServiceTestSupport.class.getName().equals(intent.getAction())) {
903e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom            return mIKeyChainServiceTestSupport;
913e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom        }
923e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom        return null;
933e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom    }
943e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom}
95