def webauthn_begin_assertion(): username = request.form.get('login_username') user = mitglieder.query.filter_by(id=username).first() if not user: return make_response(jsonify({'fail': 'User does not exist.'}), 401) if not user.credential_id: return make_response(jsonify({'fail': 'Unknown credential ID.'}), 401) session.pop('challenge', None) challenge = util.generate_challenge(32) # We strip the padding from the challenge stored in the session # for the reasons outlined in the comment in webauthn_begin_activate. session['challenge'] = challenge.rstrip('=') webauthn_user = webauthn.WebAuthnUser( user.ukey, user.id, user.vorname + " " + user.name, "", user.credential_id, user.pub_key, 0, RP_ID) webauthn_assertion_options = webauthn.WebAuthnAssertionOptions( webauthn_user, challenge) return jsonify(webauthn_assertion_options.assertion_dict)
def webauthn_begin_activate(): #clear session variables prior to starting a new registration session.pop('register_ukey', None) session.pop('register_id', None) session.pop('challenge', None) session['register_username'] = current_user.id session['register_display_name'] = current_user.vorname + " " + current_user.name challenge = util.generate_challenge(32) ukey = util.generate_ukey() # We strip the saved challenge of padding, so that we can do a byte # comparison on the URL-safe-without-padding challenge we get back # from the browser. # We will still pass the padded version down to the browser so that the JS # can decode the challenge into binary without too much trouble. session['challenge'] = challenge.rstrip('=') session['register_ukey'] = ukey make_credential_options = webauthn.WebAuthnMakeCredentialOptions( challenge, RP_NAME, RP_ID, ukey, current_user.id, current_user.vorname + " " + current_user.name, ORIGIN) return jsonify(make_credential_options.registration_dict)
def webauthn_begin_activate(): ''' This url is called when the registration process starts ''' username = request.form.get('register_username') if not util.validate_username(username): return make_response(jsonify({'fail': 'Invalid username.'}), 401) display_name = request.form.get('register_display_name') user_exists = database.user_exists(username) if not user_exists or not current_user.is_authenticated or not username == current_user.id: return make_response(jsonify({'fail': 'User not logged in.'}), 401) if not util.validate_token_name(display_name): return make_response(jsonify({'fail': 'Invalid display name.'}), 401) # clear session variables prior to starting a new registration session.pop('register_ukey', None) session.pop('register_username', None) session.pop('register_display_name', None) session.pop('challenge', None) session['register_username'] = username session['register_display_name'] = display_name challenge = util.generate_challenge(32) ukey = util.generate_ukey() session['challenge'] = challenge.rstrip('=') session['register_ukey'] = ukey make_credential_options = webauthn.WebAuthnMakeCredentialOptions( challenge, RP_NAME, RP_ID, ukey, username, display_name, cfg['host']['origin']) return jsonify(make_credential_options.registration_dict)
def webauthn_begin_login(): username = request.form.get('login_username') password = request.form.get('login_password') if not util.validate_username(username): return make_response(jsonify({'fail': 'Invalid username.'}), 401) _, person = auth.getPerson(username) if not person: return make_response(jsonify({'fail': 'User does not exist.'}), 401) if not person.credential_id: return make_response(jsonify({'fail': 'Unknown credential ID.'}), 401) session.pop('challenge', None) session.pop('login_password', None) challenge = util.generate_challenge(32) # We strip the padding from the challenge stored in the session # for the reasons outlined in the comment in webauthn_begin_activate. session['challenge'] = challenge.rstrip('=') session['login_password'] = password webauthn_user = webauthn.WebAuthnUser( person.ukey, person.username, person.display_name, person.icon_url, person.credential_id, person.pub_key, person.sign_count, person.rp_id) webauthn_assertion_options = webauthn.WebAuthnAssertionOptions( webauthn_user, challenge) return jsonify(webauthn_assertion_options.assertion_dict)
def webauthn_begin_assertion(): username = request.form.get('username') if not util.validate_username(username): return make_response(jsonify({'fail': 'Invalid username.'}), 401) user = User.query.filter_by(username=username).first() if not user: return make_response(jsonify({'fail': 'User does not exist.'}), 401) if not user.credential_id: return make_response(jsonify({'fail': 'Unknown credential ID.'}), 401) if 'challenge' in session: del session['challenge'] challenge = util.generate_challenge(32) session['challenge'] = challenge webauthn_user = webauthn.WebAuthnUser( user.ukey, user.username, user.display_name, user.icon_url, user.credential_id, user.pub_key, user.sign_count, user.rp_id) webauthn_assertion_options = webauthn.WebAuthnAssertionOptions( webauthn_user, challenge) return jsonify(webauthn_assertion_options.assertion_dict)
def webauthn_begin_assertion(): jsonData = request.get_json() username = jsonData['username'] if not util.validate_username(username): return make_response(jsonify({'fail': 'Invalid username.'}), 401) user = database.query_db("select * from Users where username=?",[username])[0] if len(user) == 0: return make_response(jsonify({'fail': 'User does not exist.'}), 401) if not user[4]: return make_response(jsonify({'fail': 'Unknown credential ID.'}), 401) challenge = util.generate_challenge(32) # We strip the padding from the challenge stored in the session # for the reasons outlined in the comment in webauthn_begin_activate. toStoreChallenge = challenge.rstrip('=') try: insert = database.insert_db("insert into PublicKeyCredentialCreationOptions VALUES (?,?,?,?,?,?)",[None, None,user[0],None,username,toStoreChallenge]) except: update = database.insert_db("update PublicKeyCredentialCreationOptions SET challenge=? where user_username=?",[toStoreChallenge,username]) webauthn_user = webauthn.WebAuthnUser( user[0], user[1], user[2], user[6], user[4], user[3], user[5], user[7]) webauthn_assertion_options = webauthn.WebAuthnAssertionOptions( webauthn_user, challenge) return jsonify(webauthn_assertion_options.assertion_dict)
def webauthn_begin_assertion(): username = request.form.get('login_username') if not util.validate_username(username): return make_response(jsonify({'fail': 'Invalid username.'}), 401) user = User.query.filter_by(username=username).first() if not user: return make_response(jsonify({'fail': 'User does not exist.'}), 401) if not user.credential_id: return make_response(jsonify({'fail': 'Unknown credential ID.'}), 401) session.pop('challenge', None) challenge = util.generate_challenge(32) # We strip the padding from the challenge stored in the session # for the reasons outlined in the comment in webauthn_begin_activate. session['challenge'] = challenge.rstrip('=') webauthn_user = webauthn.WebAuthnUser(user.ukey, user.username, user.display_name, user.icon_url, user.credential_id, user.pub_key, user.sign_count, user.rp_id) webauthn_assertion_options = webauthn.WebAuthnAssertionOptions( webauthn_user, challenge) return jsonify(webauthn_assertion_options.assertion_dict)
def webauthn_begin_assertion(): ''' This url is called when the authentication process begins ''' username = request.form.get('login_username') if not util.validate_username(username): return make_response(jsonify({'fail': 'Invalid username.'}), 401) credentials = database.get_credentials(username) user = database.get_user(username) if not user: return make_response(jsonify({'fail': 'User does not exist.'}), 401) session.pop('challenge', None) challenge = util.generate_challenge(32) session['challenge'] = challenge.rstrip('=') webauthn_users = [] for credential in credentials: webauthn_users.append( webauthn.WebAuthnUser(credential.ukey, credential.username, credential.display_name, credential.icon_url, credential.credential_id, credential.pub_key, credential.sign_count, credential.rp_id)) webauthn_assertion_options = webauthn.WebAuthnAssertionOptions( webauthn_users, challenge) return jsonify(webauthn_assertion_options.assertion_dict)
def reg_request(): username = request.form.get('register_username') display_name = request.form.get('register_display_name') rp_name = 'localhost' challenge = util.generate_challenge(32) ukey = util.generate_ukey() if 'register_ukey' in session: del session['register_ukey'] if 'register_username' in session: del session['register_username'] if 'register_display_name' in session: del session['register_display_name'] if 'challenge' in session: del session['challenge'] session['register_username'] = username session['register_display_name'] = display_name session['challenge'] = challenge session['register_ukey'] = ukey make_credential_options = webauthn.WebAuthnMakeCredentialOptions( challenge, rp_name, RP_ID, ukey, username, display_name, 'https://example.com') # print(make_credential_options) # print(make_credential_options.registration_dict) return json.jsonify(make_credential_options.registration_dict)
def assertion_get_options(): username = request.form.get('username') if 'challenge' in session: del session['challenge'] challenge = util.generate_challenge(32) session['challenge'] = challenge webauthn_options = webauthn.WebAuthnOptions() try: options = Options.query.filter_by(rp_id=RP_ID).first() if options is None: options = Options() options.rp_id = RP_ID options.version = CURRENT_OPTIONS_TBL_VERSION options.option_content = json.dumps(webauthn_options.get()) db.session.add(options) db.session.commit() else: if options.version != CURRENT_OPTIONS_TBL_VERSION: return make_response( jsonify({'fail': 'Options Table Version Error.'}), 400) except Exception as e: return make_response( jsonify({'fail': 'Options Database Error: {}'.format(e)}), 500) webauthn_options.set(json.loads(options.option_content)) allow_credentialids = [] if username != '' or ( webauthn_options.enableAssertionAllowCredentials == 'true' and len(webauthn_options.assertionAllowCredentialsUsers) != 0): if username != '': users = Users.query.filter_by(username=username).all() else: users = Users.query.filter( Users.id.in_( webauthn_options.assertionAllowCredentialsUsers)).all() for user in users: allow_credentialids.append(user.credential_id) webauthn_assertion_options = webauthn.WebAuthnAssertionOptions( webauthn_options, allow_credentialids, challenge, RP_ID) return make_response(jsonify(webauthn_assertion_options.assertion_dict), 200)
def webauthn_begin_activate(): print("[ENTER] begin registration") import pdb pdb.set_trace() # MakeCredentialOptions username = request.form.get('register_username') display_name = request.form.get('register_display_name') if not util.validate_username(username): return make_response(jsonify({'fail': 'Invalid username.'}), 401) if not util.validate_display_name(display_name): return make_response(jsonify({'fail': 'Invalid display name.'}), 401) if User.query.filter_by(username=username).first(): return make_response(jsonify({'fail': 'User already exists.'}), 401) #clear session variables prior to starting a new registration session.pop('register_ukey', None) session.pop('register_username', None) session.pop('register_display_name', None) session.pop('challenge', None) session['register_username'] = username session['register_display_name'] = display_name challenge = util.generate_challenge(32) print("[INFO] registration challenge ", challenge) ukey = util.generate_ukey() # We strip the saved challenge of padding, so that we can do a byte # comparison on the URL-safe-without-padding challenge we get back # from the browser. # We will still pass the padded version down to the browser so that the JS # can decode the challenge into binary without too much trouble. session['challenge'] = challenge.rstrip('=') print("[INFO] challenge.rstrip('=') ", session['challenge']) session['register_ukey'] = ukey make_credential_options = webauthn.WebAuthnMakeCredentialOptions( challenge, RP_NAME, RP_ID, ukey, username, display_name, 'https://example.com') js = make_credential_options.registration_dict pprint.pprint(js) print("[EXIT] begin registration\n") return jsonify(js)
def webauthn_begin_transfer(): amount = request.form.get('transfer_amount') recipient = request.form.get('transfer_recipient') if not util.validate_transfer_amount(amount): return make_response(jsonify({'fail': 'Invalid transfer amount.'}), 401) # Make the amount into an int type. Type safety assured by `util.validate_transfer_amount` amount = int(amount) # Extract the logged in `g.user` person = g.user.person if not person: return make_response(jsonify({'fail': 'User does not exist.'}), 401) if not person.credential_id: return make_response(jsonify({'fail': 'Unknown credential ID.'}), 401) session.pop('challenge', None) session.pop('transfer_amount', None) session.pop('transfer_recipient', None) session.pop('clientExtensions', None) challenge = util.generate_challenge(32) # We strip the padding from the challenge stored in the session # for the reasons outlined in the comment in webauthn_begin_activate. session['challenge'] = challenge.rstrip('=') session['transfer_amount'] = amount session['transfer_recipient'] = recipient session['clientExtensions'] = { 'txAuthSimple': "Authorize sending {} coins from {} to {}!".format( amount, person.username, recipient) } webauthn_user = webauthn.WebAuthnUser(person.ukey, person.username, person.display_name, person.icon_url, person.credential_id, person.pub_key, person.sign_count, person.rp_id) webauthn_assertion_options = webauthn.WebAuthnAssertionOptions( webauthn_user, challenge, clientExtensions=session['clientExtensions']) return jsonify(webauthn_assertion_options.assertion_dict)
def webauthn_begin_register(): # MakeCredentialOptions username = request.form.get('register_username') display_name = request.form.get('register_display_name') password = request.form.get('register_password') if not util.validate_username(username): return make_response(jsonify({'fail': 'Invalid username.'}), 401) if not util.validate_display_name(display_name): return make_response(jsonify({'fail': 'Invalid display name.'}), 401) if auth.isRegistered(username): return make_response(jsonify({'fail': 'User already exists.'}), 401) #clear session variables prior to starting a new registration session.pop('register_ukey', None) session.pop('register_username', None) session.pop('register_display_name', None) session.pop('register_password', None) session.pop('challenge', None) session['register_username'] = username session['register_display_name'] = display_name # TODO: I am not sure if this is safe to do?!?!? session['register_password'] = password challenge = util.generate_challenge(32) ukey = util.generate_ukey() # We strip the saved challenge of padding, so that we can do a byte # comparison on the URL-safe-without-padding challenge we get back # from the browser. # We will still pass the padded version down to the browser so that the JS # can decode the challenge into binary without too much trouble. session['challenge'] = challenge.rstrip('=') session['register_ukey'] = ukey make_credential_options = webauthn.WebAuthnMakeCredentialOptions( challenge, RP_NAME, RP_ID, ukey, username, display_name, ORIGIN, attestation='none') return jsonify(make_credential_options.registration_dict)
def webauthn_begin_activate(): # MakeCredentialOptions username = request.form.get('username') display_name = request.form.get('displayName') if not util.validate_username(username): return make_response(jsonify({'fail': 'Invalid username.'}), 401) if not util.validate_display_name(display_name): return make_response(jsonify({'fail': 'Invalid display name.'}), 401) if User.query.filter_by(username=username).first(): return make_response(jsonify({'fail': 'User already exists.'}), 401) if 'register_ukey' in session: del session['register_ukey'] if 'register_username' in session: del session['register_username'] if 'register_display_name' in session: del session['register_display_name'] if 'challenge' in session: del session['challenge'] session['register_username'] = username session['register_display_name'] = display_name rp_name = 'localhost' challenge = util.generate_challenge(32) ukey = util.generate_ukey() session['challenge'] = challenge session['register_ukey'] = ukey make_credential_options = webauthn.WebAuthnMakeCredentialOptions( challenge, rp_name, RP_ID, ukey, username, display_name, 'https://example.com') return jsonify(make_credential_options.registration_dict)
def webauthn_begin_assertion(): username = request.form.get('login_username') print("[ENTER] begin authentcation for user ", username) import pdb pdb.set_trace() if not util.validate_username(username): print("[ERROR] Invalid username.") return make_response(jsonify({'fail': 'Invalid username.'}), 401) user = User.query.filter_by(username=username).first() if not user: print("[ERROR] User does not exist.") return make_response(jsonify({'fail': 'User does not exist.'}), 401) if not user.credential_id: print("[ERROR] Unknown credential ID.") return make_response(jsonify({'fail': 'Unknown credential ID.'}), 401) session.pop('challenge', None) challenge = util.generate_challenge(32, True) print("[INFO] authentication challenge ", challenge) # print("[INFO] challenge type ", type(challenge)) # We strip the padding from the challenge stored in the session # for the reasons outlined in the comment in webauthn_begin_activate. session['challenge'] = challenge.rstrip('=') webauthn_user = webauthn.WebAuthnUser(user.ukey, user.username, user.display_name, user.icon_url, user.credential_id, user.pub_key, user.sign_count, user.rp_id) webauthn_assertion_options = webauthn.WebAuthnAssertionOptions( webauthn_user, challenge) ad = webauthn_assertion_options.assertion_dict pprint.pprint(ad) print("[EXIT] begin authentcation\n") return jsonify(ad)
def auth_request(): username = request.form.get('login_username') user = User.query.filter_by(username=username).first() if 'challenge' in session: del session['challenge'] challenge = util.generate_challenge(32) session['challenge'] = challenge webauthn_user = webauthn.WebAuthnUser(user.ukey, user.username, user.display_name, user.icon_url, user.credential_id, user.pub_key, user.sign_count, user.rp_id) webauthn_assertion_options = webauthn.WebAuthnAssertionOptions( webauthn_user, challenge) print(webauthn_assertion_options) print(webauthn_assertion_options.assertion_dict) return json.jsonify(webauthn_assertion_options.assertion_dict)
def webauthn_begin_activate(): jsonData = request.get_json() name = jsonData['name'] surname = jsonData['surname'] email = jsonData['email'] username = email display_name = name + " " + surname challenge = util.generate_challenge(32) id = util.generate_ukey() ''' PublicKeyCredentialCreationOptions rp-> Relying Party: It's the server where you want to authenticate. RP_NAME: name RP_ID: The RP ID must be equal to the origin's effective domain, or a registrable domain suffix of the origin's effective domain. The origin's scheme must be https. The origin's port is unrestricted. user information-> Information about the user registering Helps to choose from multiple credentials. username: it is a human-palatable identifier for a user account. It is intended only for display, i.e., aiding the user in determining the difference between user accounts with similar displayNames. For example, "alexm", "*****@*****.**" or "+14255551234". display_name: A human-palatable name for the user account, intended only for display. For example, "Alex P. Müller" or "田中 倫". The Relying Party SHOULD let the user choose this, and SHOULD NOT restrict the choice more than necessary. id: The user handle of the user account entity. A user handle is an opaque byte sequence with a maximum size of 64 bytes, and is not meant to be displayed to the user. ''' make_credential_options = webauthn.WebAuthnMakeCredentialOptions( challenge, RP_NAME, RP_ID, id, username, display_name, 'http://localhost') challenge = challenge.rstrip("=") insert = database.insert_db("insert into PublicKeyCredentialCreationOptions VALUES (?,?,?,?,?,?)",[RP_NAME, RP_ID,id,display_name,username,challenge]) return jsonify(make_credential_options.registration_dict)
import util print(util.generate_challenge(20)) print(util.generate_ukey())
def attestation_get_options(): username = request.form.get('username') display_name = request.form.get('displayName') if 'register_ukey' in session: del session['register_ukey'] if 'register_username' in session: del session['register_username'] if 'register_display_name' in session: del session['register_display_name'] if 'challenge' in session: del session['challenge'] if 'att_option' in session: del session['att_option'] if username == "" or username is None: username = util.random_username(8) if display_name == "" or display_name is None: display_name = username session['register_username'] = username session['register_display_name'] = display_name rp_name = RP_ID challenge = util.generate_challenge(32) ukey = util.generate_ukey() session['challenge'] = challenge session['register_ukey'] = ukey exclude_credentialids = [] webauthn_options = webauthn.WebAuthnOptions() try: options = Options.query.filter_by(rp_id=RP_ID).first() if options is None: options = Options() options.rp_id = RP_ID options.version = CURRENT_OPTIONS_TBL_VERSION options.option_content = json.dumps(webauthn_options.get()) db.session.add(options) db.session.commit() else: if options.version != CURRENT_OPTIONS_TBL_VERSION: return make_response( jsonify({'fail': 'Options Table Version Error.'}), 400) except Exception as e: return make_response( jsonify({'fail': 'Options Database Error: {}'.format(e)}), 500) webauthn_options.set(json.loads(options.option_content)) if webauthn_options.enableAttestationExcludeCredentials == 'true' and len( webauthn_options.attestationExcludeCredentialsUsers): users = Users.query.filter( Users.id.in_( webauthn_options.attestationExcludeCredentialsUsers)).all() for user in users: if not user.credential_id: app.logger.debug('Unknown credential ID.') return make_response( jsonify({'fail': 'Unknown credential ID.'}), 401) exclude_credentialids.append(str(user.credential_id)) make_credential_options = webauthn.WebAuthnMakeCredentialOptions( webauthn_options, exclude_credentialids, challenge, rp_name, RP_ID, ukey, username, display_name, 'https://example.com') reg_dict = json.dumps(make_credential_options.registration_dict, indent=2) session['att_option'] = reg_dict return make_response(jsonify(make_credential_options.registration_dict), 200)