Doctor (qkdsec.doctor)¶
KME conformance probe.
The qkdsec.doctor package runs a battery of probes against a Key
Management Entity (KME) and emits a conformance report against ETSI GS QKD
014 v1.1.1. It is the recommended first tool to point at any new KME, whether
it is hardware, a vendor simulator, or your own implementation.
Programmatic example:
from qkdsec.client import ETSI014Client
from qkdsec.doctor import run_all, format_text
client = ETSI014Client("https://kme.example.com",
client_cert=("alice.crt", "alice.key"))
report = run_all(client, slave_sae_id="sae-bob")
print(format_text(report))
Or use the CLI:
qkdsec doctor https://kme.example.com --slave-sae-id sae-bob
For full options see Doctor — KME conformance probe.
- class qkdsec.doctor.ProbeResult(name, status, summary, spec_section=None, severity='info', latency_ms=None, details=<factory>)[source]¶
Bases:
objectOutcome of a single conformance probe.
- Parameters:
- status: ProbeStatus¶
- class qkdsec.doctor.ProbeStatus(*values)[source]¶
-
- FAIL = 'fail'¶
- PASS = 'pass'¶
- SKIP = 'skip'¶
- WARN = 'warn'¶
- class qkdsec.doctor.Report(base_url, slave_sae_id, results=<factory>, total_latency_ms=0.0)[source]¶
Bases:
objectAggregate report from a doctor run.
- Parameters:
base_url (str)
slave_sae_id (str)
results (list[ProbeResult])
total_latency_ms (float)
- results: list[ProbeResult]¶
- qkdsec.doctor.format_html(report)[source]¶
Render the report as a standalone single-file HTML document.
- qkdsec.doctor.format_json(report, *, indent=2)[source]¶
Serialize the report as JSON. Stable field ordering for diffing.
- qkdsec.doctor.format_text(report, *, use_rich=True)[source]¶
Format the report as terminal text. Uses Rich if available.
Set
use_rich=Falseto force plain ASCII output (useful for log files).
- qkdsec.doctor.run_all(client, slave_sae_id, *, consume_keys=True, latency_samples=5)[source]¶
Run the full conformance battery and return a
Report.- Parameters:
client (
ETSI014Client) – A configured sync client. Must have credentials forslave_sae_id.slave_sae_id (
str) – The slave SAE ID to probe against.consume_keys (
bool) – IfFalse, skip probes that consume real keys (enc_keys / dec_keys round-trip / extensions). DefaultTrue— consumes up to 5 keys per run.latency_samples (
int) – Number of status calls to time for the latency probe.
- Return type:
Probe results¶
- class qkdsec.doctor.ProbeResult(name, status, summary, spec_section=None, severity='info', latency_ms=None, details=<factory>)[source]¶
Bases:
objectOutcome of a single conformance probe.
- Parameters:
- status: ProbeStatus¶
- class qkdsec.doctor.ProbeStatus(*values)[source]¶
-
- FAIL = 'fail'¶
- PASS = 'pass'¶
- SKIP = 'skip'¶
- WARN = 'warn'¶
Probes¶
- qkdsec.doctor.run_all(client, slave_sae_id, *, consume_keys=True, latency_samples=5)[source]¶
Run the full conformance battery and return a
Report.- Parameters:
client (
ETSI014Client) – A configured sync client. Must have credentials forslave_sae_id.slave_sae_id (
str) – The slave SAE ID to probe against.consume_keys (
bool) – IfFalse, skip probes that consume real keys (enc_keys / dec_keys round-trip / extensions). DefaultTrue— consumes up to 5 keys per run.latency_samples (
int) – Number of status calls to time for the latency probe.
- Return type:
Individual conformance probes against ETSI GS QKD 014 v1.1.1.
Each probe is a pure function that returns a ProbeResult. The probes
do not raise; failure modes are captured in the result so the doctor can run
the full battery and report on every category, even when the KME is partially
broken.
- qkdsec.doctor.probes.probe_dec_keys_roundtrip(client, slave_sae_id)[source]¶
End-to-end round-trip: enc_keys → dec_keys returns the same bytes.
- Return type:
- Parameters:
client (ETSI014Client)
slave_sae_id (str)
- qkdsec.doctor.probes.probe_enc_keys_caps(client, slave_sae_id, max_per_request, max_size)[source]¶
Verify the KME enforces max_key_per_request and max_key_size caps.
- Return type:
- Parameters:
client (ETSI014Client)
slave_sae_id (str)
max_per_request (int)
max_size (int)
- qkdsec.doctor.probes.probe_enc_keys_get(client, slave_sae_id, size=256)[source]¶
Confirm GET enc_keys returns a valid key of the requested size.
- Return type:
- Parameters:
client (ETSI014Client)
slave_sae_id (str)
size (int)
- qkdsec.doctor.probes.probe_enc_keys_post(client, slave_sae_id, size=256)[source]¶
Confirm POST enc_keys works the same as GET (ETSI 014 alternative form).
- Return type:
- Parameters:
client (ETSI014Client)
slave_sae_id (str)
size (int)
- qkdsec.doctor.probes.probe_error_contract_400(client, slave_sae_id)[source]¶
Confirm the KME returns HTTP 400 for an invalid key size.
- Return type:
- Parameters:
client (ETSI014Client)
slave_sae_id (str)
- qkdsec.doctor.probes.probe_error_contract_404(client, slave_sae_id)[source]¶
Confirm the KME returns HTTP 404 for an unknown key_ID.
- Return type:
- Parameters:
client (ETSI014Client)
slave_sae_id (str)
- qkdsec.doctor.probes.probe_extensions_accepted(client, slave_sae_id)[source]¶
Check the KME does not reject optional extension fields in the body.
- Return type:
- Parameters:
client (ETSI014Client)
slave_sae_id (str)
- qkdsec.doctor.probes.probe_latency(client, slave_sae_id, samples=5)[source]¶
Measure status-endpoint latency across N samples.
- Return type:
- Parameters:
client (ETSI014Client)
slave_sae_id (str)
samples (int)
- qkdsec.doctor.probes.probe_reachability(client, slave_sae_id)[source]¶
Confirm the KME responds to a status request (TLS + auth working).
- Return type:
- Parameters:
client (ETSI014Client)
slave_sae_id (str)
- qkdsec.doctor.probes.probe_status_fields(client, slave_sae_id)[source]¶
Validate that the §5.2 status response includes all required fields.
- Return type:
- Parameters:
client (ETSI014Client)
slave_sae_id (str)
Formatters¶
- qkdsec.doctor.format_text(report, *, use_rich=True)[source]¶
Format the report as terminal text. Uses Rich if available.
Set
use_rich=Falseto force plain ASCII output (useful for log files).