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

kdbx3: fix length of transform_rounds field #222

Merged

Conversation

basak
Copy link
Contributor

@basak basak commented Dec 27, 2020

The official KeePass client produces and expects a 64 bit field, not a
32 bit field, for this parameter.

Using the incorrect length happens to parse just fine. The correct
length is encoded into the header so there is no parsing misalignment.
And because the field is little endian, parsing the field itself as a 32
bit field even though it is actually a 64 bit field also works, provided
that the field value fits into 32 bits, which it typically does.

However, if we write header field back out, we write it with a 32 bit
length, and KeePass rejects this. We weren't writing out the header
ourselves previously because kdbx.header.data wasn't being removed (see
#219 (comment)).
However if we start doing that, such as to fix issue #219, then this bug
is revealed.

The fix is trivial: we change the declaration to be a 64 bit field to
match the official client.

The official KeePass client produces and expects a 64 bit field, not a
32 bit field, for this parameter.

Using the incorrect length happens to parse just fine. The correct
length is encoded into the header so there is no parsing misalignment.
And because the field is little endian, parsing the field itself as a 32
bit field even though it is actually a 64 bit field also works, provided
that the field value fits into 32 bits, which it typically does.

However, if we write header field back out, we write it with a 32 bit
length, and KeePass rejects this. We weren't writing out the header
ourselves previously because kdbx.header.data wasn't being removed (see
libkeepass#219 (comment)).
However if we start doing that, such as to fix issue libkeepass#219, then this bug
is revealed.

The fix is trivial: we change the declaration to be a 64 bit field to
match the official client.
@Evidlo
Copy link
Member

Evidlo commented Jan 4, 2021

Thanks for finding this.

pschmitt pushed a commit to pschmitt/pykeepass that referenced this pull request Jan 27, 2021
The official KeePass client produces and expects a 64 bit field, not a
32 bit field, for this parameter.

Using the incorrect length happens to parse just fine. The correct
length is encoded into the header so there is no parsing misalignment.
And because the field is little endian, parsing the field itself as a 32
bit field even though it is actually a 64 bit field also works, provided
that the field value fits into 32 bits, which it typically does.

However, if we write header field back out, we write it with a 32 bit
length, and KeePass rejects this. We weren't writing out the header
ourselves previously because kdbx.header.data wasn't being removed (see
libkeepass#219 (comment)).
However if we start doing that, such as to fix issue libkeepass#219, then this bug
is revealed.

The fix is trivial: we change the declaration to be a 64 bit field to
match the official client.
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.

2 participants