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