IKeystoreService.cpp revision 4306123e81371bd8bd85f77c2375d29ac53ff771
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 duplicate(const String16& srcKey, int32_t srcUid, const String16& destKey,
492            int32_t destUid)
493    {
494        Parcel data, reply;
495        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
496        data.writeString16(srcKey);
497        data.writeInt32(srcUid);
498        data.writeString16(destKey);
499        data.writeInt32(destUid);
500        status_t status = remote()->transact(BnKeystoreService::DUPLICATE, data, &reply);
501        if (status != NO_ERROR) {
502            ALOGD("duplicate() could not contact remote: %d\n", status);
503            return -1;
504        }
505        int32_t err = reply.readExceptionCode();
506        int32_t ret = reply.readInt32();
507        if (err < 0) {
508            ALOGD("duplicate() caught exception %d\n", err);
509            return -1;
510        }
511        return ret;
512    }
513
514    virtual int32_t is_hardware_backed()
515    {
516        Parcel data, reply;
517        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
518        status_t status = remote()->transact(BnKeystoreService::IS_HARDWARE_BACKED, data, &reply);
519        if (status != NO_ERROR) {
520            ALOGD("is_hardware_backed() could not contact remote: %d\n", status);
521            return -1;
522        }
523        int32_t err = reply.readExceptionCode();
524        int32_t ret = reply.readInt32();
525        if (err < 0) {
526            ALOGD("is_hardware_backed() caught exception %d\n", err);
527            return -1;
528        }
529        return ret;
530    }
531};
532
533IMPLEMENT_META_INTERFACE(KeystoreService, "android.security.keystore");
534
535// ----------------------------------------------------------------------
536
537status_t BnKeystoreService::onTransact(
538    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
539{
540    switch(code) {
541        case TEST: {
542            CHECK_INTERFACE(IKeystoreService, data, reply);
543            int32_t ret = test();
544            reply->writeNoException();
545            reply->writeInt32(ret);
546            return NO_ERROR;
547        } break;
548        case GET: {
549            CHECK_INTERFACE(IKeystoreService, data, reply);
550            String16 name = data.readString16();
551            void* out = NULL;
552            size_t outSize = 0;
553            int32_t ret = get(name, (uint8_t**) &out, &outSize);
554            reply->writeNoException();
555            if (ret == 1) {
556                reply->writeInt32(outSize);
557                void* buf = reply->writeInplace(outSize);
558                memcpy(buf, out, outSize);
559                free(out);
560            } else {
561                reply->writeInt32(-1);
562            }
563            return NO_ERROR;
564        } break;
565        case INSERT: {
566            CHECK_INTERFACE(IKeystoreService, data, reply);
567            String16 name = data.readString16();
568            ssize_t inSize = data.readInt32();
569            const void* in;
570            if (inSize >= 0 && (size_t) inSize <= data.dataAvail()) {
571                in = data.readInplace(inSize);
572            } else {
573                in = NULL;
574                inSize = 0;
575            }
576            int uid = data.readInt32();
577            int32_t ret = insert(name, (const uint8_t*) in, (size_t) inSize, uid);
578            reply->writeNoException();
579            reply->writeInt32(ret);
580            return NO_ERROR;
581        } break;
582        case DEL: {
583            CHECK_INTERFACE(IKeystoreService, data, reply);
584            String16 name = data.readString16();
585            int uid = data.readInt32();
586            int32_t ret = del(name, uid);
587            reply->writeNoException();
588            reply->writeInt32(ret);
589            return NO_ERROR;
590        } break;
591        case EXIST: {
592            CHECK_INTERFACE(IKeystoreService, data, reply);
593            String16 name = data.readString16();
594            int uid = data.readInt32();
595            int32_t ret = exist(name, uid);
596            reply->writeNoException();
597            reply->writeInt32(ret);
598            return NO_ERROR;
599        } break;
600        case SAW: {
601            CHECK_INTERFACE(IKeystoreService, data, reply);
602            String16 name = data.readString16();
603            int uid = data.readInt32();
604            Vector<String16> matches;
605            int32_t ret = saw(name, uid, &matches);
606            reply->writeNoException();
607            reply->writeInt32(matches.size());
608            Vector<String16>::const_iterator it = matches.begin();
609            for (; it != matches.end(); ++it) {
610                reply->writeString16(*it);
611            }
612            reply->writeInt32(ret);
613            return NO_ERROR;
614        } break;
615        case RESET: {
616            CHECK_INTERFACE(IKeystoreService, data, reply);
617            int32_t ret = reset();
618            reply->writeNoException();
619            reply->writeInt32(ret);
620            return NO_ERROR;
621        } break;
622        case PASSWORD: {
623            CHECK_INTERFACE(IKeystoreService, data, reply);
624            String16 pass = data.readString16();
625            int32_t ret = password(pass);
626            reply->writeNoException();
627            reply->writeInt32(ret);
628            return NO_ERROR;
629        } break;
630        case LOCK: {
631            CHECK_INTERFACE(IKeystoreService, data, reply);
632            int32_t ret = lock();
633            reply->writeNoException();
634            reply->writeInt32(ret);
635            return NO_ERROR;
636        } break;
637        case UNLOCK: {
638            CHECK_INTERFACE(IKeystoreService, data, reply);
639            String16 pass = data.readString16();
640            int32_t ret = unlock(pass);
641            reply->writeNoException();
642            reply->writeInt32(ret);
643            return NO_ERROR;
644        } break;
645        case ZERO: {
646            CHECK_INTERFACE(IKeystoreService, data, reply);
647            int32_t ret = zero();
648            reply->writeNoException();
649            reply->writeInt32(ret);
650            return NO_ERROR;
651        } break;
652        case GENERATE: {
653            CHECK_INTERFACE(IKeystoreService, data, reply);
654            String16 name = data.readString16();
655            int uid = data.readInt32();
656            int32_t ret = generate(name, uid);
657            reply->writeNoException();
658            reply->writeInt32(ret);
659            return NO_ERROR;
660        } break;
661        case IMPORT: {
662            CHECK_INTERFACE(IKeystoreService, data, reply);
663            String16 name = data.readString16();
664            ssize_t inSize = data.readInt32();
665            const void* in;
666            if (inSize >= 0 && (size_t) inSize <= data.dataAvail()) {
667                in = data.readInplace(inSize);
668            } else {
669                in = NULL;
670                inSize = 0;
671            }
672            int uid = data.readInt32();
673            int32_t ret = import(name, (const uint8_t*) in, (size_t) inSize, uid);
674            reply->writeNoException();
675            reply->writeInt32(ret);
676            return NO_ERROR;
677        } break;
678        case SIGN: {
679            CHECK_INTERFACE(IKeystoreService, data, reply);
680            String16 name = data.readString16();
681            ssize_t inSize = data.readInt32();
682            const void* in;
683            if (inSize >= 0 && (size_t) inSize <= data.dataAvail()) {
684                in = data.readInplace(inSize);
685            } else {
686                in = NULL;
687                inSize = 0;
688            }
689            void* out = NULL;
690            size_t outSize = 0;
691            int32_t ret = sign(name, (const uint8_t*) in, (size_t) inSize, (uint8_t**) &out, &outSize);
692            reply->writeNoException();
693            if (outSize > 0 && out != NULL) {
694                reply->writeInt32(outSize);
695                void* buf = reply->writeInplace(outSize);
696                memcpy(buf, out, outSize);
697                free(out);
698            } else {
699                reply->writeInt32(-1);
700            }
701            reply->writeInt32(ret);
702            return NO_ERROR;
703        } break;
704        case VERIFY: {
705            CHECK_INTERFACE(IKeystoreService, data, reply);
706            String16 name = data.readString16();
707            ssize_t inSize = data.readInt32();
708            const void* in;
709            if (inSize >= 0 && (size_t) inSize <= data.dataAvail()) {
710                in = data.readInplace(inSize);
711            } else {
712                in = NULL;
713                inSize = 0;
714            }
715            ssize_t sigSize = data.readInt32();
716            const void* sig;
717            if (sigSize >= 0 && (size_t) sigSize <= data.dataAvail()) {
718                sig = data.readInplace(sigSize);
719            } else {
720                sig = NULL;
721                sigSize = 0;
722            }
723            bool ret = verify(name, (const uint8_t*) in, (size_t) inSize, (const uint8_t*) sig,
724                    (size_t) sigSize);
725            reply->writeNoException();
726            reply->writeInt32(ret ? 1 : 0);
727            return NO_ERROR;
728        } break;
729        case GET_PUBKEY: {
730            CHECK_INTERFACE(IKeystoreService, data, reply);
731            String16 name = data.readString16();
732            void* out = NULL;
733            size_t outSize = 0;
734            int32_t ret = get_pubkey(name, (unsigned char**) &out, &outSize);
735            reply->writeNoException();
736            if (outSize > 0 && out != NULL) {
737                reply->writeInt32(outSize);
738                void* buf = reply->writeInplace(outSize);
739                memcpy(buf, out, outSize);
740                free(out);
741            } else {
742                reply->writeInt32(-1);
743            }
744            reply->writeInt32(ret);
745            return NO_ERROR;
746        } break;
747        case DEL_KEY: {
748            CHECK_INTERFACE(IKeystoreService, data, reply);
749            String16 name = data.readString16();
750            int uid = data.readInt32();
751            int32_t ret = del_key(name, uid);
752            reply->writeNoException();
753            reply->writeInt32(ret);
754            return NO_ERROR;
755        } break;
756        case GRANT: {
757            CHECK_INTERFACE(IKeystoreService, data, reply);
758            String16 name = data.readString16();
759            int32_t granteeUid = data.readInt32();
760            int32_t ret = grant(name, granteeUid);
761            reply->writeNoException();
762            reply->writeInt32(ret);
763            return NO_ERROR;
764        } break;
765        case UNGRANT: {
766            CHECK_INTERFACE(IKeystoreService, data, reply);
767            String16 name = data.readString16();
768            int32_t granteeUid = data.readInt32();
769            int32_t ret = ungrant(name, granteeUid);
770            reply->writeNoException();
771            reply->writeInt32(ret);
772            return NO_ERROR;
773        } break;
774        case GETMTIME: {
775            CHECK_INTERFACE(IKeystoreService, data, reply);
776            String16 name = data.readString16();
777            int64_t ret = getmtime(name);
778            reply->writeNoException();
779            reply->writeInt64(ret);
780            return NO_ERROR;
781        } break;
782        case DUPLICATE: {
783            CHECK_INTERFACE(IKeystoreService, data, reply);
784            String16 srcKey = data.readString16();
785            int32_t srcUid = data.readInt32();
786            String16 destKey = data.readString16();
787            int32_t destUid = data.readInt32();
788            int32_t ret = duplicate(srcKey, srcUid, destKey, destUid);
789            reply->writeNoException();
790            reply->writeInt32(ret);
791            return NO_ERROR;
792        } break;
793        case IS_HARDWARE_BACKED: {
794            CHECK_INTERFACE(IKeystoreService, data, reply);
795            int32_t ret = is_hardware_backed();
796            reply->writeNoException();
797            reply->writeInt32(ret);
798            return NO_ERROR;
799        }
800        default:
801            return BBinder::onTransact(code, data, reply, flags);
802    }
803}
804
805// ----------------------------------------------------------------------------
806
807}; // namespace android
808