static ManagerShPtr create();
+ int importWrappedKey(const CryptoAlgorithm ¶ms,
+ 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
-
_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
}
EXCEPTION_GUARD_END
}
+int Manager::Impl::importWrappedKey(const CryptoAlgorithm ¶ms,
+ 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
const Alias &newKeyAlias,
const Policy &newKeyPolicy);
+ int importWrappedKey(const CryptoAlgorithm ¶ms,
+ const Alias &wrappingKeyAlias,
+ const Password &wrappingKeyPassword,
+ const Alias &alias,
+ const RawBuffer &encryptedKey,
+ const KeyType keyType,
+ const Policy &policy);
private:
int saveBinaryData(
cAlg);
}
+int Manager::importWrappedKey(
+ const CryptoAlgorithm ¶ms,
+ 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)
{
SAVE_PKCS12,
GET_PKCS12,
GET_PROTECTION_STATUS,
- DERIVE
+ DERIVE,
+ IMPORT_WRAPPED_KEY
};
enum class EncryptionCommand : int {
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) {}
ThrowErr(Exc::Crypto::OperationNotSupported);
}
+ virtual Token unwrap(const CryptoAlgorithm &,
+ const Data &,
+ const Password &,
+ const RawBuffer &)
+ {
+ ThrowErr(Exc::Crypto::OperationNotSupported);
+ }
+
virtual ~GObj()
{
}
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;
#include <sw-backend/obj.h>
#include <sw-backend/store.h>
#include <sw-backend/internals.h>
+#include <ckm/ckm-key.h>
namespace CKM {
namespace Crypto {
return Token(backendId(), data.type, Store::pack(data.buffer, pass));
}
+Token Key::unwrap(const CryptoAlgorithm ¶ms,
+ 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);
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
DataType m_type;
};
-class SKey : public BData {
+class Key : public BData {
+ using BData::BData;
+
+ Token unwrap(const CryptoAlgorithm ¶ms,
+ 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,
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;
}));
}
-} // namespace CKM
+RawBuffer CKMLogic::importWrappedKey(
+ const Credentials &cred,
+ const int msgId,
+ const CryptoAlgorithm ¶ms,
+ 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
const Policy &policy);
int unlockSystemDB();
+
+ RawBuffer importWrappedKey(
+ const Credentials &cred,
+ const int msgId,
+ const CryptoAlgorithm ¶ms,
+ 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
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);
}
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());