Implementation of ckmc_export_wrapped_key 84/289984/30
authorm.ksiezak <m.ksiezak@samsung.com>
Thu, 16 Mar 2023 10:56:02 +0000 (11:56 +0100)
committerDariusz Michaluk <d.michaluk@samsung.com>
Fri, 31 Mar 2023 08:24:13 +0000 (10:24 +0200)
Change-Id: I2769be74b1ad3d76537d31bc3f7ac4659946029f

15 files changed:
src/include/ckm/ckm-manager.h
src/include/ckmc/ckmc-manager.h
src/manager/client-capi/ckmc-manager.cpp
src/manager/client/client-manager-impl.cpp
src/manager/client/client-manager-impl.h
src/manager/client/client-manager.cpp
src/manager/common/protocols.h
src/manager/crypto/generic-backend/gobj.h
src/manager/crypto/sw-backend/obj.cpp
src/manager/crypto/sw-backend/obj.h
src/manager/crypto/sw-backend/store.cpp
src/manager/crypto/sw-backend/store.h
src/manager/service/ckm-logic.cpp
src/manager/service/ckm-logic.h
src/manager/service/ckm-service.cpp

index defe6ce..8ce5dea 100644 (file)
@@ -186,6 +186,14 @@ public:
                                                 const KeyType keyType,
                                                 const Policy &policy);
 
+       int exportWrappedKey(const CryptoAlgorithm &params,
+                                                const Alias &wrappingKeyAlias,
+                                                const Password &wrappingKeyPassword,
+                                                const Alias &wrappedKeyAlias,
+                                                const Password &wrappedKeyPassword,
+                                                KeyType &keyType,
+                                                RawBuffer &wrappedKey);
+
 private:
        std::unique_ptr<Impl> m_impl;
 };
index 54c5ab5..fd92c25 100644 (file)
@@ -1062,18 +1062,18 @@ int ckmc_import_wrapped_key(const ckmc_param_list_h params,
  *                   - #CKMC_ALGO_RSA_OAEP
  * @param[in] wrapping_key_alias The name of the wrapping key
  * @param[in] wrapping_key_password An optional password of the wrapping key
- * @param[in] alias The name of the key to be wrapped and exported
- * @param[in] password An optional password used to decrypt the key pointed by @a alias
+ * @param[in] wrapped_key_alias The name of the key to be wrapped and exported
+ * @param[in] wrapped_key_password An optional password used to decrypt the key pointed by @a wrapped_key_alias
  * @param[out] ppwrapped_key The wrapped key
  *
  * @return @c 0 on success, otherwise a negative error value
  * @retval #CKMC_ERROR_NONE Successful
  * @retval #CKMC_ERROR_INVALID_PARAMETER Input parameter is invalid (missing or invalid mandatory
  *                                       algorithm parameter, GCM tag authentication failed,
- *                                       @a wrapping_key_alias = NULL, @a alias = NULL,
- *                                       @a wrapped_key = NULL, @a ppwrapped_key = NULL)
+ *                                       @a wrapping_key_alias = NULL, @a wrapped_key_alias = NULL,
+ *                                       @a ppwrapped_key = NULL)
  * @retval #CKMC_ERROR_DB_LOCKED A user key is not loaded in memory (a user is not logged in)
- * @retval #CKMC_ERROR_DB_ALIAS_UNKNOWN @a wrapping_key_alias or @a alias does not exist
+ * @retval #CKMC_ERROR_DB_ALIAS_UNKNOWN @a wrapping_key_alias or @a wrapped_key_alias does not exist
  * @retval #CKMC_ERROR_DB_ERROR Failed due to a database error
  * @retval #CKMC_ERROR_AUTHENTICATION_FAILED Wrapping key decryption failed because
  *                                           @a wrapping_key_password is incorrect
