ETSI 014 client (qkdsec.client)¶
ETSI GS QKD 014 REST client for Key Management Entity (KME) systems.
Use this to fetch quantum keys from real QKD hardware (Toshiba, ID Quantique, QuantumCTek, etc.) or from a local KME simulator. Both synchronous and asynchronous clients are provided.
- Sync example:
>>> from qkdsec.client import ETSI014Client >>> kme = ETSI014Client("https://kme.example.com", ... client_cert=("alice.crt", "alice.key")) >>> status = kme.status("sae-bob") >>> keys = kme.get_enc_keys("sae-bob", number=1, size=256)
Async example (requires pip install qkdsec[async]):
from qkdsec.client.aio import AsyncETSI014Client
async with AsyncETSI014Client("https://kme.example.com",
client_cert=("alice.crt", "alice.key")) as kme:
keys = await kme.get_enc_keys("sae-bob", number=1, size=256)
Synchronous client¶
- class qkdsec.client.ETSI014Client(base_url, *, client_cert=None, verify=True, timeout=30.0, extra_headers=None, session=None)[source]¶
Bases:
objectSynchronous client for an ETSI GS QKD 014 Key Management Entity (KME).
- Parameters:
base_url (
str) – Base URL of the KME (e.g.,"https://kme.example.com:8443"). The/api/v1/keyspath is appended automatically.client_cert (
Union[str,tuple[str,str],None]) – Client certificate for mTLS. Pass a path to a combined cert+key PEM file, or a(cert_path, key_path)tuple. Most production KMEs require mTLS.verify (
Union[bool,str]) – TLS verification mode.True(default) uses the system CA bundle. Pass a path to a CA certificate file to pin a custom CA.Falsedisables verification (do not use in production).timeout (
float) – Per-request timeout in seconds. Default 30.extra_headers (
Optional[dict]) – Additional headers to send on every request.session (
Optional[Session]) – Reuse an existing session (useful for connection pooling or testing).
- get_dec_keys(slave_sae_id, *, key_ids, key_id_extensions=None, key_ids_extension=None)[source]¶
Fetch specific keys by key_ID for the slave SAE (ETSI 014 §5.4).
Returns just the list of keys. Use
get_dec_keys_container()to accesskey_container_extension.
- get_dec_keys_container(slave_sae_id, *, key_ids, key_id_extensions=None, key_ids_extension=None)[source]¶
Fetch keys by key_ID and return the full ETSI 014 §5.4 container.
- Parameters:
slave_sae_id (
str) – The SAE ID of the decrypting peer (this client).key_ids (
list[str]) – The key identifiers to retrieve, previously obtained by the master SAE viaget_enc_keys.key_id_extensions (
Optional[dict[str,dict[str,Any]]]) – Per-key extension data, keyed by key_ID (ETSI 014 §5.4.2key_ID_extension).key_ids_extension (
Optional[dict[str,Any]]) – Container-level extension data for the request (ETSI 014 §5.4.2key_IDs_extension).
- Return type:
- get_enc_keys(slave_sae_id, *, number=1, size=256, method='GET', additional_slave_sae_ids=None, extension_mandatory=None, extension_optional=None)[source]¶
Fetch encryption keys for the master SAE (ETSI 014 §5.3).
Returns just the list of keys for backwards compatibility. Use
get_enc_keys_container()to accesskey_container_extension.
- get_enc_keys_container(slave_sae_id, *, number=1, size=256, method='GET', additional_slave_sae_ids=None, extension_mandatory=None, extension_optional=None)[source]¶
Fetch encryption keys and return the full ETSI 014 §5.3 container.
- Parameters:
slave_sae_id (
str) – The SAE ID of the intended decrypting peer.number (
int) – Number of keys to request. KMEs typically cap this at 20.size (
int) – Key size in bits. Must be a multiple of 8.method (
str) –"GET"(query params) or"POST"(JSON body). Multicast and extensions force POST automatically since GET cannot carry them.additional_slave_sae_ids (
Optional[list[str]]) – Additional slave SAEs that should be able to retrieve the same key (ETSI 014 multicast). Forces POST.extension_mandatory (
Optional[list[dict[str,Any]]]) – Vendor-specific parameters the KME MUST honor (ETSI 014 §5.3.2). Forces POST. The KME rejects the request if it cannot satisfy.extension_optional (
Optional[list[dict[str,Any]]]) – Vendor-specific parameters the KME MAY honor (ETSI 014 §5.3.2). Forces POST. Best-effort.
- Return type:
Asynchronous client¶
- class qkdsec.client.aio.AsyncETSI014Client(base_url, *, client_cert=None, verify=True, timeout=30.0, extra_headers=None, client=None)[source]¶
Bases:
objectAsynchronous client for an ETSI GS QKD 014 KME.
Parameters mirror
qkdsec.client.ETSI014Clientexactly.Use as an async context manager to ensure the underlying httpx client is closed:
async with AsyncETSI014Client(...) as kme: await kme.status("sae-bob")
- Parameters:
- async get_dec_keys(slave_sae_id, *, key_ids, key_id_extensions=None, key_ids_extension=None)[source]¶
Fetch specific keys by key_ID for the slave SAE (ETSI 014 §5.4).
- async get_dec_keys_container(slave_sae_id, *, key_ids, key_id_extensions=None, key_ids_extension=None)[source]¶
Fetch keys by key_ID and return the full ETSI 014 §5.4 container.
- async get_enc_keys(slave_sae_id, *, number=1, size=256, method='GET', additional_slave_sae_ids=None, extension_mandatory=None, extension_optional=None)[source]¶
Fetch encryption keys for the master SAE (ETSI 014 §5.3).
- async get_enc_keys_container(slave_sae_id, *, number=1, size=256, method='GET', additional_slave_sae_ids=None, extension_mandatory=None, extension_optional=None)[source]¶
Fetch encryption keys and return the full ETSI 014 §5.3 container.
Response types¶
- class qkdsec.client.KeyResponse(key_id, key, key_id_extension=None, key_extension=None)[source]¶
Bases:
objectA single key fetched from the KME (ETSI 014 §5.3.3 / §5.4.3).
- Parameters:
- key_id¶
The KME-assigned key identifier (UUID). Used to retrieve the matching key on the slave SAE via
get_dec_keys.- Type:
- key_id_extension¶
Vendor-specific or non-standard extension data attached to the key identifier (ETSI 014 §5.3.3
key_ID_extension).- Type:
dict, optional
- class qkdsec.client.KeysContainer(keys=<factory>, key_container_extension=None)[source]¶
Bases:
objectA container of keys returned by enc_keys / dec_keys (ETSI 014 §5.3.3).
Wraps
list[KeyResponse]to also surface the optional container-level extension. Iterating over aKeysContaineryields its keys, so most callers can treat it like a list.- Parameters:
keys (list[KeyResponse])
- keys¶
- Type:
- key_container_extension¶
Vendor-specific extension data attached to the container as a whole (ETSI 014 §5.3.3
key_container_extension).- Type:
dict, optional
- keys: list[KeyResponse]¶
- class qkdsec.client.StatusResponse(source_kme_id, target_kme_id, master_sae_id, slave_sae_id, key_size, stored_key_count, max_key_count, max_key_per_request, max_key_size, min_key_size, max_sae_id_count, status_extension=None)[source]¶
Bases:
objectKME status for a given slave SAE (ETSI GS QKD 014 §5.2).
- Parameters:
Errors¶
- exception qkdsec.client.KMEHTTPError(status_code, message)[source]¶
Bases:
KMEErrorRaised when the KME returns a non-2xx HTTP response.
- exception qkdsec.client.KMENotFoundError(message)[source]¶
Bases:
KMEHTTPErrorRaised on HTTP 404 (e.g., key_ID not found or already retrieved).
- Parameters:
message (str)