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