@@ -1089,8 +1089,8 @@ int ckmc_import_wrapped_key(const ckmc_param_list_h params,
 int ckmc_export_wrapped_key(const ckmc_param_list_h params,
                             const char *wrapping_key_alias,
                             const char *wrapping_key_password,
-                            const char *alias,
-                            const char *password,
+                            const char *wrapped_key_alias,
+                            const char *wrapped_key_password,
                             ckmc_key_s **ppwrapped_key);
 
 
index 488f287..e5fa0ec 100644 (file)
@@ -1049,3 +1049,49 @@ int ckmc_import_wrapped_key(const ckmc_param_list_h params,
 
        EXCEPTION_GUARD_END
 }
+
+KEY_MANAGER_CAPI
+int ckmc_export_wrapped_key(const ckmc_param_list_h params,
+                                                       const char *wrapping_key_alias,
+                                                       const char *wrapping_key_password,
+                                                       const char *wrapped_key_alias,
+                                                       const char *wrapped_key_password,
+                                                       ckmc_key_s **ppwrapped_key)
+{
+       EXCEPTION_GUARD_START_CAPI
+
+       if (params == nullptr ||
+               wrapping_key_alias == nullptr ||
+               wrapped_key_alias == nullptr ||
+               ppwrapped_key == nullptr)
+                       return CKMC_ERROR_INVALID_PARAMETER;
+
+       const CKM::CryptoAlgorithm *ca = reinterpret_cast<const CKM::CryptoAlgorithm *>
+                                                                        (params);
+
+       int ret = 0;
+       ckmc_key_s *wrapped_key = nullptr;
+       CKM::RawBuffer wrappedKey;
+       CKM::KeyType keyType;
+       auto mgr = CKM::Manager::create();
+
+       ret = to_ckmc_error(mgr->exportWrappedKey(*ca,
+                                                                                         CKM::Alias(wrapping_key_alias),
+                                                                                         _tostring(wrapping_key_password),
+                                                                                         CKM::Alias(wrapped_key_alias),
+                                                                                         _tostring(wrapped_key_password),
+                                                                                         keyType,
+                                                                                         wrappedKey));
+
+
+
+       if (ret == CKMC_ERROR_NONE) {
+               ckmc_key_type_e ckmcKeyType = static_cast<ckmc_key_type_e>(keyType);
+               ret = ckmc_key_new(wrappedKey.data(), wrappedKey.size(), ckmcKeyType, nullptr, &wrapped_key);
+               if (ret == CKMC_ERROR_NONE)
+                       *ppwrapped_key = wrapped_key;
+       }
+
+       return ret;
+       EXCEPTION_GUARD_END
+}
index 5228f91..d2d8534 100644 (file)
@@ -789,4 +789,47 @@ int Manager::Impl::importWrappedKey(const CryptoAlgorithm &params,
        EXCEPTION_GUARD_END
 }
 
+int Manager::Impl::exportWrappedKey(const CryptoAlgorithm &params,
+                                                                       const Alias &wrappingKeyAlias,
+                                                                       const Password &wrappingKeyPassword,
+                                                                       const Alias &wrappedKeyAlias,
+                                                                       const Password &wrappedKeyPassword,
+                                                                       KeyType &keyType,
+                                                                       RawBuffer &wrappedKey)
+{
+       EXCEPTION_GUARD_START_CPPAPI
+
+       AliasSupport wrapping_helper(wrappingKeyAlias);
+       AliasSupport wrapped_helper(wrappedKeyAlias);
+       DataType *dataTypeKey = nullptr;
+
+       int retCode = Request(*this,
+               LogicCommand::EXPORT_WRAPPED_KEY,
+               m_storageConnection,
+               CryptoAlgorithmSerializable(params),
+               wrapping_helper.getName(),
+               wrapping_helper.getOwner(),
+               wrappingKeyPassword,
+               wrapped_helper.getName(),
+               wrapped_helper.getOwner(),
+               wrappedKeyPassword
+       ).maybeDeserialize(dataTypeKey, wrappedKey);
+
+       if (retCode != CKM_API_SUCCESS)
+               return retCode;
+
+       if (dataTypeKey->isSKey()) {
+               keyType = KeyType::KEY_AES;
+       } else if (dataTypeKey->isKeyPrivate()) {
+               keyType = KeyType::KEY_RSA_PRIVATE;
+       } else {
+               return CKM_API_ERROR_INVALID_FORMAT;
+       }
+
+       return retCode;
+
+       EXCEPTION_GUARD_END
+}
+
+
 } // namespace CKM
index 19dbcc5..91e5732 100644 (file)
@@ -149,6 +149,14 @@ public:
                                                 const KeyType keyType,
                                                 const Policy &policy);
 
