1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.keychain.tests.support;
18 
19 import android.app.Service;
20 import android.content.Intent;
21 import android.os.IBinder;
22 import android.os.RemoteException;
23 import android.security.KeyChain;
24 import android.security.KeyStore;
25 import android.util.Log;
26 
27 public class KeyChainServiceTestSupport extends Service {
28     private static final String TAG = "KeyChainServiceTest";
29 
30     private final KeyStore mKeyStore = KeyStore.getInstance();
31 
32     private final IKeyChainServiceTestSupport.Stub mIKeyChainServiceTestSupport
33             = new IKeyChainServiceTestSupport.Stub() {
34         @Override public boolean keystoreReset() {
35             Log.d(TAG, "keystoreReset");
36             return mKeyStore.reset();
37         }
38         @Override public boolean keystoreSetPassword(String password) {
39             Log.d(TAG, "keystoreSetPassword");
40             return mKeyStore.onUserPasswordChanged(password);
41         }
42         @Override public boolean keystorePut(String key, byte[] value) {
43             Log.d(TAG, "keystorePut");
44             return mKeyStore.put(key, value, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED);
45         }
46         @Override public boolean keystoreImportKey(String key, byte[] value) {
47             Log.d(TAG, "keystoreImport");
48             return mKeyStore.importKey(key, value, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED);
49         }
50 
51         @Override public void revokeAppPermission(final int uid, final String alias)
52                 throws RemoteException {
53             Log.d(TAG, "revokeAppPermission");
54             blockingSetGrantPermission(uid, alias, false);
55         }
56 
57         @Override public void grantAppPermission(final int uid, final String alias)
58                 throws RemoteException {
59             Log.d(TAG, "grantAppPermission");
60             blockingSetGrantPermission(uid, alias, true);
61         }
62 
63         /**
64          * Binds to the KeyChainService and requests that permission for the sender to
65          * access the specified alias is granted/revoked.
66          * This method blocks so it must not be called from the UI thread.
67          * @param senderUid
68          * @param alias
69          */
70         private void blockingSetGrantPermission(int senderUid, String alias, boolean value)
71                 throws RemoteException {
72             KeyChain.KeyChainConnection connection = null;
73             try {
74                 connection = KeyChain.bind(KeyChainServiceTestSupport.this);
75                 connection.getService().setGrant(senderUid, alias, value);
76             } catch (InterruptedException e) {
77                 // should never happen. if it does we will not grant the requested permission
78                 Log.e(TAG, "interrupted while granting access");
79                 Thread.currentThread().interrupt();
80             } finally {
81                 if (connection != null) {
82                     connection.close();
83                 }
84             }
85         }
86     };
87 
onBind(Intent intent)88     @Override public IBinder onBind(Intent intent) {
89         if (IKeyChainServiceTestSupport.class.getName().equals(intent.getAction())) {
90             return mIKeyChainServiceTestSupport;
91         }
92         return null;
93     }
94 }
95