Skip to content

Commit 5003b96

Browse files
Merge pull request #119 from Jev-Engineering/feat/issue57-p256-loader-contract
Bind connected signature verification to anchored public-key snapshots
2 parents e39dc0c + 77a7715 commit 5003b96

10 files changed

Lines changed: 220 additions & 26 deletions

File tree

‎SHA256SUMS‎

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ eb12ff7678ce4733bedd686ddd9064ca8b89cd1c0d3f5ab84726caf7b0268158 jev_integratio
314314
e58055c1074ee97c45a23e0e8716f436deafcdec848f0bcac29d851faac4c4d8 jev_integration_evaluator/data/threshold-spec.schema.json
315315
aa187d402c316d3e1d92dad6e9148a08f45acc3d9609f2397cf493ecd1b4ddf9 jev_integration_evaluator/data/trace.schema.json
316316
62ae35743633fa26d0ee1e74c79c6cb55d4ee1a59af55ed3790190f0ba224baa jev_integration_evaluator/data/typescript_ast.cjs
317-
0dc89666f8b57f1ffc73ba1a848c2ea016b75a490db157cb54738fb57e2f22ac jev_integration_evaluator/data/use-case-template-matrix-v1.json
317+
c18694f8b315776407f8defd16ee2b7fa8cbac47f50c142b59f1c560916895a0 jev_integration_evaluator/data/use-case-template-matrix-v1.json
318318
6a8fa2ff484e3272cc28768167171fec368ab207c86e546875e41a5e84da4b6e jev_integration_evaluator/data/use-case-template-matrix-v1.schema.json
319319
7b78327dafc6e5f189f5316e7abfa9a81952ea7eb68baa55a9728784a4557ecf jev_integration_evaluator/data/windows-connected-delivery-plan-v1.schema.json
320320
08f9cf041780de811e9d84e2ff817d3d72b439a10e098cf9dbaedd6d03c77d5e jev_integration_evaluator/data/windows-connected-delivery-scope-v1.schema.json
@@ -347,7 +347,7 @@ a39ffb4d794b9c0b7bf8c507d9361e684a4e622e6373c8f9bb92012f423438b6 jev_integratio
347347
02739fd54e223bed2646e46938ecb438b596c4dd269d2920841f87ebb4031a8d jev_integration_evaluator/integrations/adaptation_runtime.py
348348
664bce2d74875579f48348ba817a9ecb2cad34f59e2ded1596f61f592a5a3193 jev_integration_evaluator/integrations/adaptation_shapes.py
349349
80ff31f3f74bc7d2ac8d374aeba5e2d064649d9db3324455b2ebff5b48dca79e jev_integration_evaluator/integrations/composite.py
350-
6b6184dd5c9f70dca8d6d85a7a37c494da60fa6d5db4f3820bc15352f247b3f2 jev_integration_evaluator/integrations/composite_console.py
350+
b44a504c274df612ecd5cd06d44dcc1cd9f56dc882a50c3d4257aa70235a4f75 jev_integration_evaluator/integrations/composite_console.py
351351
44f24d63538a0385b0a66b8283e3db96638c68b9e8da29236c58415f4d6bc1af jev_integration_evaluator/integrations/contracts.py
352352
9e64379f4f9586beb539bad8f5f54be6e856ce79ccdb772d73d175d33e5c2219 jev_integration_evaluator/integrations/errors.py
353353
21aa34d26c10bdc024725d5f60c67d61a34986b9f824371339eea3a9d8a0e5b4 jev_integration_evaluator/integrations/host.py
@@ -433,7 +433,7 @@ cbbd2a92eeb685c0e859746fd8ebc40fd8bfaa9fb2901d6cf79a31f183ed4517 references/arc
433433
349fe248157cd4882e6621939bfc28dc9edecb54e3397d0705dacc5eeea48db4 references/composite-transactions-v1.md
434434
fdd82ced94ade58abbff02589b21a318670711dabb276b544e12726b70554614 references/confidence-and-calibration.md
435435
9fb76e904994c7f8c9fa96e45c37d4c8b4fc67ae9e5996c98ea8e140e850724f references/connected-composite-binding-v1.md
436-
9b5dcfb7a829ef86d41404b09b27ba29629240ee7cf4b78c28de76e5f76191aa references/connected-delivery-v1.md
436+
d2f2e07bc361e731f639978ec0259ce9652db93f01ff10551f9778b4824b9870 references/connected-delivery-v1.md
437437
6d0d3a9f92c643123cf3c577a13a94bffe9a011515688db40ddb9f5067a835b5 references/connected-installed-binding-v1.md
438438
313892a92e30412b83466577dcc05e4437e26fd53e735787de3e3c8dcedcefad references/data-contracts.md
439439
20c354b1b84ad6e079a49ce8098f261411cd469ce7176afa0297762a1d5b2b09 references/executable-implementation-prompt.md
@@ -734,7 +734,7 @@ e6c21c61a0652ea348ca1fa72c3e2d2b0df4c29f2d2b31aa101cb2e7b5473a5d tests/independ
734734
0f1663c62c614bb5053fbcc0175760889391326bd56f808f02ecd8babea0ef17 tests/independent_hosts/registered_alpha_connected/pyproject.toml
735735
f3fa3e10a9c233224f399aece5d60bfe4ce2f6aec96043f97b7633c8d44e38a1 tests/independent_hosts/registered_alpha_connected/qualification.py
736736
ee3d08a82f10edefbf1cc563dbffecf18772db62fbd82d4bee5ad8a9425c371a tests/independent_hosts/registered_alpha_connected/src/registered_alpha/__init__.py
737-
da82b6ea432a108fbb6788a5532bcb881a993003d84748d5dab6da3034353a75 tests/independent_hosts/registered_alpha_connected/src/registered_alpha/connected_authority.py
737+
4fb1808ec5690dd70d742a4302c9466a46bc0b39edf892477e6bb20e2a53f18b tests/independent_hosts/registered_alpha_connected/src/registered_alpha/connected_authority.py
738738
19f152bfa720de7ab3baa9c6db24c000f9058904bec741a3a5f19fc8dd08f7c7 tests/independent_hosts/registered_alpha_connected/src/registered_alpha/console.py
739739
097d23c5ce68b53c59038fb8ac195744d8ab9adafa2bdf1ce1939ed91a67d4e5 tests/independent_hosts/registered_alpha_connected/src/registered_alpha/host.py
740740
21ac598980a951f6b4e0f098bc1756ccfffbbe7e8c12d36a228c8381ca0c013b tests/independent_hosts/registered_alpha_connected/src/registered_alpha/requirements.lock
@@ -760,19 +760,19 @@ ec04a01d497f35f10d51607b636023bc2b1f622e87bc6b7fe99de300adc02d32 tests/independ
760760
0c1f169e847504851b588cac189b805f24b317288411ca9699b16cbf41ea0252 tests/independent_hosts/registered_dual/src/registered_dual/runtime.json
761761
db2a51bd2751a1dcfff052104ccec28c369cba6f59d73f2508ee218c5bc0bf87 tests/independent_hosts/registered_dual/src/registered_dual/work_queue.py
762762
79e112487ac189e9096a336389c0098bad12fb142bf99391aa79e23eef01752b tests/independent_hosts/registered_dual_connected/README.md
763-
315992087b921c8c1965eac76a5dba3eb167e14df172138b3d8d17ca55a6a689 tests/independent_hosts/registered_dual_connected/installed_journey.py
763+
eb972e1f25f67c5adf0d824166a1723a49ab138b50952ab1312e0996d0270cad tests/independent_hosts/registered_dual_connected/installed_journey.py
764764
23570482720c6a32ac0480b678458d2ec96b6419f879b5304cca91696a52c77e tests/independent_hosts/registered_dual_connected/oracle-v1.json
765765
6bae5f8680ae5b2cf054431e177ce22a94c5e13770187497c0df7044db7e574f tests/independent_hosts/registered_dual_connected/pyproject.toml
766766
f9549b9f69acb69d8c7f72fb323131d3218051722e1ee706e406795b86a69f55 tests/independent_hosts/registered_dual_connected/qualification.py
767-
97f1402c1b152a36f03d38fb5fb54f16acbaa3c841c11e030dbb8b407ecda6fa tests/independent_hosts/registered_dual_connected/review-v1.json
767+
6c601061db97483454c86dcadba98c18315fab6f54b7b80a354a70ab6f711980 tests/independent_hosts/registered_dual_connected/review-v1.json
768768
ee3d08a82f10edefbf1cc563dbffecf18772db62fbd82d4bee5ad8a9425c371a tests/independent_hosts/registered_dual_connected/src/registered_dual/__init__.py
769769
ec04a01d497f35f10d51607b636023bc2b1f622e87bc6b7fe99de300adc02d32 tests/independent_hosts/registered_dual_connected/src/registered_dual/alpha.py
770-
6d78e48d8991c5e93878451a1491b93737f7fab2b1a9493f37fd3a23e126704c tests/independent_hosts/registered_dual_connected/src/registered_dual/connected_authority.py
770+
406cec77bbe986efbada92d1f7385042b43714f2f9fcc1dab88015905be67a68 tests/independent_hosts/registered_dual_connected/src/registered_dual/connected_authority.py
771771
bf3516e197d2ca6cc90514edd663125d0593003c274185d60b0f3e94e47c1dd9 tests/independent_hosts/registered_dual_connected/src/registered_dual/console.py
772772
21ac598980a951f6b4e0f098bc1756ccfffbbe7e8c12d36a228c8381ca0c013b tests/independent_hosts/registered_dual_connected/src/registered_dual/requirements.lock
773773
0c1f169e847504851b588cac189b805f24b317288411ca9699b16cbf41ea0252 tests/independent_hosts/registered_dual_connected/src/registered_dual/runtime.json
774774
db2a51bd2751a1dcfff052104ccec28c369cba6f59d73f2508ee218c5bc0bf87 tests/independent_hosts/registered_dual_connected/src/registered_dual/work_queue.py
775-
60b178c3d7990e6ad93e77fc65b43f98493f60b6d1f67769ecaa15c85b7c5081 tests/independent_hosts/retrieval_connected/connected_authority.py
775+
aeec52d48062081b56fc632c23433737c8b5a490089b1095520e4a9074d0805e tests/independent_hosts/retrieval_connected/connected_authority.py
776776
6a542d2d11f307325a14f48eaa03fe2a9cb0c6b94dae326bbdf73e132586260e tests/independent_hosts/work_queue/README.md
777777
8b2233fa32fefe9418faa8ba9e1c493b0e59aea7313ef0a56b63a26d990d2e3c tests/independent_hosts/work_queue/installed_journey.py
778778
e38588c30eb9edcc34403b895c89f66303837583f46bd315c62cca0f425ec3ba tests/independent_hosts/work_queue/oracle-v1.json
@@ -830,6 +830,7 @@ f15e9b55163998541e8d762c36f383cba0395bf818d45871da19c26856e1c8e0 tests/test_cod
830830
4845bc21ff445511473bcd900c600f9e747b2a5ab885feb08bf5aaab341c265c tests/test_composite_transaction.py
831831
b93acf12f8ac02c948c571145b116e22c4e6d00cb8153e9fef944b710ae3939f tests/test_connected_composite_binding.py
832832
479d9941524bba37648624ce0f7e8b68ee5578c7a691ba3cc30456d090052aa5 tests/test_connected_installed_binding.py
833+
a2c0298d270a217a1b4d3c0960fd7b3150e7272aace6b953f475031e9464806a tests/test_connected_loader_public_keys.py
833834
973e8f663cc4ae78d4a7424405312b6afa64e83b6b65e15c94771db95c7e42ae tests/test_executable_cli.py
834835
edece8e52e538e46845243ab38c84c36f7b0b2b3938134bf025a1ca872ea2dfa tests/test_executable_command_receipts.py
835836
a466a3c93172360d797b6becbc9f376fc28966fd8fefa3205bf0397af94139ef tests/test_executable_failure_receipts.py