+       int exportWrappedKey(const CryptoAlgorithm &params,
+                                                const Alias &wrappingKeyAlias,
+                                                const Password &wrappingKeyPassword,
+                                                const Alias &wrappedKeyAlias,
+                                                const Password &wrappedKeyPassword,
+                                                KeyType &keyType,
+                                                RawBuffer &wrappedKey);
+
 private:
        int saveBinaryData(
                const Alias &alias,
index 2c4d1d8..8ef76bb 100644 (file)
@@ -324,5 +324,24 @@ ManagerShPtr Manager::create()
        }
 }
 
-} // namespace CKM
+int  Manager::exportWrappedKey(
+       const CryptoAlgorithm &params,
+       const Alias &wrappingKeyAlias,
+       const Password &wrappingKeyPassword,
+       const Alias &wrappedKeyAlias,
+       const Password &wrappedKeyPassword,
+       KeyType &keyType,
+       RawBuffer &wrappedKey)
+{
+       return m_impl->exportWrappedKey(
+               params,
+               wrappingKeyAlias,
+               wrappingKeyPassword,
+               wrappedKeyAlias,
+               wrappedKeyPassword,
+               keyType,
+               wrappedKey
+       );
+}
 
+} // namespace CKM
index 3670b9c..3b1cad8 100644 (file)
@@ -68,7 +68,8 @@ enum class LogicCommand : int {
        GET_PKCS12,
        GET_PROTECTION_STATUS,
        DERIVE,
-       IMPORT_WRAPPED_KEY
+       IMPORT_WRAPPED_KEY,
+       EXPORT_WRAPPED_KEY
 };
 
 enum class EncryptionCommand : int {
@@ -138,4 +139,3 @@ struct COMMON_API CryptoAlgorithmSerializable : public CryptoAlgorithm,
 };
 
 } // namespace CKM
-
index 7e60dab..8433e67 100644 (file)
@@ -84,6 +84,13 @@ public:
                ThrowErr(Exc::Crypto::OperationNotSupported);
        }
 
+       virtual RawBuffer wrap(const CryptoAlgorithm &,
+                                                  const Token &,
+                                                  const Password &)
+       {
+               ThrowErr(Exc::Crypto::OperationNotSupported);
+       }
+
        virtual ~GObj()
        {
        }
index 1f812e0..a120cc6 100644 (file)
@@ -94,6 +94,16 @@ Token Key::unwrap(const CryptoAlgorithm &params,
        return Token(backendId(), encryptedKey.type, Store::pack(decrypted, pass));
 }
 
+RawBuffer Key::wrap(const CryptoAlgorithm &params,
+                                       const Token &keyToWrap,
+                                       const Password &keyToWrapPass)
+{
+
+       RawBuffer data = Store::unpack(keyToWrap.data, keyToWrapPass);
+       return encrypt(params, data);
+}
+
+
 RawBuffer SKey::encrypt(const CryptoAlgorithm &alg, const RawBuffer &data)
 {
        return Internals::symmetricEncrypt(getBinary(), alg, data);
@@ -223,6 +233,13 @@ Token Cert::unwrap(const CryptoAlgorithm &, const Data &, const Password &, cons
        ThrowErr(Exc::Crypto::OperationNotSupported);
 }
 
+RawBuffer  Cert::wrap(const CryptoAlgorithm &,
+                                         const Token &,
+                                         const Password &)
+{
+       ThrowErr(Exc::Crypto::OperationNotSupported);
+}
+
 } // namespace SW
 } // namespace Crypto
 } // namespace CKM
index 15ddb98..16b801a 100644 (file)
@@ -57,6 +57,11 @@ class Key : public BData {
                                 const Data &encryptedKey,
                                 const Password &pass,
                                 const RawBuffer &hash) override;
+
+       RawBuffer wrap(const CryptoAlgorithm &params,
+                                  const Token &keyToWrap,
+                                  const Password &keyToWrapPass) override;
+
 };
 
 class SKey : public Key {
@@ -95,6 +100,10 @@ public:
                                 const Password &,
                                 const RawBuffer &) override;
 
+       RawBuffer wrap(const CryptoAlgorithm &,
+                                  const Token &,
+                                  const Password &) override;
+
 protected:
        EvpShPtr getEvpShPtr() override;
 };
