2f4d5a5e49f53631350f64fea661dc2e9f9911b6
[platform/framework/native/installer.git] / src / XmlHandler / PrivilegeHandler.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17 /**
18  * @file                PrivilegeHandler.cpp
19  * @brief               This is the implementation for the PrivilegeHandler class.
20  */
21
22 #include <stdlib.h>
23
24 #include <FBaseString.h>
25 #include <FBaseLog.h>
26 #include <FSecCryptoAesCipher.h>
27 #include <FSecCryptoSha1Hash.h>
28 #include <FBase_StringConverter.h>
29 #include <FBaseInternalTypes.h>
30 #include <FSec_AccessControlTypes.h>
31 #include <FSec_DeviceKeyGenerator.h>
32 #include <FIoFile.h>
33
34 #include "InstallerDefs.h"
35 #include "PrivilegeHandler.h"
36 #include "InstallerUtil.h"
37
38 using namespace Tizen::App;
39 using namespace Tizen::Base;
40 using namespace Tizen::Base::Collection;
41 using namespace Tizen::Base::Utility;
42 using namespace Tizen::Security;
43 using namespace Tizen::Security::Crypto;
44 using namespace Tizen::Text;
45 using namespace Tizen::Io;
46
47
48 result
49 PrivilegeHandler::PickExternalPrivilege(const IList& fullPrivilegeList, IList& normalPrivilegeList, IList& externalPrivilegeList)
50 {
51         result r = E_SUCCESS;
52         File file;
53         String externalPrivilege;
54         ArrayList privilegeList;
55
56         r = file.Construct(EXTERNAL_PRIVILEGE_FILE_NAME, "r");
57         TryReturnResultTag(OSP_INSTALLER, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
58
59         privilegeList.Construct();
60
61         while (file.Read(externalPrivilege) == E_SUCCESS)
62         {
63                 externalPrivilege.Remove(externalPrivilege.GetLength()-1, 1);
64                 privilegeList.Add(new String(externalPrivilege));
65         }
66
67         IEnumerator* pEnum = fullPrivilegeList.GetEnumeratorN();
68
69         while(pEnum->MoveNext() == E_SUCCESS)
70         {
71                 String* tempString = static_cast<String*>(pEnum->GetCurrent());
72
73                 if (privilegeList.Contains(*tempString))
74                 {
75                         externalPrivilegeList.Add(new String(*tempString));
76                 }
77                 else
78                 {
79                         normalPrivilegeList.Add(new String(*tempString));
80                 }
81         }
82
83         delete pEnum;
84         privilegeList.RemoveAll(true);
85         return r;
86 }
87
88 result
89 PrivilegeHandler::GenerateCipherPrivilege(const AppId& appId, const IList& privilegeList, String& encryptedPrivileges, String& checksum, IList& stringPrivilegeList)
90 {
91         result r = E_SUCCESS;
92         byte* pBitwisePrivilege = null;
93         int count = 0;
94         ArrayList normalPrivilegeList;
95
96         encryptedPrivileges.Clear();
97         checksum.Clear();
98         normalPrivilegeList.Construct();
99
100         count = privilegeList.GetCount();
101         if (count == 0)
102         {
103                 goto CATCH;
104         }
105
106         r = PickExternalPrivilege(privilegeList, normalPrivilegeList, stringPrivilegeList);
107         TryReturnResultTag(OSP_INSTALLER, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
108
109         pBitwisePrivilege = PackPrivilegeN(normalPrivilegeList);
110         TryReturnResultTag(OSP_INSTALLER, pBitwisePrivilege != null, GetLastResult(), GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
111
112         r = GetEncryptedBitwise(pBitwisePrivilege, encryptedPrivileges);
113         TryCatchTag(OSP_INSTALLER, r == E_SUCCESS, r = E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
114
115         r = GetChecksum(appId, pBitwisePrivilege, checksum);
116         TryCatchTag(OSP_INSTALLER, r == E_SUCCESS, r = E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
117
118         // fall through
119
120 CATCH:
121
122         if (pBitwisePrivilege)
123         {
124                 free(pBitwisePrivilege);
125         }
126
127         normalPrivilegeList.RemoveAll(true);
128         return r;
129 }
130
131 result
132 PrivilegeHandler::GenerateCipherPrivilege(const AppId& appId, const IList& privilegeList, int visibilityLevel, String& encryptedPrivileges, String& checksum, IList& stringPrivilegeList)
133 {
134         result r = E_SUCCESS;
135         byte* pBitwisePrivilege = null;
136         int count = 0;
137         ArrayList normalPrivilegeList;
138
139         encryptedPrivileges.Clear();
140         checksum.Clear();
141         normalPrivilegeList.Construct();
142
143         count = privilegeList.GetCount();
144         if (count == 0)
145         {
146                 goto CATCH;
147         }
148
149         r = PickExternalPrivilege(privilegeList, normalPrivilegeList, stringPrivilegeList);
150         TryReturnResultTag(OSP_INSTALLER, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
151
152         r = PackPrivilegeN(normalPrivilegeList, visibilityLevel, &pBitwisePrivilege);
153         TryReturnResultTag(OSP_INSTALLER, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
154
155         r = GetEncryptedBitwise(pBitwisePrivilege, encryptedPrivileges);
156         TryCatchTag(OSP_INSTALLER, r == E_SUCCESS, r = E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
157
158         r = GetChecksum(appId, pBitwisePrivilege, checksum);
159         TryCatchTag(OSP_INSTALLER, r == E_SUCCESS, r = E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
160
161         // fall through
162
163 CATCH:
164
165         if (pBitwisePrivilege)
166         {
167                 free(pBitwisePrivilege);
168         }
169
170         normalPrivilegeList.RemoveAll(true);
171         return r;
172 }
173
174 byte*
175 PrivilegeHandler::PackPrivilegeN(const IList& privilegeList)
176 {
177         result r = E_SUCCESS;
178         int index = 0;
179         int privilegeEnum = 0;
180         int position = 0;
181         bool validStringFlag = false;
182         bool resultFlag = true;
183         byte privilegeBit = 0;
184         byte* pResult = null;
185         byte* pBitwisePrivilege = null;
186         IEnumerator* pEnum = null;
187
188         ClearLastResult();
189
190         pResult = (byte*) malloc(sizeof(byte) * MAX_BITWISE_PRIV_SIZE);
191         TryReturnResultTag(OSP_INSTALLER, pResult != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
192
193         memset(pResult, 0, MAX_BITWISE_PRIV_SIZE);
194
195         pEnum = privilegeList.GetEnumeratorN();
196         TryCatch(pEnum != null, r = E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
197
198         while (pEnum->MoveNext() == E_SUCCESS)
199         {
200                 validStringFlag = false;
201                 String privilegeURI = L"http://tizen.org/privilege/";
202
203                 String* pTempString = (String*) pEnum->GetCurrent();
204
205                 if ((pTempString->GetLength()) < (privilegeURI.GetLength()))
206                 {
207                         AppLogExceptionTag(OSP_INSTALLER, "[E_INVALID_ARG] Invalid privilege string (Length error): [%ls]", pTempString->GetPointer());
208                         resultFlag = false;
209                         continue;
210                 }
211
212                 String uriString;
213                 pTempString->SubString(0, privilegeURI.GetLength(), uriString);
214
215                 if (!(uriString.Equals(privilegeURI, true)))
216                 {
217                         AppLogExceptionTag(OSP_INSTALLER, "[E_INVALID_ARG] Invalid privilege string (URI error): [%ls]", pTempString->GetPointer());
218                         resultFlag = false;
219                         continue;
220                 }
221
222                 String privilegeString;
223                 pTempString->SubString(privilegeURI.GetLength(), pTempString->GetLength()-privilegeURI.GetLength(), privilegeString);
224
225                 for (index = 0; index < _MAX_PRIVILEGE_ENUM; index++)
226                 {
227                         if (wcscmp(privilegeListTable[index].privilegeString, privilegeString.GetPointer()) == 0)
228                         {
229                                 validStringFlag = true;
230                                 privilegeEnum = static_cast< int >(privilegeListTable[index].privilege);
231
232                                 position = privilegeEnum / _BITS_IN_BYTE;
233                                 privilegeBit = (byte) (privilegeEnum % _BITS_IN_BYTE);
234                                 pResult[position] = pResult[position] | (1 << privilegeBit);
235                                 break;
236                         }
237                 }
238
239                 if (validStringFlag == false)
240                 {
241                         AppLogExceptionTag(OSP_INSTALLER, "[E_INVALID_ARG] Invalid privilege string: [%ls]", pTempString->GetPointer());
242                         resultFlag = false;
243                 }
244         }
245
246         TryCatchTag(OSP_INSTALLER, resultFlag == true, r = E_INVALID_ARG, "[E_INVALID_ARG] One of privilege string is invalid.");
247
248         pBitwisePrivilege = pResult;
249
250         delete pEnum;
251
252         return pBitwisePrivilege;
253
254 CATCH:
255
256         delete pEnum;
257         free(pResult);
258
259         SetLastResult(r);
260
261         return null;
262 }
263
264 result
265 PrivilegeHandler::PackPrivilegeN(const IList& privilegeList, int visibilityLevel, byte** ppBitwisePrivilege)
266 {
267         result r = E_SUCCESS;
268         int index = 0;
269         int privilegeEnum = 0;
270         int position = 0;
271         bool validStringFlag = false;
272         bool validLevelFlag = true;
273         bool resultFlag = true;
274         bool resultLevelFlag = true;
275         byte privilegeBit = 0;
276         byte* pResult = null;
277         IEnumerator* pEnum = null;
278
279         ClearLastResult();
280
281         pResult = (byte*) malloc(sizeof(byte) * MAX_BITWISE_PRIV_SIZE);
282         TryReturnResultTag(OSP_INSTALLER, pResult != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
283
284         memset(pResult, 0, MAX_BITWISE_PRIV_SIZE);
285
286         pEnum = privilegeList.GetEnumeratorN();
287         TryCatchTag(OSP_INSTALLER, pEnum != null, r = E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
288
289         while (pEnum->MoveNext() == E_SUCCESS)
290         {
291                 validStringFlag = false;
292                 validLevelFlag = true;
293
294                 String privilegeURI = L"http://tizen.org/privilege/";
295
296                 String* pTempString = (String*) pEnum->GetCurrent();
297
298                 if ((pTempString->GetLength()) < (privilegeURI.GetLength()))
299                 {
300                         AppLogExceptionTag(OSP_INSTALLER, "[E_INVALID_ARG] Invalid privilege string (Length error): [%ls]", pTempString->GetPointer());
301                         resultFlag = false;
302                         continue;
303                 }
304
305                 String uriString;
306                 pTempString->SubString(0, privilegeURI.GetLength(), uriString);
307
308                 if (!(uriString.Equals(privilegeURI, true)))
309                 {
310                         AppLogExceptionTag(OSP_INSTALLER, "[E_INVALID_ARG] Invalid privilege string (URI error): [%ls]", pTempString->GetPointer());
311                         resultFlag = false;
312                         continue;
313                 }
314
315                 String privilegeString;
316                 pTempString->SubString(privilegeURI.GetLength(), pTempString->GetLength()-privilegeURI.GetLength(), privilegeString);
317
318                 for (index = 0; index < _MAX_PRIVILEGE_ENUM; index++)
319                 {
320                         if (wcscmp(privilegeListTable[index].privilegeString, privilegeString.GetPointer()) == 0)
321                         {
322                                 validStringFlag = true;
323                                 privilegeEnum = static_cast< int >(privilegeListTable[index].privilege);
324
325                                 if (visibilityLevel != _API_VISIBILITY_NONE)
326                                 {
327                                         if (visibilityLevelListTable[privilegeEnum][_PRV_API_VER_2_0] > visibilityLevel)
328                                         {
329                                                 validLevelFlag = false;
330                                                 break;
331                                         }
332                                 }
333
334                                 position = privilegeEnum / _BITS_IN_BYTE;
335                                 privilegeBit = (byte) (privilegeEnum % _BITS_IN_BYTE);
336                                 pResult[position] = pResult[position] | (1 << privilegeBit);
337                                 break;
338                         }
339                 }
340
341                 if (validStringFlag == false)
342                 {
343                         AppLogExceptionTag(OSP_INSTALLER, "[E_INVALID_ARG] Invalid privilege string: [%ls]", pTempString->GetPointer());
344                         resultFlag = false;
345                 }
346
347                 if (validLevelFlag == false)
348                 {
349                         AppLogExceptionTag(OSP_INSTALLER, "[E_ILLEGAL_ACCESS] The application does not have the privilege level to register [%ls]", pTempString->GetPointer());
350                         resultLevelFlag = false;
351                 }
352         }
353
354         TryCatchTag(OSP_INSTALLER, resultLevelFlag == true, r = E_ILLEGAL_ACCESS, "[E_ILLEGAL_ACCESS] Unauthorized privileges are detected.");
355         TryCatchTag(OSP_INSTALLER, resultFlag == true, r = E_INVALID_ARG, "[E_INVALID_ARG] Unsupported privilege strings are detected.");
356
357         *ppBitwisePrivilege = pResult;
358
359         delete pEnum;
360
361         return r;
362
363 CATCH:
364
365         delete pEnum;
366         free(pResult);
367
368         return r;
369 }
370
371
372 result
373 PrivilegeHandler::GetEncryptedBitwise(byte* pBitwisePrivilege, String& encryptedPrivileges)
374 {
375         result r = E_SUCCESS;
376         ByteBuffer* pTempBitwisePrivilege = null;
377
378         pTempBitwisePrivilege = new (std::nothrow) ByteBuffer();
379         TryReturnResultTag(OSP_INSTALLER, pTempBitwisePrivilege != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation is failed.");
380
381         r = pTempBitwisePrivilege->Construct(MAX_BITWISE_PRIV_SIZE);
382         TryCatchTag(OSP_INSTALLER, r == E_SUCCESS, r = E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
383
384         r = pTempBitwisePrivilege->SetArray(pBitwisePrivilege, 0, MAX_BITWISE_PRIV_SIZE);
385         TryCatchTag(OSP_INSTALLER, r == E_SUCCESS, r = E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
386         pTempBitwisePrivilege->Flip();
387
388         r = StringUtil::EncodeToBase64String(*pTempBitwisePrivilege, encryptedPrivileges);
389         TryCatchTag(OSP_INSTALLER, r == E_SUCCESS, r = E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
390
391         // fall through
392
393 CATCH:
394
395         delete pTempBitwisePrivilege;
396
397         return r;
398 }
399
400 result
401 PrivilegeHandler::GetChecksum(AppId appId, byte* pBitwisePrivilege, String& checksum)
402 {
403         result r = E_SUCCESS;
404         byte tempChecksumString[MAX_BITWISE_PRIV_SIZE + MAX_APP_ID_SIZE];
405
406         ByteBuffer input;
407         IHash* pHash = null;
408         ByteBuffer* pChecksumByteBuffer = null;
409         char* pAppId = null;
410
411         pAppId = (char*) _StringConverter::CopyToCharArrayN(appId);
412         TryCatchTag(OSP_INSTALLER, pAppId != null, r = E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
413
414         memcpy(tempChecksumString, pAppId, MAX_APP_ID_SIZE);
415         memcpy(tempChecksumString + MAX_APP_ID_SIZE, pBitwisePrivilege, MAX_BITWISE_PRIV_SIZE);
416
417         delete[] pAppId;
418         pAppId = null;
419
420         r = input.Construct(MAX_APP_ID_SIZE + MAX_BITWISE_PRIV_SIZE);
421         TryCatchTag(OSP_INSTALLER, r == E_SUCCESS, r = E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
422
423         r = input.SetArray(tempChecksumString, 0, MAX_APP_ID_SIZE + MAX_BITWISE_PRIV_SIZE);
424         TryCatchTag(OSP_INSTALLER, r == E_SUCCESS, r = E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
425         input.Flip();
426
427         pHash = new (std::nothrow) Sha1Hash();
428         TryCatchTag(OSP_INSTALLER, pHash != null, r = E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation is failed.");
429
430         pChecksumByteBuffer = pHash->GetHashN(input);
431         TryCatchTag(OSP_INSTALLER, pChecksumByteBuffer != null, r = E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
432
433         r = StringUtil::EncodeToBase64String(*pChecksumByteBuffer, checksum);
434         TryCatchTag(OSP_INSTALLER, r == E_SUCCESS, r = E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
435
436         // fall through
437
438 CATCH:
439
440         delete pHash;
441         delete pChecksumByteBuffer;
442
443         return r;
444 }