Switch keystore to binder

Change-Id: I6dacdc43bcc1a56e47655e37e825ee6a205eb56b
diff --git a/keystore/IKeystoreService.cpp b/keystore/IKeystoreService.cpp
new file mode 100644
index 0000000..9b4590e
--- /dev/null
+++ b/keystore/IKeystoreService.cpp
@@ -0,0 +1,726 @@
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** 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.
+*/
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#define LOG_TAG "KeystoreService"
+#include <utils/Log.h>
+
+#include <binder/Parcel.h>
+#include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
+
+#include <keystore/IKeystoreService.h>
+
+namespace android {
+
+class BpKeystoreService: public BpInterface<IKeystoreService>
+{
+public:
+    BpKeystoreService(const sp<IBinder>& impl)
+        : BpInterface<IKeystoreService>(impl)
+    {
+    }
+
+    // test ping
+    virtual int32_t test()
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
+        status_t status = remote()->transact(BnKeystoreService::TEST, data, &reply);
+        if (status != NO_ERROR) {
+            ALOGD("test() could not contact remote: %d\n", status);
+            return -1;
+        }
+        int32_t err = reply.readExceptionCode();
+        int32_t ret = reply.readInt32();
+        if (err < 0) {
+            ALOGD("test() caught exception %d\n", err);
+            return -1;
+        }
+        return ret;
+    }
+
+    virtual int32_t get(const String16& name, uint8_t** item, size_t* itemLength)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
+        data.writeString16(name);
+        status_t status = remote()->transact(BnKeystoreService::GET, data, &reply);
+        if (status != NO_ERROR) {
+            ALOGD("get() could not contact remote: %d\n", status);
+            return -1;
+        }
+        int32_t err = reply.readExceptionCode();
+        ssize_t len = reply.readInt32();
+        if (len >= 0 && (size_t) len <= reply.dataAvail()) {
+            size_t ulen = (size_t) len;
+            const void* buf = reply.readInplace(ulen);
+            *item = (uint8_t*) malloc(ulen);
+            if (*item != NULL) {
+                memcpy(*item, buf, ulen);
+                *itemLength = ulen;
+            } else {
+                ALOGE("out of memory allocating output array in get");
+                *itemLength = 0;
+            }
+        } else {
+            *itemLength = 0;
+        }
+        if (err < 0) {
+            ALOGD("get() caught exception %d\n", err);
+            return -1;
+        }
+        return 0;
+    }
+
+    virtual int32_t insert(const String16& name, const uint8_t* item, size_t itemLength)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
+        data.writeString16(name);
+        data.writeInt32(itemLength);
+        void* buf = data.writeInplace(itemLength);
+        memcpy(buf, item, itemLength);
+        status_t status = remote()->transact(BnKeystoreService::INSERT, data, &reply);
+        if (status != NO_ERROR) {
+            ALOGD("import() could not contact remote: %d\n", status);
+            return -1;
+        }
+        int32_t err = reply.readExceptionCode();
+        int32_t ret = reply.readInt32();
+        if (err < 0) {
+            ALOGD("import() caught exception %d\n", err);
+            return -1;
+        }
+        return ret;
+    }
+
+    virtual int32_t del(const String16& name)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
+        data.writeString16(name);
+        status_t status = remote()->transact(BnKeystoreService::DEL, data, &reply);
+        if (status != NO_ERROR) {
+            ALOGD("del() could not contact remote: %d\n", status);
+            return -1;
+        }
+        int32_t err = reply.readExceptionCode();
+        int32_t ret = reply.readInt32();
+        if (err < 0) {
+            ALOGD("del() caught exception %d\n", err);
+            return -1;
+        }
+        return ret;
+    }
+
+    virtual int32_t exist(const String16& name)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
+        data.writeString16(name);
+        status_t status = remote()->transact(BnKeystoreService::EXIST, data, &reply);
+        if (status != NO_ERROR) {
+            ALOGD("exist() could not contact remote: %d\n", status);
+            return -1;
+        }
+        int32_t err = reply.readExceptionCode();
+        int32_t ret = reply.readInt32();
+        if (err < 0) {
+            ALOGD("exist() caught exception %d\n", err);
+            return -1;
+        }
+        return ret;
+    }
+
+    virtual int32_t saw(const String16& name, Vector<String16>* matches)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
+        data.writeString16(name);
+        status_t status = remote()->transact(BnKeystoreService::SAW, data, &reply);
+        if (status != NO_ERROR) {
+            ALOGD("saw() could not contact remote: %d\n", status);
+            return -1;
+        }
+        int32_t err = reply.readExceptionCode();
+        int32_t numMatches = reply.readInt32();
+        for (int32_t i = 0; i < numMatches; i++) {
+            matches->push(reply.readString16());
+        }
+        int32_t ret = reply.readInt32();
+        if (err < 0) {
+            ALOGD("saw() caught exception %d\n", err);
+            return -1;
+        }
+        return ret;
+    }
+
+    virtual int32_t reset()
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
+        status_t status = remote()->transact(BnKeystoreService::RESET, data, &reply);
+        if (status != NO_ERROR) {
+            ALOGD("reset() could not contact remote: %d\n", status);
+            return -1;
+        }
+        int32_t err = reply.readExceptionCode();
+        int32_t ret = reply.readInt32();
+        if (err < 0) {
+            ALOGD("reset() caught exception %d\n", err);
+            return -1;
+        }
+        return ret;
+    }
+
+    virtual int32_t password(const String16& password)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
+        data.writeString16(password);
+        status_t status = remote()->transact(BnKeystoreService::PASSWORD, data, &reply);
+        if (status != NO_ERROR) {
+            ALOGD("password() could not contact remote: %d\n", status);
+            return -1;
+        }
+        int32_t err = reply.readExceptionCode();
+        int32_t ret = reply.readInt32();
+        if (err < 0) {
+            ALOGD("password() caught exception %d\n", err);
+            return -1;
+        }
+        return ret;
+    }
+
+    virtual int32_t lock()
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
+        status_t status = remote()->transact(BnKeystoreService::LOCK, data, &reply);
+        if (status != NO_ERROR) {
+            ALOGD("lock() could not contact remote: %d\n", status);
+            return -1;
+        }
+        int32_t err = reply.readExceptionCode();
+        int32_t ret = reply.readInt32();
+        if (err < 0) {
+            ALOGD("lock() caught exception %d\n", err);
+            return -1;
+        }
+        return ret;
+    }
+
+    virtual int32_t unlock(const String16& password)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
+        data.writeString16(password);
+        status_t status = remote()->transact(BnKeystoreService::UNLOCK, data, &reply);
+        if (status != NO_ERROR) {
+            ALOGD("unlock() could not contact remote: %d\n", status);
+            return -1;
+        }
+        int32_t err = reply.readExceptionCode();
+        int32_t ret = reply.readInt32();
+        if (err < 0) {
+            ALOGD("unlock() caught exception %d\n", err);
+            return -1;
+        }
+        return ret;
+    }
+
+    virtual int32_t zero()
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
+        status_t status = remote()->transact(BnKeystoreService::ZERO, data, &reply);
+        if (status != NO_ERROR) {
+            ALOGD("zero() could not contact remote: %d\n", status);
+            return -1;
+        }
+        int32_t err = reply.readExceptionCode();
+        int32_t ret = reply.readInt32();
+        if (err < 0) {
+            ALOGD("zero() caught exception %d\n", err);
+            return -1;
+        }
+        return ret;
+    }
+
+    virtual int32_t generate(const String16& name)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
+        data.writeString16(name);
+        status_t status = remote()->transact(BnKeystoreService::GENERATE, data, &reply);
+        if (status != NO_ERROR) {
+            ALOGD("generate() could not contact remote: %d\n", status);
+            return -1;
+        }
+        int32_t err = reply.readExceptionCode();
+        int32_t ret = reply.readInt32();
+        if (err < 0) {
+            ALOGD("generate() caught exception %d\n", err);
+            return -1;
+        }
+        return ret;
+    }
+
+    virtual int32_t import(const String16& name, const uint8_t* key, size_t keyLength)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
+        data.writeString16(name);
+        data.writeInt32(keyLength);
+        void* buf = data.writeInplace(keyLength);
+        memcpy(buf, key, keyLength);
+        status_t status = remote()->transact(BnKeystoreService::IMPORT, data, &reply);
+        if (status != NO_ERROR) {
+            ALOGD("import() could not contact remote: %d\n", status);
+            return -1;
+        }
+        int32_t err = reply.readExceptionCode();
+        int32_t ret = reply.readInt32();
+        if (err < 0) {
+            ALOGD("import() caught exception %d\n", err);
+            return -1;
+        }
+        return ret;
+    }
+
+    virtual int32_t sign(const String16& name, const uint8_t* in, size_t inLength, uint8_t** out,
+            size_t* outLength)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
+        data.writeString16(name);
+        data.writeInt32(inLength);
+        void* buf = data.writeInplace(inLength);
+        memcpy(buf, in, inLength);
+        status_t status = remote()->transact(BnKeystoreService::SIGN, data, &reply);
+        if (status != NO_ERROR) {
+            ALOGD("import() could not contact remote: %d\n", status);
+            return -1;
+        }
+        int32_t err = reply.readExceptionCode();
+        ssize_t len = reply.readInt32();
+        if (len >= 0 && (size_t) len <= reply.dataAvail()) {
+            size_t ulen = (size_t) len;
+            const void* outBuf = reply.readInplace(ulen);
+            *out = (uint8_t*) malloc(ulen);
+            if (*out != NULL) {
+                memcpy((void*) *out, outBuf, ulen);
+                *outLength = ulen;
+            } else {
+                ALOGE("out of memory allocating output array in sign");
+                *outLength = 0;
+            }
+        } else {
+            *outLength = 0;
+        }
+        if (err < 0) {
+            ALOGD("import() caught exception %d\n", err);
+            return -1;
+        }
+        return 0;
+    }
+
+    virtual int32_t verify(const String16& name, const uint8_t* in, size_t inLength,
+            const uint8_t* signature, size_t signatureLength)
+    {
+        Parcel data, reply;
+        void* buf;
+
+        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
+        data.writeString16(name);
+        data.writeInt32(inLength);
+        buf = data.writeInplace(inLength);
+        memcpy(buf, in, inLength);
+        data.writeInt32(signatureLength);
+        buf = data.writeInplace(signatureLength);
+        memcpy(buf, signature, signatureLength);
+        status_t status = remote()->transact(BnKeystoreService::VERIFY, data, &reply);
+        if (status != NO_ERROR) {
+            ALOGD("verify() could not contact remote: %d\n", status);
+            return -1;
+        }
+        int32_t err = reply.readExceptionCode();
+        int32_t ret = reply.readInt32();
+        if (err < 0) {
+            ALOGD("verify() caught exception %d\n", err);
+            return -1;
+        }
+        return ret;
+    }
+
+    virtual int32_t get_pubkey(const String16& name, uint8_t** pubkey, size_t* pubkeyLength)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
+        data.writeString16(name);
+        status_t status = remote()->transact(BnKeystoreService::GET_PUBKEY, data, &reply);
+        if (status != NO_ERROR) {
+            ALOGD("get_pubkey() could not contact remote: %d\n", status);
+            return -1;
+        }
+        int32_t err = reply.readExceptionCode();
+        ssize_t len = reply.readInt32();
+        if (len >= 0 && (size_t) len <= reply.dataAvail()) {
+            size_t ulen = (size_t) len;
+            const void* buf = reply.readInplace(ulen);
+            *pubkey = (uint8_t*) malloc(ulen);
+            if (*pubkey != NULL) {
+                memcpy(*pubkey, buf, ulen);
+                *pubkeyLength = ulen;
+            } else {
+                ALOGE("out of memory allocating output array in get_pubkey");
+                *pubkeyLength = 0;
+            }
+        } else {
+            *pubkeyLength = 0;
+        }
+        if (err < 0) {
+            ALOGD("get_pubkey() caught exception %d\n", err);
+            return -1;
+        }
+        return 0;
+     }
+
+    virtual int32_t del_key(const String16& name)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
+        data.writeString16(name);
+        status_t status = remote()->transact(BnKeystoreService::DEL_KEY, data, &reply);
+        if (status != NO_ERROR) {
+            ALOGD("del_key() could not contact remote: %d\n", status);
+            return -1;
+        }
+        int32_t err = reply.readExceptionCode();
+        int32_t ret = reply.readInt32();
+        if (err < 0) {
+            ALOGD("del_key() caught exception %d\n", err);
+            return -1;
+        }
+        return ret;
+    }
+
+    virtual int32_t grant(const String16& name, int32_t granteeUid)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
+        data.writeString16(name);
+        data.writeInt32(granteeUid);
+        status_t status = remote()->transact(BnKeystoreService::GRANT, data, &reply);
+        if (status != NO_ERROR) {
+            ALOGD("grant() could not contact remote: %d\n", status);
+            return -1;
+        }
+        int32_t err = reply.readExceptionCode();
+        int32_t ret = reply.readInt32();
+        if (err < 0) {
+            ALOGD("grant() caught exception %d\n", err);
+            return -1;
+        }
+        return ret;
+    }
+
+    virtual int32_t ungrant(const String16& name, int32_t granteeUid)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
+        data.writeString16(name);
+        data.writeInt32(granteeUid);
+        status_t status = remote()->transact(BnKeystoreService::UNGRANT, data, &reply);
+        if (status != NO_ERROR) {
+            ALOGD("ungrant() could not contact remote: %d\n", status);
+            return -1;
+        }
+        int32_t err = reply.readExceptionCode();
+        int32_t ret = reply.readInt32();
+        if (err < 0) {
+            ALOGD("ungrant() caught exception %d\n", err);
+            return -1;
+        }
+        return ret;
+    }
+
+    int64_t getmtime(const String16& name)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
+        data.writeString16(name);
+        status_t status = remote()->transact(BnKeystoreService::GETMTIME, data, &reply);
+        if (status != NO_ERROR) {
+            ALOGD("getmtime() could not contact remote: %d\n", status);
+            return -1;
+        }
+        int32_t err = reply.readExceptionCode();
+        int64_t ret = reply.readInt64();
+        if (err < 0) {
+            ALOGD("getmtime() caught exception %d\n", err);
+            return -1;
+        }
+        return ret;
+    }
+};
+
+IMPLEMENT_META_INTERFACE(KeystoreService, "android.security.keystore");
+
+// ----------------------------------------------------------------------
+
+status_t BnKeystoreService::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    switch(code) {
+        case TEST: {
+            CHECK_INTERFACE(IKeystoreService, data, reply);
+            int32_t ret = test();
+            reply->writeNoException();
+            reply->writeInt32(ret);
+            return NO_ERROR;
+        } break;
+        case GET: {
+            CHECK_INTERFACE(IKeystoreService, data, reply);
+            String16 name = data.readString16();
+            void* out = NULL;
+            size_t outSize = 0;
+            int32_t ret = get(name, (uint8_t**) &out, &outSize);
+            reply->writeNoException();
+            if (ret == 1) {
+                reply->writeInt32(outSize);
+                void* buf = reply->writeInplace(outSize);
+                memcpy(buf, out, outSize);
+                free(out);
+            } else {
+                reply->writeInt32(-1);
+            }
+            return NO_ERROR;
+        } break;
+        case INSERT: {
+            CHECK_INTERFACE(IKeystoreService, data, reply);
+            String16 name = data.readString16();
+            ssize_t inSize = data.readInt32();
+            const void* in;
+            if (inSize >= 0 && (size_t) inSize <= data.dataAvail()) {
+                in = data.readInplace(inSize);
+            } else {
+                in = NULL;
+                inSize = 0;
+            }
+            int32_t ret = insert(name, (const uint8_t*) in, (size_t) inSize);
+            reply->writeNoException();
+            reply->writeInt32(ret);
+            return NO_ERROR;
+        } break;
+        case DEL: {
+            CHECK_INTERFACE(IKeystoreService, data, reply);
+            String16 name = data.readString16();
+            int32_t ret = del(name);
+            reply->writeNoException();
+            reply->writeInt32(ret);
+            return NO_ERROR;
+        } break;
+        case EXIST: {
+            CHECK_INTERFACE(IKeystoreService, data, reply);
+            String16 name = data.readString16();
+            int32_t ret = exist(name);
+            reply->writeNoException();
+            reply->writeInt32(ret);
+            return NO_ERROR;
+        } break;
+        case SAW: {
+            CHECK_INTERFACE(IKeystoreService, data, reply);
+            String16 name = data.readString16();
+            Vector<String16> matches;
+            int32_t ret = saw(name, &matches);
+            reply->writeNoException();
+            reply->writeInt32(matches.size());
+            Vector<String16>::const_iterator it = matches.begin();
+            for (; it != matches.end(); ++it) {
+                reply->writeString16(*it);
+            }
+            reply->writeInt32(ret);
+            return NO_ERROR;
+        } break;
+        case RESET: {
+            CHECK_INTERFACE(IKeystoreService, data, reply);
+            int32_t ret = reset();
+            reply->writeNoException();
+            reply->writeInt32(ret);
+            return NO_ERROR;
+        } break;
+        case PASSWORD: {
+            CHECK_INTERFACE(IKeystoreService, data, reply);
+            String16 pass = data.readString16();
+            int32_t ret = password(pass);
+            reply->writeNoException();
+            reply->writeInt32(ret);
+            return NO_ERROR;
+        } break;
+        case LOCK: {
+            CHECK_INTERFACE(IKeystoreService, data, reply);
+            int32_t ret = lock();
+            reply->writeNoException();
+            reply->writeInt32(ret);
+            return NO_ERROR;
+        } break;
+        case UNLOCK: {
+            CHECK_INTERFACE(IKeystoreService, data, reply);
+            String16 pass = data.readString16();
+            int32_t ret = unlock(pass);
+            reply->writeNoException();
+            reply->writeInt32(ret);
+            return NO_ERROR;
+        } break;
+        case ZERO: {
+            CHECK_INTERFACE(IKeystoreService, data, reply);
+            int32_t ret = zero();
+            reply->writeNoException();
+            reply->writeInt32(ret);
+            return NO_ERROR;
+        } break;
+        case GENERATE: {
+            CHECK_INTERFACE(IKeystoreService, data, reply);
+            String16 name = data.readString16();
+            int32_t ret = generate(name);
+            reply->writeNoException();
+            reply->writeInt32(ret);
+            return NO_ERROR;
+        } break;
+        case IMPORT: {
+            CHECK_INTERFACE(IKeystoreService, data, reply);
+            String16 name = data.readString16();
+            ssize_t inSize = data.readInt32();
+            const void* in;
+            if (inSize >= 0 && (size_t) inSize <= data.dataAvail()) {
+                in = data.readInplace(inSize);
+            } else {
+                in = NULL;
+                inSize = 0;
+            }
+            int32_t ret = import(name, (const uint8_t*) in, (size_t) inSize);
+            reply->writeNoException();
+            reply->writeInt32(ret);
+            return NO_ERROR;
+        } break;
+        case SIGN: {
+            CHECK_INTERFACE(IKeystoreService, data, reply);
+            String16 name = data.readString16();
+            ssize_t inSize = data.readInt32();
+            const void* in;
+            if (inSize >= 0 && (size_t) inSize <= data.dataAvail()) {
+                in = data.readInplace(inSize);
+            } else {
+                in = NULL;
+                inSize = 0;
+            }
+            void* out = NULL;
+            size_t outSize = 0;
+            int32_t ret = sign(name, (const uint8_t*) in, (size_t) inSize, (uint8_t**) &out, &outSize);
+            reply->writeNoException();
+            reply->writeInt32(outSize);
+            void* buf = reply->writeInplace(outSize);
+            memcpy(buf, out, outSize);
+            free(out);
+            reply->writeInt32(ret);
+            return NO_ERROR;
+        } break;
+        case VERIFY: {
+            CHECK_INTERFACE(IKeystoreService, data, reply);
+            String16 name = data.readString16();
+            ssize_t inSize = data.readInt32();
+            const void* in;
+            if (inSize >= 0 && (size_t) inSize <= data.dataAvail()) {
+                in = data.readInplace(inSize);
+            } else {
+                in = NULL;
+                inSize = 0;
+            }
+            ssize_t sigSize = data.readInt32();
+            const void* sig;
+            if (sigSize >= 0 && (size_t) sigSize <= data.dataAvail()) {
+                sig = data.readInplace(sigSize);
+            } else {
+                sig = NULL;
+                sigSize = 0;
+            }
+            bool ret = verify(name, (const uint8_t*) in, (size_t) inSize, (const uint8_t*) sig,
+                    (size_t) sigSize);
+            reply->writeNoException();
+            reply->writeInt32(ret ? 1 : 0);
+            return NO_ERROR;
+        } break;
+        case GET_PUBKEY: {
+            CHECK_INTERFACE(IKeystoreService, data, reply);
+            String16 name = data.readString16();
+            void* out = NULL;
+            size_t outSize = 0;
+            int32_t ret = get_pubkey(name, (unsigned char**) &out, &outSize);
+            reply->writeNoException();
+            reply->writeInt32(outSize);
+            void* buf = reply->writeInplace(outSize);
+            memcpy(buf, out, outSize);
+            free(out);
+            reply->writeInt32(ret);
+            return NO_ERROR;
+        }
+        case DEL_KEY: {
+            CHECK_INTERFACE(IKeystoreService, data, reply);
+            String16 name = data.readString16();
+            int32_t ret = del_key(name);
+            reply->writeNoException();
+            reply->writeInt32(ret);
+            return NO_ERROR;
+        } break;
+        case GRANT: {
+            CHECK_INTERFACE(IKeystoreService, data, reply);
+            String16 name = data.readString16();
+            int32_t granteeUid = data.readInt32();
+            int32_t ret = grant(name, granteeUid);
+            reply->writeNoException();
+            reply->writeInt32(ret);
+            return NO_ERROR;
+        } break;
+        case UNGRANT: {
+            CHECK_INTERFACE(IKeystoreService, data, reply);
+            String16 name = data.readString16();
+            int32_t granteeUid = data.readInt32();
+            int32_t ret = ungrant(name, granteeUid);
+            reply->writeNoException();
+            reply->writeInt32(ret);
+            return NO_ERROR;
+        } break;
+        case GETMTIME: {
+            CHECK_INTERFACE(IKeystoreService, data, reply);
+            String16 name = data.readString16();
+            int64_t ret = getmtime(name);
+            reply->writeNoException();
+            reply->writeInt64(ret);
+            return NO_ERROR;
+        } break;
+        default:
+            return BBinder::onTransact(code, data, reply, flags);
+    }
+}
+
+// ----------------------------------------------------------------------------
+
+}; // namespace android