polaris-sdk-python 0.1.0__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.
@@ -0,0 +1,104 @@
1
+ """python -m polaris_verify.conformance -- the verifier CLI the conformance suite drives.
2
+
3
+ Reads ONE conformance case as JSON on stdin and prints a verdict as JSON on stdout. The case
4
+ names the artifact it is about; a verifier dispatches on it:
5
+
6
+ {"artifact": "authenticity-pack", "pack": {...}, "anchors": ["<hex>", ...]}
7
+ -> {"authentic": bool, "issuer_trusted": bool|null}
8
+ {"artifact": "status-assertion", "assertion": {...}, "now": "<iso8601>"}
9
+ -> {"authentic": bool, "fresh": bool|null, "active": bool|null}
10
+ {"artifact": "<epoch-checkpoint|revocation-feed|federation-manifest|
11
+ federation-status-bundle|transparency-sth>", "object": {...}, "now": "<iso8601>"}
12
+ -> {"authentic": bool, "fresh": bool|null}
13
+ {"artifact": "timestamp-anchor", "timestamp": {...}, "log_key": "<hex>"|null,
14
+ "trusted_witnesses": ["<hex>", ...]|null, "threshold": int}
15
+ -> {"anchored": bool, "witnessed": bool|null}
16
+
17
+ For backward compatibility a case with no `artifact` is an authenticity pack. A conformant
18
+ verifier in any language implements this same stdin->stdout contract; conformance/run_conformance.py
19
+ drives it over the published cases and checks every verdict. See conformance/SPEC.md.
20
+ """
21
+ import json
22
+ import sys
23
+
24
+ from . import (verify_attestation, verify_authenticity, verify_cross_authority, verify_holder,
25
+ verify_id_token,
26
+ verify_signed_artifact, verify_status_assertion, verify_timestamp_anchor)
27
+
28
+ _SIGNED_ARTIFACTS = {"epoch-checkpoint", "revocation-feed", "federation-manifest",
29
+ "federation-status-bundle", "transparency-sth", "timestamp", "registry", "exchange-request", "signed-document", "id-token", "trust-list", "exchange-receipt", "exchange-mint", "holder-binding", "holder-proof", "epoch-leaves",
30
+ "agent-grant", "grant-revocation", "agent-proof"}
31
+
32
+
33
+ def main(argv=None):
34
+ try:
35
+ case = json.load(sys.stdin)
36
+ except Exception as e:
37
+ print(json.dumps({"error": "could not read case: %s" % e}))
38
+ return 2
39
+ if not isinstance(case, dict):
40
+ case = {"pack": case}
41
+ artifact = case.get("artifact", "authenticity-pack")
42
+ if artifact == "authenticity-pack":
43
+ pack = case.get("pack") if "pack" in case else case
44
+ v = verify_authenticity(pack or {}, case.get("anchors"))
45
+ print(json.dumps({"authentic": v.authentic, "issuer_trusted": v.issuer_trusted}))
46
+ return 0
47
+ if artifact == "status-assertion":
48
+ v = verify_status_assertion(case.get("assertion") or {}, now=case.get("now"))
49
+ print(json.dumps({"authentic": v.authentic, "fresh": v.fresh, "active": v.active}))
50
+ return 0
51
+ if artifact == "trust-attestation":
52
+ v = verify_attestation(case.get("object") or {},
53
+ attesting_agency_id=case.get("attesting_agency_id"),
54
+ expected_key=case.get("expected_key"))
55
+ print(json.dumps({"authentic": v.authentic, "fresh": v.fresh}))
56
+ return 0
57
+ if artifact == "id-token":
58
+ # v9.420: an ID token verified as a generic signed artifact is verified for
59
+ # its SIGNATURE only, and a token minted for one relying party carries a
60
+ # perfectly good signature at another. Audience confusion and nonce replay
61
+ # are the two attacks this artifact exists to stop, so the contract asks
62
+ # about them.
63
+ anchors = case.get("anchors")
64
+ if anchors == "self":
65
+ anchors = [(case.get("object") or {}).get("public_key_hex")]
66
+ v = verify_id_token(case.get("object") or {}, audience=case.get("audience"),
67
+ nonce=case.get("nonce"), now=case.get("now"), anchors=anchors)
68
+ print(json.dumps({"authentic": v.authentic, "audience_matches": v.audience_matches,
69
+ "nonce_matches": v.nonce_matches, "fresh": v.fresh,
70
+ "issuer_trusted": v.issuer_trusted}))
71
+ return 0
72
+ if artifact in _SIGNED_ARTIFACTS:
73
+ anchors = case.get("anchors")
74
+ if anchors == "self":
75
+ anchors = [(case.get("object") or {}).get("public_key_hex")]
76
+ v = verify_signed_artifact(case.get("object") or {}, now=case.get("now"),
77
+ anchors=anchors)
78
+ print(json.dumps({"authentic": v.authentic, "fresh": v.fresh,
79
+ "issuer_trusted": v.issuer_trusted}))
80
+ return 0
81
+ if artifact == "timestamp-anchor":
82
+ v = verify_timestamp_anchor(case.get("timestamp") or {}, log_key=case.get("log_key"),
83
+ trusted_witnesses=case.get("trusted_witnesses"),
84
+ threshold=int(case.get("threshold") or 1))
85
+ print(json.dumps({"anchored": v.anchored, "witnessed": v.witnessed}))
86
+ return 0
87
+ if artifact == "holder-chain":
88
+ v = verify_holder(case.get("credential") or {}, case.get("binding") or {}, case.get("proof") or {},
89
+ expected_nonce=case.get("expected_nonce"), expected_context=case.get("expected_context"),
90
+ now=case.get("now"))
91
+ print(json.dumps({"proved": v.proved}))
92
+ return 0
93
+ if artifact == "cross-authority":
94
+ v = verify_cross_authority(case.get("pack") or {}, case.get("context_id"),
95
+ case.get("manifests") or [], trusted_anchors=case.get("trusted_anchors"),
96
+ revocation_feed=case.get("revocation_feed"), now=case.get("now"))
97
+ print(json.dumps({"decision": v.decision, "authentic": v.authentic, "issuer_trusted": v.issuer_trusted}))
98
+ return 0
99
+ print(json.dumps({"error": "unknown artifact: %s" % artifact}))
100
+ return 2
101
+
102
+
103
+ if __name__ == "__main__":
104
+ sys.exit(main())