1 /*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 //#define LOG_NDEBUG 0
18 #define LOG_TAG "IDrm"
19 #include <utils/Log.h>
20
21 #include <binder/Parcel.h>
22 #include <media/IDrm.h>
23 #include <media/stagefright/MediaErrors.h>
24 #include <media/stagefright/foundation/ADebug.h>
25 #include <media/stagefright/foundation/AString.h>
26
27 namespace android {
28
29 enum {
30 INIT_CHECK = IBinder::FIRST_CALL_TRANSACTION,
31 IS_CRYPTO_SUPPORTED,
32 CREATE_PLUGIN,
33 DESTROY_PLUGIN,
34 OPEN_SESSION,
35 CLOSE_SESSION,
36 GET_KEY_REQUEST,
37 PROVIDE_KEY_RESPONSE,
38 REMOVE_KEYS,
39 RESTORE_KEYS,
40 QUERY_KEY_STATUS,
41 GET_PROVISION_REQUEST,
42 PROVIDE_PROVISION_RESPONSE,
43 GET_SECURE_STOPS,
44 RELEASE_SECURE_STOPS,
45 GET_PROPERTY_STRING,
46 GET_PROPERTY_BYTE_ARRAY,
47 SET_PROPERTY_STRING,
48 SET_PROPERTY_BYTE_ARRAY,
49 SET_CIPHER_ALGORITHM,
50 SET_MAC_ALGORITHM,
51 ENCRYPT,
52 DECRYPT,
53 SIGN,
54 SIGN_RSA,
55 VERIFY,
56 SET_LISTENER,
57 GET_SECURE_STOP,
58 RELEASE_ALL_SECURE_STOPS
59 };
60
61 struct BpDrm : public BpInterface<IDrm> {
BpDrmandroid::BpDrm62 explicit BpDrm(const sp<IBinder> &impl)
63 : BpInterface<IDrm>(impl) {
64 }
65
initCheckandroid::BpDrm66 virtual status_t initCheck() const {
67 Parcel data, reply;
68 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
69 status_t status = remote()->transact(INIT_CHECK, data, &reply);
70 if (status != OK) {
71 return status;
72 }
73
74 return reply.readInt32();
75 }
76
isCryptoSchemeSupportedandroid::BpDrm77 virtual bool isCryptoSchemeSupported(const uint8_t uuid[16], const String8 &mimeType) {
78 Parcel data, reply;
79 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
80 data.write(uuid, 16);
81 data.writeString8(mimeType);
82 status_t status = remote()->transact(IS_CRYPTO_SUPPORTED, data, &reply);
83 if (status != OK) {
84 ALOGE("isCryptoSchemeSupported: binder call failed: %d", status);
85 return false;
86 }
87
88 return reply.readInt32() != 0;
89 }
90
createPluginandroid::BpDrm91 virtual status_t createPlugin(const uint8_t uuid[16],
92 const String8& appPackageName) {
93 Parcel data, reply;
94 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
95 data.write(uuid, 16);
96 data.writeString8(appPackageName);
97 status_t status = remote()->transact(CREATE_PLUGIN, data, &reply);
98 if (status != OK) {
99 ALOGE("createPlugin: binder call failed: %d", status);
100 return status;
101 }
102
103 return reply.readInt32();
104 }
105
destroyPluginandroid::BpDrm106 virtual status_t destroyPlugin() {
107 Parcel data, reply;
108 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
109 status_t status = remote()->transact(DESTROY_PLUGIN, data, &reply);
110 if (status != OK) {
111 return status;
112 }
113
114 return reply.readInt32();
115 }
116
openSessionandroid::BpDrm117 virtual status_t openSession(Vector<uint8_t> &sessionId) {
118 Parcel data, reply;
119 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
120
121 status_t status = remote()->transact(OPEN_SESSION, data, &reply);
122 if (status != OK) {
123 return status;
124 }
125 readVector(reply, sessionId);
126
127 return reply.readInt32();
128 }
129
closeSessionandroid::BpDrm130 virtual status_t closeSession(Vector<uint8_t> const &sessionId) {
131 Parcel data, reply;
132 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
133
134 writeVector(data, sessionId);
135 status_t status = remote()->transact(CLOSE_SESSION, data, &reply);
136 if (status != OK) {
137 return status;
138 }
139
140 return reply.readInt32();
141 }
142
143 virtual status_t
getKeyRequestandroid::BpDrm144 getKeyRequest(Vector<uint8_t> const &sessionId,
145 Vector<uint8_t> const &initData,
146 String8 const &mimeType, DrmPlugin::KeyType keyType,
147 KeyedVector<String8, String8> const &optionalParameters,
148 Vector<uint8_t> &request, String8 &defaultUrl,
149 DrmPlugin::KeyRequestType *keyRequestType) {
150 Parcel data, reply;
151 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
152
153 writeVector(data, sessionId);
154 writeVector(data, initData);
155 data.writeString8(mimeType);
156 data.writeInt32((uint32_t)keyType);
157
158 data.writeInt32(optionalParameters.size());
159 for (size_t i = 0; i < optionalParameters.size(); ++i) {
160 data.writeString8(optionalParameters.keyAt(i));
161 data.writeString8(optionalParameters.valueAt(i));
162 }
163
164 status_t status = remote()->transact(GET_KEY_REQUEST, data, &reply);
165 if (status != OK) {
166 return status;
167 }
168
169 readVector(reply, request);
170 defaultUrl = reply.readString8();
171 *keyRequestType = static_cast<DrmPlugin::KeyRequestType>(reply.readInt32());
172
173 return reply.readInt32();
174 }
175
provideKeyResponseandroid::BpDrm176 virtual status_t provideKeyResponse(Vector<uint8_t> const &sessionId,
177 Vector<uint8_t> const &response,
178 Vector<uint8_t> &keySetId) {
179 Parcel data, reply;
180 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
181 writeVector(data, sessionId);
182 writeVector(data, response);
183
184 status_t status = remote()->transact(PROVIDE_KEY_RESPONSE, data, &reply);
185 if (status != OK) {
186 return status;
187 }
188
189 readVector(reply, keySetId);
190
191 return reply.readInt32();
192 }
193
removeKeysandroid::BpDrm194 virtual status_t removeKeys(Vector<uint8_t> const &keySetId) {
195 Parcel data, reply;
196 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
197
198 writeVector(data, keySetId);
199 status_t status = remote()->transact(REMOVE_KEYS, data, &reply);
200 if (status != OK) {
201 return status;
202 }
203
204 return reply.readInt32();
205 }
206
restoreKeysandroid::BpDrm207 virtual status_t restoreKeys(Vector<uint8_t> const &sessionId,
208 Vector<uint8_t> const &keySetId) {
209 Parcel data, reply;
210 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
211
212 writeVector(data, sessionId);
213 writeVector(data, keySetId);
214 status_t status = remote()->transact(RESTORE_KEYS, data, &reply);
215 if (status != OK) {
216 return status;
217 }
218
219 return reply.readInt32();
220 }
221
queryKeyStatusandroid::BpDrm222 virtual status_t queryKeyStatus(Vector<uint8_t> const &sessionId,
223 KeyedVector<String8, String8> &infoMap) const {
224 Parcel data, reply;
225 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
226
227 writeVector(data, sessionId);
228 status_t status = remote()->transact(QUERY_KEY_STATUS, data, &reply);
229 if (status != OK) {
230 return status;
231 }
232
233 infoMap.clear();
234 size_t count = reply.readInt32();
235 for (size_t i = 0; i < count; i++) {
236 String8 key = reply.readString8();
237 String8 value = reply.readString8();
238 infoMap.add(key, value);
239 }
240 return reply.readInt32();
241 }
242
getProvisionRequestandroid::BpDrm243 virtual status_t getProvisionRequest(String8 const &certType,
244 String8 const &certAuthority,
245 Vector<uint8_t> &request,
246 String8 &defaultUrl) {
247 Parcel data, reply;
248 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
249
250 data.writeString8(certType);
251 data.writeString8(certAuthority);
252 status_t status = remote()->transact(GET_PROVISION_REQUEST, data, &reply);
253 if (status != OK) {
254 return status;
255 }
256
257 readVector(reply, request);
258 defaultUrl = reply.readString8();
259
260 return reply.readInt32();
261 }
262
provideProvisionResponseandroid::BpDrm263 virtual status_t provideProvisionResponse(Vector<uint8_t> const &response,
264 Vector<uint8_t> &certificate,
265 Vector<uint8_t> &wrappedKey) {
266 Parcel data, reply;
267 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
268
269 writeVector(data, response);
270 status_t status = remote()->transact(PROVIDE_PROVISION_RESPONSE, data, &reply);
271 if (status != OK) {
272 return status;
273 }
274
275 readVector(reply, certificate);
276 readVector(reply, wrappedKey);
277
278 return reply.readInt32();
279 }
280
getSecureStopsandroid::BpDrm281 virtual status_t getSecureStops(List<Vector<uint8_t> > &secureStops) {
282 Parcel data, reply;
283 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
284
285 status_t status = remote()->transact(GET_SECURE_STOPS, data, &reply);
286 if (status != OK) {
287 return status;
288 }
289
290 secureStops.clear();
291 uint32_t count = reply.readInt32();
292 for (size_t i = 0; i < count; i++) {
293 Vector<uint8_t> secureStop;
294 readVector(reply, secureStop);
295 secureStops.push_back(secureStop);
296 }
297 return reply.readInt32();
298 }
299
getSecureStopandroid::BpDrm300 virtual status_t getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
301 Parcel data, reply;
302 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
303
304 writeVector(data, ssid);
305 status_t status = remote()->transact(GET_SECURE_STOP, data, &reply);
306 if (status != OK) {
307 return status;
308 }
309
310 readVector(reply, secureStop);
311 return reply.readInt32();
312 }
313
releaseSecureStopsandroid::BpDrm314 virtual status_t releaseSecureStops(Vector<uint8_t> const &ssRelease) {
315 Parcel data, reply;
316 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
317
318 writeVector(data, ssRelease);
319 status_t status = remote()->transact(RELEASE_SECURE_STOPS, data, &reply);
320 if (status != OK) {
321 return status;
322 }
323
324 return reply.readInt32();
325 }
326
releaseAllSecureStopsandroid::BpDrm327 virtual status_t releaseAllSecureStops() {
328 Parcel data, reply;
329 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
330
331 status_t status = remote()->transact(RELEASE_ALL_SECURE_STOPS, data, &reply);
332 if (status != OK) {
333 return status;
334 }
335
336 return reply.readInt32();
337 }
338
getPropertyStringandroid::BpDrm339 virtual status_t getPropertyString(String8 const &name, String8 &value) const {
340 Parcel data, reply;
341 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
342
343 data.writeString8(name);
344 status_t status = remote()->transact(GET_PROPERTY_STRING, data, &reply);
345 if (status != OK) {
346 return status;
347 }
348
349 value = reply.readString8();
350 return reply.readInt32();
351 }
352
getPropertyByteArrayandroid::BpDrm353 virtual status_t getPropertyByteArray(String8 const &name, Vector<uint8_t> &value) const {
354 Parcel data, reply;
355 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
356
357 data.writeString8(name);
358 status_t status = remote()->transact(GET_PROPERTY_BYTE_ARRAY, data, &reply);
359 if (status != OK) {
360 return status;
361 }
362
363 readVector(reply, value);
364 return reply.readInt32();
365 }
366
setPropertyStringandroid::BpDrm367 virtual status_t setPropertyString(String8 const &name, String8 const &value) const {
368 Parcel data, reply;
369 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
370
371 data.writeString8(name);
372 data.writeString8(value);
373 status_t status = remote()->transact(SET_PROPERTY_STRING, data, &reply);
374 if (status != OK) {
375 return status;
376 }
377
378 return reply.readInt32();
379 }
380
setPropertyByteArrayandroid::BpDrm381 virtual status_t setPropertyByteArray(String8 const &name,
382 Vector<uint8_t> const &value) const {
383 Parcel data, reply;
384 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
385
386 data.writeString8(name);
387 writeVector(data, value);
388 status_t status = remote()->transact(SET_PROPERTY_BYTE_ARRAY, data, &reply);
389 if (status != OK) {
390 return status;
391 }
392
393 return reply.readInt32();
394 }
395
396
setCipherAlgorithmandroid::BpDrm397 virtual status_t setCipherAlgorithm(Vector<uint8_t> const &sessionId,
398 String8 const &algorithm) {
399 Parcel data, reply;
400 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
401
402 writeVector(data, sessionId);
403 data.writeString8(algorithm);
404 status_t status = remote()->transact(SET_CIPHER_ALGORITHM, data, &reply);
405 if (status != OK) {
406 return status;
407 }
408 return reply.readInt32();
409 }
410
setMacAlgorithmandroid::BpDrm411 virtual status_t setMacAlgorithm(Vector<uint8_t> const &sessionId,
412 String8 const &algorithm) {
413 Parcel data, reply;
414 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
415
416 writeVector(data, sessionId);
417 data.writeString8(algorithm);
418 status_t status = remote()->transact(SET_MAC_ALGORITHM, data, &reply);
419 if (status != OK) {
420 return status;
421 }
422 return reply.readInt32();
423 }
424
encryptandroid::BpDrm425 virtual status_t encrypt(Vector<uint8_t> const &sessionId,
426 Vector<uint8_t> const &keyId,
427 Vector<uint8_t> const &input,
428 Vector<uint8_t> const &iv,
429 Vector<uint8_t> &output) {
430 Parcel data, reply;
431 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
432
433 writeVector(data, sessionId);
434 writeVector(data, keyId);
435 writeVector(data, input);
436 writeVector(data, iv);
437
438 status_t status = remote()->transact(ENCRYPT, data, &reply);
439 if (status != OK) {
440 return status;
441 }
442 readVector(reply, output);
443
444 return reply.readInt32();
445 }
446
decryptandroid::BpDrm447 virtual status_t decrypt(Vector<uint8_t> const &sessionId,
448 Vector<uint8_t> const &keyId,
449 Vector<uint8_t> const &input,
450 Vector<uint8_t> const &iv,
451 Vector<uint8_t> &output) {
452 Parcel data, reply;
453 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
454
455 writeVector(data, sessionId);
456 writeVector(data, keyId);
457 writeVector(data, input);
458 writeVector(data, iv);
459
460 status_t status = remote()->transact(DECRYPT, data, &reply);
461 if (status != OK) {
462 return status;
463 }
464 readVector(reply, output);
465
466 return reply.readInt32();
467 }
468
signandroid::BpDrm469 virtual status_t sign(Vector<uint8_t> const &sessionId,
470 Vector<uint8_t> const &keyId,
471 Vector<uint8_t> const &message,
472 Vector<uint8_t> &signature) {
473 Parcel data, reply;
474 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
475
476 writeVector(data, sessionId);
477 writeVector(data, keyId);
478 writeVector(data, message);
479
480 status_t status = remote()->transact(SIGN, data, &reply);
481 if (status != OK) {
482 return status;
483 }
484 readVector(reply, signature);
485
486 return reply.readInt32();
487 }
488
verifyandroid::BpDrm489 virtual status_t verify(Vector<uint8_t> const &sessionId,
490 Vector<uint8_t> const &keyId,
491 Vector<uint8_t> const &message,
492 Vector<uint8_t> const &signature,
493 bool &match) {
494 Parcel data, reply;
495 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
496
497 writeVector(data, sessionId);
498 writeVector(data, keyId);
499 writeVector(data, message);
500 writeVector(data, signature);
501
502 status_t status = remote()->transact(VERIFY, data, &reply);
503 if (status != OK) {
504 return status;
505 }
506 match = (bool)reply.readInt32();
507 return reply.readInt32();
508 }
509
signRSAandroid::BpDrm510 virtual status_t signRSA(Vector<uint8_t> const &sessionId,
511 String8 const &algorithm,
512 Vector<uint8_t> const &message,
513 Vector<uint8_t> const &wrappedKey,
514 Vector<uint8_t> &signature) {
515 Parcel data, reply;
516 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
517
518 writeVector(data, sessionId);
519 data.writeString8(algorithm);
520 writeVector(data, message);
521 writeVector(data, wrappedKey);
522
523 status_t status = remote()->transact(SIGN_RSA, data, &reply);
524 if (status != OK) {
525 return status;
526 }
527 readVector(reply, signature);
528
529 return reply.readInt32();
530 }
531
setListenerandroid::BpDrm532 virtual status_t setListener(const sp<IDrmClient>& listener) {
533 Parcel data, reply;
534 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
535 data.writeStrongBinder(IInterface::asBinder(listener));
536 status_t status = remote()->transact(SET_LISTENER, data, &reply);
537 if (status != OK) {
538 return status;
539 }
540 return reply.readInt32();
541 }
542
543 private:
readVectorandroid::BpDrm544 void readVector(Parcel &reply, Vector<uint8_t> &vector) const {
545 uint32_t size = reply.readInt32();
546 vector.insertAt((size_t)0, size);
547 reply.read(vector.editArray(), size);
548 }
549
writeVectorandroid::BpDrm550 void writeVector(Parcel &data, Vector<uint8_t> const &vector) const {
551 data.writeInt32(vector.size());
552 data.write(vector.array(), vector.size());
553 }
554
555 DISALLOW_EVIL_CONSTRUCTORS(BpDrm);
556 };
557
558 IMPLEMENT_META_INTERFACE(Drm, "android.drm.IDrm");
559
560 ////////////////////////////////////////////////////////////////////////////////
561
readVector(const Parcel & data,Vector<uint8_t> & vector) const562 void BnDrm::readVector(const Parcel &data, Vector<uint8_t> &vector) const {
563 uint32_t size = data.readInt32();
564 vector.insertAt((size_t)0, size);
565 data.read(vector.editArray(), size);
566 }
567
writeVector(Parcel * reply,Vector<uint8_t> const & vector) const568 void BnDrm::writeVector(Parcel *reply, Vector<uint8_t> const &vector) const {
569 reply->writeInt32(vector.size());
570 reply->write(vector.array(), vector.size());
571 }
572
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)573 status_t BnDrm::onTransact(
574 uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
575 switch (code) {
576 case INIT_CHECK:
577 {
578 CHECK_INTERFACE(IDrm, data, reply);
579 reply->writeInt32(initCheck());
580 return OK;
581 }
582
583 case IS_CRYPTO_SUPPORTED:
584 {
585 CHECK_INTERFACE(IDrm, data, reply);
586 uint8_t uuid[16];
587 data.read(uuid, sizeof(uuid));
588 String8 mimeType = data.readString8();
589 reply->writeInt32(isCryptoSchemeSupported(uuid, mimeType));
590 return OK;
591 }
592
593 case CREATE_PLUGIN:
594 {
595 CHECK_INTERFACE(IDrm, data, reply);
596 uint8_t uuid[16];
597 data.read(uuid, sizeof(uuid));
598 String8 appPackageName = data.readString8();
599 reply->writeInt32(createPlugin(uuid, appPackageName));
600 return OK;
601 }
602
603 case DESTROY_PLUGIN:
604 {
605 CHECK_INTERFACE(IDrm, data, reply);
606 reply->writeInt32(destroyPlugin());
607 return OK;
608 }
609
610 case OPEN_SESSION:
611 {
612 CHECK_INTERFACE(IDrm, data, reply);
613 Vector<uint8_t> sessionId;
614 status_t result = openSession(sessionId);
615 writeVector(reply, sessionId);
616 reply->writeInt32(result);
617 return OK;
618 }
619
620 case CLOSE_SESSION:
621 {
622 CHECK_INTERFACE(IDrm, data, reply);
623 Vector<uint8_t> sessionId;
624 readVector(data, sessionId);
625 reply->writeInt32(closeSession(sessionId));
626 return OK;
627 }
628
629 case GET_KEY_REQUEST:
630 {
631 CHECK_INTERFACE(IDrm, data, reply);
632 Vector<uint8_t> sessionId, initData;
633
634 readVector(data, sessionId);
635 readVector(data, initData);
636 String8 mimeType = data.readString8();
637 DrmPlugin::KeyType keyType = (DrmPlugin::KeyType)data.readInt32();
638
639 KeyedVector<String8, String8> optionalParameters;
640 uint32_t count = data.readInt32();
641 for (size_t i = 0; i < count; ++i) {
642 String8 key, value;
643 key = data.readString8();
644 value = data.readString8();
645 optionalParameters.add(key, value);
646 }
647
648 Vector<uint8_t> request;
649 String8 defaultUrl;
650 DrmPlugin::KeyRequestType keyRequestType = DrmPlugin::kKeyRequestType_Unknown;
651
652 status_t result = getKeyRequest(sessionId, initData, mimeType,
653 keyType, optionalParameters, request, defaultUrl,
654 &keyRequestType);
655
656 writeVector(reply, request);
657 reply->writeString8(defaultUrl);
658 reply->writeInt32(static_cast<int32_t>(keyRequestType));
659 reply->writeInt32(result);
660 return OK;
661 }
662
663 case PROVIDE_KEY_RESPONSE:
664 {
665 CHECK_INTERFACE(IDrm, data, reply);
666 Vector<uint8_t> sessionId, response, keySetId;
667 readVector(data, sessionId);
668 readVector(data, response);
669 uint32_t result = provideKeyResponse(sessionId, response, keySetId);
670 writeVector(reply, keySetId);
671 reply->writeInt32(result);
672 return OK;
673 }
674
675 case REMOVE_KEYS:
676 {
677 CHECK_INTERFACE(IDrm, data, reply);
678 Vector<uint8_t> keySetId;
679 readVector(data, keySetId);
680 reply->writeInt32(removeKeys(keySetId));
681 return OK;
682 }
683
684 case RESTORE_KEYS:
685 {
686 CHECK_INTERFACE(IDrm, data, reply);
687 Vector<uint8_t> sessionId, keySetId;
688 readVector(data, sessionId);
689 readVector(data, keySetId);
690 reply->writeInt32(restoreKeys(sessionId, keySetId));
691 return OK;
692 }
693
694 case QUERY_KEY_STATUS:
695 {
696 CHECK_INTERFACE(IDrm, data, reply);
697 Vector<uint8_t> sessionId;
698 readVector(data, sessionId);
699 KeyedVector<String8, String8> infoMap;
700 status_t result = queryKeyStatus(sessionId, infoMap);
701 size_t count = infoMap.size();
702 reply->writeInt32(count);
703 for (size_t i = 0; i < count; ++i) {
704 reply->writeString8(infoMap.keyAt(i));
705 reply->writeString8(infoMap.valueAt(i));
706 }
707 reply->writeInt32(result);
708 return OK;
709 }
710
711 case GET_PROVISION_REQUEST:
712 {
713 CHECK_INTERFACE(IDrm, data, reply);
714 String8 certType = data.readString8();
715 String8 certAuthority = data.readString8();
716
717 Vector<uint8_t> request;
718 String8 defaultUrl;
719 status_t result = getProvisionRequest(certType, certAuthority,
720 request, defaultUrl);
721 writeVector(reply, request);
722 reply->writeString8(defaultUrl);
723 reply->writeInt32(result);
724 return OK;
725 }
726
727 case PROVIDE_PROVISION_RESPONSE:
728 {
729 CHECK_INTERFACE(IDrm, data, reply);
730 Vector<uint8_t> response;
731 Vector<uint8_t> certificate;
732 Vector<uint8_t> wrappedKey;
733 readVector(data, response);
734 status_t result = provideProvisionResponse(response, certificate, wrappedKey);
735 writeVector(reply, certificate);
736 writeVector(reply, wrappedKey);
737 reply->writeInt32(result);
738 return OK;
739 }
740
741 case GET_SECURE_STOPS:
742 {
743 CHECK_INTERFACE(IDrm, data, reply);
744 List<Vector<uint8_t> > secureStops;
745 status_t result = getSecureStops(secureStops);
746 size_t count = secureStops.size();
747 reply->writeInt32(count);
748 List<Vector<uint8_t> >::iterator iter = secureStops.begin();
749 while(iter != secureStops.end()) {
750 size_t size = iter->size();
751 reply->writeInt32(size);
752 reply->write(iter->array(), iter->size());
753 iter++;
754 }
755 reply->writeInt32(result);
756 return OK;
757 }
758
759 case GET_SECURE_STOP:
760 {
761 CHECK_INTERFACE(IDrm, data, reply);
762 Vector<uint8_t> ssid, secureStop;
763 readVector(data, ssid);
764 status_t result = getSecureStop(ssid, secureStop);
765 writeVector(reply, secureStop);
766 reply->writeInt32(result);
767 return OK;
768 }
769
770 case RELEASE_SECURE_STOPS:
771 {
772 CHECK_INTERFACE(IDrm, data, reply);
773 Vector<uint8_t> ssRelease;
774 readVector(data, ssRelease);
775 reply->writeInt32(releaseSecureStops(ssRelease));
776 return OK;
777 }
778
779 case RELEASE_ALL_SECURE_STOPS:
780 {
781 CHECK_INTERFACE(IDrm, data, reply);
782 reply->writeInt32(releaseAllSecureStops());
783 return OK;
784 }
785
786 case GET_PROPERTY_STRING:
787 {
788 CHECK_INTERFACE(IDrm, data, reply);
789 String8 name = data.readString8();
790 String8 value;
791 status_t result = getPropertyString(name, value);
792 reply->writeString8(value);
793 reply->writeInt32(result);
794 return OK;
795 }
796
797 case GET_PROPERTY_BYTE_ARRAY:
798 {
799 CHECK_INTERFACE(IDrm, data, reply);
800 String8 name = data.readString8();
801 Vector<uint8_t> value;
802 status_t result = getPropertyByteArray(name, value);
803 writeVector(reply, value);
804 reply->writeInt32(result);
805 return OK;
806 }
807
808 case SET_PROPERTY_STRING:
809 {
810 CHECK_INTERFACE(IDrm, data, reply);
811 String8 name = data.readString8();
812 String8 value = data.readString8();
813 reply->writeInt32(setPropertyString(name, value));
814 return OK;
815 }
816
817 case SET_PROPERTY_BYTE_ARRAY:
818 {
819 CHECK_INTERFACE(IDrm, data, reply);
820 String8 name = data.readString8();
821 Vector<uint8_t> value;
822 readVector(data, value);
823 reply->writeInt32(setPropertyByteArray(name, value));
824 return OK;
825 }
826
827 case SET_CIPHER_ALGORITHM:
828 {
829 CHECK_INTERFACE(IDrm, data, reply);
830 Vector<uint8_t> sessionId;
831 readVector(data, sessionId);
832 String8 algorithm = data.readString8();
833 reply->writeInt32(setCipherAlgorithm(sessionId, algorithm));
834 return OK;
835 }
836
837 case SET_MAC_ALGORITHM:
838 {
839 CHECK_INTERFACE(IDrm, data, reply);
840 Vector<uint8_t> sessionId;
841 readVector(data, sessionId);
842 String8 algorithm = data.readString8();
843 reply->writeInt32(setMacAlgorithm(sessionId, algorithm));
844 return OK;
845 }
846
847 case ENCRYPT:
848 {
849 CHECK_INTERFACE(IDrm, data, reply);
850 Vector<uint8_t> sessionId, keyId, input, iv, output;
851 readVector(data, sessionId);
852 readVector(data, keyId);
853 readVector(data, input);
854 readVector(data, iv);
855 uint32_t result = encrypt(sessionId, keyId, input, iv, output);
856 writeVector(reply, output);
857 reply->writeInt32(result);
858 return OK;
859 }
860
861 case DECRYPT:
862 {
863 CHECK_INTERFACE(IDrm, data, reply);
864 Vector<uint8_t> sessionId, keyId, input, iv, output;
865 readVector(data, sessionId);
866 readVector(data, keyId);
867 readVector(data, input);
868 readVector(data, iv);
869 uint32_t result = decrypt(sessionId, keyId, input, iv, output);
870 writeVector(reply, output);
871 reply->writeInt32(result);
872 return OK;
873 }
874
875 case SIGN:
876 {
877 CHECK_INTERFACE(IDrm, data, reply);
878 Vector<uint8_t> sessionId, keyId, message, signature;
879 readVector(data, sessionId);
880 readVector(data, keyId);
881 readVector(data, message);
882 uint32_t result = sign(sessionId, keyId, message, signature);
883 writeVector(reply, signature);
884 reply->writeInt32(result);
885 return OK;
886 }
887
888 case VERIFY:
889 {
890 CHECK_INTERFACE(IDrm, data, reply);
891 Vector<uint8_t> sessionId, keyId, message, signature;
892 readVector(data, sessionId);
893 readVector(data, keyId);
894 readVector(data, message);
895 readVector(data, signature);
896 bool match = false;
897 uint32_t result = verify(sessionId, keyId, message, signature, match);
898 reply->writeInt32(match);
899 reply->writeInt32(result);
900 return OK;
901 }
902
903 case SIGN_RSA:
904 {
905 CHECK_INTERFACE(IDrm, data, reply);
906 Vector<uint8_t> sessionId, message, wrappedKey, signature;
907 readVector(data, sessionId);
908 String8 algorithm = data.readString8();
909 readVector(data, message);
910 readVector(data, wrappedKey);
911 uint32_t result = signRSA(sessionId, algorithm, message, wrappedKey, signature);
912 writeVector(reply, signature);
913 reply->writeInt32(result);
914 return OK;
915 }
916
917 case SET_LISTENER: {
918 CHECK_INTERFACE(IDrm, data, reply);
919 sp<IDrmClient> listener =
920 interface_cast<IDrmClient>(data.readStrongBinder());
921 reply->writeInt32(setListener(listener));
922 return NO_ERROR;
923 } break;
924
925 default:
926 return BBinder::onTransact(code, data, reply, flags);
927 }
928 }
929
930 } // namespace android
931