‎jev_integration_evaluator/data/use-case-template-matrix-v1.json‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
"root": "tests/independent_hosts/registered_alpha_connected",
1414
"host_sha256": "097d23c5ce68b53c59038fb8ac195744d8ab9adafa2bdf1ce1939ed91a67d4e5",
1515
"console_sha256": "19f152bfa720de7ab3baa9c6db24c000f9058904bec741a3a5f19fc8dd08f7c7",
16-
"loader_sha256": "da82b6ea432a108fbb6788a5532bcb881a993003d84748d5dab6da3034353a75",
16+
"loader_sha256": "4fb1808ec5690dd70d742a4302c9466a46bc0b39edf892477e6bb20e2a53f18b",
1717
"project_sha256": "0f1663c62c614bb5053fbcc0175760889391326bd56f808f02ecd8babea0ef17",
1818
"installed_execution": "qualified_offline_connected_shadow_startup_protocol",
1919
"provider": "unobserved",
@@ -30,7 +30,7 @@
3030
"JEV-EDF19BDB65F0": {"file": "src/registered_dual/alpha.py", "sha256": "ec04a01d497f35f10d51607b636023bc2b1f622e87bc6b7fe99de300adc02d32"}
3131
},
3232
"console_sha256": "bf3516e197d2ca6cc90514edd663125d0593003c274185d60b0f3e94e47c1dd9",
33-
"loader_sha256": "6d78e48d8991c5e93878451a1491b93737f7fab2b1a9493f37fd3a23e126704c",
33+
"loader_sha256": "406cec77bbe986efbada92d1f7385042b43714f2f9fcc1dab88015905be67a68",
3434
"project_sha256": "6bae5f8680ae5b2cf054431e177ce22a94c5e13770187497c0df7044db7e574f",
3535
"installed_execution": "qualified_offline_connected_dual_shadow_protocol",
3636
"provider": "unobserved",

