Implementation of ckmc_import_wrapped_key 29/288529/24
authorm.ksiezak <m.ksiezak@samsung.com>
Fri, 17 Feb 2023 13:57:55 +0000 (14:57 +0100)
committerDariusz Michaluk <d.michaluk@samsung.com>
Fri, 31 Mar 2023 08:24:13 +0000 (10:24 +0200)
Change-Id: Ic8d2a865de2a705d39a4de06e9b91de5a6f30ef5

14 files changed:
src/include/ckm/ckm-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/generic-backend/gstore.h
src/manager/crypto/sw-backend/obj.cpp
src/manager/crypto/sw-backend/obj.h
src/manager/service/ckm-logic.cpp
src/manager/service/ckm-logic.h
src/manager/service/ckm-service.cpp
unit-tests/test_sw-backend.cpp

index 8a94b54..defe6ce 100644 (file)
@@ -178,9 +178,16 @@ public:
 
        static ManagerShPtr create();
 
+       int importWrappedKey(const CryptoAlgorithm &params,
+                                                const Alias &wrappingKeyAlias,
+                                                const Password &wrappingKeyPassword,
+                                                const Alias &alias,
+                                                const RawBuffer &encryptedKey,
+                                                const KeyType keyType,
+                                                const Policy &policy);
+
 private:
        std::unique_ptr<Impl> m_impl;
 };
 
 } // namespace CKM
-
index ba72405..488f287 100644 (file)
@@ -1012,6 +1012,40 @@ int ckmc_key_derive(const ckmc_param_list_h params,
                                                                                _tostring(secret_password),
                                                                                CKM::Alias(new_key_alias),
                                                                                _toCkmPolicy(new_key_policy)));
+       EXCEPTION_GUARD_END
+}
+
+KEY_MANAGER_CAPI
+int ckmc_import_wrapped_key(const ckmc_param_list_h params,
+                                                       const char *wrapping_key_alias,
+                                                       const char *wrapping_key_password,
+                                                       const char *alias,
+                                                       const ckmc_key_s *wrapped_key,
+                                                       const ckmc_policy_s policy)
+{
+       EXCEPTION_GUARD_START_CAPI
+
+       if (params == nullptr ||
+               wrapping_key_alias == nullptr ||
+               alias == nullptr ||
+               wrapped_key == nullptr ||
+               wrapped_key->raw_key == nullptr ||
+               wrapped_key->key_size == 0)
+                       return CKMC_ERROR_INVALID_PARAMETER;
+
+       const CKM::CryptoAlgorithm *ca = reinterpret_cast<const CKM::CryptoAlgorithm *>
+                                                                        (params);
+
+       auto mgr = CKM::Manager::create();
+
+       return to_ckmc_error(mgr->importWrappedKey(*ca,
+                                                                                          CKM::Alias(wrapping_key_alias),
+                                                                                          _tostring(wrapping_key_password),
+                                                                                          CKM::Alias(alias),
+                                                                                          CKM::RawBuffer(wrapped_key->raw_key,
+                                                                                                                         wrapped_key->raw_key + wrapped_key->key_size),
+                                                                                          static_cast<CKM::KeyType>(wrapped_key->key_type),
+                                                                                          _toCkmPolicy(policy)));
 
        EXCEPTION_GUARD_END
 }
index 08d4157..5228f91 100644 (file)
@@ -759,4 +759,34 @@ int Manager::Impl::deriveKey(const CryptoAlgorithm &algo,
        EXCEPTION_GUARD_END
 }
 
+int Manager::Impl::importWrappedKey(const CryptoAlgorithm &params,
+                                                                       const Alias &wrappingKeyAlias,
+                                                                       const Password &wrappingKeyPassword,
+                                                                       const Alias &alias,
+                                                                       const RawBuffer &encryptedKey,
+                                                                       const KeyType keyType,
+                                                                       const Policy &policy)
+{
+       EXCEPTION_GUARD_START_CPPAPI
+
+       AliasSupport wrapping_helper(wrappingKeyAlias);
+       AliasSupport helper(alias);
+
+       return Request(*this,
+               LogicCommand::IMPORT_WRAPPED_KEY,
+               m_storageConnection,
+               CryptoAlgorithmSerializable(params),
+               wrappingKeyPassword,
+               encryptedKey,
+               DataType(keyType),
+               PolicySerializable(policy),
+               helper.getName(),
+               helper.getOwner(),
+               wrapping_helper.getName(),
+               wrapping_helper.getOwner()
+               ).maybeDeserialize();
+
+       EXCEPTION_GUARD_END
+}
+
 } // namespace CKM
