/* * Copyright 2011 yingxinwu.g@gmail.com * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package xink.vpn.wrapper; import java.lang.reflect.Method; import xink.vpn.AppException; import android.app.Activity; import android.content.ActivityNotFoundException; import android.content.Context; import android.content.Intent; import android.util.Log; public class KeyStore extends AbstractWrapper { public static final String UNLOCK_ACTION = "android.credentials.UNLOCK"; private static final int NO_ERROR = 1; /* private static final int LOCKED = 2; private static final int UNINITIALIZED = 3; private static final int SYSTEM_ERROR = 4; private static final int PROTOCOL_ERROR = 5; private static final int PERMISSION_DENIED = 6; private static final int KEY_NOT_FOUND = 7; private static final int VALUE_CORRUPTED = 8; private static final int UNDEFINED_ACTION = 9; private static final int WRONG_PASSWORD = 10; */ public KeyStore(final Context ctx) { super(ctx, "android.security.KeyStore", new StubInstanceCreator() { @Override protected Object newStubInstance(final Class<?> stubClass, final Context ctx) throws Exception { Method method = stubClass.getMethod("getInstance"); return method.invoke(null); } }); } public boolean put(final String key, final String value) { return this.<Boolean> invokeStubMethod("put", key, value); } public boolean contains(final VpnProfile p) { String key = L2tpIpsecPskProfile.KEY_PREFIX_IPSEC_PSK + p.getId(); return this.<Boolean> invokeStubMethod("contains", key); } public boolean delete(final String key) { return this.<Boolean> invokeStubMethod("delete", key); } public void unlock(final Activity ctx) { try { Intent intent = new Intent(UNLOCK_ACTION); ctx.startActivity(intent); } catch (ActivityNotFoundException e) { Log.e("xink", "unlock credentials failed", e); } } public boolean isUnlocked() { int err = this.<Integer> invokeStubMethod("test"); Log.d("xink", "KeyStore.test result is: " + err); return err == NO_ERROR; } /** * Check whether the keystore is hacked by xink. */ public boolean isHacked() { try { Method m = getStubClass().getDeclaredMethod("execute", int.class, byte[][].class); m.setAccessible(true); m.invoke(getStub(), 'x', new byte[0][]); } catch (Throwable e) { throw new AppException("verify failed", e); } int err = invokeStubMethod("getLastError"); Log.d("xink", "cmd 'x' result=" + err); return err == NO_ERROR; } }