def get_client(): global use_prompt if WindowsClient.is_available( ) and not ctypes.windll.shell32.IsUserAnAdmin(): # Use the Windows WebAuthn API if available, and we're not running as admin client = WindowsClient("https://example.com") else: # Locate a device for dev in enumerate_devices(): client = Fido2Client(dev, "https://example.com") if client.info.options.get("rk"): use_prompt = not (CtapPcscDevice and isinstance(dev, CtapPcscDevice)) break else: print("No Authenticator with support for resident key found!") sys.exit(1) # Prefer UV if supported if client.info.options.get("uv"): uv = "preferred" print("Authenticator supports User Verification") elif client.info.options.get("clientPin"): # Prompt for PIN if needed pin = getpass("Please enter PIN: ") else: print("PIN not set, won't use") return client
On Windows, the native WebAuthn API will be used. """ from __future__ import print_function, absolute_import, unicode_literals from fido2.hid import CtapHidDevice from fido2.client import Fido2Client, WindowsClient from fido2.server import Fido2Server from getpass import getpass import sys use_prompt = False pin = None uv = "discouraged" uv = "preferred" if WindowsClient.is_available(): # Use the Windows WebAuthn API if available client = WindowsClient("https://example.com") else: # Locate a device dev = next(CtapHidDevice.list_devices(), None) if dev is not None: print("Use USB HID channel.") use_prompt = True else: try: from fido2.pcsc import CtapPcscDevice dev = next(CtapPcscDevice.list_devices(), None) print("Use NFC channel.") except Exception as e:
def yubikey_authenticate(request): # type: (dict) -> Optional[dict] auth_func = None # type: Optional[Callable[[], Union[AuthenticatorAssertionResponse, dict, None]]] evt = threading.Event() response = None # type: Optional[str] if 'authenticateRequests' in request: # U2F options = request['authenticateRequests'] origin = options[0].get('appId') or '' challenge = options[0]['challenge'] keys = [{ 'version': x.get('version') or '', 'keyHandle': x['keyHandle'] } for x in options if 'keyHandle' in x] dev = next(CtapHidDevice.list_devices(), None) if not dev: logging.warning("No Security Key detected") return client = U2fClient(dev, origin) def auth_func(): nonlocal response response = client.sign(origin, challenge, keys, event=evt) elif 'publicKeyCredentialRequestOptions' in request: # WebAuthN origin = '' options = request['publicKeyCredentialRequestOptions'] if 'extensions' in options: extensions = options['extensions'] origin = extensions.get('appid') or '' credentials = options.get('allowCredentials') or [] for c in credentials: if isinstance(c.get('id'), str): c['id'] = utils.base64_url_decode(c['id']) rq_options = PublicKeyCredentialRequestOptions( utils.base64_url_decode(options['challenge']), rp_id=options['rpId'], user_verification='discouraged', allow_credentials=credentials) if WindowsClient.is_available(): client = WindowsClient(origin, verify=verify_rp_id_none) else: dev = next(CtapHidDevice.list_devices(), None) if not dev: logging.warning("No Security Key detected") return client = Fido2Client(dev, origin, verify=verify_rp_id_none) def auth_func(): nonlocal response nonlocal rq_options attempt = 0 while attempt < 2: attempt += 1 try: rs = client.get_assertion(rq_options, event=evt) response = rs.get_response(0) break except ClientError as err: if isinstance(err.cause, CtapError) and attempt == 1: if err.cause.code == CtapError.ERR.NO_CREDENTIALS: print( '\n\nKeeper Security stopped supporting U2F security keys starting February 2022.\n' 'If you registered your security key prior to this date please re-register it within the Web Vault.\n' 'For information on using security keys with Keeper see the documentation: \n' 'https://docs.keeper.io/enterprise-guide/two-factor-authentication#security-keys-fido-webauthn\n' 'Commander will use the fallback security key authentication method.\n\n' 'To use your Yubikey with Commander, please touch the flashing Security key one more time.\n' ) rq_options = PublicKeyCredentialRequestOptions( utils.base64_url_decode(options['challenge']), rp_id=origin, user_verification='discouraged', allow_credentials=credentials) continue raise err else: logging.warning('Invalid Security Key request') return prompt_session = None def func(): nonlocal prompt_session nonlocal evt try: time.sleep(0.1) auth_func() except: pass if prompt_session: evt = None prompt_session.app.exit() elif evt: print('\npress Enter to resume...') th = threading.Thread(target=func) th.start() try: prompt = 'Touch the flashing Security key to authenticate or press Enter to resume with the primary two factor authentication...' if os.isatty(0) and os.isatty(1): prompt_session = PromptSession(multiline=False, complete_while_typing=False) prompt_session.prompt(prompt) prompt_session = None else: input(prompt) except KeyboardInterrupt: prompt_session = None if evt: evt.set() evt = None th.join() return response
class YubicoAttestationVerifier(AttestationVerifier): """Example implementation of an AttestationVerifier. This simple example will attempt to verify all trust paths using the Yubico CA. A real implementation can use the information in the attestation result, or the authenticator data, to determine which CA should be used to verify the path. """ def ca_lookup(self, result, auth_data): return [YUBICO_CA] use_prompt = False pin = None uv = "discouraged" if WindowsClient.is_available() and not ctypes.windll.shell32.IsUserAnAdmin(): # Use the Windows WebAuthn API if available, and we're not running as admin client = WindowsClient("https://example.com") else: # Locate a device dev = next(CtapHidDevice.list_devices(), None) if dev is not None: print("Use USB HID channel.") use_prompt = True else: try: from fido2.pcsc import CtapPcscDevice dev = next(CtapPcscDevice.list_devices(), None) print("Use NFC channel.") except Exception as e:
def sign_request(public_key, authn_select): """Signs a WebAuthn challenge and returns the data. :param public_key dict containing `rpId` the relying party and `challenge` the received challenge :param authn_select string, that contains the allowed public key of the user :return dict containing clientDataJSON, authenticatorData, signature, credentialId and userHandle if available. """ use_prompt = False pin = None uv = "discouraged" if WindowsClient.is_available( ) and not ctypes.windll.shell32.IsUserAnAdmin(): # Use the Windows WebAuthn API if available, and we're not running as admin client = WindowsClient("https://example.com") else: dev = next(CtapHidDevice.list_devices(), None) if dev is not None: print("Use USB HID channel.") use_prompt = True else: try: from fido2.pcsc import CtapPcscDevice dev = next(CtapPcscDevice.list_devices(), None) print("Use NFC channel.") except Exception as e: print("NFC channel search error:", e) if not dev: print("No FIDO device found") sys.exit(1) client = Fido2Client(dev, "http://localhost:8080", verify=lambda x, y: True) # Prefer UV if supported if client.info.options.get("uv"): uv = "preferred" print("Authenticator supports User Verification") elif client.info.options.get("clientPin"): # Prompt for PIN if needed pin = getpass("Please enter PIN: ") else: print("PIN not set, won't use") # the base64 library does not work when padding is missing, so append some allowed_key = base64.urlsafe_b64decode(authn_select + '===') pubKey = PublicKeyCredentialRequestOptions( public_key['challenge'], rp_id=public_key['rpId'], allow_credentials=[ PublicKeyCredentialDescriptor(PublicKeyCredentialType.PUBLIC_KEY, allowed_key) ]) # Authenticate the credential if use_prompt: print("\nTouch your authenticator device now...\n") # Only one cred in allowCredentials, only one response. result = client.get_assertion(pubKey, pin=pin).get_response(0) data = { "clientDataJSON": b64encode(result.client_data), "authenticatorData": b64encode(result.authenticator_data), "signature": b64encode(result.signature), "credentialId": b64encode(result.credential_id), } if result.user_handle: data['userHandle'] = b64encode(result.user_handle) return data
from fido2.hid import CtapHidDevice from fido2.client import Fido2Client, WindowsClient from fido2.server import Fido2Server from fido2.ctap2 import AttestedCredentialData from getpass import getpass from fido2.utils import websafe_encode, websafe_decode import sys import ldap use_prompt = False pin = None uv = "discouraged" if WindowsClient.is_available(): # Use the Windows WebAuthn API if available client = WindowsClient( "https://testrandomdomainthatsurelydoesntexist123.com") else: print("No client available") server = Fido2Server( { "id": "testrandomdomainthatsurelydoesntexist.com", "name": "Example RP" }, attestation="direct") #LDAP Query SCOPE_SUBTREE = 2
On Windows, the native WebAuthn API will be used. """ from __future__ import print_function, absolute_import, unicode_literals from fido2.hid import CtapHidDevice from fido2.client import Fido2Client, WindowsClient from fido2.server import Fido2Server from getpass import getpass import sys import ctypes use_prompt = False pin = None uv = "discouraged" if WindowsClient.is_available() and not ctypes.windll.shell32.IsUserAnAdmin(): # Use the Windows WebAuthn API if available, and we're not running as admin client = WindowsClient("https://example.com") else: # Locate a device dev = next(CtapHidDevice.list_devices(), None) if dev is not None: print("Use USB HID channel.") use_prompt = True else: try: from fido2.pcsc import CtapPcscDevice dev = next(CtapPcscDevice.list_devices(), None) print("Use NFC channel.") except Exception as e:
""" from __future__ import print_function, absolute_import, unicode_literals from fido2.hid import CtapHidDevice from fido2.client import Fido2Client, WindowsClient from fido2.server import Fido2Server from getpass import getpass from fido2.utils import websafe_encode, websafe_decode import sys use_prompt = False pin = None uv = "discouraged" if WindowsClient.is_available(): # Use the Windows WebAuthn API if available client = WindowsClient("https://testrandomdomainthatsurelydoesntexist.com") else: # Locate a device dev = next(CtapHidDevice.list_devices(), None) if dev is not None: print("Use USB HID channel.") use_prompt = True else: try: from fido2.pcsc import CtapPcscDevice dev = next(CtapPcscDevice.list_devices(), None) print("Use NFC channel.") except Exception as e:
from fido2.ctap import CtapError, STATUS from fido2.client import Fido2Client, WindowsClient, PinRequiredError from fido2.server import Fido2Server from getpass import getpass import sys import ctypes def on_keepalive(status): if status == STATUS.UPNEEDED: # Waiting for touch print("\nTouch your authenticator device now...\n") uv = "discouraged" if WindowsClient.is_available() and not ctypes.windll.shell32.IsUserAnAdmin(): # Use the Windows WebAuthn API if available, and we're not running as admin client = WindowsClient("https://example.com") else: # Locate a device dev = next(CtapHidDevice.list_devices(), None) if dev is not None: print("Use USB HID channel.") else: try: from fido2.pcsc import CtapPcscDevice dev = next(CtapPcscDevice.list_devices(), None) print("Use NFC channel.") except Exception as e: print("NFC channel search error:", e)
# Handle user interaction class CliInteraction(UserInteraction): def prompt_up(self): print("\nTouch your authenticator device now...\n") def request_pin(self, permissions, rd_id): return getpass("Enter PIN: ") def request_uv(self, permissions, rd_id): print("User Verification required.") return True uv = "discouraged" if WindowsClient.is_available() and not ctypes.windll.shell32.IsUserAnAdmin(): # Use the Windows WebAuthn API if available, and we're not running as admin client = WindowsClient("https://example.com") else: # Locate a device for dev in enumerate_devices(): client = Fido2Client(dev, "https://example.com", user_interaction=CliInteraction()) if client.info.options.get("rk"): break else: print("No Authenticator with support for resident key found!") sys.exit(1) # Prefer UV if supported