index 96a081b..7d610f7 100644 (file)
@@ -72,50 +72,6 @@ RawBuffer passwordToKey(const Password &password, const RawBuffer &salt,
        return result;
 }
 
-RawBuffer unpack(const RawBuffer &packed, const Password &pass)
-{
-       MessageBuffer buffer;
-       buffer.Push(RawBuffer(packed));
-       int encryptionScheme = EncryptionScheme::NONE;
-       RawBuffer data;
-       buffer.Deserialize(encryptionScheme, data);
-
-       if (encryptionScheme == EncryptionScheme::NONE) {
-               if (!pass.empty())
-                       ThrowErr(Exc::AuthenticationFailed, "Unexpected custom password.");
-               return data;
-       }
-
-       MessageBuffer internalBuffer;
-       internalBuffer.Push(std::move(data));
-       RawBuffer encrypted;
-       RawBuffer iv;
-       RawBuffer tag;
-
-       // serialization exceptions will be catched as CKM::Exception and will cause
-       // CKM_API_ERROR_SERVER_ERROR
-       internalBuffer.Deserialize(encrypted, iv, tag);
-
-       /*
-        * AES GCM will check data integrity and handle cases where:
-        * - wrong password is used
-        * - password is empty when it shouldn't be
-        */
-       RawBuffer key = passwordToKey(pass, iv, Params::DERIVED_KEY_LENGTH);
-
-       RawBuffer ret;
-
-       try {
-               ret = Crypto::SW::Internals::decryptDataAesGcm(key, encrypted, iv, tag);
-       } catch (const Exc::Crypto::InputParam &e) {
-               ThrowErr(Exc::AuthenticationFailed, "Decryption with custom password failed, authentication failed");
-       } catch (const Exc::Exception &e) {
-               ThrowErr(Exc::InternalError, "Decryption with custom password failed, internal error");
-       }
-
-       return ret;
-}
-
 std::string rawToHexString(const RawBuffer &raw)
 {
        return hexDump<std::string>(raw);
@@ -214,6 +170,50 @@ RawBuffer Store::pack(const RawBuffer &data, const Password &pass)
        return SerializeMessage(scheme, packed);
 }
 
+RawBuffer Store::unpack(const RawBuffer &packed, const Password &pass)
+{
+       MessageBuffer buffer;
+       buffer.Push(RawBuffer(packed));
+       int encryptionScheme = EncryptionScheme::NONE;
+       RawBuffer data;
+       buffer.Deserialize(encryptionScheme, data);
+
+       if (encryptionScheme == EncryptionScheme::NONE) {
+               if (!pass.empty())
+                       ThrowErr(Exc::AuthenticationFailed, "Unexpected custom password.");
+               return data;
+       }
+
+       MessageBuffer internalBuffer;
+       internalBuffer.Push(std::move(data));
+       RawBuffer encrypted;
+       RawBuffer iv;
+       RawBuffer tag;
+
+       // serialization exceptions will be catched as CKM::Exception and will cause
+       // CKM_API_ERROR_SERVER_ERROR
+       internalBuffer.Deserialize(encrypted, iv, tag);
+
+       /*
+        * AES GCM will check data integrity and handle cases where:
+        * - wrong password is used
+        * - password is empty when it shouldn't be
+        */
+       RawBuffer key = passwordToKey(pass, iv, Params::DERIVED_KEY_LENGTH);
+
+       RawBuffer ret;
+
+       try {
+               ret = Crypto::SW::Internals::decryptDataAesGcm(key, encrypted, iv, tag);
+       } catch (const Exc::Crypto::InputParam &e) {
+               ThrowErr(Exc::AuthenticationFailed, "Decryption with custom password failed, authentication failed");
+       } catch (const Exc::Exception &e) {
+               ThrowErr(Exc::InternalError, "Decryption with custom password failed, internal error");
+       }
+
+       return ret;
+}
+
 } // namespace SW
 } // namespace Crypto
 } // namespace CKM
index eba1365..fa61e9b 100644 (file)
@@ -45,6 +45,7 @@ public:
        void destroy(const Token &) override {}
 
        static RawBuffer pack(const RawBuffer &data, const Password &pass);