index 6371bfe..19dbcc5 100644 (file)
@@ -141,6 +141,13 @@ public:
                                  const Alias &newKeyAlias,
                                  const Policy &newKeyPolicy);
 
+       int importWrappedKey(const CryptoAlgorithm &params,
+                                                const Alias &wrappingKeyAlias,
+                                                const Password &wrappingKeyPassword,
+                                                const Alias &alias,
+                                                const RawBuffer &encryptedKey,
+                                                const KeyType keyType,
+                                                const Policy &policy);
 
 private:
        int saveBinaryData(
index 45cc796..2c4d1d8 100644 (file)
@@ -251,6 +251,26 @@ int Manager::verifySignature(
                           cAlg);
 }
 
+int Manager::importWrappedKey(
+       const CryptoAlgorithm &params,
+       const Alias &wrappingKeyAlias,
+       const Password &wrappingKeyPassword,
+       const Alias &alias,
+       const RawBuffer &encryptedKey,
+       const KeyType keyType,
+       const Policy &policy)
+{
+       return m_impl->importWrappedKey(
+               params,
+               wrappingKeyAlias,
+               wrappingKeyPassword,
+               alias,
+               encryptedKey,
+               keyType,
+               policy
+       );
+}
+
 int Manager::ocspCheck(const CertificateShPtrVector &certificateChainVector,
                                           int &ocspStatus)
 {
index 8796e5b..3670b9c 100644 (file)
@@ -67,7 +67,8 @@ enum class LogicCommand : int {
        SAVE_PKCS12,
        GET_PKCS12,
        GET_PROTECTION_STATUS,
-       DERIVE
+       DERIVE,
+       IMPORT_WRAPPED_KEY
 };
 
 enum class EncryptionCommand : int {
index 4763878..7e60dab 100644 (file)
 namespace CKM {
 namespace Crypto {
 
+// Data is very generic and does not say anything about content.
+struct Data {
+       Data() {};
+       Data(const DataType &t, RawBuffer d) : type(t), data(std::move(d)) {}
+       DataType type;
+       RawBuffer data; // buffer will be better?
+};
+
 class GObj {
 protected:
        explicit GObj(CryptoBackend backendId) : m_backendId(backendId) {}
@@ -68,6 +76,14 @@ public:
                ThrowErr(Exc::Crypto::OperationNotSupported);
        }
 
+       virtual Token unwrap(const CryptoAlgorithm &,
+                                                const Data &,
+                                                const Password &,
+                                                const RawBuffer &)
+       {
+               ThrowErr(Exc::Crypto::OperationNotSupported);
+       }
+
        virtual ~GObj()
        {
        }
index 191dc99..5d54c5a 100644 (file)
 namespace CKM {
 namespace Crypto {
 
-// Data is very generic and does not say anything about content.
-struct Data {
-       Data() {};
-       Data(const DataType &t, RawBuffer d) : type(t), data(std::move(d)) {}
-       DataType type;
-       RawBuffer data; // buffer will be better?
-};
-
 class GStore {
 public:
        virtual GObjUPtr getObject(const Token &, const Password &) = 0;
index 9b4e1a2..1f812e0 100644 (file)
@@ -29,6 +29,7 @@
 #include <sw-backend/obj.h>
 #include <sw-backend/store.h>
 #include <sw-backend/internals.h>
+#include <ckm/ckm-key.h>
 
 namespace CKM {
 namespace Crypto {
@@ -65,6 +66,34 @@ Token BData::derive(const CryptoAlgorithm &alg, const Password &pass, const RawB
        return Token(backendId(), data.type, Store::pack(data.buffer, pass));
 }
 
+Token Key::unwrap(const CryptoAlgorithm &params,
+                                 const Data &encryptedKey,
+                                 const Password &pass,
+                                 const RawBuffer &)
+{
+       auto decrypted = decrypt(params, encryptedKey.data);
+
+       if (!encryptedKey.type.isKey()) {
+               ThrowErr(Exc::Crypto::InputParam, "Wrapped data is not a key");
+       }
+
+       // validate the decrypted key
+       if (encryptedKey.type.isSKey()) {
+               auto tmp = CKM::Key::createAES(decrypted);
+               if (!tmp)
+                       ThrowErr(Exc::Crypto::InputParam, "Wrapped data is not a valid AES key");
+       } else {
+               auto tmp = CKM::Key::create(decrypted);
+               if (!tmp)
+                       ThrowErr(Exc::Crypto::InputParam, "Wrapped data is not a valid asymmetric key");
+
+               if (encryptedKey.type != DataType(tmp->getType()))
+                       ThrowErr(Exc::Crypto::InputParam, "Wrapped key type does not match the required one");
+       }
+
+       return Token(backendId(), encryptedKey.type, Store::pack(decrypted, pass));
+}
+
 RawBuffer SKey::encrypt(const CryptoAlgorithm &alg, const RawBuffer &data)
 {
        return Internals::symmetricEncrypt(getBinary(), alg, data);
@@ -189,6 +218,11 @@ Token Cert::derive(const CryptoAlgorithm &, const Password &, const RawBuffer &)
        ThrowErr(Exc::Crypto::OperationNotSupported);
 }
 
+Token Cert::unwrap(const CryptoAlgorithm &, const Data &, const Password &, const RawBuffer &)
+{
+       ThrowErr(Exc::Crypto::OperationNotSupported);
+}
+
 } // namespace SW
 } // namespace Crypto
 } // namespace CKM
index 2712341..15ddb98 100644 (file)
@@ -50,19 +50,26 @@ protected:
        DataType m_type;
 };
 
-class SKey : public BData {
+class Key : public BData {
+       using BData::BData;
+
+       Token unwrap(const CryptoAlgorithm &params,
+                                const Data &encryptedKey,
+                                const Password &pass,
+                                const RawBuffer &hash) override;
+};
+
+class SKey : public Key {
 public:
-       SKey(CryptoBackend backendId, RawBuffer buffer, DataType keyType) :
-               BData(backendId, std::move(buffer), keyType) {}
+       using Key::Key;
 
        RawBuffer encrypt(const CryptoAlgorithm &, const RawBuffer &) override;
        RawBuffer decrypt(const CryptoAlgorithm &, const RawBuffer &) override;
 };
 
-class AKey : public BData {
+class AKey : public Key {
 public:
-       AKey(CryptoBackend backendId, RawBuffer buffer, DataType dataType) :
-               BData(backendId, std::move(buffer), dataType) {}
+       using Key::Key;
 
        RawBuffer sign(const CryptoAlgorithm &alg, const RawBuffer &message) override;
        int verify(const CryptoAlgorithm &alg,
@@ -80,9 +87,13 @@ protected:
 
 class Cert : public AKey {
 public:
-       Cert(CryptoBackend backendId, RawBuffer buffer, DataType dataType) :
-               AKey(backendId, std::move(buffer), dataType) {}
+       using AKey::AKey;
+
        Token derive(const CryptoAlgorithm &, const Password &, const RawBuffer &) override;
+       Token unwrap(const CryptoAlgorithm &,
+                                const Data &,
+                                const Password &,
+                                const RawBuffer &) override;
 
 protected:
        EvpShPtr getEvpShPtr() override;
index 496b95b..bc88876 100644 (file)
@@ -1562,5 +1562,41 @@ RawBuffer CKMLogic::deriveKey(
        }));
 }
 
-} // namespace CKM
+RawBuffer CKMLogic::importWrappedKey(
+       const Credentials &cred,
+       const int msgId,
+       const CryptoAlgorithm &params,
+       const Name &wrappingKeyName,
+       const ClientId &wrappingKeyOwner,
+       const Password &wrappingKeyPassword,
+       const Name &encryptedKeyName,
+       const ClientId &encryptedKeyOwner,
+       const RawBuffer &encryptedKey,
+       const CKM::DataType encryptedKeyType,
+       const PolicySerializable &encryptedKeyPolicy)
+{
+
+       return SerializeMessage(msgId, tryRet([&] {
+               Crypto::GObjUPtr wrappingKey;
 
+               auto [dbOp, digest, retCode] = beginSaveAndGetHash(cred, encryptedKeyName, encryptedKeyOwner);
+               if (retCode != CKM_API_SUCCESS)
+                       return retCode;
+
+               retCode = readDataHelper(false, cred, DataType::DB_KEY_FIRST, wrappingKeyName,
+                                                               wrappingKeyOwner, wrappingKeyPassword, wrappingKey);
+               if (retCode != CKM_API_SUCCESS)
+                       return retCode;
+
+               Token token = wrappingKey->unwrap(params,
+                                                                                 Crypto::Data(encryptedKeyType, std::move(encryptedKey)),
+                                                                                 encryptedKeyPolicy.password,
+                                                                                 digest);
+
+               dbOp.finalize(std::move(token), encryptedKeyPolicy);
+
+               return retCode;
+       }));
+}
+
+} // namespace CKM
index 8829612..ce990bb 100644 (file)
@@ -230,6 +230,20 @@ public:
                const Policy &policy);
 
        int unlockSystemDB();
+
+       RawBuffer importWrappedKey(
+               const Credentials &cred,
+               const int msgId,
+               const CryptoAlgorithm &params,
+               const Name &wrappingKeyName,
+               const ClientId &wrappingKeyOwner,
+               const Password &wrappingKeyPassword,
+               const Name &encryptedKeyName,
+               const ClientId &encryptedKeyOwner,
+               const RawBuffer &encryptedKey,
+               const CKM::DataType encryptedKeyType,
+               const PolicySerializable &encryptedKeyPolicy);
+
 private:
        // select private/system database depending on asking uid and owner id.
        // output: database handler for effective owner
index 27c90ad..8d06e64 100644 (file)
@@ -458,6 +458,40 @@ RawBuffer CKMService::ProcessStorage(Credentials &cred, MessageBuffer &buffer)
                        newKeyPolicy);
        }
 
+       case LogicCommand::IMPORT_WRAPPED_KEY: {
+               CryptoAlgorithmSerializable params;
+               Name wrappingKeyName;
+               ClientId wrappingKeyOwner;
+               Password wrappingKeyPassword;
+               Name encryptedKeyName;
+               RawBuffer encryptedKey;
+               CKM::DataType encryptedKeyType;
+               PolicySerializable encryptedKeyPolicy;
+
+               buffer.Deserialize(params,
+                                                  wrappingKeyPassword,
+                                                  encryptedKey,
+                                                  encryptedKeyType,
+                                                  encryptedKeyPolicy,
+                                                  encryptedKeyName,
+                                                  explicitOwner,
+                                                  wrappingKeyName,
+                                                  wrappingKeyOwner);
+
+               return m_logic->importWrappedKey(
+                                       cred,
+                                       msgId,
+                                       params,
+                                       wrappingKeyName,
+                                       cred.effectiveOwner(wrappingKeyOwner),
+                                       wrappingKeyPassword,
+                                       encryptedKeyName,
+                                       cred.effectiveOwner(explicitOwner),
+                                       encryptedKey,
+                                       encryptedKeyType,
+                                       encryptedKeyPolicy);
+       }
+
        default:
                Throw(Exception::BrokenProtocol);
        }
index 4de683e..a4e6077 100644 (file)
@@ -75,9 +75,9 @@ void checkKey(const Token& token, KeyType keyType, const Password& pass)
 
        KeyShPtr key;
        if (dataType.isSKey())
-               key = Key::createAES(data);
+               key = CKM::Key::createAES(data);
        else
-               key = Key::create(data);
+               key = CKM::Key::create(data);
 
        BOOST_REQUIRE(key);
        BOOST_REQUIRE(!key->empty());