handshake_complete
- Category: auth
- Access: write
- Audience: internal (ordinary users do not normally call this directly)
Purpose
Completes a hybrid handshake: derives the shared secret, verifies the credential envelope, and returns a sealed session response. Single use per challenge; any failure denies generically.
Arguments
Required: challenge_id, client_ecdh.
Optional: envelope_ct, envelope_iv, envelope_tag, kem_ct, profile.
-
challenge_id. Note: Single-use; unknown, reused, or expired ids deny generically. -
client_ecdh. Note: Caller ephemeral P-256 public material; exact length required. -
envelope_ct. Note: Credential envelope ciphertext carrying a bootstrap or ticket credential. -
envelope_iv. Note: Envelope nonce; exact length required. -
envelope_tag. Note: Envelope tag; exact length required. -
kem_ct. Note: ML-KEM-768 ciphertext; exact length required. -
profile. Note: Requested profile boundary only, never authority: unknown names deny like bad credentials, and the credential check runs against the selected profile's own grants.
Result
Sealed response envelope object with iv, ct, and tag; inside are session_id, client_id, expires_at, session credential, bound profile, and (ticket path only) the new bootstrap secret.
Boundaries
Pre-authentication call bound to the challenge's connection. Ticket enrolment burns the ticket, provisions the principal, and opens the session atomically; grants come from server-held entries only, never caller claims. Ordinary users never call this directly.
Lifecycle / side effects
Derives the hybrid secret over the full transcript, opens the credential envelope, verifies a bootstrap or ticket credential, opens a 1-hour registry session, mints its credential, and seals the session response. Post-commit failures revoke the just-made session rather than leaving it orphaned.
Errors
Every failure shape (bad challenge, bad key lengths, transcript mismatch, envelope failure, unknown credential, full key heap) denies generically as handshake failed with no oracle.
Example
{
"challenge_id": "<uuid>",
"client_ecdh": "<b64u>"
}
Result shape:
{
"ct": "<b64u>",
"iv": "<b64u>",
"tag": "<b64u>"
}
Real calls also carry kem_ct and the envelope_iv/ct/tag triplet; the sealed session response is an iv/ct/tag envelope.
See also
handshake_challenge, issue_enrollment_ticket, close_session, revoke_agent.