jonesmarvin8 24f6f1f8ca fixes
2026-04-26 21:29:54 -04:00

44 lines
1.4 KiB
Python

import os
from ..card_interface import CardInterface
from .. import constants
from ..preconditions import require_secure_channel
from typing import Optional
@require_secure_channel
def mutually_authenticate(
card: CardInterface,
client_challenge: Optional[bytes] = None
) -> None:
'''
Performs mutual authentication between the client and the Keycard.
Preconditions:
- Secure Channel must be opened
The card will respond with a cryptographic challenge. The secure
session will verify the response. If the response is not exactly
32 bytes, or if the response has an unexpected status word, the
function raises an error.
Args:
transport: A Transport instance for sending APDUs.
session: A SecureChannel instance used for wrapping/unwrapping.
client_challenge (bytes, optional): Optional challenge bytes.
If not provided, a random 32-byte value will be generated.
Raises:
APDUError: If the response status word is not 0x9000.
ValueError: If the decrypted response is not exactly 32 bytes.
'''
client_challenge = client_challenge or os.urandom(32)
response: bytes = card.send_secure_apdu(
ins=constants.INS_MUTUALLY_AUTHENTICATE,
data=client_challenge
)
if len(response) != 32:
raise ValueError(
'Response to MUTUALLY AUTHENTICATE is not 32 bytes')