IKeystoreService.cpp revision 07438c8d7256d3788dac323b4d0055f201e0bec9
1/*
2**
3** Copyright 2008, The Android Open Source Project
4**
5** Licensed under the Apache License, Version 2.0 (the "License");
6** you may not use this file except in compliance with the License.
7** You may obtain a copy of the License at
8**
9**     http://www.apache.org/licenses/LICENSE-2.0
10**
11** Unless required by applicable law or agreed to in writing, software
12** distributed under the License is distributed on an "AS IS" BASIS,
13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14** See the License for the specific language governing permissions and
15** limitations under the License.
16*/
17
18#include <stdint.h>
19#include <sys/types.h>
20
21#define LOG_TAG "KeystoreService"
22#include <utils/Log.h>
23
24#include <binder/Parcel.h>
25#include <binder/IPCThreadState.h>
26#include <binder/IServiceManager.h>
27
28#include <keystore/IKeystoreService.h>
29
30namespace android {
31
32class BpKeystoreService: public BpInterface<IKeystoreService>
33{
34public:
35    BpKeystoreService(const sp<IBinder>& impl)
36        : BpInterface<IKeystoreService>(impl)
37    {
38    }
39
40    // test ping
41    virtual int32_t test()
42    {
43        Parcel data, reply;
44        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
45        status_t status = remote()->transact(BnKeystoreService::TEST, data, &reply);
46        if (status != NO_ERROR) {
47            ALOGD("test() could not contact remote: %d\n", status);
48            return -1;
49        }
50        int32_t err = reply.readExceptionCode();
51        int32_t ret = reply.readInt32();
52        if (err < 0) {
53            ALOGD("test() caught exception %d\n", err);
54            return -1;
55        }
56        return ret;
57    }
58
59    virtual int32_t get(const String16& name, uint8_t** item, size_t* itemLength)
60    {
61        Parcel data, reply;
62        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
63        data.writeString16(name);
64        status_t status = remote()->transact(BnKeystoreService::GET, data, &reply);
65        if (status != NO_ERROR) {
66            ALOGD("get() could not contact remote: %d\n", status);
67            return -1;
68        }
69        int32_t err = reply.readExceptionCode();
70        ssize_t len = reply.readInt32();
71        if (len >= 0 && (size_t) len <= reply.dataAvail()) {
72            size_t ulen = (size_t) len;
73            const void* buf = reply.readInplace(ulen);
74            *item = (uint8_t*) malloc(ulen);
75            if (*item != NULL) {
76                memcpy(*item, buf, ulen);
77                *itemLength = ulen;
78            } else {
79                ALOGE("out of memory allocating output array in get");
80                *itemLength = 0;
81            }
82        } else {
83            *itemLength = 0;
84        }
85        if (err < 0) {
86            ALOGD("get() caught exception %d\n", err);
87            return -1;
88        }
89        return 0;
90    }
91
92    virtual int32_t insert(const String16& name, const uint8_t* item, size_t itemLength)
93    {
94        Parcel data, reply;
95        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
96        data.writeString16(name);
97        data.writeInt32(itemLength);
98        void* buf = data.writeInplace(itemLength);
99        memcpy(buf, item, itemLength);
100        status_t status = remote()->transact(BnKeystoreService::INSERT, data, &reply);
101        if (status != NO_ERROR) {
102            ALOGD("import() could not contact remote: %d\n", status);
103            return -1;
104        }
105        int32_t err = reply.readExceptionCode();
106        int32_t ret = reply.readInt32();
107        if (err < 0) {
108            ALOGD("import() caught exception %d\n", err);
109            return -1;
110        }
111        return ret;
112    }
113
114    virtual int32_t del(const String16& name)
115    {
116        Parcel data, reply;
117        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
118        data.writeString16(name);
119        status_t status = remote()->transact(BnKeystoreService::DEL, data, &reply);
120        if (status != NO_ERROR) {
121            ALOGD("del() could not contact remote: %d\n", status);
122            return -1;
123        }
124        int32_t err = reply.readExceptionCode();
125        int32_t ret = reply.readInt32();
126        if (err < 0) {
127            ALOGD("del() caught exception %d\n", err);
128            return -1;
129        }
130        return ret;
131    }
132
133    virtual int32_t exist(const String16& name)
134    {
135        Parcel data, reply;
136        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
137        data.writeString16(name);
138        status_t status = remote()->transact(BnKeystoreService::EXIST, data, &reply);
139        if (status != NO_ERROR) {
140            ALOGD("exist() could not contact remote: %d\n", status);
141            return -1;
142        }
143        int32_t err = reply.readExceptionCode();
144        int32_t ret = reply.readInt32();
145        if (err < 0) {
146            ALOGD("exist() caught exception %d\n", err);
147            return -1;
148        }
149        return ret;
150    }
151
152    virtual int32_t saw(const String16& name, Vector<String16>* matches)
153    {
154        Parcel data, reply;
155        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
156        data.writeString16(name);
157        status_t status = remote()->transact(BnKeystoreService::SAW, data, &reply);
158        if (status != NO_ERROR) {
159            ALOGD("saw() could not contact remote: %d\n", status);
160            return -1;
161        }
162        int32_t err = reply.readExceptionCode();
163        int32_t numMatches = reply.readInt32();
164        for (int32_t i = 0; i < numMatches; i++) {
165            matches->push(reply.readString16());
166        }
167        int32_t ret = reply.readInt32();
168        if (err < 0) {
169            ALOGD("saw() caught exception %d\n", err);
170            return -1;
171        }
172        return ret;
173    }
174
175    virtual int32_t reset()
176    {
177        Parcel data, reply;
178        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
179        status_t status = remote()->transact(BnKeystoreService::RESET, data, &reply);
180        if (status != NO_ERROR) {
181            ALOGD("reset() could not contact remote: %d\n", status);
182            return -1;
183        }
184        int32_t err = reply.readExceptionCode();
185        int32_t ret = reply.readInt32();
186        if (err < 0) {
187            ALOGD("reset() caught exception %d\n", err);
188            return -1;
189        }
190        return ret;
191    }
192
193    virtual int32_t password(const String16& password)
194    {
195        Parcel data, reply;
196        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
197        data.writeString16(password);
198        status_t status = remote()->transact(BnKeystoreService::PASSWORD, data, &reply);
199        if (status != NO_ERROR) {
200            ALOGD("password() could not contact remote: %d\n", status);
201            return -1;
202        }
203        int32_t err = reply.readExceptionCode();
204        int32_t ret = reply.readInt32();
205        if (err < 0) {
206            ALOGD("password() caught exception %d\n", err);
207            return -1;
208        }
209        return ret;
210    }
211
212    virtual int32_t lock()
213    {
214        Parcel data, reply;
215        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
216        status_t status = remote()->transact(BnKeystoreService::LOCK, data, &reply);
217        if (status != NO_ERROR) {
218            ALOGD("lock() could not contact remote: %d\n", status);
219            return -1;
220        }
221        int32_t err = reply.readExceptionCode();
222        int32_t ret = reply.readInt32();
223        if (err < 0) {
224            ALOGD("lock() caught exception %d\n", err);
225            return -1;
226        }
227        return ret;
228    }
229
230    virtual int32_t unlock(const String16& password)
231    {
232        Parcel data, reply;
233        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
234        data.writeString16(password);
235        status_t status = remote()->transact(BnKeystoreService::UNLOCK, data, &reply);
236        if (status != NO_ERROR) {
237            ALOGD("unlock() could not contact remote: %d\n", status);
238            return -1;
239        }
240        int32_t err = reply.readExceptionCode();
241        int32_t ret = reply.readInt32();
242        if (err < 0) {
243            ALOGD("unlock() caught exception %d\n", err);
244            return -1;
245        }
246        return ret;
247    }
248
249    virtual int32_t zero()
250    {
251        Parcel data, reply;
252        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
253        status_t status = remote()->transact(BnKeystoreService::ZERO, data, &reply);
254        if (status != NO_ERROR) {
255            ALOGD("zero() could not contact remote: %d\n", status);
256            return -1;
257        }
258        int32_t err = reply.readExceptionCode();
259        int32_t ret = reply.readInt32();
260        if (err < 0) {
261            ALOGD("zero() caught exception %d\n", err);
262            return -1;
263        }
264        return ret;
265    }
266
267    virtual int32_t generate(const String16& name)
268    {
269        Parcel data, reply;
270        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
271        data.writeString16(name);
272        status_t status = remote()->transact(BnKeystoreService::GENERATE, data, &reply);
273        if (status != NO_ERROR) {
274            ALOGD("generate() could not contact remote: %d\n", status);
275            return -1;
276        }
277        int32_t err = reply.readExceptionCode();
278        int32_t ret = reply.readInt32();
279        if (err < 0) {
280            ALOGD("generate() caught exception %d\n", err);
281            return -1;
282        }
283        return ret;
284    }
285
286    virtual int32_t import(const String16& name, const uint8_t* key, size_t keyLength)
287    {
288        Parcel data, reply;
289        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
290        data.writeString16(name);
291        data.writeInt32(keyLength);
292        void* buf = data.writeInplace(keyLength);
293        memcpy(buf, key, keyLength);
294        status_t status = remote()->transact(BnKeystoreService::IMPORT, data, &reply);
295        if (status != NO_ERROR) {
296            ALOGD("import() could not contact remote: %d\n", status);
297            return -1;
298        }
299        int32_t err = reply.readExceptionCode();
300        int32_t ret = reply.readInt32();
301        if (err < 0) {
302            ALOGD("import() caught exception %d\n", err);
303            return -1;
304        }
305        return ret;
306    }
307
308    virtual int32_t sign(const String16& name, const uint8_t* in, size_t inLength, uint8_t** out,
309            size_t* outLength)
310    {
311        Parcel data, reply;
312        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
313        data.writeString16(name);
314        data.writeInt32(inLength);
315        void* buf = data.writeInplace(inLength);
316        memcpy(buf, in, inLength);
317        status_t status = remote()->transact(BnKeystoreService::SIGN, data, &reply);
318        if (status != NO_ERROR) {
319            ALOGD("import() could not contact remote: %d\n", status);
320            return -1;
321        }
322        int32_t err = reply.readExceptionCode();
323        ssize_t len = reply.readInt32();
324        if (len >= 0 && (size_t) len <= reply.dataAvail()) {
325            size_t ulen = (size_t) len;
326            const void* outBuf = reply.readInplace(ulen);
327            *out = (uint8_t*) malloc(ulen);
328            if (*out != NULL) {
329                memcpy((void*) *out, outBuf, ulen);
330                *outLength = ulen;
331            } else {
332                ALOGE("out of memory allocating output array in sign");
333                *outLength = 0;
334            }
335        } else {
336            *outLength = 0;
337        }
338        if (err < 0) {
339            ALOGD("import() caught exception %d\n", err);
340            return -1;
341        }
342        return 0;
343    }
344
345    virtual int32_t verify(const String16& name, const uint8_t* in, size_t inLength,
346            const uint8_t* signature, size_t signatureLength)
347    {
348        Parcel data, reply;
349        void* buf;
350
351        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
352        data.writeString16(name);
353        data.writeInt32(inLength);
354        buf = data.writeInplace(inLength);
355        memcpy(buf, in, inLength);
356        data.writeInt32(signatureLength);
357        buf = data.writeInplace(signatureLength);
358        memcpy(buf, signature, signatureLength);
359        status_t status = remote()->transact(BnKeystoreService::VERIFY, data, &reply);
360        if (status != NO_ERROR) {
361            ALOGD("verify() could not contact remote: %d\n", status);
362            return -1;
363        }
364        int32_t err = reply.readExceptionCode();
365        int32_t ret = reply.readInt32();
366        if (err < 0) {
367            ALOGD("verify() caught exception %d\n", err);
368            return -1;
369        }
370        return ret;
371    }
372
373    virtual int32_t get_pubkey(const String16& name, uint8_t** pubkey, size_t* pubkeyLength)
374    {
375        Parcel data, reply;
376        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
377        data.writeString16(name);
378        status_t status = remote()->transact(BnKeystoreService::GET_PUBKEY, data, &reply);
379        if (status != NO_ERROR) {
380            ALOGD("get_pubkey() could not contact remote: %d\n", status);
381            return -1;
382        }
383        int32_t err = reply.readExceptionCode();
384        ssize_t len = reply.readInt32();
385        if (len >= 0 && (size_t) len <= reply.dataAvail()) {
386            size_t ulen = (size_t) len;
387            const void* buf = reply.readInplace(ulen);
388            *pubkey = (uint8_t*) malloc(ulen);
389            if (*pubkey != NULL) {
390                memcpy(*pubkey, buf, ulen);
391                *pubkeyLength = ulen;
392            } else {
393                ALOGE("out of memory allocating output array in get_pubkey");
394                *pubkeyLength = 0;
395            }
396        } else {
397            *pubkeyLength = 0;
398        }
399        if (err < 0) {
400            ALOGD("get_pubkey() caught exception %d\n", err);
401            return -1;
402        }
403        return 0;
404     }
405
406    virtual int32_t del_key(const String16& name)
407    {
408        Parcel data, reply;
409        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
410        data.writeString16(name);
411        status_t status = remote()->transact(BnKeystoreService::DEL_KEY, data, &reply);
412        if (status != NO_ERROR) {
413            ALOGD("del_key() could not contact remote: %d\n", status);
414            return -1;
415        }
416        int32_t err = reply.readExceptionCode();
417        int32_t ret = reply.readInt32();
418        if (err < 0) {
419            ALOGD("del_key() caught exception %d\n", err);
420            return -1;
421        }
422        return ret;
423    }
424
425    virtual int32_t grant(const String16& name, int32_t granteeUid)
426    {
427        Parcel data, reply;
428        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
429        data.writeString16(name);
430        data.writeInt32(granteeUid);
431        status_t status = remote()->transact(BnKeystoreService::GRANT, data, &reply);
432        if (status != NO_ERROR) {
433            ALOGD("grant() could not contact remote: %d\n", status);
434            return -1;
435        }
436        int32_t err = reply.readExceptionCode();
437        int32_t ret = reply.readInt32();
438        if (err < 0) {
439            ALOGD("grant() caught exception %d\n", err);
440            return -1;
441        }
442        return ret;
443    }
444
445    virtual int32_t ungrant(const String16& name, int32_t granteeUid)
446    {
447        Parcel data, reply;
448        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
449        data.writeString16(name);
450        data.writeInt32(granteeUid);
451        status_t status = remote()->transact(BnKeystoreService::UNGRANT, data, &reply);
452        if (status != NO_ERROR) {
453            ALOGD("ungrant() could not contact remote: %d\n", status);
454            return -1;
455        }
456        int32_t err = reply.readExceptionCode();
457        int32_t ret = reply.readInt32();
458        if (err < 0) {
459            ALOGD("ungrant() caught exception %d\n", err);
460            return -1;
461        }
462        return ret;
463    }
464
465    int64_t getmtime(const String16& name)
466    {
467        Parcel data, reply;
468        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
469        data.writeString16(name);
470        status_t status = remote()->transact(BnKeystoreService::GETMTIME, data, &reply);
471        if (status != NO_ERROR) {
472            ALOGD("getmtime() could not contact remote: %d\n", status);
473            return -1;
474        }
475        int32_t err = reply.readExceptionCode();
476        int64_t ret = reply.readInt64();
477        if (err < 0) {
478            ALOGD("getmtime() caught exception %d\n", err);
479            return -1;
480        }
481        return ret;
482    }
483};
484
485IMPLEMENT_META_INTERFACE(KeystoreService, "android.security.keystore");
486
487// ----------------------------------------------------------------------
488
489status_t BnKeystoreService::onTransact(
490    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
491{
492    switch(code) {
493        case TEST: {
494            CHECK_INTERFACE(IKeystoreService, data, reply);
495            int32_t ret = test();
496            reply->writeNoException();
497            reply->writeInt32(ret);
498            return NO_ERROR;
499        } break;
500        case GET: {
501            CHECK_INTERFACE(IKeystoreService, data, reply);
502            String16 name = data.readString16();
503            void* out = NULL;
504            size_t outSize = 0;
505            int32_t ret = get(name, (uint8_t**) &out, &outSize);
506            reply->writeNoException();
507            if (ret == 1) {
508                reply->writeInt32(outSize);
509                void* buf = reply->writeInplace(outSize);
510                memcpy(buf, out, outSize);
511                free(out);
512            } else {
513                reply->writeInt32(-1);
514            }
515            return NO_ERROR;
516        } break;
517        case INSERT: {
518            CHECK_INTERFACE(IKeystoreService, data, reply);
519            String16 name = data.readString16();
520            ssize_t inSize = data.readInt32();
521            const void* in;
522            if (inSize >= 0 && (size_t) inSize <= data.dataAvail()) {
523                in = data.readInplace(inSize);
524            } else {
525                in = NULL;
526                inSize = 0;
527            }
528            int32_t ret = insert(name, (const uint8_t*) in, (size_t) inSize);
529            reply->writeNoException();
530            reply->writeInt32(ret);
531            return NO_ERROR;
532        } break;
533        case DEL: {
534            CHECK_INTERFACE(IKeystoreService, data, reply);
535            String16 name = data.readString16();
536            int32_t ret = del(name);
537            reply->writeNoException();
538            reply->writeInt32(ret);
539            return NO_ERROR;
540        } break;
541        case EXIST: {
542            CHECK_INTERFACE(IKeystoreService, data, reply);
543            String16 name = data.readString16();
544            int32_t ret = exist(name);
545            reply->writeNoException();
546            reply->writeInt32(ret);
547            return NO_ERROR;
548        } break;
549        case SAW: {
550            CHECK_INTERFACE(IKeystoreService, data, reply);
551            String16 name = data.readString16();
552            Vector<String16> matches;
553            int32_t ret = saw(name, &matches);
554            reply->writeNoException();
555            reply->writeInt32(matches.size());
556            Vector<String16>::const_iterator it = matches.begin();
557            for (; it != matches.end(); ++it) {
558                reply->writeString16(*it);
559            }
560            reply->writeInt32(ret);
561            return NO_ERROR;
562        } break;
563        case RESET: {
564            CHECK_INTERFACE(IKeystoreService, data, reply);
565            int32_t ret = reset();
566            reply->writeNoException();
567            reply->writeInt32(ret);
568            return NO_ERROR;
569        } break;
570        case PASSWORD: {
571            CHECK_INTERFACE(IKeystoreService, data, reply);
572            String16 pass = data.readString16();
573            int32_t ret = password(pass);
574            reply->writeNoException();
575            reply->writeInt32(ret);
576            return NO_ERROR;
577        } break;
578        case LOCK: {
579            CHECK_INTERFACE(IKeystoreService, data, reply);
580            int32_t ret = lock();
581            reply->writeNoException();
582            reply->writeInt32(ret);
583            return NO_ERROR;
584        } break;
585        case UNLOCK: {
586            CHECK_INTERFACE(IKeystoreService, data, reply);
587            String16 pass = data.readString16();
588            int32_t ret = unlock(pass);
589            reply->writeNoException();
590            reply->writeInt32(ret);
591            return NO_ERROR;
592        } break;
593        case ZERO: {
594            CHECK_INTERFACE(IKeystoreService, data, reply);
595            int32_t ret = zero();
596            reply->writeNoException();
597            reply->writeInt32(ret);
598            return NO_ERROR;
599        } break;
600        case GENERATE: {
601            CHECK_INTERFACE(IKeystoreService, data, reply);
602            String16 name = data.readString16();
603            int32_t ret = generate(name);
604            reply->writeNoException();
605            reply->writeInt32(ret);
606            return NO_ERROR;
607        } break;
608        case IMPORT: {
609            CHECK_INTERFACE(IKeystoreService, data, reply);
610            String16 name = data.readString16();
611            ssize_t inSize = data.readInt32();
612            const void* in;
613            if (inSize >= 0 && (size_t) inSize <= data.dataAvail()) {
614                in = data.readInplace(inSize);
615            } else {
616                in = NULL;
617                inSize = 0;
618            }
619            int32_t ret = import(name, (const uint8_t*) in, (size_t) inSize);
620            reply->writeNoException();
621            reply->writeInt32(ret);
622            return NO_ERROR;
623        } break;
624        case SIGN: {
625            CHECK_INTERFACE(IKeystoreService, data, reply);
626            String16 name = data.readString16();
627            ssize_t inSize = data.readInt32();
628            const void* in;
629            if (inSize >= 0 && (size_t) inSize <= data.dataAvail()) {
630                in = data.readInplace(inSize);
631            } else {
632                in = NULL;
633                inSize = 0;
634            }
635            void* out = NULL;
636            size_t outSize = 0;
637            int32_t ret = sign(name, (const uint8_t*) in, (size_t) inSize, (uint8_t**) &out, &outSize);
638            reply->writeNoException();
639            reply->writeInt32(outSize);
640            void* buf = reply->writeInplace(outSize);
641            memcpy(buf, out, outSize);
642            free(out);
643            reply->writeInt32(ret);
644            return NO_ERROR;
645        } break;
646        case VERIFY: {
647            CHECK_INTERFACE(IKeystoreService, data, reply);
648            String16 name = data.readString16();
649            ssize_t inSize = data.readInt32();
650            const void* in;
651            if (inSize >= 0 && (size_t) inSize <= data.dataAvail()) {
652                in = data.readInplace(inSize);
653            } else {
654                in = NULL;
655                inSize = 0;
656            }
657            ssize_t sigSize = data.readInt32();
658            const void* sig;
659            if (sigSize >= 0 && (size_t) sigSize <= data.dataAvail()) {
660                sig = data.readInplace(sigSize);
661            } else {
662                sig = NULL;
663                sigSize = 0;
664            }
665            bool ret = verify(name, (const uint8_t*) in, (size_t) inSize, (const uint8_t*) sig,
666                    (size_t) sigSize);
667            reply->writeNoException();
668            reply->writeInt32(ret ? 1 : 0);
669            return NO_ERROR;
670        } break;
671        case GET_PUBKEY: {
672            CHECK_INTERFACE(IKeystoreService, data, reply);
673            String16 name = data.readString16();
674            void* out = NULL;
675            size_t outSize = 0;
676            int32_t ret = get_pubkey(name, (unsigned char**) &out, &outSize);
677            reply->writeNoException();
678            reply->writeInt32(outSize);
679            void* buf = reply->writeInplace(outSize);
680            memcpy(buf, out, outSize);
681            free(out);
682            reply->writeInt32(ret);
683            return NO_ERROR;
684        }
685        case DEL_KEY: {
686            CHECK_INTERFACE(IKeystoreService, data, reply);
687            String16 name = data.readString16();
688            int32_t ret = del_key(name);
689            reply->writeNoException();
690            reply->writeInt32(ret);
691            return NO_ERROR;
692        } break;
693        case GRANT: {
694            CHECK_INTERFACE(IKeystoreService, data, reply);
695            String16 name = data.readString16();
696            int32_t granteeUid = data.readInt32();
697            int32_t ret = grant(name, granteeUid);
698            reply->writeNoException();
699            reply->writeInt32(ret);
700            return NO_ERROR;
701        } break;
702        case UNGRANT: {
703            CHECK_INTERFACE(IKeystoreService, data, reply);
704            String16 name = data.readString16();
705            int32_t granteeUid = data.readInt32();
706            int32_t ret = ungrant(name, granteeUid);
707            reply->writeNoException();
708            reply->writeInt32(ret);
709            return NO_ERROR;
710        } break;
711        case GETMTIME: {
712            CHECK_INTERFACE(IKeystoreService, data, reply);
713            String16 name = data.readString16();
714            int64_t ret = getmtime(name);
715            reply->writeNoException();
716            reply->writeInt64(ret);
717            return NO_ERROR;
718        } break;
719        default:
720            return BBinder::onTransact(code, data, reply, flags);
721    }
722}
723
724// ----------------------------------------------------------------------------
725
726}; // namespace android
727