Skip to content

Commit

Permalink
Add parsing of authentication factor headers
Browse files Browse the repository at this point in the history
This adds the ability to parse and validate (but not use) authentication factor
information contained within the KDBX outer header.

Use authentication factor headers if present for opening database

Saving the database will still discard the header information, but read-only
access works.
  • Loading branch information
BryanJacobs authored and droidmonkey committed Dec 1, 2024
1 parent 9a63e80 commit 8a39859
Show file tree
Hide file tree
Showing 35 changed files with 1,834 additions and 32 deletions.
210 changes: 179 additions & 31 deletions share/translations/keepassxc_en.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="en_US">
<context>
<name>AESCBCFactorKeyDerivation</name>
<message>
<source>Performing AES-CBC decryption on wrapped key</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>AboutDialog</name>
<message>
Expand Down Expand Up @@ -635,6 +642,13 @@
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>AuthenticationFactor</name>
<message>
<source>Validation failed when unwrapping factor &apos;%1&apos;: %2</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>AutoType</name>
<message>
Expand Down Expand Up @@ -4908,6 +4922,14 @@ If this reoccurs, then your database file may be corrupt.</source>
<extracomment>Translation: variant map = data structure for storing meta data</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>Parsing authentication factors</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Parsed authentication factors, got %1 group</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>Kdbx4Writer</name>
Expand Down Expand Up @@ -4996,6 +5018,109 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>KdbxXmlAuthenticationFactorReader</name>
<message>
<source>Read authentication factor XML: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>XML parsing failure on authentication factors: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Failed to parse authentication factor info</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Read authentication factor compat version: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Incompatible authentication factor version</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Secondary authentication factors are comprehensive</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Comprehensive set to unknown value %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unknown element type while processing authentication factor info: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unable to decode validation input for authentication factor</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unable to decode validation output for authentication factor</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unknown authentication validation type %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unable to decode challenge for authentication factor</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unknown element type while processing authentication factor group: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Authentication factor group is empty!</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>An authentication factor group contains only unsupported factors</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Factor is a SHA256-hashed password</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Factor is a FIDO credential with type ES256</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unrecognized factor UUID %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unrecognized factor key type %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unable to decode key salt for authentication factor</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unable to decode wrapped key for authentication factor</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Encountered a CredentialID element on factor of non-FIDO type %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unable to decode FIDO credential ID for authentication factor</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unknown element type while processing generic authentication factor: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Factor %1 is missing required fields</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>KdbxXmlReader</name>
<message>
Expand Down Expand Up @@ -6700,6 +6825,13 @@ The following data is missing:
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>PasswordAuthenticationFactor</name>
<message>
<source>Falling back to default user password for factor &apos;%1&apos;</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>PasswordEditWidget</name>
<message>
Expand Down Expand Up @@ -8908,6 +9040,22 @@ This option is deprecated, use --set-key-file instead.</source>
<source>Failed to decrypt key data.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Factor &apos;%1&apos; did not contribute key material</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Got a key part from factor &apos;%1&apos;</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Attempting to add key material from extra authentication factors</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unable to get keying material from an authentication factor group</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Origin is empty or not allowed</source>
<translation type="unfinished"></translation>
Expand All @@ -8928,6 +9076,10 @@ This option is deprecated, use --set-key-file instead.</source>
<source>Wait for timer to expire</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unknown passkeys error</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Challenge is shorter than required minimum length</source>
<translation type="unfinished"></translation>
Expand All @@ -8936,6 +9088,10 @@ This option is deprecated, use --set-key-file instead.</source>
<source>user.id does not match the required length</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Cannot generate valid passphrases because the wordlist is too short</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Favorite</source>
<comment>Tag for favorite entries</comment>
Expand All @@ -8957,6 +9113,18 @@ This option is deprecated, use --set-key-file instead.</source>
<source>Failed to decrypt json file: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unsupported format, ensure your Bitwarden export is password-protected</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Invalid KDF iterations, cannot decrypt json file</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Only PBKDF and Argon2 are supported, cannot decrypt json file</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Invalid encKeyValidation field</source>
<translation type="unfinished"></translation>
Expand Down Expand Up @@ -9007,31 +9175,30 @@ This option is deprecated, use --set-key-file instead.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Enter Shortcut</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Action</source>
<source>Delete plugin data?</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Shortcuts</source>
<translation type="unfinished"></translation>
<message numerus="yes">
<source>Delete plugin data from Entry(s)?</source>
<translation type="unfinished">
<numerusform></numerusform>
<numerusform></numerusform>
</translation>
</message>
<message>
<source>Unknown passkeys error</source>
<source>Enter Shortcut</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Invalid KDF iterations, cannot decrypt json file</source>
<source>Action</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unsupported format, ensure your Bitwarden export is password-protected</source>
<source>Shortcuts</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Only PBKDF and Argon2 are supported, cannot decrypt json file</source>
<source>Passkey</source>
<translation type="unfinished"></translation>
</message>
<message>
Expand All @@ -9054,25 +9221,6 @@ This option is deprecated, use --set-key-file instead.</source>
<source>Shortcut %1 conflicts with &apos;%2&apos;. Overwrite shortcut?</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Cannot generate valid passphrases because the wordlist is too short</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Delete plugin data?</source>
<translation type="unfinished"></translation>
</message>
<message numerus="yes">
<source>Delete plugin data from Entry(s)?</source>
<translation type="unfinished">
<numerusform></numerusform>
<numerusform></numerusform>
</translation>
</message>
<message>
<source>Passkey</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>QtIOCompressor</name>
Expand Down
10 changes: 10 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ endif()

