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 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 Parcel data, reply;
93 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
94 data.write(uuid, 16);
95
96 status_t status = remote()->transact(CREATE_PLUGIN, data, &reply);
97 if (status != OK) {
98 return status;
99 }
100
101 return reply.readInt32();
102 }
103
destroyPluginandroid::BpDrm104 virtual status_t destroyPlugin() {
105 Parcel data, reply;
106 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
107 status_t status = remote()->transact(DESTROY_PLUGIN, data, &reply);
108 if (status != OK) {
109 return status;
110 }
111
112 return reply.readInt32();
113 }
114
openSessionandroid::BpDrm115 virtual status_t openSession(Vector<uint8_t> &sessionId) {
116 Parcel data, reply;
117 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
118
119 status_t status = remote()->transact(OPEN_SESSION, data, &reply);
120 if (status != OK) {
121 return status;
122 }
123 readVector(reply, sessionId);
124
125 return reply.readInt32();
126 }
127
closeSessionandroid::BpDrm128 virtual status_t closeSession(Vector<uint8_t> const &sessionId) {
129 Parcel data, reply;
130 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
131
132 writeVector(data, sessionId);
133 status_t status = remote()->transact(CLOSE_SESSION, data, &reply);
134 if (status != OK) {
135 return status;
136 }
137
138 return reply.readInt32();
139 }
140
141 virtual status_t
getKeyRequestandroid::BpDrm142 getKeyRequest(Vector<uint8_t> const &sessionId,
143 Vector<uint8_t> const &initData,
144 String8 const &mimeType, DrmPlugin::KeyType keyType,
145 KeyedVector<String8, String8> const &optionalParameters,
146 Vector<uint8_t> &request, String8 &defaultUrl,
147 DrmPlugin::KeyRequestType *keyRequestType) {
148 Parcel data, reply;
149 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
150
151 writeVector(data, sessionId);
152 writeVector(data, initData);
153 data.writeString8(mimeType);
154 data.writeInt32((uint32_t)keyType);
155
156 data.writeInt32(optionalParameters.size());
157 for (size_t i = 0; i < optionalParameters.size(); ++i) {
158 data.writeString8(optionalParameters.keyAt(i));
159 data.writeString8(optionalParameters.valueAt(i));
160 }
161
162 status_t status = remote()->transact(GET_KEY_REQUEST, data, &reply);
163 if (status != OK) {
164 return status;
165 }
166
167 readVector(reply, request);
168 defaultUrl = reply.readString8();
169 *keyRequestType = static_cast<DrmPlugin::KeyRequestType>(reply.readInt32());
170
171 return reply.readInt32();
172 }
173
provideKeyResponseandroid::BpDrm174 virtual status_t provideKeyResponse(Vector<uint8_t> const &sessionId,
175 Vector<uint8_t> const &response,
176 Vector<uint8_t> &keySetId) {
177 Parcel data, reply;
178 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
179 writeVector(data, sessionId);
180 writeVector(data, response);
181
182 status_t status = remote()->transact(PROVIDE_KEY_RESPONSE, data, &reply);
183 if (status != OK) {
184 return status;
185 }
186
187 readVector(reply, keySetId);
188
189 return reply.readInt32();
190 }
191
removeKeysandroid::BpDrm192 virtual status_t removeKeys(Vector<uint8_t> const &keySetId) {
193 Parcel data, reply;
194 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
195
196 writeVector(data, keySetId);
197 status_t status = remote()->transact(REMOVE_KEYS, data, &reply);
198 if (status != OK) {
199 return status;
200 }
201
202 return reply.readInt32();
203 }
204
restoreKeysandroid::BpDrm205 virtual status_t restoreKeys(Vector<uint8_t> const &sessionId,
206 Vector<uint8_t> const &keySetId) {
207 Parcel data, reply;
208 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
209
210 writeVector(data, sessionId);
211 writeVector(data, keySetId);
212 status_t status = remote()->transact(RESTORE_KEYS, data, &reply);
213 if (status != OK) {
214 return status;
215 }
216
217 return reply.readInt32();
218 }
219
queryKeyStatusandroid::BpDrm220 virtual status_t queryKeyStatus(Vector<uint8_t> const &sessionId,
221 KeyedVector<String8, String8> &infoMap) const {
222 Parcel data, reply;
223 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
224
225 writeVector(data, sessionId);
226 status_t status = remote()->transact(QUERY_KEY_STATUS, data, &reply);
227 if (status != OK) {
228 return status;
229 }
230
231 infoMap.clear();
232 size_t count = reply.readInt32();
233 for (size_t i = 0; i < count; i++) {
234 String8 key = reply.readString8();
235 String8 value = reply.readString8();
236 infoMap.add(key, value);
237 }
238 return reply.readInt32();
239 }
240
getProvisionRequestandroid::BpDrm241 virtual status_t getProvisionRequest(String8 const &certType,
242 String8 const &certAuthority,
243 Vector<uint8_t> &request,
244 String8 &defaultUrl) {
245 Parcel data, reply;
246 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
247
248 data.writeString8(certType);
249 data.writeString8(certAuthority);
250 status_t status = remote()->transact(GET_PROVISION_REQUEST, data, &reply);
251 if (status != OK) {
252 return status;
253 }
254
255 readVector(reply, request);
256 defaultUrl = reply.readString8();
257
258 return reply.readInt32();
259 }
260
provideProvisionResponseandroid::BpDrm261 virtual status_t provideProvisionResponse(Vector<uint8_t> const &response,
262 Vector<uint8_t> &certificate,
263 Vector<uint8_t> &wrappedKey) {
264 Parcel data, reply;
265 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
266
267 writeVector(data, response);
268 status_t status = remote()->transact(PROVIDE_PROVISION_RESPONSE, data, &reply);
269 if (status != OK) {
270 return status;
271 }
272
273 readVector(reply, certificate);
274 readVector(reply, wrappedKey);
275
276 return reply.readInt32();
277 }
278
getSecureStopsandroid::BpDrm279 virtual status_t getSecureStops(List<Vector<uint8_t> > &secureStops) {
280 Parcel data, reply;
281 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
282
283 status_t status = remote()->transact(GET_SECURE_STOPS, data, &reply);
284 if (status != OK) {
285 return status;
286 }
287
288 secureStops.clear();
289 uint32_t count = reply.readInt32();
290 for (size_t i = 0; i < count; i++) {
291 Vector<uint8_t> secureStop;
292 readVector(reply, secureStop);
293 secureStops.push_back(secureStop);
294 }
295 return reply.readInt32();
296 }
297
getSecureStopandroid::BpDrm298 virtual status_t getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
299 Parcel data, reply;
300 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
301
302 writeVector(data, ssid);
303 status_t status = remote()->transact(GET_SECURE_STOP, data, &reply);
304 if (status != OK) {
305 return status;
306 }
307
308 readVector(reply, secureStop);
309 return reply.readInt32();
310 }
311
releaseSecureStopsandroid::BpDrm312 virtual status_t releaseSecureStops(Vector<uint8_t> const &ssRelease) {
313 Parcel data, reply;
314 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
315
316 writeVector(data, ssRelease);
317 status_t status = remote()->transact(RELEASE_SECURE_STOPS, data, &reply);
318 if (status != OK) {
319 return status;
320 }
321
322 return reply.readInt32();
323 }
324
releaseAllSecureStopsandroid::BpDrm325 virtual status_t releaseAllSecureStops() {
326 Parcel data, reply;
327 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
328
329 status_t status = remote()->transact(RELEASE_ALL_SECURE_STOPS, data, &reply);
330 if (status != OK) {
331 return status;
332 }
333
334 return reply.readInt32();
335 }
336
getPropertyStringandroid::BpDrm337 virtual status_t getPropertyString(String8 const &name, String8 &value) const {
338 Parcel data, reply;
339 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
340
341 data.writeString8(name);
342 status_t status = remote()->transact(GET_PROPERTY_STRING, data, &reply);
343 if (status != OK) {
344 return status;
345 }
346
347 value = reply.readString8();
348 return reply.readInt32();
349 }
350
getPropertyByteArrayandroid::BpDrm351 virtual status_t getPropertyByteArray(String8 const &name, Vector<uint8_t> &value) const {
352 Parcel data, reply;
353 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
354
355 data.writeString8(name);
356 status_t status = remote()->transact(GET_PROPERTY_BYTE_ARRAY, data, &reply);
357 if (status != OK) {
358 return status;
359 }
360
361 readVector(reply, value);
362 return reply.readInt32();
363 }
364
setPropertyStringandroid::BpDrm365 virtual status_t setPropertyString(String8 const &name, String8 const &value) const {
366 Parcel data, reply;
367 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
368
369 data.writeString8(name);
370 data.writeString8(value);
371 status_t status = remote()->transact(SET_PROPERTY_STRING, data, &reply);
372 if (status != OK) {
373 return status;
374 }
375
376 return reply.readInt32();
377 }
378
setPropertyByteArrayandroid::BpDrm379 virtual status_t setPropertyByteArray(String8 const &name,
380 Vector<uint8_t> const &value) const {
381 Parcel data, reply;
382 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
383
384 data.writeString8(name);
385 writeVector(data, value);
386 status_t status = remote()->transact(SET_PROPERTY_BYTE_ARRAY, data, &reply);
387 if (status != OK) {
388 return status;
389 }
390
391 return reply.readInt32();
392 }
393
394
setCipherAlgorithmandroid::BpDrm395 virtual status_t setCipherAlgorithm(Vector<uint8_t> const &sessionId,
396 String8 const &algorithm) {
397 Parcel data, reply;
398 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
399
400 writeVector(data, sessionId);
401 data.writeString8(algorithm);
402 status_t status = remote()->transact(SET_CIPHER_ALGORITHM, data, &reply);
403 if (status != OK) {
404 return status;
405 }
406 return reply.readInt32();
407 }
408
setMacAlgorithmandroid::BpDrm409 virtual status_t setMacAlgorithm(Vector<uint8_t> const &sessionId,
410 String8 const &algorithm) {
411 Parcel data, reply;
412 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
413
414 writeVector(data, sessionId);
415 data.writeString8(algorithm);
416 status_t status = remote()->transact(SET_MAC_ALGORITHM, data, &reply);
417 if (status != OK) {
418 return status;
419 }
420 return reply.readInt32();
421 }
422
encryptandroid::BpDrm423 virtual status_t encrypt(Vector<uint8_t> const &sessionId,
424 Vector<uint8_t> const &keyId,
425 Vector<uint8_t> const &input,
426 Vector<uint8_t> const &iv,
427 Vector<uint8_t> &output) {
428 Parcel data, reply;
429 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
430
431 writeVector(data, sessionId);
432 writeVector(data, keyId);
433 writeVector(data, input);
434 writeVector(data, iv);
435
436 status_t status = remote()->transact(ENCRYPT, data, &reply);
437 if (status != OK) {
438 return status;
439 }
440 readVector(reply, output);
441
442 return reply.readInt32();
443 }
444
decryptandroid::BpDrm445 virtual status_t decrypt(Vector<uint8_t> const &sessionId,
446 Vector<uint8_t> const &keyId,
447 Vector<uint8_t> const &input,
448 Vector<uint8_t> const &iv,
449 Vector<uint8_t> &output) {
450 Parcel data, reply;
451 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
452
453 writeVector(data, sessionId);
454 writeVector(data, keyId);
455 writeVector(data, input);
456 writeVector(data, iv);
457
458 status_t status = remote()->transact(DECRYPT, data, &reply);
459 if (status != OK) {
460 return status;
461 }
462 readVector(reply, output);
463
464 return reply.readInt32();
465 }
466
signandroid::BpDrm467 virtual status_t sign(Vector<uint8_t> const &sessionId,
468 Vector<uint8_t> const &keyId,
469 Vector<uint8_t> const &message,
470 Vector<uint8_t> &signature) {
471 Parcel data, reply;
472 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
473
474 writeVector(data, sessionId);
475 writeVector(data, keyId);
476 writeVector(data, message);
477
478 status_t status = remote()->transact(SIGN, data, &reply);
479 if (status != OK) {
480 return status;
481 }
482 readVector(reply, signature);
483
484 return reply.readInt32();
485 }
486
verifyandroid::BpDrm487 virtual status_t verify(Vector<uint8_t> const &sessionId,
488 Vector<uint8_t> const &keyId,
489 Vector<uint8_t> const &message,
490 Vector<uint8_t> const &signature,
491 bool &match) {
492 Parcel data, reply;
493 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
494
495 writeVector(data, sessionId);
496 writeVector(data, keyId);
497 writeVector(data, message);
498 writeVector(data, signature);
499
500 status_t status = remote()->transact(VERIFY, data, &reply);
501 if (status != OK) {
502 return status;
503 }
504 match = (bool)reply.readInt32();
505 return reply.readInt32();
506 }
507
signRSAandroid::BpDrm508 virtual status_t signRSA(Vector<uint8_t> const &sessionId,
509 String8 const &algorithm,
510 Vector<uint8_t> const &message,
511 Vector<uint8_t> const &wrappedKey,
512 Vector<uint8_t> &signature) {
513 Parcel data, reply;
514 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
515
516 writeVector(data, sessionId);
517 data.writeString8(algorithm);
518 writeVector(data, message);
519 writeVector(data, wrappedKey);
520
521 status_t status = remote()->transact(SIGN_RSA, data, &reply);
522 if (status != OK) {
523 return status;
524 }
525 readVector(reply, signature);
526
527 return reply.readInt32();
528 }
529
setListenerandroid::BpDrm530 virtual status_t setListener(const sp<IDrmClient>& listener) {
531 Parcel data, reply;
532 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
533 data.writeStrongBinder(IInterface::asBinder(listener));
534 status_t status = remote()->transact(SET_LISTENER, data, &reply);
535 if (status != OK) {
536 return status;
537 }
538 return reply.readInt32();
539 }
540
541 private:
readVectorandroid::BpDrm542 void readVector(Parcel &reply, Vector<uint8_t> &vector) const {
543 uint32_t size = reply.readInt32();
544 vector.insertAt((size_t)0, size);
545 reply.read(vector.editArray(), size);
546 }
547
writeVectorandroid::BpDrm548 void writeVector(Parcel &data, Vector<uint8_t> const &vector) const {
549 data.writeInt32(vector.size());
550 data.write(vector.array(), vector.size());
551 }
552
553 DISALLOW_EVIL_CONSTRUCTORS(BpDrm);
554 };
555
556 IMPLEMENT_META_INTERFACE(Drm, "android.drm.IDrm");
557
558 ////////////////////////////////////////////////////////////////////////////////
559
readVector(const Parcel & data,Vector<uint8_t> & vector) const560 void BnDrm::readVector(const Parcel &data, Vector<uint8_t> &vector) const {
561 uint32_t size = data.readInt32();
562 vector.insertAt((size_t)0, size);
563 data.read(vector.editArray(), size);
564 }
565
writeVector(Parcel * reply,Vector<uint8_t> const & vector) const566 void BnDrm::writeVector(Parcel *reply, Vector<uint8_t> const &vector) const {
567 reply->writeInt32(vector.size());
568 reply->write(vector.array(), vector.size());
569 }
570
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)571 status_t BnDrm::onTransact(
572 uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
573 switch (code) {
574 case INIT_CHECK:
575 {
576 CHECK_INTERFACE(IDrm, data, reply);
577 reply->writeInt32(initCheck());
578 return OK;
579 }
580
581 case IS_CRYPTO_SUPPORTED:
582 {
583 CHECK_INTERFACE(IDrm, data, reply);
584 uint8_t uuid[16];
585 data.read(uuid, sizeof(uuid));
586 String8 mimeType = data.readString8();
587 reply->writeInt32(isCryptoSchemeSupported(uuid, mimeType));
588
589 return OK;
590 }
591
592 case CREATE_PLUGIN:
593 {
594 CHECK_INTERFACE(IDrm, data, reply);
595 uint8_t uuid[16];
596 data.read(uuid, sizeof(uuid));
597 reply->writeInt32(createPlugin(uuid));
598 return OK;
599 }
600
601 case DESTROY_PLUGIN:
602 {
603 CHECK_INTERFACE(IDrm, data, reply);
604 reply->writeInt32(destroyPlugin());
605 return OK;
606 }
607
608 case OPEN_SESSION:
609 {
610 CHECK_INTERFACE(IDrm, data, reply);
611 Vector<uint8_t> sessionId;
612 status_t result = openSession(sessionId);
613 writeVector(reply, sessionId);
614 reply->writeInt32(result);
615 return OK;
616 }
617
618 case CLOSE_SESSION:
619 {
620 CHECK_INTERFACE(IDrm, data, reply);
621 Vector<uint8_t> sessionId;
622 readVector(data, sessionId);
623 reply->writeInt32(closeSession(sessionId));
624 return OK;
625 }
626
627 case GET_KEY_REQUEST:
628 {
629 CHECK_INTERFACE(IDrm, data, reply);
630 Vector<uint8_t> sessionId, initData;
631
632 readVector(data, sessionId);
633 readVector(data, initData);
634 String8 mimeType = data.readString8();
635 DrmPlugin::KeyType keyType = (DrmPlugin::KeyType)data.readInt32();
636
637 KeyedVector<String8, String8> optionalParameters;
638 uint32_t count = data.readInt32();
639 for (size_t i = 0; i < count; ++i) {
640 String8 key, value;
641 key = data.readString8();
642 value = data.readString8();
643 optionalParameters.add(key, value);
644 }
645
646 Vector<uint8_t> request;
647 String8 defaultUrl;
648 DrmPlugin::KeyRequestType keyRequestType = DrmPlugin::kKeyRequestType_Unknown;
649
650 status_t result = getKeyRequest(sessionId, initData, mimeType,
651 keyType, optionalParameters, request, defaultUrl,
652 &keyRequestType);
653
654 writeVector(reply, request);
655 reply->writeString8(defaultUrl);
656 reply->writeInt32(static_cast<int32_t>(keyRequestType));
657 reply->writeInt32(result);
658 return OK;
659 }
660
661 case PROVIDE_KEY_RESPONSE:
662 {
663 CHECK_INTERFACE(IDrm, data, reply);
664 Vector<uint8_t> sessionId, response, keySetId;
665 readVector(data, sessionId);
666 readVector(data, response);
667 uint32_t result = provideKeyResponse(sessionId, response, keySetId);
668 writeVector(reply, keySetId);
669 reply->writeInt32(result);
670 return OK;
671 }
672
673 case REMOVE_KEYS:
674 {
675 CHECK_INTERFACE(IDrm, data, reply);
676 Vector<uint8_t> keySetId;
677 readVector(data, keySetId);
678 reply->writeInt32(removeKeys(keySetId));
679 return OK;
680 }
681
682 case RESTORE_KEYS:
683 {
684 CHECK_INTERFACE(IDrm, data, reply);
685 Vector<uint8_t> sessionId, keySetId;
686 readVector(data, sessionId);
687 readVector(data, keySetId);
688 reply->writeInt32(restoreKeys(sessionId, keySetId));
689 return OK;
690 }
691
692 case QUERY_KEY_STATUS:
693 {
694 CHECK_INTERFACE(IDrm, data, reply);
695 Vector<uint8_t> sessionId;
696 readVector(data, sessionId);
697 KeyedVector<String8, String8> infoMap;
698 status_t result = queryKeyStatus(sessionId, infoMap);
699 size_t count = infoMap.size();
700 reply->writeInt32(count);
701 for (size_t i = 0; i < count; ++i) {
702 reply->writeString8(infoMap.keyAt(i));
703 reply->writeString8(infoMap.valueAt(i));
704 }
705 reply->writeInt32(result);
706 return OK;
707 }
708
709 case GET_PROVISION_REQUEST:
710 {
711 CHECK_INTERFACE(IDrm, data, reply);
712 String8 certType = data.readString8();
713 String8 certAuthority = data.readString8();
714
715 Vector<uint8_t> request;
716 String8 defaultUrl;
717 status_t result = getProvisionRequest(certType, certAuthority,
718 request, defaultUrl);
719 writeVector(reply, request);
720 reply->writeString8(defaultUrl);
721 reply->writeInt32(result);
722 return OK;
723 }
724
725 case PROVIDE_PROVISION_RESPONSE:
726 {
727 CHECK_INTERFACE(IDrm, data, reply);
728 Vector<uint8_t> response;
729 Vector<uint8_t> certificate;
730 Vector<uint8_t> wrappedKey;
731 readVector(data, response);
732 status_t result = provideProvisionResponse(response, certificate, wrappedKey);
733 writeVector(reply, certificate);
734 writeVector(reply, wrappedKey);
735 reply->writeInt32(result);
736 return OK;
737 }
738
739 case GET_SECURE_STOPS:
740 {
741 CHECK_INTERFACE(IDrm, data, reply);
742 List<Vector<uint8_t> > secureStops;
743 status_t result = getSecureStops(secureStops);
744 size_t count = secureStops.size();
745 reply->writeInt32(count);
746 List<Vector<uint8_t> >::iterator iter = secureStops.begin();
747 while(iter != secureStops.end()) {
748 size_t size = iter->size();
749 reply->writeInt32(size);
750 reply->write(iter->array(), iter->size());
751 iter++;
752 }
753 reply->writeInt32(result);
754 return OK;
755 }
756
757 case GET_SECURE_STOP:
758 {
759 CHECK_INTERFACE(IDrm, data, reply);
760 Vector<uint8_t> ssid, secureStop;
761 readVector(data, ssid);
762 status_t result = getSecureStop(ssid, secureStop);
763 writeVector(reply, secureStop);
764 reply->writeInt32(result);
765 return OK;
766 }
767
768 case RELEASE_SECURE_STOPS:
769 {
770 CHECK_INTERFACE(IDrm, data, reply);
771 Vector<uint8_t> ssRelease;
772 readVector(data, ssRelease);
773 reply->writeInt32(releaseSecureStops(ssRelease));
774 return OK;
775 }
776
777 case RELEASE_ALL_SECURE_STOPS:
778 {
779 CHECK_INTERFACE(IDrm, data, reply);
780 reply->writeInt32(releaseAllSecureStops());
781 return OK;
782 }
783
784 case GET_PROPERTY_STRING:
785 {
786 CHECK_INTERFACE(IDrm, data, reply);
787 String8 name = data.readString8();
788 String8 value;
789 status_t result = getPropertyString(name, value);
790 reply->writeString8(value);
791 reply->writeInt32(result);
792 return OK;
793 }
794
795 case GET_PROPERTY_BYTE_ARRAY:
796 {
797 CHECK_INTERFACE(IDrm, data, reply);
798 String8 name = data.readString8();
799 Vector<uint8_t> value;
800 status_t result = getPropertyByteArray(name, value);
801 writeVector(reply, value);
802 reply->writeInt32(result);
803 return OK;
804 }
805
806 case SET_PROPERTY_STRING:
807 {
808 CHECK_INTERFACE(IDrm, data, reply);
809 String8 name = data.readString8();
810 String8 value = data.readString8();
811 reply->writeInt32(setPropertyString(name, value));
812 return OK;
813 }
814
815 case SET_PROPERTY_BYTE_ARRAY:
816 {
817 CHECK_INTERFACE(IDrm, data, reply);
818 String8 name = data.readString8();
819 Vector<uint8_t> value;
820 readVector(data, value);
821 reply->writeInt32(setPropertyByteArray(name, value));
822 return OK;
823 }
824
825 case SET_CIPHER_ALGORITHM:
826 {
827 CHECK_INTERFACE(IDrm, data, reply);
828 Vector<uint8_t> sessionId;
829 readVector(data, sessionId);
830 String8 algorithm = data.readString8();
831 reply->writeInt32(setCipherAlgorithm(sessionId, algorithm));
832 return OK;
833 }
834
835 case SET_MAC_ALGORITHM:
836 {
837 CHECK_INTERFACE(IDrm, data, reply);
838 Vector<uint8_t> sessionId;
839 readVector(data, sessionId);
840 String8 algorithm = data.readString8();
841 reply->writeInt32(setMacAlgorithm(sessionId, algorithm));
842 return OK;
843 }
844
845 case ENCRYPT:
846 {
847 CHECK_INTERFACE(IDrm, data, reply);
848 Vector<uint8_t> sessionId, keyId, input, iv, output;
849 readVector(data, sessionId);
850 readVector(data, keyId);
851 readVector(data, input);
852 readVector(data, iv);
853 uint32_t result = encrypt(sessionId, keyId, input, iv, output);
854 writeVector(reply, output);
855 reply->writeInt32(result);
856 return OK;
857 }
858
859 case DECRYPT:
860 {
861 CHECK_INTERFACE(IDrm, data, reply);
862 Vector<uint8_t> sessionId, keyId, input, iv, output;
863 readVector(data, sessionId);
864 readVector(data, keyId);
865 readVector(data, input);
866 readVector(data, iv);
867 uint32_t result = decrypt(sessionId, keyId, input, iv, output);
868 writeVector(reply, output);
869 reply->writeInt32(result);
870 return OK;
871 }
872
873 case SIGN:
874 {
875 CHECK_INTERFACE(IDrm, data, reply);
876 Vector<uint8_t> sessionId, keyId, message, signature;
877 readVector(data, sessionId);
878 readVector(data, keyId);
879 readVector(data, message);
880 uint32_t result = sign(sessionId, keyId, message, signature);
881 writeVector(reply, signature);
882 reply->writeInt32(result);
883 return OK;
884 }
885
886 case VERIFY:
887 {
888 CHECK_INTERFACE(IDrm, data, reply);
889 Vector<uint8_t> sessionId, keyId, message, signature;
890 readVector(data, sessionId);
891 readVector(data, keyId);
892 readVector(data, message);
893 readVector(data, signature);
894 bool match;
895 uint32_t result = verify(sessionId, keyId, message, signature, match);
896 reply->writeInt32(match);
897 reply->writeInt32(result);
898 return OK;
899 }
900
901 case SIGN_RSA:
902 {
903 CHECK_INTERFACE(IDrm, data, reply);
904 Vector<uint8_t> sessionId, message, wrappedKey, signature;
905 readVector(data, sessionId);
906 String8 algorithm = data.readString8();
907 readVector(data, message);
908 readVector(data, wrappedKey);
909 uint32_t result = signRSA(sessionId, algorithm, message, wrappedKey, signature);
910 writeVector(reply, signature);
911 reply->writeInt32(result);
912 return OK;
913 }
914
915 case SET_LISTENER: {
916 CHECK_INTERFACE(IDrm, data, reply);
917 sp<IDrmClient> listener =
918 interface_cast<IDrmClient>(data.readStrongBinder());
919 reply->writeInt32(setListener(listener));
920 return NO_ERROR;
921 } break;
922
923 default:
924 return BBinder::onTransact(code, data, reply, flags);
925 }
926 }
927
928 } // namespace android
929