KeyType &keyType,
RawBuffer &wrappedKey);
+ int wrapConcatenatedData(const CryptoAlgorithm ¶ms,
+ const Alias &wrappingKeyAlias,
+ const Password &wrappingKeyPassword,
+ const Alias &alias,
+ const Password &password,
+ const RawBuffer &data,
+ RawBuffer &wrappedKey);
+
+ int unwrapConcatenatedData(const CryptoAlgorithm ¶ms,
+ const Alias &wrappingKeyAlias,
+ const Password &wrappingKeyPassword,
+ const RawBuffer &wrappedKey,
+ const Alias &alias,
+ size_t size,
+ const Policy &policy,
+ RawBuffer &data);
+
int initializeCipher(const CryptoAlgorithm ¶ms,
const Alias &keyAlias,
const Password &keyPassword,
const ckmc_raw_buffer_s *data,
ckmc_key_s **ppwrapped_key)
{
- (void) params;
- (void) wrapping_key_alias;
- (void) wrapping_key_password;
- (void) alias;
- (void) password;
- (void) data;
- (void) ppwrapped_key;
+ EXCEPTION_GUARD_START_CAPI
- return CKMC_ERROR_NONE;
+ if (params == nullptr || wrapping_key_alias == nullptr ||
+ alias == nullptr || data == 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 wrapped_key_buffer;
+ CKM::KeyType key_type = CKM::KeyType::KEY_AES;
+
+ auto mgr = CKM::Manager::create();
+
+ ret = to_ckmc_error(
+ mgr->wrapConcatenatedData(*ca,
+ CKM::Alias(wrapping_key_alias),
+ _tostring(wrapping_key_password),
+ CKM::Alias(alias),
+ _tostring(password),
+ CKM::RawBuffer(data->data, data->data + data->size),
+ wrapped_key_buffer));
+
+ if (ret == CKMC_ERROR_NONE) {
+ ret = ckmc_key_new(wrapped_key_buffer.data(),
+ wrapped_key_buffer.size(),
+ static_cast<ckmc_key_type_e>(key_type),
+ nullptr,
+ &wrapped_key);
+ if (ret == CKMC_ERROR_NONE)
+ *ppwrapped_key = wrapped_key;
+ }
+
+ return ret;
+ EXCEPTION_GUARD_END
}
KEY_MANAGER_CAPI
const ckmc_policy_s policy,
ckmc_raw_buffer_s **ppdata)
{
- (void) params;
- (void) wrapping_key_alias;
- (void) wrapping_key_password;
- (void) wrapped_key;
- (void) alias;
- (void) size;
- (void) policy;
- (void) ppdata;
+ EXCEPTION_GUARD_START_CAPI
- return CKMC_ERROR_NONE;
+ if (params == nullptr || wrapping_key_alias == nullptr ||
+ wrapped_key == nullptr ||
+ wrapped_key->raw_key == nullptr ||
+ wrapped_key->key_size == 0 ||
+ wrapped_key->key_size * 8 < size ||
+ alias == nullptr ||
+ ((size != 128) & (size != 192) & (size != 256)) ||
+ ppdata == nullptr)
+ return CKMC_ERROR_INVALID_PARAMETER;
+
+ const CKM::CryptoAlgorithm *ca = reinterpret_cast<const CKM::CryptoAlgorithm *>
+ (params);
+
+ int ret = 0;
+ CKM::RawBuffer data_buffer;
+
+ if (static_cast<CKM::KeyType>(wrapped_key->key_type) != CKM::KeyType::KEY_AES)
+ return CKMC_ERROR_INVALID_PARAMETER;
+
+ auto mgr = CKM::Manager::create();
+
+ ret = to_ckmc_error(
+ mgr->unwrapConcatenatedData(*ca,
+ CKM::Alias(wrapping_key_alias),
+ _tostring(wrapping_key_password),
+ CKM::RawBuffer(wrapped_key->raw_key,
+ wrapped_key->raw_key + wrapped_key->key_size),
+ CKM::Alias(alias),
+ size,
+ _toCkmPolicy(policy),
+ data_buffer));
+
+ if (ret == CKMC_ERROR_NONE) {
+ ret = ckmc_buffer_new(data_buffer.data(),
+ data_buffer.size(),
+ ppdata);
+ }
+
+ return ret;
+ EXCEPTION_GUARD_END
}
\ No newline at end of file
EXCEPTION_GUARD_END
}
+int Manager::Impl::wrapConcatenatedData(const CryptoAlgorithm ¶ms,
+ const Alias &wrappingKeyAlias,
+ const Password &wrappingKeyPassword,
+ const Alias &alias,
+ const Password &password,
+ const RawBuffer &data,
+ RawBuffer &wrappedKey)
+{
+ EXCEPTION_GUARD_START_CPPAPI
+
+ AliasSupport wrappingAliasHelper(wrappingKeyAlias);
+ AliasSupport aliasHelper(alias);
+ DataType dataTypeKey;
+
+ int retCode = Request(*this,
+ LogicCommand::WRAP_CONCATENATED_DATA,
+ m_storageConnection,
+ CryptoAlgorithmSerializable(params),
+ wrappingAliasHelper.getName(),
+ wrappingAliasHelper.getOwner(),
+ wrappingKeyPassword,
+ aliasHelper.getName(),
+ aliasHelper.getOwner(),
+ password,
+ data
+ ).maybeDeserialize(dataTypeKey, wrappedKey);
+
+ if (retCode != CKM_API_SUCCESS)
+ return retCode;
+
+ if (!dataTypeKey.isSymmetricKey()) {
+ return CKM_API_ERROR_INVALID_FORMAT;
+ }
+
+ return retCode;
+
+ EXCEPTION_GUARD_END
+}
+
+int Manager::Impl::unwrapConcatenatedData(const CryptoAlgorithm ¶ms,
+ const Alias &wrappingKeyAlias,
+ const Password &wrappingKeyPassword,
+ const RawBuffer &wrappedKey,
+ const Alias &alias,
+ size_t size,
+ const Policy &policy,
+ RawBuffer &data)
+{
+ EXCEPTION_GUARD_START_CPPAPI
+
+ AliasSupport wrappingAliasHelper(wrappingKeyAlias);
+ AliasSupport aliasHelper(alias);
+
+ return Request(*this,
+ LogicCommand::UNWRAP_CONCATENATED_DATA,
+ m_storageConnection,
+ CryptoAlgorithmSerializable(params),
+ wrappingAliasHelper.getName(),
+ wrappingAliasHelper.getOwner(),
+ wrappingKeyPassword,
+ wrappedKey,
+ aliasHelper.getName(),
+ aliasHelper.getOwner(),
+ size,
+ PolicySerializable(policy)
+ ).maybeDeserialize(data);
+
+ EXCEPTION_GUARD_END
+}
+
int Manager::Impl::initializeCipher(
const CryptoAlgorithm ¶ms,
const Alias &keyAlias,
KeyType &keyType,
RawBuffer &wrappedKey);
+ int wrapConcatenatedData(const CryptoAlgorithm ¶ms,
+ const Alias &wrappingKeyAlias,
+ const Password &wrappingKeyPassword,
+ const Alias &alias,
+ const Password &password,
+ const RawBuffer &data,
+ RawBuffer &wrappedKey);
+
+ int unwrapConcatenatedData(const CryptoAlgorithm ¶ms,
+ const Alias &wrappingKeyAlias,
+ const Password &wrappingKeyPassword,
+ const RawBuffer &wrappedKey,
+ const Alias &alias,
+ size_t size,
+ const Policy &policy,
+ RawBuffer &data);
+
int initializeCipher(const CryptoAlgorithm ¶ms,
const Alias &keyAlias,
const Password &keyPassword,
);
}
+int Manager::wrapConcatenatedData(
+ const CryptoAlgorithm ¶ms,
+ const Alias &wrappingKeyAlias,
+ const Password &wrappingKeyPassword,
+ const Alias &alias,
+ const Password &password,
+ const RawBuffer &data,
+ RawBuffer &wrappedKey)
+{
+ return m_impl->wrapConcatenatedData(
+ params,
+ wrappingKeyAlias,
+ wrappingKeyPassword,
+ alias,
+ password,
+ data,
+ wrappedKey
+ );
+}
+
+int Manager::unwrapConcatenatedData(
+ const CryptoAlgorithm ¶ms,
+ const Alias &wrappingKeyAlias,
+ const Password &wrappingKeyPassword,
+ const RawBuffer &wrappedKey,
+ const Alias &alias,
+ size_t size,
+ const Policy &policy,
+ RawBuffer &data)
+{
+ return m_impl->unwrapConcatenatedData(
+ params,
+ wrappingKeyAlias,
+ wrappingKeyPassword,
+ wrappedKey,
+ alias,
+ size,
+ policy,
+ data
+ );
+}
+
int Manager::initializeCipher(
const CryptoAlgorithm ¶ms,
const Alias &keyAlias,
DERIVE,
IMPORT_WRAPPED_KEY,
EXPORT_WRAPPED_KEY,
+ WRAP_CONCATENATED_DATA,
+ UNWRAP_CONCATENATED_DATA,
GET_BACKEND_INFO
};
ThrowErr(Exc::Crypto::OperationNotSupported);
}
+ virtual RawBuffer wrapConcatenated(const CryptoAlgorithm &,
+ const Token &,
+ const Password &,
+ const RawBuffer &)
+ {
+ ThrowErr(Exc::Crypto::OperationNotSupported);
+ }
+
+ virtual std::tuple<Token, RawBuffer> unwrapConcatenated(const CryptoAlgorithm &,
+ const Data &,
+ const Password &,
+ size_t,
+ const RawBuffer &)
+ {
+ ThrowErr(Exc::Crypto::OperationNotSupported);
+ }
+
// onward = true for encryption/signing, false for decryption/verification
virtual GCtxShPtr initContext(const CryptoAlgorithm &, bool /*onward*/)
{
return encrypt(params, data);
}
-
RawBuffer SKey::encrypt(const CryptoAlgorithm &alg, const RawBuffer &data)
{
return Internals::symmetricEncrypt(getBinary(), alg, data);
ThrowErr(Exc::Crypto::OperationNotSupported);
}
+RawBuffer AKey::wrapConcatenated(const CryptoAlgorithm ¶ms,
+ const Token &keyToWrap,
+ const Password &keyToWrapPass,
+ const RawBuffer &data)
+{
+ RawBuffer key = Store::unpack(keyToWrap.data, keyToWrapPass);
+
+ key.insert(key.end(), data.begin(), data.begin() + data.size());
+ return encrypt(params, key);
+}
+
+std::tuple<Token, RawBuffer> AKey::unwrapConcatenated(const CryptoAlgorithm ¶ms,
+ const Data &wrappedKey,
+ const Password &pass,
+ size_t size,
+ const RawBuffer &)
+{
+ if (!wrappedKey.type.isSymmetricKey()) {
+ ThrowErr(Exc::Crypto::InputParam, "Wrapped data is not a symmetric key");
+ }
+
+ auto decrypted = decrypt(params, wrappedKey.data);
+ RawBuffer key;
+ key.reserve(size/8);
+ key.insert(key.end(), decrypted.begin(), decrypted.begin() + size/8);
+ RawBuffer data;
+ data.reserve(decrypted.size() - size/8);
+ data.insert(data.end(), decrypted.begin() + size/8, decrypted.end());
+
+ // validate the decrypted key
+ auto tmp = CKM::Key::createAES(key);
+ if (!tmp)
+ ThrowErr(Exc::Crypto::InputParam, "Wrapped data is not a valid AES key");
+
+ return std::make_tuple(Token(backendId(), wrappedKey.type, Store::pack(key, pass)), data);
+}
+
EvpShPtr Cert::getEvpShPtr()
{
if (m_evp)
ThrowErr(Exc::Crypto::OperationNotSupported);
}
+RawBuffer Cert::wrapConcatenated(const CryptoAlgorithm &,
+ const Token &, const Password &,
+ const RawBuffer &)
+{
+ ThrowErr(Exc::Crypto::OperationNotSupported);
+}
+
+std::tuple<Token, RawBuffer> Cert::unwrapConcatenated(const CryptoAlgorithm &,
+ const Data &, const Password &,
+ size_t,
+ const RawBuffer &)
+{
+ ThrowErr(Exc::Crypto::OperationNotSupported);
+}
+
} // namespace SW
} // namespace Crypto
} // namespace CKM
RawBuffer wrap(const CryptoAlgorithm ¶ms,
const Token &keyToWrap,
const Password &keyToWrapPass) override;
-
};
class SKey : public Key {
Token derive(const CryptoAlgorithm &, const Password &, const RawBuffer &) override;
GCtxShPtr initContext(const CryptoAlgorithm &, bool) override;
+ RawBuffer wrapConcatenated(const CryptoAlgorithm ¶ms,
+ const Token &keyToWrap,
+ const Password &keyToWrapPass,
+ const RawBuffer &data) override;
+
+ std::tuple<Token, RawBuffer> unwrapConcatenated(const CryptoAlgorithm ¶ms,
+ const Data &wrappedKey,
+ const Password &pass,
+ size_t size,
+ const RawBuffer &data) override;
+
protected:
virtual EvpShPtr getEvpShPtr();
const Token &,
const Password &) override;
+ RawBuffer wrapConcatenated(const CryptoAlgorithm &,
+ const Token &, const Password &,
+ const RawBuffer &) override;
+
+ std::tuple<Token, RawBuffer> unwrapConcatenated(const CryptoAlgorithm &,
+ const Data &, const Password &,
+ size_t,
+ const RawBuffer &) override;
+
protected:
EvpShPtr getEvpShPtr() override;
};
retCode2 = readRowHelper(false, cred, DataType::DB_KEY_FIRST, keyName,
keyOwner, keyPassword, wrappedKeyRow, wrappedKeyType);
+
if (retCode2 != CKM_API_SUCCESS)
return retCode2;
+ if (wrappingKey->backendId() != wrappedKeyRow.backendId) {
+ LogError("Mismatched backends");
+ return CKM_API_ERROR_INPUT_PARAM;
+ }
+
if (!wrappedKeyType.isSymmetricKey()) {
LogError("Only symmetric key can be exported");
return CKM_API_ERROR_INPUT_PARAM;
return SerializeMessage(msgID, retCode, wrappedKeyType, wrappedKey);
}
+RawBuffer CKMLogic::wrapConcatenatedData(
+ const Credentials &cred,
+ const int msgID,
+ const CryptoAlgorithm ¶ms,
+ const Name &wrappingKeyName,
+ const ClientId &wrappingKeyOwner,
+ const Password &wrappingKeyPassword,
+ const Name &keyName,
+ const ClientId &keyOwner,
+ const Password &keyPassword,
+ const RawBuffer &data)
+{
+ Crypto::GObjUPtr wrappingKey;
+ DB::Row keyRow;
+ DataType keyType;
+ RawBuffer wrappedKey;
+
+ auto retCode = tryRet([&] {
+ auto retCode2 = readDataHelper(false, cred, DataType::KEY_RSA_PUBLIC, wrappingKeyName,
+ wrappingKeyOwner, wrappingKeyPassword, wrappingKey);
+ if (retCode2 != CKM_API_SUCCESS)
+ return retCode2;
+
+ retCode2 = readRowHelper(false, cred, DataType::DB_KEY_FIRST, keyName,
+ keyOwner, keyPassword, keyRow, keyType);
+ if (retCode2 != CKM_API_SUCCESS)
+ return retCode2;
+
+ if (wrappingKey->backendId() != keyRow.backendId) {
+ LogError("Mismatched backends");
+ return CKM_API_ERROR_INPUT_PARAM;
+ }
+
+ if (!keyType.isSymmetricKey()) {
+ LogError("Only symmetric key can be exported");
+ return CKM_API_ERROR_INPUT_PARAM;
+ }
+
+ wrappedKey = wrappingKey->wrapConcatenated(params, keyRow, keyPassword, data);
+
+ return retCode2;
+ });
+
+ return SerializeMessage(msgID, retCode, keyType, wrappedKey);
+}
+
+RawBuffer CKMLogic::unwrapConcatenatedData(
+ const Credentials &cred,
+ const int msgID,
+ const CryptoAlgorithm ¶ms,
+ const Name &wrappingKeyName,
+ const ClientId &wrappingKeyOwner,
+ const Password &wrappingKeyPassword,
+ const RawBuffer &wrappedKey,
+ const Name &keyName,
+ const ClientId &keyOwner,
+ size_t size,
+ const PolicySerializable &policy)
+{
+ RawBuffer data;
+
+ auto retCode = tryRet([&] {
+ Crypto::GObjUPtr wrappingKey;
+
+ auto [dbOp, digest, retCode2] = beginSaveAndGetHash(cred, keyName, keyOwner);
+ if (retCode2 != CKM_API_SUCCESS)
+ return retCode2;
+
+ DataType wrappingKeyType;
+ retCode2 = readDataHelper(false,
+ cred,
+ DataType::DB_KEY_FIRST,
+ wrappingKeyName,
+ wrappingKeyOwner,
+ wrappingKeyPassword,
+ wrappingKey,
+ wrappingKeyType);
+ if (retCode2 != CKM_API_SUCCESS)
+ return retCode2;
+
+ if (wrappingKeyType != DataType::KEY_RSA_PRIVATE) {
+ LogError("Only a private RSA key can be used for decryption");
+ return CKM_API_ERROR_INPUT_PARAM;
+ }
+
+ if (!m_decider.checkStore(wrappingKey->backendId(), DataType::KEY_AES, policy, true)) {
+ LogDebug("Can't import the wrapped key to backend " <<
+ static_cast<int>(wrappingKey->backendId()) << " with given policy");
+ return CKM_API_ERROR_INPUT_PARAM;
+ }
+
+ std::tuple<Token, RawBuffer> tokenWithData =
+ wrappingKey->unwrapConcatenated(params,
+ Crypto::Data(DataType::KEY_AES, wrappedKey),
+ policy.password,
+ size,
+ digest);
+
+ dbOp.finalize(std::move(std::get<0>(tokenWithData)), policy);
+ data = std::get<1>(tokenWithData);
+
+ return retCode2;
+ });
+
+ return SerializeMessage(msgID, retCode, data);
+}
+
RawBuffer CKMLogic::getBackendInfo(const int msgID, BackendId backend)
{
BackendInfo info;
const ClientId &keyOwner,
const Password &keyPassword);
+ RawBuffer wrapConcatenatedData(
+ const Credentials &cred,
+ const int msgID,
+ const CryptoAlgorithm ¶ms,
+ const Name &wrappingKeyName,
+ const ClientId &wrappingKeyOwner,
+ const Password &wrappingKeyPassword,
+ const Name &keyName,
+ const ClientId &keyOwner,
+ const Password &keyPassword,
+ const RawBuffer &data);
+
+ RawBuffer unwrapConcatenatedData(
+ const Credentials &cred,
+ const int msgID,
+ const CryptoAlgorithm ¶ms,
+ const Name &wrappingKeyName,
+ const ClientId &wrappingKeyOwner,
+ const Password &wrappingKeyPassword,
+ const RawBuffer &wrappedKey,
+ const Name &keyName,
+ const ClientId &keyOwner,
+ size_t size,
+ const PolicySerializable &policy);
+
RawBuffer getBackendInfo(
const int msgID,
BackendId backend);
keyPassword);
}
+ case LogicCommand::WRAP_CONCATENATED_DATA: {
+ CryptoAlgorithmSerializable params;
+ Name wrappingKeyName;
+ ClientId wrappingKeyOwner;
+ Password wrappingKeyPassword;
+ Name keyName;
+ Password keyPassword;
+ RawBuffer data;
+
+ buffer.Deserialize(params,
+ wrappingKeyName,
+ wrappingKeyOwner,
+ wrappingKeyPassword,
+ keyName,
+ explicitOwner,
+ keyPassword,
+ data);
+
+ return m_logic->wrapConcatenatedData(
+ cred,
+ msgId,
+ params,
+ wrappingKeyName,
+ cred.effectiveOwner(wrappingKeyOwner),
+ wrappingKeyPassword,
+ keyName,
+ cred.effectiveOwner(explicitOwner),
+ keyPassword,
+ data);
+ }
+
+ case LogicCommand::UNWRAP_CONCATENATED_DATA: {
+ CryptoAlgorithmSerializable params;
+ Name wrappingKeyName;
+ ClientId wrappingKeyOwner;
+ Password wrappingKeyPassword;
+ RawBuffer wrappedKey;
+ Name keyName;
+ size_t size;
+ PolicySerializable policy;
+
+ buffer.Deserialize(params,
+ wrappingKeyName,
+ wrappingKeyOwner,
+ wrappingKeyPassword,
+ wrappedKey,
+ keyName,
+ explicitOwner,
+ size,
+ policy);
+
+ return m_logic->unwrapConcatenatedData(
+ cred,
+ msgId,
+ params,
+ wrappingKeyName,
+ cred.effectiveOwner(wrappingKeyOwner),
+ wrappingKeyPassword,
+ wrappedKey,
+ keyName,
+ cred.effectiveOwner(explicitOwner),
+ size,
+ policy);
+ }
+
case LogicCommand::GET_BACKEND_INFO: {
BackendId backend;