Пример #1
0
def do_enroll():
    devs = u2f.list_devices()
    req = make_reg_request()
    result = register.register(devs, req, OUR_APPID)

    # check client data from token
    clientData = json.loads(websafe_decode(result['clientData']))

    assert clientData['origin'] == OUR_APPID
    assert clientData['challenge'] == req['challenge']
    assert clientData['typ'] == 'navigator.id.finishEnrollment'

    # check registration data
    regData = decode_reg_response(websafe_decode(result['registrationData']))

    salt = os.urandom(32)

    with open('data.json', 'w') as f:
        db = dict(hkey=websafe_encode(H(regData.pubkey)),
                  keyhandle=websafe_encode(regData.keyhandle),
                  salt=websafe_encode(salt))
        json.dump(db, f)
        print 'written data to', f.name

    key = hashlib.pbkdf2_hmac('sha256', regData.pubkey + SOME_PASSWORD, salt,
                              SOME_ITERATIONS)
    print 'secret is', key.encode('hex')
Пример #2
0
def main():
    args = parse_args()

    facet = text_type(args.facet, sys.stdin.encoding or sys.getdefaultencoding())
    if args.infile:
        with open(args.infile, 'r') as f:
            data = f.read()
    else:
        if sys.stdin.isatty():
            sys.stderr.write('Enter RegistrationRequest JSON data...\n')
        data = sys.stdin.read()
    params = json.loads(data, object_hook=u2str)

    if args.soft:
        from u2flib_host.soft import SoftU2FDevice
        devices = [SoftU2FDevice(args.soft)]
    else:
        devices = u2f.list_devices()
    result = register(devices, params, facet)

    if args.outfile:
        with open(args.outfile, 'w') as f:
            json.dump(result, f)
        sys.stderr.write('Output written to %s\n' % args.outfile)
    else:
        sys.stderr.write('\n---Result---\n')
        print(json.dumps(result))
Пример #3
0
def do_auth():
    devs = u2f.list_devices()
    db = json.load(open('data.json'))

    keyhandle = websafe_decode(db['keyhandle'])
    salt = websafe_decode(db['salt'])
    hkey = websafe_decode(db['hkey'])

    req = make_auth_request(keyhandle)

    result = authenticate.authenticate(devs, req, OUR_APPID, check_only = False)

    authData = decode_auth_response(websafe_decode(result['signatureData']))

    open('sig.der', 'w').write(authData.sig)

    # decode our signature, and reconstruct the message that was signed
    sig = decode_sig(authData.sig)
    signed_message = H(req['appId']) + encode_auth_response_prefix(authData) + H(websafe_decode(result['clientData']))
    
    # recover the two possible public keys from the signature
    pubkeys = ecdsa.recover_candidate_pubkeys(ec.nistp256, hashlib.sha256, signed_message, sig)
    pubkeys = [ec.nistp256.ec2osp(pk) for pk in pubkeys]

    if H(pubkeys[0]) == hkey:
        pubkey = pubkeys[0]
    elif H(pubkeys[1]) == hkey:
        pubkey = pubkeys[1]
    else:
        print 'token is broken/lying/replayed!'
        sys.exit(1)

    key = hashlib.pbkdf2_hmac('sha256', pubkey + SOME_PASSWORD, salt, SOME_ITERATIONS)
    print 'secret is', key.encode('hex')
Пример #4
0
def do_enroll():
    devs = u2f.list_devices()
    req = make_reg_request()
    result = register.register(devs, req, OUR_APPID)
    
    # check client data from token
    clientData = json.loads(websafe_decode(result['clientData']))

    assert clientData['origin'] == OUR_APPID
    assert clientData['challenge'] == req['challenge']
    assert clientData['typ'] == 'navigator.id.finishEnrollment'
   
    # check registration data
    regData = decode_reg_response(websafe_decode(result['registrationData']))

    salt = os.urandom(32)

    with open('data.json', 'w') as f:
        db = dict(
            hkey = websafe_encode(H(regData.pubkey)),
            keyhandle = websafe_encode(regData.keyhandle),
            salt = websafe_encode(salt)
        )
        json.dump(db, f)
        print 'written data to', f.name

    key = hashlib.pbkdf2_hmac('sha256', regData.pubkey + SOME_PASSWORD, salt, SOME_ITERATIONS)
    print 'secret is', key.encode('hex')
