diff --git a/share/translations/keepassxc_en.ts b/share/translations/keepassxc_en.ts
index 574dc39671..f8f78d13d0 100644
--- a/share/translations/keepassxc_en.ts
+++ b/share/translations/keepassxc_en.ts
@@ -9424,6 +9424,26 @@ This option is deprecated, use --set-key-file instead.
Confirm Replace Entry References
+
+ Version information not found.
+
+
+
+ Major version %1 is not supported.
+
+
+
+ No exporter data or timestamp provided.
+
+
+
+ No accounts to read.
+
+
+
+ No accounts were succesfully read.
+
+ QtIOCompressor
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 1bf2a795ec..89af67649b 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -57,6 +57,8 @@ set(core_SOURCES
crypto/kdf/AesKdf.cpp
crypto/kdf/Argon2Kdf.cpp
format/BitwardenReader.cpp
+ format/CredentialExchangeReader.cpp
+ format/CredentialExchangeWriter.cpp
format/CsvExporter.cpp
format/CsvParser.cpp
format/HtmlExporter.cpp
diff --git a/src/format/CredentialExchangeReader.cpp b/src/format/CredentialExchangeReader.cpp
new file mode 100644
index 0000000000..91338a73e6
--- /dev/null
+++ b/src/format/CredentialExchangeReader.cpp
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2026 KeePassXC Team
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 or (at your option)
+ * version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include "CredentialExchangeReader.h"
+
+#include "core/Entry.h"
+
+#include
+#include
+#include
+#include
+#include
+
+static const auto CREDENTIAL_PASSKEY = QStringLiteral("passkey");
+
+namespace
+{
+ // Parse created and modified timestamps
+ void setTimeInfo(const QScopedPointer& entry, const QJsonObject& item)
+ {
+ auto timeInfo = entry->timeInfo();
+ const auto creationAt = item["creationAt"].toInteger();
+ const auto modifiedAt = item["modifiedAt"].toInteger();
+ const auto creationTimestamp = QDateTime::fromSecsSinceEpoch(creationAt).toUTC();
+ const auto modifiedTimestamp = QDateTime::fromSecsSinceEpoch(modifiedAt).toUTC();
+ timeInfo.setCreationTime(creationTimestamp);
+ timeInfo.setLastModificationTime(modifiedTimestamp);
+ entry->setTimeInfo(timeInfo);
+ }
+
+ // Parse credential of "passkey" type
+ void setPasskeyCredential(const QScopedPointer& entry, const QJsonObject& credential)
+ {
+ const auto credentialId = credential["credentialId"].toString();
+ const auto rpId = credential["rpId"].toString();
+ const auto passkeyUsername = credential["username"].toString();
+ const auto userDisplayName = credential["userDisplayName"].toString();
+ const auto userHandle = credential["userHandle"].toString();
+ // The value MUST be PKCS#8 ASN.1 DER formatted byte string which is then Base64url encoded.
+ const auto privateKey = credential["key"].toString();
+
+ // TODO: fido2Extensions.hmacCredentials should be handled after PRF support has been made.
+ entry->attributes()->set(EntryAttributes::KPEX_PASSKEY_USERNAME, passkeyUsername);
+ entry->attributes()->set(EntryAttributes::KPEX_PASSKEY_CREDENTIAL_ID, credentialId, true);
+ entry->attributes()->set(EntryAttributes::KPEX_PASSKEY_PRIVATE_KEY_PEM, privateKey, true);
+ entry->attributes()->set(EntryAttributes::KPEX_PASSKEY_RELYING_PARTY, rpId);
+ entry->attributes()->set(EntryAttributes::KPEX_PASSKEY_USER_HANDLE, userHandle, true);
+ entry->attributes()->set(EntryAttributes::KPEX_PASSKEY_FLAG_BE, "1");
+ entry->attributes()->set(EntryAttributes::KPEX_PASSKEY_FLAG_BS, "1");
+ }
+
+ // Account can has multiple items. Create a new entry for an Account, and parse Items to it.
+ // Credentials under Item can contain multple objects. Only passkey credentials are supported for now.
+ // TODO: It needs to be decided if each Item needs a separate entry, or is one Account one entry, and each
+ // Item is added to it. The Account doesn't have a common title, but title can vary per each Item.
+ Entry* readAccount(const QJsonObject& account)
+ {
+ QScopedPointer entry(new Entry());
+
+ // Account info
+ const auto username = account["username"].toString();
+ const auto email = account["email"].toString();
+ // KeePassXC does not have a separate email field. Use email as username if username is not set.
+ entry->setUsername(username.isEmpty() ? email : username);
+
+ // Parse Item entities
+ const auto items = account["items"].toArray();
+ for (const auto& i : items) {
+ const auto item = i.toObject();
+
+ entry->setEmitModified(false);
+ entry->setUuid(QUuid::createUuid());
+
+ // TODO: How to handle titles if there are multiple items?
+ entry->setTitle(item["title"].toString());
+ setTimeInfo(entry, item);
+
+ // Parse item credentials
+ const auto credentials = item["credentials"].toArray();
+ for (const auto& cred : credentials) {
+ const auto credential = cred.toObject();
+ const auto credentialType = credential["type"].toString();
+
+ // Only support passkeys for now
+ if (credentialType == CREDENTIAL_PASSKEY) {
+ setPasskeyCredential(entry, credential);
+ }
+ }
+
+ entry->setEmitModified(true);
+ }
+
+ return entry.take();
+ }
+} // namespace
+
+bool CredentialExchangeReader::hasError()
+{
+ return !m_error.isEmpty();
+}
+
+QString CredentialExchangeReader::errorString()
+{
+ return m_error;
+}
+
+QList CredentialExchangeReader::readEntries(const QJsonObject& data)
+{
+ // Verify version
+ const auto version = data["version"].toObject();
+ if (version.isEmpty()) {
+ m_error = QObject::tr("Version information not found.");
+ return {};
+ }
+
+ // Minor versions should be compatible
+ const auto majorVersion = version["major"].toInt();
+ if (majorVersion < CXF_MAJOR_VERSION) {
+ m_error = QObject::tr("Major version %1 is not supported.").arg(majorVersion);
+ return {};
+ }
+
+ // Check exporter and timestamp exists
+ if (data["exporterRpId"].toString().isEmpty() || data["exporterDisplayName"].toString().isEmpty()
+ || data["timestamp"].toInteger() == 0) {
+ m_error = QObject::tr("No exporter data or timestamp provided.");
+ return {};
+ }
+
+ // Parse accounts
+ const auto accounts = data["accounts"].toArray();
+ if (accounts.isEmpty()) {
+ // No accounts to import
+ m_error = QObject::tr("No accounts to read.");
+ return {};
+ }
+
+ QList entries;
+ for (const auto& account : accounts) {
+ const auto accountEntry = readAccount(account.toObject());
+ if (accountEntry) {
+ entries << accountEntry;
+ }
+ }
+
+ if (entries.isEmpty()) {
+ m_error = QObject::tr("No accounts were succesfully read.");
+ }
+ return entries;
+}
diff --git a/src/format/CredentialExchangeReader.h b/src/format/CredentialExchangeReader.h
new file mode 100644
index 0000000000..f382b0f19b
--- /dev/null
+++ b/src/format/CredentialExchangeReader.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2026 KeePassXC Team
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 or (at your option)
+ * version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef CREDENTIAL_EXCHANGE_READER_H
+#define CREDENTIAL_EXCHANGE_READER_H
+
+#define CXF_MAJOR_VERSION 1
+#define CXF_MINOR_VERSION 0
+
+#include
+
+class Entry;
+
+class CredentialExchangeReader
+{
+public:
+ explicit CredentialExchangeReader() = default;
+ ~CredentialExchangeReader() = default;
+
+ QList readEntries(const QJsonObject& data);
+
+ bool hasError();
+ QString errorString();
+
+private:
+ QString m_error;
+};
+
+#endif // CREDENTIAL_EXCHANGE_READER_H
diff --git a/src/format/CredentialExchangeWriter.cpp b/src/format/CredentialExchangeWriter.cpp
new file mode 100644
index 0000000000..7f20138be3
--- /dev/null
+++ b/src/format/CredentialExchangeWriter.cpp
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2026 KeePassXC Team
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 or (at your option)
+ * version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include "CredentialExchangeWriter.h"
+#include "CredentialExchangeReader.h"
+
+#include "core/Clock.h"
+#include "core/Entry.h"
+
+#include
+
+static const auto EXPORTER_RPID = QStringLiteral("keepassxc.org");
+static const auto EXPORTER_DISPLAY_NAME = QStringLiteral("KeePassXC");
+
+namespace
+{
+ QJsonObject writeEntry(const Entry* entry)
+ {
+ // Only passkey entries are supported at the moment
+ if (!entry->hasPasskey()) {
+ return {};
+ }
+
+ QJsonObject entryObject{
+ {"id", QString(entry->uuid().toByteArray().toBase64())},
+ {"username", entry->username()},
+ {"email", QString()}, // There is no email in KeePassXC
+ };
+
+ QJsonArray items;
+ const auto passkeyUsername = entry->attributes()->value(EntryAttributes::KPEX_PASSKEY_USERNAME);
+ const auto credentialId = entry->attributes()->value(EntryAttributes::KPEX_PASSKEY_CREDENTIAL_ID);
+ const auto privateKey = entry->attributes()->value(EntryAttributes::KPEX_PASSKEY_PRIVATE_KEY_PEM);
+ const auto rpId = entry->attributes()->value(EntryAttributes::KPEX_PASSKEY_RELYING_PARTY);
+ const auto userHandle = entry->attributes()->value(EntryAttributes::KPEX_PASSKEY_USER_HANDLE);
+
+ QJsonArray credentials;
+ credentials << QJsonObject{
+ {"type", "passkey"},
+ {"credentialId", credentialId},
+ {"rpId", rpId},
+ {"username", passkeyUsername},
+ {"userDisplayName", QString()}, // KeePassXC does not store this
+ {"userHandle", userHandle},
+ {"key", privateKey},
+ };
+ // TODO: Write fido2Extensions
+
+ const auto& timeInfo = entry->timeInfo();
+ const auto creationAt = timeInfo.creationTime().toUTC().toSecsSinceEpoch();
+ const auto modifiedAt = timeInfo.lastModificationTime().toUTC().toSecsSinceEpoch();
+ items << QJsonObject{{"id", credentialId},
+ {"creationAt", creationAt},
+ {"modifiedAt", modifiedAt},
+ {"title", entry->title()},
+ {"credentials", credentials}};
+
+ entryObject["items"] = items;
+ return entryObject;
+ }
+} // namespace
+
+QJsonObject CredentialExchangeWriter::writeEntries(const QList& entries)
+{
+ if (entries.isEmpty()) {
+ // No entries provided
+ return {};
+ }
+
+ QJsonObject version{
+ {"major", CXF_MAJOR_VERSION},
+ {"minor", CXF_MINOR_VERSION},
+ };
+
+ QJsonArray accounts;
+ for (const auto& entry : entries) {
+ if (const auto entryObject = writeEntry(entry); !entryObject.isEmpty()) {
+ accounts << entryObject;
+ }
+ }
+
+ const auto timestamp = static_cast(Clock::currentSecondsSinceEpoch());
+ return QJsonObject{{"version", version},
+ {"exporterRpId", EXPORTER_RPID},
+ {"exporterDisplayName", EXPORTER_DISPLAY_NAME},
+ {"timestamp", timestamp},
+ {"accounts", accounts}};
+}
diff --git a/src/format/CredentialExchangeWriter.h b/src/format/CredentialExchangeWriter.h
new file mode 100644
index 0000000000..819c25d304
--- /dev/null
+++ b/src/format/CredentialExchangeWriter.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2026 KeePassXC Team
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 or (at your option)
+ * version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef CREDENTIAL_EXCHANGE_WRITER_H
+#define CREDENTIAL_EXCHANGE_WRITER_H
+
+#include
+#include
+
+class Entry;
+
+class CredentialExchangeWriter
+{
+public:
+ explicit CredentialExchangeWriter() = default;
+ ~CredentialExchangeWriter() = default;
+
+ QJsonObject writeEntries(const QList& entries);
+};
+
+#endif // CREDENTIAL_EXCHANGE_WRITER_H
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index d11e5660b5..554b784181 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -85,6 +85,9 @@ add_unit_test(NAME testdeletedobjects SOURCES TestDeletedObjects.cpp
add_unit_test(NAME testkeepass1reader SOURCES TestKeePass1Reader.cpp
LIBS ${TEST_LIBRARIES})
+add_unit_test(NAME testcredentialexchange SOURCES TestCredentialExchange.cpp
+ LIBS ${TEST_LIBRARIES})
+
add_unit_test(NAME testimports SOURCES TestImports.cpp
LIBS ${TEST_LIBRARIES})
diff --git a/tests/TestCredentialExchange.cpp b/tests/TestCredentialExchange.cpp
new file mode 100644
index 0000000000..53c153e5fc
--- /dev/null
+++ b/tests/TestCredentialExchange.cpp
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2026 KeePassXC Team
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 or (at your option)
+ * version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+#include "TestCredentialExchange.h"
+
+#include "config-keepassx-tests.h"
+#include "core/Entry.h"
+#include "format/CredentialExchangeReader.h"
+#include "format/CredentialExchangeWriter.h"
+
+#include
+#include
+#include
+#include
+
+QTEST_GUILESS_MAIN(TestCredentialExchange)
+
+// clang-format off
+const QString CredentialExchangeData = R"(
+ {
+ "version": {
+ "major": 1,
+ "minor": 0
+ },
+ "exporterRpId": "exporter.example.com",
+ "exporterDisplayName": "Exporter app",
+ "timestamp": 1705228800,
+ "accounts": [
+ {
+ "id": "DZSXp7iBQY-Fg-OofakQtQ",
+ "username": "jane_smith",
+ "email": "jane.smith@example.com",
+ "fullName": "Jane Smith",
+ "items": [
+ {
+ "id": "akKA3Y0jQRuK7sKplB0Y9w",
+ "creationAt": 1705142400,
+ "modifiedAt": 1705228800,
+ "title": "WebAuthn.io",
+ "subtitle": "johndoe",
+ "credentials": [
+ {
+ "type": "passkey",
+ "credentialId": "Y3JlZGVudGlhbElkRXhhbXBsZQ",
+ "rpId": "webauthn.io",
+ "username": "johndoe",
+ "userDisplayName": "John Doe",
+ "userHandle": "cnEzaNHWcYK3coWZjvoaV1Hj9gnI12mKe2dL2HZVFlY",
+ "key": "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgARu_0sCt20EpgVxb4Puq3Ga5VVLpuTY75ngvZlyq3X6hRANCAASmdk1xLsK0oOlhxIPp0d1ZuS0sT9nf6BZtSelhqvLBW0fOL33l_bXgsr_STUHjCLn8l6gcRJwe7OQvbQubZ1dY",
+ "fido2Extensions": {
+ "hmacCredentials": {
+ "algorithm": "hmac-sha256",
+ "credWithUV": "j3N5T9qLpWz2rYf4vS6lDn1KpQx8E0fRc2a7Bm5nUsw",
+ "credWithoutUV": "y2R8tL3eWf5qBz0sK4hHn9rVgX7pD1cQm6uTj2aP8Fs"
+ },
+ "credBlob": "eyJ1c2VyTmFtZSI6ICJKb2huIERvZSIsICJ1c2VySWQiOiAiamRvZS0wMDEiLCAiZW1haWwiOiAiamRvZUBleGFtcGxlLmNvbSJ9",
+ "largeBlob": {
+ "uncompressedSize": 129,
+ "data": "HYxBCoUwDESvMgcQT-Hqr71ATIMtlKQkkY-3twrDLIb3Zq8tMEMKUfZ7pBR08lNwdDtAEcaN3vXfsuJnVbGZrNhf82PYrl5ma1JTXCGOQkkLaAxETnmBOb53O51GbYwQdslYHw"
+ },
+ "payments": true
+ }
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+)";
+
+// clang-format on
+
+void TestCredentialExchange::initTestCase()
+{
+ QLocale::setDefault(QLocale::c());
+}
+
+void TestCredentialExchange::testCredentialExchangeReader()
+{
+ const QJsonDocument doc(QJsonDocument::fromJson(CredentialExchangeData.toUtf8()));
+ const auto importData = doc.object();
+
+ CredentialExchangeReader reader;
+ const auto entries = reader.readEntries(importData);
+ QVERIFY2(!reader.hasError(), qPrintable(reader.errorString()));
+
+ QVERIFY(!entries.isEmpty());
+ const auto firstEntry = entries.first();
+ QCOMPARE(firstEntry->username(), QString("jane_smith"));
+ QCOMPARE(firstEntry->title(), QString("WebAuthn.io"));
+ QCOMPARE(firstEntry->attributes()->value(EntryAttributes::KPEX_PASSKEY_USERNAME), QString("johndoe"));
+ QCOMPARE(firstEntry->attributes()->value(EntryAttributes::KPEX_PASSKEY_CREDENTIAL_ID),
+ QString("Y3JlZGVudGlhbElkRXhhbXBsZQ"));
+ QCOMPARE(firstEntry->attributes()->value(EntryAttributes::KPEX_PASSKEY_PRIVATE_KEY_PEM),
+ QString("MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgARu_"
+ "0sCt20EpgVxb4Puq3Ga5VVLpuTY75ngvZlyq3X6hRANCAASmdk1xLsK0oOlhxIPp0d1ZuS0sT9nf6BZtSelhqvLBW0fOL33l_"
+ "bXgsr_STUHjCLn8l6gcRJwe7OQvbQubZ1dY"));
+ QCOMPARE(firstEntry->attributes()->value(EntryAttributes::KPEX_PASSKEY_RELYING_PARTY), QString("webauthn.io"));
+ QCOMPARE(firstEntry->attributes()->value(EntryAttributes::KPEX_PASSKEY_USER_HANDLE),
+ QString("cnEzaNHWcYK3coWZjvoaV1Hj9gnI12mKe2dL2HZVFlY"));
+ QCOMPARE(firstEntry->timeInfo().creationTime().toString(Qt::ISODate), QString("2024-01-13T10:40:00Z"));
+ QCOMPARE(firstEntry->timeInfo().lastModificationTime().toString(Qt::ISODate), QString("2024-01-14T10:40:00Z"));
+}
+
+void TestCredentialExchange::testCredentialExchangeWriter()
+{
+ const auto firstEntry = new Entry();
+ firstEntry->setUuid(QUuid::createUuid());
+ firstEntry->setUsername("John Doe");
+ firstEntry->setTitle("Title for John Doe");
+ firstEntry->attributes()->set(EntryAttributes::KPEX_PASSKEY_USERNAME, "johndoe");
+ firstEntry->attributes()->set(EntryAttributes::KPEX_PASSKEY_CREDENTIAL_ID, "Y3JlZGVudGlhbElkRXhhbXBsZQ");
+ firstEntry->attributes()->set(EntryAttributes::KPEX_PASSKEY_PRIVATE_KEY_PEM, "MIGHAgEAMBMGByqGS...");
+ firstEntry->attributes()->set(EntryAttributes::KPEX_PASSKEY_RELYING_PARTY, "webauthn.io");
+ firstEntry->attributes()->set(EntryAttributes::KPEX_PASSKEY_USER_HANDLE,
+ "cnEzaNHWcYK3coWZjvoaV1Hj9gnI12mKe2dL2HZVFlY");
+
+ const auto secondEntry = new Entry();
+ secondEntry->setUuid(QUuid::createUuid());
+ secondEntry->setUsername("Jane Doe");
+ secondEntry->setTitle("Title for Jane Doe");
+ secondEntry->attributes()->set(EntryAttributes::KPEX_PASSKEY_USERNAME, "janedoe");
+ secondEntry->attributes()->set(EntryAttributes::KPEX_PASSKEY_CREDENTIAL_ID, "GVuElkRXhhbXBsZdGlhY3JlZb");
+ secondEntry->attributes()->set(EntryAttributes::KPEX_PASSKEY_PRIVATE_KEY_PEM, "XIGHAgEAMBMGByqGS...");
+ secondEntry->attributes()->set(EntryAttributes::KPEX_PASSKEY_RELYING_PARTY, "webauthn.io");
+ secondEntry->attributes()->set(EntryAttributes::KPEX_PASSKEY_USER_HANDLE,
+ "K3coWgnI12mZjvoaV1Hj92HZVFlYKecnEzaNHWcY2dL");
+
+ QList entries;
+ entries << firstEntry << secondEntry;
+
+ CredentialExchangeWriter writer;
+ const auto result = writer.writeEntries(entries);
+ QVERIFY(result["accounts"].toArray().size() == 2);
+}
diff --git a/tests/TestCredentialExchange.h b/tests/TestCredentialExchange.h
new file mode 100644
index 0000000000..af0476a924
--- /dev/null
+++ b/tests/TestCredentialExchange.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2026 KeePassXC Team
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 or (at your option)
+ * version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef KEEPASSXC_TESTCREDENTIALEXCHANGE_H
+#define KEEPASSXC_TESTCREDENTIALEXCHANGE_H
+
+#include
+
+class TestCredentialExchange : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void initTestCase();
+ void testCredentialExchangeReader();
+ void testCredentialExchangeWriter();
+};
+
+#endif // KEEPASSXC_TESTCREDENTIALEXCHANGE_H