otdf-python 0.4.0__py3-none-any.whl → 0.4.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. otdf_python/__init__.py +1 -2
  2. otdf_python/__main__.py +1 -2
  3. otdf_python/address_normalizer.py +8 -10
  4. otdf_python/aesgcm.py +8 -0
  5. otdf_python/assertion_config.py +21 -0
  6. otdf_python/asym_crypto.py +18 -22
  7. otdf_python/auth_headers.py +7 -6
  8. otdf_python/autoconfigure_utils.py +21 -7
  9. otdf_python/cli.py +5 -5
  10. otdf_python/collection_store.py +13 -1
  11. otdf_python/collection_store_impl.py +5 -0
  12. otdf_python/config.py +13 -0
  13. otdf_python/connect_client.py +1 -0
  14. otdf_python/constants.py +2 -0
  15. otdf_python/crypto_utils.py +4 -0
  16. otdf_python/dpop.py +3 -5
  17. otdf_python/ecc_constants.py +12 -14
  18. otdf_python/ecc_mode.py +7 -2
  19. otdf_python/ecdh.py +24 -31
  20. otdf_python/eckeypair.py +5 -0
  21. otdf_python/header.py +5 -0
  22. otdf_python/invalid_zip_exception.py +6 -2
  23. otdf_python/kas_client.py +66 -55
  24. otdf_python/kas_connect_rpc_client.py +75 -38
  25. otdf_python/kas_info.py +4 -3
  26. otdf_python/kas_key_cache.py +10 -9
  27. otdf_python/key_type.py +4 -0
  28. otdf_python/key_type_constants.py +4 -11
  29. otdf_python/manifest.py +24 -0
  30. otdf_python/nanotdf.py +30 -28
  31. otdf_python/nanotdf_ecdsa_struct.py +5 -11
  32. otdf_python/nanotdf_type.py +13 -1
  33. otdf_python/policy_binding_serializer.py +6 -4
  34. otdf_python/policy_info.py +6 -0
  35. otdf_python/policy_object.py +8 -0
  36. otdf_python/policy_stub.py +2 -0
  37. otdf_python/resource_locator.py +22 -13
  38. otdf_python/sdk.py +51 -73
  39. otdf_python/sdk_builder.py +60 -47
  40. otdf_python/sdk_exceptions.py +11 -1
  41. otdf_python/symmetric_and_payload_config.py +6 -0
  42. otdf_python/tdf.py +47 -10
  43. otdf_python/tdf_reader.py +10 -13
  44. otdf_python/tdf_writer.py +5 -0
  45. otdf_python/token_source.py +4 -3
  46. otdf_python/version.py +5 -0
  47. otdf_python/zip_reader.py +10 -2
  48. otdf_python/zip_writer.py +11 -0
  49. {otdf_python-0.4.0.dist-info → otdf_python-0.4.2.dist-info}/METADATA +3 -2
  50. {otdf_python-0.4.0.dist-info → otdf_python-0.4.2.dist-info}/RECORD +81 -72
  51. {otdf_python-0.4.0.dist-info → otdf_python-0.4.2.dist-info}/WHEEL +1 -1
  52. otdf_python_proto/__init__.py +2 -6
  53. otdf_python_proto/authorization/__init__.py +10 -0
  54. otdf_python_proto/authorization/authorization_connect.py +250 -0
  55. otdf_python_proto/authorization/v2/authorization_connect.py +315 -0
  56. otdf_python_proto/entityresolution/__init__.py +10 -0
  57. otdf_python_proto/entityresolution/entity_resolution_connect.py +185 -0
  58. otdf_python_proto/entityresolution/v2/entity_resolution_connect.py +185 -0
  59. otdf_python_proto/kas/__init__.py +2 -2
  60. otdf_python_proto/kas/kas_connect.py +259 -0
  61. otdf_python_proto/policy/actions/__init__.py +11 -0
  62. otdf_python_proto/policy/actions/actions_connect.py +380 -0
  63. otdf_python_proto/policy/attributes/__init__.py +11 -0
  64. otdf_python_proto/policy/attributes/attributes_connect.py +1310 -0
  65. otdf_python_proto/policy/kasregistry/__init__.py +11 -0
  66. otdf_python_proto/policy/kasregistry/key_access_server_registry_connect.py +912 -0
  67. otdf_python_proto/policy/keymanagement/__init__.py +11 -0
  68. otdf_python_proto/policy/keymanagement/key_management_connect.py +380 -0
  69. otdf_python_proto/policy/namespaces/__init__.py +11 -0
  70. otdf_python_proto/policy/namespaces/namespaces_connect.py +648 -0
  71. otdf_python_proto/policy/registeredresources/__init__.py +11 -0
  72. otdf_python_proto/policy/registeredresources/registered_resources_connect.py +770 -0
  73. otdf_python_proto/policy/resourcemapping/__init__.py +11 -0
  74. otdf_python_proto/policy/resourcemapping/resource_mapping_connect.py +790 -0
  75. otdf_python_proto/policy/subjectmapping/__init__.py +11 -0
  76. otdf_python_proto/policy/subjectmapping/subject_mapping_connect.py +851 -0
  77. otdf_python_proto/policy/unsafe/__init__.py +11 -0
  78. otdf_python_proto/policy/unsafe/unsafe_connect.py +705 -0
  79. otdf_python_proto/wellknownconfiguration/__init__.py +10 -0
  80. otdf_python_proto/wellknownconfiguration/wellknown_configuration_connect.py +124 -0
  81. otdf_python_proto/authorization/authorization_pb2_connect.py +0 -191
  82. otdf_python_proto/authorization/v2/authorization_pb2_connect.py +0 -233
  83. otdf_python_proto/entityresolution/entity_resolution_pb2_connect.py +0 -149
  84. otdf_python_proto/entityresolution/v2/entity_resolution_pb2_connect.py +0 -149
  85. otdf_python_proto/kas/kas_pb2_connect.py +0 -192
  86. otdf_python_proto/policy/actions/actions_pb2_connect.py +0 -275
  87. otdf_python_proto/policy/attributes/attributes_pb2_connect.py +0 -863
  88. otdf_python_proto/policy/kasregistry/key_access_server_registry_pb2_connect.py +0 -611
  89. otdf_python_proto/policy/keymanagement/key_management_pb2_connect.py +0 -275
  90. otdf_python_proto/policy/namespaces/namespaces_pb2_connect.py +0 -443
  91. otdf_python_proto/policy/registeredresources/registered_resources_pb2_connect.py +0 -527
  92. otdf_python_proto/policy/resourcemapping/resource_mapping_pb2_connect.py +0 -527
  93. otdf_python_proto/policy/subjectmapping/subject_mapping_pb2_connect.py +0 -569
  94. otdf_python_proto/policy/unsafe/unsafe_pb2_connect.py +0 -485
  95. otdf_python_proto/wellknownconfiguration/wellknown_configuration_pb2_connect.py +0 -107
  96. {otdf_python-0.4.0.dist-info → otdf_python-0.4.2.dist-info}/licenses/LICENSE +0 -0
