tizen 2.4 release
[framework/security/key-manager.git] / src / manager / service / ckm-logic.cpp
index b324a20..e3b4544 100644 (file)
@@ -60,20 +60,40 @@ CKMLogic::CKMLogic()
 
 CKMLogic::~CKMLogic(){}
 
-void CKMLogic::loadDKEKFile(uid_t user, const Password &password, bool apiReq) {
-    auto &handle = m_userDataMap[user];
+void CKMLogic::loadDKEKFile(
+    const ClientID &clientID,
+    const Password &password,
+    bool apiReq)
+{
+    auto &handle = m_userDataMap[clientID];
 
-    FileSystem fs(user);
+    FileSystem fs(clientID);
 
     auto wrappedDKEKMain = fs.getDKEK();
     auto wrappedDKEKBackup = fs.getDKEKBackup();
 
+#ifdef PASSWORD_PROTECTION_DISABLE
+    if (wrappedDKEKMain.empty()) {
+        wrappedDKEKMain = KeyProvider::generateDomainKEK(clientID, Password(""));
+        fs.saveDKEK(wrappedDKEKMain);
+    }
+
+    try{
+        chooseDKEKFile(handle, Password(""), wrappedDKEKMain, wrappedDKEKBackup);
+    } catch (const KeyProvider::Exception::Base &e) {
+        chooseDKEKFile(handle, password, wrappedDKEKMain, wrappedDKEKBackup);
+        fs.saveDKEK(handle.keyProvider.getWrappedDomainKEK(Password("")));
+        handle.isMainDKEK = true;
+        LogInfo("Password Protected DB was migrated to Password Protection Disabled DB.");
+    }
+#else
     if (wrappedDKEKMain.empty()) {
-        wrappedDKEKMain = KeyProvider::generateDomainKEK(std::to_string(user), password);
+        wrappedDKEKMain = KeyProvider::generateDomainKEK(clientID, password);
         fs.saveDKEK(wrappedDKEKMain);
     }
 
     chooseDKEKFile(handle, password, wrappedDKEKMain, wrappedDKEKBackup);
+#endif
 
     if (!password.empty() || apiReq) {
         handle.isDKEKConfirmed = true;
@@ -103,10 +123,10 @@ void CKMLogic::chooseDKEKFile(
     }
 }
 
-void CKMLogic::saveDKEKFile(uid_t user, const Password &password) {
-    auto &handle = m_userDataMap[user];
+void CKMLogic::saveDKEKFile(const ClientID &clientID, const Password &password) {
+    auto &handle = m_userDataMap[clientID];
 
-    FileSystem fs(user);
+    FileSystem fs(clientID);
     if (handle.isMainDKEK)
         fs.createDKEKBackup();
 
@@ -116,20 +136,24 @@ void CKMLogic::saveDKEKFile(uid_t user, const Password &password) {
     handle.isDKEKConfirmed = false;
 }
 
-RawBuffer CKMLogic::unlockUserKey(uid_t user, const Password &password, bool apiRequest) {
+RawBuffer CKMLogic::unlockUserKey(
+    const ClientID &clientID,
+    const Password &password,
+    bool apiRequest)
+{
     int retCode = CKM_API_SUCCESS;
 
     try {
-        if (0 == m_userDataMap.count(user) || !(m_userDataMap[user].keyProvider.isInitialized())) {
-            auto &handle = m_userDataMap[user];
-            FileSystem fs(user);
+        if (0 == m_userDataMap.count(clientID) || !(m_userDataMap[clientID].keyProvider.isInitialized())) {
+            auto &handle = m_userDataMap[clientID];
+            FileSystem fs(clientID);
 
-            loadDKEKFile(user, password, apiRequest);
+            loadDKEKFile(clientID, password, apiRequest);
 
             auto wrappedDatabaseDEK = fs.getDBDEK();
 
             if (wrappedDatabaseDEK.empty()) {
-                wrappedDatabaseDEK = handle.keyProvider.generateDEK(std::to_string(user));
+                wrappedDatabaseDEK = handle.keyProvider.generateDEK(clientID);
                 fs.saveDBDEK(wrappedDatabaseDEK);
             }
 
@@ -140,11 +164,12 @@ RawBuffer CKMLogic::unlockUserKey(uid_t user, const Password &password, bool api
             // remove data of removed apps during locked state
             AppLabelVector removedApps = fs.clearRemovedsApps();
             for(auto& appSmackLabel : removedApps) {
+                handle.crypto.removeKey(appSmackLabel);
                 handle.database.deleteKey(appSmackLabel);
             }
-        } else if (apiRequest == true && m_userDataMap[user].isDKEKConfirmed == false) {
+        } else if (apiRequest == true && m_userDataMap[clientID].isDKEKConfirmed == false) {
             // now we will try to choose the DKEK key and remove old one
-            loadDKEKFile(user, password, apiRequest);
+            loadDKEKFile(clientID, password, apiRequest);
         }
     } catch (const KeyProvider::Exception::PassWordError &e) {
         LogError("Incorrect Password " << e.GetMessage());
@@ -166,7 +191,7 @@ RawBuffer CKMLogic::unlockUserKey(uid_t user, const Password &password, bool api
     if(retCode != CKM_API_SUCCESS) {
         // When not successful, UserData in m_userDataMap should be erased.
         // Because other operations make decision based on the existence of UserData in m_userDataMap.
-        m_userDataMap.erase(user);
+        m_userDataMap.erase(clientID);
     }
 
     return MessageBuffer::Serialize(retCode).Pop();
@@ -177,35 +202,47 @@ RawBuffer CKMLogic::updateCCMode() {
     return MessageBuffer::Serialize(CKM_API_SUCCESS).Pop();
 }
 
-RawBuffer CKMLogic::lockUserKey(uid_t user) {
+RawBuffer CKMLogic::lockUserKey(const ClientID &clientID) {
     int retCode = CKM_API_SUCCESS;
     // TODO try catch for all errors that should be supported by error code
-    m_userDataMap.erase(user);
+
+#ifdef PASSWORD_PROTECTION_DISABLE
+    (void) clientID;
+#else
+    m_userDataMap.erase(clientID);
+#endif
 
     return MessageBuffer::Serialize(retCode).Pop();
 
 }
 
-RawBuffer CKMLogic::removeUserData(uid_t user) {
+RawBuffer CKMLogic::removeUserData(const ClientID &clientID) {
     int retCode = CKM_API_SUCCESS;
     // TODO try catch for all errors that should be supported by error code
-    m_userDataMap.erase(user);
 
-    FileSystem fs(user);
+    m_userDataMap.erase(clientID);
+
+    FileSystem fs(clientID);
     fs.removeUserData();
 
     return MessageBuffer::Serialize(retCode).Pop();
 }
 
 RawBuffer CKMLogic::changeUserPassword(
-    uid_t user,
+    const ClientID &clientID,
     const Password &oldPassword,
     const Password &newPassword)
 {
     int retCode = CKM_API_SUCCESS;
+
+#ifdef PASSWORD_PROTECTION_DISABLE
+    (void) clientID;
+    (void) oldPassword;
+    (void) newPassword;
+#else
     try {
-        loadDKEKFile(user, oldPassword, true);
-        saveDKEKFile(user, newPassword);
+        loadDKEKFile(clientID, oldPassword, true);
+        saveDKEKFile(clientID, newPassword);
     } catch (const KeyProvider::Exception::PassWordError &e) {
         LogError("Incorrect Password " << e.GetMessage());
         retCode = CKM_API_ERROR_AUTHENTICATION_FAILED;
@@ -219,25 +256,29 @@ RawBuffer CKMLogic::changeUserPassword(
         LogError("CKM::Exception: " << e.GetMessage());
         retCode = CKM_API_ERROR_SERVER_ERROR;
     }
+#endif
 
     return MessageBuffer::Serialize(retCode).Pop();
 }
 
 RawBuffer CKMLogic::resetUserPassword(
-    uid_t user,
+    const ClientID &clientID,
     const Password &newPassword)
 {
     int retCode = CKM_API_SUCCESS;
-
+#ifdef PASSWORD_PROTECTION_DISABLE
+    (void) clientID;
+    (void) newPassword;
+#else
     try {
-        if (0 == m_userDataMap.count(user)) {
+        if (0 == m_userDataMap.count(clientID)) {
             // Check if key exists. If exists we must return error
-            FileSystem fs(user);
+            FileSystem fs(clientID);
             auto wrappedDKEKMain = fs.getDKEK();
             if (!wrappedDKEKMain.empty())
                 retCode = CKM_API_ERROR_BAD_REQUEST;
         } else {
-            saveDKEKFile(user, newPassword);
+            saveDKEKFile(clientID, newPassword);
         }
     } catch (const FileSystem::Exception::Base &e) {
         LogError("Error in FileSystem " << e.GetMessage());
@@ -246,30 +287,30 @@ RawBuffer CKMLogic::resetUserPassword(
         LogError("CKM::Exception: " << e.GetMessage());
         retCode = CKM_API_ERROR_SERVER_ERROR;
     }
+#endif
 
     return MessageBuffer::Serialize(retCode).Pop();
 }
 
-RawBuffer CKMLogic::removeApplicationData(const Label &smackLabel) {
+RawBuffer CKMLogic::removeApplicationData(const std::string &zone, const Label &smackLabel) {
     int retCode = CKM_API_SUCCESS;
 
     try {
-
         if (smackLabel.empty()) {
             retCode = CKM_API_ERROR_INPUT_PARAM;
         } else {
-            UidVector uids = FileSystem::getUIDsFromDBFile();
-            for (auto userId : uids) {
-                if (0 == m_userDataMap.count(userId)) {
-                    FileSystem fs(userId);
+            ClientIDVector clientIDVec = FileSystem::getClientIDsFromDBFile(zone);
+            for (auto clientID : clientIDVec) {
+                if (0 == m_userDataMap.count(clientID)) {
+                    FileSystem fs(clientID);
                     fs.addRemovedApp(smackLabel);
                 } else {
-                    auto &handle = m_userDataMap[userId];
+                    auto &handle = m_userDataMap[clientID];
+                    handle.crypto.removeKey(smackLabel);
                     handle.database.deleteKey(smackLabel);
                 }
             }
         }
-
     } catch (const DB::Crypto::Exception::InternalError &e) {
         LogError("DB::Crypto couldn't remove data: " << e.GetMessage());
         retCode = CKM_API_ERROR_DB_ERROR;
@@ -298,7 +339,6 @@ int CKMLogic::checkSaveConditions(
         LogWarning("Invalid parameter passed to key-manager");
         return CKM_API_ERROR_INPUT_PARAM;
     }
-
     // check if allowed to save using ownerLabel
     int access_ec = m_accessControl.canSave(ownerLabel, cred.smackLabel);
     if(access_ec != CKM_API_SUCCESS)
@@ -387,7 +427,7 @@ RawBuffer CKMLogic::saveData(
     const PolicySerializable &policy)
 {
     int retCode;
-    if (0 == m_userDataMap.count(cred.uid))
+    if (0 == m_userDataMap.count(cred.clientID))
         retCode = CKM_API_ERROR_DB_LOCKED;
     else
     {
@@ -481,7 +521,7 @@ RawBuffer CKMLogic::savePKCS12(
     const PolicySerializable &certPolicy)
 {
     int retCode;
-    if (0 == m_userDataMap.count(cred.uid))
+    if (0 == m_userDataMap.count(cred.clientID))
         retCode = CKM_API_ERROR_DB_LOCKED;
     else
     {
@@ -517,7 +557,7 @@ int CKMLogic::removeDataHelper(
         const Name &name,
         const Label &ownerLabel)
 {
-    if (0 == m_userDataMap.count(cred.uid))
+    if (0 == m_userDataMap.count(cred.clientID))
         return CKM_API_ERROR_DB_LOCKED;
 
     if (!isNameValid(name) || !isLabelValid(ownerLabel)) {
@@ -525,7 +565,7 @@ int CKMLogic::removeDataHelper(
         return CKM_API_ERROR_INPUT_PARAM;
     }
 
-    auto &database = m_userDataMap[cred.uid].database;
+    auto &database = m_userDataMap[cred.clientID].database;
     DB::Crypto::Transaction transaction(&database);
 
     // read and check permissions
@@ -584,14 +624,14 @@ int CKMLogic::readSingleRow(const Name &name,
     {
         // read all key types
         row_optional = database.getRow(name,
-                                         ownerLabel,
-                                         DataType::DB_KEY_FIRST,
-                                         DataType::DB_KEY_LAST);
+                                       ownerLabel,
+                                       DataType::DB_KEY_FIRST,
+                                       DataType::DB_KEY_LAST);
     } else {
         // read anything else
         row_optional = database.getRow(name,
-                                         ownerLabel,
-                                         dataType);
+                                       ownerLabel,
+                                       dataType);
     }
 
     if(!row_optional) {
@@ -604,7 +644,6 @@ int CKMLogic::readSingleRow(const Name &name,
     return CKM_API_SUCCESS;
 }
 
-
 int CKMLogic::readMultiRow(const Name &name,
                            const Label &ownerLabel,
                            DataType dataType,
@@ -615,31 +654,35 @@ int CKMLogic::readMultiRow(const Name &name,
     {
         // read all key types
         database.getRows(name,
-                          ownerLabel,
-                          DataType::DB_KEY_FIRST,
-                          DataType::DB_KEY_LAST,
-                          output);
+                         ownerLabel,
+                         DataType::DB_KEY_FIRST,
+                         DataType::DB_KEY_LAST,
+                         output);
     }
     else if (dataType.isChainCert())
     {
         // read all key types
         database.getRows(name,
-                          ownerLabel,
-                          DataType::DB_CHAIN_FIRST,
-                          DataType::DB_CHAIN_LAST,
-                          output);
+                         ownerLabel,
+                         DataType::DB_CHAIN_FIRST,
+                         DataType::DB_CHAIN_LAST,
+                         output);
     }
     else
     {
         // read anything else
         database.getRows(name,
-                          ownerLabel,
-                          dataType,
-                          output);
+                         ownerLabel,
+                         dataType,
+                         output);
     }
 
     if(!output.size()) {
-        LogError("No row for given name, label and type");
+        /*
+         *  readMultiRow is only used to get row which cannot exist
+         *  So, it shouldn't print error log
+         */
+        LogDebug("No row for given name, label and type");
         return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
     }
 
@@ -670,7 +713,7 @@ int CKMLogic::readDataHelper(
     const Password &password,
     DB::RowVector &rows)
 {
-    if (0 == m_userDataMap.count(cred.uid))
+    if (0 == m_userDataMap.count(cred.clientID))
         return CKM_API_ERROR_DB_LOCKED;
 
     // use client label if not explicitly provided
@@ -679,7 +722,7 @@ int CKMLogic::readDataHelper(
     if (!isNameValid(name) || !isLabelValid(ownerLabel))
         return CKM_API_ERROR_INPUT_PARAM;
 
-    auto &handler = m_userDataMap[cred.uid];
+    auto &handler = m_userDataMap[cred.clientID];
 
     // read rows
     DB::Crypto::Transaction transaction(&handler.database);
@@ -722,7 +765,7 @@ int CKMLogic::readDataHelper(
     const Password &password,
     DB::Row &row)
 {
-    if (0 == m_userDataMap.count(cred.uid))
+    if (0 == m_userDataMap.count(cred.clientID))
         return CKM_API_ERROR_DB_LOCKED;
 
     // use client label if not explicitly provided
@@ -731,7 +774,7 @@ int CKMLogic::readDataHelper(
     if (!isNameValid(name) || !isLabelValid(ownerLabel))
         return CKM_API_ERROR_INPUT_PARAM;
 
-    auto &handler = m_userDataMap[cred.uid];
+    auto &handler = m_userDataMap[cred.clientID];
 
     // read row
     DB::Crypto::Transaction transaction(&handler.database);
@@ -900,8 +943,8 @@ RawBuffer CKMLogic::getDataList(
     int retCode = CKM_API_SUCCESS;
     LabelNameVector labelNameVector;
 
-    if (0 < m_userDataMap.count(cred.uid)) {
-        auto &database = m_userDataMap[cred.uid].database;
+    if (0 < m_userDataMap.count(cred.clientID)) {
+        auto &database = m_userDataMap[cred.clientID].database;
 
         Try {
             if (dataType.isKey()) {
@@ -941,7 +984,7 @@ int CKMLogic::saveDataHelper(
     const RawBuffer &data,
     const PolicySerializable &policy)
 {
-    auto &handler = m_userDataMap[cred.uid];
+    auto &handler = m_userDataMap[cred.clientID];
 
     // use client label if not explicitly provided
     const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
@@ -968,7 +1011,7 @@ int CKMLogic::saveDataHelper(
     const PolicySerializable &keyPolicy,
     const PolicySerializable &certPolicy)
 {
-    auto &handler = m_userDataMap[cred.uid];
+    auto &handler = m_userDataMap[cred.clientID];
 
     // use client label if not explicitly provided
     const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
@@ -1004,7 +1047,7 @@ int CKMLogic::createKeyPairHelper(
     const PolicySerializable &policyPrivate,
     const PolicySerializable &policyPublic)
 {
-    if (0 == m_userDataMap.count(cred.uid))
+    if (0 == m_userDataMap.count(cred.clientID))
         return CKM_API_ERROR_DB_LOCKED;
 
     KeyImpl prv, pub;
@@ -1036,7 +1079,7 @@ int CKMLogic::createKeyPairHelper(
         return CKM_API_ERROR_SERVER_ERROR; // TODO error code
     }
 
-    auto &database = m_userDataMap[cred.uid].database;
+    auto &database = m_userDataMap[cred.clientID].database;
     DB::Crypto::Transaction transaction(&database);
 
     retCode = saveDataHelper(cred,
@@ -1249,7 +1292,8 @@ RawBuffer CKMLogic::getCertificateChain(
     auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_CHAIN_CERT),
                                              commandId,
                                              retCode,
-                                             chainRawVector);
+                                             chainRawVector,
+                                             m_accessControl.isCCMode());
     return response.Pop();
 }
 
@@ -1290,7 +1334,8 @@ RawBuffer CKMLogic::getCertificateChain(
     auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_CHAIN_ALIAS),
                                              commandId,
                                              retCode,
-                                             chainRawVector);
+                                             chainRawVector,
+                                             m_accessControl.isCCMode());
     return response.Pop();
 }
 
@@ -1360,22 +1405,46 @@ RawBuffer CKMLogic::verifySignature(
     try {
         do {
             CryptoService cs;
+            DB::RowVector rowVec;
             DB::Row row;
             KeyImpl key;
 
             // try certificate first - looking for a public key.
             // in case of PKCS, pub key from certificate will be found first
             // rather than private key from the same PKCS.
-            retCode = readDataHelper(false, cred, DataType::CERTIFICATE, publicKeyOrCertName, ownerLabel, password, row);
-            if (retCode == CKM_API_SUCCESS) {
-                CertificateImpl cert(row.data, DataFormat::FORM_DER);
+            retCode = readDataHelper(
+                    false,
+                    cred,
+                    DataType::CERTIFICATE,
+                    publicKeyOrCertName,
+                    ownerLabel,
+                    password,
+                    rowVec);
+
+            // output cannot be more than 1
+            if (rowVec.size() > 1) {
+                ThrowMsg(CKM::Exception,
+                    "More than one certificate mapped to a label[" << ownerLabel << "]");
+            }
+            else if (retCode == CKM_API_SUCCESS && rowVec.size() == 1) {
+                CertificateImpl cert(rowVec[0].data, DataFormat::FORM_DER);
                 key = cert.getKeyImpl();
-            } else if (retCode == CKM_API_ERROR_DB_ALIAS_UNKNOWN) {
-                retCode = readDataHelper(false, cred, DataType::DB_KEY_FIRST, publicKeyOrCertName, ownerLabel, password, row);
+            }
+            else if (retCode == CKM_API_ERROR_DB_ALIAS_UNKNOWN && rowVec.size() == 0) {
+                retCode = readDataHelper(
+                        false,
+                        cred,
+                        DataType::DB_KEY_FIRST,
+                        publicKeyOrCertName,
+                        ownerLabel,
+                        password,
+                        row);
+
                 if (retCode != CKM_API_SUCCESS)
                     break;
                 key = KeyImpl(row.data);
-            } else {
+            }
+            else {
                 break;
             }
 
@@ -1441,11 +1510,10 @@ int CKMLogic::setPermissionHelper(
     int access_ec = m_accessControl.canModify(ownerLabel, cred.smackLabel);
     if(access_ec != CKM_API_SUCCESS)
         return access_ec;
-
-    if (0 == m_userDataMap.count(cred.uid))
+    if (0 == m_userDataMap.count(cred.clientID))
         return CKM_API_ERROR_DB_LOCKED;
 
-    auto &database = m_userDataMap[cred.uid].database;
+    auto &database = m_userDataMap[cred.clientID].database;
     DB::Crypto::Transaction transaction(&database);
 
     if( !database.isNameLabelPresent(name, ownerLabel) )