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