‎jev_integration_evaluator/integrations/composite_console.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ def render_composite_console(root: Path, selection: dict, specs: dict) -> tuple[
8686
'bf3516e197d2ca6cc90514edd663125d0593003c274185d60b0f3e94e47c1dd9'
8787
and loader_anchored
8888
and hashlib.sha256(loader.read_bytes()).hexdigest() ==
89-
'6d78e48d8991c5e93878451a1491b93737f7fab2b1a9493f37fd3a23e126704c')
89+
'406cec77bbe986efbada92d1f7385042b43714f2f9fcc1dab88015905be67a68')
9090
entry = _function(tree, first['function'], 0)
9191
_function(tree, 'observe_composite_runtime', 3)
9292
statement = entry.body[-1]

‎references/connected-delivery-v1.md‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,13 @@ and then stops each session through an exact scope. It does not establish a
2424
real provider, combined observed canary/active gate, connected upgrade or
2525
rollback, or measured benefit.
2626

27+
The reviewed Linux Alpha, retrieval D and dual loaders accept only an anchored
28+
public-only P-256 key. Before deriving environment evidence or checking a grant,
29+
they inspect the exact pinned PEM bytes with fixed trusted OpenSSL 3 tooling.
30+
RSA, other EC curves, private-key PEM and inspection failures are rejected;
31+
a valid signature from another algorithm does not satisfy this profile. Source
32+
and loader pin changes require fresh bindings and installed receipts.
33+
2734
The source application, modified verification, offline wheel build, and
2835
installation follow [the package profile](template-installation-v1.md). The
2936
read-only `template connected-installed-bind` step then recomputes wheel RECORD,
@@ -43,7 +50,7 @@ and child launch environment. The private issuer key never enters the child,
4350
wheel, source or committed fixture. The loader checks owner/mode/link count,
4451
verifies signatures with fixed `/usr/bin/openssl` argv and a clean OpenSSL 3
4552
environment, and recomputes the verifier's binary hash/version and runtime
46-
facts before each route. A changed public key or verifier needs a new reviewed
53+
facts before each route. Signature verification rehashes the exact anchored public PEM snapshot and supplies it through an owned temporary-file descriptor; OpenSSL never reopens the public key pathname after validation. Local replacement-race tests use independently signed foreign keys and retain the original failing outcomes. A changed public key or verifier needs a new reviewed
4754
plan and issuer signature. Secret values and raw prompts do not belong in
4855
plans, scopes or reports.
4956

