api-vzd
api-vzd copied to clipboard
Documentation regarding the owner-authenticate process using ECC softcerts
While implementing the handling of ECC certificates (*_SMCB_HCI_ENC_E256
), I came accross the ECC sample in ./samples/directory-samples-python/directory_samples/owner_authenticate_konnektor.py.
In this sample, the signing of the challenge is performed by a request to a Gematik Konnektor using external_authenticate():
challenge_response_signature = external_authenticate(card_handle, challenge_response_hash, "ECC")
debug_print("ExternalAuthenticate Request")
debug_print(last_soap_request())
debug_print("ExternalAuthenticate Response")
debug_print(last_soap_response())
debug_print("Received signature from konnektor")
debug_print(challenge_response_signature)
# ECC signatures must be post-processed
r, s = ec_utils.decode_dss_signature(challenge_response_signature)
challenge_response_signature = _encode_int(r, 256) + _encode_int(s, 256)
signed_token = header_and_payload + "." + base64url_encode(challenge_response_signature)
debug_print("Complete signed challenge response")
debug_print(signed_token, soft_wrap=True)
I'm trying to implement this signing manually without requesting a Konntektor, just like in the provided RSA sample ./samples/directory-samples-python/directory_samples/owner_authenticate_softcert.py:
smcb_cert_bytes = open(owner_cert_filename_der, "rb").read()
cert_base64 = b64encode(smcb_cert_bytes).decode("ascii")
payload = {
"njwt": challenge
}
jwstoken = jws.JWS(dumps(payload).encode('utf-8'))
jwstoken.add_signature(
smcb_key,
None,
json_encode({
"typ": "JWT",
"cty": "NJWT",
# BASE64(DER)
"x5c": [cert_base64],
# BP256R1 or PS256
"alg": "PS256"
}),
)
signed_token = jwstoken.serialize(True)
debug_print(signed_token, soft_wrap=True)
I tried looking for the documentation about how the Konntektor is creating this signature, but looking through the Konnektor spec (gemSpec_Kon_V*.pdf) wasn't helpful.
def external_authenticate(card_handle: str, hash: bytes, crypt: str):
service = create_service_client(
"AuthSignatureService_v7_4_1",
"http://ws.gematik.de/conn/AuthSignatureService/WSDL/v7.4"
)
if crypt == "RSA":
optional_outputs = {
'SignatureType': 'urn:ietf:rfc:3447',
'SignatureSchemes': 'RSASSA-PSS'
}
else:
optional_outputs = {
'SignatureType': 'urn:bsi:tr:03111:ecdsa',
}
response = service.ExternalAuthenticate(
CardHandle=card_handle,
Context={
"MandantId": connector_config.mandant_id,
"ClientSystemId": connector_config.client_system_id,
"WorkplaceId": connector_config.workplace_id,
},
OptionalInputs=optional_outputs,
BinaryString={
"Base64Data": {
"MimeType": "application/octet-stream",
"_value_1": hash
}
}
)
return response.SignatureObject.Base64Signature._value_1
Could you point me into the right direction, or did I overlook something the Konntektor specification?