Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No biometric attestation after creating publicKeyCredential #226

Open
droider91 opened this issue Dec 13, 2022 · 7 comments
Open

No biometric attestation after creating publicKeyCredential #226

droider91 opened this issue Dec 13, 2022 · 7 comments

Comments

@droider91
Copy link

droider91 commented Dec 13, 2022

First of all thanks for the awesome future ready feature @push2085 @arshadnoor
Here is what I am doint in my android application.

  1. I am hitting the pre register api and getting this data
    {"Response":{"rp":{"name":"FIDOServer","id":"fidoidqa.com"},"user":{"name":"devendra","id":"s5wXaholuoVwk86KQ0d_hmIxOkQPNS-bBBes8X4Cex8","displayName":"devendraLiapC"},"challenge":"COJ03Ch_6KDjlvnZ1jg_Qw","pubKeyCredParams":[{"type":"public-key","alg":-7},{"type":"public-key","alg":-35},{"type":"public-key","alg":-36},{"type":"public-key","alg":-8},{"type":"public-key","alg":-47},{"type":"public-key","alg":-257},{"type":"public-key","alg":-258},{"type":"public-key","alg":-259},{"type":"public-key","alg":-37},{"type":"public-key","alg":-38},{"type":"public-key","alg":-38}],"excludeCredentials":[{"type":"public-key","id":"NEVDOUQzNkMzMDBEM0U3MS1FNDczNTQ3QUVDRDQ1ODRELTk1MEJFOTM2NTI5MEIxNjctMTIxNkNFQjY1ODIzQTI5OQ","alg":-7},{"type":"public-key","id":"MUUzMDY0RkNGQUZEOTM5Ni1FMzlFOUM2MkUwOTQ4NzcwLTA0NzUyMEFBREM0ODUwM0UtMEU4ODdFOEFCRjFCMDE3QQ","alg":-7},{"type":"public-key","id":"hhkXnYmUiu_bzLy5HPHJvZs6TQA-302jRdeLHBgpL40","alg":-257}],"attestation":"direct"}}
  2. Then with this response I am creating the PreregisterChallenge
    var preregisterChallenge = PreregisterChallenge() val authenticatorSelectionCriteria = AuthenticatorSelectionCriteria() authenticatorSelectionCriteria.authenticatorAttachment = "Android" authenticatorSelectionCriteria.isRequireResidentKey = true authenticatorSelectionCriteria.userVerification = "required" val authSelectionJson = Gson().toJson(authenticatorSelectionCriteria) val myCustomArray: JsonArray = Gson().toJsonTree(userData.Response?.pubKeyCredParams).asJsonArray preregisterChallenge.apply { id = 100 uid = 1001 did = 1003 rpid = userData.Response?.rp?.id userid = "1001" username = "devendra" displayName = "devendra" challenge = userData.Response?.challenge authenticatorSelectionJSONObject = JSONObject(authSelectionJson) authenticatorSelection = authSelectionJson publicKeyCredentialParams = myCustomArray.toString() credParamsJSONArray = JSONArray(myCustomArray.toString()) }
    and passing this challenge like this
    val publicKeyCredential = AuthenticatorMakeCredential.execute( ContextWrapper(context), preregisterChallenge, "fidoidqa.com" ) as PublicKeyCredential
    I am getting the publickKeyCredential without any error
    then I am creating preauth challenge
    var preauthenticateChallenge = PreauthenticateChallenge() preauthenticateChallenge.apply { id = 100 uid = 1001 did = 1003 rpid = userData.Response?.rp?.id challenge = userData.Response?.challenge } // Generate the digital signature val sign = AuthenticatorGetAssertion.execute( ContextWrapper(context), preauthenticateChallenge, publicKeyCredential, 1, "fidoidqa.com" )
    But in this process I am not getting the biometric prompt to sign the public key.

Here is what I want to do

  1. user hits the pre register api,
  2. user received the response and challenge data
  3. app created the pub key cred
  4. now user have to prove his identity using biometric and sign the pub key credential
  5. then I will call the register api
    and on another screen same user will again prove his presence to any transaction

Please let me know where I am doing wrong in code or what is the process to do the above points
Thanks again

@push2085
Copy link
Contributor

Hi @droider91 ,
Here is the flow you need to follow to work with SKFS

  1. Call the preregister API to get the challenge (Which you are already doing)

  2. The application now uses the response from the fido server and makes the create credential call (which i believe you are doing as well)

  3. You now need to call the Register API and register the new credential with the FIDO server. (I believe you may be missing this step).

  4. Only when the fido server has successfully stored the new credential, you can call the preauthenticate challenge.

