1 /* 2 * Copyright (C) 2007 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 #include <parser_rel.h> 18 #include <parser_dm.h> 19 #include <xml_tinyParser.h> 20 #include <wbxml_tinyparser.h> 21 #include <drm_decoder.h> 22 #include <svc_drm.h> 23 24 /* See parser_rel.h */ 25 int32_t drm_monthDays(int32_t year, int32_t month) 26 { 27 switch (month) { 28 case 1: 29 case 3: 30 case 5: 31 case 7: 32 case 8: 33 case 10: 34 case 12: 35 return 31; 36 case 4: 37 case 6: 38 case 9: 39 case 11: 40 return 30; 41 case 2: 42 if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)) 43 return 29; 44 else 45 return 28; 46 default: 47 return -1; 48 } 49 } 50 51 int32_t drm_checkDate(int32_t year, int32_t month, int32_t day, 52 int32_t hour, int32_t min, int32_t sec) 53 { 54 if (month >= 1 && month <= 12 && 55 day >= 1 && day <= drm_monthDays(year, month) && 56 hour >= 0 && hour <= 23 && 57 min >= 0 && min <= 59 && sec >= 0 && sec <= 59) 58 return 0; 59 else 60 return -1; 61 } 62 63 static int32_t drm_getStartEndTime(uint8_t * pValue, int32_t valueLen, 64 T_DRM_DATETIME * dateTime) 65 { 66 int32_t year, mon, day, hour, min, sec; 67 uint8_t pTmp[64] = {0}; 68 69 strncpy((char *)pTmp, (char *)pValue, valueLen); 70 { 71 uint8_t * pHead = pTmp; 72 uint8_t * pEnd = NULL; 73 uint8_t tmpByte; 74 75 /** get year */ 76 pEnd = (uint8_t *)strstr((char *)pHead, "-"); 77 if(NULL == pEnd) 78 return FALSE; 79 tmpByte = *pEnd; 80 *pEnd = '\0'; 81 year = atoi((char *)pHead); 82 pHead = pEnd + 1; 83 *pEnd = tmpByte; 84 85 /** get month */ 86 pEnd = (uint8_t *)strstr((char *)pHead, "-"); 87 if(NULL == pEnd) 88 return FALSE; 89 tmpByte = *pEnd; 90 *pEnd = '\0'; 91 mon = atoi((char *)pHead); 92 pHead = pEnd + 1; 93 *pEnd = tmpByte; 94 95 /** get day */ 96 pEnd = (uint8_t *)strstr((char *)pHead, "T"); 97 if(NULL == pEnd) 98 return FALSE; 99 tmpByte = *pEnd; 100 *pEnd = '\0'; 101 day = atoi((char *)pHead); 102 pHead = pEnd + 1; 103 *pEnd = tmpByte; 104 105 /** get hour */ 106 pEnd = (uint8_t *)strstr((char *)pHead, ":"); 107 if(NULL == pEnd) 108 return FALSE; 109 tmpByte = *pEnd; 110 *pEnd = '\0'; 111 hour = atoi((char *)pHead); 112 pHead = pEnd + 1; 113 *pEnd = tmpByte; 114 115 /** get minute */ 116 pEnd = (uint8_t *)strstr((char *)pHead, ":"); 117 if(NULL == pEnd) 118 return FALSE; 119 tmpByte = *pEnd; 120 *pEnd = '\0'; 121 min = atoi((char *)pHead); 122 pHead = pEnd + 1; 123 *pEnd = tmpByte; 124 125 /** get second */ 126 sec = atoi((char *)pHead); 127 } 128 if (0 != drm_checkDate(year, mon, day, hour, min, sec)) 129 return FALSE; 130 131 YMD_HMS_2_INT(year, mon, day, dateTime->date, hour, min, sec, 132 dateTime->time); 133 return TRUE; 134 } 135 136 static int32_t drm_checkWhetherHasUnknowConstraint(uint8_t* drm_constrain) 137 { 138 char* begin_constrain = "<o-ex:constraint>"; 139 char* end_constrain = "</o-ex:constraint>"; 140 char* constrain_begin = strstr((char*)drm_constrain,begin_constrain); 141 char* constrain_end = strstr((char*)drm_constrain,end_constrain); 142 uint32_t constrain_len = 0; 143 144 if(NULL == constrain_begin) 145 return FALSE; 146 147 if(NULL == constrain_end) 148 return TRUE; 149 150 /* compute valid characters length */ 151 { 152 uint32_t constrain_begin_len = strlen(begin_constrain); 153 char* cur_pos = constrain_begin + constrain_begin_len; 154 155 constrain_len = (constrain_end - constrain_begin) - constrain_begin_len; 156 157 while(cur_pos < constrain_end){ 158 if(isspace(*cur_pos)) 159 constrain_len--; 160 161 cur_pos++; 162 } 163 } 164 165 /* check all constraints */ 166 { 167 #define DRM_ALL_CONSTRAINT_COUNT 5 168 169 int32_t i = 0; 170 int32_t has_datetime = FALSE; 171 int32_t has_start_or_end = FALSE; 172 173 char* all_vaild_constraints[DRM_ALL_CONSTRAINT_COUNT][2] = { 174 {"<o-dd:count>","</o-dd:count>"}, 175 {"<o-dd:interval>","</o-dd:interval>"}, 176 {"<o-dd:datetime>","</o-dd:datetime>"}, 177 {"<o-dd:start>","</o-dd:start>"}, 178 {"<o-dd:end>","</o-dd:end>"} 179 }; 180 181 for(i = 0; i < DRM_ALL_CONSTRAINT_COUNT; i++){ 182 char*start = strstr((char*)drm_constrain,all_vaild_constraints[i][0]); 183 184 if(start && (start < constrain_end)){ 185 char* end = strstr((char*)drm_constrain,all_vaild_constraints[i][1]); 186 187 if(end && (end < constrain_end)){ 188 if(0 == strncmp(all_vaild_constraints[i][0],"<o-dd:datetime>",strlen("<o-dd:datetime>"))){ 189 constrain_len -= strlen(all_vaild_constraints[i][0]); 190 constrain_len -= strlen(all_vaild_constraints[i][1]); 191 192 if(0 == constrain_len) 193 return TRUE; 194 195 has_datetime = TRUE; 196 continue; 197 } 198 199 if((0 == strncmp(all_vaild_constraints[i][0],"<o-dd:start>",strlen("<o-dd:start>"))) 200 || (0 == strncmp(all_vaild_constraints[i][0],"<o-dd:end>",strlen("<o-dd:end>")))){ 201 if(FALSE == has_datetime) 202 return TRUE; 203 else 204 has_start_or_end = TRUE; 205 } 206 207 constrain_len -= (end - start); 208 constrain_len -= strlen(all_vaild_constraints[i][1]); 209 210 if(0 == constrain_len) 211 if(has_datetime != has_start_or_end) 212 return TRUE; 213 else 214 return FALSE; 215 } 216 else 217 return TRUE; 218 } 219 } 220 221 if(has_datetime != has_start_or_end) 222 return TRUE; 223 224 if(constrain_len) 225 return TRUE; 226 else 227 return FALSE; 228 } 229 } 230 231 static int32_t drm_getRightValue(uint8_t * buffer, int32_t bufferLen, 232 T_DRM_Rights * ro, uint8_t * operation, 233 uint8_t oper_char) 234 { 235 uint8_t *pBuf, *pValue; 236 uint8_t sProperty[256]; 237 int32_t valueLen; 238 int32_t year, mon, day, hour, min, sec; 239 T_DRM_Rights_Constraint *pConstraint; 240 int32_t *bIsAble; 241 uint8_t *ret = NULL; 242 int32_t flag = 0; 243 244 if (operation == NULL) { 245 switch (oper_char) { 246 case REL_TAG_PLAY: 247 pConstraint = &(ro->PlayConstraint); 248 bIsAble = &(ro->bIsPlayable); 249 break; 250 case REL_TAG_DISPLAY: 251 pConstraint = &(ro->DisplayConstraint); 252 bIsAble = &(ro->bIsDisplayable); 253 break; 254 case REL_TAG_EXECUTE: 255 pConstraint = &(ro->ExecuteConstraint); 256 bIsAble = &(ro->bIsExecuteable); 257 break; 258 case REL_TAG_PRINT: 259 pConstraint = &(ro->PrintConstraint); 260 bIsAble = &(ro->bIsPrintable); 261 break; 262 default: 263 return FALSE; /* The input parm is err */ 264 } 265 } else { 266 if (strcmp((char *)operation, "play") == 0) { 267 pConstraint = &(ro->PlayConstraint); 268 bIsAble = &(ro->bIsPlayable); 269 } else if (strcmp((char *)operation, "display") == 0) { 270 pConstraint = &(ro->DisplayConstraint); 271 bIsAble = &(ro->bIsDisplayable); 272 } else if (strcmp((char *)operation, "execute") == 0) { 273 pConstraint = &(ro->ExecuteConstraint); 274 bIsAble = &(ro->bIsExecuteable); 275 } else if (strcmp((char *)operation, "print") == 0) { 276 pConstraint = &(ro->PrintConstraint); 277 bIsAble = &(ro->bIsPrintable); 278 } else 279 return FALSE; /* The input parm is err */ 280 } 281 282 if (operation == NULL) { 283 sprintf((char *)sProperty, "%c%c%c%c", REL_TAG_RIGHTS, 284 REL_TAG_AGREEMENT, REL_TAG_PERMISSION, oper_char); 285 ret = WBXML_DOM_getNode(buffer, bufferLen, sProperty); 286 } else { 287 sprintf((char *)sProperty, 288 "o-ex:rights\\o-ex:agreement\\o-ex:permission\\o-dd:%s", 289 operation); 290 ret = XML_DOM_getNode(buffer, sProperty); 291 } 292 CHECK_VALIDITY(ret); 293 if (NULL == ret) 294 return TRUE; 295 WRITE_RO_FLAG(*bIsAble, 1, pConstraint->Indicator, DRM_NO_CONSTRAINT); /* If exit first assume have utter rights */ 296 flag = 1; 297 298 if (operation == NULL) { /* If father element node is not exit then return */ 299 sprintf((char *)sProperty, "%c%c%c%c%c", REL_TAG_RIGHTS, 300 REL_TAG_AGREEMENT, REL_TAG_PERMISSION, oper_char, 301 REL_TAG_CONSTRAINT); 302 ret = WBXML_DOM_getNode(buffer, bufferLen, sProperty); 303 } else { 304 sprintf((char *)sProperty, 305 "o-ex:rights\\o-ex:agreement\\o-ex:permission\\o-dd:%s\\o-ex:constraint", 306 operation); 307 ret = XML_DOM_getNode(buffer, sProperty); 308 } 309 310 CHECK_VALIDITY(ret); 311 if (ret == NULL) 312 return TRUE; 313 314 if(TRUE == drm_checkWhetherHasUnknowConstraint(ret)) 315 return FALSE; 316 317 *bIsAble = 0; 318 pConstraint->Indicator = DRM_NO_PERMISSION; /* If exit constraint assume have no rights */ 319 flag = 2; 320 321 if (operation == NULL) { 322 sprintf((char *)sProperty, "%c%c%c%c%c%c", REL_TAG_RIGHTS, 323 REL_TAG_AGREEMENT, REL_TAG_PERMISSION, oper_char, 324 REL_TAG_CONSTRAINT, REL_TAG_INTERVAL); 325 pBuf = 326 WBXML_DOM_getNodeValue(buffer, bufferLen, sProperty, (uint8_t **)&pValue, 327 &valueLen); 328 } else { 329 sprintf((char *)sProperty, 330 "o-ex:rights\\o-ex:agreement\\o-ex:permission\\o-dd:%s\\o-ex:constraint\\o-dd:interval", 331 operation); 332 pBuf = XML_DOM_getNodeValue(buffer, sProperty, &pValue, &valueLen); 333 } 334 CHECK_VALIDITY(pBuf); 335 if (pBuf) { /* If interval element exit then get the value */ 336 uint8_t pTmp[64] = {0}; 337 338 strncpy((char *)pTmp, (char *)pValue, valueLen); 339 { 340 uint8_t * pHead = pTmp + 1; 341 uint8_t * pEnd = NULL; 342 uint8_t tmpChar; 343 344 /** get year */ 345 pEnd = (uint8_t *)strstr((char *)pHead, "Y"); 346 if(NULL == pEnd) 347 return FALSE; 348 tmpChar = *pEnd; 349 *pEnd = '\0'; 350 year = atoi((char *)pHead); 351 pHead = pEnd + 1; 352 *pEnd = tmpChar; 353 354 /** get month */ 355 pEnd = (uint8_t *)strstr((char *)pHead, "M"); 356 if(NULL == pEnd) 357 return FALSE; 358 tmpChar = *pEnd; 359 *pEnd = '\0'; 360 mon = atoi((char *)pHead); 361 pHead = pEnd + 1; 362 *pEnd = tmpChar; 363 364 /** get day */ 365 pEnd = (uint8_t *)strstr((char *)pHead, "D"); 366 if(NULL == pEnd) 367 return FALSE; 368 tmpChar = *pEnd; 369 *pEnd = '\0'; 370 day = atoi((char *)pHead); 371 pHead = pEnd + 2; 372 *pEnd = tmpChar; 373 374 /** get hour */ 375 pEnd = (uint8_t *)strstr((char *)pHead, "H"); 376 if(NULL == pEnd) 377 return FALSE; 378 tmpChar = *pEnd; 379 *pEnd = '\0'; 380 hour = atoi((char *)pHead); 381 pHead = pEnd + 1; 382 *pEnd = tmpChar; 383 384 /** get minute */ 385 pEnd = (uint8_t *)strstr((char *)pHead, "M"); 386 if(NULL == pEnd) 387 return FALSE; 388 tmpChar = *pEnd; 389 *pEnd = '\0'; 390 min = atoi((char *)pHead); 391 pHead = pEnd + 1; 392 *pEnd = tmpChar; 393 394 /** get second */ 395 pEnd = (uint8_t *)strstr((char *)pHead, "S"); 396 if(NULL == pEnd) 397 return FALSE; 398 tmpChar = *pEnd; 399 *pEnd = '\0'; 400 sec = atoi((char *)pHead); 401 pHead = pEnd + 1; 402 *pEnd = tmpChar; 403 } 404 405 if (year < 0 || mon < 0 || day < 0 || hour < 0 406 || min < 0 || sec < 0) 407 return FALSE; 408 YMD_HMS_2_INT(year, mon, day, pConstraint->Interval.date, hour, 409 min, sec, pConstraint->Interval.time); 410 WRITE_RO_FLAG(*bIsAble, 1, pConstraint->Indicator, 411 DRM_INTERVAL_CONSTRAINT); 412 flag = 3; 413 } 414 415 if (operation == NULL) { 416 sprintf((char *)sProperty, "%c%c%c%c%c%c", REL_TAG_RIGHTS, 417 REL_TAG_AGREEMENT, REL_TAG_PERMISSION, oper_char, 418 REL_TAG_CONSTRAINT, REL_TAG_COUNT); 419 pBuf = 420 WBXML_DOM_getNodeValue(buffer, bufferLen, sProperty, (uint8_t **)&pValue, 421 &valueLen); 422 } else { 423 sprintf((char *)sProperty, 424 "o-ex:rights\\o-ex:agreement\\o-ex:permission\\o-dd:%s\\o-ex:constraint\\o-dd:count", 425 operation); 426 pBuf = XML_DOM_getNodeValue(buffer, sProperty, &pValue, &valueLen); 427 } 428 CHECK_VALIDITY(pBuf); 429 if (pBuf) { /* If count element exit the get the value */ 430 uint8_t pTmp[16] = {0}; 431 int32_t i; 432 433 for (i = 0; i < valueLen; i++) { /* Check the count format */ 434 if (0 == isdigit(*(pValue + i))) 435 return FALSE; 436 } 437 438 strncpy((char *)pTmp, (char *)pValue, valueLen); 439 pConstraint->Count = atoi((char *)pTmp); 440 441 if(0 == pConstraint->Count) 442 { 443 WRITE_RO_FLAG(*bIsAble, 0, pConstraint->Indicator, DRM_NO_PERMISSION); 444 } 445 else if( pConstraint->Count > 0) 446 { 447 WRITE_RO_FLAG(*bIsAble, 1, pConstraint->Indicator, DRM_COUNT_CONSTRAINT); 448 } 449 else /* < 0 */ 450 { 451 return FALSE; 452 } 453 454 flag = 3; 455 } 456 457 if (operation == NULL) { 458 sprintf((char *)sProperty, "%c%c%c%c%c%c%c", REL_TAG_RIGHTS, 459 REL_TAG_AGREEMENT, REL_TAG_PERMISSION, oper_char, 460 REL_TAG_CONSTRAINT, REL_TAG_DATETIME, REL_TAG_START); 461 pBuf = 462 WBXML_DOM_getNodeValue(buffer, bufferLen, sProperty, (uint8_t **)&pValue, 463 &valueLen); 464 } else { 465 sprintf((char *)sProperty, 466 "o-ex:rights\\o-ex:agreement\\o-ex:permission\\o-dd:%s\\o-ex:constraint\\o-dd:datetime\\o-dd:start", 467 operation); 468 pBuf = XML_DOM_getNodeValue(buffer, sProperty, &pValue, &valueLen); 469 } 470 CHECK_VALIDITY(pBuf); 471 if (pBuf) { /* If start element exit then get the value */ 472 if (FALSE == 473 drm_getStartEndTime(pValue, valueLen, &pConstraint->StartTime)) 474 return FALSE; 475 WRITE_RO_FLAG(*bIsAble, 1, pConstraint->Indicator, DRM_START_TIME_CONSTRAINT); 476 flag = 3; 477 } 478 479 if (operation == NULL) { 480 sprintf((char *)sProperty, "%c%c%c%c%c%c%c", REL_TAG_RIGHTS, 481 REL_TAG_AGREEMENT, REL_TAG_PERMISSION, oper_char, 482 REL_TAG_CONSTRAINT, REL_TAG_DATETIME, REL_TAG_END); 483 pBuf = 484 WBXML_DOM_getNodeValue(buffer, bufferLen, sProperty, (uint8_t **)&pValue, 485 &valueLen); 486 } else { 487 sprintf((char *)sProperty, 488 "o-ex:rights\\o-ex:agreement\\o-ex:permission\\o-dd:%s\\o-ex:constraint\\o-dd:datetime\\o-dd:end", 489 operation); 490 pBuf = XML_DOM_getNodeValue(buffer, sProperty, &pValue, &valueLen); 491 } 492 CHECK_VALIDITY(pBuf); 493 if (pBuf) { 494 if (FALSE == 495 drm_getStartEndTime(pValue, valueLen, &pConstraint->EndTime)) 496 return FALSE; 497 WRITE_RO_FLAG(*bIsAble, 1, pConstraint->Indicator, DRM_END_TIME_CONSTRAINT); 498 flag = 3; 499 } 500 501 if (2 == flag) 502 WRITE_RO_FLAG(*bIsAble, 1, pConstraint->Indicator, DRM_NO_CONSTRAINT); /* If exit first assume have utter rights */ 503 return TRUE; 504 } 505 506 /* See parser_rel.h */ 507 int32_t drm_relParser(uint8_t* buffer, int32_t bufferLen, int32_t Format, T_DRM_Rights* pRights) 508 { 509 uint8_t *pBuf, *pValue; 510 uint8_t sProperty[256]; 511 int32_t valueLen; 512 513 if (TYPE_DRM_RIGHTS_WBXML != Format && TYPE_DRM_RIGHTS_XML != Format) /* It is not the support parse format */ 514 return FALSE; 515 516 if (TYPE_DRM_RIGHTS_XML == Format) { 517 /* Check whether it is a CD, and parse it using TYPE_DRM_RIGHTS_XML */ 518 if (NULL != drm_strnstr(buffer, (uint8_t *)HEADERS_CONTENT_ID, bufferLen)) 519 return FALSE; 520 521 pBuf = 522 XML_DOM_getNodeValue(buffer, 523 (uint8_t *)"o-ex:rights\\o-ex:context\\o-dd:version", 524 &pValue, &valueLen); 525 CHECK_VALIDITY(pBuf); 526 527 if (pBuf) { 528 if (valueLen > 8) /* Check version lenth */ 529 return FALSE; 530 531 /* error version */ 532 if(strncmp(pValue,"1.0",valueLen)) 533 return FALSE; 534 535 strncpy((char *)pRights->Version, (char *)pValue, valueLen); 536 } else 537 return FALSE; 538 539 /* this means there is more than one version label in rights */ 540 if(strstr((char*)pBuf, "<o-dd:version>")) 541 return FALSE; 542 543 pBuf = 544 XML_DOM_getNodeValue(buffer, 545 (uint8_t *)"o-ex:rights\\o-ex:agreement\\o-ex:asset\\ds:KeyInfo\\ds:KeyValue", 546 &pValue, &valueLen); 547 CHECK_VALIDITY(pBuf); 548 if (pBuf) { /* Get keyvalue */ 549 int32_t keyLen; 550 551 if (24 != valueLen) 552 return FALSE; 553 554 keyLen = drm_decodeBase64(NULL, 0, pValue, &valueLen); 555 if (keyLen < 0) 556 return FALSE; 557 558 if (DRM_KEY_LEN != drm_decodeBase64(pRights->KeyValue, keyLen, pValue, &valueLen)) 559 return FALSE; 560 } 561 562 pBuf = 563 XML_DOM_getNodeValue(buffer, 564 (uint8_t *)"o-ex:rights\\o-ex:agreement\\o-ex:asset\\o-ex:context\\o-dd:uid", 565 &pValue, &valueLen); 566 CHECK_VALIDITY(pBuf); 567 if (pBuf) { 568 if (valueLen > DRM_UID_LEN) 569 return FALSE; 570 strncpy((char *)pRights->uid, (char *)pValue, valueLen); 571 pRights->uid[valueLen] = '\0'; 572 } else 573 return FALSE; 574 575 /* this means there is more than one uid label in rights */ 576 if(strstr((char*)pBuf, "<o-dd:uid>")) 577 return FALSE; 578 579 if (FALSE == 580 drm_getRightValue(buffer, bufferLen, pRights, (uint8_t *)"play", 0)) 581 return FALSE; 582 583 if (FALSE == 584 drm_getRightValue(buffer, bufferLen, pRights, (uint8_t *)"display", 0)) 585 return FALSE; 586 587 if (FALSE == 588 drm_getRightValue(buffer, bufferLen, pRights, (uint8_t *)"execute", 0)) 589 return FALSE; 590 591 if (FALSE == 592 drm_getRightValue(buffer, bufferLen, pRights, (uint8_t *)"print", 0)) 593 return FALSE; 594 } else if (TYPE_DRM_RIGHTS_WBXML == Format) { 595 if (!REL_CHECK_WBXML_HEADER(buffer)) 596 return FALSE; 597 598 sprintf((char *)sProperty, "%c%c%c", REL_TAG_RIGHTS, REL_TAG_CONTEXT, 599 REL_TAG_VERSION); 600 pBuf = 601 WBXML_DOM_getNodeValue(buffer, bufferLen, sProperty, (uint8_t **)&pValue, 602 &valueLen); 603 CHECK_VALIDITY(pBuf); 604 605 if (pBuf) { 606 if (valueLen > 8) /* Check version lenth */ 607 return FALSE; 608 strncpy((char *)pRights->Version, (char *)pValue, valueLen); 609 } else 610 return FALSE; 611 612 sprintf((char *)sProperty, "%c%c%c%c%c", 613 REL_TAG_RIGHTS, REL_TAG_AGREEMENT, REL_TAG_ASSET, 614 REL_TAG_KEYINFO, REL_TAG_KEYVALUE); 615 pBuf = 616 WBXML_DOM_getNodeValue(buffer, bufferLen, sProperty, (uint8_t **)&pValue, 617 &valueLen); 618 CHECK_VALIDITY(pBuf); 619 if (pBuf) { 620 if (DRM_KEY_LEN != valueLen) 621 return FALSE; 622 memcpy(pRights->KeyValue, pValue, DRM_KEY_LEN); 623 memset(pValue, 0, DRM_KEY_LEN); /* Clean the KeyValue */ 624 } 625 626 sprintf((char *)sProperty, "%c%c%c%c%c", 627 REL_TAG_RIGHTS, REL_TAG_AGREEMENT, REL_TAG_ASSET, 628 REL_TAG_CONTEXT, REL_TAG_UID); 629 pBuf = 630 WBXML_DOM_getNodeValue(buffer, bufferLen, sProperty, (uint8_t **)&pValue, 631 &valueLen); 632 CHECK_VALIDITY(pBuf); 633 if (pBuf) { 634 if (valueLen > DRM_UID_LEN) 635 return FALSE; 636 strncpy((char *)pRights->uid, (char *)pValue, valueLen); 637 pRights->uid[valueLen] = '\0'; 638 } else 639 return FALSE; 640 641 if (FALSE == 642 drm_getRightValue(buffer, bufferLen, pRights, NULL, 643 REL_TAG_PLAY)) 644 return FALSE; 645 646 if (FALSE == 647 drm_getRightValue(buffer, bufferLen, pRights, NULL, 648 REL_TAG_DISPLAY)) 649 return FALSE; 650 651 if (FALSE == 652 drm_getRightValue(buffer, bufferLen, pRights, NULL, 653 REL_TAG_EXECUTE)) 654 return FALSE; 655 656 if (FALSE == 657 drm_getRightValue(buffer, bufferLen, pRights, NULL, 658 REL_TAG_PRINT)) 659 return FALSE; 660 } 661 662 return TRUE; 663 } 664