const KeyType keyType,
const Policy &policy);
+ int exportWrappedKey(const CryptoAlgorithm ¶ms,
+ const Alias &wrappingKeyAlias,
+ const Password &wrappingKeyPassword,
+ const Alias &wrappedKeyAlias,
+ const Password &wrappedKeyPassword,
+ KeyType &keyType,
+ RawBuffer &wrappedKey);
+
private:
std::unique_ptr<Impl> m_impl;
};
* - #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
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);
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
+}
EXCEPTION_GUARD_END
}
+int Manager::Impl::exportWrappedKey(const CryptoAlgorithm ¶ms,
+ 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
const KeyType keyType,
const Policy &policy);
+ int exportWrappedKey(const CryptoAlgorithm ¶ms,
+ const Alias &wrappingKeyAlias,
+ const Password &wrappingKeyPassword,
+ const Alias &wrappedKeyAlias,
+ const Password &wrappedKeyPassword,
+ KeyType &keyType,
+ RawBuffer &wrappedKey);
+
private:
int saveBinaryData(
const Alias &alias,
}
}
-} // namespace CKM
+int Manager::exportWrappedKey(
+ const CryptoAlgorithm ¶ms,
+ 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
GET_PKCS12,
GET_PROTECTION_STATUS,
DERIVE,
- IMPORT_WRAPPED_KEY
+ IMPORT_WRAPPED_KEY,
+ EXPORT_WRAPPED_KEY
};
enum class EncryptionCommand : int {
};
} // namespace CKM
-
ThrowErr(Exc::Crypto::OperationNotSupported);
}
+ virtual RawBuffer wrap(const CryptoAlgorithm &,
+ const Token &,
+ const Password &)
+ {
+ ThrowErr(Exc::Crypto::OperationNotSupported);
+ }
+
virtual ~GObj()
{
}
return Token(backendId(), encryptedKey.type, Store::pack(decrypted, pass));
}
+RawBuffer Key::wrap(const CryptoAlgorithm ¶ms,
+ 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);
ThrowErr(Exc::Crypto::OperationNotSupported);
}
+RawBuffer Cert::wrap(const CryptoAlgorithm &,
+ const Token &,
+ const Password &)
+{
+ ThrowErr(Exc::Crypto::OperationNotSupported);
+}
+
} // namespace SW
} // namespace Crypto
} // namespace CKM
const Data &encryptedKey,
const Password &pass,
const RawBuffer &hash) override;
+
+ RawBuffer wrap(const CryptoAlgorithm ¶ms,
+ const Token &keyToWrap,
+ const Password &keyToWrapPass) override;
+
};
class SKey : public Key {
const Password &,
const RawBuffer &) override;
+ RawBuffer wrap(const CryptoAlgorithm &,
+ const Token &,
+ const Password &) override;
+
protected:
EvpShPtr getEvpShPtr() override;
};
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);
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
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
const CKM::DataType encryptedKeyType,
const PolicySerializable &encryptedKeyPolicy)
{
-
return SerializeMessage(msgId, tryRet([&] {
Crypto::GObjUPtr wrappingKey;
}));
}
+RawBuffer CKMLogic::exportWrappedKey(
+ const Credentials &cred,
+ const int msgID,
+ const CryptoAlgorithm ¶ms,
+ 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
const ClientId &newKeyOwner,
const Policy &newKeyPolicy);
+ RawBuffer exportWrappedKey(
+ const Credentials &cred,
+ const int msgID,
+ const CryptoAlgorithm ¶ms,
+ 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,
};
} // namespace CKM
-
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);
}