Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
}
),
"data" / Prefixed(
Int32ul,
Switch(
this.id,
{'compression_flags': CompressionFlags,
'kdf_parameters': VariantDictionary,
'cipher_id': CipherId
},
default=GreedyBytes
)
)
)
DynamicHeader = DynamicDict(
'id',
RepeatUntil(
lambda item, a, b: item.id == 'end',
DynamicHeaderItem
)
)
# -------------------- Payload Verification --------------------
def compute_payload_block_hash(this):
"""Compute hash of each payload block.
Used to prevent payload corruption and tampering."""
return hmac.new(
hashlib.sha512(
struct.pack('
'protected_stream_key': 0x02,
'binary': 0x03
}
),
"data" / Prefixed(
Int32ul,
Switch(
this.type,
{'protected_stream_id': ProtectedStreamId},
default=GreedyBytes
)
)
)
# another binary header inside decrypted and decompressed Payload
InnerHeader = DynamicDict(
'type',
RepeatUntil(lambda item, a, b: item.type == 'end', InnerHeaderItem),
# FIXME - this is a hack because inner header is not truly a dict,
# it has multiple binary elements.
lump=['binary']
)
UnpackedPayload = Reparsed(
Struct(
"inner_header" / InnerHeader,
"xml" / Unprotect(
this.inner_header.protected_stream_id.data,
this.inner_header.protected_stream_key.data,
XML(GreedyBytes)
)
)
def __init__(self, key, subcon, lump=[]):
super(DynamicDict, self).__init__(subcon)
self.key = key
self.lump = lump
0x05: Int64ul,
0x08: Flag,
0x0C: Int32sl,
0x0D: Int64sl,
0x42: GreedyBytes,
0x18: GreedyString('utf-8')
}
)
),
"next_byte" / Peek(Byte)
)
# new dynamic dictionary structure added in KDBX4
VariantDictionary = Struct(
"version" / Bytes(2),
"dict" / DynamicDict(
'key',
RepeatUntil(
lambda item, a, b: item.next_byte == 0x00,
VariantDictionaryItem
)
),
Padding(1) * "null padding"
)
# -------------------- Dynamic Header --------------------
# https://github.com/dlech/KeePass2.x/blob/dbb9d60095ef39e6abc95d708fb7d03ce5ae865e/KeePassLib/Serialization/KdbxFile.cs#L234-L246
DynamicHeaderItem = Struct(
"id" / Mapping(
Byte,
),
"data" / Prefixed(
Int16ul,
Switch(
this.id,
{'compression_flags': CompressionFlags,
'cipher_id': CipherId,
'transform_rounds': Int32ul,
'protected_stream_id': ProtectedStreamId
},
default=GreedyBytes
)
),
)
DynamicHeader = DynamicDict(
'id',
RepeatUntil(
lambda item, a, b: item.id == 'end',
DynamicHeaderItem
)
)
# -------------------- Payload Verification --------------------
# encrypted payload is split into multiple data blocks with hashes
PayloadBlock = Struct(
"block_index" / Checksum(
Int32ul,
lambda this: this._index,
this
),