Skip to content

Commit

Permalink
kdbx3: fix length of transform_rounds field
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
basak committed Dec 27, 2020
1 parent 8a41d9b commit ab73441
Showing 1 changed file with 3 additions and 3 deletions.
6 changes: 3 additions & 3 deletions pykeepass/kdbx_parsing/kdbx3.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@

import hashlib
from construct import (
Byte, Bytes, Int16ul, Int32ul, RepeatUntil, GreedyBytes, Struct, this,
Mapping, Switch, Prefixed, Padding, Checksum, Computed, IfThenElse,
Byte, Bytes, Int16ul, Int32ul, Int64ul, RepeatUntil, GreedyBytes, Struct,
this, Mapping, Switch, Prefixed, Padding, Checksum, Computed, IfThenElse,
Pointer, Tell, len_
)
from .common import (
Expand Down Expand Up @@ -66,7 +66,7 @@ def compute_transformed(context):
this.id,
{'compression_flags': CompressionFlags,
'cipher_id': CipherId,
'transform_rounds': Int32ul,
'transform_rounds': Int64ul,
'protected_stream_id': ProtectedStreamId
},
default=GreedyBytes
Expand Down

0 comments on commit ab73441

Please sign in to comment.