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
584IMPLEMENT_META_INTERFACE(KeystoreService, "android.security.keystore");
585
586// ----------------------------------------------------------------------
587
588status_t BnKeystoreService::onTransact(
589    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
590{
591    switch(code) {
592        case TEST: {
593            CHECK_INTERFACE(IKeystoreService, data, reply);
594            int32_t ret = test();
595            reply->writeNoException();
596            reply->writeInt32(ret);
597            return NO_ERROR;
598        } break;
599        case GET: {
600            CHECK_INTERFACE(IKeystoreService, data, reply);
601            String16 name = data.readString16();
602            void* out = NULL;
603            size_t outSize = 0;
604            int32_t ret = get(name, (uint8_t**) &out, &outSize);
605            reply->writeNoException();
606            if (ret == 1) {
607                reply->writeInt32(outSize);
608                void* buf = reply->writeInplace(outSize);
609                memcpy(buf, out, outSize);
610                free(out);
611            } else {
612                reply->writeInt32(-1);
613            }
614            return NO_ERROR;
615        } break;
616        case INSERT: {
617            CHECK_INTERFACE(IKeystoreService, data, reply);
618            String16 name = data.readString16();
619            ssize_t inSize = data.readInt32();
620            const void* in;
621            if (inSize >= 0 && (size_t) inSize <= data.dataAvail()) {
622                in = data.readInplace(inSize);
623            } else {
624                in = NULL;
625                inSize = 0;
626            }
627            int uid = data.readInt32();
628            int32_t flags = data.readInt32();
629            int32_t ret = insert(name, (const uint8_t*) in, (size_t) inSize, uid, flags);
630            reply->writeNoException();
631            reply->writeInt32(ret);
632            return NO_ERROR;
633        } break;
634        case DEL: {
635            CHECK_INTERFACE(IKeystoreService, data, reply);
636            String16 name = data.readString16();
637            int uid = data.readInt32();
638            int32_t ret = del(name, uid);
639            reply->writeNoException();
640            reply->writeInt32(ret);
641            return NO_ERROR;
642        } break;
643        case EXIST: {
644            CHECK_INTERFACE(IKeystoreService, data, reply);
645            String16 name = data.readString16();
646            int uid = data.readInt32();
647            int32_t ret = exist(name, uid);
648            reply->writeNoException();
649            reply->writeInt32(ret);
650            return NO_ERROR;
651        } break;
652        case SAW: {
653            CHECK_INTERFACE(IKeystoreService, data, reply);
654            String16 name = data.readString16();
655            int uid = data.readInt32();
656            Vector<String16> matches;
657            int32_t ret = saw(name, uid, &matches);
658            reply->writeNoException();
659            reply->writeInt32(matches.size());
660            Vector<String16>::const_iterator it = matches.begin();
661            for (; it != matches.end(); ++it) {
662                reply->writeString16(*it);
663            }
664            reply->writeInt32(ret);
665            return NO_ERROR;
666        } break;
667        case RESET: {
668            CHECK_INTERFACE(IKeystoreService, data, reply);
669            int32_t ret = reset();
670            reply->writeNoException();
671            reply->writeInt32(ret);
672            return NO_ERROR;
673        } break;
674        case PASSWORD: {
675            CHECK_INTERFACE(IKeystoreService, data, reply);
676            String16 pass = data.readString16();
677            int32_t ret = password(pass);
678            reply->writeNoException();
679            reply->writeInt32(ret);
680            return NO_ERROR;
681        } break;
682        case LOCK: {
683            CHECK_INTERFACE(IKeystoreService, data, reply);
684            int32_t ret = lock();
685            reply->writeNoException();
686            reply->writeInt32(ret);
687            return NO_ERROR;
688        } break;
689        case UNLOCK: {
690            CHECK_INTERFACE(IKeystoreService, data, reply);
691            String16 pass = data.readString16();
692            int32_t ret = unlock(pass);
693            reply->writeNoException();
694            reply->writeInt32(ret);
695            return NO_ERROR;
696        } break;
697        case ZERO: {
698            CHECK_INTERFACE(IKeystoreService, data, reply);
699            int32_t ret = zero();
700            reply->writeNoException();
701            reply->writeInt32(ret);
702            return NO_ERROR;
703        } break;
704        case GENERATE: {
705            CHECK_INTERFACE(IKeystoreService, data, reply);
706            String16 name = data.readString16();
707            int32_t uid = data.readInt32();
708            int32_t keyType = data.readInt32();
709            int32_t keySize = data.readInt32();
710            int32_t flags = data.readInt32();
711            Vector<sp<KeystoreArg> > args;
712            ssize_t numArgs = data.readInt32();
713            if (numArgs > 0) {
714                for (size_t i = 0; i < (size_t) numArgs; i++) {
715                    ssize_t inSize = data.readInt32();
716                    if (inSize >= 0 && (size_t) inSize <= data.dataAvail()) {
717                        sp<KeystoreArg> arg = new KeystoreArg(data.readInplace(inSize), inSize);
718                        args.push_back(arg);
719                    } else {
720                        args.push_back(NULL);
721                    }
722                }
723            }
724            int32_t ret = generate(name, uid, keyType, keySize, flags, &args);
725            reply->writeNoException();
726            reply->writeInt32(ret);
727            return NO_ERROR;
728        } break;
729        case IMPORT: {
730            CHECK_INTERFACE(IKeystoreService, data, reply);
731            String16 name = data.readString16();
732            ssize_t inSize = data.readInt32();
733            const void* in;
734            if (inSize >= 0 && (size_t) inSize <= data.dataAvail()) {
735                in = data.readInplace(inSize);
736            } else {
737                in = NULL;
738                inSize = 0;
739            }
740            int uid = data.readInt32();
741            int32_t flags = data.readInt32();
742            int32_t ret = import(name, (const uint8_t*) in, (size_t) inSize, uid, flags);
743            reply->writeNoException();
744            reply->writeInt32(ret);
745            return NO_ERROR;
746        } break;
747        case SIGN: {
748            CHECK_INTERFACE(IKeystoreService, data, reply);
749            String16 name = data.readString16();
750            ssize_t inSize = data.readInt32();
751            const void* in;
752            if (inSize >= 0 && (size_t) inSize <= data.dataAvail()) {
753                in = data.readInplace(inSize);
754            } else {
755                in = NULL;
756                inSize = 0;
757            }
758            void* out = NULL;
759            size_t outSize = 0;
760            int32_t ret = sign(name, (const uint8_t*) in, (size_t) inSize, (uint8_t**) &out, &outSize);
761            reply->writeNoException();
762            if (outSize > 0 && out != NULL) {
763                reply->writeInt32(outSize);
764                void* buf = reply->writeInplace(outSize);
765                memcpy(buf, out, outSize);
766                free(out);
767            } else {
768                reply->writeInt32(-1);
769            }
770            reply->writeInt32(ret);
771            return NO_ERROR;
772        } break;
773        case VERIFY: {
774            CHECK_INTERFACE(IKeystoreService, data, reply);
775            String16 name = data.readString16();
776            ssize_t inSize = data.readInt32();
777            const void* in;
778            if (inSize >= 0 && (size_t) inSize <= data.dataAvail()) {
779                in = data.readInplace(inSize);
780            } else {
781                in = NULL;
782                inSize = 0;
783            }
784            ssize_t sigSize = data.readInt32();
785            const void* sig;
786            if (sigSize >= 0 && (size_t) sigSize <= data.dataAvail()) {
787                sig = data.readInplace(sigSize);
788            } else {
789                sig = NULL;
790                sigSize = 0;
791            }
792            bool ret = verify(name, (const uint8_t*) in, (size_t) inSize, (const uint8_t*) sig,
793                    (size_t) sigSize);
794            reply->writeNoException();
795            reply->writeInt32(ret ? 1 : 0);
796            return NO_ERROR;
797        } break;
798        case GET_PUBKEY: {
799            CHECK_INTERFACE(IKeystoreService, data, reply);
800            String16 name = data.readString16();
801            void* out = NULL;
802            size_t outSize = 0;
803            int32_t ret = get_pubkey(name, (unsigned char**) &out, &outSize);
804            reply->writeNoException();
805            if (outSize > 0 && out != NULL) {
806                reply->writeInt32(outSize);
807                void* buf = reply->writeInplace(outSize);
808                memcpy(buf, out, outSize);
809                free(out);
810            } else {
811                reply->writeInt32(-1);
812            }
813            reply->writeInt32(ret);
814            return NO_ERROR;
815        } break;
816        case DEL_KEY: {
817            CHECK_INTERFACE(IKeystoreService, data, reply);
818            String16 name = data.readString16();
819            int uid = data.readInt32();
820            int32_t ret = del_key(name, uid);
821            reply->writeNoException();
822            reply->writeInt32(ret);
823            return NO_ERROR;
824        } break;
825        case GRANT: {
826            CHECK_INTERFACE(IKeystoreService, data, reply);
827            String16 name = data.readString16();
828            int32_t granteeUid = data.readInt32();
829            int32_t ret = grant(name, granteeUid);
830            reply->writeNoException();
831            reply->writeInt32(ret);
832            return NO_ERROR;
833        } break;
834        case UNGRANT: {
835            CHECK_INTERFACE(IKeystoreService, data, reply);
836            String16 name = data.readString16();
837            int32_t granteeUid = data.readInt32();
838            int32_t ret = ungrant(name, granteeUid);
839            reply->writeNoException();
840            reply->writeInt32(ret);
841            return NO_ERROR;
842        } break;
843        case GETMTIME: {
844            CHECK_INTERFACE(IKeystoreService, data, reply);
845            String16 name = data.readString16();
846            int64_t ret = getmtime(name);
847            reply->writeNoException();
848            reply->writeInt64(ret);
849            return NO_ERROR;
850        } break;
851        case DUPLICATE: {
852            CHECK_INTERFACE(IKeystoreService, data, reply);
853            String16 srcKey = data.readString16();
854            int32_t srcUid = data.readInt32();
855            String16 destKey = data.readString16();
856            int32_t destUid = data.readInt32();
857            int32_t ret = duplicate(srcKey, srcUid, destKey, destUid);
858            reply->writeNoException();
859            reply->writeInt32(ret);
860            return NO_ERROR;
861        } break;
862        case IS_HARDWARE_BACKED: {
863            CHECK_INTERFACE(IKeystoreService, data, reply);
864            String16 keyType = data.readString16();
865            int32_t ret = is_hardware_backed(keyType);
866            reply->writeNoException();
867            reply->writeInt32(ret);
868            return NO_ERROR;
869        }
870        case CLEAR_UID: {
871            CHECK_INTERFACE(IKeystoreService, data, reply);
872            int64_t uid = data.readInt64();
873            int32_t ret = clear_uid(uid);
874            reply->writeNoException();
875            reply->writeInt32(ret);
876            return NO_ERROR;
877        }
878        default:
879            return BBinder::onTransact(code, data, reply, flags);
880    }
881}
882
883// ----------------------------------------------------------------------------
884
885}; // namespace android
886