FA-76611 / Email MIME structure / Open access
Validate the structure of a multipart/signed entity: exact part count · case 01
A signed entity with a third, unsigned part is accepted, letting content ride along outside the signature.
ROOT CAUSE
The exact part count decision evaluates `if len(parts) < 2:` where the contract requires `if len(parts) != 2:`.
VERIFIED REPAIR
Use `if len(parts) != 2:` for the exact part count decision and keep every other rule of the model unchanged.
Unsuccessful approach: Rejecting only a repeated signature part still accepts other trailing parts. The attempted `if len(parts) < 2 or (len(parts) > 2 and parts[2]['type'].lower() == proto):` still disagrees with a fixture.
Case contract
Parameter names are case-insensitive. Findings, in order: not-signed (and stop) unless type is multipart/signed; missing-protocol; part-count (and stop) unless exactly two parts; protocol-mismatch when a protocol exists and the second part's type differs from it (case-insensitive); missing-micalg, or micalg-mismatch when a protocol exists and the micalg family disagrees (pgp-* exactly when the protocol is application/pgp-signature); unprotected-8bit when the signed first part uses 8bit or binary transfer encoding.
Why this case matters
Signed mail is only verifiable when its structure is exact; lax checks accept tampered or unverifiable messages.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(node):
if node['type'].lower() != 'multipart/signed':
return ['not-signed']
issues = []
params = {k.lower(): v for k, v in node.get('params', {}).items()}
proto = (params.get('protocol') or '').lower()
if not proto:
issues.append('missing-protocol')
parts = node.get('parts', [])
if len(parts) < 2:
issues.append('part-count')
return issues
if proto and parts[1]['type'].lower() != proto:
issues.append('protocol-mismatch')
micalg = (params.get('micalg') or '').lower()
if not micalg:
issues.append('missing-micalg')
elif proto and micalg.startswith('pgp-') != (proto == 'application/pgp-signature'):
issues.append('micalg-mismatch')
if (parts[0].get('cte') or '7bit').lower() in ('8bit', 'binary'):
issues.append('unprotected-8bit')
return issues
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
_CASES = {1: [('mixed-case parameter names', ({'type': 'multipart/signed', 'params': {'Protocol': 'application/pgp-signature', 'MICALG': 'pgp-sha256'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/pgp-signature'}]},), []), ('extra third part', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pgp-signature', 'micalg': 'pgp-sha256'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/pgp-signature'}, {'type': 'image/png'}]},), ['part-count']), ('mixed-case protocol and part type', ({'type': 'multipart/signed', 'params': {'protocol': 'Application/pgp-signature', 'micalg': 'pgp-sha512'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/PGP-signature'}]},), []), ('S/MIME signature', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pkcs7-signature', 'micalg': 'sha-256'}, 'parts': [{'type': 'multipart/mixed'}, {'type': 'application/pkcs7-signature'}]},), []), ('cross-family micalg', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pgp-signature', 'micalg': 'sha-256'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/pgp-signature'}]},), ['micalg-mismatch']), ('8bit signed content', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pgp-signature', 'micalg': 'pgp-sha256'}, 'parts': [{'type': 'text/plain', 'cte': '8bit'}, {'type': 'application/pgp-signature'}]},), ['unprotected-8bit']), ('binary signed content', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pgp-signature', 'micalg': 'pgp-sha256'}, 'parts': [{'type': 'text/plain', 'cte': 'BINARY'}, {'type': 'application/pgp-signature'}]},), ['unprotected-8bit']), ('missing protocol with S/MIME part', ({'type': 'multipart/signed', 'params': {'micalg': 'sha-256'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/pkcs7-signature'}]},), ['missing-protocol']), ('not signed', ({'type': 'multipart/mixed', 'parts': []},), ['not-signed'])], 2: [('mixed-case parameter names', ({'type': 'multipart/signed', 'params': {'Protocol': 'application/pgp-signature', 'MICALG': 'pgp-sha512'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/pgp-signature'}]},), []), ('extra third part', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pgp-signature', 'micalg': 'pgp-sha256'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/pgp-signature'}, {'type': 'image/png'}]},), ['part-count']), ('mixed-case protocol and part type', ({'type': 'multipart/signed', 'params': {'protocol': 'Application/pgp-signature', 'micalg': 'pgp-sha512'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/PGP-signature'}]},), []), ('S/MIME signature', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pkcs7-signature', 'micalg': 'sha-256'}, 'parts': [{'type': 'multipart/mixed'}, {'type': 'application/pkcs7-signature'}]},), []), ('cross-family micalg', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pgp-signature', 'micalg': 'sha-256'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/pgp-signature'}]},), ['micalg-mismatch']), ('8bit signed content', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pgp-signature', 'micalg': 'pgp-sha256'}, 'parts': [{'type': 'text/plain', 'cte': '8bit'}, {'type': 'application/pgp-signature'}]},), ['unprotected-8bit']), ('binary signed content', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pgp-signature', 'micalg': 'pgp-sha256'}, 'parts': [{'type': 'text/plain', 'cte': 'BINARY'}, {'type': 'application/pgp-signature'}]},), ['unprotected-8bit']), ('missing protocol with S/MIME part', ({'type': 'multipart/signed', 'params': {'micalg': 'sha-256'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/pkcs7-signature'}]},), ['missing-protocol']), ('not signed', ({'type': 'multipart/mixed', 'parts': []},), ['not-signed'])], 3: [('mixed-case parameter names', ({'type': 'multipart/signed', 'params': {'Protocol': 'application/pgp-signature', 'MICALG': 'pgp-sha128'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/pgp-signature'}]},), []), ('extra third part', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pgp-signature', 'micalg': 'pgp-sha256'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/pgp-signature'}, {'type': 'image/png'}]},), ['part-count']), ('mixed-case protocol and part type', ({'type': 'multipart/signed', 'params': {'protocol': 'Application/pgp-signature', 'micalg': 'pgp-sha512'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/PGP-signature'}]},), []), ('S/MIME signature', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pkcs7-signature', 'micalg': 'sha-256'}, 'parts': [{'type': 'multipart/mixed'}, {'type': 'application/pkcs7-signature'}]},), []), ('cross-family micalg', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pgp-signature', 'micalg': 'sha-256'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/pgp-signature'}]},), ['micalg-mismatch']), ('8bit signed content', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pgp-signature', 'micalg': 'pgp-sha256'}, 'parts': [{'type': 'text/plain', 'cte': '8bit'}, {'type': 'application/pgp-signature'}]},), ['unprotected-8bit']), ('binary signed content', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pgp-signature', 'micalg': 'pgp-sha256'}, 'parts': [{'type': 'text/plain', 'cte': 'BINARY'}, {'type': 'application/pgp-signature'}]},), ['unprotected-8bit']), ('missing protocol with S/MIME part', ({'type': 'multipart/signed', 'params': {'micalg': 'sha-256'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/pkcs7-signature'}]},), ['missing-protocol']), ('not signed', ({'type': 'multipart/mixed', 'parts': []},), ['not-signed'])], 4: [('mixed-case parameter names', ({'type': 'multipart/signed', 'params': {'Protocol': 'application/pgp-signature', 'MICALG': 'pgp-sha256'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/pgp-signature'}]},), []), ('extra third part', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pgp-signature', 'micalg': 'pgp-sha256'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/pgp-signature'}, {'type': 'image/png'}]},), ['part-count']), ('mixed-case protocol and part type', ({'type': 'multipart/signed', 'params': {'protocol': 'Application/pgp-signature', 'micalg': 'pgp-sha512'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/PGP-signature'}]},), []), ('S/MIME signature', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pkcs7-signature', 'micalg': 'sha-256'}, 'parts': [{'type': 'multipart/mixed'}, {'type': 'application/pkcs7-signature'}]},), []), ('cross-family micalg', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pgp-signature', 'micalg': 'sha-256'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/pgp-signature'}]},), ['micalg-mismatch']), ('8bit signed content', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pgp-signature', 'micalg': 'pgp-sha256'}, 'parts': [{'type': 'text/plain', 'cte': '8bit'}, {'type': 'application/pgp-signature'}]},), ['unprotected-8bit']), ('binary signed content', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pgp-signature', 'micalg': 'pgp-sha256'}, 'parts': [{'type': 'text/plain', 'cte': 'BINARY'}, {'type': 'application/pgp-signature'}]},), ['unprotected-8bit']), ('missing protocol with S/MIME part', ({'type': 'multipart/signed', 'params': {'micalg': 'sha-256'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/pkcs7-signature'}]},), ['missing-protocol']), ('not signed', ({'type': 'multipart/mixed', 'parts': []},), ['not-signed'])], 5: [('mixed-case parameter names', ({'type': 'multipart/signed', 'params': {'Protocol': 'application/pgp-signature', 'MICALG': 'pgp-sha512'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/pgp-signature'}]},), []), ('extra third part', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pgp-signature', 'micalg': 'pgp-sha256'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/pgp-signature'}, {'type': 'image/png'}]},), ['part-count']), ('mixed-case protocol and part type', ({'type': 'multipart/signed', 'params': {'protocol': 'Application/pgp-signature', 'micalg': 'pgp-sha512'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/PGP-signature'}]},), []), ('S/MIME signature', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pkcs7-signature', 'micalg': 'sha-256'}, 'parts': [{'type': 'multipart/mixed'}, {'type': 'application/pkcs7-signature'}]},), []), ('cross-family micalg', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pgp-signature', 'micalg': 'sha-256'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/pgp-signature'}]},), ['micalg-mismatch']), ('8bit signed content', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pgp-signature', 'micalg': 'pgp-sha256'}, 'parts': [{'type': 'text/plain', 'cte': '8bit'}, {'type': 'application/pgp-signature'}]},), ['unprotected-8bit']), ('binary signed content', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pgp-signature', 'micalg': 'pgp-sha256'}, 'parts': [{'type': 'text/plain', 'cte': 'BINARY'}, {'type': 'application/pgp-signature'}]},), ['unprotected-8bit']), ('missing protocol with S/MIME part', ({'type': 'multipart/signed', 'params': {'micalg': 'sha-256'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/pkcs7-signature'}]},), ['missing-protocol']), ('not signed', ({'type': 'multipart/mixed', 'parts': []},), ['not-signed'])]}
for _label, _args, _expected in _CASES[N]:
check(_label, solve(*_args), _expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| mixed-case parameter names | [] | [] | Passed |
| extra third part | [] | ['part-count'] | Failed |
| mixed-case protocol and part type | [] | [] | Passed |
| S/MIME signature | [] | [] | Passed |
| cross-family micalg | ['micalg-mismatch'] | ['micalg-mismatch'] | Passed |
| 8bit signed content | ['unprotected-8bit'] | ['unprotected-8bit'] | Passed |
| binary signed content | ['unprotected-8bit'] | ['unprotected-8bit'] | Passed |
| missing protocol with S/MIME part | ['missing-protocol'] | ['missing-protocol'] | Passed |
| not signed | ['not-signed'] | ['not-signed'] | Passed |
SHA-256 / e636819a6152fa239735f3c5067d8151f2f3151fddd4ebc82b42bc836a4be934
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(node):
if node['type'].lower() != 'multipart/signed':
return ['not-signed']
issues = []
params = {k.lower(): v for k, v in node.get('params', {}).items()}
proto = (params.get('protocol') or '').lower()
if not proto:
issues.append('missing-protocol')
parts = node.get('parts', [])
if len(parts) < 2 or (len(parts) > 2 and parts[2]['type'].lower() == proto):
issues.append('part-count')
return issues
if proto and parts[1]['type'].lower() != proto:
issues.append('protocol-mismatch')
micalg = (params.get('micalg') or '').lower()
if not micalg:
issues.append('missing-micalg')
elif proto and micalg.startswith('pgp-') != (proto == 'application/pgp-signature'):
issues.append('micalg-mismatch')
if (parts[0].get('cte') or '7bit').lower() in ('8bit', 'binary'):
issues.append('unprotected-8bit')
return issues
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
_CASES = {1: [('mixed-case parameter names', ({'type': 'multipart/signed', 'params': {'Protocol': 'application/pgp-signature', 'MICALG': 'pgp-sha256'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/pgp-signature'}]},), []), ('extra third part', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pgp-signature', 'micalg': 'pgp-sha256'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/pgp-signature'}, {'type': 'image/png'}]},), ['part-count']), ('mixed-case protocol and part type', ({'type': 'multipart/signed', 'params': {'protocol': 'Application/pgp-signature', 'micalg': 'pgp-sha512'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/PGP-signature'}]},), []), ('S/MIME signature', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pkcs7-signature', 'micalg': 'sha-256'}, 'parts': [{'type': 'multipart/mixed'}, {'type': 'application/pkcs7-signature'}]},), []), ('cross-family micalg', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pgp-signature', 'micalg': 'sha-256'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/pgp-signature'}]},), ['micalg-mismatch']), ('8bit signed content', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pgp-signature', 'micalg': 'pgp-sha256'}, 'parts': [{'type': 'text/plain', 'cte': '8bit'}, {'type': 'application/pgp-signature'}]},), ['unprotected-8bit']), ('binary signed content', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pgp-signature', 'micalg': 'pgp-sha256'}, 'parts': [{'type': 'text/plain', 'cte': 'BINARY'}, {'type': 'application/pgp-signature'}]},), ['unprotected-8bit']), ('missing protocol with S/MIME part', ({'type': 'multipart/signed', 'params': {'micalg': 'sha-256'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/pkcs7-signature'}]},), ['missing-protocol']), ('not signed', ({'type': 'multipart/mixed', 'parts': []},), ['not-signed'])], 2: [('mixed-case parameter names', ({'type': 'multipart/signed', 'params': {'Protocol': 'application/pgp-signature', 'MICALG': 'pgp-sha512'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/pgp-signature'}]},), []), ('extra third part', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pgp-signature', 'micalg': 'pgp-sha256'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/pgp-signature'}, {'type': 'image/png'}]},), ['part-count']), ('mixed-case protocol and part type', ({'type': 'multipart/signed', 'params': {'protocol': 'Application/pgp-signature', 'micalg': 'pgp-sha512'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/PGP-signature'}]},), []), ('S/MIME signature', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pkcs7-signature', 'micalg': 'sha-256'}, 'parts': [{'type': 'multipart/mixed'}, {'type': 'application/pkcs7-signature'}]},), []), ('cross-family micalg', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pgp-signature', 'micalg': 'sha-256'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/pgp-signature'}]},), ['micalg-mismatch']), ('8bit signed content', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pgp-signature', 'micalg': 'pgp-sha256'}, 'parts': [{'type': 'text/plain', 'cte': '8bit'}, {'type': 'application/pgp-signature'}]},), ['unprotected-8bit']), ('binary signed content', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pgp-signature', 'micalg': 'pgp-sha256'}, 'parts': [{'type': 'text/plain', 'cte': 'BINARY'}, {'type': 'application/pgp-signature'}]},), ['unprotected-8bit']), ('missing protocol with S/MIME part', ({'type': 'multipart/signed', 'params': {'micalg': 'sha-256'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/pkcs7-signature'}]},), ['missing-protocol']), ('not signed', ({'type': 'multipart/mixed', 'parts': []},), ['not-signed'])], 3: [('mixed-case parameter names', ({'type': 'multipart/signed', 'params': {'Protocol': 'application/pgp-signature', 'MICALG': 'pgp-sha128'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/pgp-signature'}]},), []), ('extra third part', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pgp-signature', 'micalg': 'pgp-sha256'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/pgp-signature'}, {'type': 'image/png'}]},), ['part-count']), ('mixed-case protocol and part type', ({'type': 'multipart/signed', 'params': {'protocol': 'Application/pgp-signature', 'micalg': 'pgp-sha512'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/PGP-signature'}]},), []), ('S/MIME signature', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pkcs7-signature', 'micalg': 'sha-256'}, 'parts': [{'type': 'multipart/mixed'}, {'type': 'application/pkcs7-signature'}]},), []), ('cross-family micalg', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pgp-signature', 'micalg': 'sha-256'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/pgp-signature'}]},), ['micalg-mismatch']), ('8bit signed content', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pgp-signature', 'micalg': 'pgp-sha256'}, 'parts': [{'type': 'text/plain', 'cte': '8bit'}, {'type': 'application/pgp-signature'}]},), ['unprotected-8bit']), ('binary signed content', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pgp-signature', 'micalg': 'pgp-sha256'}, 'parts': [{'type': 'text/plain', 'cte': 'BINARY'}, {'type': 'application/pgp-signature'}]},), ['unprotected-8bit']), ('missing protocol with S/MIME part', ({'type': 'multipart/signed', 'params': {'micalg': 'sha-256'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/pkcs7-signature'}]},), ['missing-protocol']), ('not signed', ({'type': 'multipart/mixed', 'parts': []},), ['not-signed'])], 4: [('mixed-case parameter names', ({'type': 'multipart/signed', 'params': {'Protocol': 'application/pgp-signature', 'MICALG': 'pgp-sha256'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/pgp-signature'}]},), []), ('extra third part', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pgp-signature', 'micalg': 'pgp-sha256'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/pgp-signature'}, {'type': 'image/png'}]},), ['part-count']), ('mixed-case protocol and part type', ({'type': 'multipart/signed', 'params': {'protocol': 'Application/pgp-signature', 'micalg': 'pgp-sha512'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/PGP-signature'}]},), []), ('S/MIME signature', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pkcs7-signature', 'micalg': 'sha-256'}, 'parts': [{'type': 'multipart/mixed'}, {'type': 'application/pkcs7-signature'}]},), []), ('cross-family micalg', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pgp-signature', 'micalg': 'sha-256'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/pgp-signature'}]},), ['micalg-mismatch']), ('8bit signed content', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pgp-signature', 'micalg': 'pgp-sha256'}, 'parts': [{'type': 'text/plain', 'cte': '8bit'}, {'type': 'application/pgp-signature'}]},), ['unprotected-8bit']), ('binary signed content', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pgp-signature', 'micalg': 'pgp-sha256'}, 'parts': [{'type': 'text/plain', 'cte': 'BINARY'}, {'type': 'application/pgp-signature'}]},), ['unprotected-8bit']), ('missing protocol with S/MIME part', ({'type': 'multipart/signed', 'params': {'micalg': 'sha-256'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/pkcs7-signature'}]},), ['missing-protocol']), ('not signed', ({'type': 'multipart/mixed', 'parts': []},), ['not-signed'])], 5: [('mixed-case parameter names', ({'type': 'multipart/signed', 'params': {'Protocol': 'application/pgp-signature', 'MICALG': 'pgp-sha512'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/pgp-signature'}]},), []), ('extra third part', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pgp-signature', 'micalg': 'pgp-sha256'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/pgp-signature'}, {'type': 'image/png'}]},), ['part-count']), ('mixed-case protocol and part type', ({'type': 'multipart/signed', 'params': {'protocol': 'Application/pgp-signature', 'micalg': 'pgp-sha512'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/PGP-signature'}]},), []), ('S/MIME signature', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pkcs7-signature', 'micalg': 'sha-256'}, 'parts': [{'type': 'multipart/mixed'}, {'type': 'application/pkcs7-signature'}]},), []), ('cross-family micalg', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pgp-signature', 'micalg': 'sha-256'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/pgp-signature'}]},), ['micalg-mismatch']), ('8bit signed content', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pgp-signature', 'micalg': 'pgp-sha256'}, 'parts': [{'type': 'text/plain', 'cte': '8bit'}, {'type': 'application/pgp-signature'}]},), ['unprotected-8bit']), ('binary signed content', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pgp-signature', 'micalg': 'pgp-sha256'}, 'parts': [{'type': 'text/plain', 'cte': 'BINARY'}, {'type': 'application/pgp-signature'}]},), ['unprotected-8bit']), ('missing protocol with S/MIME part', ({'type': 'multipart/signed', 'params': {'micalg': 'sha-256'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/pkcs7-signature'}]},), ['missing-protocol']), ('not signed', ({'type': 'multipart/mixed', 'parts': []},), ['not-signed'])]}
for _label, _args, _expected in _CASES[N]:
check(_label, solve(*_args), _expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| mixed-case parameter names | [] | [] | Passed |
| extra third part | [] | ['part-count'] | Failed |
| mixed-case protocol and part type | [] | [] | Passed |
| S/MIME signature | [] | [] | Passed |
| cross-family micalg | ['micalg-mismatch'] | ['micalg-mismatch'] | Passed |
| 8bit signed content | ['unprotected-8bit'] | ['unprotected-8bit'] | Passed |
| binary signed content | ['unprotected-8bit'] | ['unprotected-8bit'] | Passed |
| missing protocol with S/MIME part | ['missing-protocol'] | ['missing-protocol'] | Passed |
| not signed | ['not-signed'] | ['not-signed'] | Passed |
SHA-256 / 1e18593aa6f7ae95735015bd552d4cf8417c21c0574cf93482c194f4c52cf874
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(node):
if node['type'].lower() != 'multipart/signed':
return ['not-signed']
issues = []
params = {k.lower(): v for k, v in node.get('params', {}).items()}
proto = (params.get('protocol') or '').lower()
if not proto:
issues.append('missing-protocol')
parts = node.get('parts', [])
if len(parts) != 2:
issues.append('part-count')
return issues
if proto and parts[1]['type'].lower() != proto:
issues.append('protocol-mismatch')
micalg = (params.get('micalg') or '').lower()
if not micalg:
issues.append('missing-micalg')
elif proto and micalg.startswith('pgp-') != (proto == 'application/pgp-signature'):
issues.append('micalg-mismatch')
if (parts[0].get('cte') or '7bit').lower() in ('8bit', 'binary'):
issues.append('unprotected-8bit')
return issues
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
_CASES = {1: [('mixed-case parameter names', ({'type': 'multipart/signed', 'params': {'Protocol': 'application/pgp-signature', 'MICALG': 'pgp-sha256'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/pgp-signature'}]},), []), ('extra third part', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pgp-signature', 'micalg': 'pgp-sha256'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/pgp-signature'}, {'type': 'image/png'}]},), ['part-count']), ('mixed-case protocol and part type', ({'type': 'multipart/signed', 'params': {'protocol': 'Application/pgp-signature', 'micalg': 'pgp-sha512'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/PGP-signature'}]},), []), ('S/MIME signature', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pkcs7-signature', 'micalg': 'sha-256'}, 'parts': [{'type': 'multipart/mixed'}, {'type': 'application/pkcs7-signature'}]},), []), ('cross-family micalg', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pgp-signature', 'micalg': 'sha-256'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/pgp-signature'}]},), ['micalg-mismatch']), ('8bit signed content', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pgp-signature', 'micalg': 'pgp-sha256'}, 'parts': [{'type': 'text/plain', 'cte': '8bit'}, {'type': 'application/pgp-signature'}]},), ['unprotected-8bit']), ('binary signed content', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pgp-signature', 'micalg': 'pgp-sha256'}, 'parts': [{'type': 'text/plain', 'cte': 'BINARY'}, {'type': 'application/pgp-signature'}]},), ['unprotected-8bit']), ('missing protocol with S/MIME part', ({'type': 'multipart/signed', 'params': {'micalg': 'sha-256'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/pkcs7-signature'}]},), ['missing-protocol']), ('not signed', ({'type': 'multipart/mixed', 'parts': []},), ['not-signed'])], 2: [('mixed-case parameter names', ({'type': 'multipart/signed', 'params': {'Protocol': 'application/pgp-signature', 'MICALG': 'pgp-sha512'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/pgp-signature'}]},), []), ('extra third part', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pgp-signature', 'micalg': 'pgp-sha256'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/pgp-signature'}, {'type': 'image/png'}]},), ['part-count']), ('mixed-case protocol and part type', ({'type': 'multipart/signed', 'params': {'protocol': 'Application/pgp-signature', 'micalg': 'pgp-sha512'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/PGP-signature'}]},), []), ('S/MIME signature', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pkcs7-signature', 'micalg': 'sha-256'}, 'parts': [{'type': 'multipart/mixed'}, {'type': 'application/pkcs7-signature'}]},), []), ('cross-family micalg', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pgp-signature', 'micalg': 'sha-256'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/pgp-signature'}]},), ['micalg-mismatch']), ('8bit signed content', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pgp-signature', 'micalg': 'pgp-sha256'}, 'parts': [{'type': 'text/plain', 'cte': '8bit'}, {'type': 'application/pgp-signature'}]},), ['unprotected-8bit']), ('binary signed content', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pgp-signature', 'micalg': 'pgp-sha256'}, 'parts': [{'type': 'text/plain', 'cte': 'BINARY'}, {'type': 'application/pgp-signature'}]},), ['unprotected-8bit']), ('missing protocol with S/MIME part', ({'type': 'multipart/signed', 'params': {'micalg': 'sha-256'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/pkcs7-signature'}]},), ['missing-protocol']), ('not signed', ({'type': 'multipart/mixed', 'parts': []},), ['not-signed'])], 3: [('mixed-case parameter names', ({'type': 'multipart/signed', 'params': {'Protocol': 'application/pgp-signature', 'MICALG': 'pgp-sha128'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/pgp-signature'}]},), []), ('extra third part', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pgp-signature', 'micalg': 'pgp-sha256'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/pgp-signature'}, {'type': 'image/png'}]},), ['part-count']), ('mixed-case protocol and part type', ({'type': 'multipart/signed', 'params': {'protocol': 'Application/pgp-signature', 'micalg': 'pgp-sha512'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/PGP-signature'}]},), []), ('S/MIME signature', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pkcs7-signature', 'micalg': 'sha-256'}, 'parts': [{'type': 'multipart/mixed'}, {'type': 'application/pkcs7-signature'}]},), []), ('cross-family micalg', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pgp-signature', 'micalg': 'sha-256'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/pgp-signature'}]},), ['micalg-mismatch']), ('8bit signed content', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pgp-signature', 'micalg': 'pgp-sha256'}, 'parts': [{'type': 'text/plain', 'cte': '8bit'}, {'type': 'application/pgp-signature'}]},), ['unprotected-8bit']), ('binary signed content', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pgp-signature', 'micalg': 'pgp-sha256'}, 'parts': [{'type': 'text/plain', 'cte': 'BINARY'}, {'type': 'application/pgp-signature'}]},), ['unprotected-8bit']), ('missing protocol with S/MIME part', ({'type': 'multipart/signed', 'params': {'micalg': 'sha-256'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/pkcs7-signature'}]},), ['missing-protocol']), ('not signed', ({'type': 'multipart/mixed', 'parts': []},), ['not-signed'])], 4: [('mixed-case parameter names', ({'type': 'multipart/signed', 'params': {'Protocol': 'application/pgp-signature', 'MICALG': 'pgp-sha256'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/pgp-signature'}]},), []), ('extra third part', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pgp-signature', 'micalg': 'pgp-sha256'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/pgp-signature'}, {'type': 'image/png'}]},), ['part-count']), ('mixed-case protocol and part type', ({'type': 'multipart/signed', 'params': {'protocol': 'Application/pgp-signature', 'micalg': 'pgp-sha512'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/PGP-signature'}]},), []), ('S/MIME signature', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pkcs7-signature', 'micalg': 'sha-256'}, 'parts': [{'type': 'multipart/mixed'}, {'type': 'application/pkcs7-signature'}]},), []), ('cross-family micalg', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pgp-signature', 'micalg': 'sha-256'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/pgp-signature'}]},), ['micalg-mismatch']), ('8bit signed content', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pgp-signature', 'micalg': 'pgp-sha256'}, 'parts': [{'type': 'text/plain', 'cte': '8bit'}, {'type': 'application/pgp-signature'}]},), ['unprotected-8bit']), ('binary signed content', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pgp-signature', 'micalg': 'pgp-sha256'}, 'parts': [{'type': 'text/plain', 'cte': 'BINARY'}, {'type': 'application/pgp-signature'}]},), ['unprotected-8bit']), ('missing protocol with S/MIME part', ({'type': 'multipart/signed', 'params': {'micalg': 'sha-256'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/pkcs7-signature'}]},), ['missing-protocol']), ('not signed', ({'type': 'multipart/mixed', 'parts': []},), ['not-signed'])], 5: [('mixed-case parameter names', ({'type': 'multipart/signed', 'params': {'Protocol': 'application/pgp-signature', 'MICALG': 'pgp-sha512'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/pgp-signature'}]},), []), ('extra third part', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pgp-signature', 'micalg': 'pgp-sha256'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/pgp-signature'}, {'type': 'image/png'}]},), ['part-count']), ('mixed-case protocol and part type', ({'type': 'multipart/signed', 'params': {'protocol': 'Application/pgp-signature', 'micalg': 'pgp-sha512'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/PGP-signature'}]},), []), ('S/MIME signature', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pkcs7-signature', 'micalg': 'sha-256'}, 'parts': [{'type': 'multipart/mixed'}, {'type': 'application/pkcs7-signature'}]},), []), ('cross-family micalg', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pgp-signature', 'micalg': 'sha-256'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/pgp-signature'}]},), ['micalg-mismatch']), ('8bit signed content', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pgp-signature', 'micalg': 'pgp-sha256'}, 'parts': [{'type': 'text/plain', 'cte': '8bit'}, {'type': 'application/pgp-signature'}]},), ['unprotected-8bit']), ('binary signed content', ({'type': 'multipart/signed', 'params': {'protocol': 'application/pgp-signature', 'micalg': 'pgp-sha256'}, 'parts': [{'type': 'text/plain', 'cte': 'BINARY'}, {'type': 'application/pgp-signature'}]},), ['unprotected-8bit']), ('missing protocol with S/MIME part', ({'type': 'multipart/signed', 'params': {'micalg': 'sha-256'}, 'parts': [{'type': 'text/plain'}, {'type': 'application/pkcs7-signature'}]},), ['missing-protocol']), ('not signed', ({'type': 'multipart/mixed', 'parts': []},), ['not-signed'])]}
for _label, _args, _expected in _CASES[N]:
check(_label, solve(*_args), _expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| mixed-case parameter names | [] | [] | Passed |
| extra third part | ['part-count'] | ['part-count'] | Passed |
| mixed-case protocol and part type | [] | [] | Passed |
| S/MIME signature | [] | [] | Passed |
| cross-family micalg | ['micalg-mismatch'] | ['micalg-mismatch'] | Passed |
| 8bit signed content | ['unprotected-8bit'] | ['unprotected-8bit'] | Passed |
| binary signed content | ['unprotected-8bit'] | ['unprotected-8bit'] | Passed |
| missing protocol with S/MIME part | ['missing-protocol'] | ['missing-protocol'] | Passed |
| not signed | ['not-signed'] | ['not-signed'] | Passed |
SHA-256 / 2a5d93fad294dc0b9ce96dca553f5c817a84b85ecfd8cddfd2cb3579b17d87a0
Verification & scope
Stipulated offline model over pre-parsed MIME dictionaries; not a conforming MIME parser, generator or mail client. This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.
Observations recorded using Python 3.12.14 at 2026-09-29T14:49:17.893285+00:00.
Case digest / e7f03b102f7bb0d69eb32fb8e5b823dd6fa63c0456e3f3fe50e4127b27d91457