Пример #5
0
def main():
    args = parse_args()

    facet = text_type(args.facet, sys.stdin.encoding
                      or sys.getdefaultencoding())
    if args.infile:
        with open(args.infile, 'r') as f:
            data = f.read()
    else:
        if sys.stdin.isatty():
            sys.stderr.write('Enter RegistrationRequest JSON data...\n')
        data = sys.stdin.read()
    params = json.loads(data, object_hook=u2str)

    if args.soft:
        from u2flib_host.soft import SoftU2FDevice
        devices = [SoftU2FDevice(args.soft)]
    else:
        devices = u2f.list_devices()
    result = register(devices, params, facet)

    if args.outfile:
        with open(args.outfile, 'w') as f:
            json.dump(result, f)
        sys.stderr.write('Output written to %s\n' % args.outfile)
    else:
        sys.stderr.write('\n---Result---\n')
        print(json.dumps(result))
Пример #6
0
    def setTwoFactorMethod(self, user_dn, factor_method, user_password=None):
        if factor_method == "u2f":
            print(_("checking U2F devices..."))
            # check for devices
            devices = u2f.list_devices()
            if len(devices) == 0:
                print(_("No U2F devices found, aborting!"))
                return

        response = self.proxy.setTwoFactorMethod(user_dn, factor_method, user_password)
        if response is None:
            return
        if factor_method == "u2f":
            # bind
            response = loads(response)
            for device in devices:
                # The with block ensures that the device is opened and closed.
                print(_("Please touch the flashing U2F device now."))
                with device as dev:
                    # Register the device with some service
                    for request in response['registerRequests']:
                        registration_response = u2f.register(device, request, request['appId'])
                        response = self.proxy.completeU2FRegistration(user_dn, registration_response)
                        if response is True:
                            print(_("U2F authentication has been enabled"))

        elif response.startswith("otpauth://"):
            url = pyqrcode.create(response, error='L')
            print(url.terminal(quiet_zone=1))
        else:
            print(response)
Пример #7
0
def main():
    args = parse_args()

    facet = text_type(args.facet)
    if args.infile:
        with open(args.infile, 'r') as f:
            data = f.read()
    else:
        if sys.stdin.isatty():
            sys.stderr.write('Enter AuthenticateRequest JSON data...\n')
        data = sys.stdin.read()

    params = json.loads(data)
    if args.soft:
        from u2flib_host.soft import SoftU2FDevice
        devices = [SoftU2FDevice(args.soft)]
    else:
        devices = u2f.list_devices()
    result = authenticate(devices, params, facet, args.check_only)

    if args.outfile:
        with open(args.outfile, 'w') as f:
            json.dump(result, f)
        sys.stderr.write('Output written to %s\n' % args.outfile)
    else:
        sys.stderr.write('\n---Result---\n')
        print(json.dumps(result))
Пример #8
0
def main():
    args = parse_args()

    facet = text_type(args.facet)
    if args.infile:
        with open(args.infile, 'r') as f:
            data = f.read()
    else:
        if sys.stdin.isatty():
            sys.stderr.write('Enter AuthenticateRequest JSON data...\n')
        data = sys.stdin.read()

    params = json.loads(data)
    if args.soft:
        from u2flib_host.soft import SoftU2FDevice
        devices = [SoftU2FDevice(args.soft)]
    else:
        devices = u2f.list_devices()
    result = authenticate(devices, params, facet, args.check_only)

    if args.outfile:
        with open(args.outfile, 'w') as f:
            json.dump(result, f)
        sys.stderr.write('Output written to %s\n' % args.outfile)
    else:
        sys.stderr.write('\n---Result---\n')
        print(json.dumps(result))
