// // Open Service Platform // Copyright (c) 2012 Samsung Electronics Co., Ltd. // // Licensed under the Apache License, Version 2.0 (the License); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // /** * @file PrivilegeHandler.cpp * @brief This is the implementation for the PrivilegeHandler class. */ #include #include #include #include #include #include #include #include #include #include "PrivilegeHandler.h" using namespace Tizen::App; using namespace Tizen::Base; using namespace Tizen::Base::Collection; using namespace Tizen::Base::Utility; using namespace Tizen::Security; using namespace Tizen::Security::Crypto; using namespace Tizen::Text; result PrivilegeHandler::GenerateCipherPrivilege(const AppId& appId, const IList& privilegeList, String& encryptedPrivileges, String& checksum) { result r = E_SUCCESS; byte* pBitwisePrivilege = null; int count = 0; SysLog(NID_SEC, "Enter."); encryptedPrivileges.Clear(); checksum.Clear(); count = privilegeList.GetCount(); if (count == 0) { goto CATCH; } pBitwisePrivilege = PackPrivilegeN(privilegeList); SysTryReturnResult(NID_SEC, pBitwisePrivilege != null, GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult())); r = GetEncryptedBitwise(pBitwisePrivilege, encryptedPrivileges); SysTryCatch(NID_SEC, r == E_SUCCESS, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred."); r = GetChecksum(appId, pBitwisePrivilege, checksum); SysTryCatch(NID_SEC, r == E_SUCCESS, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred."); // fall through CATCH: if (pBitwisePrivilege) { free(pBitwisePrivilege); } SysLog(NID_SEC, "Exit."); return r; } result PrivilegeHandler::GenerateCipherPrivilege(const AppId& appId, const IList& privilegeList, int visibilityLevel, String& encryptedPrivileges, String& checksum) { result r = E_SUCCESS; byte* pBitwisePrivilege = null; int count = 0; SysLog(NID_SEC, "Enter."); encryptedPrivileges.Clear(); checksum.Clear(); count = privilegeList.GetCount(); if (count == 0) { goto CATCH; } r = PackPrivilegeN(privilegeList, visibilityLevel, &pBitwisePrivilege); SysTryReturnResult(NID_SEC, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r)); r = GetEncryptedBitwise(pBitwisePrivilege, encryptedPrivileges); SysTryCatch(NID_SEC, r == E_SUCCESS, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred."); r = GetChecksum(appId, pBitwisePrivilege, checksum); SysTryCatch(NID_SEC, r == E_SUCCESS, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred."); // fall through CATCH: if (pBitwisePrivilege) { free(pBitwisePrivilege); } SysLog(NID_SEC, "Exit."); return r; } byte* PrivilegeHandler::PackPrivilegeN(const IList& privilegeList) { result r = E_SUCCESS; int index = 0; int privilegeEnum = 0; int position = 0; bool validStringFlag = false; bool resultFlag = true; byte privilegeBit = 0; byte* pResult = null; byte* pBitwisePrivilege = null; IEnumerator* pEnum = null; SysLog(NID_SEC, "Enter."); ClearLastResult(); pResult = (byte*) malloc(sizeof(byte) * MAX_BITWISE_PRIV_SIZE); SysTryReturn(NID_SEC, pResult != null, null, E_OUT_OF_MEMORY, "The memory is insufficient."); memset(pResult, 0, MAX_BITWISE_PRIV_SIZE); pEnum = privilegeList.GetEnumeratorN(); SysTryCatch(NID_SEC, pEnum != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred."); while (pEnum->MoveNext() == E_SUCCESS) { validStringFlag = false; String privilegeURI = L"http://tizen.org/privilege/"; String* pTempString = (String*) pEnum->GetCurrent(); if ((pTempString->GetLength()) < (privilegeURI.GetLength())) { SysLogException(NID_SEC, E_INVALID_ARG, "[E_INVALID_ARG] Invalid privilege string : %ls", pTempString->GetPointer()); resultFlag = false; continue; } String uriString; pTempString->SubString(0, privilegeURI.GetLength(), uriString); if (!(uriString.Equals(privilegeURI, true))) { SysLogException(NID_SEC, E_INVALID_ARG, "[E_INVALID_ARG] Invalid privilege string : %ls", pTempString->GetPointer()); resultFlag = false; continue; } String privilegeString; pTempString->SubString(privilegeURI.GetLength(), pTempString->GetLength()-privilegeURI.GetLength(), privilegeString); for (index = 0; index < _MAX_PRIVILEGE_ENUM; index++) { if (wcscmp(privilegeListTable[index].privilegeString, privilegeString.GetPointer()) == 0) { validStringFlag = true; privilegeEnum = static_cast< int >(privilegeListTable[index].privilege); position = privilegeEnum / _BITS_IN_BYTE; privilegeBit = (byte) (privilegeEnum % _BITS_IN_BYTE); pResult[position] = pResult[position] | (1 << privilegeBit); break; } } if (validStringFlag == false) { SysLogException(NID_SEC, E_INVALID_ARG, "[E_INVALID_ARG] Invalid privilege string : %ls", pTempString->GetPointer()); resultFlag = false; } } SysTryCatch(NID_SEC, resultFlag == true, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] One of privilege string is invalid."); pBitwisePrivilege = pResult; delete pEnum; SysLog(NID_SEC, "Exit."); return pBitwisePrivilege; CATCH: delete pEnum; free(pResult); SysLog(NID_SEC, "Exit."); return null; } result PrivilegeHandler::PackPrivilegeN(const IList& privilegeList, int visibilityLevel, byte** ppBitwisePrivilege) { result r = E_SUCCESS; int index = 0; int privilegeEnum = 0; int position = 0; bool validStringFlag = false; bool validLevelFlag = true; bool resultFlag = true; byte privilegeBit = 0; byte* pResult = null; IEnumerator* pEnum = null; SysLog(NID_SEC, "Enter."); ClearLastResult(); pResult = (byte*) malloc(sizeof(byte) * MAX_BITWISE_PRIV_SIZE); SysTryReturn(NID_SEC, pResult != null, null, E_OUT_OF_MEMORY, "The memory is insufficient."); memset(pResult, 0, MAX_BITWISE_PRIV_SIZE); pEnum = privilegeList.GetEnumeratorN(); SysTryCatch(NID_SEC, pEnum != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred."); while (pEnum->MoveNext() == E_SUCCESS) { validStringFlag = false; validLevelFlag = true; String privilegeURI = L"http://tizen.org/privilege/"; String* pTempString = (String*) pEnum->GetCurrent(); if ((pTempString->GetLength()) < (privilegeURI.GetLength())) { SysLogException(NID_SEC, E_INVALID_ARG, "[E_INVALID_ARG] Invalid privilege string : %ls", pTempString->GetPointer()); resultFlag = false; continue; } String uriString; pTempString->SubString(0, privilegeURI.GetLength(), uriString); if (!(uriString.Equals(privilegeURI, true))) { SysLogException(NID_SEC, E_INVALID_ARG, "[E_INVALID_ARG] Invalid privilege string : %ls", pTempString->GetPointer()); resultFlag = false; continue; } String privilegeString; pTempString->SubString(privilegeURI.GetLength(), pTempString->GetLength()-privilegeURI.GetLength(), privilegeString); for (index = 0; index < _MAX_PRIVILEGE_ENUM; index++) { if (wcscmp(privilegeListTable[index].privilegeString, privilegeString.GetPointer()) == 0) { validStringFlag = true; privilegeEnum = static_cast< int >(privilegeListTable[index].privilege); if (visibilityLevel != _API_VISIBILITY_NONE) { if (visibilityLevelListTable[privilegeEnum][_PRV_API_VER_2_0] > visibilityLevel) { validLevelFlag = false; break; } } position = privilegeEnum / _BITS_IN_BYTE; privilegeBit = (byte) (privilegeEnum % _BITS_IN_BYTE); pResult[position] = pResult[position] | (1 << privilegeBit); break; } } if (validStringFlag == false) { SysLogException(NID_SEC, E_INVALID_ARG, "[E_INVALID_ARG] Invalid privilege string : %ls", pTempString->GetPointer()); resultFlag = false; } if (validLevelFlag == false) { SysLogException(NID_SEC, E_INVALID_ARG, "[E_INVALID_ARG] The application does not have the visibility to register %ls", pTempString->GetPointer()); resultFlag = false; } } SysTryCatch(NID_SEC, resultFlag == true, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] One of privilege string is invalid."); *ppBitwisePrivilege = pResult; delete pEnum; SysLog(NID_SEC, "Exit.");; return r; CATCH: delete pEnum; free(pResult); SysLog(NID_SEC, "Exit."); return r; } result PrivilegeHandler::GetEncryptedBitwise(byte* pBitwisePrivilege, String& encryptedPrivileges) { result r = E_SUCCESS; ISecretKey* pKey = null; ByteBuffer ivByte; ByteBuffer* pEncryptedBitwisePrivilege = null; ByteBuffer* pTempBitwisePrivilege = null; AesCipher cipherEnc; const byte ivector[_IV_LEN] = { 0x3E, 0xB5, 0x01, 0x45, 0xE4, 0xF8, 0x75, 0x3F, 0x08, 0x9D, 0x9F, 0x57, 0x3B, 0x63, 0xEF, 0x4B}; SysLog(NID_SEC, "Enter."); pTempBitwisePrivilege = new (std::nothrow) ByteBuffer(); SysTryReturnResult(NID_SEC, pTempBitwisePrivilege != null, E_OUT_OF_MEMORY, "Memory allocation is failed."); r = pTempBitwisePrivilege->Construct(MAX_BITWISE_PRIV_SIZE); SysTryCatch(NID_SEC, r == E_SUCCESS, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred."); r = ivByte.Construct(_IV_LEN); SysTryCatch(NID_SEC, r == E_SUCCESS, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred."); r = ivByte.SetArray(ivector, 0, _IV_LEN); SysTryCatch(NID_SEC, r == E_SUCCESS, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred."); ivByte.Flip(); r = pTempBitwisePrivilege->SetArray(pBitwisePrivilege, 0, MAX_BITWISE_PRIV_SIZE); SysTryCatch(NID_SEC, r == E_SUCCESS, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred."); pTempBitwisePrivilege->Flip(); r = cipherEnc.Construct(L"CBC/128/PKCS7PADDING", CIPHER_ENCRYPT); SysTryCatch(NID_SEC, r == E_SUCCESS, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred."); pKey = _DeviceKeyGenerator::GenerateDeviceKeyN(_KEY_LEN); SysTryCatch(NID_SEC, pKey != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred."); r = cipherEnc.SetKey(*pKey); SysTryCatch(NID_SEC, r == E_SUCCESS, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred."); r = cipherEnc.SetInitialVector(ivByte); SysTryCatch(NID_SEC, r == E_SUCCESS, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred."); pEncryptedBitwisePrivilege = cipherEnc.EncryptN(*pTempBitwisePrivilege); SysTryCatch(NID_SEC, pEncryptedBitwisePrivilege != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred."); r = StringUtil::EncodeToBase64String(*pEncryptedBitwisePrivilege, encryptedPrivileges); SysTryCatch(NID_SEC, r == E_SUCCESS, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred."); // fall through CATCH: delete pTempBitwisePrivilege; delete pKey; delete pEncryptedBitwisePrivilege; SysLog(NID_SEC, "Exit."); return r; } result PrivilegeHandler::GetChecksum(AppId appId, byte* pBitwisePrivilege, String& checksum) { result r = E_SUCCESS; byte tempChecksumString[MAX_BITWISE_PRIV_SIZE + MAX_APP_ID_SIZE]; ISecretKey* pKey = null; ByteBuffer ivByte; ByteBuffer input; IHmac* pHmac = null; ByteBuffer* pChecksumByteBuffer = null; char* pAppId = null; pAppId = (char*) _StringConverter::CopyToCharArrayN(appId); SysTryCatch(NID_SEC, pAppId != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred."); memcpy(tempChecksumString, pAppId, MAX_APP_ID_SIZE); memcpy(tempChecksumString + MAX_APP_ID_SIZE, pBitwisePrivilege, MAX_BITWISE_PRIV_SIZE); delete[] pAppId; pAppId = null; r = input.Construct(MAX_APP_ID_SIZE + MAX_BITWISE_PRIV_SIZE); SysTryCatch(NID_SEC, r == E_SUCCESS, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred."); r = input.SetArray(tempChecksumString, 0, MAX_APP_ID_SIZE + MAX_BITWISE_PRIV_SIZE); SysTryCatch(NID_SEC, r == E_SUCCESS, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred."); input.Flip(); pHmac = new (std::nothrow) Sha1Hmac(); SysTryCatch(NID_SEC, pHmac != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation is failed."); pKey = _DeviceKeyGenerator::GenerateDeviceKeyN(_KEY_LEN); SysTryCatch(NID_SEC, pKey != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred."); r = pHmac->SetKey(*pKey); SysTryCatch(NID_SEC, r == E_SUCCESS, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred."); pChecksumByteBuffer = pHmac->GetHmacN(input); SysTryCatch(NID_SEC, pChecksumByteBuffer != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred."); r = StringUtil::EncodeToBase64String(*pChecksumByteBuffer, checksum); SysTryCatch(NID_SEC, r == E_SUCCESS, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred."); // fall through CATCH: delete pKey; delete pHmac; delete pChecksumByteBuffer; return r; }