IKeystoreService.cpp revision 0225407783ee339164a0cd8ca5ef04c99d27c59a
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, int uid)
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        data.writeInt32(uid);
101        status_t status = remote()->transact(BnKeystoreService::INSERT, data, &reply);
102        if (status != NO_ERROR) {
103            ALOGD("import() could not contact remote: %d\n", status);
104            return -1;
105        }
106        int32_t err = reply.readExceptionCode();
107        int32_t ret = reply.readInt32();
108        if (err < 0) {
109            ALOGD("import() caught exception %d\n", err);
110            return -1;
111        }
112        return ret;
113    }
114
115    virtual int32_t del(const String16& name, int uid)
116    {
117        Parcel data, reply;
118        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
119        data.writeString16(name);
120        data.writeInt32(uid);
121        status_t status = remote()->transact(BnKeystoreService::DEL, data, &reply);
122        if (status != NO_ERROR) {
123            ALOGD("del() could not contact remote: %d\n", status);
124            return -1;
125        }
126        int32_t err = reply.readExceptionCode();
127        int32_t ret = reply.readInt32();
128        if (err < 0) {
129            ALOGD("del() caught exception %d\n", err);
130            return -1;
131        }
132        return ret;
133    }
134
135    virtual int32_t exist(const String16& name, int uid)
136    {
137        Parcel data, reply;
138        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
139        data.writeString16(name);
140        data.writeInt32(uid);
141        status_t status = remote()->transact(BnKeystoreService::EXIST, data, &reply);
142        if (status != NO_ERROR) {
143            ALOGD("exist() could not contact remote: %d\n", status);
144            return -1;
145        }
146        int32_t err = reply.readExceptionCode();
147        int32_t ret = reply.readInt32();
148        if (err < 0) {
149            ALOGD("exist() caught exception %d\n", err);
150            return -1;
151        }
152        return ret;
153    }
154
155    virtual int32_t saw(const String16& name, int uid, Vector<String16>* matches)
156    {
157        Parcel data, reply;
158        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
159        data.writeString16(name);
160        data.writeInt32(uid);
161        status_t status = remote()->transact(BnKeystoreService::SAW, data, &reply);
162        if (status != NO_ERROR) {
163            ALOGD("saw() could not contact remote: %d\n", status);
164            return -1;
165        }
166        int32_t err = reply.readExceptionCode();
167        int32_t numMatches = reply.readInt32();
168        for (int32_t i = 0; i < numMatches; i++) {
169            matches->push(reply.readString16());
170        }
171        int32_t ret = reply.readInt32();
172        if (err < 0) {
173            ALOGD("saw() caught exception %d\n", err);
174            return -1;
175        }
176        return ret;
177    }
178
179    virtual int32_t reset()
180    {
181        Parcel data, reply;
182        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
183        status_t status = remote()->transact(BnKeystoreService::RESET, data, &reply);
184        if (status != NO_ERROR) {
185            ALOGD("reset() could not contact remote: %d\n", status);
186            return -1;
187        }
188        int32_t err = reply.readExceptionCode();
189        int32_t ret = reply.readInt32();
190        if (err < 0) {
191            ALOGD("reset() caught exception %d\n", err);
192            return -1;
193        }
194        return ret;
195    }
196
197    virtual int32_t password(const String16& password)
198    {
199        Parcel data, reply;
200        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
201        data.writeString16(password);
202        status_t status = remote()->transact(BnKeystoreService::PASSWORD, data, &reply);
203        if (status != NO_ERROR) {
204            ALOGD("password() could not contact remote: %d\n", status);
205            return -1;
206        }
207        int32_t err = reply.readExceptionCode();
208        int32_t ret = reply.readInt32();
209        if (err < 0) {
210            ALOGD("password() caught exception %d\n", err);
211            return -1;
212        }
213        return ret;
214    }
215
216    virtual int32_t lock()
217    {
218        Parcel data, reply;
219        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
220        status_t status = remote()->transact(BnKeystoreService::LOCK, data, &reply);
221        if (status != NO_ERROR) {
222            ALOGD("lock() could not contact remote: %d\n", status);
223            return -1;
224        }
225        int32_t err = reply.readExceptionCode();
226        int32_t ret = reply.readInt32();
227        if (err < 0) {
228            ALOGD("lock() caught exception %d\n", err);
229            return -1;
230        }
231        return ret;
232    }
233
234    virtual int32_t unlock(const String16& password)
235    {
236        Parcel data, reply;
237        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
238        data.writeString16(password);
239        status_t status = remote()->transact(BnKeystoreService::UNLOCK, data, &reply);
240        if (status != NO_ERROR) {
241            ALOGD("unlock() could not contact remote: %d\n", status);
242            return -1;
243        }
244        int32_t err = reply.readExceptionCode();
245        int32_t ret = reply.readInt32();
246        if (err < 0) {
247            ALOGD("unlock() caught exception %d\n", err);
248            return -1;
249        }
250        return ret;
251    }
252
253    virtual int32_t zero()
254    {
255        Parcel data, reply;
256        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
257        status_t status = remote()->transact(BnKeystoreService::ZERO, data, &reply);
258        if (status != NO_ERROR) {
259            ALOGD("zero() could not contact remote: %d\n", status);
260            return -1;
261        }
262        int32_t err = reply.readExceptionCode();
263        int32_t ret = reply.readInt32();
264        if (err < 0) {
265            ALOGD("zero() caught exception %d\n", err);
266            return -1;
267        }
268        return ret;
269    }
270
271    virtual int32_t generate(const String16& name, int uid)
272    {
273        Parcel data, reply;
274        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
275        data.writeString16(name);
276        data.writeInt32(uid);
277        status_t status = remote()->transact(BnKeystoreService::GENERATE, data, &reply);
278        if (status != NO_ERROR) {
279            ALOGD("generate() could not contact remote: %d\n", status);
280            return -1;
281        }
282        int32_t err = reply.readExceptionCode();
283        int32_t ret = reply.readInt32();
284        if (err < 0) {
285            ALOGD("generate() caught exception %d\n", err);
286            return -1;
287        }
288        return ret;
289    }
290
291    virtual int32_t import(const String16& name, const uint8_t* key, size_t keyLength, int uid)
292    {
293        Parcel data, reply;
294        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
295        data.writeString16(name);
296        data.writeInt32(keyLength);
297        void* buf = data.writeInplace(keyLength);
298        memcpy(buf, key, keyLength);
299        data.writeInt32(uid);
300        status_t status = remote()->transact(BnKeystoreService::IMPORT, data, &reply);
301        if (status != NO_ERROR) {
302            ALOGD("import() could not contact remote: %d\n", status);
303            return -1;
304        }
305        int32_t err = reply.readExceptionCode();
306        int32_t ret = reply.readInt32();
307        if (err < 0) {
308            ALOGD("import() caught exception %d\n", err);
309            return -1;
310        }
311        return ret;
312    }
313
314    virtual int32_t sign(const String16& name, const uint8_t* in, size_t inLength, uint8_t** out,
315            size_t* outLength)
316    {
317        Parcel data, reply;
318        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
319        data.writeString16(name);
320        data.writeInt32(inLength);
321        void* buf = data.writeInplace(inLength);
322        memcpy(buf, in, inLength);
323        status_t status = remote()->transact(BnKeystoreService::SIGN, data, &reply);
324        if (status != NO_ERROR) {
325            ALOGD("import() could not contact remote: %d\n", status);
326            return -1;
327        }
328        int32_t err = reply.readExceptionCode();
329        ssize_t len = reply.readInt32();
330        if (len >= 0 && (size_t) len <= reply.dataAvail()) {
331            size_t ulen = (size_t) len;
332            const void* outBuf = reply.readInplace(ulen);
333            *out = (uint8_t*) malloc(ulen);
334            if (*out != NULL) {
335                memcpy((void*) *out, outBuf, ulen);
336                *outLength = ulen;
337            } else {
338                ALOGE("out of memory allocating output array in sign");
339                *outLength = 0;
340            }
341        } else {
342            *outLength = 0;
343        }
344        if (err < 0) {
345            ALOGD("import() caught exception %d\n", err);
346            return -1;
347        }
348        return 0;
349    }
350
351    virtual int32_t verify(const String16& name, const uint8_t* in, size_t inLength,
352            const uint8_t* signature, size_t signatureLength)
353    {
354        Parcel data, reply;
355        void* buf;
356
357        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
358        data.writeString16(name);
359        data.writeInt32(inLength);
360        buf = data.writeInplace(inLength);
361        memcpy(buf, in, inLength);
362        data.writeInt32(signatureLength);
363        buf = data.writeInplace(signatureLength);
364        memcpy(buf, signature, signatureLength);
365        status_t status = remote()->transact(BnKeystoreService::VERIFY, data, &reply);
366        if (status != NO_ERROR) {
367            ALOGD("verify() could not contact remote: %d\n", status);
368            return -1;
369        }
370        int32_t err = reply.readExceptionCode();
371        int32_t ret = reply.readInt32();
372        if (err < 0) {
373            ALOGD("verify() caught exception %d\n", err);
374            return -1;
375        }
376        return ret;
377    }
378
379    virtual int32_t get_pubkey(const String16& name, uint8_t** pubkey, size_t* pubkeyLength)
380    {
381        Parcel data, reply;
382        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
383        data.writeString16(name);
384        status_t status = remote()->transact(BnKeystoreService::GET_PUBKEY, data, &reply);
385        if (status != NO_ERROR) {
386            ALOGD("get_pubkey() could not contact remote: %d\n", status);
387            return -1;
388        }
389        int32_t err = reply.readExceptionCode();
390        ssize_t len = reply.readInt32();
391        if (len >= 0 && (size_t) len <= reply.dataAvail()) {
392            size_t ulen = (size_t) len;
393            const void* buf = reply.readInplace(ulen);
394            *pubkey = (uint8_t*) malloc(ulen);
395            if (*pubkey != NULL) {
396                memcpy(*pubkey, buf, ulen);
397                *pubkeyLength = ulen;
398            } else {
399                ALOGE("out of memory allocating output array in get_pubkey");
400                *pubkeyLength = 0;
401            }
402        } else {
403            *pubkeyLength = 0;
404        }
405        if (err < 0) {
406            ALOGD("get_pubkey() caught exception %d\n", err);
407            return -1;
408        }
409        return 0;
410     }
411
412    virtual int32_t del_key(const String16& name, int uid)
413    {
414        Parcel data, reply;
415        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
416        data.writeString16(name);
417        data.writeInt32(uid);
418        status_t status = remote()->transact(BnKeystoreService::DEL_KEY, data, &reply);
419        if (status != NO_ERROR) {
420            ALOGD("del_key() could not contact remote: %d\n", status);
421            return -1;
422        }
423        int32_t err = reply.readExceptionCode();
424        int32_t ret = reply.readInt32();
425        if (err < 0) {
426            ALOGD("del_key() caught exception %d\n", err);
427            return -1;
428        }
429        return ret;
430    }
431
432    virtual int32_t grant(const String16& name, int32_t granteeUid)
433    {
434        Parcel data, reply;
435        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
436        data.writeString16(name);
437        data.writeInt32(granteeUid);
438        status_t status = remote()->transact(BnKeystoreService::GRANT, data, &reply);
439        if (status != NO_ERROR) {
440            ALOGD("grant() could not contact remote: %d\n", status);
441            return -1;
442        }
443        int32_t err = reply.readExceptionCode();
444        int32_t ret = reply.readInt32();
445        if (err < 0) {
446            ALOGD("grant() caught exception %d\n", err);
447            return -1;
448        }
449        return ret;
450    }
451
452    virtual int32_t ungrant(const String16& name, int32_t granteeUid)
453    {
454        Parcel data, reply;
455        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
456        data.writeString16(name);
457        data.writeInt32(granteeUid);
458        status_t status = remote()->transact(BnKeystoreService::UNGRANT, data, &reply);
459        if (status != NO_ERROR) {
460            ALOGD("ungrant() could not contact remote: %d\n", status);
461            return -1;
462        }
463        int32_t err = reply.readExceptionCode();
464        int32_t ret = reply.readInt32();
465        if (err < 0) {
466            ALOGD("ungrant() caught exception %d\n", err);
467            return -1;
468        }
469        return ret;
470    }
471
472    int64_t getmtime(const String16& name)
473    {
474        Parcel data, reply;
475        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
476        data.writeString16(name);
477        status_t status = remote()->transact(BnKeystoreService::GETMTIME, data, &reply);
478        if (status != NO_ERROR) {
479            ALOGD("getmtime() could not contact remote: %d\n", status);
480            return -1;
481        }
482        int32_t err = reply.readExceptionCode();
483        int64_t ret = reply.readInt64();
484        if (err < 0) {
485            ALOGD("getmtime() caught exception %d\n", err);
486            return -1;
487        }
488        return ret;
489    }
490
491    virtual int32_t migrate(const String16& name, int32_t targetUid)
492    {
493        Parcel data, reply;
494        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
495        data.writeString16(name);
496        data.writeInt32(targetUid);
497        status_t status = remote()->transact(BnKeystoreService::MIGRATE, data, &reply);
498        if (status != NO_ERROR) {
499            ALOGD("migrate() could not contact remote: %d\n", status);
500            return -1;
501        }
502        int32_t err = reply.readExceptionCode();
503        int32_t ret = reply.readInt32();
504        if (err < 0) {
505            ALOGD("migrate() caught exception %d\n", err);
506            return -1;
507        }
508        return ret;
509    }
510};
511
512IMPLEMENT_META_INTERFACE(KeystoreService, "android.security.keystore");
513
514// ----------------------------------------------------------------------
515
516status_t BnKeystoreService::onTransact(
517    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
518{
519    switch(code) {
520        case TEST: {
521            CHECK_INTERFACE(IKeystoreService, data, reply);
522            int32_t ret = test();
523            reply->writeNoException();
524            reply->writeInt32(ret);
525            return NO_ERROR;
526        } break;
527        case GET: {
528            CHECK_INTERFACE(IKeystoreService, data, reply);
529            String16 name = data.readString16();
530            void* out = NULL;
531            size_t outSize = 0;
532            int32_t ret = get(name, (uint8_t**) &out, &outSize);
533            reply->writeNoException();
534            if (ret == 1) {
535                reply->writeInt32(outSize);
536                void* buf = reply->writeInplace(outSize);
537                memcpy(buf, out, outSize);
538                free(out);
539            } else {
540                reply->writeInt32(-1);
541            }
542            return NO_ERROR;
543        } break;
544        case INSERT: {
545            CHECK_INTERFACE(IKeystoreService, data, reply);
546            String16 name = data.readString16();
547            ssize_t inSize = data.readInt32();
548            const void* in;
549            if (inSize >= 0 && (size_t) inSize <= data.dataAvail()) {
550                in = data.readInplace(inSize);
551            } else {
552                in = NULL;
553                inSize = 0;
554            }
555            int uid = data.readInt32();
556            int32_t ret = insert(name, (const uint8_t*) in, (size_t) inSize, uid);
557            reply->writeNoException();
558            reply->writeInt32(ret);
559            return NO_ERROR;
560        } break;
561        case DEL: {
562            CHECK_INTERFACE(IKeystoreService, data, reply);
563            String16 name = data.readString16();
564            int uid = data.readInt32();
565            int32_t ret = del(name, uid);
566            reply->writeNoException();
567            reply->writeInt32(ret);
568            return NO_ERROR;
569        } break;
570        case EXIST: {
571            CHECK_INTERFACE(IKeystoreService, data, reply);
572            String16 name = data.readString16();
573            int uid = data.readInt32();
574            int32_t ret = exist(name, uid);
575            reply->writeNoException();
576            reply->writeInt32(ret);
577            return NO_ERROR;
578        } break;
579        case SAW: {
580            CHECK_INTERFACE(IKeystoreService, data, reply);
581            String16 name = data.readString16();
582            int uid = data.readInt32();
583            Vector<String16> matches;
584            int32_t ret = saw(name, uid, &matches);
585            reply->writeNoException();
586            reply->writeInt32(matches.size());
587            Vector<String16>::const_iterator it = matches.begin();
588            for (; it != matches.end(); ++it) {
589                reply->writeString16(*it);
590            }
591            reply->writeInt32(ret);
592            return NO_ERROR;
593        } break;
594        case RESET: {
595            CHECK_INTERFACE(IKeystoreService, data, reply);
596            int32_t ret = reset();
597            reply->writeNoException();
598            reply->writeInt32(ret);
599            return NO_ERROR;
600        } break;
601        case PASSWORD: {
602            CHECK_INTERFACE(IKeystoreService, data, reply);
603            String16 pass = data.readString16();
604            int32_t ret = password(pass);
605            reply->writeNoException();
606            reply->writeInt32(ret);
607            return NO_ERROR;
608        } break;
609        case LOCK: {
610            CHECK_INTERFACE(IKeystoreService, data, reply);
611            int32_t ret = lock();
612            reply->writeNoException();
613            reply->writeInt32(ret);
614            return NO_ERROR;
615        } break;
616        case UNLOCK: {
617            CHECK_INTERFACE(IKeystoreService, data, reply);
618            String16 pass = data.readString16();
619            int32_t ret = unlock(pass);
620            reply->writeNoException();
621            reply->writeInt32(ret);
622            return NO_ERROR;
623        } break;
624        case ZERO: {
625            CHECK_INTERFACE(IKeystoreService, data, reply);
626            int32_t ret = zero();
627            reply->writeNoException();
628            reply->writeInt32(ret);
629            return NO_ERROR;
630        } break;
631        case GENERATE: {
632            CHECK_INTERFACE(IKeystoreService, data, reply);
633            String16 name = data.readString16();
634            int uid = data.readInt32();
635            int32_t ret = generate(name, uid);
636            reply->writeNoException();
637            reply->writeInt32(ret);
638            return NO_ERROR;
639        } break;
640        case IMPORT: {
641            CHECK_INTERFACE(IKeystoreService, data, reply);
642            String16 name = data.readString16();
643            ssize_t inSize = data.readInt32();
644            const void* in;
645            if (inSize >= 0 && (size_t) inSize <= data.dataAvail()) {
646                in = data.readInplace(inSize);
647            } else {
648                in = NULL;
649                inSize = 0;
650            }
651            int uid = data.readInt32();
652            int32_t ret = import(name, (const uint8_t*) in, (size_t) inSize, uid);
653            reply->writeNoException();
654            reply->writeInt32(ret);
655            return NO_ERROR;
656        } break;
657        case SIGN: {
658            CHECK_INTERFACE(IKeystoreService, data, reply);
659            String16 name = data.readString16();
660            ssize_t inSize = data.readInt32();
661            const void* in;
662            if (inSize >= 0 && (size_t) inSize <= data.dataAvail()) {
663                in = data.readInplace(inSize);
664            } else {
665                in = NULL;
666                inSize = 0;
667            }
668            void* out = NULL;
669            size_t outSize = 0;
670            int32_t ret = sign(name, (const uint8_t*) in, (size_t) inSize, (uint8_t**) &out, &outSize);
671            reply->writeNoException();
672            if (outSize > 0 && out != NULL) {
673                reply->writeInt32(outSize);
674                void* buf = reply->writeInplace(outSize);
675                memcpy(buf, out, outSize);
676                free(out);
677            } else {
678                reply->writeInt32(-1);
679            }
680            reply->writeInt32(ret);
681            return NO_ERROR;
682        } break;
683        case VERIFY: {
684            CHECK_INTERFACE(IKeystoreService, data, reply);
685            String16 name = data.readString16();
686            ssize_t inSize = data.readInt32();
687            const void* in;
688            if (inSize >= 0 && (size_t) inSize <= data.dataAvail()) {
689                in = data.readInplace(inSize);
690            } else {
691                in = NULL;
692                inSize = 0;
693            }
694            ssize_t sigSize = data.readInt32();
695            const void* sig;
696            if (sigSize >= 0 && (size_t) sigSize <= data.dataAvail()) {
697                sig = data.readInplace(sigSize);
698            } else {
699                sig = NULL;
700                sigSize = 0;
701            }
702            bool ret = verify(name, (const uint8_t*) in, (size_t) inSize, (const uint8_t*) sig,
703                    (size_t) sigSize);
704            reply->writeNoException();
705            reply->writeInt32(ret ? 1 : 0);
706            return NO_ERROR;
707        } break;
708        case GET_PUBKEY: {
709            CHECK_INTERFACE(IKeystoreService, data, reply);
710            String16 name = data.readString16();
711            void* out = NULL;
712            size_t outSize = 0;
713            int32_t ret = get_pubkey(name, (unsigned char**) &out, &outSize);
714            reply->writeNoException();
715            if (outSize > 0 && out != NULL) {
716                reply->writeInt32(outSize);
717                void* buf = reply->writeInplace(outSize);
718                memcpy(buf, out, outSize);
719                free(out);
720            } else {
721                reply->writeInt32(-1);
722            }
723            reply->writeInt32(ret);
724            return NO_ERROR;
725        } break;
726        case DEL_KEY: {
727            CHECK_INTERFACE(IKeystoreService, data, reply);
728            String16 name = data.readString16();
729            int uid = data.readInt32();
730            int32_t ret = del_key(name, uid);
731            reply->writeNoException();
732            reply->writeInt32(ret);
733            return NO_ERROR;
734        } break;
735        case GRANT: {
736            CHECK_INTERFACE(IKeystoreService, data, reply);
737            String16 name = data.readString16();
738            int32_t granteeUid = data.readInt32();
739            int32_t ret = grant(name, granteeUid);
740            reply->writeNoException();
741            reply->writeInt32(ret);
742            return NO_ERROR;
743        } break;
744        case UNGRANT: {
745            CHECK_INTERFACE(IKeystoreService, data, reply);
746            String16 name = data.readString16();
747            int32_t granteeUid = data.readInt32();
748            int32_t ret = ungrant(name, granteeUid);
749            reply->writeNoException();
750            reply->writeInt32(ret);
751            return NO_ERROR;
752        } break;
753        case GETMTIME: {
754            CHECK_INTERFACE(IKeystoreService, data, reply);
755            String16 name = data.readString16();
756            int64_t ret = getmtime(name);
757            reply->writeNoException();
758            reply->writeInt64(ret);
759            return NO_ERROR;
760        } break;
761        case MIGRATE: {
762            CHECK_INTERFACE(IKeystoreService, data, reply);
763            String16 name = data.readString16();
764            int32_t targetUid = data.readInt32();
765            int32_t ret = migrate(name, targetUid);
766            reply->writeNoException();
767            reply->writeInt32(ret);
768            return NO_ERROR;
769        } break;
770        default:
771            return BBinder::onTransact(code, data, reply, flags);
772    }
773}
774
775// ----------------------------------------------------------------------------
776
777}; // namespace android
778