Home | History | Annotate | Download | only in parser
      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