Skip to content

Commit ab73441

Browse files
committed
kdbx3: fix length of transform_rounds field
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.
1 parent 8a41d9b commit ab73441

File tree

1 file changed

+3
-3
lines changed

1 file changed

+3
-3
lines changed

pykeepass/kdbx_parsing/kdbx3.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33

44
import hashlib
55
from construct import (
6-
Byte, Bytes, Int16ul, Int32ul, RepeatUntil, GreedyBytes, Struct, this,
7-
Mapping, Switch, Prefixed, Padding, Checksum, Computed, IfThenElse,
6+
Byte, Bytes, Int16ul, Int32ul, Int64ul, RepeatUntil, GreedyBytes, Struct,
7+
this, Mapping, Switch, Prefixed, Padding, Checksum, Computed, IfThenElse,
88
Pointer, Tell, len_
99
)
1010
from .common import (
@@ -66,7 +66,7 @@ def compute_transformed(context):
6666
this.id,
6767
{'compression_flags': CompressionFlags,
6868
'cipher_id': CipherId,
69-
'transform_rounds': Int32ul,
69+
'transform_rounds': Int64ul,
7070
'protected_stream_id': ProtectedStreamId
7171
},
7272
default=GreedyBytes

0 commit comments

Comments
 (0)