Files
ESP32_Serial_Swiss_Army_Knife/tests/wolfssh_parser_contract/review.py
T
Commander1024 51f835c22f Harden SSH parsing and add notice tooling
- Enforce exact service and channel names with bounded failure parsing
- Add hash-pinned offline notice assembly and regression coverage
- Record advisory dispositions, provenance, integration evidence, and
  remaining gates
2026-09-16 15:06:38 +02:00

182 lines
8.9 KiB
Python

#!/usr/bin/env python3
"""Finite remaining-parser source/provenance contract; optional read-only profile replay."""
import hashlib
import json
import os
from pathlib import Path
import re
import shlex
import subprocess
import sys
sys.dont_write_bytecode = True
ROOT = Path(__file__).resolve().parents[2]
HERE = Path(__file__).resolve().parent
sys.path.insert(0, str(ROOT / 'tests/wolfssh_auth_contract'))
from run import extract
from security_overrides import ENTRIES, render_entry
# Independently specified delta against the reviewed original+ordering+parser
# baseline. Reversing precisely these bytes must recover its whole-source hash.
BASELINE_SHA = '4948f8c447670eb54153dd1f3db69e4fa3092f7d7f7ed58a18a8fa05fcd168ca'
NOTICE = '''/* Server parser review modified 2026-09-16: bounded CHANNEL_FAILURE
* and ssh-userauth service validation; PR899/902 subset, not full PRs.
* Local follow-up: exact bounded channel-request names.
* Provenance/limits: docs/ssh_parser_remaining_review.md.
*/
'''
SERVICE = ''' /* PR902 current-server subset: reject before publishing the transition.
* The owner closes on this error; no best-effort disconnect is queued. */
if (nameSz != sizeof("ssh-userauth") - 1 ||
WMEMCMP(serviceName, "ssh-userauth", sizeof("ssh-userauth") - 1) != 0)
return WS_INVALID_STATE_E;
'''
OLD_FAILURE = ''' if (ssh == NULL || buf == NULL || len != 0 || idx == NULL)
ret = WS_BAD_ARGUMENT;
if (ret == WS_SUCCESS)
ret = WS_CHANOPEN_FAILED;'''
NEW_FAILURE = ''' word32 begin, channelId;
if (ssh == NULL || buf == NULL || idx == NULL)
return WS_BAD_ARGUMENT;
begin = *idx;
ret = GetUint32(&channelId, buf, len, &begin);
if (ret != WS_SUCCESS)
return ret;
if (begin != len)
return WS_BUFFER_E;
if (ChannelFind(ssh, channelId, WS_CHANNEL_ID_SELF) == NULL)
return WS_INVALID_CHANID;
*idx = begin;
ret = WS_CHANOPEN_FAILED;'''
PINS = {
'tools/wolfssh_order/delta.json': '6a81376fe3ffc5f449cde105402963f52d2d78cc844153e869a7e1e0f734fb76',
'managed_components/wolfssl__wolfssl/wolfcrypt/src/signature.c': '62ab3db3dfd251b2a2c73b69ef05aab6085d2e0d673fd9159514b3ee261cea4f',
}
PATCHES = {
'899': ('d2eeec5e263a4821c90805963eeb0666e99868a6', 'e33c8b0aaa3c5a5d6c5201e6141cafd2383a1ed6931fea6655a9b757fbe0b0ce'),
'902': ('ffa646a4b9d47d5d9d6127db140c433c58b1e276', '4dc3a69f8cecb34f5091b9c22e0012ea6020b7ede9c1ab3de4d96264168c345a'),
'918': ('fd82a4bcf55935f0801b14bca6be9c71e32ae914', 'a2a59707086c6273a2c339e63db49846a5a1862c73924b60a845a03d7d41be41'),
'919': ('0317c40fc131fab952d291d43c56c7b7ce5f4303', '753fffea9925deeed4ddfc7aeba1fce0e950602b52ed1434bd817c2d48857b2f'),
}
def digest(data):
return hashlib.sha256(data).hexdigest()
def check_sources(original, generated):
assert digest(original.read_bytes()) == \
'81ff1f9166708abd5c2911e9fe57c0aee01c88b5d3f68c909ee8a856d37f36a9'
text = generated.decode()
prior = text
for new, old in ((NOTICE, ''), (SERVICE, ''), (NEW_FAILURE, OLD_FAILURE)):
assert prior.count(new) == 1, 'Independent delta anchor changed'
prior = prior.replace(new, old)
# Independent name list/format, never imported from the generator's edits.
for name in ('env', 'shell', 'exec', 'subsystem', 'pty-req', 'window-change',
'exit-status', 'exit-signal', 'auth-agent-req@openssh.com'):
new = (f'typeSz == sizeof("{name}") - 1 &&\n'
f' WMEMCMP(type, "{name}", sizeof("{name}") - 1) == 0')
old = f'WSTRNCMP(type, "{name}", typeSz) == 0'
assert prior.count(new) == 1, name
prior = prior.replace(new, old)
assert digest(prior.encode()) == BASELINE_SHA, 'Unreviewed generated-source delta'
assert extract(prior, 'DoChannelRequest') == extract(original.read_text(), 'DoChannelRequest')
for path, sha in PINS.items():
assert digest((ROOT / path).read_bytes()) == sha, path
provenance = json.loads((HERE / 'provenance.json').read_text())
assert set(provenance) == set(PATCHES)
for number, (commit, sha) in PATCHES.items():
data = (HERE / f'pr{number}.patch').read_bytes()
assert digest(data) == sha and data.startswith(f'From {commit} '.encode())
assert provenance[number] == {
'url': f'https://patch-diff.githubusercontent.com/raw/wolfSSL/wolfssh/pull/{number}.patch',
'commit_url': f'https://github.com/wolfSSL/wolfssh/commit/{commit}.patch',
'commit': commit, 'sha256': sha,
}
for name in ('ParseRSAPubKey', 'ParseECCPubKey', 'ParsePubKey', 'DoKexDhReply',
'DoChannelOpen', 'DoGlobalRequest',
'DoServiceAccept'):
# DoKexDhReply has an ordering delta, checked by the whole baseline pin.
if name != 'DoKexDhReply':
assert extract(text, name) == extract(original.read_text(), name), name
# SignHEcdsa has preprocessor-selected bodies after its signature; compare
# its complete region rather than using the single-body extractor.
start, end = 'static int SignHEcdsa(', 'static int SignH('
def signer_region(source):
begin = source.index(start)
return source[begin:source.index(end, begin)]
assert signer_region(text) == signer_region(original.read_text())
assert len(re.findall(r'\bParsePubKey\s*\(', text)) == 2
assert 'ParsePubKey(ssh, sigKeyBlock_ptr, pubKey, pubKeySz)' in extract(text, 'DoKexDhReply')
assert len(re.findall(r'\bParseECCPubKey\s*\(', text)) == 2
assert len(re.findall(r'\bParseRSAPubKey\s*\(', text)) == 2
packet = extract(text, 'DoPacket')
assert packet.index('IsMessageAllowed(ssh, msg, WS_MSG_RECV)') < packet.index('switch (msg)')
print('PASS: independent whole-source delta, unchanged ordering/client/request branch bodies, archived PR provenance')
return prior.encode()
def check_profile(generated, prior):
databases = list((ROOT / '.pio/build').glob('*/compile_commands.json'))
assert len(databases) == 1, 'Need one unambiguous production compile database'
entries = json.loads(databases[0].read_text())
matches = []
for entry in entries:
path = (Path(entry['directory']) / entry['file']).resolve()
assert path != ROOT / 'managed_components/wolfssl__wolfssh/src/internal.c'
if path.parts[-3:] == ('security_overrides', 'wolfssh_internal', 'internal.c'):
matches.append((entry, path))
assert len(matches) == 1
entry, path = matches[0]
actual = path.read_bytes()
assert actual in (generated, prior), 'Unreviewed production generated input'
args = entry.get('arguments') or shlex.split(entry['command'])
clean = []; skip = False
for arg in args:
if skip:
skip = False
elif arg in ('-o', '-MF', '-MT', '-MQ'):
skip = True
elif arg not in ('-c', '-MD', '-MMD', '-MP'):
clean.append(arg)
result = subprocess.run(clean + ['-E', '-dM'], cwd=entry['directory'],
capture_output=True, text=True, check=True, timeout=60,
env={**os.environ, 'CCACHE_DISABLE': '1'})
macros = dict(re.findall(r'^#define (\w+)(?: (.*))?$', result.stdout, re.M))
assert macros.get('LIBWOLFSSH_VERSION_HEX') == '0x01004020'
for name in ('WOLFSSH_FWD', 'WOLFSSH_AGENT', 'WOLFSSH_CERTS', 'WOLFSSH_SFTP',
'WOLFSSH_SCP', 'WOLFSSH_NO_ECDSA', 'WOLFSSH_NO_ED25519',
'NO_WOLFSSH_SERVER', 'NO_WOLFSSH_CLIENT', 'WOLFSSH_SHELL'):
assert name not in macros, name
for name in ('WOLFSSH_NO_RSA', 'WOLFSSH_NO_DH', 'WOLFSSL_VALIDATE_ECC_IMPORT',
'WOLFSSL_ECDHX_SHARED_NOT_ZERO', 'CURVE25519_SMALL', 'ED25519_SMALL',
'WOLFSSH_TERM'):
assert name in macros, name
# Compile the fresh source with the saved real target flags, without changing
# the production build tree or creating objects/dependency files.
import tempfile
with tempfile.TemporaryDirectory(prefix='ssh-parser-syntax-') as directory:
fresh = Path(directory) / 'internal.c'; fresh.write_bytes(generated)
syntax = [str(fresh) if (Path(entry['directory']) / arg).resolve() == path
else arg for arg in clean]
subprocess.run(syntax + ['-fsyntax-only'], cwd=entry['directory'], check=True,
timeout=60, env={**os.environ, 'CCACHE_DISABLE': '1'})
print('PASS: actual Xtensa profile + fresh generated source syntax (no objects/build regeneration)')
print('Production generated source:', 'current' if actual == generated else
'REVIEWED PRIOR BASELINE; regeneration/build still required')
if __name__ == '__main__':
assert sys.argv[1:] in ([], ['--profile'])
entry = next(e for e in ENTRIES if e.name == 'wolfssh_internal')
original, generated = render_entry(entry, {'project': ROOT})
prior = check_sources(original, generated)
print('Fresh generated SHA-256:', digest(generated))
if '--profile' in sys.argv:
check_profile(generated, prior)