+       static RawBuffer unpack(const RawBuffer &packed, const Password &pass);
 };
 
 } // namespace SW
index bc88876..d931083 100644 (file)
@@ -1575,7 +1575,6 @@ RawBuffer CKMLogic::importWrappedKey(
        const CKM::DataType encryptedKeyType,
        const PolicySerializable &encryptedKeyPolicy)
 {
-
        return SerializeMessage(msgId, tryRet([&] {
                Crypto::GObjUPtr wrappingKey;
 
@@ -1599,4 +1598,39 @@ RawBuffer CKMLogic::importWrappedKey(
        }));
 }
 
+RawBuffer CKMLogic::exportWrappedKey(
+       const Credentials &cred,
+       const int msgID,
+       const CryptoAlgorithm &params,
+       const Name &wrappingKeyName,
+       const ClientId &wrappingKeyOwner,
+       const Password &wrappingKeyPassword,
+       const Name &wrappedKeyName,
+       const ClientId &wrappedKeyOwner,
+       const Password &wrappedKeyPassword)
+{
+       Crypto::GObjUPtr wrappingKey;
+       DB::Row wrappedKeyRow;
+       DataType wrappedKeyType;
+       RawBuffer wrappedKey;
+
+       auto retCode = tryRet([&] {
+               auto retCode = readDataHelper(false, cred, DataType::DB_KEY_FIRST, wrappingKeyName,
+                                                                         wrappingKeyOwner, wrappingKeyPassword, wrappingKey);
+               if (retCode != CKM_API_SUCCESS)
+                       return retCode;
+
+               retCode = readRowHelper(false, cred, DataType::DB_KEY_FIRST, wrappedKeyName,
+                                                               wrappedKeyOwner, wrappedKeyPassword, wrappedKeyRow, wrappedKeyType);
+               if (retCode != CKM_API_SUCCESS)
+                       return retCode;
+
+               wrappedKey = wrappingKey->wrap(params, wrappedKeyRow, wrappedKeyPassword);
+
+               return retCode;
+       });
+
+       return SerializeMessage(msgID, retCode, wrappedKeyType, wrappedKey);
+}
+
 } // namespace CKM
index ce990bb..b87848b 100644 (file)
@@ -202,6 +202,17 @@ public:
                const ClientId &newKeyOwner,
                const Policy &newKeyPolicy);
 
+       RawBuffer exportWrappedKey(
+               const Credentials &cred,
+               const int msgID,
+               const CryptoAlgorithm &params,
+               const Name &wrappingKeyName,
+               const ClientId &wrappingKeyOwner,
+               const Password &wrappingKeyPassword,
+               const Name &wrappedKeyName,
+               const ClientId &wrappedKeyOwner,
+               const Password &wrappedKeyPassword);
+
        int setPermissionHelper(
                const Credentials &cred,
                const Name &name,
@@ -408,4 +419,3 @@ protected:
 };
 
 } // namespace CKM
-
index 8d06e64..5c52e09 100644 (file)
@@ -492,6 +492,35 @@ RawBuffer CKMService::ProcessStorage(Credentials &cred, MessageBuffer &buffer)
                                        encryptedKeyPolicy);
        }
 
+       case LogicCommand::EXPORT_WRAPPED_KEY: {
+               CryptoAlgorithmSerializable params;
+               Name wrappingKeyName;
+               ClientId wrappingKeyOwner;
+               Password wrappingKeyPassword;
+               Name wrappedKeyName;
+               ClientId wrappedKeyOwner;
+               Password wrappedKeyPassword;
+
+               buffer.Deserialize(params,
+                                                  wrappingKeyName,
+                                                  wrappingKeyOwner,
+                                                  wrappingKeyPassword,
+                                                  wrappedKeyName,
+                                                  wrappedKeyOwner,
+                                                  wrappedKeyPassword);
+
+               return m_logic->exportWrappedKey(
+                                       cred,
+                                       msgId,
+                                       params,
+                                       wrappingKeyName,
+                                       cred.effectiveOwner(wrappingKeyOwner),
+                                       wrappingKeyPassword,
+                                       wrappedKeyName,
+                                       cred.effectiveOwner(wrappedKeyOwner),
+                                       wrappedKeyPassword);
+       }
+
        default:
                Throw(Exception::BrokenProtocol);
        }