‎tests/independent_hosts/registered_alpha_connected/src/registered_alpha/connected_authority.py‎

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,25 @@ def _public_key() -> Path:
4949
or any(character not in '0123456789abcdef' for character in expected)):
5050
raise RuntimeError('connected_public_key_unanchored')
5151
key = _private_file(reference, maximum=4096)
52-
if hashlib.sha256(key.read_bytes()).hexdigest() != expected:
52+
pem = key.read_bytes()
53+
if hashlib.sha256(pem).hexdigest() != expected:
5354
raise RuntimeError('connected_public_key_changed')
55+
if (not pem.startswith(b'-----BEGIN PUBLIC KEY-----\n')
56+
or b'PRIVATE KEY' in pem):
57+
raise RuntimeError('connected_public_key_invalid')
58+
# Inspect the exact anchored bytes, using the same fixed trusted verifier.
59+
# A valid signature from another algorithm does not satisfy this profile.
60+
_openssl_identity()
61+
try:
62+
inspected = subprocess.run([str(OPENSSL), 'pkey', '-pubin', '-text', '-noout'],
63+
input=pem, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL,
64+
timeout=2, env=OPENSSL_ENV, check=False)
65+
except (OSError, subprocess.TimeoutExpired):
66+
raise RuntimeError('connected_public_key_invalid') from None
67+
if (inspected.returncode != 0 or len(inspected.stdout) > 4096
68+
or b'Public-Key: (256 bit)' not in inspected.stdout
69+
or b'ASN1 OID: prime256v1' not in inspected.stdout):
70+
raise RuntimeError('connected_public_key_invalid')
5471
return key
5572

