Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement KDBX4 database saving #58

Merged
merged 1 commit into from
Jan 16, 2023
Merged

Implement KDBX4 database saving #58

merged 1 commit into from
Jan 16, 2023

Conversation

louib
Copy link
Collaborator

@louib louib commented Oct 5, 2022

This is a first draft for KDBX4 database saving support. This is still a WIP, but I wanted to open the PR now in order to get early feedback. This PR also includes some refactorings that could be extracted to separate PRs in order to make the code review easier and safer.

Fixes #14

TODO

  • Implement AES encrypt
  • Implement TwoFish encrypt
  • Implement Salsa20 encrypt
  • Implement ChaCha20 encrypt
  • Implement GZip compress
  • Dump binary attachments
  • Implement protected attributes

@varjolintu
Copy link
Collaborator

Nice work!

@2franix
Copy link

2franix commented Dec 27, 2022

Looks promising! I too would be interested in saving databases. Thanks for the addition!

@sseemayer
Copy link
Owner

Since I made quite a mess of the git history in merging all the outstanding PRs, I have made a rebase of your changes onto the current master branch. You can find it at kdbx4-saving.

@louib
Copy link
Collaborator Author

louib commented Dec 30, 2022

@sseemayer don't bother rebasing this PR. My plan is split this PR into smaller patches that are more focused and easier to review. For example, I'm going to create a PR that only extracts the constant values that are going to be used both when reading and writing. I also think that we're going to need to fence the database saving feature behind a feature flag. The reason is that writing a database will result in data loss until we support all the kdbx4 fields.

Since I made quite a mess of the git history in merging all the outstanding PRs

I think we should enable branch protection on the master branch. We have many CI checks that should pass before any commit makes its way to the master branch, I don't see any reason not to leverage those CI jobs for every change to the codebase. What do you think?

@sseemayer
Copy link
Owner

Sounds good! I have added something for the master branch.

@louib louib force-pushed the save_kp4 branch 7 times, most recently from a36e0b6 to a93f271 Compare January 15, 2023 18:03
@louib louib marked this pull request as ready for review January 15, 2023 18:09
@louib
Copy link
Collaborator Author

louib commented Jan 15, 2023

This PR is ready for reviews. The Database::save function is only available from inside the library, using pub(crate). This will give us more time to stabilize the new code and finish the XML parsing and dumping functions. As of right now, using the Database::save function will result in data loss because we do not parse and dump all the XML elements in a database.

I added a bunch of unit tests for many of the ciphers and kdfs combinations, but not all the combinations are covered. After this PR is merged, I will open a PR to switch to matrix testing so that we cover all the combinations. This will also reduce duplicated code in the tests.

Being able to parse and dump databases will be very helpful in the future to add more granular unit tests, because we won't have to rely on "magic" databases, committed to the repo as fixtures. It will still be useful to parse actual databases from other apps as integration tests, but at least that won't be our only option for testing.

I added a bunch of TODOs in the XML parsing functions for all the fields we are not parsing right now. Those fields were seen in a KeePassXC database. I think KeePassXC supports all the fields in the kdbx4 format, but I'm not 100% sure about that.

@droidmonkey I'd like to have your opinion on the default HMAC block size. The block size (along with most of the hmac module) was inspired by the KeePassXC codebase. I'm honestly not sure if that value makes sense.

@DavidVentura I'd like to have your input on this PR, if you get a chance. The feature won't be available yet externally, so it won't be available to implement in pykeepass-rs right now, but I think we're pretty close to having the feature available at least behind a cargo feature flag.

@@ -211,7 +316,7 @@ impl TryFrom<VariantDictionary> for KdfSettings {
}
}

#[derive(Debug)]
#[derive(PartialEq, Debug)]
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PartialEq might not be needed

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in #85

@sseemayer
Copy link
Owner

Thank you for the fantastic work, it looks great!

I like the idea of getting things merged with a visibility of pub(crate) for now until we can do some more cleanups.

@DavidVentura
Copy link
Contributor

Hi!
I don't think I'll be able to review at least this week -- only think I'm able to contribute with is a similar effort I went through before:

Add write support, #1

I'm not sure how helpful it'll be for you, I wasn't really sure what I was doing at that time, but it did seem to work!

@louib louib merged commit 3e8cad4 into sseemayer:master Jan 16, 2023
@louib louib deleted the save_kp4 branch January 16, 2023 00:25
@louib
Copy link
Collaborator Author

louib commented Jan 16, 2023

@DavidVentura Thanks for linking the PR. I had a look at it, and there's a few things in there that I think we could port over here, notably all the Group and Entry fields that you implemented. We'll have to implement all of those and all the remaining Database/Group/Entry fields before making the new Database::save function.

@droidmonkey
Copy link

droidmonkey commented Jan 16, 2023

@droidmonkey I'd like to have your opinion on the default HMAC block size. The block size (along with most of the hmac module) was inspired by the KeePassXC codebase. I'm honestly not sure if that value makes sense.

@louib
I am personally not a fan of the data streams in the KeePassXC codebase, they are from KeePassX era. The block size is not relevant because it is embedded as part of the stream (HASH + BLOCKSIZE + DATA) so when you read the block it reads the size that was actually stored. So... the block size is really just for chunking the data out for efficient reads, 1 MiB seems reasonable to me 😄

@louib
Copy link
Collaborator Author

louib commented Jan 29, 2023

@droidmonkey thanks for the review! Let's go with that default for now then.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Feature to encrypt a Keepass database
6 participants