Пример #9
0
def get_u2f_devices():
    """Get all U2F devices attached to the machine"""
    devices = u2f.list_devices()
    for device in devices:
        try:
            device.open()
        except:  # pylint: disable=bare-except
            devices.remove(device)
    return devices
Пример #10
0
def getDevice():
    devices = u2f.list_devices()
    if len(devices) != 1:
        sys.stderr.write('\nMore than one or no device detected. Exiting\n')
        sys.exit(1)

    device = None
    try:
        device = devices[0]
        device.open()
    except:
        pass
    return device
Пример #11
0
def main():
    with u2f.list_devices()[0] as dev:
        dev.send_apdu(U2F_VENDOR_JUJU, INS_ERASE)

        with open('key.pem') as f:
            key = ecdsa.SigningKey.from_pem(f.read())
            dev.send_apdu(U2F_VENDOR_JUJU,
                          INS_SET_PRIVATE_KEY,
                          data=key.to_string())

        with open('cert.der', 'rb') as f:
            dev.send_apdu(U2F_VENDOR_JUJU, INS_SET_CERTIFICATE, data=f.read())

        dev.send_apdu(U2F_VENDOR_JUJU,
                      INS_SET_SEED,
                      data=secrets.token_bytes(256))
Пример #12
0
def u2f_auth(challenges, facet):
    devices = u2f.list_devices()
    for device in devices[:]:
        try:
            device.open()
        except:
            # Some U2F devices fail on the first attempt to open but
            # succeed on subsequent attempts. So retry once.
            try:
                device.open()
            except:
                devices.remove(device)

    try:
        prompted = False
        while devices:
            removed = []
            for device in devices:
                remove = True
                for challenge in challenges:
                    try:
                        return u2f.authenticate(device, json.dumps(challenge),
                                                facet)
                    except exc.APDUError as e:
                        if e.code == APDU_USE_NOT_SATISFIED:
                            remove = False
                            if not prompted:
                                print('Touch the flashing U2F device to '
                                      'authenticate...')
                                prompted = True
                        else:
                            pass
                    except exc.DeviceError:
                        pass
                if remove:
                    removed.append(device)
            devices = [d for d in devices if d not in removed]
            for d in removed:
                d.close()
            time.sleep(0.25)
    finally:
        for device in devices:
            device.close()
    raise RuntimeWarning("U2F Device Not Found")
Пример #13
0
def okta_mfa_u2f(conf, s, factors, state_token):
    devices = u2f.list_devices()
    if not devices:
        err('no u2f devices found')
        return None
    for factor in factors:
        provider = factor.get('provider', '')
        log('mfa {0} challenge request'.format(provider))
        r = s.post(
            factor.get('url'),
            headers=hdr_json(),
            data = json.dumps({
                'stateToken': state_token
            })
        )
        if r.status_code != 200:
            err('okta mfa challenge request failed. {0}'.format(reprr(r)))
        dbg(conf.get('debug'), 'challenge.response', r.status_code, r.text)
        j = parse_rjson(r)
        factor = j['_embedded']['factor']
        profile = factor['profile']
        auth_request_data = {
            'appId': profile['appId'],
            'keyHandle': profile['credentialId'],
            'version': profile['version'],
            'challenge': factor['_embedded']['challenge']['nonce']
        }
        signed = do_u2f_sign(conf, devices, auth_request_data, profile['appId'], state_token)
        if signed:
            log('mfa {0} signed request'.format(provider))
            r = s.post(
                j['_links']['next']['href'],
                headers=hdr_json(),
                data = json.dumps(signed)
            )
            if r.status_code != 200:
                err('okta mfa signed request failed. {0}'.format(reprr(r)))
            dbg(conf.get('debug'), 'u2d.next.resp', r.status_code, r.text)
            j = parse_rjson(r)
            return j.get('sessionToken', '').strip()
        else:
            return None
