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 <dcf/DrmRawContent.h>
18
19
DrmRawContent(istream & inRawData)20 DrmRawContent::DrmRawContent(istream& inRawData)
21 {
22 uint32_t count = inRawData.stream_size();
23
24 if (count <= MAX_PIECE_LEN)
25 {
26 uint8_t* data = new uint8_t[count];
27
28 if(!data)
29 {
30 return;
31 }
32
33 inRawData.read(data,count);
34
35 const uint8_t* dcf = data;
36
37 //parse DCF file header
38 if(false == parseDcfHeader(dcf))
39 {
40 delete []data;
41 return;
42 }
43
44 dcf = data;
45 dcf += FIX_HEADER_LEN;
46
47 if(dcf >= (data + count))
48 {
49 return;
50 }
51
52 // parse container box
53 FullBox conFullBox(dcf);
54
55 if(DCF_CONTAINER_BOX != conFullBox.getType())
56 {
57 return;
58 }
59
60 //check whether it is multipart DCF or not
61 do
62 {
63 uint64_t size = conFullBox.getSize();
64
65 mContainer.push_back(new DcfContainer(dcf,inRawData,dcf-data));
66
67 dcf += size;
68
69 // come to the end of raw content
70 if(dcf >= (data + count))
71 {
72 break;
73 }
74
75 conFullBox = FullBox(dcf);
76 }while(DCF_CONTAINER_BOX == conFullBox.getType());
77
78 // compute DCF hash using Sha1Agent
79 Sha1Agent drmSha1Hash;
80 drmSha1Hash.computeHash(data,dcf-data,mDcfHash);
81
82 //// parse mutable box
83
84 delete []data;
85 }
86 }
87
~DrmRawContent()88 DrmRawContent::~DrmRawContent()
89 {
90 uint32_t size = mContainer.size();
91
92 for(uint32_t i = 0; i < size; i++)
93 {
94 delete mContainer[i];
95 }
96
97 mContainer.clear();
98 }
99
getContents(void) const100 vector<DcfContainer*> DrmRawContent::getContents(void) const
101 {
102 return mContainer;
103 }
104
getDcfHashLen() const105 uint32_t DrmRawContent::getDcfHashLen() const
106 {
107 return DCF_HASH_LEN;
108 }
109
getDcfHash(uint8_t * outDcfHash) const110 void DrmRawContent::getDcfHash(uint8_t* outDcfHash) const
111 {
112 if(outDcfHash)
113 {
114 memcpy(outDcfHash,mDcfHash,DCF_HASH_LEN);
115 }
116
117 return;
118 }
119
parseDcfHeader(const uint8_t * dcfHead)120 bool DrmRawContent::parseDcfHeader(const uint8_t* dcfHead)
121 {
122 if(!dcfHead)
123 {
124 return false;
125 }
126
127 if(FIX_HEADER_LEN != ntohl(*(uint32_t *)dcfHead))
128 {
129 return false;
130 }
131
132 dcfHead += 4;
133 uint32_t type = *(uint32_t *)dcfHead;
134
135 if(DCF_FILE_TYPE != type)
136 {
137 return false;
138 }
139
140 dcfHead += 4;
141 type = *(uint32_t *)dcfHead;
142
143 if(DCF_FILE_BRAND != type)
144 {
145 return false;
146 }
147
148 dcfHead += 4;
149 if(2 != ntohl(*(uint32_t *)dcfHead))
150 {
151 return false;
152 }
153
154 dcfHead += 4;
155 type = *(uint32_t *)dcfHead;
156
157 if(DCF_FILE_BRAND != type)
158 {
159 return false;
160 }
161
162 dcfHead += 4;
163 return true;
164 }
165