def test_get_not_matching_rpid(): """test get not mathcing rpid""" device = SoftWebauthnDevice() device.cred_init('rpid', b'randomhandle') pkcro = copy.deepcopy(PKCRO) pkcro['publicKey']['rpId'] = 'another_rpid' with pytest.raises(ValueError): device.get(pkcro, 'https://example.org')
def test_login_webauthn(live_server, selenium, webauthn_credential_factory): # pylint: disable=unused-argument """test login by webauthn""" device = SoftWebauthnDevice() device.cred_init(webauthn.rp.id, b'randomhandle') wncred = webauthn_credential_factory.create(initialized_device=device) # factory post_generate does not call commit to propagate self.attr changes, that messes the actual db state when # accessing from different process such as real browser db.session.commit() selenium.get(url_for('auth.login_route', _external=True)) selenium.find_element_by_xpath( '//form//input[@name="username"]').send_keys(wncred.user.username) selenium.find_element_by_xpath('//form//input[@type="submit"]').click() # some javascript code must be emulated webdriver_waituntil(selenium, js_variable_ready('window.pkcro_raw')) pkcro = cbor.decode( b64decode( selenium.execute_script('return window.pkcro_raw;').encode( 'utf-8'))) assertion = device.get(pkcro, 'https://%s' % webauthn.rp.id) selenium.execute_script( 'authenticate_assertion(CBOR.decode(Sner.base64_to_array_buffer("%s")));' % b64encode(cbor.encode(assertion)).decode('utf-8')) # and back to standard test codeflow webdriver_waituntil( selenium, EC.presence_of_element_located((By.XPATH, '//a[text()="Logout"]')))
def test_login_webauthn(live_server, selenium, test_user): # pylint: disable=unused-argument """test login by webauthn""" device = SoftWebauthnDevice() device.cred_init(webauthn.rp.id, b'randomhandle') persist_and_detach( WebauthnCredential(user=test_user, user_handle=device.user_handle, credential_data=cbor.encode( device.cred_as_attested().__dict__))) selenium.get(url_for('auth.login_route', _external=True)) selenium.find_element_by_xpath( '//form//input[@name="username"]').send_keys(test_user.username) selenium.find_element_by_xpath('//form//input[@type="submit"]').click() # some javascript code must be emulated webdriver_waituntil(selenium, js_variable_ready('window.pkcro_raw')) pkcro = cbor.decode( b64decode( selenium.execute_script('return window.pkcro_raw;').encode( 'utf-8'))) assertion = device.get(pkcro, 'https://%s' % webauthn.rp.id) selenium.execute_script( 'authenticate_assertion(CBOR.decode(Sner.base64_to_array_buffer("%s")));' % b64encode(cbor.encode(assertion)).decode('utf-8')) # and back to standard test codeflow webdriver_waituntil( selenium, EC.presence_of_element_located((By.XPATH, '//a[text()="Logout"]')))
def test_login_webauthn(client, webauthn_credential_factory): """test login by webauthn""" device = SoftWebauthnDevice() device.cred_init(webauthn.rp.id, b'randomhandle') wncred = webauthn_credential_factory.create(initialized_device=device) form = client.get(url_for('auth.login_route')).form form['username'] = wncred.user.username response = form.submit() assert response.status_code == HTTPStatus.FOUND response = response.follow() # some javascript code muset be emulated pkcro = cbor.decode( b64decode( client.post(url_for('auth.login_webauthn_pkcro_route'), { 'csrf_token': get_csrf_token(client) }).body)) assertion = device.get(pkcro, f'https://{webauthn.rp.id}') assertion_data = { 'credentialRawId': assertion['rawId'], 'authenticatorData': assertion['response']['authenticatorData'], 'clientDataJSON': assertion['response']['clientDataJSON'], 'signature': assertion['response']['signature'], 'userHandle': assertion['response']['userHandle'] } form = response.form form['assertion'] = b64encode(cbor.encode(assertion_data)) response = form.submit() # and back to standard test codeflow assert response.status_code == HTTPStatus.FOUND response = client.get(url_for('index_route')) assert response.lxml.xpath('//a[text()="Logout"]')
def test_get(): """test get""" device = SoftWebauthnDevice() device.cred_init(PKCRO['publicKey']['rpId'], b'randomhandle') assertion = device.get(PKCRO, 'https://example.org') assert assertion device.private_key.public_key().verify( assertion['response']['signature'], assertion['response']['authenticatorData'] + sha256(assertion['response']['clientDataJSON']), ec.ECDSA(hashes.SHA256()))
def test_authenticate(): """test authentication""" device = SoftWebauthnDevice() device.cred_init('example.org', b'randomhandle') registered_credential = device.cred_as_attested() server = Fido2Server( PublicKeyCredentialRpEntity('example.org', 'test server')) options, state = server.authenticate_begin([registered_credential]) assertion = device.get(options, 'https://example.org') server.authenticate_complete( state, [registered_credential], assertion['rawId'], ClientData(assertion['response']['clientDataJSON']), AuthenticatorData(assertion['response']['authenticatorData']), assertion['response']['signature'])
def test_webauthn_authenticate(test_client, init_database): sign_in_response = sign_in(test_client, "jennie", "9df1c362e4df3e51edd1acde9") device = SoftWebauthnDevice() user = User.query.filter_by(username="******").first() webauthn = Webauthn.query.filter_by(user_id=user.did).first() user_handle = webauthn.user_identifier device.cred_init(TestConfig.RP_ID, user_handle) device.private_key = KeyList.priv_one user5_first_security_key_public_key = ES256.from_cryptography_key( device.private_key.public_key()) key = (Key.query.filter_by(user_id=user.did).filter_by( public_key=cbor.encode(user5_first_security_key_public_key)).first()) device.credential_id = key.credential_id pkcro = cbor.decode(test_client.post("/webauthn/authenticate/begin").data) assertion = device.get(pkcro, f"https://{TestConfig.RP_ID}") assertion_data = cbor.encode({ "credentialId": assertion["rawId"], "clientDataJSON": assertion["response"]["clientDataJSON"], "authenticatorData": assertion["response"]["authenticatorData"], "signature": assertion["response"]["signature"], "userHandle": assertion["response"]["userHandle"], }) raw_response = test_client.post( "/webauthn/authenticate/complete", input_stream=BytesIO(assertion_data), content_type="application/cbor", ) authentication_response = cbor.decode(raw_response.data) assert authentication_response == {"status": "OK"} settings_response = test_client.get("/settings") assert settings_response.status_code == 200
def test_example_server_authentication(client): # pylint: disable=redefined-outer-name """Authentication example""" # Already registered credential is typicaly part of fixture test-case code. # # NOTE: the storage of the credential data on the RP side is not in scope # of Webauthn spec. Yubico example server uses module scoped variable. device = SoftWebauthnDevice() device.cred_init('localhost', b'randomhandle') tests.example_server.credentials = [device.cred_as_attested()] # Browser starts authentication by requesting # publicKeyCredentialRequestOptions (pkcro) from the RP. pkcro = cbor.decode(client.post('/api/authenticate/begin').data) print('publicKeyCredentialRequestOptions: ', pkcro) # publicKeyCredentialRequestOptions object is passed to the authenticator, # which performs requester user verification and return credential object # (assertion). assertion = device.get(pkcro, 'https://localhost') print('credential assertion: ', assertion) # Browser conveys assertion data to the RP for authentication. assertion_data = cbor.encode({ 'credentialId': assertion['rawId'], 'clientDataJSON': assertion['response']['clientDataJSON'], 'authenticatorData': assertion['response']['authenticatorData'], 'signature': assertion['response']['signature'], 'userHandle': assertion['response']['userHandle'] }) raw_response = client.post( '/api/authenticate/complete', input_stream=BytesIO(assertion_data), content_type='application/cbor' ) authentication_response = cbor.decode(raw_response.data) print('authentication response:', authentication_response) # RP will verify assertion and on success proceeds with user logon. assert authentication_response == {'status': 'OK'}
def test_webauthn_login_route(client, test_user): """test login by webauthn""" device = SoftWebauthnDevice() device.cred_init(webauthn.rp.ident, b'randomhandle') persist_and_detach( WebauthnCredential(user=test_user, user_handle=device.user_handle, credential_data=cbor.encode( device.cred_as_attested().__dict__))) form = client.get(url_for('app.login_route')).form form['username'] = test_user.username response = form.submit() assert response.status_code == HTTPStatus.FOUND response = response.follow() # some javascript code muset be emulated pkcro = cbor.decode( b64decode( client.post(url_for('app.webauthn_pkcro_route'), { 'csrf_token': get_csrf_token(client) }).body)) assertion = device.get(pkcro, 'https://%s' % webauthn.rp.ident) assertion_data = { 'credentialRawId': assertion['rawId'], 'authenticatorData': assertion['response']['authenticatorData'], 'clientDataJSON': assertion['response']['clientDataJSON'], 'signature': assertion['response']['signature'], 'userHandle': assertion['response']['userHandle'] } form = response.form form['assertion'] = b64encode(cbor.encode(assertion_data)) response = form.submit() # and back to standard test codeflow assert response.status_code == HTTPStatus.FOUND response = client.get(url_for('app.index_route')) assert response.lxml.xpath('//a[text()="Logout"]')