5673

@@ -134,16 +151,22 @@ def verify_authority(kind: str, exact_digest: str) -> bool:
134151
try:
135152
if (_public_key() != key_file or _openssl_identity() != verifier_identity):
136153
return False
154+
public_pem = key_file.read_bytes()
155+
if hashlib.sha256(public_pem).hexdigest() != os.environ.get('REGISTERED_ALPHA_AUTH_PUBKEY_SHA256'):
156+
return False
137157
raw = base64.b64decode(signature, validate=True)
138-
with tempfile.TemporaryFile(mode='w+b') as signature_file:
158+
with (tempfile.TemporaryFile(mode='w+b') as signature_file,
159+
tempfile.TemporaryFile(mode='w+b') as public_file):
139160
signature_file.write(raw)
140161
signature_file.flush()
162+
public_file.write(public_pem)
163+
public_file.flush()
141164
verification = subprocess.run(
142-
[str(OPENSSL), 'dgst', '-sha256', '-verify', str(key_file),
165+
[str(OPENSSL), 'dgst', '-sha256', '-verify', f'/proc/self/fd/{public_file.fileno()}',
143166
'-signature', f'/proc/self/fd/{signature_file.fileno()}'],
144167
input=(kind + ':' + exact_digest).encode('ascii'),
145168
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL,
146-
pass_fds=(signature_file.fileno(),), timeout=2,
169+
pass_fds=(signature_file.fileno(), public_file.fileno()), timeout=2,
147170
env=OPENSSL_ENV, check=False)
148171
return verification.returncode == 0
149172
except (OSError, ValueError, RuntimeError, subprocess.TimeoutExpired):

‎tests/independent_hosts/registered_dual_connected/installed_journey.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
_qualification = importlib.util.module_from_spec(_spec)
3434
_spec.loader.exec_module(_qualification)
3535
ROOT = _qualification.ROOT
36-
FROZEN_REVIEW_SHA256 = '97f1402c1b152a36f03d38fb5fb54f16acbaa3c841c11e030dbb8b407ecda6fa'
36+
FROZEN_REVIEW_SHA256 = '6c601061db97483454c86dcadba98c18315fab6f54b7b80a354a70ab6f711980'
3737
FROZEN_ORACLE_SHA256 = '23570482720c6a32ac0480b678458d2ec96b6419f879b5304cca91696a52c77e'
3838

3939

‎tests/independent_hosts/registered_dual_connected/review-v1.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
"pyproject.toml": "6bae5f8680ae5b2cf054431e177ce22a94c5e13770187497c0df7044db7e574f",
2020
"src/registered_dual/__init__.py": "ee3d08a82f10edefbf1cc563dbffecf18772db62fbd82d4bee5ad8a9425c371a",
2121
"src/registered_dual/alpha.py": "ec04a01d497f35f10d51607b636023bc2b1f622e87bc6b7fe99de300adc02d32",
22-
"src/registered_dual/connected_authority.py": "6d78e48d8991c5e93878451a1491b93737f7fab2b1a9493f37fd3a23e126704c",
22+
"src/registered_dual/connected_authority.py": "406cec77bbe986efbada92d1f7385042b43714f2f9fcc1dab88015905be67a68",
2323
"src/registered_dual/console.py": "bf3516e197d2ca6cc90514edd663125d0593003c274185d60b0f3e94e47c1dd9",
2424
"src/registered_dual/requirements.lock": "21ac598980a951f6b4e0f098bc1756ccfffbbe7e8c12d36a228c8381ca0c013b",
2525
"src/registered_dual/runtime.json": "0c1f169e847504851b588cac189b805f24b317288411ca9699b16cbf41ea0252",

‎tests/independent_hosts/registered_dual_connected/src/registered_dual/connected_authority.py‎

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,25 @@ def _public_key() -> Path:
4949
or any(character not in '0123456789abcdef' for character in expected)):
5050
raise RuntimeError('connected_public_key_unanchored')
5151
key = _private_file(reference, maximum=4096)
52-
if hashlib.sha256(key.read_bytes()).hexdigest() != expected:
52+
pem = key.read_bytes()
53+
if hashlib.sha256(pem).hexdigest() != expected:
5354
raise RuntimeError('connected_public_key_changed')
55+
if (not pem.startswith(b'-----BEGIN PUBLIC KEY-----\n')
56+
or b'PRIVATE KEY' in pem):
57+
raise RuntimeError('connected_public_key_invalid')
58+
# Inspect the exact anchored bytes, using the same fixed trusted verifier.
59+
# A valid signature from another algorithm does not satisfy this profile.
60+
_openssl_identity()
61+
try:
62+
inspected = subprocess.run([str(OPENSSL), 'pkey', '-pubin', '-text', '-noout'],
63+
input=pem, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL,
64+
timeout=2, env=OPENSSL_ENV, check=False)
65+
except (OSError, subprocess.TimeoutExpired):
66+
raise RuntimeError('connected_public_key_invalid') from None
67+
if (inspected.returncode != 0 or len(inspected.stdout) > 4096
68+
or b'Public-Key: (256 bit)' not in inspected.stdout
69+
or b'ASN1 OID: prime256v1' not in inspected.stdout):
70+
raise RuntimeError('connected_public_key_invalid')
5471
return key
5572