@@ -1,5 +1,4 @@
1
- """
2
- Elliptic Curve Constants for NanoTDF.
1
+ """Elliptic Curve Constants for NanoTDF.
3
2
 
4
3
  This module defines shared constants for elliptic curve operations used across
5
4
  the SDK, particularly for NanoTDF encryption/decryption.
@@ -14,8 +13,7 @@ from cryptography.hazmat.primitives.asymmetric import ec
14
13
 
15
14
 
16
15
  class ECCConstants:
17
- """
18
- Centralized constants for elliptic curve cryptography operations.
16
+ """Centralized constants for elliptic curve cryptography operations.
19
17
 
20
18
  This class provides mappings between curve names, curve type integers,
21
19
  cryptography curve objects, and compressed public key sizes.
@@ -67,8 +65,7 @@ class ECCConstants:
67
65
 
68
66
  @classmethod
69
67
  def get_curve_name(cls, curve_type: int) -> str:
70
- """
71
- Get curve name from curve type integer.
68
+ """Get curve name from curve type integer.
72
69
 
73
70
  Args:
74
71
  curve_type: Curve type (0=secp256r1, 1=secp384r1, 2=secp521r1, 3=secp256k1)
@@ -78,6 +75,7 @@ class ECCConstants:
78
75
 
79
76
  Raises:
80
77
  ValueError: If curve_type is not supported
