• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 */
drm_monthDays(int32_t year,int32_t month)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 
drm_checkDate(int32_t year,int32_t month,int32_t day,int32_t hour,int32_t min,int32_t sec)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 
drm_getStartEndTime(uint8_t * pValue,int32_t valueLen,T_DRM_DATETIME * dateTime)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 
drm_checkWhetherHasUnknowConstraint(uint8_t * drm_constrain)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 
drm_getRightValue(uint8_t * buffer,int32_t bufferLen,T_DRM_Rights * ro,uint8_t * operation,uint8_t oper_char)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 */
drm_relParser(uint8_t * buffer,int32_t bufferLen,int32_t Format,T_DRM_Rights * pRights)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