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 if (vector.insertAt((size_t)0, size) < 0) {
565 vector.clear();
566 }
567 if (data.read(vector.editArray(), size) != NO_ERROR) {
568 vector.clear();
569 android_errorWriteWithInfoLog(0x534e4554, "62872384", -1, NULL, 0);
570 }
571 }
572
writeVector(Parcel * reply,Vector<uint8_t> const & vector) const573 void BnDrm::writeVector(Parcel *reply, Vector<uint8_t> const &vector) const {
574 reply->writeInt32(vector.size());
575 reply->write(vector.array(), vector.size());
576 }
577
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)578 status_t BnDrm::onTransact(
579 uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
580 switch (code) {
581 case INIT_CHECK:
582 {
583 CHECK_INTERFACE(IDrm, data, reply);
584 reply->writeInt32(initCheck());
585 return OK;
586 }
587
588 case IS_CRYPTO_SUPPORTED:
589 {
590 CHECK_INTERFACE(IDrm, data, reply);
591 uint8_t uuid[16];
592 data.read(uuid, sizeof(uuid));
593 String8 mimeType = data.readString8();
594 reply->writeInt32(isCryptoSchemeSupported(uuid, mimeType));
595 return OK;
596 }
597
598 case CREATE_PLUGIN:
599 {
600 CHECK_INTERFACE(IDrm, data, reply);
601 uint8_t uuid[16];
602 data.read(uuid, sizeof(uuid));
603 String8 appPackageName = data.readString8();
604 reply->writeInt32(createPlugin(uuid, appPackageName));
605 return OK;
606 }
607
608 case DESTROY_PLUGIN:
609 {
610 CHECK_INTERFACE(IDrm, data, reply);
611 reply->writeInt32(destroyPlugin());
612 return OK;
613 }
614
615 case OPEN_SESSION:
616 {
617 CHECK_INTERFACE(IDrm, data, reply);
618 Vector<uint8_t> sessionId;
619 status_t result = openSession(sessionId);
620 writeVector(reply, sessionId);
621 reply->writeInt32(result);
622 return OK;
623 }
624
625 case CLOSE_SESSION:
626 {
627 CHECK_INTERFACE(IDrm, data, reply);
628 Vector<uint8_t> sessionId;
629 readVector(data, sessionId);
630 reply->writeInt32(closeSession(sessionId));
631 return OK;
632 }
633
634 case GET_KEY_REQUEST:
635 {
636 CHECK_INTERFACE(IDrm, data, reply);
637 Vector<uint8_t> sessionId, initData;
638
639 readVector(data, sessionId);
640 readVector(data, initData);
641 String8 mimeType = data.readString8();
642 DrmPlugin::KeyType keyType = (DrmPlugin::KeyType)data.readInt32();
643
644 KeyedVector<String8, String8> optionalParameters;
645 uint32_t count = data.readInt32();
646 for (size_t i = 0; i < count; ++i) {
647 String8 key, value;
648 key = data.readString8();
649 value = data.readString8();
650 optionalParameters.add(key, value);
651 }
652
653 Vector<uint8_t> request;
654 String8 defaultUrl;
655 DrmPlugin::KeyRequestType keyRequestType = DrmPlugin::kKeyRequestType_Unknown;
656
657 status_t result = getKeyRequest(sessionId, initData, mimeType,
658 keyType, optionalParameters, request, defaultUrl,
659 &keyRequestType);
660
661 writeVector(reply, request);
662 reply->writeString8(defaultUrl);
663 reply->writeInt32(static_cast<int32_t>(keyRequestType));
664 reply->writeInt32(result);
665 return OK;
666 }
667
668 case PROVIDE_KEY_RESPONSE:
669 {
670 CHECK_INTERFACE(IDrm, data, reply);
671 Vector<uint8_t> sessionId, response, keySetId;
672 readVector(data, sessionId);
673 readVector(data, response);
674 uint32_t result = provideKeyResponse(sessionId, response, keySetId);
675 writeVector(reply, keySetId);
676 reply->writeInt32(result);
677 return OK;
678 }
679
680 case REMOVE_KEYS:
681 {
682 CHECK_INTERFACE(IDrm, data, reply);
683 Vector<uint8_t> keySetId;
684 readVector(data, keySetId);
685 reply->writeInt32(removeKeys(keySetId));
686 return OK;
687 }
688
689 case RESTORE_KEYS:
690 {
691 CHECK_INTERFACE(IDrm, data, reply);
692 Vector<uint8_t> sessionId, keySetId;
693 readVector(data, sessionId);
694 readVector(data, keySetId);
695 reply->writeInt32(restoreKeys(sessionId, keySetId));
696 return OK;
697 }
698
699 case QUERY_KEY_STATUS:
700 {
701 CHECK_INTERFACE(IDrm, data, reply);
702 Vector<uint8_t> sessionId;
703 readVector(data, sessionId);
704 KeyedVector<String8, String8> infoMap;
705 status_t result = queryKeyStatus(sessionId, infoMap);
706 size_t count = infoMap.size();
707 reply->writeInt32(count);
708 for (size_t i = 0; i < count; ++i) {
709 reply->writeString8(infoMap.keyAt(i));
710 reply->writeString8(infoMap.valueAt(i));
711 }
712 reply->writeInt32(result);
713 return OK;
714 }
715
716 case GET_PROVISION_REQUEST:
717 {
718 CHECK_INTERFACE(IDrm, data, reply);
719 String8 certType = data.readString8();
720 String8 certAuthority = data.readString8();
721
722 Vector<uint8_t> request;
723 String8 defaultUrl;
724 status_t result = getProvisionRequest(certType, certAuthority,
725 request, defaultUrl);
726 writeVector(reply, request);
727 reply->writeString8(defaultUrl);
728 reply->writeInt32(result);
729 return OK;
730 }
731
732 case PROVIDE_PROVISION_RESPONSE:
733 {
734 CHECK_INTERFACE(IDrm, data, reply);
735 Vector<uint8_t> response;
736 Vector<uint8_t> certificate;
737 Vector<uint8_t> wrappedKey;
738 readVector(data, response);
739 status_t result = provideProvisionResponse(response, certificate, wrappedKey);
740 writeVector(reply, certificate);
741 writeVector(reply, wrappedKey);
742 reply->writeInt32(result);
743 return OK;
744 }
745
746 case GET_SECURE_STOPS:
747 {
748 CHECK_INTERFACE(IDrm, data, reply);
749 List<Vector<uint8_t> > secureStops;
750 status_t result = getSecureStops(secureStops);
751 size_t count = secureStops.size();
752 reply->writeInt32(count);
753 List<Vector<uint8_t> >::iterator iter = secureStops.begin();
754 while(iter != secureStops.end()) {
755 size_t size = iter->size();
756 reply->writeInt32(size);
757 reply->write(iter->array(), iter->size());
758 iter++;
759 }
760 reply->writeInt32(result);
761 return OK;
762 }
763
764 case GET_SECURE_STOP:
765 {
766 CHECK_INTERFACE(IDrm, data, reply);
767 Vector<uint8_t> ssid, secureStop;
768 readVector(data, ssid);
769 status_t result = getSecureStop(ssid, secureStop);
770 writeVector(reply, secureStop);
771 reply->writeInt32(result);
772 return OK;
773 }
774
775 case RELEASE_SECURE_STOPS:
776 {
777 CHECK_INTERFACE(IDrm, data, reply);
778 Vector<uint8_t> ssRelease;
779 readVector(data, ssRelease);
780 reply->writeInt32(releaseSecureStops(ssRelease));
781 return OK;
782 }
783
784 case RELEASE_ALL_SECURE_STOPS:
785 {
786 CHECK_INTERFACE(IDrm, data, reply);
787 reply->writeInt32(releaseAllSecureStops());
788 return OK;
789 }
790
791 case GET_PROPERTY_STRING:
792 {
793 CHECK_INTERFACE(IDrm, data, reply);
794 String8 name = data.readString8();
795 String8 value;
796 status_t result = getPropertyString(name, value);
797 reply->writeString8(value);
798 reply->writeInt32(result);
799 return OK;
800 }
801
802 case GET_PROPERTY_BYTE_ARRAY:
803 {
804 CHECK_INTERFACE(IDrm, data, reply);
805 String8 name = data.readString8();
806 Vector<uint8_t> value;
807 status_t result = getPropertyByteArray(name, value);
808 writeVector(reply, value);
809 reply->writeInt32(result);
810 return OK;
811 }
812
813 case SET_PROPERTY_STRING:
814 {
815 CHECK_INTERFACE(IDrm, data, reply);
816 String8 name = data.readString8();
817 String8 value = data.readString8();
818 reply->writeInt32(setPropertyString(name, value));
819 return OK;
820 }
821
822 case SET_PROPERTY_BYTE_ARRAY:
823 {
824 CHECK_INTERFACE(IDrm, data, reply);
825 String8 name = data.readString8();
826 Vector<uint8_t> value;
827 readVector(data, value);
828 reply->writeInt32(setPropertyByteArray(name, value));
829 return OK;
830 }
831
832 case SET_CIPHER_ALGORITHM:
833 {
834 CHECK_INTERFACE(IDrm, data, reply);
835 Vector<uint8_t> sessionId;
836 readVector(data, sessionId);
837 String8 algorithm = data.readString8();
838 reply->writeInt32(setCipherAlgorithm(sessionId, algorithm));
839 return OK;
840 }
841
842 case SET_MAC_ALGORITHM:
843 {
844 CHECK_INTERFACE(IDrm, data, reply);
845 Vector<uint8_t> sessionId;
846 readVector(data, sessionId);
847 String8 algorithm = data.readString8();
848 reply->writeInt32(setMacAlgorithm(sessionId, algorithm));
849 return OK;
850 }
851
852 case ENCRYPT:
853 {
854 CHECK_INTERFACE(IDrm, data, reply);
855 Vector<uint8_t> sessionId, keyId, input, iv, output;
856 readVector(data, sessionId);
857 readVector(data, keyId);
858 readVector(data, input);
859 readVector(data, iv);
860 uint32_t result = encrypt(sessionId, keyId, input, iv, output);
861 writeVector(reply, output);
862 reply->writeInt32(result);
863 return OK;
864 }
865
866 case DECRYPT:
867 {
868 CHECK_INTERFACE(IDrm, data, reply);
869 Vector<uint8_t> sessionId, keyId, input, iv, output;
870 readVector(data, sessionId);
871 readVector(data, keyId);
872 readVector(data, input);
873 readVector(data, iv);
874 uint32_t result = decrypt(sessionId, keyId, input, iv, output);
875 writeVector(reply, output);
876 reply->writeInt32(result);
877 return OK;
878 }
879
880 case SIGN:
881 {
882 CHECK_INTERFACE(IDrm, data, reply);
883 Vector<uint8_t> sessionId, keyId, message, signature;
884 readVector(data, sessionId);
885 readVector(data, keyId);
886 readVector(data, message);
887 uint32_t result = sign(sessionId, keyId, message, signature);
888 writeVector(reply, signature);
889 reply->writeInt32(result);
890 return OK;
891 }
892
893 case VERIFY:
894 {
895 CHECK_INTERFACE(IDrm, data, reply);
896 Vector<uint8_t> sessionId, keyId, message, signature;
897 readVector(data, sessionId);
898 readVector(data, keyId);
899 readVector(data, message);
900 readVector(data, signature);
901 bool match = false;
902 uint32_t result = verify(sessionId, keyId, message, signature, match);
903 reply->writeInt32(match);
904 reply->writeInt32(result);
905 return OK;
906 }
907
908 case SIGN_RSA:
909 {
910 CHECK_INTERFACE(IDrm, data, reply);
911 Vector<uint8_t> sessionId, message, wrappedKey, signature;
912 readVector(data, sessionId);
913 String8 algorithm = data.readString8();
914 readVector(data, message);
915 readVector(data, wrappedKey);
916 uint32_t result = signRSA(sessionId, algorithm, message, wrappedKey, signature);
917 writeVector(reply, signature);
918 reply->writeInt32(result);
919 return OK;
920 }
921
922 case SET_LISTENER: {
923 CHECK_INTERFACE(IDrm, data, reply);
924 sp<IDrmClient> listener =
925 interface_cast<IDrmClient>(data.readStrongBinder());
926 reply->writeInt32(setListener(listener));
927 return NO_ERROR;
928 } break;
929
930 default:
931 return BBinder::onTransact(code, data, reply, flags);
932 }
933 }
934
935 } // namespace android
936