78
+
81
79
  """
82
80
  name = cls.CURVE_TYPE_TO_NAME.get(curve_type)
83
81
  if name is None:
@@ -89,8 +87,7 @@ class ECCConstants:
89
87
 
90
88
  @classmethod
91
89
  def get_curve_type(cls, curve_name: str) -> int:
92
- """
93
- Get curve type integer from curve name.
90
+ """Get curve type integer from curve name.
94
91
 
95
92
  Args:
96
93
  curve_name: Curve name (e.g., "secp256r1")
@@ -100,6 +97,7 @@ class ECCConstants:
100
97
 
101
98
  Raises:
102
99
  ValueError: If curve_name is not supported
100
+
103
101
  """
104
102
  curve_type = cls.CURVE_NAME_TO_TYPE.get(curve_name.lower())
105
103
  if curve_type is None:
@@ -111,8 +109,7 @@ class ECCConstants:
111
109
 
112
110
  @classmethod
113
111
  def get_compressed_key_size_by_type(cls, curve_type: int) -> int:
114
- """
115
- Get compressed public key size from curve type integer.
112
+ """Get compressed public key size from curve type integer.
116
113
 
117
114
  Args:
118
115
  curve_type: Curve type (0=secp256r1, 1=secp384r1, 2=secp521r1, 3=secp256k1)
@@ -122,6 +119,7 @@ class ECCConstants:
122
119
 
123
120
  Raises:
124
121
  ValueError: If curve_type is not supported
122
+
125
123
  """
126
124
  size = cls.COMPRESSED_KEY_SIZE_BY_TYPE.get(curve_type)
127
125
  if size is None:
@@ -133,8 +131,7 @@ class ECCConstants:
133
131
 
134
132
  @classmethod
135
133
  def get_compressed_key_size_by_name(cls, curve_name: str) -> int:
136
- """
137
- Get compressed public key size from curve name.
134
+ """Get compressed public key size from curve name.
138
135
 
139
136
  Args:
140
137
  curve_name: Curve name (e.g., "secp256r1")
@@ -144,6 +141,7 @@ class ECCConstants:
144
141
 
145
142
  Raises:
146
143
  ValueError: If curve_name is not supported
144
+
147
145
  """
148
146
  size = cls.COMPRESSED_KEY_SIZE_BY_NAME.get(curve_name.lower())
149
147
  if size is None:
@@ -155,8 +153,7 @@ class ECCConstants:
155
153
 
156
154
  @classmethod
157
155
  def get_curve_object(cls, curve_name: str) -> ec.EllipticCurve:
158
- """
159
- Get cryptography library curve object from curve name.
156
+ """Get cryptography library curve object from curve name.
160
157
 
161
158
  Args:
162
159
  curve_name: Curve name (e.g., "secp256r1")
@@ -166,6 +163,7 @@ class ECCConstants:
166
163
 
167
164
  Raises:
168
165
  ValueError: If curve_name is not supported
166
+
169
167
  """
170
168
  curve = cls.CURVE_OBJECTS.get(curve_name.lower())
171
169
  if curve is None:
otdf_python/ecc_mode.py CHANGED
@@ -1,9 +1,10 @@
1
+ """Elliptic Curve Cryptography mode enumeration."""
2
+
1
3
  from otdf_python.ecc_constants import ECCConstants
2
4
 
3
5
 
4
6
  class ECCMode:
5
- """
6
- ECC (Elliptic Curve Cryptography) mode configuration for NanoTDF.
7
+ """ECC (Elliptic Curve Cryptography) mode configuration for NanoTDF.
7
8
 
8
9
  This class encapsulates the curve type and policy binding mode (GMAC vs ECDSA)
9
10
  that are encoded in the NanoTDF header. It delegates to ECCConstants for
@@ -11,6 +12,7 @@ class ECCMode:
11
12
  """
12
13
 
13
14
  def __init__(self, curve_mode: int = 0, use_ecdsa_binding: bool = False):
15
+ """Initialize ECC mode."""
14
16
  self.curve_mode = curve_mode
15
17
  self.use_ecdsa_binding = use_ecdsa_binding
16
18
 
@@ -34,6 +36,7 @@ class ECCMode:
34
36
 
35
37
  Raises:
36
38
  ValueError: If curve_mode is not supported
39
+
37
40
  """
38
41
  # Delegate to ECCConstants for the authoritative mapping
39
42
  return ECCConstants.get_curve_name(self.curve_mode)
@@ -50,6 +53,7 @@ class ECCMode:
50
53
 
51
54
  Raises:
52
55
  ValueError: If curve_type is not supported
56
+
53
57
  """
