@mitre/hdf-schema 3.0.0 → 3.1.0-rc.1
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.
- package/LICENSE.md +55 -0
- package/README.md +96 -41
- package/dist/go/hdf.go +148 -104
- package/dist/helpers.js +4 -44
- package/dist/index.d.ts +26 -1
- package/dist/index.js +26 -1
- package/dist/schemas/hdf-amendments.schema.json +178 -53
- package/dist/schemas/hdf-baseline.schema.json +181 -56
- package/dist/schemas/hdf-comparison.schema.json +523 -108
- package/dist/schemas/hdf-evidence-package.schema.json +175 -50
- package/dist/schemas/hdf-plan.schema.json +181 -56
- package/dist/schemas/hdf-results.schema.json +502 -87
- package/dist/schemas/hdf-system.schema.json +190 -65
- package/dist/ts/hdf-amendments.d.ts +43 -15
- package/dist/ts/hdf-amendments.js +18 -7
- package/dist/ts/hdf-amendments.ts +44 -15
- package/dist/ts/hdf-results.d.ts +91 -37
- package/dist/ts/hdf-results.js +40 -20
- package/dist/ts/hdf-results.ts +91 -36
- package/package.json +44 -44
- package/dist/python/hdf_amendments.py +0 -695
- package/dist/python/hdf_baseline.py +0 -782
- package/dist/python/hdf_comparison.py +0 -1771
- package/dist/python/hdf_evidence_package.py +0 -593
- package/dist/python/hdf_plan.py +0 -363
- package/dist/python/hdf_results.py +0 -2163
- package/dist/python/hdf_system.py +0 -904
- package/src/schemas/hdf-amendments.schema.json +0 -97
- package/src/schemas/hdf-baseline.schema.json +0 -190
- package/src/schemas/hdf-comparison.schema.json +0 -107
- package/src/schemas/hdf-evidence-package.schema.json +0 -227
- package/src/schemas/hdf-plan.schema.json +0 -92
- package/src/schemas/hdf-results.schema.json +0 -304
- package/src/schemas/hdf-system.schema.json +0 -136
- package/src/schemas/primitives/amendments.schema.json +0 -155
- package/src/schemas/primitives/common.schema.json +0 -814
- package/src/schemas/primitives/comparison.schema.json +0 -809
- package/src/schemas/primitives/component.schema.json +0 -518
- package/src/schemas/primitives/data-flow.schema.json +0 -158
- package/src/schemas/primitives/extensions.schema.json +0 -342
- package/src/schemas/primitives/parameter.schema.json +0 -128
- package/src/schemas/primitives/plan.schema.json +0 -128
- package/src/schemas/primitives/platform.schema.json +0 -32
- package/src/schemas/primitives/result.schema.json +0 -133
- package/src/schemas/primitives/runner.schema.json +0 -83
- package/src/schemas/primitives/statistics.schema.json +0 -71
- package/src/schemas/primitives/system.schema.json +0 -132
- package/src/schemas/primitives/target.schema.json +0 -523
|
@@ -1,593 +0,0 @@
|
|
|
1
|
-
from dataclasses import dataclass
|
|
2
|
-
from typing import Optional, Any, Dict, List, TypeVar, Type, cast, Callable
|
|
3
|
-
from enum import Enum
|
|
4
|
-
from uuid import UUID
|
|
5
|
-
from datetime import datetime
|
|
6
|
-
import dateutil.parser
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
T = TypeVar("T")
|
|
10
|
-
EnumT = TypeVar("EnumT", bound=Enum)
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
def from_int(x: Any) -> int:
|
|
14
|
-
assert isinstance(x, int) and not isinstance(x, bool)
|
|
15
|
-
return x
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
def from_none(x: Any) -> Any:
|
|
19
|
-
assert x is None
|
|
20
|
-
return x
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
def from_union(fs, x):
|
|
24
|
-
for f in fs:
|
|
25
|
-
try:
|
|
26
|
-
return f(x)
|
|
27
|
-
except:
|
|
28
|
-
pass
|
|
29
|
-
assert False
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
def from_bool(x: Any) -> bool:
|
|
33
|
-
assert isinstance(x, bool)
|
|
34
|
-
return x
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
def from_float(x: Any) -> float:
|
|
38
|
-
assert isinstance(x, (float, int)) and not isinstance(x, bool)
|
|
39
|
-
return float(x)
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
def to_float(x: Any) -> float:
|
|
43
|
-
assert isinstance(x, (int, float))
|
|
44
|
-
return x
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
def to_class(c: Type[T], x: Any) -> dict:
|
|
48
|
-
assert isinstance(x, c)
|
|
49
|
-
return cast(Any, x).to_dict()
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
def from_str(x: Any) -> str:
|
|
53
|
-
assert isinstance(x, str)
|
|
54
|
-
return x
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
def to_enum(c: Type[EnumT], x: Any) -> EnumT:
|
|
58
|
-
assert isinstance(x, c)
|
|
59
|
-
return x.value
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
def from_dict(f: Callable[[Any], T], x: Any) -> Dict[str, T]:
|
|
63
|
-
assert isinstance(x, dict)
|
|
64
|
-
return { k: f(v) for (k, v) in x.items() }
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
def from_datetime(x: Any) -> datetime:
|
|
68
|
-
return dateutil.parser.parse(x)
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
def from_list(f: Callable[[Any], T], x: Any) -> List[T]:
|
|
72
|
-
assert isinstance(x, list)
|
|
73
|
-
return [f(y) for y in x]
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
@dataclass
|
|
77
|
-
class SBOMCoverage:
|
|
78
|
-
"""SBOM coverage across system components.
|
|
79
|
-
|
|
80
|
-
SBOM coverage statistics for the system.
|
|
81
|
-
"""
|
|
82
|
-
components_with_sbom: Optional[int] = None
|
|
83
|
-
"""Number of system components that have an associated SBOM."""
|
|
84
|
-
|
|
85
|
-
total_components: Optional[int] = None
|
|
86
|
-
"""Total number of components in the system."""
|
|
87
|
-
|
|
88
|
-
@staticmethod
|
|
89
|
-
def from_dict(obj: Any) -> 'SBOMCoverage':
|
|
90
|
-
assert isinstance(obj, dict)
|
|
91
|
-
components_with_sbom = from_union([from_int, from_none], obj.get("componentsWithSbom"))
|
|
92
|
-
total_components = from_union([from_int, from_none], obj.get("totalComponents"))
|
|
93
|
-
return SBOMCoverage(components_with_sbom, total_components)
|
|
94
|
-
|
|
95
|
-
def to_dict(self) -> dict:
|
|
96
|
-
result: dict = {}
|
|
97
|
-
if self.components_with_sbom is not None:
|
|
98
|
-
result["componentsWithSbom"] = from_union([from_int, from_none], self.components_with_sbom)
|
|
99
|
-
if self.total_components is not None:
|
|
100
|
-
result["totalComponents"] = from_union([from_int, from_none], self.total_components)
|
|
101
|
-
return result
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
@dataclass
|
|
105
|
-
class CompletenessCheck:
|
|
106
|
-
"""Summary of assessment completeness and compliance status.
|
|
107
|
-
|
|
108
|
-
Informational summary of assessment completeness. Not authoritative — tools should
|
|
109
|
-
compute these from the referenced documents.
|
|
110
|
-
"""
|
|
111
|
-
all_baselines_assessed: Optional[bool] = None
|
|
112
|
-
"""Whether all baselines referenced by system components have assessment results."""
|
|
113
|
-
|
|
114
|
-
all_components_covered: Optional[bool] = None
|
|
115
|
-
"""Whether all system components have at least one matching target in the results."""
|
|
116
|
-
|
|
117
|
-
compliance_percent: Optional[float] = None
|
|
118
|
-
"""Overall compliance percentage across all assessments."""
|
|
119
|
-
|
|
120
|
-
expired_waivers: Optional[int] = None
|
|
121
|
-
"""Number of waivers/amendments that have expired."""
|
|
122
|
-
|
|
123
|
-
sbom_coverage: Optional[SBOMCoverage] = None
|
|
124
|
-
"""SBOM coverage across system components."""
|
|
125
|
-
|
|
126
|
-
unresolved_poams: Optional[int] = None
|
|
127
|
-
"""Number of POA&M items that are still open (not completed)."""
|
|
128
|
-
|
|
129
|
-
@staticmethod
|
|
130
|
-
def from_dict(obj: Any) -> 'CompletenessCheck':
|
|
131
|
-
assert isinstance(obj, dict)
|
|
132
|
-
all_baselines_assessed = from_union([from_bool, from_none], obj.get("allBaselinesAssessed"))
|
|
133
|
-
all_components_covered = from_union([from_bool, from_none], obj.get("allComponentsCovered"))
|
|
134
|
-
compliance_percent = from_union([from_float, from_none], obj.get("compliancePercent"))
|
|
135
|
-
expired_waivers = from_union([from_int, from_none], obj.get("expiredWaivers"))
|
|
136
|
-
sbom_coverage = from_union([SBOMCoverage.from_dict, from_none], obj.get("sbomCoverage"))
|
|
137
|
-
unresolved_poams = from_union([from_int, from_none], obj.get("unresolvedPoams"))
|
|
138
|
-
return CompletenessCheck(all_baselines_assessed, all_components_covered, compliance_percent, expired_waivers, sbom_coverage, unresolved_poams)
|
|
139
|
-
|
|
140
|
-
def to_dict(self) -> dict:
|
|
141
|
-
result: dict = {}
|
|
142
|
-
if self.all_baselines_assessed is not None:
|
|
143
|
-
result["allBaselinesAssessed"] = from_union([from_bool, from_none], self.all_baselines_assessed)
|
|
144
|
-
if self.all_components_covered is not None:
|
|
145
|
-
result["allComponentsCovered"] = from_union([from_bool, from_none], self.all_components_covered)
|
|
146
|
-
if self.compliance_percent is not None:
|
|
147
|
-
result["compliancePercent"] = from_union([to_float, from_none], self.compliance_percent)
|
|
148
|
-
if self.expired_waivers is not None:
|
|
149
|
-
result["expiredWaivers"] = from_union([from_int, from_none], self.expired_waivers)
|
|
150
|
-
if self.sbom_coverage is not None:
|
|
151
|
-
result["sbomCoverage"] = from_union([lambda x: to_class(SBOMCoverage, x), from_none], self.sbom_coverage)
|
|
152
|
-
if self.unresolved_poams is not None:
|
|
153
|
-
result["unresolvedPoams"] = from_union([from_int, from_none], self.unresolved_poams)
|
|
154
|
-
return result
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
class HashAlgorithm(Enum):
|
|
158
|
-
"""The hash algorithm used for the checksum.
|
|
159
|
-
|
|
160
|
-
Supported cryptographic hash algorithms for checksums and integrity verification.
|
|
161
|
-
"""
|
|
162
|
-
SHA256 = "sha256"
|
|
163
|
-
SHA384 = "sha384"
|
|
164
|
-
SHA512 = "sha512"
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
@dataclass
|
|
168
|
-
class Checksum:
|
|
169
|
-
"""Cryptographic checksum for verifying the referenced document's integrity.
|
|
170
|
-
|
|
171
|
-
Cryptographic checksum for baseline integrity verification.
|
|
172
|
-
"""
|
|
173
|
-
algorithm: HashAlgorithm
|
|
174
|
-
"""The hash algorithm used for the checksum."""
|
|
175
|
-
|
|
176
|
-
value: str
|
|
177
|
-
"""The checksum value."""
|
|
178
|
-
|
|
179
|
-
@staticmethod
|
|
180
|
-
def from_dict(obj: Any) -> 'Checksum':
|
|
181
|
-
assert isinstance(obj, dict)
|
|
182
|
-
algorithm = HashAlgorithm(obj.get("algorithm"))
|
|
183
|
-
value = from_str(obj.get("value"))
|
|
184
|
-
return Checksum(algorithm, value)
|
|
185
|
-
|
|
186
|
-
def to_dict(self) -> dict:
|
|
187
|
-
result: dict = {}
|
|
188
|
-
result["algorithm"] = to_enum(HashAlgorithm, self.algorithm)
|
|
189
|
-
result["value"] = from_str(self.value)
|
|
190
|
-
return result
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
class ContentType(Enum):
|
|
194
|
-
"""The type of HDF document being referenced.
|
|
195
|
-
|
|
196
|
-
The type of document referenced in the evidence package.
|
|
197
|
-
"""
|
|
198
|
-
HDF_AMENDMENTS = "hdf-amendments"
|
|
199
|
-
HDF_BASELINE = "hdf-baseline"
|
|
200
|
-
HDF_COMPARISON = "hdf-comparison"
|
|
201
|
-
HDF_PLAN = "hdf-plan"
|
|
202
|
-
HDF_RESULTS = "hdf-results"
|
|
203
|
-
HDF_SYSTEM = "hdf-system"
|
|
204
|
-
SBOM = "sbom"
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
@dataclass
|
|
208
|
-
class ContentReference:
|
|
209
|
-
"""A reference to an HDF document or SBOM included in the evidence package."""
|
|
210
|
-
|
|
211
|
-
type: ContentType
|
|
212
|
-
"""The type of HDF document being referenced."""
|
|
213
|
-
|
|
214
|
-
uri: str
|
|
215
|
-
"""URI to the document. Can be a relative path or absolute URL."""
|
|
216
|
-
|
|
217
|
-
checksum: Optional[Checksum] = None
|
|
218
|
-
"""Cryptographic checksum for verifying the referenced document's integrity."""
|
|
219
|
-
|
|
220
|
-
component_ref: Optional[UUID] = None
|
|
221
|
-
"""componentId of the component this content entry relates to. Use to link SBOMs, results,
|
|
222
|
-
or other documents to a specific system component.
|
|
223
|
-
"""
|
|
224
|
-
description: Optional[str] = None
|
|
225
|
-
"""Optional description of this content entry."""
|
|
226
|
-
|
|
227
|
-
@staticmethod
|
|
228
|
-
def from_dict(obj: Any) -> 'ContentReference':
|
|
229
|
-
assert isinstance(obj, dict)
|
|
230
|
-
type = ContentType(obj.get("type"))
|
|
231
|
-
uri = from_str(obj.get("uri"))
|
|
232
|
-
checksum = from_union([Checksum.from_dict, from_none], obj.get("checksum"))
|
|
233
|
-
component_ref = from_union([lambda x: UUID(x), from_none], obj.get("componentRef"))
|
|
234
|
-
description = from_union([from_str, from_none], obj.get("description"))
|
|
235
|
-
return ContentReference(type, uri, checksum, component_ref, description)
|
|
236
|
-
|
|
237
|
-
def to_dict(self) -> dict:
|
|
238
|
-
result: dict = {}
|
|
239
|
-
result["type"] = to_enum(ContentType, self.type)
|
|
240
|
-
result["uri"] = from_str(self.uri)
|
|
241
|
-
if self.checksum is not None:
|
|
242
|
-
result["checksum"] = from_union([lambda x: to_class(Checksum, x), from_none], self.checksum)
|
|
243
|
-
if self.component_ref is not None:
|
|
244
|
-
result["componentRef"] = from_union([lambda x: str(x), from_none], self.component_ref)
|
|
245
|
-
if self.description is not None:
|
|
246
|
-
result["description"] = from_union([from_str, from_none], self.description)
|
|
247
|
-
return result
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
@dataclass
|
|
251
|
-
class Generator:
|
|
252
|
-
"""Information about the tool that generated this document.
|
|
253
|
-
|
|
254
|
-
Information about the tool that generated this HDF file.
|
|
255
|
-
"""
|
|
256
|
-
name: str
|
|
257
|
-
"""The name of the software that produced this HDF file. Example: 'gosec-to-hdf'."""
|
|
258
|
-
|
|
259
|
-
version: str
|
|
260
|
-
"""The version of the tool. Example: '5.22.3'."""
|
|
261
|
-
|
|
262
|
-
@staticmethod
|
|
263
|
-
def from_dict(obj: Any) -> 'Generator':
|
|
264
|
-
assert isinstance(obj, dict)
|
|
265
|
-
name = from_str(obj.get("name"))
|
|
266
|
-
version = from_str(obj.get("version"))
|
|
267
|
-
return Generator(name, version)
|
|
268
|
-
|
|
269
|
-
def to_dict(self) -> dict:
|
|
270
|
-
result: dict = {}
|
|
271
|
-
result["name"] = from_str(self.name)
|
|
272
|
-
result["version"] = from_str(self.version)
|
|
273
|
-
return result
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
@dataclass
|
|
277
|
-
class Integrity:
|
|
278
|
-
"""Cryptographic integrity information for verifying this evidence package has not been
|
|
279
|
-
tampered with.
|
|
280
|
-
|
|
281
|
-
Cryptographic integrity information for verifying the HDF file has not been tampered
|
|
282
|
-
with. If algorithm is provided, checksum must also be provided, and vice versa.
|
|
283
|
-
"""
|
|
284
|
-
algorithm: Optional[HashAlgorithm] = None
|
|
285
|
-
"""The hash algorithm used for the checksum."""
|
|
286
|
-
|
|
287
|
-
checksum: Optional[str] = None
|
|
288
|
-
"""The checksum value."""
|
|
289
|
-
|
|
290
|
-
signature: Optional[str] = None
|
|
291
|
-
"""Optional cryptographic signature."""
|
|
292
|
-
|
|
293
|
-
signed_by: Optional[str] = None
|
|
294
|
-
"""Identifier of who signed this file."""
|
|
295
|
-
|
|
296
|
-
@staticmethod
|
|
297
|
-
def from_dict(obj: Any) -> 'Integrity':
|
|
298
|
-
assert isinstance(obj, dict)
|
|
299
|
-
algorithm = from_union([HashAlgorithm, from_none], obj.get("algorithm"))
|
|
300
|
-
checksum = from_union([from_str, from_none], obj.get("checksum"))
|
|
301
|
-
signature = from_union([from_str, from_none], obj.get("signature"))
|
|
302
|
-
signed_by = from_union([from_str, from_none], obj.get("signedBy"))
|
|
303
|
-
return Integrity(algorithm, checksum, signature, signed_by)
|
|
304
|
-
|
|
305
|
-
def to_dict(self) -> dict:
|
|
306
|
-
result: dict = {}
|
|
307
|
-
if self.algorithm is not None:
|
|
308
|
-
result["algorithm"] = from_union([lambda x: to_enum(HashAlgorithm, x), from_none], self.algorithm)
|
|
309
|
-
if self.checksum is not None:
|
|
310
|
-
result["checksum"] = from_union([from_str, from_none], self.checksum)
|
|
311
|
-
if self.signature is not None:
|
|
312
|
-
result["signature"] = from_union([from_str, from_none], self.signature)
|
|
313
|
-
if self.signed_by is not None:
|
|
314
|
-
result["signedBy"] = from_union([from_str, from_none], self.signed_by)
|
|
315
|
-
return result
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
class TypeEnum(Enum):
|
|
319
|
-
"""The type of identifier. Use 'email' for email addresses, 'username' for user accounts,
|
|
320
|
-
'system' for automated systems, 'simple' for basic string identifiers without additional
|
|
321
|
-
classification, or 'other' for custom identity systems.
|
|
322
|
-
"""
|
|
323
|
-
EMAIL = "email"
|
|
324
|
-
OTHER = "other"
|
|
325
|
-
SIMPLE = "simple"
|
|
326
|
-
SYSTEM = "system"
|
|
327
|
-
USERNAME = "username"
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
@dataclass
|
|
331
|
-
class Identity:
|
|
332
|
-
"""Identity of who prepared this evidence package.
|
|
333
|
-
|
|
334
|
-
Represents an identity that performed an action, such as capturing evidence or applying
|
|
335
|
-
an override.
|
|
336
|
-
|
|
337
|
-
The identity that created this signature.
|
|
338
|
-
"""
|
|
339
|
-
identifier: str
|
|
340
|
-
"""The identifier value. Example: 'user@example.com', 'jdoe', 'automated-scanner-01'."""
|
|
341
|
-
|
|
342
|
-
type: TypeEnum
|
|
343
|
-
"""The type of identifier. Use 'email' for email addresses, 'username' for user accounts,
|
|
344
|
-
'system' for automated systems, 'simple' for basic string identifiers without additional
|
|
345
|
-
classification, or 'other' for custom identity systems.
|
|
346
|
-
"""
|
|
347
|
-
description: Optional[str] = None
|
|
348
|
-
"""Optional description of the identity or identity system, particularly useful when type is
|
|
349
|
-
'other'.
|
|
350
|
-
"""
|
|
351
|
-
|
|
352
|
-
@staticmethod
|
|
353
|
-
def from_dict(obj: Any) -> 'Identity':
|
|
354
|
-
assert isinstance(obj, dict)
|
|
355
|
-
identifier = from_str(obj.get("identifier"))
|
|
356
|
-
type = TypeEnum(obj.get("type"))
|
|
357
|
-
description = from_union([from_str, from_none], obj.get("description"))
|
|
358
|
-
return Identity(identifier, type, description)
|
|
359
|
-
|
|
360
|
-
def to_dict(self) -> dict:
|
|
361
|
-
result: dict = {}
|
|
362
|
-
result["identifier"] = from_str(self.identifier)
|
|
363
|
-
result["type"] = to_enum(TypeEnum, self.type)
|
|
364
|
-
if self.description is not None:
|
|
365
|
-
result["description"] = from_union([from_str, from_none], self.description)
|
|
366
|
-
return result
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
@dataclass
|
|
370
|
-
class VerificationMethod:
|
|
371
|
-
"""The verification method containing the public key for signature verification.
|
|
372
|
-
|
|
373
|
-
Verification method containing the public key needed to verify a digital signature.
|
|
374
|
-
Supports multiple key formats including JWK (for RSA, EC), PEM, and Base58.
|
|
375
|
-
"""
|
|
376
|
-
controller: str
|
|
377
|
-
"""The entity that controls this verification method. Can be a DID, URI, or other identifier."""
|
|
378
|
-
|
|
379
|
-
type: str
|
|
380
|
-
"""The type of verification method. Example: 'JsonWebKey2020', 'RsaVerificationKey2018',
|
|
381
|
-
'Ed25519VerificationKey2020'.
|
|
382
|
-
"""
|
|
383
|
-
public_key_base58: Optional[str] = None
|
|
384
|
-
"""Public key in Base58 format, commonly used with Ed25519 keys."""
|
|
385
|
-
|
|
386
|
-
public_key_jwk: Optional[Dict[str, Any]] = None
|
|
387
|
-
"""Public key in JSON Web Key format."""
|
|
388
|
-
|
|
389
|
-
public_key_pem: Optional[str] = None
|
|
390
|
-
"""Public key in PEM format. Example: '-----BEGIN PUBLIC KEY-----...-----END PUBLIC
|
|
391
|
-
KEY-----'.
|
|
392
|
-
"""
|
|
393
|
-
|
|
394
|
-
@staticmethod
|
|
395
|
-
def from_dict(obj: Any) -> 'VerificationMethod':
|
|
396
|
-
assert isinstance(obj, dict)
|
|
397
|
-
controller = from_str(obj.get("controller"))
|
|
398
|
-
type = from_str(obj.get("type"))
|
|
399
|
-
public_key_base58 = from_union([from_str, from_none], obj.get("publicKeyBase58"))
|
|
400
|
-
public_key_jwk = from_union([lambda x: from_dict(lambda x: x, x), from_none], obj.get("publicKeyJwk"))
|
|
401
|
-
public_key_pem = from_union([from_str, from_none], obj.get("publicKeyPem"))
|
|
402
|
-
return VerificationMethod(controller, type, public_key_base58, public_key_jwk, public_key_pem)
|
|
403
|
-
|
|
404
|
-
def to_dict(self) -> dict:
|
|
405
|
-
result: dict = {}
|
|
406
|
-
result["controller"] = from_str(self.controller)
|
|
407
|
-
result["type"] = from_str(self.type)
|
|
408
|
-
if self.public_key_base58 is not None:
|
|
409
|
-
result["publicKeyBase58"] = from_union([from_str, from_none], self.public_key_base58)
|
|
410
|
-
if self.public_key_jwk is not None:
|
|
411
|
-
result["publicKeyJwk"] = from_union([lambda x: from_dict(lambda x: x, x), from_none], self.public_key_jwk)
|
|
412
|
-
if self.public_key_pem is not None:
|
|
413
|
-
result["publicKeyPem"] = from_union([from_str, from_none], self.public_key_pem)
|
|
414
|
-
return result
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
@dataclass
|
|
418
|
-
class Signature:
|
|
419
|
-
"""Digital signature covering the entire evidence package.
|
|
420
|
-
|
|
421
|
-
A digital signature following W3C Data Integrity Proofs pattern. Supports hardware
|
|
422
|
-
security tokens (PKCS#11/PKCS#12), Yubikeys, GPG keys, passkeys, and other cryptographic
|
|
423
|
-
signing methods via JWK, PEM, or Base58 key formats.
|
|
424
|
-
"""
|
|
425
|
-
created: datetime
|
|
426
|
-
"""When the signature was created. ISO 8601 format."""
|
|
427
|
-
|
|
428
|
-
creator: Identity
|
|
429
|
-
"""The identity that created this signature."""
|
|
430
|
-
|
|
431
|
-
proof_purpose: str
|
|
432
|
-
"""The purpose of this signature. Example: 'attestation', 'authentication',
|
|
433
|
-
'assertionMethod'.
|
|
434
|
-
"""
|
|
435
|
-
signature_value: str
|
|
436
|
-
"""The base64-encoded or base58-encoded signature value."""
|
|
437
|
-
|
|
438
|
-
type: str
|
|
439
|
-
"""The signature suite type. Example: 'JsonWebSignature2020', 'RsaSignature2018',
|
|
440
|
-
'Ed25519Signature2020'.
|
|
441
|
-
"""
|
|
442
|
-
verification_method: VerificationMethod
|
|
443
|
-
"""The verification method containing the public key for signature verification."""
|
|
444
|
-
|
|
445
|
-
challenge: Optional[str] = None
|
|
446
|
-
"""Challenge value from the verifier, used in challenge-response authentication."""
|
|
447
|
-
|
|
448
|
-
domain: Optional[str] = None
|
|
449
|
-
"""Domain restriction for the signature, prevents cross-domain replay attacks."""
|
|
450
|
-
|
|
451
|
-
nonce: Optional[str] = None
|
|
452
|
-
"""Random value to prevent replay attacks."""
|
|
453
|
-
|
|
454
|
-
@staticmethod
|
|
455
|
-
def from_dict(obj: Any) -> 'Signature':
|
|
456
|
-
assert isinstance(obj, dict)
|
|
457
|
-
created = from_datetime(obj.get("created"))
|
|
458
|
-
creator = Identity.from_dict(obj.get("creator"))
|
|
459
|
-
proof_purpose = from_str(obj.get("proofPurpose"))
|
|
460
|
-
signature_value = from_str(obj.get("signatureValue"))
|
|
461
|
-
type = from_str(obj.get("type"))
|
|
462
|
-
verification_method = VerificationMethod.from_dict(obj.get("verificationMethod"))
|
|
463
|
-
challenge = from_union([from_str, from_none], obj.get("challenge"))
|
|
464
|
-
domain = from_union([from_str, from_none], obj.get("domain"))
|
|
465
|
-
nonce = from_union([from_str, from_none], obj.get("nonce"))
|
|
466
|
-
return Signature(created, creator, proof_purpose, signature_value, type, verification_method, challenge, domain, nonce)
|
|
467
|
-
|
|
468
|
-
def to_dict(self) -> dict:
|
|
469
|
-
result: dict = {}
|
|
470
|
-
result["created"] = self.created.isoformat()
|
|
471
|
-
result["creator"] = to_class(Identity, self.creator)
|
|
472
|
-
result["proofPurpose"] = from_str(self.proof_purpose)
|
|
473
|
-
result["signatureValue"] = from_str(self.signature_value)
|
|
474
|
-
result["type"] = from_str(self.type)
|
|
475
|
-
result["verificationMethod"] = to_class(VerificationMethod, self.verification_method)
|
|
476
|
-
if self.challenge is not None:
|
|
477
|
-
result["challenge"] = from_union([from_str, from_none], self.challenge)
|
|
478
|
-
if self.domain is not None:
|
|
479
|
-
result["domain"] = from_union([from_str, from_none], self.domain)
|
|
480
|
-
if self.nonce is not None:
|
|
481
|
-
result["nonce"] = from_union([from_str, from_none], self.nonce)
|
|
482
|
-
return result
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
@dataclass
|
|
486
|
-
class HdfEvidencePackage:
|
|
487
|
-
"""Bundles references to all HDF documents for audit, authorization, and compliance review.
|
|
488
|
-
Each content entry references a document by type, URI, and checksum for integrity
|
|
489
|
-
verification.
|
|
490
|
-
"""
|
|
491
|
-
contents: List[ContentReference]
|
|
492
|
-
"""References to HDF documents included in this evidence package."""
|
|
493
|
-
|
|
494
|
-
name: str
|
|
495
|
-
"""Human-readable name for this evidence package. Example: 'Enterprise Portal ATO Evidence -
|
|
496
|
-
Q1 2026'.
|
|
497
|
-
"""
|
|
498
|
-
completeness_check: Optional[CompletenessCheck] = None
|
|
499
|
-
"""Summary of assessment completeness and compliance status."""
|
|
500
|
-
|
|
501
|
-
description: Optional[str] = None
|
|
502
|
-
"""Description of the evidence package's purpose and scope."""
|
|
503
|
-
|
|
504
|
-
generator: Optional[Generator] = None
|
|
505
|
-
"""Information about the tool that generated this document."""
|
|
506
|
-
|
|
507
|
-
integrity: Optional[Integrity] = None
|
|
508
|
-
"""Cryptographic integrity information for verifying this evidence package has not been
|
|
509
|
-
tampered with.
|
|
510
|
-
"""
|
|
511
|
-
labels: Optional[Dict[str, str]] = None
|
|
512
|
-
"""Optional key-value labels for grouping and querying evidence packages."""
|
|
513
|
-
|
|
514
|
-
package_id: Optional[UUID] = None
|
|
515
|
-
"""Unique identifier for this evidence package. Optional in casual use, expected in
|
|
516
|
-
production ATO submissions. Auto-generated if omitted during creation.
|
|
517
|
-
"""
|
|
518
|
-
plan_ref: Optional[str] = None
|
|
519
|
-
"""URI to the hdf-plan document that drove this assessment. Used for completeness
|
|
520
|
-
verification — every baseline in the plan should have a corresponding results document in
|
|
521
|
-
this package.
|
|
522
|
-
"""
|
|
523
|
-
prepared_at: Optional[datetime] = None
|
|
524
|
-
"""When this evidence package was prepared. ISO 8601 format."""
|
|
525
|
-
|
|
526
|
-
prepared_by: Optional[Identity] = None
|
|
527
|
-
"""Identity of who prepared this evidence package."""
|
|
528
|
-
|
|
529
|
-
signature: Optional[Signature] = None
|
|
530
|
-
"""Digital signature covering the entire evidence package."""
|
|
531
|
-
|
|
532
|
-
system_ref: Optional[str] = None
|
|
533
|
-
"""URI to the hdf-system document this evidence package covers."""
|
|
534
|
-
|
|
535
|
-
version: Optional[str] = None
|
|
536
|
-
"""Version of this evidence package."""
|
|
537
|
-
|
|
538
|
-
@staticmethod
|
|
539
|
-
def from_dict(obj: Any) -> 'HdfEvidencePackage':
|
|
540
|
-
assert isinstance(obj, dict)
|
|
541
|
-
contents = from_list(ContentReference.from_dict, obj.get("contents"))
|
|
542
|
-
name = from_str(obj.get("name"))
|
|
543
|
-
completeness_check = from_union([CompletenessCheck.from_dict, from_none], obj.get("completenessCheck"))
|
|
544
|
-
description = from_union([from_str, from_none], obj.get("description"))
|
|
545
|
-
generator = from_union([Generator.from_dict, from_none], obj.get("generator"))
|
|
546
|
-
integrity = from_union([Integrity.from_dict, from_none], obj.get("integrity"))
|
|
547
|
-
labels = from_union([lambda x: from_dict(from_str, x), from_none], obj.get("labels"))
|
|
548
|
-
package_id = from_union([lambda x: UUID(x), from_none], obj.get("packageId"))
|
|
549
|
-
plan_ref = from_union([from_str, from_none], obj.get("planRef"))
|
|
550
|
-
prepared_at = from_union([from_datetime, from_none], obj.get("preparedAt"))
|
|
551
|
-
prepared_by = from_union([Identity.from_dict, from_none], obj.get("preparedBy"))
|
|
552
|
-
signature = from_union([Signature.from_dict, from_none], obj.get("signature"))
|
|
553
|
-
system_ref = from_union([from_str, from_none], obj.get("systemRef"))
|
|
554
|
-
version = from_union([from_str, from_none], obj.get("version"))
|
|
555
|
-
return HdfEvidencePackage(contents, name, completeness_check, description, generator, integrity, labels, package_id, plan_ref, prepared_at, prepared_by, signature, system_ref, version)
|
|
556
|
-
|
|
557
|
-
def to_dict(self) -> dict:
|
|
558
|
-
result: dict = {}
|
|
559
|
-
result["contents"] = from_list(lambda x: to_class(ContentReference, x), self.contents)
|
|
560
|
-
result["name"] = from_str(self.name)
|
|
561
|
-
if self.completeness_check is not None:
|
|
562
|
-
result["completenessCheck"] = from_union([lambda x: to_class(CompletenessCheck, x), from_none], self.completeness_check)
|
|
563
|
-
if self.description is not None:
|
|
564
|
-
result["description"] = from_union([from_str, from_none], self.description)
|
|
565
|
-
if self.generator is not None:
|
|
566
|
-
result["generator"] = from_union([lambda x: to_class(Generator, x), from_none], self.generator)
|
|
567
|
-
if self.integrity is not None:
|
|
568
|
-
result["integrity"] = from_union([lambda x: to_class(Integrity, x), from_none], self.integrity)
|
|
569
|
-
if self.labels is not None:
|
|
570
|
-
result["labels"] = from_union([lambda x: from_dict(from_str, x), from_none], self.labels)
|
|
571
|
-
if self.package_id is not None:
|
|
572
|
-
result["packageId"] = from_union([lambda x: str(x), from_none], self.package_id)
|
|
573
|
-
if self.plan_ref is not None:
|
|
574
|
-
result["planRef"] = from_union([from_str, from_none], self.plan_ref)
|
|
575
|
-
if self.prepared_at is not None:
|
|
576
|
-
result["preparedAt"] = from_union([lambda x: x.isoformat(), from_none], self.prepared_at)
|
|
577
|
-
if self.prepared_by is not None:
|
|
578
|
-
result["preparedBy"] = from_union([lambda x: to_class(Identity, x), from_none], self.prepared_by)
|
|
579
|
-
if self.signature is not None:
|
|
580
|
-
result["signature"] = from_union([lambda x: to_class(Signature, x), from_none], self.signature)
|
|
581
|
-
if self.system_ref is not None:
|
|
582
|
-
result["systemRef"] = from_union([from_str, from_none], self.system_ref)
|
|
583
|
-
if self.version is not None:
|
|
584
|
-
result["version"] = from_union([from_str, from_none], self.version)
|
|
585
|
-
return result
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
def hdf_evidence_package_from_dict(s: Any) -> HdfEvidencePackage:
|
|
589
|
-
return HdfEvidencePackage.from_dict(s)
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
def hdf_evidence_package_to_dict(x: HdfEvidencePackage) -> Any:
|
|
593
|
-
return to_class(HdfEvidencePackage, x)
|