def calculate(ctx, slot, challenge, totp, digits):
    """
    Perform a challenge-response operation.

    Send a challenge (in hex) to a YubiKey slot with a challenge-response
    credential, and read the response. Supports output as a OATH-TOTP code.
    """
    controller = ctx.obj['controller']
    if not challenge and not totp:
        ctx.fail('No challenge provided.')

    # Check that slot is not empty
    slot1, slot2 = controller.slot_status
    if (slot == 1 and not slot1) or (slot == 2 and not slot2):
        ctx.fail('Cannot perform challenge-response on an empty slot.')

    # Timestamp challenge should be int
    if challenge and totp:
        try:
            challenge = int(challenge)
        except Exception as e:
            logger.error('Error', exc_info=e)
            ctx.fail('Timestamp challenge for TOTP must be an integer.')
    try:
        res = controller.calculate(
            slot, challenge, totp=totp,
            digits=int(digits), wait_for_touch=False)
    except YkpersError as e:
        # Touch is set
        if e.errno == 11:
            prompt_for_touch()
            try:
                res = controller.calculate(
                    slot, challenge, totp=totp,
                    digits=int(digits), wait_for_touch=True)
            except YkpersError as e:
                # Touch timed out
                if e.errno == 4:
                    ctx.fail('The YubiKey timed out.')
                else:
                    ctx.fail(e)
        else:
            ctx.fail('Failed to calculate challenge.')
    click.echo(res)
def calculate ( ctx , slot , challenge , totp , digits ) : controller = ctx . obj [ 'controller' ] if not challenge and not totp : ctx . fail ( 'No challenge provided.' ) slot1 , slot2 = controller . slot_status if ( slot == 1 and not slot1 ) or ( slot == 2 and not slot2 ) : ctx . fail ( 'Cannot perform challenge-response on an empty slot.' ) if challenge and totp : try : challenge = int ( challenge ) except Exception as e : logger . error ( 'Error' , exc_info = e ) ctx . fail ( 'Timestamp challenge for TOTP must be an integer.' ) try : res = controller . calculate ( slot , challenge , totp = totp , digits = int ( digits ) , wait_for_touch = False ) except YkpersError as e : if e . errno == 11 : prompt_for_touch ( ) try : res = controller . calculate ( slot , challenge , totp = totp , digits = int ( digits ) , wait_for_touch = True ) except YkpersError as e : if e . errno == 4 : ctx . fail ( 'The YubiKey timed out.' ) else : ctx . fail ( e ) else : ctx . fail ( 'Failed to calculate challenge.' ) click . echo ( res )
Perform a challenge-response operation.

    Send a challenge (in hex) to a YubiKey slot with a challenge-response
    credential, and read the response. Supports output as a OATH-TOTP code.