54
58
  # Delegate to ECCConstants for the authoritative mapping
55
59
  return ECCConstants.get_compressed_key_size_by_type(curve_type)
@@ -71,6 +75,7 @@ class ECCMode:
71
75
 
72
76
  Raises:
73
77
  ValueError: If curve_str is not a supported curve or binding type
78
+
74
79
  """
75
80
  # Handle policy binding types (always use secp256r1 as default curve)
76
81
  if curve_str.lower() == "gmac":
otdf_python/ecdh.py CHANGED
@@ -1,5 +1,4 @@
1
- """
2
- ECDH (Elliptic Curve Diffie-Hellman) key exchange for NanoTDF.
1
+ """ECDH (Elliptic Curve Diffie-Hellman) key exchange for NanoTDF.
3
2
 
4
3
  This module implements the ECDH key exchange protocol with HKDF key derivation
5
4
  as specified in the NanoTDF spec. It supports the following curves:
@@ -36,24 +35,17 @@ NANOTDF_HKDF_SALT = bytes.fromhex(
36
35
  class ECDHError(Exception):
37
36
  """Base exception for ECDH operations."""
38
37
 
39
- pass
40
-
41
38
 
42
39
  class UnsupportedCurveError(ECDHError):
43
40
  """Raised when an unsupported curve is specified."""
44
41
 
45
- pass
46
-
47
42
 
48
43
  class InvalidKeyError(ECDHError):
49
44
  """Raised when a key is invalid or malformed."""
50
45
 
51
- pass
52
-
53
46
 
54
47
  def get_curve(curve_name: str) -> ec.EllipticCurve:
55
- """
56
- Get the cryptography curve object for a given curve name.
48
+ """Get the cryptography curve object for a given curve name.
57
49
 
58
50
  Args:
59
51
  curve_name: Name of the curve (e.g., "secp256r1")
@@ -63,6 +55,7 @@ def get_curve(curve_name: str) -> ec.EllipticCurve:
63
55
 
64
56
  Raises:
65
57
  UnsupportedCurveError: If the curve is not supported
58
+
66
59
  """
67
60
  try:
68
61
  # Delegate to ECCConstants for the authoritative mapping
@@ -72,8 +65,7 @@ def get_curve(curve_name: str) -> ec.EllipticCurve:
72
65
 
73
66
 
74
67
  def get_compressed_key_size(curve_name: str) -> int:
75
- """
76
- Get the size of a compressed public key for a given curve.
68
+ """Get the size of a compressed public key for a given curve.
77
69
 
78
70
  Args:
79
71
  curve_name: Name of the curve (e.g., "secp256r1")
@@ -83,6 +75,7 @@ def get_compressed_key_size(curve_name: str) -> int:
83
75
 
84
76
  Raises:
85
77
  UnsupportedCurveError: If the curve is not supported
78
+
86
79
  """
87
80
  try:
88
81
  # Delegate to ECCConstants for the authoritative mapping
@@ -94,8 +87,7 @@ def get_compressed_key_size(curve_name: str) -> int:
94
87
  def generate_ephemeral_keypair(
95
88
  curve_name: str,
96
89
  ) -> tuple[ec.EllipticCurvePrivateKey, ec.EllipticCurvePublicKey]:
97
- """
98
- Generate an ephemeral keypair for ECDH.
90
+ """Generate an ephemeral keypair for ECDH.
99
91
 
100
92
  Args:
101
93
  curve_name: Name of the curve (e.g., "secp256r1")
@@ -105,6 +97,7 @@ def generate_ephemeral_keypair(
105
97
 
106
98
  Raises:
107
99
  UnsupportedCurveError: If the curve is not supported
100
+
108
101
  """
109
102
  curve = get_curve(curve_name)
110
103
  private_key = ec.generate_private_key(curve, default_backend())
