Merge "Use atomic operation for Reference counting" into tizen_2.1
[platform/framework/native/appfw.git] / src / security / FSec_PrivilegeInfo.cpp
1 //
2 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
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 /**
18  * @file                FSec_PrivilegeManagerInfo.cpp
19  * @brief               This is the implementation for the Privilege Information class.
20  */
21
22 #include <unique_ptr.h>
23 #include <stdlib.h>
24 #include <dukgen.h>
25
26 #include <FBaseSysLog.h>
27 #include <FBase_StringConverter.h>
28 #include <FBaseString.h>
29 #include <FAppPkg_PackageInfoImpl.h>
30 #include <FSecSecretKey.h>
31 #include <FSecCryptoAesCipher.h>
32 #include <FSecCryptoSha1Hmac.h>
33 #include <FSecCryptoSha1Hash.h>
34 #include <FBaseColArrayList.h>
35
36 #include "FSec_PrivilegeInfo.h"
37
38 using namespace Tizen::App;
39 using namespace Tizen::App::Package;
40 using namespace Tizen::Base;
41 using namespace Tizen::Base::Collection;
42 using namespace Tizen::Base::Utility;
43 using namespace Tizen::Security::Crypto;
44 using namespace Tizen::Text;
45
46 namespace Tizen { namespace Security
47 {
48
49 _PrivilegeInfo::_PrivilegeInfo(void)
50 {
51         memset(__bitwisePrivilege, 0, MAX_BITWISE_PRIV_SIZE);
52         __bitwiseLength = 0;
53         __apiVisibility = 0;
54 }
55
56 _PrivilegeInfo::~_PrivilegeInfo(void)
57 {
58         __privilegeList.RemoveAll(true);
59 }
60
61 result
62 _PrivilegeInfo::Construct(const AppId& appId, const byte* pBitwisePrivilege, const ArrayList* pPrivilegeList)
63 {
64         result r = E_SUCCESS;
65
66         SysTryReturnResult(NID_SEC, (pBitwisePrivilege != null), E_INVALID_ARG, "One of the argument is invalid.");
67         SysTryReturnResult(NID_SEC,
68                                           appId.GetLength() > 0 && appId.GetLength() == MAX_APP_ID_SIZE, E_INVALID_ARG,
69                                           "One of the argument is invalid.");
70
71         // Set base length of privilege information to max
72         __bitwiseLength = MAX_BITWISE_PRIV_SIZE;
73
74         __appId = appId;
75         memcpy(__bitwisePrivilege, pBitwisePrivilege, __bitwiseLength);
76
77
78         std::unique_ptr<IEnumerator> pEnum(null);
79         r = __privilegeList.Construct();
80         SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
81
82         pEnum.reset(pPrivilegeList->GetEnumeratorN());
83         SysTryReturnResult(NID_SEC, pEnum != null, E_SYSTEM, "An unexpected system error occurred.");
84
85         while (pEnum->MoveNext() == E_SUCCESS)
86         {
87                 String* tempString = static_cast< String* >(pEnum->GetCurrent());
88                 __privilegeList.Add(new String(*tempString));
89         }
90
91         return r;
92 }
93
94 result
95 _PrivilegeInfo::Construct(const AppId& appId, const String& encryptedPrivileges, const String& checksum, const ArrayList* pPrivilegeList)
96 {
97         result r = E_SUCCESS;
98         byte* pDecrytpedBitwisePrivilege = null;
99
100         std::unique_ptr<ByteBuffer> pBitwisePrivilege(null);
101         _PackageInfoImpl infoImpl;
102
103         SysTryReturnResult(NID_SEC,
104                                           appId.GetLength() > 0 && appId.GetLength() == MAX_APP_ID_SIZE, E_INVALID_ARG,
105                                           "One of the argument is invalid.");
106         SysTryReturnResult(NID_SEC, encryptedPrivileges.GetLength() > 0, E_INVALID_ARG, "One of the argument is invalid.");
107         SysTryReturnResult(NID_SEC, checksum.GetLength() > 0, E_INVALID_ARG, "One of the argument is invalid.");
108
109         pBitwisePrivilege.reset(StringUtil::DecodeBase64StringN(encryptedPrivileges));
110         SysTryReturnResult(NID_SEC, pBitwisePrivilege != null, E_SYSTEM, "An unexpected system error occurred.");
111
112         pDecrytpedBitwisePrivilege = const_cast <byte*>(pBitwisePrivilege->GetPointer());
113         SysTryReturnResult(NID_SEC, pDecrytpedBitwisePrivilege != null, E_SYSTEM, "An unexpected system error occurred.");
114
115         r = VerifyIntegrity(appId, pDecrytpedBitwisePrivilege, checksum, pBitwisePrivilege->GetLimit());
116         SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_INVALID_ARG, "The checksum is abnormal.");
117
118         // Set base length of privilege information
119         __bitwiseLength = pBitwisePrivilege->GetLimit();
120
121         memcpy(__bitwisePrivilege, pDecrytpedBitwisePrivilege, __bitwiseLength);
122         __appId = appId;
123
124         r = infoImpl.Construct(appId);
125         if (r == E_APP_NOT_INSTALLED)
126         {
127                 SysLogException(NID_SEC, E_DATA_NOT_FOUND, "[E_DATA_NOT_FOUND] The package information does not exist.");
128                 return E_DATA_NOT_FOUND;
129         }
130         SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
131
132         __apiVisibility = infoImpl.GetApiVisibility();
133         SysTryReturnResult(NID_SEC, __apiVisibility >= 0, E_SYSTEM, "An unexpected system error occurred.");
134
135         std::unique_ptr<IEnumerator> pEnum(null);
136         r = __privilegeList.Construct();
137         SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
138
139         pEnum.reset(pPrivilegeList->GetEnumeratorN());
140         SysTryReturnResult(NID_SEC, pEnum != null, E_SYSTEM, "An unexpected system error occurred.");
141
142         while (pEnum->MoveNext() == E_SUCCESS)
143         {
144                 String* tempString = static_cast< String* >(pEnum->GetCurrent());
145                 __privilegeList.Add(new String(*tempString));
146         }
147
148         return r;
149 }
150
151 result
152 _PrivilegeInfo::Construct(const AppId& appId, const String& encryptedPrivileges, const String& checksum, const String& encryptedVisibiliity, const String& visibilityChecksum, const ArrayList* pPrivilegeList)
153 {
154         result r = E_SUCCESS;
155         byte* pDecrytpedBitwisePrivilege = null;
156         int visibility = 0;
157
158         ByteBuffer ivByte;
159         std::unique_ptr<ISecretKey> pKey(null);
160         std::unique_ptr<ByteBuffer> pEncryptedBitwisePrivilege(null);
161         std::unique_ptr<ByteBuffer> pBitwisePrivilege(null);
162         std::unique_ptr<ByteBuffer> pEncryptedVisibility(null);
163         std::unique_ptr<ByteBuffer> pVisibility(null);
164         AesCipher cipherDec;
165         _PackageInfoImpl infoImpl;
166         const byte ivector[_IV_LEN] =
167         {
168                 0x3E, 0xB5, 0x01, 0x45, 0xE4, 0xF8, 0x75, 0x3F,
169                 0x08, 0x9D, 0x9F, 0x57, 0x3B, 0x63, 0xEF, 0x4B
170         };
171
172         SysTryReturnResult(NID_SEC,
173                                           appId.GetLength() > 0 && appId.GetLength() == MAX_APP_ID_SIZE, E_INVALID_ARG,
174                                           "One of the argument is invalid.");
175         SysTryReturnResult(NID_SEC, encryptedPrivileges.GetLength() > 0, E_INVALID_ARG, "One of the argument is invalid.");
176         SysTryReturnResult(NID_SEC, checksum.GetLength() > 0, E_INVALID_ARG, "One of the argument is invalid.");
177
178         pEncryptedBitwisePrivilege.reset(StringUtil::DecodeBase64StringN(encryptedPrivileges));
179         SysTryReturnResult(NID_SEC, pEncryptedBitwisePrivilege != null, E_SYSTEM, "An unexpected system error occurred.");
180
181         pEncryptedVisibility.reset(StringUtil::DecodeBase64StringN(encryptedVisibiliity));
182         SysTryReturnResult(NID_SEC, pEncryptedVisibility != null, E_SYSTEM, "An unexpected system error occurred.");
183
184         r = ivByte.Construct(_IV_LEN);
185         SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
186
187         r = ivByte.SetArray(ivector, 0, _IV_LEN);
188         SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
189         ivByte.Flip();
190
191         r = cipherDec.Construct(L"CBC/128/PKCS7PADDING", CIPHER_DECRYPT);
192         SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
193
194         pKey.reset(GetDeviceUniqueKeyN());
195         SysTryReturnResult(NID_SEC, pKey != null, E_SYSTEM, "An unexpected system error occurred.");
196
197         r = cipherDec.SetKey(*pKey.get());
198         SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
199
200         r = cipherDec.SetInitialVector(ivByte);
201         SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
202
203         pBitwisePrivilege.reset(cipherDec.DecryptN(*pEncryptedBitwisePrivilege.get()));
204         SysTryReturnResult(NID_SEC, pBitwisePrivilege != null, E_SYSTEM, "An unexpected system error occurred.");
205
206         pVisibility.reset(cipherDec.DecryptN(*pEncryptedVisibility.get()));
207         SysTryReturnResult(NID_SEC, pBitwisePrivilege != null, E_SYSTEM, "An unexpected system error occurred.");
208
209         pDecrytpedBitwisePrivilege = const_cast <byte*>(pBitwisePrivilege->GetPointer());
210         SysTryReturnResult(NID_SEC, pDecrytpedBitwisePrivilege != null, E_SYSTEM, "An unexpected system error occurred.");
211
212         visibility = static_cast<int>(*(pVisibility->GetPointer()));
213
214         r = VerifyIntegrity(appId, pDecrytpedBitwisePrivilege, checksum, pBitwisePrivilege->GetLimit(), visibility, visibilityChecksum);
215         SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_INVALID_ARG, "The checksum is abnormal.");
216
217         // Set base length of privilege information
218         __bitwiseLength = pBitwisePrivilege->GetLimit();
219
220         memcpy(__bitwisePrivilege, pDecrytpedBitwisePrivilege, __bitwiseLength);
221         __appId = appId;
222
223         __apiVisibility = visibility;
224
225         std::unique_ptr<IEnumerator> pEnum(null);
226         r = __privilegeList.Construct();
227         SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
228
229         pEnum.reset(pPrivilegeList->GetEnumeratorN());
230         SysTryReturnResult(NID_SEC, pEnum != null, E_SYSTEM, "An unexpected system error occurred.");
231
232         while (pEnum->MoveNext() == E_SUCCESS)
233         {
234                 String* tempString = static_cast< String* >(pEnum->GetCurrent());
235                 __privilegeList.Add(new String(*tempString));
236         }
237
238         return r;
239 }
240
241
242 _PrivilegeInfo*
243 _PrivilegeInfo::CloneN(void) const
244 {
245         _PrivilegeInfo* pPrivilegeInfo = null;
246         result r = E_SUCCESS;
247
248         ClearLastResult();
249
250         pPrivilegeInfo = new (std::nothrow) _PrivilegeInfo();
251         SysTryReturn(NID_SEC, pPrivilegeInfo != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
252
253         pPrivilegeInfo->__bitwiseLength = this->__bitwiseLength;
254
255         pPrivilegeInfo->__appId.Clear();
256         pPrivilegeInfo->__appId.Append(this->__appId);
257         memcpy(pPrivilegeInfo->__bitwisePrivilege, this->__bitwisePrivilege, pPrivilegeInfo->__bitwiseLength);
258
259         std::unique_ptr<IEnumerator> pEnum(null);
260         r = pPrivilegeInfo->__privilegeList.Construct();
261         SysTryCatch(NID_SEC, r == E_SUCCESS, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
262
263         pEnum.reset(this->__privilegeList.GetEnumeratorN());
264         SysTryCatch(NID_SEC, r == E_SUCCESS, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
265
266         while (pEnum->MoveNext() == E_SUCCESS)
267         {
268                 String* tempString = static_cast< String* >(pEnum->GetCurrent());
269                 pPrivilegeInfo->__privilegeList.Add(new String(*tempString));
270         }
271
272         return pPrivilegeInfo;
273
274 CATCH:
275
276         SetLastResult(r);
277
278         delete pPrivilegeInfo;
279         return null;
280 }
281
282 result
283 _PrivilegeInfo::Construct(const _PrivilegeInfo& privilegeInfo)
284 {
285         result r = E_SUCCESS;
286
287         SysTryReturnResult(NID_SEC, privilegeInfo.__appId.GetLength() > 0 && privilegeInfo.__appId.GetLength() == MAX_APP_ID_SIZE, E_INVALID_ARG, "The argument is invalid.");
288
289         __bitwiseLength = privilegeInfo.__bitwiseLength;
290
291         __appId = privilegeInfo.__appId;
292         memcpy(__bitwisePrivilege, privilegeInfo.__bitwisePrivilege, __bitwiseLength);
293
294         __apiVisibility = privilegeInfo.__apiVisibility;
295
296         __privilegeList.Construct();
297
298         IEnumerator* pEnum = privilegeInfo.__privilegeList.GetEnumeratorN();
299         while (pEnum->MoveNext() == E_SUCCESS)
300         {
301                 String* tempString = static_cast< String* >(pEnum->GetCurrent());
302                 __privilegeList.Add(new String(*tempString));
303         }
304
305         delete pEnum;
306         return r;
307 }
308
309 const String
310 _PrivilegeInfo::GetAppId(void) const
311 {
312         return __appId;
313 }
314
315 result
316 _PrivilegeInfo::GetBitwisePrivilegeN(byte*& pBitwisePrivilege) const
317 {
318         byte* pReturn = null;
319         result r = E_SUCCESS;
320
321         pReturn = (byte*) malloc(sizeof(byte) * MAX_BITWISE_PRIV_SIZE);
322         SysTryReturnResult(NID_SEC, pReturn != null, E_OUT_OF_MEMORY, "Memory allocation is failed.");
323         memcpy(pReturn, __bitwisePrivilege, MAX_BITWISE_PRIV_SIZE);
324
325         pBitwisePrivilege = pReturn;
326
327         return r;
328 }
329
330 result
331 _PrivilegeInfo::GetEncryptedBitwise(String& encryptedPrivileges) const
332 {
333         result r = E_SUCCESS;
334         ByteBuffer ivByte;
335         std::unique_ptr<ISecretKey> pKey(null);
336         std::unique_ptr<ByteBuffer> pEncryptedBitwisePrivilege(null);
337         std::unique_ptr<ByteBuffer> pBitwisePrivilege(null);
338         AesCipher cipherEnc;
339         const byte ivector[_IV_LEN] = { 0x3E, 0xB5, 0x01, 0x45, 0xE4, 0xF8, 0x75, 0x3F, 0x08, 0x9D, 0x9F, 0x57, 0x3B, 0x63, 0xEF, 0x4B};
340
341         pBitwisePrivilege.reset(new (std::nothrow) ByteBuffer());
342         SysTryReturnResult(NID_SEC, pBitwisePrivilege != null, E_OUT_OF_MEMORY, "Memory allocation is failed.");
343
344         r = pBitwisePrivilege->Construct(__bitwiseLength);
345         SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
346
347         r = ivByte.Construct(_IV_LEN);
348         SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
349
350         r = ivByte.SetArray(ivector, 0, _IV_LEN);
351         SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
352         ivByte.Flip();
353
354         r = pBitwisePrivilege->SetArray(__bitwisePrivilege, 0, __bitwiseLength);
355         SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
356         pBitwisePrivilege->Flip();
357
358         r = cipherEnc.Construct(L"CBC/128/PKCS7PADDING", CIPHER_ENCRYPT);
359         SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
360
361         pKey.reset(GetDeviceUniqueKeyN());
362         SysTryReturnResult(NID_SEC, pKey != null, E_SYSTEM, "An unexpected system error occurred.");
363
364         r = cipherEnc.SetKey(*(pKey.get()));
365         SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
366
367         r = cipherEnc.SetInitialVector(ivByte);
368         SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
369
370         pEncryptedBitwisePrivilege.reset(cipherEnc.EncryptN(*(pBitwisePrivilege.get())));
371         SysTryReturnResult(NID_SEC, pEncryptedBitwisePrivilege != null, E_SYSTEM, "An unexpected system error occurred.");
372
373         r = StringUtil::EncodeToBase64String(*(pEncryptedBitwisePrivilege.get()), encryptedPrivileges);
374         SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
375
376         return r;
377 }
378
379 result
380 _PrivilegeInfo::GetChecksum(String& checksum) const
381 {
382         result r = E_SUCCESS;
383         byte tempChecksumString[MAX_BITWISE_PRIV_SIZE + MAX_APP_ID_SIZE];
384
385         ByteBuffer ivByte;
386         ByteBuffer input;
387         std::unique_ptr<ISecretKey> pKey(null);
388         std::unique_ptr<IHmac> pHmac(null);
389         std::unique_ptr<ByteBuffer> pChecksumByteBuffer(null);
390         std::unique_ptr<char[]> pAppId(null);
391
392         pAppId.reset(_StringConverter::CopyToCharArrayN(__appId));
393         SysTryReturnResult(NID_SEC, pAppId != null, E_SYSTEM, "An unexpected system error occurred.");
394
395         memcpy(tempChecksumString, pAppId.get(), MAX_APP_ID_SIZE);
396         memcpy(tempChecksumString + MAX_APP_ID_SIZE, __bitwisePrivilege, __bitwiseLength);
397
398         pAppId.reset(null);
399
400         r = input.Construct(MAX_APP_ID_SIZE + __bitwiseLength);
401         SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
402
403         r = input.SetArray(tempChecksumString, 0, MAX_APP_ID_SIZE + __bitwiseLength);
404         SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
405         input.Flip();
406
407         pHmac.reset(new (std::nothrow) Sha1Hmac());
408         SysTryReturnResult(NID_SEC, pHmac != null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation is failed.");
409
410         pKey.reset(GetDeviceUniqueKeyN());
411         SysTryReturnResult(NID_SEC, pKey != null, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
412
413         r = pHmac->SetKey(*(pKey.get()));
414         SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
415
416         pChecksumByteBuffer.reset(pHmac->GetHmacN(input));
417         SysTryReturnResult(NID_SEC, pChecksumByteBuffer != null, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
418
419         r = StringUtil::EncodeToBase64String(*(pChecksumByteBuffer.get()), checksum);
420         SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
421
422         return r;
423 }
424
425 bool
426 _PrivilegeInfo::HasPrivilege(_Privilege privilege) const
427 {
428         bool ret = false;
429         int targetIndex = static_cast< int >(privilege) / _BITS_IN_BYTE;
430         byte privilegeBit = (byte) (static_cast< int >(privilege) % _BITS_IN_BYTE);
431         byte bitwiseTargetPrivilege = 0;
432         byte tempBitwisePrivilege = 0;
433
434         if (__apiVisibility != _API_VISIBILITY_NONE) // To be removed
435         {
436                 if (visibilityLevelListTable[privilege][_PRV_API_VER_2_0] > __apiVisibility)
437                 {
438                         SysLog(NID_SEC, "Result : FALSE [Visibility]");
439                         return ret;
440                 }
441         }
442
443         bitwiseTargetPrivilege = bitwiseTargetPrivilege | (1 << privilegeBit);
444         tempBitwisePrivilege = __bitwisePrivilege[targetIndex] & bitwiseTargetPrivilege;
445
446         if (bitwiseTargetPrivilege == tempBitwisePrivilege)
447         {
448                 SysLog(NID_SEC, "Result : TRUE");
449                 ret = true;
450         }
451         else
452         {
453                 SysLogException(NID_SEC, E_PRIVILEGE_DENIED, "Result : FALSE [%ls, %ls]", __appId.GetPointer(), privilegeListTable[privilege].privilegeString);
454         }
455
456         return ret;
457 }
458
459 bool
460 _PrivilegeInfo::HasPrivilegeEx(_Privilege privilege) const
461 {
462         bool ret = false;
463         int targetIndex = static_cast< int >(privilege) / _BITS_IN_BYTE;
464         byte privilegeBit = (byte) (static_cast< int >(privilege) % _BITS_IN_BYTE);
465         byte bitwiseTargetPrivilege = 0;
466         byte tempBitwisePrivilege = 0;
467
468         if (__apiVisibility != _API_VISIBILITY_NONE) // To be removed
469         {
470                 if (visibilityLevelListTable[privilege][_PRV_API_VER_2_0] > __apiVisibility)
471                 {
472                         return ret;
473                 }
474         }
475
476         bitwiseTargetPrivilege = bitwiseTargetPrivilege | (1 << privilegeBit);
477         tempBitwisePrivilege = __bitwisePrivilege[targetIndex] & bitwiseTargetPrivilege;
478
479         if (bitwiseTargetPrivilege == tempBitwisePrivilege)
480         {
481                 SysLog(NID_SEC, "Result : TRUE");
482                 ret = true;
483         }
484
485         return ret;
486 }
487
488 bool
489 _PrivilegeInfo::HasPrivilege(const String& privilege) const
490 {
491     bool ret = false;
492     bool validStringFlag = false;
493     int privilegeEnum = -1;
494     int index = 0;
495
496         String privilegeURI = L"http://tizen.org/privilege/";
497     String privilegeSubString;
498     String privilegeSubStringURI;
499     privilege.SubString(0, privilegeURI.GetLength(), privilegeSubStringURI);
500
501     if (privilegeSubStringURI.Equals(privilegeURI, true))
502     {
503         privilege.SubString(privilegeURI.GetLength(), privilege.GetLength() - privilegeURI.GetLength(), privilegeSubString);
504         for (index = 0; index < _MAX_PRIVILEGE_ENUM; index++)
505                 {
506                         if (wcscmp(privilegeListTable[index].privilegeString, privilegeSubString.GetPointer()) == 0)
507                         {
508                                 validStringFlag = true;
509                                 privilegeEnum = index;
510                                 break;
511                         }
512                 }
513     }
514
515     if (validStringFlag)
516     {
517         ret = HasPrivilege(privilegeListTable[index].privilege);
518
519     }
520     else
521     {
522         ret = __privilegeList.Contains(privilege);
523         if (ret)
524                 {
525                         SysLog(NID_SEC, "Result : TRUE");
526                 }
527                 else
528                 {
529                         SysLogException(NID_SEC, E_PRIVILEGE_DENIED, "Result : FALSE [%ls, %ls]", __appId.GetPointer(), privilege.GetPointer());
530                 }
531     }
532
533         return ret;
534 }
535
536 result
537 _PrivilegeInfo::VerifyIntegrity(const AppId& appId, const byte* targetBitwisePrivilege, const Tizen::Base::String& storedChecksum, int length)
538 {
539         result r = E_SUCCESS;
540         bool verifyResult = false;
541         byte tempChecksumString[MAX_BITWISE_PRIV_SIZE + MAX_APP_ID_SIZE];
542         String base64EncodedChecksum;
543         ByteBuffer input;
544         std::unique_ptr<IHash> pHash(null);
545         std::unique_ptr<ByteBuffer> pChecksumByteBuffer(null);
546         std::unique_ptr<char> pAppId(null);
547
548         SysTryReturnResult(NID_SEC, length <= MAX_BITWISE_PRIV_SIZE, E_INVALID_ARG, "The privilege information of %ls is invalid.", appId.GetPointer());
549
550         pAppId.reset(_StringConverter::CopyToCharArrayN(appId));
551         SysTryReturnResult(NID_SEC, pAppId != null, E_SYSTEM, "An unexpected system error occurred.");
552
553         memcpy(tempChecksumString, pAppId.get(), MAX_APP_ID_SIZE);
554         memcpy(tempChecksumString + MAX_APP_ID_SIZE, targetBitwisePrivilege, length);
555
556         pAppId.reset(null);
557
558         r = input.Construct(MAX_APP_ID_SIZE + length);
559         SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
560
561         r = input.SetArray(tempChecksumString, 0, MAX_APP_ID_SIZE + length);
562         SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
563         input.Flip();
564
565         pHash.reset(new (std::nothrow) Sha1Hash());
566         SysTryReturnResult(NID_SEC, pHash != null, E_OUT_OF_MEMORY, "Memory allocation is failed.");
567
568         pChecksumByteBuffer.reset(pHash->GetHashN(input));
569         SysTryReturnResult(NID_SEC, pChecksumByteBuffer != null, E_SYSTEM, "An unexpected system error occurred.");
570
571         r = StringUtil::EncodeToBase64String(*(pChecksumByteBuffer.get()), base64EncodedChecksum);
572         SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
573
574         verifyResult = storedChecksum.Equals(base64EncodedChecksum, true);
575         if (verifyResult != true)
576         {
577                 r = E_INVALID_ARG;
578         }
579
580         return r;
581 }
582
583 result
584 _PrivilegeInfo::VerifyIntegrityEx(const AppId& appId, const byte* targetBitwisePrivilege, const Tizen::Base::String& storedChecksum, int length)
585 {
586         result r = E_SUCCESS;
587         bool verifyResult = false;
588         byte tempChecksumString[MAX_BITWISE_PRIV_SIZE + MAX_APP_ID_SIZE];
589         String base64EncodedChecksum;
590         ByteBuffer ivByte;
591         ByteBuffer input;
592         std::unique_ptr<IHmac> pHmac(null);
593         std::unique_ptr<ByteBuffer> pChecksumByteBuffer(null);
594         std::unique_ptr<ISecretKey> pKey(null);
595         std::unique_ptr<char[]> pAppId(null);
596
597         SysTryReturnResult(NID_SEC, length <= MAX_BITWISE_PRIV_SIZE, E_INVALID_ARG, "The privilege information of [%ls] is invalid.", appId.GetPointer());
598
599         pAppId.reset(_StringConverter::CopyToCharArrayN(appId));
600         SysTryReturnResult(NID_SEC, pAppId != null, E_SYSTEM, "An unexpected system error occurred.");
601
602         memcpy(tempChecksumString, pAppId.get(), MAX_APP_ID_SIZE);
603         memcpy(tempChecksumString + MAX_APP_ID_SIZE, targetBitwisePrivilege, length);
604
605         pAppId.reset(null);
606
607         r = input.Construct(MAX_APP_ID_SIZE + length);
608         SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
609
610         r = input.SetArray(tempChecksumString, 0, MAX_APP_ID_SIZE + length);
611         SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
612         input.Flip();
613
614         pHmac.reset(new (std::nothrow) Sha1Hmac());
615         SysTryReturnResult(NID_SEC, pHmac != null, E_OUT_OF_MEMORY, "Memory allocation is failed.");
616
617         pKey.reset(GetDeviceUniqueKeyN());
618         SysTryReturnResult(NID_SEC, pKey != null, E_SYSTEM, "An unexpected system error occurred.");
619
620         r = pHmac->SetKey(*(pKey.get()));
621         SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
622
623         pChecksumByteBuffer.reset(pHmac->GetHmacN(input));
624         SysTryReturnResult(NID_SEC, pChecksumByteBuffer != null, E_SYSTEM, "An unexpected system error occurred.");
625
626         r = StringUtil::EncodeToBase64String(*(pChecksumByteBuffer.get()), base64EncodedChecksum);
627         SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
628
629         verifyResult = storedChecksum.Equals(base64EncodedChecksum, true);
630         if (verifyResult != true)
631         {
632                 r = E_INVALID_ARG;
633         }
634
635         return r;
636 }
637
638 result
639 _PrivilegeInfo::VerifyIntegrity(const AppId& appId, const byte* targetBitwisePrivilege, const Tizen::Base::String& storedChecksum, int length, int visibility, const Tizen::Base::String& storedVisibilityChecksum)
640 {
641         result r = E_SUCCESS;
642         bool verifyResult = false;
643         byte tempChecksumString[MAX_BITWISE_PRIV_SIZE + MAX_APP_ID_SIZE];
644         byte tempVisibilityChecksumString[sizeof(int) + MAX_APP_ID_SIZE];
645         String base64EncodedChecksum;
646         String base64EncodedVisibilityChecksum;
647         ByteBuffer ivByte;
648         ByteBuffer input;
649         ByteBuffer visibilityInput;
650         std::unique_ptr<IHmac> pHmac(null);
651         std::unique_ptr<ByteBuffer> pChecksumByteBuffer(null);
652         std::unique_ptr<ByteBuffer> pVisibilityChecksumByteBuffer(null);
653         std::unique_ptr<ISecretKey> pKey(null);
654         std::unique_ptr<char[]> pAppId(null);
655
656         SysTryReturnResult(NID_SEC, length <= MAX_BITWISE_PRIV_SIZE, E_INVALID_ARG, "The privilege information of [%ls] is invalid.", appId.GetPointer());
657
658         pAppId.reset(_StringConverter::CopyToCharArrayN(appId));
659         SysTryReturnResult(NID_SEC, pAppId != null, E_SYSTEM, "An unexpected system error occurred.");
660
661         memcpy(tempChecksumString, pAppId.get(), MAX_APP_ID_SIZE);
662         memcpy(tempChecksumString + MAX_APP_ID_SIZE, targetBitwisePrivilege, length);
663
664         memcpy(tempVisibilityChecksumString, pAppId.get(), MAX_APP_ID_SIZE);
665         memcpy(tempVisibilityChecksumString + MAX_APP_ID_SIZE, (byte*)(&visibility), sizeof(int));
666
667         pAppId.reset(null);
668
669         r = input.Construct(MAX_APP_ID_SIZE + length);
670         SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
671
672         r = input.SetArray(tempChecksumString, 0, MAX_APP_ID_SIZE + length);
673         SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
674         input.Flip();
675
676         r = visibilityInput.Construct(MAX_APP_ID_SIZE + sizeof(int));
677         SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
678
679         r = visibilityInput.SetArray(tempVisibilityChecksumString, 0, MAX_APP_ID_SIZE + sizeof(int));
680         SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
681         visibilityInput.Flip();
682
683         pHmac.reset(new (std::nothrow) Sha1Hmac());
684         SysTryReturnResult(NID_SEC, pHmac != null, E_OUT_OF_MEMORY, "Memory allocation is failed.");
685
686         pKey.reset(GetDeviceUniqueKeyN());
687         SysTryReturnResult(NID_SEC, pKey != null, E_SYSTEM, "An unexpected system error occurred.");
688
689         r = pHmac->SetKey(*(pKey.get()));
690         SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
691
692         pChecksumByteBuffer.reset(pHmac->GetHmacN(input));
693         SysTryReturnResult(NID_SEC, pChecksumByteBuffer != null, E_SYSTEM, "An unexpected system error occurred.");
694
695         r = StringUtil::EncodeToBase64String(*(pChecksumByteBuffer.get()), base64EncodedChecksum);
696         SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
697
698         verifyResult = storedChecksum.Equals(base64EncodedChecksum, true);
699         if (verifyResult != true)
700         {
701                 r = E_INVALID_ARG;
702         }
703
704         pVisibilityChecksumByteBuffer.reset(pHmac->GetHmacN(visibilityInput));
705         SysTryReturnResult(NID_SEC, pChecksumByteBuffer != null, E_SYSTEM, "An unexpected system error occurred.");
706
707         r = StringUtil::EncodeToBase64String(*(pVisibilityChecksumByteBuffer.get()), base64EncodedVisibilityChecksum);
708         SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
709
710         verifyResult = storedVisibilityChecksum.Equals(base64EncodedVisibilityChecksum, true);
711         if (verifyResult != true)
712         {
713                 r = E_INVALID_ARG;
714         }
715
716         return r;
717 }
718
719 ISecretKey*
720 _PrivilegeInfo::GetDeviceUniqueKeyN(void)
721 {
722         result r = E_SUCCESS;
723         ByteBuffer* pTempValue = null;
724         ISecretKey* pKey = null;
725
726         char uniqueInfo[_INFO_LEN] =
727         {
728                 0x09, 0x25, 0x19, 0x87, 0xBF, 0x02, 0x14, 0x19,
729                 0x88, 0xDD, 0x12, 0x30, 0x19, 0x86, 0xAD, 0xED
730         };
731
732         char* pUniqueKey = null;
733         pUniqueKey = GetDeviceUniqueKey(uniqueInfo, _INFO_LEN, _KEY_LEN);
734         SysTryCatch(NID_SEC, pUniqueKey != null, , E_SYSTEM, "[E_SYSTEM] Failed to generate the unique key.");
735
736         pTempValue = new (std::nothrow) ByteBuffer();
737         SysTryCatch(NID_SEC, pTempValue != null, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
738
739         r = pTempValue->Construct(_KEY_LEN);
740         SysTryCatch(NID_SEC, r == E_SUCCESS, , r, "[%s] Failed to generate device unique key.", GetErrorMessage(r));
741
742         r = pTempValue->SetArray(reinterpret_cast <byte*>(pUniqueKey), 0, _KEY_LEN);
743         SysTryCatch(NID_SEC, r == E_SUCCESS, , r, "[%s] Failed to generate device unique key.", GetErrorMessage(r));
744
745         pTempValue->Flip();
746
747         pKey = new (std::nothrow) SecretKey();
748         SysTryCatch(NID_SEC, pKey != null, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
749
750         r = pKey->SetKey(*pTempValue);
751         SysTryCatch(NID_SEC, r == E_SUCCESS, , r, "[%s] Failed to generate device unique key.", GetErrorMessage(r));
752
753         if (pUniqueKey != null)
754         {
755                 free(pUniqueKey);
756         }
757         delete pTempValue;
758
759         return pKey;
760
761 CATCH:
762         if (pUniqueKey != null)
763         {
764                 free(pUniqueKey);
765         }
766         delete pTempValue;
767         delete pKey;
768
769         return null;
770 }
771
772 }} //Tizen::Security