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(args->size());
299        for (Vector<sp<KeystoreArg> >::iterator it = args->begin(); it != args->end(); ++it) {
300            sp<KeystoreArg> item = *it;
301            size_t keyLength = item->size();
302            data.writeInt32(keyLength);
303            void* buf = data.writeInplace(keyLength);
304            memcpy(buf, item->data(), keyLength);
305        }
306        status_t status = remote()->transact(BnKeystoreService::GENERATE, data, &reply);
307        if (status != NO_ERROR) {
308            ALOGD("generate() could not contact remote: %d\n", status);
309            return -1;
310        }
311        int32_t err = reply.readExceptionCode();
312        int32_t ret = reply.readInt32();
313        if (err < 0) {
314            ALOGD("generate() caught exception %d\n", err);
315            return -1;
316        }
317        return ret;
318    }
319
320    virtual int32_t import(const String16& name, const uint8_t* key, size_t keyLength, int uid,
321            int flags)
322    {
323        Parcel data, reply;
324        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
325        data.writeString16(name);
326        data.writeInt32(keyLength);
327        void* buf = data.writeInplace(keyLength);
328        memcpy(buf, key, keyLength);
329        data.writeInt32(uid);
330        data.writeInt32(flags);
331        status_t status = remote()->transact(BnKeystoreService::IMPORT, data, &reply);
332        if (status != NO_ERROR) {
333            ALOGD("import() could not contact remote: %d\n", status);
334            return -1;
335        }
336        int32_t err = reply.readExceptionCode();
337        int32_t ret = reply.readInt32();
338        if (err < 0) {
339            ALOGD("import() caught exception %d\n", err);
340            return -1;
341        }
342        return ret;
343    }
344
345    virtual int32_t sign(const String16& name, const uint8_t* in, size_t inLength, uint8_t** out,
346            size_t* outLength)
347    {
348        Parcel data, reply;
349        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
350        data.writeString16(name);
351        data.writeInt32(inLength);
352        void* buf = data.writeInplace(inLength);
353        memcpy(buf, in, inLength);
354        status_t status = remote()->transact(BnKeystoreService::SIGN, data, &reply);
355        if (status != NO_ERROR) {
356            ALOGD("import() could not contact remote: %d\n", status);
357            return -1;
358        }
359        int32_t err = reply.readExceptionCode();
360        ssize_t len = reply.readInt32();
361        if (len >= 0 && (size_t) len <= reply.dataAvail()) {
362            size_t ulen = (size_t) len;
363            const void* outBuf = reply.readInplace(ulen);
364            *out = (uint8_t*) malloc(ulen);
365            if (*out != NULL) {
366                memcpy((void*) *out, outBuf, ulen);
367                *outLength = ulen;
368            } else {
369                ALOGE("out of memory allocating output array in sign");
370                *outLength = 0;
371            }
372        } else {
373            *outLength = 0;
374        }
375        if (err < 0) {
376            ALOGD("import() caught exception %d\n", err);
377            return -1;
378        }
379        return 0;
380    }
381
382    virtual int32_t verify(const String16& name, const uint8_t* in, size_t inLength,
383            const uint8_t* signature, size_t signatureLength)
384    {
385        Parcel data, reply;
386        void* buf;
387
388        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
389        data.writeString16(name);
390        data.writeInt32(inLength);
391        buf = data.writeInplace(inLength);
392        memcpy(buf, in, inLength);
393        data.writeInt32(signatureLength);
394        buf = data.writeInplace(signatureLength);
395        memcpy(buf, signature, signatureLength);
396        status_t status = remote()->transact(BnKeystoreService::VERIFY, data, &reply);
397        if (status != NO_ERROR) {
398            ALOGD("verify() could not contact remote: %d\n", status);
399            return -1;
400        }
401        int32_t err = reply.readExceptionCode();
402        int32_t ret = reply.readInt32();
403        if (err < 0) {
404            ALOGD("verify() caught exception %d\n", err);
405            return -1;
406        }
407        return ret;
408    }
409
410    virtual int32_t get_pubkey(const String16& name, uint8_t** pubkey, size_t* pubkeyLength)
411    {
412        Parcel data, reply;
413        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
414        data.writeString16(name);
415        status_t status = remote()->transact(BnKeystoreService::GET_PUBKEY, data, &reply);
416        if (status != NO_ERROR) {
417            ALOGD("get_pubkey() could not contact remote: %d\n", status);
418            return -1;
419        }
420        int32_t err = reply.readExceptionCode();
421        ssize_t len = reply.readInt32();
422        if (len >= 0 && (size_t) len <= reply.dataAvail()) {
423            size_t ulen = (size_t) len;
424            const void* buf = reply.readInplace(ulen);
425            *pubkey = (uint8_t*) malloc(ulen);
426            if (*pubkey != NULL) {
427                memcpy(*pubkey, buf, ulen);
428                *pubkeyLength = ulen;
429            } else {
430                ALOGE("out of memory allocating output array in get_pubkey");
431                *pubkeyLength = 0;
432            }
433        } else {
434            *pubkeyLength = 0;
435        }
436        if (err < 0) {
437            ALOGD("get_pubkey() caught exception %d\n", err);
438            return -1;
439        }
440        return 0;
441     }
442
443    virtual int32_t del_key(const String16& name, int uid)
444    {
445        Parcel data, reply;
446        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
447        data.writeString16(name);
448        data.writeInt32(uid);
449        status_t status = remote()->transact(BnKeystoreService::DEL_KEY, data, &reply);
450        if (status != NO_ERROR) {
451            ALOGD("del_key() could not contact remote: %d\n", status);
452            return -1;
453        }
454        int32_t err = reply.readExceptionCode();
455        int32_t ret = reply.readInt32();
456        if (err < 0) {
457            ALOGD("del_key() caught exception %d\n", err);
458            return -1;
459        }
460        return ret;
461    }
462
463    virtual int32_t grant(const String16& name, int32_t granteeUid)
464    {
465        Parcel data, reply;
466        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
467        data.writeString16(name);
468        data.writeInt32(granteeUid);
469        status_t status = remote()->transact(BnKeystoreService::GRANT, data, &reply);
470        if (status != NO_ERROR) {
471            ALOGD("grant() could not contact remote: %d\n", status);
472            return -1;
473        }
474        int32_t err = reply.readExceptionCode();
475        int32_t ret = reply.readInt32();
476        if (err < 0) {
477            ALOGD("grant() caught exception %d\n", err);
478            return -1;
479        }
480        return ret;
481    }
482
483    virtual int32_t ungrant(const String16& name, int32_t granteeUid)
484    {
485        Parcel data, reply;
486        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
487        data.writeString16(name);
488        data.writeInt32(granteeUid);
489        status_t status = remote()->transact(BnKeystoreService::UNGRANT, data, &reply);
490        if (status != NO_ERROR) {
491            ALOGD("ungrant() could not contact remote: %d\n", status);
492            return -1;
493        }
494        int32_t err = reply.readExceptionCode();
495        int32_t ret = reply.readInt32();
496        if (err < 0) {
497            ALOGD("ungrant() caught exception %d\n", err);
498            return -1;
499        }
500        return ret;
501    }
502
503    int64_t getmtime(const String16& name)
504    {
505        Parcel data, reply;
506        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
507        data.writeString16(name);
508        status_t status = remote()->transact(BnKeystoreService::GETMTIME, data, &reply);
509        if (status != NO_ERROR) {
510            ALOGD("getmtime() could not contact remote: %d\n", status);
511            return -1;
512        }
513        int32_t err = reply.readExceptionCode();
514        int64_t ret = reply.readInt64();
515        if (err < 0) {
516            ALOGD("getmtime() caught exception %d\n", err);
517            return -1;
518        }
519        return ret;
520    }
521
522    virtual int32_t duplicate(const String16& srcKey, int32_t srcUid, const String16& destKey,
523            int32_t destUid)
524    {
525        Parcel data, reply;
526        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
527        data.writeString16(srcKey);
528        data.writeInt32(srcUid);
529        data.writeString16(destKey);
530        data.writeInt32(destUid);
531        status_t status = remote()->transact(BnKeystoreService::DUPLICATE, data, &reply);
532        if (status != NO_ERROR) {
533            ALOGD("duplicate() could not contact remote: %d\n", status);
534            return -1;
535        }
536        int32_t err = reply.readExceptionCode();
537        int32_t ret = reply.readInt32();
538        if (err < 0) {
539            ALOGD("duplicate() caught exception %d\n", err);
540            return -1;
541        }
542        return ret;
543    }
544
545    virtual int32_t is_hardware_backed(const String16& keyType)
546    {
547        Parcel data, reply;
548        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
549        data.writeString16(keyType);
550        status_t status = remote()->transact(BnKeystoreService::IS_HARDWARE_BACKED, data, &reply);
551        if (status != NO_ERROR) {
552            ALOGD("is_hardware_backed() could not contact remote: %d\n", status);
553            return -1;
554        }
555        int32_t err = reply.readExceptionCode();
556        int32_t ret = reply.readInt32();
557        if (err < 0) {
558            ALOGD("is_hardware_backed() caught exception %d\n", err);
559            return -1;
560        }
561        return ret;
562    }
563
564    virtual int32_t clear_uid(int64_t uid)
565    {
566        Parcel data, reply;
567        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
568        data.writeInt64(uid);
569        status_t status = remote()->transact(BnKeystoreService::CLEAR_UID, data, &reply);
570        if (status != NO_ERROR) {
571            ALOGD("clear_uid() could not contact remote: %d\n", status);
572            return -1;
573        }
574        int32_t err = reply.readExceptionCode();
575        int32_t ret = reply.readInt32();
576        if (err < 0) {
577            ALOGD("clear_uid() caught exception %d\n", err);
578            return -1;
579        }
580        return ret;
581    }
582
583    virtual int32_t reset_uid(int32_t uid) {
584        Parcel data, reply;
585        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
586        data.writeInt32(uid);
587        status_t status = remote()->transact(BnKeystoreService::RESET_UID, data, &reply);
588        if (status != NO_ERROR) {
589            ALOGD("reset_uid() could not contact remote: %d\n", status);
590            return -1;
591        }
592        int32_t err = reply.readExceptionCode();
593        int32_t ret = reply.readInt32();
594        if (err < 0) {
595            ALOGD("reset_uid() caught exception %d\n", err);
596            return -1;
597        }
598        return ret;
599
600    }
601
602    virtual int32_t sync_uid(int32_t sourceUid, int32_t targetUid)
603    {
604        Parcel data, reply;
605        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
606        data.writeInt32(sourceUid);
607        data.writeInt32(targetUid);
608        status_t status = remote()->transact(BnKeystoreService::SYNC_UID, data, &reply);
609        if (status != NO_ERROR) {
610            ALOGD("sync_uid() could not contact remote: %d\n", status);
611            return -1;
612        }
613        int32_t err = reply.readExceptionCode();
614        int32_t ret = reply.readInt32();
615        if (err < 0) {
616            ALOGD("sync_uid() caught exception %d\n", err);
617            return -1;
618        }
619        return ret;
620    }
621
622    virtual int32_t password_uid(const String16& password, int32_t uid)
623    {
624        Parcel data, reply;
625        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
626        data.writeString16(password);
627        data.writeInt32(uid);
628        status_t status = remote()->transact(BnKeystoreService::PASSWORD_UID, data, &reply);
629        if (status != NO_ERROR) {
630            ALOGD("password_uid() could not contact remote: %d\n", status);
631            return -1;
632        }
633        int32_t err = reply.readExceptionCode();
634        int32_t ret = reply.readInt32();
635        if (err < 0) {
636            ALOGD("password_uid() caught exception %d\n", err);
637            return -1;
638        }
639        return ret;
640    }
641};
642
643IMPLEMENT_META_INTERFACE(KeystoreService, "android.security.keystore");
644
645// ----------------------------------------------------------------------
646
647status_t BnKeystoreService::onTransact(
648    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
649{
650    switch(code) {
651        case TEST: {
652            CHECK_INTERFACE(IKeystoreService, data, reply);
653            int32_t ret = test();
654            reply->writeNoException();
655            reply->writeInt32(ret);
656            return NO_ERROR;
657        } break;
658        case GET: {
659            CHECK_INTERFACE(IKeystoreService, data, reply);
660            String16 name = data.readString16();
661            void* out = NULL;
662            size_t outSize = 0;
663            int32_t ret = get(name, (uint8_t**) &out, &outSize);
664            reply->writeNoException();
665            if (ret == 1) {
666                reply->writeInt32(outSize);
667                void* buf = reply->writeInplace(outSize);
668                memcpy(buf, out, outSize);
669                free(out);
670            } else {
671                reply->writeInt32(-1);
672            }
673            return NO_ERROR;
674        } break;
675        case INSERT: {
676            CHECK_INTERFACE(IKeystoreService, data, reply);
677            String16 name = data.readString16();
678            ssize_t inSize = data.readInt32();
679            const void* in;
680            if (inSize >= 0 && (size_t) inSize <= data.dataAvail()) {
681                in = data.readInplace(inSize);
682            } else {
683                in = NULL;
684                inSize = 0;
685            }
686            int uid = data.readInt32();
687            int32_t flags = data.readInt32();
688            int32_t ret = insert(name, (const uint8_t*) in, (size_t) inSize, uid, flags);
689            reply->writeNoException();
690            reply->writeInt32(ret);
691            return NO_ERROR;
692        } break;
693        case DEL: {
694            CHECK_INTERFACE(IKeystoreService, data, reply);
695            String16 name = data.readString16();
696            int uid = data.readInt32();
697            int32_t ret = del(name, uid);
698            reply->writeNoException();
699            reply->writeInt32(ret);
700            return NO_ERROR;
701        } break;
702        case EXIST: {
703            CHECK_INTERFACE(IKeystoreService, data, reply);
704            String16 name = data.readString16();
705            int uid = data.readInt32();
706            int32_t ret = exist(name, uid);
707            reply->writeNoException();
708            reply->writeInt32(ret);
709            return NO_ERROR;
710        } break;
711        case SAW: {
712            CHECK_INTERFACE(IKeystoreService, data, reply);
713            String16 name = data.readString16();
714            int uid = data.readInt32();
715            Vector<String16> matches;
716            int32_t ret = saw(name, uid, &matches);
717            reply->writeNoException();
718            reply->writeInt32(matches.size());
719            Vector<String16>::const_iterator it = matches.begin();
720            for (; it != matches.end(); ++it) {
721                reply->writeString16(*it);
722            }
723            reply->writeInt32(ret);
724            return NO_ERROR;
725        } break;
726        case RESET: {
727            CHECK_INTERFACE(IKeystoreService, data, reply);
728            int32_t ret = reset();
729            reply->writeNoException();
730            reply->writeInt32(ret);
731            return NO_ERROR;
732        } break;
733        case PASSWORD: {
734            CHECK_INTERFACE(IKeystoreService, data, reply);
735            String16 pass = data.readString16();
736            int32_t ret = password(pass);
737            reply->writeNoException();
738            reply->writeInt32(ret);
739            return NO_ERROR;
740        } break;
741        case LOCK: {
742            CHECK_INTERFACE(IKeystoreService, data, reply);
743            int32_t ret = lock();
744            reply->writeNoException();
745            reply->writeInt32(ret);
746            return NO_ERROR;
747        } break;
748        case UNLOCK: {
749            CHECK_INTERFACE(IKeystoreService, data, reply);
750            String16 pass = data.readString16();
751            int32_t ret = unlock(pass);
752            reply->writeNoException();
753            reply->writeInt32(ret);
754            return NO_ERROR;
755        } break;
756        case ZERO: {
757            CHECK_INTERFACE(IKeystoreService, data, reply);
758            int32_t ret = zero();
759            reply->writeNoException();
760            reply->writeInt32(ret);
761            return NO_ERROR;
762        } break;
763        case GENERATE: {
764            CHECK_INTERFACE(IKeystoreService, data, reply);
765            String16 name = data.readString16();
766            int32_t uid = data.readInt32();
767            int32_t keyType = data.readInt32();
768            int32_t keySize = data.readInt32();
769            int32_t flags = data.readInt32();
770            Vector<sp<KeystoreArg> > args;
771            ssize_t numArgs = data.readInt32();
772            if (numArgs > 0) {
773                for (size_t i = 0; i < (size_t) numArgs; i++) {
774                    ssize_t inSize = data.readInt32();
775                    if (inSize >= 0 && (size_t) inSize <= data.dataAvail()) {
776                        sp<KeystoreArg> arg = new KeystoreArg(data.readInplace(inSize), inSize);
777                        args.push_back(arg);
778                    } else {
779                        args.push_back(NULL);
780                    }
781                }
782            }
783            int32_t ret = generate(name, uid, keyType, keySize, flags, &args);
784            reply->writeNoException();
785            reply->writeInt32(ret);
786            return NO_ERROR;
787        } break;
788        case IMPORT: {
789            CHECK_INTERFACE(IKeystoreService, data, reply);
790            String16 name = data.readString16();
791            ssize_t inSize = data.readInt32();
792            const void* in;
793            if (inSize >= 0 && (size_t) inSize <= data.dataAvail()) {
794                in = data.readInplace(inSize);
795            } else {
796                in = NULL;
797                inSize = 0;
798            }
799            int uid = data.readInt32();
800            int32_t flags = data.readInt32();
801            int32_t ret = import(name, (const uint8_t*) in, (size_t) inSize, uid, flags);
802            reply->writeNoException();
803            reply->writeInt32(ret);
804            return NO_ERROR;
805        } break;
806        case SIGN: {
807            CHECK_INTERFACE(IKeystoreService, data, reply);
808            String16 name = data.readString16();
809            ssize_t inSize = data.readInt32();
810            const void* in;
811            if (inSize >= 0 && (size_t) inSize <= data.dataAvail()) {
812                in = data.readInplace(inSize);
813            } else {
814                in = NULL;
815                inSize = 0;
816            }
817            void* out = NULL;
818            size_t outSize = 0;
819            int32_t ret = sign(name, (const uint8_t*) in, (size_t) inSize, (uint8_t**) &out, &outSize);
820            reply->writeNoException();
821            if (outSize > 0 && out != NULL) {
822                reply->writeInt32(outSize);
823                void* buf = reply->writeInplace(outSize);
824                memcpy(buf, out, outSize);
825                free(out);
826            } else {
827                reply->writeInt32(-1);
828            }
829            reply->writeInt32(ret);
830            return NO_ERROR;
831        } break;
832        case VERIFY: {
833            CHECK_INTERFACE(IKeystoreService, data, reply);
834            String16 name = data.readString16();
835            ssize_t inSize = data.readInt32();
836            const void* in;
837            if (inSize >= 0 && (size_t) inSize <= data.dataAvail()) {
838                in = data.readInplace(inSize);
839            } else {
840                in = NULL;
841                inSize = 0;
842            }
843            ssize_t sigSize = data.readInt32();
844            const void* sig;
845            if (sigSize >= 0 && (size_t) sigSize <= data.dataAvail()) {
846                sig = data.readInplace(sigSize);
847            } else {
848                sig = NULL;
849                sigSize = 0;
850            }
851            bool ret = verify(name, (const uint8_t*) in, (size_t) inSize, (const uint8_t*) sig,
852                    (size_t) sigSize);
853            reply->writeNoException();
854            reply->writeInt32(ret ? 1 : 0);
855            return NO_ERROR;
856        } break;
857        case GET_PUBKEY: {
858            CHECK_INTERFACE(IKeystoreService, data, reply);
859            String16 name = data.readString16();
860            void* out = NULL;
861            size_t outSize = 0;
862            int32_t ret = get_pubkey(name, (unsigned char**) &out, &outSize);
863            reply->writeNoException();
864            if (outSize > 0 && out != NULL) {
865                reply->writeInt32(outSize);
866                void* buf = reply->writeInplace(outSize);
867                memcpy(buf, out, outSize);
868                free(out);
869            } else {
870                reply->writeInt32(-1);
871            }
872            reply->writeInt32(ret);
873            return NO_ERROR;
874        } break;
875        case DEL_KEY: {
876            CHECK_INTERFACE(IKeystoreService, data, reply);
877            String16 name = data.readString16();
878            int uid = data.readInt32();
879            int32_t ret = del_key(name, uid);
880            reply->writeNoException();
881            reply->writeInt32(ret);
882            return NO_ERROR;
883        } break;
884        case GRANT: {
885            CHECK_INTERFACE(IKeystoreService, data, reply);
886            String16 name = data.readString16();
887            int32_t granteeUid = data.readInt32();
888            int32_t ret = grant(name, granteeUid);
889            reply->writeNoException();
890            reply->writeInt32(ret);
891            return NO_ERROR;
892        } break;
893        case UNGRANT: {
894            CHECK_INTERFACE(IKeystoreService, data, reply);
895            String16 name = data.readString16();
896            int32_t granteeUid = data.readInt32();
897            int32_t ret = ungrant(name, granteeUid);
898            reply->writeNoException();
899            reply->writeInt32(ret);
900            return NO_ERROR;
901        } break;
902        case GETMTIME: {
903            CHECK_INTERFACE(IKeystoreService, data, reply);
904            String16 name = data.readString16();
905            int64_t ret = getmtime(name);
906            reply->writeNoException();
907            reply->writeInt64(ret);
908            return NO_ERROR;
909        } break;
910        case DUPLICATE: {
911            CHECK_INTERFACE(IKeystoreService, data, reply);
912            String16 srcKey = data.readString16();
913            int32_t srcUid = data.readInt32();
914            String16 destKey = data.readString16();
915            int32_t destUid = data.readInt32();
916            int32_t ret = duplicate(srcKey, srcUid, destKey, destUid);
917            reply->writeNoException();
918            reply->writeInt32(ret);
919            return NO_ERROR;
920        } break;
921        case IS_HARDWARE_BACKED: {
922            CHECK_INTERFACE(IKeystoreService, data, reply);
923            String16 keyType = data.readString16();
924            int32_t ret = is_hardware_backed(keyType);
925            reply->writeNoException();
926            reply->writeInt32(ret);
927            return NO_ERROR;
928        }
929        case CLEAR_UID: {
930            CHECK_INTERFACE(IKeystoreService, data, reply);
931            int64_t uid = data.readInt64();
932            int32_t ret = clear_uid(uid);
933            reply->writeNoException();
934            reply->writeInt32(ret);
935            return NO_ERROR;
936        }
937        case RESET_UID: {
938            CHECK_INTERFACE(IKeystoreService, data, reply);
939            int32_t uid = data.readInt32();
940            int32_t ret = reset_uid(uid);
941            reply->writeNoException();
942            reply->writeInt32(ret);
943            return NO_ERROR;
944        }
945        case SYNC_UID: {
946            CHECK_INTERFACE(IKeystoreService, data, reply);
947            int32_t sourceUid = data.readInt32();
948            int32_t targetUid = data.readInt32();
949            int32_t ret = sync_uid(sourceUid, targetUid);
950            reply->writeNoException();
951            reply->writeInt32(ret);
952            return NO_ERROR;
953        }
954        case PASSWORD_UID: {
955            CHECK_INTERFACE(IKeystoreService, data, reply);
956            String16 password = data.readString16();
957            int32_t uid = data.readInt32();
958            int32_t ret = password_uid(password, uid);
959            reply->writeNoException();
960            reply->writeInt32(ret);
961            return NO_ERROR;
962        }
963        default:
964            return BBinder::onTransact(code, data, reply, flags);
965    }
966}
967
968// ----------------------------------------------------------------------------
969
970}; // namespace android
971