@@ -113,14 +106,14 @@ def generate_ephemeral_keypair(
113
106
 
114
107
 
115
108
  def compress_public_key(public_key: ec.EllipticCurvePublicKey) -> bytes:
116
- """
117
- Compress an EC public key to compressed point format.
109
+ """Compress an EC public key to compressed point format.
118
110
 
119
111
  Args:
120
112
  public_key: The EC public key to compress
121
113
 
122
114
  Returns:
123
115
  bytes: Compressed public key (33-67 bytes depending on curve)
116
+
124
117
  """
125
118
  return public_key.public_bytes(
126
119
  encoding=Encoding.X962, format=PublicFormat.CompressedPoint
@@ -130,8 +123,7 @@ def compress_public_key(public_key: ec.EllipticCurvePublicKey) -> bytes:
130
123
  def decompress_public_key(
131
124
  compressed_key: bytes, curve_name: str
132
125
  ) -> ec.EllipticCurvePublicKey:
133
- """
134
- Decompress a public key from compressed point format.
126
+ """Decompress a public key from compressed point format.
135
127
 
136
128
  Args:
137
129
  compressed_key: The compressed public key bytes
@@ -143,6 +135,7 @@ def decompress_public_key(
143
135
  Raises:
144
136
  InvalidKeyError: If the key cannot be decompressed
145
137
  UnsupportedCurveError: If the curve is not supported
138
+
146
139
  """
147
140
  try:
148
141
  curve = get_curve(curve_name)
@@ -156,14 +149,13 @@ def decompress_public_key(
156
149
 
157
150
  return ec.EllipticCurvePublicKey.from_encoded_point(curve, compressed_key)
158
151
  except (ValueError, TypeError) as e:
159
- raise InvalidKeyError(f"Failed to decompress public key: {e}")
152
+ raise InvalidKeyError(f"Failed to decompress public key: {e}") from e
160
153
 
161
154
 
162
155
  def derive_shared_secret(
163
156
  private_key: ec.EllipticCurvePrivateKey, public_key: ec.EllipticCurvePublicKey
164
157
  ) -> bytes:
165
- """
166
- Derive a shared secret using ECDH.
158
+ """Derive a shared secret using ECDH.
167
159
 
168
160
  Args:
169
161
  private_key: The private key (can be ephemeral or recipient's key)
@@ -174,12 +166,13 @@ def derive_shared_secret(
174
166
 
175
167
  Raises:
176
168
  ECDHError: If ECDH fails
169
+
177
170
  """
178
171
  try:
179
172
  shared_secret = private_key.exchange(ec.ECDH(), public_key)
180
173
  return shared_secret
181
174
  except Exception as e:
182
- raise ECDHError(f"Failed to derive shared secret: {e}")
175
+ raise ECDHError(f"Failed to derive shared secret: {e}") from e
183
176
 
184
177
 
185
178
  def derive_key_from_shared_secret(
@@ -188,8 +181,7 @@ def derive_key_from_shared_secret(
188
181
  salt: bytes | None = None,
189
182
  info: bytes = b"",
190
183
  ) -> bytes:
191
- """
192
- Derive a symmetric encryption key from the ECDH shared secret using HKDF.
184
+ """Derive a symmetric encryption key from the ECDH shared secret using HKDF.
193
185
 
194
186
  Args:
195
187
  shared_secret: The raw ECDH shared secret
@@ -202,6 +194,7 @@ def derive_key_from_shared_secret(
202
194
 
203
195
  Raises:
204
196
  ECDHError: If key derivation fails
197
+
205
198
  """
206
199
  if salt is None:
207
200
  salt = NANOTDF_HKDF_SALT
@@ -216,14 +209,13 @@ def derive_key_from_shared_secret(
216
209
  )
217
210
  return hkdf.derive(shared_secret)
218
211
  except Exception as e:
219
- raise ECDHError(f"Failed to derive key from shared secret: {e}")
212
+ raise ECDHError(f"Failed to derive key from shared secret: {e}") from e
220
213
 
221
214
 
222
215
  def encrypt_key_with_ecdh(
223
216
  recipient_public_key_pem: str, curve_name: str = "secp256r1"
224
217
  ) -> tuple[bytes, bytes]:
225
- """
226
- High-level function: Generate ephemeral keypair and derive encryption key.
218
+ """High-level function: Generate ephemeral keypair and derive encryption key.
227
219
 
228
220
  This is used during NanoTDF encryption to derive the key that will be used
229
221
  to encrypt the payload. The ephemeral public key must be stored in the
@@ -242,6 +234,7 @@ def encrypt_key_with_ecdh(
242
234
  ECDHError: If key derivation fails
243
235
  InvalidKeyError: If recipient's public key is invalid
244
236
  UnsupportedCurveError: If the curve is not supported
237
+
245
238
  """
246
239
  # Load recipient's public key
247
240
  try:
@@ -251,7 +244,7 @@ def encrypt_key_with_ecdh(
251
244
  if not isinstance(recipient_public_key, ec.EllipticCurvePublicKey):
252
245
  raise InvalidKeyError("Recipient's public key is not an EC key")
253
246
  except Exception as e:
254
- raise InvalidKeyError(f"Failed to load recipient's public key: {e}")
247
+ raise InvalidKeyError(f"Failed to load recipient's public key: {e}") from e
255
248
 
256
249
  # Generate ephemeral keypair
257
250
  ephemeral_private_key, ephemeral_public_key = generate_ephemeral_keypair(curve_name)
@@ -273,8 +266,7 @@ def decrypt_key_with_ecdh(
273
266
  compressed_ephemeral_public_key: bytes,
274
267
  curve_name: str = "secp256r1",
275
268
  ) -> bytes:
276
- """
277
- High-level function: Derive decryption key from ephemeral public key and recipient's private key.
269
+ """High-level function: Derive decryption key from ephemeral public key and recipient's private key.
278
270
 
279
271
  This is used during NanoTDF decryption to derive the same key that was used
280
272
  to encrypt the payload. The ephemeral public key is extracted from the
@@ -292,6 +284,7 @@ def decrypt_key_with_ecdh(
292
284
  ECDHError: If key derivation fails
293
285
  InvalidKeyError: If keys are invalid
294
286
  UnsupportedCurveError: If the curve is not supported
287
+
295
288
  """
296
289
  # Load recipient's private key
297
290
  try:
@@ -301,7 +294,7 @@ def decrypt_key_with_ecdh(
301
294
  if not isinstance(recipient_private_key, ec.EllipticCurvePrivateKey):
302
295
  raise InvalidKeyError("Recipient's private key is not an EC key")
303
296
  except Exception as e:
304
- raise InvalidKeyError(f"Failed to load recipient's private key: {e}")
297
+ raise InvalidKeyError(f"Failed to load recipient's private key: {e}") from e
305
298
 
306
299
  # Decompress ephemeral public key
307
300
  ephemeral_public_key = decompress_public_key(
otdf_python/eckeypair.py CHANGED
@@ -1,3 +1,5 @@
1
+ """Elliptic Curve key pair management."""
2
+
1
3
  from cryptography.exceptions import InvalidSignature
2
4
  from cryptography.hazmat.backends import default_backend
3
5
  from cryptography.hazmat.primitives import hashes, serialization
@@ -12,7 +14,10 @@ from cryptography.hazmat.primitives.serialization import (
12
14
 
13
15
 
14
16
  class ECKeyPair:
17
+ """Elliptic Curve key pair for cryptographic operations."""
18
+
15
19
  def __init__(self, curve=None):
20
+ """Initialize EC key pair."""
16
21
  if curve is None:
17
22
  curve = ec.SECP256R1()
18
23
  self.private_key = ec.generate_private_key(curve, default_backend())
otdf_python/header.py CHANGED
@@ -1,3 +1,5 @@
1
+ """TDF header parsing and serialization."""
2
+
1
3
  from otdf_python.constants import MAGIC_NUMBER_AND_VERSION
2
4
  from otdf_python.ecc_mode import ECCMode
3
5
  from otdf_python.policy_info import PolicyInfo
@@ -6,10 +8,13 @@ from otdf_python.symmetric_and_payload_config import SymmetricAndPayloadConfig
6
8
 
7
9
 
8
10
  class Header:
11
+ """TDF header with encryption and policy information."""
12
+
9
13
  # Size of GMAC (Galois Message Authentication Code) for policy binding
10
14
  GMAC_SIZE = 8
11
15
 
12
16
  def __init__(self):
17
+ """Initialize TDF header."""
13
18
  self.kas_locator: ResourceLocator | None = None
14
19
  self.ecc_mode: ECCMode | None = None
15
20
  self.payload_config: SymmetricAndPayloadConfig | None = None
@@ -1,8 +1,12 @@
1
+ """Exception for invalid ZIP file errors."""
2
+
3
+
1
4
  class InvalidZipException(Exception):
2
- """
3
- Raised when a ZIP file is invalid or corrupted.
5
+ """Raised when a ZIP file is invalid or corrupted.
6
+
4
7
  Based on Java implementation.
5
8
  """
6
9
 
7
10
  def __init__(self, message: str):
11
+ """Initialize exception."""
8
12
  super().__init__(message)