Beispiel #1
0
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
Beispiel #2
0
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:
Beispiel #3
0
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
Beispiel #4
0
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:
Beispiel #5
0
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
Beispiel #6
0
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
Beispiel #7
0
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:
Beispiel #8
0
"""
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:
Beispiel #9
0
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)
Beispiel #10
0
# 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