set(core_SOURCES
core/Alloc.cpp
core/AuthenticationFactorUserData.cpp
core/AutoTypeAssociations.cpp
core/Base32.cpp
core/Bootstrap.cpp
Expand Down Expand Up @@ -68,6 +69,13 @@ set(core_SOURCES
crypto/kdf/Kdf.cpp
crypto/kdf/AesKdf.cpp
crypto/kdf/Argon2Kdf.cpp
format/multifactor/AESCBCFactorKeyDerivation.cpp
format/multifactor/AuthenticationFactor.cpp
format/multifactor/AuthenticationFactorGroup.cpp
format/multifactor/AuthenticationFactorInfo.cpp
format/multifactor/FactorKeyDerivation.cpp
format/multifactor/FidoAuthenticationFactor.cpp
format/multifactor/PasswordAuthenticationFactor.cpp
format/BitwardenReader.cpp
format/CsvExporter.cpp
format/CsvParser.cpp
Expand All @@ -77,6 +85,7 @@ set(core_SOURCES
format/KdbxReader.cpp
format/KdbxWriter.cpp
format/KdbxXmlReader.cpp
format/KdbxXmlAuthenticationFactorReader.cpp
format/KeePass2Reader.cpp
format/KeePass2Writer.cpp
format/Kdbx3Reader.cpp
Expand All @@ -94,6 +103,7 @@ set(core_SOURCES
keys/FileKey.cpp
keys/PasswordKey.cpp
keys/ChallengeResponseKey.cpp
keys/MultiAuthenticationHeaderKey.cpp
streams/HashedBlockStream.cpp
streams/HmacBlockStream.cpp
streams/LayeredStream.cpp
Expand Down
34 changes: 34 additions & 0 deletions src/core/AuthenticationFactorUserData.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright (C) 2024 KeePassXC Team <[email protected]>
*
* 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 <http://www.gnu.org/licenses/>.
*/

#include "AuthenticationFactorUserData.h"

void AuthenticationFactorUserData::addDataItem(const QString& key, const QSharedPointer<QByteArray>& value)
{
m_data.insert(key, value);
}

QSharedPointer<QByteArray> AuthenticationFactorUserData::getDataItem(const QString& key) const
{
const auto& v = m_data.find(key);

if (v == m_data.end()) {
return {nullptr};
}

return *v;
}
Loading

0 comments on commit 8a39859

Please sign in to comment.