Skip to content

Reference source · 0.1.0-dev.11

negative-conformance.md

docs/negative-conformance.md · Download original file

# Negative interoperability and mirror conformance

`0.1.0-dev.9` adds a shared synthetic rejection corpus. It tests a valid encrypted control before testing invalid messages, so a peer that rejects everything cannot pass. These local cases supplement existing tamper, authority, scope, expiry, queue, migration and subscription tests. They are not exhaustive fuzzing, an external certification or independent security review.

## Authenticated envelope corpus

The [test-only producer](../tests/helpers/adversarial.ts) deliberately constructs malformed protected headers, then computes genuine ML-KEM encapsulation, AES-GCM authentication and ML-DSA signature with the synthetic Host's legitimate keys. Most cases cannot be rejected merely because a signature was broken.

| Cases | Required result |
| --- | --- |
| Credential subject differs from signed `sender`; invalid message identifier; fractional timestamps | Reject binding or structural validation. |
| Lifetime exceeds 120 seconds; expired envelope; wrong recipient | Reject before application acceptance. |
| Unsupported suite; unsupported version; extra protected field | Reject without downgrade. |
| Duplicate protected JSON key | Reject ambiguous encoding. |
| Changed signature; padded/noncanonical base64url nonce | Reject integrity or byte profile. |

The Node tests run all twelve cases. The packaged Python and .NET peers independently open the same envelopes, including the sender-binding case without an application-supplied expected sender. Python now checks bounded integer timestamps and identifier syntax; .NET now compares the credential subject with the protected sender in the generic envelope verifier.

## Authenticated malformed pages

The shared harness lets the real Host process a valid requester message, then substitutes a fresh correctly signed/encrypted malformed response with the correct reply binding. Python/.NET durable mirrors must reject each response, clear their cached view across restart, deny even explicit stale reads and recover from a legitimate fresh baseline.

The seven mutations are a null event, a string `has_more`, a foreign Patient ID, a tombstone containing clinical content, an unknown event kind, a fractional resource version and an unsupported `DELAU` caching obligation. Mirrors validate page shape, supported types, positive safe integer versions, patient ownership, metadata and epoch, and minimal deletion representations before committing resources and cursor together.

Node source tests also reject negative baseline totals, invalid terminal page cursors, empty visibility epochs and wrong-patient staged resources. These four baseline mutations are not yet part of the shared Python/.NET subprocess corpus. Compiled TypeScript consumer tests cover its installed entry point, durable mirror and visibility transitions; Node source tests exercise its full malformed-page matrix.

## Reproduction

Use the runtimes and explicit PQ provider in the [quickstart](quickstart.md) and [SDK guide](sdks.md):

```sh
npm test
npm run package:sdks
npm run sdk:conformance
npm run typecheck
npm run check:docs
```

[Node negative tests](../tests/negative-conformance.test.ts), [visibility tests](../tests/visibility.test.ts) and [shared packaged-consumer harness](../scripts/sdk-conformance.ts) are versioned with the implementation. The .NET local test uses an explicit Python PQClean primitive provider because native ML-KEM/ML-DSA are unavailable on the tested macOS runtime. No classical fallback is accepted. Packages are installed locally, with no registry publication.

**Next:** add generated serialization/fuzzing vectors and broader baseline/persistence faults, alongside local terminology validation and reviewed platform providers.