Пример #14
0
    def __handle_result(self, response):
        """
        Handle the results of the different login steps (login, 2FA, U2F) and process with
        the next required step until the login process succeeds or fails.
        """
        try:
            result_code = int(response['state'])

            if result_code == AUTH_FAILED:
                print(_("Login of user '%s' failed") % self.__username)
                sys.exit(1)

            elif result_code == AUTH_OTP_REQUIRED:
                key = input(_("OTP-Passkey: "))
                return self.__handle_result(self.proxy.verify(key))

            elif result_code == AUTH_U2F_REQUIRED and 'u2f_data' in response:
                for device in u2f.list_devices():
                    with device as dev:
                        data = loads(response['u2f_data'])
                        print(data)
                        print(_("Please touch the flashing U2F device now."))
                        for request in data['authenticateRequests']:
                            data = u2f.authenticate(device, request,
                                                    request['appId'])
                            res = self.proxy.verify(data)
                            if 'counter' in res and 'touch' in res:
                                return True

                return False
            elif result_code == AUTH_SUCCESS:
                return True

        except Exception as e:
            print(e)
            sys.exit(1)

        return False
Пример #15
0
def do_auth():
    devs = u2f.list_devices()
    db = json.load(open('data.json'))

    keyhandle = websafe_decode(db['keyhandle'])
    salt = websafe_decode(db['salt'])
    hkey = websafe_decode(db['hkey'])

    req = make_auth_request(keyhandle)

    result = authenticate.authenticate(devs, req, OUR_APPID, check_only=False)

    authData = decode_auth_response(websafe_decode(result['signatureData']))

    open('sig.der', 'w').write(authData.sig)

    # decode our signature, and reconstruct the message that was signed
    sig = decode_sig(authData.sig)
    signed_message = H(
        req['appId']) + encode_auth_response_prefix(authData) + H(
            websafe_decode(result['clientData']))

    # recover the two possible public keys from the signature
    pubkeys = ecdsa.recover_candidate_pubkeys(ec.nistp256, hashlib.sha256,
                                              signed_message, sig)
    pubkeys = [ec.nistp256.ec2osp(pk) for pk in pubkeys]

    if H(pubkeys[0]) == hkey:
        pubkey = pubkeys[0]
    elif H(pubkeys[1]) == hkey:
        pubkey = pubkeys[1]
    else:
        print 'token is broken/lying/replayed!'
        sys.exit(1)

    key = hashlib.pbkdf2_hmac('sha256', pubkey + SOME_PASSWORD, salt,
                              SOME_ITERATIONS)
    print 'secret is', key.encode('hex')
Пример #16
0
    def __handle_result(self, response):
        """
        Handle the results of the different login steps (login, 2FA, U2F) and process with
        the next required step until the login process succeeds or fails.
        """
        try:
            print(response)
            result_code = int(response['state'])

            if result_code == AUTH_FAILED:
                print(_("Login of user '%s' failed") % self.__username)
                sys.exit(1)

            elif result_code == AUTH_OTP_REQUIRED:
                key = input(_("OTP-Passkey: "))
                return self.__handle_result(self.proxy.verify(key))

            elif result_code == AUTH_U2F_REQUIRED and 'u2f_data' in response:
                for device in u2f.list_devices():
                    with device as dev:
                        data = loads(response['u2f_data'])
                        print(data)
                        print(_("Please touch the flashing U2F device now."))
                        for request in data['authenticateRequests']:
                            data = u2f.authenticate(device, request, request['appId'])
                            res = self.proxy.verify(data)
                            if 'counter' in res and 'touch' in res:
                                return True

                return False
            elif result_code == AUTH_SUCCESS:
                return True

        except Exception as e:
            print(e)
            sys.exit(1)

        return False
Пример #17
0
import sys
import requests
import json

