The key and AAD prefix needed to decrypt a single file.
Wire format is a version byte followed by an Avro datum of KEY_METADATA_SCHEMA_V1,
byte-compatible with Java's StandardKeyMetadata.
Source code in pyiceberg/encryption/key_metadata.py
| @dataclass(frozen=True)
class StandardKeyMetadata:
"""The key and AAD prefix needed to decrypt a single file.
Wire format is a version byte followed by an Avro datum of `KEY_METADATA_SCHEMA_V1`,
byte-compatible with Java's `StandardKeyMetadata`.
"""
encryption_key: bytes = field(repr=False)
aad_prefix: bytes | None = None
file_length: int | None = None
def __post_init__(self) -> None:
"""Reject invalid key lengths here rather than only on decode, so an invalid instance cannot exist."""
if len(self.encryption_key) not in AES_KEY_LENGTHS:
raise ValueError(
f"Invalid encryption key in key metadata: expected one of {AES_KEY_LENGTHS} bytes, got {len(self.encryption_key)}"
)
@classmethod
def from_bytes(cls, data: bytes) -> StandardKeyMetadata:
"""Decode key metadata from its wire format."""
if not data:
raise ValueError("Empty key metadata")
if (version := data[0]) != KEY_METADATA_V1:
raise ValueError(f"Unsupported key metadata version: {version}")
record = construct_reader(KEY_METADATA_SCHEMA_V1).read(new_decoder(data[1:]))
return cls(encryption_key=record[0], aad_prefix=record[1], file_length=record[2])
def to_bytes(self) -> bytes:
"""Encode key metadata to its wire format."""
output = io.BytesIO()
encoder = BinaryEncoder(output)
encoder.write(bytes([KEY_METADATA_V1]))
record = Record(self.encryption_key, self.aad_prefix, self.file_length)
construct_writer(KEY_METADATA_SCHEMA_V1).write(encoder, record)
return output.getvalue()
|
__post_init__()
Reject invalid key lengths here rather than only on decode, so an invalid instance cannot exist.
Source code in pyiceberg/encryption/key_metadata.py
| def __post_init__(self) -> None:
"""Reject invalid key lengths here rather than only on decode, so an invalid instance cannot exist."""
if len(self.encryption_key) not in AES_KEY_LENGTHS:
raise ValueError(
f"Invalid encryption key in key metadata: expected one of {AES_KEY_LENGTHS} bytes, got {len(self.encryption_key)}"
)
|
Decode key metadata from its wire format.
Source code in pyiceberg/encryption/key_metadata.py
| @classmethod
def from_bytes(cls, data: bytes) -> StandardKeyMetadata:
"""Decode key metadata from its wire format."""
if not data:
raise ValueError("Empty key metadata")
if (version := data[0]) != KEY_METADATA_V1:
raise ValueError(f"Unsupported key metadata version: {version}")
record = construct_reader(KEY_METADATA_SCHEMA_V1).read(new_decoder(data[1:]))
return cls(encryption_key=record[0], aad_prefix=record[1], file_length=record[2])
|
Encode key metadata to its wire format.
Source code in pyiceberg/encryption/key_metadata.py
| def to_bytes(self) -> bytes:
"""Encode key metadata to its wire format."""
output = io.BytesIO()
encoder = BinaryEncoder(output)
encoder.write(bytes([KEY_METADATA_V1]))
record = Record(self.encryption_key, self.aad_prefix, self.file_length)
construct_writer(KEY_METADATA_SCHEMA_V1).write(encoder, record)
return output.getvalue()
|