blob: 9b4590e9b826f4146a4f3bd6e25e528bdd9b3289 [file] [log] [blame]
Kenny Root07438c82012-11-02 15:41:02 -07001/*
2**
3** Copyright 2008, The Android Open Source Project
4**
5** Licensed under the Apache License, Version 2.0 (the "License");
6** you may not use this file except in compliance with the License.
7** You may obtain a copy of the License at
8**
9** http://www.apache.org/licenses/LICENSE-2.0
10**
11** Unless required by applicable law or agreed to in writing, software
12** distributed under the License is distributed on an "AS IS" BASIS,
13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14** See the License for the specific language governing permissions and
15** limitations under the License.
16*/
17
18#include <stdint.h>
19#include <sys/types.h>
20
21#define LOG_TAG "KeystoreService"
22#include <utils/Log.h>
23
24#include <binder/Parcel.h>
25#include <binder/IPCThreadState.h>
26#include <binder/IServiceManager.h>
27
28#include <keystore/IKeystoreService.h>
29
30namespace android {
31
32class BpKeystoreService: public BpInterface<IKeystoreService>
33{
34public:
35 BpKeystoreService(const sp<IBinder>& impl)
36 : BpInterface<IKeystoreService>(impl)
37 {
38 }
39
40 // test ping
41 virtual int32_t test()
42 {
43 Parcel data, reply;
44 data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
45 status_t status = remote()->transact(BnKeystoreService::TEST, data, &reply);
46 if (status != NO_ERROR) {
47 ALOGD("test() could not contact remote: %d\n", status);
48 return -1;
49 }
50 int32_t err = reply.readExceptionCode();
51 int32_t ret = reply.readInt32();
52 if (err < 0) {
53 ALOGD("test() caught exception %d\n", err);
54 return -1;
55 }
56 return ret;
57 }
58
59 virtual int32_t get(const String16& name, uint8_t** item, size_t* itemLength)
60 {
61 Parcel data, reply;
62 data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
63 data.writeString16(name);
64 status_t status = remote()->transact(BnKeystoreService::GET, data, &reply);
65 if (status != NO_ERROR) {
66 ALOGD("get() could not contact remote: %d\n", status);
67 return -1;
68 }
69 int32_t err = reply.readExceptionCode();
70 ssize_t len = reply.readInt32();
71 if (len >= 0 && (size_t) len <= reply.dataAvail()) {
72 size_t ulen = (size_t) len;
73 const void* buf = reply.readInplace(ulen);
74 *item = (uint8_t*) malloc(ulen);
75 if (*item != NULL) {
76 memcpy(*item, buf, ulen);
77 *itemLength = ulen;
78 } else {
79 ALOGE("out of memory allocating output array in get");
80 *itemLength = 0;
81 }
82 } else {
83 *itemLength = 0;
84 }
85 if (err < 0) {
86 ALOGD("get() caught exception %d\n", err);
87 return -1;
88 }
89 return 0;
90 }
91
92 virtual int32_t insert(const String16& name, const uint8_t* item, size_t itemLength)
93 {
94 Parcel data, reply;
95 data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
96 data.writeString16(name);
97 data.writeInt32(itemLength);
98 void* buf = data.writeInplace(itemLength);
99 memcpy(buf, item, itemLength);
100 status_t status = remote()->transact(BnKeystoreService::INSERT, data, &reply);
101 if (status != NO_ERROR) {
102 ALOGD("import() could not contact remote: %d\n", status);
103 return -1;
104 }
105 int32_t err = reply.readExceptionCode();
106 int32_t ret = reply.readInt32();
107 if (err < 0) {
108 ALOGD("import() caught exception %d\n", err);
109 return -1;
110 }
111 return ret;
112 }
113
114 virtual int32_t del(const String16& name)
115 {
116 Parcel data, reply;
117 data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
118 data.writeString16(name);
119 status_t status = remote()->transact(BnKeystoreService::DEL, data, &reply);
120 if (status != NO_ERROR) {
121 ALOGD("del() could not contact remote: %d\n", status);
122 return -1;
123 }
124 int32_t err = reply.readExceptionCode();
125 int32_t ret = reply.readInt32();
126 if (err < 0) {
127 ALOGD("del() caught exception %d\n", err);
128 return -1;
129 }
130 return ret;
131 }
132
133 virtual int32_t exist(const String16& name)
134 {
135 Parcel data, reply;
136 data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
137 data.writeString16(name);
138 status_t status = remote()->transact(BnKeystoreService::EXIST, data, &reply);
139 if (status != NO_ERROR) {
140 ALOGD("exist() 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("exist() caught exception %d\n", err);
147 return -1;
148 }
149 return ret;
150 }
151
152 virtual int32_t saw(const String16& name, Vector<String16>* matches)
153 {
154 Parcel data, reply;
155 data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
156 data.writeString16(name);
157 status_t status = remote()->transact(BnKeystoreService::SAW, data, &reply);
158 if (status != NO_ERROR) {
159 ALOGD("saw() could not contact remote: %d\n", status);
160 return -1;
161 }
162 int32_t err = reply.readExceptionCode();
163 int32_t numMatches = reply.readInt32();
164 for (int32_t i = 0; i < numMatches; i++) {
165 matches->push(reply.readString16());
166 }
167 int32_t ret = reply.readInt32();
168 if (err < 0) {
169 ALOGD("saw() caught exception %d\n", err);
170 return -1;
171 }
172 return ret;
173 }
174
175 virtual int32_t reset()
176 {
177 Parcel data, reply;
178 data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
179 status_t status = remote()->transact(BnKeystoreService::RESET, data, &reply);
180 if (status != NO_ERROR) {
181 ALOGD("reset() could not contact remote: %d\n", status);
182 return -1;
183 }
184 int32_t err = reply.readExceptionCode();
185 int32_t ret = reply.readInt32();
186 if (err < 0) {
187 ALOGD("reset() caught exception %d\n", err);
188 return -1;
189 }
190 return ret;
191 }
192
193 virtual int32_t password(const String16& password)
194 {
195 Parcel data, reply;
196 data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
197 data.writeString16(password);
198 status_t status = remote()->transact(BnKeystoreService::PASSWORD, data, &reply);
199 if (status != NO_ERROR) {
200 ALOGD("password() could not contact remote: %d\n", status);
201 return -1;
202 }
203 int32_t err = reply.readExceptionCode();
204 int32_t ret = reply.readInt32();
205 if (err < 0) {
206 ALOGD("password() caught exception %d\n", err);
207 return -1;
208 }
209 return ret;
210 }
211
212 virtual int32_t lock()
213 {
214 Parcel data, reply;
215 data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
216 status_t status = remote()->transact(BnKeystoreService::LOCK, data, &reply);
217 if (status != NO_ERROR) {
218 ALOGD("lock() could not contact remote: %d\n", status);
219 return -1;
220 }
221 int32_t err = reply.readExceptionCode();
222 int32_t ret = reply.readInt32();
223 if (err < 0) {
224 ALOGD("lock() caught exception %d\n", err);
225 return -1;
226 }
227 return ret;
228 }
229
230 virtual int32_t unlock(const String16& password)
231 {
232 Parcel data, reply;
233 data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
234 data.writeString16(password);
235 status_t status = remote()->transact(BnKeystoreService::UNLOCK, data, &reply);
236 if (status != NO_ERROR) {
237 ALOGD("unlock() could not contact remote: %d\n", status);
238 return -1;
239 }
240 int32_t err = reply.readExceptionCode();
241 int32_t ret = reply.readInt32();
242 if (err < 0) {
243 ALOGD("unlock() caught exception %d\n", err);
244 return -1;
245 }
246 return ret;
247 }
248
249 virtual int32_t zero()
250 {
251 Parcel data, reply;
252 data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
253 status_t status = remote()->transact(BnKeystoreService::ZERO, data, &reply);
254 if (status != NO_ERROR) {
255 ALOGD("zero() could not contact remote: %d\n", status);
256 return -1;
257 }
258 int32_t err = reply.readExceptionCode();
259 int32_t ret = reply.readInt32();
260 if (err < 0) {
261 ALOGD("zero() caught exception %d\n", err);
262 return -1;
263 }
264 return ret;
265 }
266
267 virtual int32_t generate(const String16& name)
268 {
269 Parcel data, reply;
270 data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
271 data.writeString16(name);
272 status_t status = remote()->transact(BnKeystoreService::GENERATE, data, &reply);
273 if (status != NO_ERROR) {
274 ALOGD("generate() could not contact remote: %d\n", status);
275 return -1;
276 }
277 int32_t err = reply.readExceptionCode();
278 int32_t ret = reply.readInt32();
279 if (err < 0) {
280 ALOGD("generate() caught exception %d\n", err);
281 return -1;
282 }
283 return ret;
284 }
285
286 virtual int32_t import(const String16& name, const uint8_t* key, size_t keyLength)
287 {
288 Parcel data, reply;
289 data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
290 data.writeString16(name);
291 data.writeInt32(keyLength);
292 void* buf = data.writeInplace(keyLength);
293 memcpy(buf, key, keyLength);
294 status_t status = remote()->transact(BnKeystoreService::IMPORT, data, &reply);
295 if (status != NO_ERROR) {
296 ALOGD("import() could not contact remote: %d\n", status);
297 return -1;
298 }
299 int32_t err = reply.readExceptionCode();
300 int32_t ret = reply.readInt32();
301 if (err < 0) {
302 ALOGD("import() caught exception %d\n", err);
303 return -1;
304 }
305 return ret;
306 }
307
308 virtual int32_t sign(const String16& name, const uint8_t* in, size_t inLength, uint8_t** out,
309 size_t* outLength)
310 {
311 Parcel data, reply;
312 data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
313 data.writeString16(name);
314 data.writeInt32(inLength);
315 void* buf = data.writeInplace(inLength);
316 memcpy(buf, in, inLength);
317 status_t status = remote()->transact(BnKeystoreService::SIGN, data, &reply);
318 if (status != NO_ERROR) {
319 ALOGD("import() could not contact remote: %d\n", status);
320 return -1;
321 }
322 int32_t err = reply.readExceptionCode();
323 ssize_t len = reply.readInt32();
324 if (len >= 0 && (size_t) len <= reply.dataAvail()) {
325 size_t ulen = (size_t) len;
326 const void* outBuf = reply.readInplace(ulen);
327 *out = (uint8_t*) malloc(ulen);
328 if (*out != NULL) {
329 memcpy((void*) *out, outBuf, ulen);
330 *outLength = ulen;
331 } else {
332 ALOGE("out of memory allocating output array in sign");
333 *outLength = 0;
334 }
335 } else {
336 *outLength = 0;
337 }
338 if (err < 0) {
339 ALOGD("import() caught exception %d\n", err);
340 return -1;
341 }
342 return 0;
343 }
344
345 virtual int32_t verify(const String16& name, const uint8_t* in, size_t inLength,
346 const uint8_t* signature, size_t signatureLength)
347 {
348 Parcel data, reply;
349 void* buf;
350
351 data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
352 data.writeString16(name);
353 data.writeInt32(inLength);
354 buf = data.writeInplace(inLength);
355 memcpy(buf, in, inLength);
356 data.writeInt32(signatureLength);
357 buf = data.writeInplace(signatureLength);
358 memcpy(buf, signature, signatureLength);
359 status_t status = remote()->transact(BnKeystoreService::VERIFY, data, &reply);
360 if (status != NO_ERROR) {
361 ALOGD("verify() could not contact remote: %d\n", status);
362 return -1;
363 }
364 int32_t err = reply.readExceptionCode();
365 int32_t ret = reply.readInt32();
366 if (err < 0) {
367 ALOGD("verify() caught exception %d\n", err);
368 return -1;
369 }
370 return ret;
371 }
372
373 virtual int32_t get_pubkey(const String16& name, uint8_t** pubkey, size_t* pubkeyLength)
374 {
375 Parcel data, reply;
376 data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
377 data.writeString16(name);
378 status_t status = remote()->transact(BnKeystoreService::GET_PUBKEY, data, &reply);
379 if (status != NO_ERROR) {
380 ALOGD("get_pubkey() could not contact remote: %d\n", status);
381 return -1;
382 }
383 int32_t err = reply.readExceptionCode();
384 ssize_t len = reply.readInt32();
385 if (len >= 0 && (size_t) len <= reply.dataAvail()) {
386 size_t ulen = (size_t) len;
387 const void* buf = reply.readInplace(ulen);
388 *pubkey = (uint8_t*) malloc(ulen);
389 if (*pubkey != NULL) {
390 memcpy(*pubkey, buf, ulen);
391 *pubkeyLength = ulen;
392 } else {
393 ALOGE("out of memory allocating output array in get_pubkey");
394 *pubkeyLength = 0;
395 }
396 } else {
397 *pubkeyLength = 0;
398 }
399 if (err < 0) {
400 ALOGD("get_pubkey() caught exception %d\n", err);
401 return -1;
402 }
403 return 0;
404 }
405
406 virtual int32_t del_key(const String16& name)
407 {
408 Parcel data, reply;
409 data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
410 data.writeString16(name);
411 status_t status = remote()->transact(BnKeystoreService::DEL_KEY, data, &reply);
412 if (status != NO_ERROR) {
413 ALOGD("del_key() could not contact remote: %d\n", status);
414 return -1;
415 }
416 int32_t err = reply.readExceptionCode();
417 int32_t ret = reply.readInt32();
418 if (err < 0) {
419 ALOGD("del_key() caught exception %d\n", err);
420 return -1;
421 }
422 return ret;
423 }
424
425 virtual int32_t grant(const String16& name, int32_t granteeUid)
426 {
427 Parcel data, reply;
428 data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
429 data.writeString16(name);
430 data.writeInt32(granteeUid);
431 status_t status = remote()->transact(BnKeystoreService::GRANT, data, &reply);
432 if (status != NO_ERROR) {
433 ALOGD("grant() could not contact remote: %d\n", status);
434 return -1;
435 }
436 int32_t err = reply.readExceptionCode();
437 int32_t ret = reply.readInt32();
438 if (err < 0) {
439 ALOGD("grant() caught exception %d\n", err);
440 return -1;
441 }
442 return ret;
443 }
444
445 virtual int32_t ungrant(const String16& name, int32_t granteeUid)
446 {
447 Parcel data, reply;
448 data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
449 data.writeString16(name);
450 data.writeInt32(granteeUid);
451 status_t status = remote()->transact(BnKeystoreService::UNGRANT, data, &reply);
452 if (status != NO_ERROR) {
453 ALOGD("ungrant() 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("ungrant() caught exception %d\n", err);
460 return -1;
461 }
462 return ret;
463 }
464
465 int64_t getmtime(const String16& name)
466 {
467 Parcel data, reply;
468 data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
469 data.writeString16(name);
470 status_t status = remote()->transact(BnKeystoreService::GETMTIME, data, &reply);
471 if (status != NO_ERROR) {
472 ALOGD("getmtime() could not contact remote: %d\n", status);
473 return -1;
474 }
475 int32_t err = reply.readExceptionCode();
476 int64_t ret = reply.readInt64();
477 if (err < 0) {
478 ALOGD("getmtime() caught exception %d\n", err);
479 return -1;
480 }
481 return ret;
482 }
483};
484
485IMPLEMENT_META_INTERFACE(KeystoreService, "android.security.keystore");
486
487// ----------------------------------------------------------------------
488
489status_t BnKeystoreService::onTransact(
490 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
491{
492 switch(code) {
493 case TEST: {
494 CHECK_INTERFACE(IKeystoreService, data, reply);
495 int32_t ret = test();
496 reply->writeNoException();
497 reply->writeInt32(ret);
498 return NO_ERROR;
499 } break;
500 case GET: {
501 CHECK_INTERFACE(IKeystoreService, data, reply);
502 String16 name = data.readString16();
503 void* out = NULL;
504 size_t outSize = 0;
505 int32_t ret = get(name, (uint8_t**) &out, &outSize);
506 reply->writeNoException();
507 if (ret == 1) {
508 reply->writeInt32(outSize);
509 void* buf = reply->writeInplace(outSize);
510 memcpy(buf, out, outSize);
511 free(out);
512 } else {
513 reply->writeInt32(-1);
514 }
515 return NO_ERROR;
516 } break;
517 case INSERT: {
518 CHECK_INTERFACE(IKeystoreService, data, reply);
519 String16 name = data.readString16();
520 ssize_t inSize = data.readInt32();
521 const void* in;
522 if (inSize >= 0 && (size_t) inSize <= data.dataAvail()) {
523 in = data.readInplace(inSize);
524 } else {
525 in = NULL;
526 inSize = 0;
527 }
528 int32_t ret = insert(name, (const uint8_t*) in, (size_t) inSize);
529 reply->writeNoException();
530 reply->writeInt32(ret);
531 return NO_ERROR;
532 } break;
533 case DEL: {
534 CHECK_INTERFACE(IKeystoreService, data, reply);
535 String16 name = data.readString16();
536 int32_t ret = del(name);
537 reply->writeNoException();
538 reply->writeInt32(ret);
539 return NO_ERROR;
540 } break;
541 case EXIST: {
542 CHECK_INTERFACE(IKeystoreService, data, reply);
543 String16 name = data.readString16();
544 int32_t ret = exist(name);
545 reply->writeNoException();
546 reply->writeInt32(ret);
547 return NO_ERROR;
548 } break;
549 case SAW: {
550 CHECK_INTERFACE(IKeystoreService, data, reply);
551 String16 name = data.readString16();
552 Vector<String16> matches;
553 int32_t ret = saw(name, &matches);
554 reply->writeNoException();
555 reply->writeInt32(matches.size());
556 Vector<String16>::const_iterator it = matches.begin();
557 for (; it != matches.end(); ++it) {
558 reply->writeString16(*it);
559 }
560 reply->writeInt32(ret);
561 return NO_ERROR;
562 } break;
563 case RESET: {
564 CHECK_INTERFACE(IKeystoreService, data, reply);
565 int32_t ret = reset();
566 reply->writeNoException();
567 reply->writeInt32(ret);
568 return NO_ERROR;
569 } break;
570 case PASSWORD: {
571 CHECK_INTERFACE(IKeystoreService, data, reply);
572 String16 pass = data.readString16();
573 int32_t ret = password(pass);
574 reply->writeNoException();
575 reply->writeInt32(ret);
576 return NO_ERROR;
577 } break;
578 case LOCK: {
579 CHECK_INTERFACE(IKeystoreService, data, reply);
580 int32_t ret = lock();
581 reply->writeNoException();
582 reply->writeInt32(ret);
583 return NO_ERROR;
584 } break;
585 case UNLOCK: {
586 CHECK_INTERFACE(IKeystoreService, data, reply);
587 String16 pass = data.readString16();
588 int32_t ret = unlock(pass);
589 reply->writeNoException();
590 reply->writeInt32(ret);
591 return NO_ERROR;
592 } break;
593 case ZERO: {
594 CHECK_INTERFACE(IKeystoreService, data, reply);
595 int32_t ret = zero();
596 reply->writeNoException();
597 reply->writeInt32(ret);
598 return NO_ERROR;
599 } break;
600 case GENERATE: {
601 CHECK_INTERFACE(IKeystoreService, data, reply);
602 String16 name = data.readString16();
603 int32_t ret = generate(name);
604 reply->writeNoException();
605 reply->writeInt32(ret);
606 return NO_ERROR;
607 } break;
608 case IMPORT: {
609 CHECK_INTERFACE(IKeystoreService, data, reply);
610 String16 name = data.readString16();
611 ssize_t inSize = data.readInt32();
612 const void* in;
613 if (inSize >= 0 && (size_t) inSize <= data.dataAvail()) {
614 in = data.readInplace(inSize);
615 } else {
616 in = NULL;
617 inSize = 0;
618 }
619 int32_t ret = import(name, (const uint8_t*) in, (size_t) inSize);
620 reply->writeNoException();
621 reply->writeInt32(ret);
622 return NO_ERROR;
623 } break;
624 case SIGN: {
625 CHECK_INTERFACE(IKeystoreService, data, reply);
626 String16 name = data.readString16();
627 ssize_t inSize = data.readInt32();
628 const void* in;
629 if (inSize >= 0 && (size_t) inSize <= data.dataAvail()) {
630 in = data.readInplace(inSize);
631 } else {
632 in = NULL;
633 inSize = 0;
634 }
635 void* out = NULL;
636 size_t outSize = 0;
637 int32_t ret = sign(name, (const uint8_t*) in, (size_t) inSize, (uint8_t**) &out, &outSize);
638 reply->writeNoException();
639 reply->writeInt32(outSize);
640 void* buf = reply->writeInplace(outSize);
641 memcpy(buf, out, outSize);
642 free(out);
643 reply->writeInt32(ret);
644 return NO_ERROR;
645 } break;
646 case VERIFY: {
647 CHECK_INTERFACE(IKeystoreService, data, reply);
648 String16 name = data.readString16();
649 ssize_t inSize = data.readInt32();
650 const void* in;
651 if (inSize >= 0 && (size_t) inSize <= data.dataAvail()) {
652 in = data.readInplace(inSize);
653 } else {
654 in = NULL;
655 inSize = 0;
656 }
657 ssize_t sigSize = data.readInt32();
658 const void* sig;
659 if (sigSize >= 0 && (size_t) sigSize <= data.dataAvail()) {
660 sig = data.readInplace(sigSize);
661 } else {
662 sig = NULL;
663 sigSize = 0;
664 }
665 bool ret = verify(name, (const uint8_t*) in, (size_t) inSize, (const uint8_t*) sig,
666 (size_t) sigSize);
667 reply->writeNoException();
668 reply->writeInt32(ret ? 1 : 0);
669 return NO_ERROR;
670 } break;
671 case GET_PUBKEY: {
672 CHECK_INTERFACE(IKeystoreService, data, reply);
673 String16 name = data.readString16();
674 void* out = NULL;
675 size_t outSize = 0;
676 int32_t ret = get_pubkey(name, (unsigned char**) &out, &outSize);
677 reply->writeNoException();
678 reply->writeInt32(outSize);
679 void* buf = reply->writeInplace(outSize);
680 memcpy(buf, out, outSize);
681 free(out);
682 reply->writeInt32(ret);
683 return NO_ERROR;
684 }
685 case DEL_KEY: {
686 CHECK_INTERFACE(IKeystoreService, data, reply);
687 String16 name = data.readString16();
688 int32_t ret = del_key(name);
689 reply->writeNoException();
690 reply->writeInt32(ret);
691 return NO_ERROR;
692 } break;
693 case GRANT: {
694 CHECK_INTERFACE(IKeystoreService, data, reply);
695 String16 name = data.readString16();
696 int32_t granteeUid = data.readInt32();
697 int32_t ret = grant(name, granteeUid);
698 reply->writeNoException();
699 reply->writeInt32(ret);
700 return NO_ERROR;
701 } break;
702 case UNGRANT: {
703 CHECK_INTERFACE(IKeystoreService, data, reply);
704 String16 name = data.readString16();
705 int32_t granteeUid = data.readInt32();
706 int32_t ret = ungrant(name, granteeUid);
707 reply->writeNoException();
708 reply->writeInt32(ret);
709 return NO_ERROR;
710 } break;
711 case GETMTIME: {
712 CHECK_INTERFACE(IKeystoreService, data, reply);
713 String16 name = data.readString16();
714 int64_t ret = getmtime(name);
715 reply->writeNoException();
716 reply->writeInt64(ret);
717 return NO_ERROR;
718 } break;
719 default:
720 return BBinder::onTransact(code, data, reply, flags);
721 }
722}
723
724// ----------------------------------------------------------------------------
725
726}; // namespace android