facet = 'http://localhost:8081'
if 1:
    try:
        registrationRequest = json.loads(
            requests.get("http://localhost:8081/enroll").text)

        print registrationRequest

        registrationRequest = registrationRequest['registerRequests'][0]

        # Enumerate available devices
        devices = u2f.list_devices()

        for device in devices:
            # The with block ensures that the device is opened and closed.
            with device as dev:
                # Register the device with some service
                print 'Reg: press button . . .'
                sys.stdout.flush()
                registrationResponse = u2f.register(device,
                                                    registrationRequest, facet)
                print registrationResponse
                registrationResponse['version'] = 'U2F_V2'
                bindres = (requests.post("http://localhost:8081/bind",
                                         data={
                                             'data':
                                             json.dumps(registrationResponse)
Пример #18
0
    def _verify_single_factor(self, factor):
        """ Verifies a single MFA factor """
        req_data = {
            "stateToken": self.state_token
        }

        self.logger.debug(factor)
        if factor['factorType'] == 'token:software:totp':
            if self.totp_token:
                self.logger.debug("Using TOTP token from command line arg")
                req_data['answer'] = self.totp_token
            else:
                req_data['answer'] = input('Enter MFA verification code: ')

        post_url = factor['_links']['verify']['href']
        resp = requests.post(post_url, json=req_data)
        resp_json = resp.json()
        if 'status' in resp_json:
            if resp_json['status'] == "SUCCESS":
                return resp_json['sessionToken']
            elif resp_json['status'] == "MFA_CHALLENGE" and factor['factorType'] !='u2f':
                print("Waiting for push verification...")
                while True:
                    resp = requests.post(
                        resp_json['_links']['next']['href'], json=req_data)
                    resp_json = resp.json()
                    if resp_json['status'] == 'SUCCESS':
                        return resp_json['sessionToken']
                    elif resp_json['factorResult'] == 'TIMEOUT':
                        print("Verification timed out")
                        sys.exit(1)
                    elif resp_json['factorResult'] == 'REJECTED':
                        print("Verification was rejected")
                        sys.exit(1)
                    else:
                        time.sleep(0.5)

            if factor['factorType'] == 'u2f':
                devices = u2f.list_devices()
                if len(devices) == 0:
                    self.logger.warning("No U2F device found")
                    sys.exit(1)

                challenge = dict()
                challenge['appId'] = resp_json['_embedded']['factor']['profile']['appId']
                challenge['version'] = resp_json['_embedded']['factor']['profile']['version']
                challenge['keyHandle'] = resp_json['_embedded']['factor']['profile']['credentialId']
                challenge['challenge'] = resp_json['_embedded']['factor']['_embedded']['challenge']['nonce']

                print("Please touch your U2F device...")
                auth_response = None
                while not auth_response:
                    for device in devices:
                        with device as dev:
                            try:
                                auth_response = u2f.authenticate(dev, challenge, resp_json['_embedded']['factor']['profile']['appId'] )
                                req_data.update(auth_response)
                                resp = requests.post(resp_json['_links']['next']['href'], json=req_data)
                                resp_json = resp.json()
                                if resp_json['status'] == 'SUCCESS':
                                    return resp_json['sessionToken']
                                elif resp_json['factorResult'] == 'TIMEOUT':
                                    self.logger.warning("Verification timed out")
                                    sys.exit(1)
                                elif resp_json['factorResult'] == 'REJECTED':
                                    self.logger.warning("Verification was rejected")
                                    sys.exit(1)
                            except exc.APDUError as ex:
                                if ex.code == APDU_WRONG_DATA:
                                    devices.remove(device)
                                time.sleep(0.1)

        elif resp.status_code != 200:
            self.logger.error(resp_json['errorSummary'])
            sys.exit(1)
        else:
            self.logger.error(resp_json)
            sys.exit(1)
        return None
Пример #19
0
def u2freq(ins, p1, p2, msg):
    with u2f.list_devices()[0] as d:
        return d.send_apdu(ins, p1, p2, msg)