Let me know if you are making the register call before making any preauthenticate calls.

Thank you
Pushkar

@droider91
Copy link
Author

droider91 commented Dec 14, 2022

Hello @push2085
Thanks for your reply
As you said for point number 3, I was not calling the register api(as I am not aware of the flow)
Now After creating the public key credential
I called api with this request.
{ "username": "devendra", "clientUri": "fidoid.com", "authenticatorData": { "id": "", "rawId": "", "response": { "attestationObject": "", "clientDataJSON": "" }, "type": "public-key" } }
I am extracting these values from the PublicKeyCredential
And received the response success.
Now what is the next step?
Also I have one doubt is that the pub key cred I sent to server is without attested like I did not touch biometric.
So my doubt is When I will be asked to do the biometric check?

@push2085
Copy link
Contributor

Hi @droider91 ,
Based on what kind of application you are creating you may have to call different API's to register a FIDO credential but regardless the steps will remain the same.

  1. Call pre register API on SKFS to get challenge
  2. Take the response from step 1 and call the FIDO2 API (platform dependent) to create credential
  3. Call register API on SKFS to save the credential.
    After this
  4. Call pre authenticate API on SKFS to get challenge
  5. Take the response from step 4 and call the FIDO2 API (platform dependent) to get assertion.
  6. Call the authenticate API on SKFS to verify assertion.