5673

@@ -134,16 +151,22 @@ def verify_authority(kind: str, exact_digest: str) -> bool:
134151
try:
135152
if (_public_key() != key_file or _openssl_identity() != verifier_identity):
136153
return False
154+
public_pem = key_file.read_bytes()
155+
if hashlib.sha256(public_pem).hexdigest() != os.environ.get('REGISTERED_DUAL_AUTH_PUBKEY_SHA256'):
156+
return False
137157
raw = base64.b64decode(signature, validate=True)
138-
with tempfile.TemporaryFile(mode='w+b') as signature_file:
158+
with (tempfile.TemporaryFile(mode='w+b') as signature_file,
159+
tempfile.TemporaryFile(mode='w+b') as public_file):
139160
signature_file.write(raw)
140161
signature_file.flush()
162+
public_file.write(public_pem)
163+
public_file.flush()
141164
verification = subprocess.run(
142-
[str(OPENSSL), 'dgst', '-sha256', '-verify', str(key_file),
165+
[str(OPENSSL), 'dgst', '-sha256', '-verify', f'/proc/self/fd/{public_file.fileno()}',
143166
'-signature', f'/proc/self/fd/{signature_file.fileno()}'],
144167
input=(kind + ':' + exact_digest).encode('ascii'),
145168
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL,
146-
pass_fds=(signature_file.fileno(),), timeout=2,
169+
pass_fds=(signature_file.fileno(), public_file.fileno()), timeout=2,
147170
env=OPENSSL_ENV, check=False)
148171
return verification.returncode == 0
149172
except (OSError, ValueError, RuntimeError, subprocess.TimeoutExpired):

0 commit comments

Comments
 (0)