If you are creating a web application, take a look at one of our sample applications for javascript sample to make the FIDO calls
(https://github.com/StrongKey/fido2/blob/master/sampleapps/java/basic/server/src/main/webapp/js/fido2demo.js)

If you are making a iOS application, you can look at our sample iOS app to look at how to make fido calls (https://github.com/StrongKey/fido2/tree/master/sampleapps/swift/StrongKeyFIDODemo)

If you are creating an android application, you can look at our sample SACL application for code snippets (https://github.com/StrongKey/fido2/tree/master/sampleapps/java/sacl/mobile/android) or go to android fido2 api (https://developers.google.com/identity/fido/android/native-apps).

In all of above when you make a make credential call, you have to pass in options, which will determine what kind of authenticator will be registered.

If your device supports biometrics and is enabled, it should prompt you for it.

Also do this for the next test, on the FIDO server, enable fine logging (in a terminal)
shell> asadmin set-log-levels SKFS=FINE

Run a registration and capture logs for the specific transaction from /usr/local/strongkey/payara5/glassfish/domains/domain1/logs/server.log

Attach the log to this issue and I can look and let you know what kind of registration was processed.

Thank you
Pushkar

@droider91
Copy link
Author

Hello @push2085
As you directed above,

  1. Called preAuthenticate API and created preauthenticate challenge like this
    var preauthenticateChallenge = PreauthenticateChallenge() preauthenticateChallenge.apply { id = 100 uid = 1001 did = 1003 rpid = authData.Response?.rpId challenge = authData.Response?.challenge allowCredentialsJSONArray = JSONArray(Gson().toJsonTree(authData.Response?.allowCredentials).toString()) allowCredentials = JSONArray( Gson().toJsonTree(authData.Response?.allowCredentials).toString() ).toString() }
    And then created the authenticateSignature
    sign = AuthenticatorGetAssertion.execute( ContextWrapper(context), preauthenticateChallenge, publicKeyCredential, 1, "https://fidoid.com" ) as AuthenticationSignature

and get Signature object from
` val fidoImpl = FidoAuthenticatorImpl(context)

        val bioSignature = fidoImpl.getSignatureObject(
            publicKeyCredential?.credentialId,
            ContextWrapper(context)
        ) as Signature`

and passed this bioSignature to biometric prompt
and finally if biometric success
{"clientUri":"https://dev-sp42.compactidentityqa.com","publicKeyCredential":{"id":"eeyJrZXluYW1lIjoiM0RBM0U1MzcxNzEyMjg5MC1FMUFBQjZDNkI4OUM5QjFBLUQyODJEQTY5RUMzMkQxQ0YtODMzN0IyRTczRTk2NTE1MCIsIm9yaWdpbiI6IkdFTkVSQVRFRCIsImFsZ29yaXRobSI6IkVDIFtzZWNwMjU2cjFdIiwic2l6ZSI6MjU2LCJ1c2VyYXV0aCI6dHJ1ZSwic2Vtb2R1bGUiOiJ0cnVlIFtUUlVTVEVEX0VYRUNVVElPTl9FTlZJUk9OTUVOVF0iLCJwdWJsaWNrZXkiOiIzMDU5MzAxMzA2MDcyYTg2NDhjZTNkMDIwMTA2MDgyYTg2NDhjZTNkMDMwMTA3MDM0MjAwMDQ1NmRlYjcxNjhjOTkxNTAzNjE3MzNiNzIwNDE4ZGE1MTY2ODgxNDFjNGY4MjFkMWI3NzE3MTljZGI2OWQ5MGVhYzk3ZDJlNGJkZWM4MDI3NGE0ZDc1NDVlMTkyMmJhMmNlYzc1NjYwYmEyZTFkZjIxYWU4NDRjZDU5ZDhhODFlMCJ9","rawId":"eyJrZXluYW1lIjoiM0RBM0U1MzcxNzEyMjg5MC1FMUFBQjZDNkI4OUM5QjFBLUQyODJEQTY5RUMzMkQxQ0YtODMzN0IyRTczRTk2NTE1MCIsIm9yaWdpbiI6IkdFTkVSQVRFRCIsImFsZ29yaXRobSI6IkVDIFtzZWNwMjU2cjFdIiwic2l6ZSI6MjU2LCJ1c2VyYXV0aCI6dHJ1ZSwic2Vtb2R1bGUiOiJ0cnVlIFtUUlVTVEVEX0VYRUNVVElPTl9FTlZJUk9OTUVOVF0iLCJwdWJsaWNrZXkiOiIzMDU5MzAxMzA2MDcyYTg2NDhjZTNkMDIwMTA2MDgyYTg2NDhjZTNkMDMwMTA3MDM0MjAwMDQ1NmRlYjcxNjhjOTkxNTAzNjE3MzNiNzIwNDE4ZGE1MTY2ODgxNDFjNGY4MjFkMWI3NzE3MTljZGI2OWQ5MGVhYzk3ZDJlNGJkZWM4MDI3NGE0ZDc1NDVlMTkyMmJhMmNlYzc1NjYwYmEyZTFkZjIxYWU4NDRjZDU5ZDhhODFlMCJ9","response":{"authenticatorData":"30aa545e970026ca59b4d0ed9f1c185c577c10074891316b19aab7e900404905dc400000001cafebabecafebeef0123456789abcdef0043334441334535333731373132323839302d453141414236433642383943394231412d443238324441363945433332443143462d38333337423245373345393635313530a501020326200121582056deb7168c99150361733b720418da516688141c4f821d1b771719cdb69d90ea225820c97d2e4bdec80274a4d7545e1922ba2cec75660ba2e1df21ae844cd59d8a81e0a16375766d8183040601","clientDataJSON":"eeyJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIiwiY2hhbGxlbmdlIjoiMU5KMWlCX0kwRC11ZWdDLXBWMll0USIsIm9yaWdpbiI6Imh0dHBzOlwvXC9kZXYtc3A0Mi5jb21wYWN0aWRlbnRpdHlxYS5jb20iLCJ0b2tlbkJpbmRpbmciOnsic3RhdHVzIjoibm90LXN1cHBvcnRlZCJ9fQ","signature":"MEUCIQCOISSwxKDfDReMgYXZ589W8UOqG8gNWUC-U6T1t240rwIgMfEBJmgf_xC2nqvndcI8EHg9aHNSkDdMvLha0QTUn14","userHandle":""},"type":"public-key"},"username":"devendra"}

Is this correct process?

@push2085
Copy link
Contributor

Hi @droider91,
Theoretically it is the right process but you should verify with the server and see if it succeds or fails and paste errors here if you cannot figure out the problem

Thank you
Pushkar

@droider91
Copy link
Author

Hello @push2085 Thank you for your support
But I want to develop same app with iOS, In that case would you please elaborate the flow theoretically for iOS, not complete code but classes name with uses.

@StrongKeyAbhishek
Copy link

Hi @droider91,
The flow remains the same regardless of the platform and the only variable is how to call the WebAuthn API on each platform. On web you make the JavaScript calls. On Android you can call the Android fido2 API. On iOS/macOS Apple has their Public-Private Key Authentication APIs which support both Passkeys and Security Keys.
You can take a look at our iOS Demo Application on how we used Apple's API with SKFS to support Passkeys and Security Keys in a Native iOS application.

Thanks,
Abhishek

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants