StrongKey / fido2

Open-source FIDO server, featuring the FIDO2 standard. https://demo4.strongkey.com/getstarted/#/openapi/fido
204 stars 59 forks source link

SKFS register failed. An error happened: "FIDO-ERR-2001: FIDO 2 Error Message : {0}Registration Signature verification : false" #201

Open kimo6416337 opened 2 years ago

kimo6416337 commented 2 years ago

I wrote a C-language program which does FIDO register flow on a private SKFS. My preregister flow works well but meet the "FIDO-ERR-2001: FIDO 2 Error Message : {0}Registration Signature verification : false" error. I don't know why. This program calls pregister and register APIs by using system call on curl command. When the program receives the preregister response (such as challenge, rp info, user info, etc), it sends to the external FIDO authenticator (Yubico USB key) by python-libfido2 library. I also wrote a python code to do this. The partial code is as below.

client = Fido2Client(dev, origin, user_interaction=CliInteraction())
create_options = {
    "publicKey": PublicKeyCredentialCreationOptions(
        **pub_key_cred_creation_options
    )
}
result = client.make_credential(create_options["publicKey"])

The program receives the information such as client data and attestation object. Next, I need to create the clientDataJSON and attestationObject strings. The clientDataJSON is as below.

client_data = {}
client_data["type"] = result.client_data.type
client_data["challenge"] = result.client_data.challenge.decode('utf-8')
client_data["origin"] = result.client_data.origin
client_data["cross_origin"] = result.client_data.cross_origin
clientDataJSON  = base64UrlEncode(json.dumps(client_data).encode('utf-8')).decode('utf-8')

The attestationObject is as below. It consists of different parts of information (fmt, authData, attStmt). attStmt is a dictionary object.

att_stmt["alg"] = result.attestation_object.att_stmt['alg']
att_stmt["sig"] = result.attestation_object.att_stmt['sig']
att_stmt["x5c"] = result.attestation_object.att_stmt['x5c']
attestation_object["attStmt"] = att_stmt

fmt is a string.

attestation_object["fmt"] = result.attestation_object.fmt

authData is a bytes-type object. Because python-libfido2 returns a class object, I need to combine the bytes data by referring to the webauthn spec.

str_aaguid = result.attestation_object.auth_data.credential_data.aaguid.__str__().replace('-', '')
intlist_aaguid = [ int(str_aaguid[2*i:2*i+2], 16) for i in range(0, int(len(str_aaguid)/2)) ]
bytes_aaguid = bytes(intlist_aaguid)
credential_data = bytes_aaguid
credential_data += \
    len(list(result.attestation_object.auth_data.credential_data.credential_id)).to_bytes(2, byteorder='big')
credential_data += result.attestation_object.auth_data.credential_data.credential_id
if result.attestation_object.auth_data.credential_data.public_key[1] == 2:
    credential_data += createCOSEEC2PublicKey(result.attestation_object.auth_data.credential_data.public_key)
auth_data = result.attestation_object.auth_data.rp_id_hash
auth_data += result.attestation_object.auth_data.flags.to_bytes(1, byteorder='big')
auth_data += result.attestation_object.auth_data.counter.to_bytes(4, byteorder='big')
auth_data += credential_data
attestation_object["authData"] = auth_data

Finally, CBOR-encode the atteestationObject.

cbor_data = cbor2.dumps(attestation_object)
atteestationObject= base64UrlEncode(cbor_data).decode('utf-8')

The problem is when the C program sends origin, credential id, clientDataJSON, and attestationObject to the register endpoint of SKFS, the "Registration Signature verification : false" error happens.

I've checked the glassfish log of SKFS, but I still don't know why because I'm not familiar with Java language and the source code of SKFS. A part of the glassfish log is as below.

[2022-08-04T03:11:05.049-0400] [Payara 5.2020.7] [INFO] [] [] [tid: _ThreadID=71 _ThreadName=http-thread-pool::http-listener-2(9)] [timeMillis: 1659597065049] [levelValue: 800] [[
  rpidhashfrompolicy = S/ybIkMj6soGXSAwVHmFMPZKG+S8Gt+tqPZJWxgsodc=]]

[2022-08-04T03:11:05.057-0400] [Payara 5.2020.7] [SEVERE] [FIDO-ERR-0015] [SKFS] [tid: _ThreadID=71 _ThreadName=http-thread-pool::http-listener-2(9)] [timeMillis: 1659597065057] [levelValue: 1000] [[
  FIDO-ERR-0015: User signature could not be verified: Failed to verify Packed signature]]

[2022-08-04T03:11:05.057-0400] [Payara 5.2020.7] [SEVERE] [FIDO-MSG-2001] [SKFS] [tid: _ThreadID=71 _ThreadName=http-thread-pool::http-listener-2(9)] [timeMillis: 1659597065057] [levelValue: 1000] [[
  FIDO-MSG-2001: FIDO 2 Debug Message : Registration Signature verification : false]]

[2022-08-04T03:11:05.058-0400] [Payara 5.2020.7] [SEVERE] [] [SKFS] [tid: _ThreadID=71 _ThreadName=http-thread-pool::http-listener-2(9)] [timeMillis: 1659597065058] [levelValue: 1000] [[
  FIDO-ERR-2001: FIDO 2 Error Message : {"Response":"FIDO-ERR-2001: FIDO 2 Error Message : {0}Registration Signature verification : false"}]]

[2022-08-04T03:11:05.058-0400] [Payara 5.2020.7] [SEVERE] [] [] [tid: _ThreadID=71 _ThreadName=http-thread-pool::http-listener-2(9)] [timeMillis: 1659597065058] [levelValue: 1000] [[
  com.strongkey.skfs.utilities.SKIllegalArgumentException: {"Response":"FIDO-ERR-2001: FIDO 2 Error Message : {0}Registration Signature verification : false"}
        at com.strongkey.skfs.txbeans.FIDO2RegistrationBean.execute(FIDO2RegistrationBean.java:127)
        at sun.reflect.GeneratedMethodAccessor272.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

Thus, can anyone help to solve the problem? Thanks!

arshadnoor commented 2 years ago

Lighthope,

If I understand your flow, it sounds like you are NOT using FIDO for authenticating users through a web-browser - you are using the Python library to relay messages between the Authenticator and the SKFS; is that correct?

On 8/14/22 1:55 AM, Lighthope wrote:

I wrote a C-language program which does FIDO register flow on a private SKFS. My preregister flow works well but meet the "FIDO-ERR-2001: FIDO 2 Error Message : {0}Registration Signature verification : false" error. I don't know why. This program calls pregister and register APIs by using system call on curl command. When the program receives the preregister response (such as challenge, rp info, user info, etc), it sends to the external FIDO authenticator (Yubico USB key) by python-libfido2 https://github.com/Yubico/python-fido2 library. I also wrote a python code to do this. The partial code is as below.

|client = Fido2Client(dev, origin, user_interaction=CliInteraction()) create_options = { "publicKey": PublicKeyCredentialCreationOptions( **pub_key_cred_creation_options ) } result = client.make_credential(create_options["publicKey"]) |

The program receives the information such as client data and attestation object. Next, I need to create the clientDataJSON and attestationObject strings. The clientDataJSON is as below.

|client_data = {} client_data["type"] = result.client_data.type client_data["challenge"] = result.client_data.challenge.decode('utf-8') client_data["origin"] = result.client_data.origin client_data["cross_origin"] = result.client_data.cross_origin clientDataJSON = base64UrlEncode(json.dumps(client_data).encode('utf-8')).decode('utf-8') |

The attestationObject is as below. It consists of different parts of information (fmt, authData, attStmt). attStmt is a dictionary object.

|att_stmt["alg"] = result.attestation_object.att_stmt['alg'] att_stmt["sig"] = result.attestation_object.att_stmt['sig'] att_stmt["x5c"] = result.attestation_object.att_stmt['x5c'] attestation_object["attStmt"] = att_stmt |

fmt is a string.

|attestation_object["fmt"] = result.attestation_object.fmt |

authData is a bytes-type object. Because python-libfido2 returns a class object, I need to combine the bytes data by referring to the webauthn spec.

|str_aaguid = result.attestation_object.auth_data.credential_data.aaguid.str().replace('-', '') intlist_aaguid = [ int(str_aaguid[2i:2i+2], 16) for i in range(0, int(len(str_aaguid)/2)) ] bytes_aaguid = bytes(intlist_aaguid) credential_data = bytes_aaguid credential_data += \ len(list(result.attestation_object.auth_data.credential_data.credential_id)).to_bytes(2, byteorder='big') credential_data += result.attestation_object.auth_data.credential_data.credential_id if result.attestation_object.auth_data.credential_data.public_key[1] == 2: credential_data += createCOSEEC2PublicKey(result.attestation_object.auth_data.credential_data.public_key) auth_data = result.attestation_object.auth_data.rp_id_hash auth_data += result.attestation_object.auth_data.flags.to_bytes(1, byteorder='big') auth_data += result.attestation_object.auth_data.counter.to_bytes(4, byteorder='big') auth_data += credential_data attestation_object["authData"] = auth_data |

Finally, CBOR-encode the atteestationObject.

|cbor_data = cbor2.dumps(attestation_object) atteestationObject= base64UrlEncode(cbor_data).decode('utf-8') |

The problem is when the C program sends origin, credential id, clientDataJSON, and attestationObject to the register endpoint of SKFS, the "Registration Signature verification : false" error happens.

I've checked the glassfish log of SKFS, but I still don't know why because I'm not familiar with Java language and the source code of SKFS. A part of the glassfish log is as below.

[2022-08-04T03:11:05.049-0400] [Payara 5.2020.7] [INFO] [] [] [tid: _ThreadID=71 _ThreadName=http-thread-pool::http-listener-2(9)] [timeMillis: 1659597065049] [levelValue: 800] [[ rpidhashfrompolicy = S/ybIkMj6soGXSAwVHmFMPZKG+S8Gt+tqPZJWxgsodc=]] [2022-08-04T03:11:05.057-0400] [Payara 5.2020.7] [SEVERE] [FIDO-ERR-0015] [SKFS] [tid: _ThreadID=71 _ThreadName=http-thread-pool::http-listener-2(9)] [timeMillis: 1659597065057] [levelValue: 1000] [[ FIDO-ERR-0015: User signature could not be verified: Failed to verify Packed signature]] [2022-08-04T03:11:05.057-0400] [Payara 5.2020.7] [SEVERE] [FIDO-MSG-2001] [SKFS] [tid: _ThreadID=71 _ThreadName=http-thread-pool::http-listener-2(9)] [timeMillis: 1659597065057] [levelValue: 1000] [[ FIDO-MSG-2001: FIDO 2 Debug Message : Registration Signature verification : false]] [2022-08-04T03:11:05.058-0400] [Payara 5.2020.7] [SEVERE] [] [SKFS] [tid: _ThreadID=71 _ThreadName=http-thread-pool::http-listener-2(9)] [timeMillis: 1659597065058] [levelValue: 1000] [[ FIDO-ERR-2001: FIDO 2 Error Message : {"Response":"FIDO-ERR-2001: FIDO 2 Error Message : {0}Registration Signature verification : false"}]] [2022-08-04T03:11:05.058-0400] [Payara 5.2020.7] [SEVERE] [] [] [tid: _ThreadID=71 _ThreadName=http-thread-pool::http-listener-2(9)] [timeMillis: 1659597065058] [levelValue: 1000] [[ com.strongkey.skfs.utilities.SKIllegalArgumentException: {"Response":"FIDO-ERR-2001: FIDO 2 Error Message : {0}Registration Signature verification : false"} at com.strongkey.skfs.txbeans.FIDO2RegistrationBean.execute(FIDO2RegistrationBean.java:127) at sun.reflect.GeneratedMethodAccessor272.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

Thus, can anyone help to solve the problem? Thanks!

— Reply to this email directly, view it on GitHub https://github.com/StrongKey/fido2/issues/201, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABWSVTR7N5S5F2WXRRZLZJ3VZCYBDANCNFSM56PQJJRQ. You are receiving this because you are subscribed to this thread.Message ID: @.***>

kimo6416337 commented 2 years ago

@arshadnoor hi

Yes, I am not using a web browser to authenticate with FIDO authenticator. You can see my FIDO architecture picture as the follows. volume encryption-FIDO2 volume encryption - concept of phase 2 preregister-www drawio

I've also tried to hardcode the clientDataJSON and attestationObject, but still have the signature verification error. Slide17

push2085 commented 2 years ago

hi @kimo6416337,

While we are trying to figure out what might be the problem based on your code snippets above, can you also do the following and give us more details logs from the server log so that we can see if we get more details from it.

On the FIDO server: 1) Log in as 'strongkey' user 2) In a terminal window, change logging levels shell> asadmin set-log-levels SKFS=FINE shell> asadmin set-log-levels CRYPTO=FINE

3) Once this is done, in the same terminal window, tail the server logs: shell> tsl

4) At this point, try and run another transaction from your C program which should print more FINE level logs in the glassfish server which you can see in the terminal where you had 'tsl' running.

5) Capture the full glassfish log output from the terminal for your transaction and send it to us here either as an atttachment or just as text here and it may give us a little more information.

Thank you Pushkar

kimo6416337 commented 2 years ago

@push2085 A part of glassfish log is as attached. glassfish.log

push2085 commented 2 years ago

Hi While we look at the logs, can you share the options that get sent to the authenticator in the publickeycredentialcreateoptions as I suspect the client data passed in might be the issue because that is something that a client adds to the create request and that is something your c program is simulating.

kimo6416337 commented 2 years ago

@push2085 Sure. The content of PublicKeyCredentialCreationOptions is

{'publicKey': PublicKeyCredentialCreationOptions(rp=PublicKeyCredentialRpEntity(name='FIDOServer', id='howie2.fido.com'), user=PublicKeyCredentialUserEntity(name='johndoe', id=b'Bs3eUb4q_nz5xe93dLc50jnCMns6zu8ac8vx_6mSJjI', display_name=None), challenge=b'2yiG1m-DXiYfIEv8gf2Sgg', pub_key_cred_params=[PublicKeyCredentialParameters(type=<PublicKeyCredentialType.PUBLIC_KEY: 'public-key'>, alg=-7), PublicKeyCredentialParameters(type=<PublicKeyCredentialType.PUBLIC_KEY: 'public-key'>, alg=-35), PublicKeyCredentialParameters(type=<PublicKeyCredentialType.PUBLIC_KEY: 'public-key'>, alg=-36), PublicKeyCredentialParameters(type=<PublicKeyCredentialType.PUBLIC_KEY: 'public-key'>, alg=-8), PublicKeyCredentialParameters(type=<PublicKeyCredentialType.PUBLIC_KEY: 'public-key'>, alg=-47), PublicKeyCredentialParameters(type=<PublicKeyCredentialType.PUBLIC_KEY: 'public-key'>, alg=-257), PublicKeyCredentialParameters(type=<PublicKeyCredentialType.PUBLIC_KEY: 'public-key'>, alg=-258), PublicKeyCredentialParameters(type=<PublicKeyCredentialType.PUBLIC_KEY: 'public-key'>, alg=-259), PublicKeyCredentialParameters(type=<PublicKeyCredentialType.PUBLIC_KEY: 'public-key'>, alg=-37), PublicKeyCredentialParameters(type=<PublicKeyCredentialType.PUBLIC_KEY: 'public-key'>, alg=-38), PublicKeyCredentialParameters(type=<PublicKeyCredentialType.PUBLIC_KEY: 'public-key'>, alg=-38)], timeout=None, exclude_credentials=None, authenticator_selection=AuthenticatorSelectionCriteria(authenticator_attachment=None, resident_key=<ResidentKeyRequirement.DISCOURAGED: 'discouraged'>, user_verification=None, require_resident_key=False), attestation=<AttestationConveyancePreference.DIRECT: 'direct'>, extensions=None)}

And the content of Class PublicKeyCredentialCreationOptions, which is defined by python-libfido2 library.

class PublicKeyCredentialCreationOptions(_CamelCaseDataObject):
    rp: PublicKeyCredentialRpEntity
    user: PublicKeyCredentialUserEntity
    challenge: bytes
    pub_key_cred_params: Sequence[PublicKeyCredentialParameters] = field(
        metadata=dict(deserialize=PublicKeyCredentialParameters._deserialize_list),
    )
    timeout: Optional[int] = None
    exclude_credentials: Optional[Sequence[PublicKeyCredentialDescriptor]] = field(
        default=None,
        metadata=dict(deserialize=PublicKeyCredentialDescriptor._deserialize_list),
    )
    authenticator_selection: Optional[AuthenticatorSelectionCriteria] = None
    attestation: Optional[AttestationConveyancePreference] = None
    extensions: Optional[Mapping[str, Any]] = None

As I said, I still meet the error even if I hardcode the client data nad attestation object with the ones in a real-world working register request payload of a StrongKey policy module demo. Thus, I don't think it's python-libfido2's problem. Maybe I don't do correct encoding/decoding on my output to the SKFS, or incorrect format.

push2085 commented 2 years ago

We are still debugging this to figure out what's wrong. Here is my current theory, the signature is calculated over the concatenation of Auth data byte array and client data byte array so is it possible that when the library is calculating the client data before it generates the signature, it's using different data compared to what you are sending in the response and that is why it's failing?

Also what you I suggest you also do is to follow these steps (https://docs.strongkey.com/index.php/skfs-home/skfs-usage/policy-module-demo/skfs-installation-with-fido2-same) on your local fido server machine to install the sample app locally to make sure the fido key works on this sample app on a browser based application. This will eliminate any problems with the install itself and will come down to debugging the right format of the data being sent.

kimo6416337 commented 2 years ago

@push2085 I can register/login with the policy module demo based on my local SKFS. Screenshot 2022-08-16 155144 Screenshot 2022-08-16 155333 Screenshot 2022-08-16 155400 Screenshot 2022-08-16 155508

arshadnoor commented 2 years ago

So, this indicates that the Authenticator and the SKFS are working correctly when the browser and the FIDOPolicy webapp are used for registration/authentication. This narrows down the problem to either the Python library you are using, or the C-code you've written that integrates with the Python library.

To determine which one is causing the problem - and since you seem to know Python better than we do - have you tried testing your Python library configuration with the tests shown here - and in particular, this test?

If the tests pass correctly, then the Python library is probably not the problem; you may then want to look at the way the test code is passing its parameters to the Authenticator and compare it to the way your C-code is passing similar parameters to the Python library. You may also want to post an issue on the Python library forum to see if they have ideas on what's causing your response to be rejected by our FIDO server.

In general, the SKFS has rarely had issues with FIDO Certified Authenticators when used with supported browsers - most Authenticator programmers are familiar with SKFS since 2015 when the SKFS was one of the official FIDO servers used by the FIDO Alliance for certifying U2F Security Keys.

kimo6416337 commented 2 years ago

@arshadnoor @push2085
The unit tests of python-libfido2 pass, so we can think python-libfido2 is correct. You can see the result in the picture below. Screenshot 2022-08-16 223409

Now back to focus on my C code. I need some help to check the correction of the client data and attestation object. My C code calls SKFS' register restful API bby system call as follows:

/sbin/curl -X POST -k -H 'Content-Type: application/json' -d @/tmp/fido-register-999999.json https://howie2.fido.com:8181/skfs/rest/register 2>/dev/null

The content of posted json file (/tmp/fido-register-999999.json) is:

{"svcinfo":{"did":1,"protocol":"FIDO2_0","authtype":"PASSWORD","svcusername":"svcfidouser","svcpassword":"Abcd1234!"},"payload":{"strongkeyMetadata":{"version":"1.0","create_location":"Sunnyvale,CA","username":"johndoe","origin":"https://howie2.fido.com"},"publicKeyCredential":{"id":"4fFgUe2Wl9cP-Kq65lWLz5lSGPs4USSIb0zfzLUyFcvjHY7pouTiTRysmtNxFv3L1lgpTNaXyz-53ZPj5iIAEw","rawId":"4fFgUe2Wl9cP-Kq65lWLz5lSGPs4USSIb0zfzLUyFcvjHY7pouTiTRysmtNxFv3L1lgpTNaXyz-53ZPj5iIAEw","response":{"attestationObject":"o2NmbXRmcGFja2VkZ2F0dFN0bXSjY2FsZyZjc2lnWEcwRQIgR7Dt7kvEQ4D37AvGi6QFM-cJWQYXj64i3KtkWtmRheUCIQD6XmhXCzawqC1xqw5a__PPMX6B23IRcMpUt2oGUBdxfGN4NWOBWQLdMIIC2TCCAcGgAwIBAgIJAPDqu31oBEyKMA0GCSqGSIb3DQEBCwUAMC4xLDAqBgNVBAMTI1l1YmljbyBVMkYgUm9vdCBDQSBTZXJpYWwgNDU3MjAwNjMxMCAXDTE0MDgwMTAwMDAwMFoYDzIwNTAwOTA0MDAwMDAwWjBvMQswCQYDVQQGEwJTRTESMBAGA1UECgwJWXViaWNvIEFCMSIwIAYDVQQLDBlBdXRoZW50aWNhdG9yIEF0dGVzdGF0aW9uMSgwJgYDVQQDDB9ZdWJpY28gVTJGIEVFIFNlcmlhbCAyMTA5NDY3Mzc2MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE5mfTO7qcRZuAnvzLaguuLFz8S9eB1XNIPZb96SUfZCzN5sIGVRTzM4JGrJlSgAAq0jivvANxttf6w7_LnnnSMKOBgTB_MBMGCisGAQQBgsQKDQEEBQQDBQQDMCIGCSsGAQQBgsQKAgQVMS4zLjYuMS40LjEuNDE0ODIuMS43MBMGCysGAQQBguUcAgEBBAQDAgQwMCEGCysGAQQBguUcAQEEBBIEEC_AV5-BE0fqsRa7Wo25ICowDAYDVR0TAQH_BAIwADANBgkqhkiG9w0BAQsFAAOCAQEAtjGoKNeTOK0pAIoNf3mjoD3PLgybH2L6z7SKnlWVd6dRbJWbZCsY8AxMdyKNGfnUQiJcEmi9IxigjGoXcwZPApnJm7JDike7Z7HQ2yUrlJZ-EgFamivp5C3UVCaIkGH-HyJW_vh23XOZMkaDcRqwbeq8b0Voavnu4YF5bCM7PtnsPcCsvfL5DahPGSfpc9YyANG49OQBOZolNF3MBKKrspOAI7RfW0JSQY0NUnWFYx9hxFbNuYsKFN4NblJ_Zz9tMk1YYSkTJ6VfxHTo5tfIcaLfZ1dIrMeY12-WevjMufFW_qB4ErY5Gjft3cbiZBELmbQ9QLUyLX78lHiLC9pJImhhdXRoRGF0YVjES_ybIkMj6soGXSAwVHmFMPZKG-S8Gt-tqPZJWxgsoddFAAAAAy_AV5-BE0fqsRa7Wo25ICoAQOHxYFHtlpfXD_iquuZVi8-ZUhj7OFEkiG9M38y1MhXL4x2O6aLk4k0crJrTcRb9y9ZYKUzWl8s_ud2T4-YiABOlAQIDJiABIVggsJ73hjh60y0jbwTVBtCZyw59oIIwRoazaoPA5rHnbLQiWCAimMd4RFXPPFaujZoqCJsRmUWTXdRzXl2C35-Z_CpCGg","clientDataJSON":"eyJ0eXBlIjogIndlYmF1dGhuLmNyZWF0ZSIsICJjaGFsbGVuZ2UiOiAiTlU0cEZjaDBlNldGTUtqVnljcFBEZyIsICJvcmlnaW4iOiAiaHR0cHM6Ly9ob3dpZTIuZmlkby5jb20iLCAiY3Jvc3Nfb3JpZ2luIjogZmFsc2V9"},"type":"public-key"}}}

After beautifying the format,

{
   "svcinfo":{
      "did":1,
      "protocol":"FIDO2_0",
      "authtype":"PASSWORD",
      "svcusername":"svcfidouser",
      "svcpassword":"Abcd1234!"
   },
   "payload":{
      "strongkeyMetadata":{
         "version":"1.0",
         "create_location":"Sunnyvale,CA",
         "username":"johndoe",
         "origin":"https://howie2.fido.com"
      },
      "publicKeyCredential":{
         "id":"4fFgUe2Wl9cP-Kq65lWLz5lSGPs4USSIb0zfzLUyFcvjHY7pouTiTRysmtNxFv3L1lgpTNaXyz-53ZPj5iIAEw",
         "rawId":"4fFgUe2Wl9cP-Kq65lWLz5lSGPs4USSIb0zfzLUyFcvjHY7pouTiTRysmtNxFv3L1lgpTNaXyz-53ZPj5iIAEw",
         "response":{
            "attestationObject":"o2NmbXRmcGFja2VkZ2F0dFN0bXSjY2FsZyZjc2lnWEcwRQIgR7Dt7kvEQ4D37AvGi6QFM-cJWQYXj64i3KtkWtmRheUCIQD6XmhXCzawqC1xqw5a__PPMX6B23IRcMpUt2oGUBdxfGN4NWOBWQLdMIIC2TCCAcGgAwIBAgIJAPDqu31oBEyKMA0GCSqGSIb3DQEBCwUAMC4xLDAqBgNVBAMTI1l1YmljbyBVMkYgUm9vdCBDQSBTZXJpYWwgNDU3MjAwNjMxMCAXDTE0MDgwMTAwMDAwMFoYDzIwNTAwOTA0MDAwMDAwWjBvMQswCQYDVQQGEwJTRTESMBAGA1UECgwJWXViaWNvIEFCMSIwIAYDVQQLDBlBdXRoZW50aWNhdG9yIEF0dGVzdGF0aW9uMSgwJgYDVQQDDB9ZdWJpY28gVTJGIEVFIFNlcmlhbCAyMTA5NDY3Mzc2MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE5mfTO7qcRZuAnvzLaguuLFz8S9eB1XNIPZb96SUfZCzN5sIGVRTzM4JGrJlSgAAq0jivvANxttf6w7_LnnnSMKOBgTB_MBMGCisGAQQBgsQKDQEEBQQDBQQDMCIGCSsGAQQBgsQKAgQVMS4zLjYuMS40LjEuNDE0ODIuMS43MBMGCysGAQQBguUcAgEBBAQDAgQwMCEGCysGAQQBguUcAQEEBBIEEC_AV5-BE0fqsRa7Wo25ICowDAYDVR0TAQH_BAIwADANBgkqhkiG9w0BAQsFAAOCAQEAtjGoKNeTOK0pAIoNf3mjoD3PLgybH2L6z7SKnlWVd6dRbJWbZCsY8AxMdyKNGfnUQiJcEmi9IxigjGoXcwZPApnJm7JDike7Z7HQ2yUrlJZ-EgFamivp5C3UVCaIkGH-HyJW_vh23XOZMkaDcRqwbeq8b0Voavnu4YF5bCM7PtnsPcCsvfL5DahPGSfpc9YyANG49OQBOZolNF3MBKKrspOAI7RfW0JSQY0NUnWFYx9hxFbNuYsKFN4NblJ_Zz9tMk1YYSkTJ6VfxHTo5tfIcaLfZ1dIrMeY12-WevjMufFW_qB4ErY5Gjft3cbiZBELmbQ9QLUyLX78lHiLC9pJImhhdXRoRGF0YVjES_ybIkMj6soGXSAwVHmFMPZKG-S8Gt-tqPZJWxgsoddFAAAAAy_AV5-BE0fqsRa7Wo25ICoAQOHxYFHtlpfXD_iquuZVi8-ZUhj7OFEkiG9M38y1MhXL4x2O6aLk4k0crJrTcRb9y9ZYKUzWl8s_ud2T4-YiABOlAQIDJiABIVggsJ73hjh60y0jbwTVBtCZyw59oIIwRoazaoPA5rHnbLQiWCAimMd4RFXPPFaujZoqCJsRmUWTXdRzXl2C35-Z_CpCGg",
            "clientDataJSON":"eyJ0eXBlIjogIndlYmF1dGhuLmNyZWF0ZSIsICJjaGFsbGVuZ2UiOiAiTlU0cEZjaDBlNldGTUtqVnljcFBEZyIsICJvcmlnaW4iOiAiaHR0cHM6Ly9ob3dpZTIuZmlkby5jb20iLCAiY3Jvc3Nfb3JpZ2luIjogZmFsc2V9"
         },
         "type":"public-key"
      }
   }
}

But still meet signature verification error. Screenshot 2022-08-16 230513

Could you help to check if this calling restful API is legal? are the content of attestation object and client data json legal?

kimo6416337 commented 2 years ago

Could anyone answer my restful api problem?

@arshadnoor @push2085 The unit tests of python-libfido2 pass, so we can think python-libfido2 is correct. You can see the result in the picture below. Screenshot 2022-08-16 223409

Now back to focus on my C code. I need some help to check the correction of the client data and attestation object. My C code calls SKFS' register restful API bby system call as follows:

/sbin/curl -X POST -k -H 'Content-Type: application/json' -d @/tmp/fido-register-999999.json https://howie2.fido.com:8181/skfs/rest/register 2>/dev/null

The content of posted json file (/tmp/fido-register-999999.json) is:

{"svcinfo":{"did":1,"protocol":"FIDO2_0","authtype":"PASSWORD","svcusername":"svcfidouser","svcpassword":"Abcd1234!"},"payload":{"strongkeyMetadata":{"version":"1.0","create_location":"Sunnyvale,CA","username":"johndoe","origin":"https://howie2.fido.com"},"publicKeyCredential":{"id":"4fFgUe2Wl9cP-Kq65lWLz5lSGPs4USSIb0zfzLUyFcvjHY7pouTiTRysmtNxFv3L1lgpTNaXyz-53ZPj5iIAEw","rawId":"4fFgUe2Wl9cP-Kq65lWLz5lSGPs4USSIb0zfzLUyFcvjHY7pouTiTRysmtNxFv3L1lgpTNaXyz-53ZPj5iIAEw","response":{"attestationObject":"o2NmbXRmcGFja2VkZ2F0dFN0bXSjY2FsZyZjc2lnWEcwRQIgR7Dt7kvEQ4D37AvGi6QFM-cJWQYXj64i3KtkWtmRheUCIQD6XmhXCzawqC1xqw5a__PPMX6B23IRcMpUt2oGUBdxfGN4NWOBWQLdMIIC2TCCAcGgAwIBAgIJAPDqu31oBEyKMA0GCSqGSIb3DQEBCwUAMC4xLDAqBgNVBAMTI1l1YmljbyBVMkYgUm9vdCBDQSBTZXJpYWwgNDU3MjAwNjMxMCAXDTE0MDgwMTAwMDAwMFoYDzIwNTAwOTA0MDAwMDAwWjBvMQswCQYDVQQGEwJTRTESMBAGA1UECgwJWXViaWNvIEFCMSIwIAYDVQQLDBlBdXRoZW50aWNhdG9yIEF0dGVzdGF0aW9uMSgwJgYDVQQDDB9ZdWJpY28gVTJGIEVFIFNlcmlhbCAyMTA5NDY3Mzc2MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE5mfTO7qcRZuAnvzLaguuLFz8S9eB1XNIPZb96SUfZCzN5sIGVRTzM4JGrJlSgAAq0jivvANxttf6w7_LnnnSMKOBgTB_MBMGCisGAQQBgsQKDQEEBQQDBQQDMCIGCSsGAQQBgsQKAgQVMS4zLjYuMS40LjEuNDE0ODIuMS43MBMGCysGAQQBguUcAgEBBAQDAgQwMCEGCysGAQQBguUcAQEEBBIEEC_AV5-BE0fqsRa7Wo25ICowDAYDVR0TAQH_BAIwADANBgkqhkiG9w0BAQsFAAOCAQEAtjGoKNeTOK0pAIoNf3mjoD3PLgybH2L6z7SKnlWVd6dRbJWbZCsY8AxMdyKNGfnUQiJcEmi9IxigjGoXcwZPApnJm7JDike7Z7HQ2yUrlJZ-EgFamivp5C3UVCaIkGH-HyJW_vh23XOZMkaDcRqwbeq8b0Voavnu4YF5bCM7PtnsPcCsvfL5DahPGSfpc9YyANG49OQBOZolNF3MBKKrspOAI7RfW0JSQY0NUnWFYx9hxFbNuYsKFN4NblJ_Zz9tMk1YYSkTJ6VfxHTo5tfIcaLfZ1dIrMeY12-WevjMufFW_qB4ErY5Gjft3cbiZBELmbQ9QLUyLX78lHiLC9pJImhhdXRoRGF0YVjES_ybIkMj6soGXSAwVHmFMPZKG-S8Gt-tqPZJWxgsoddFAAAAAy_AV5-BE0fqsRa7Wo25ICoAQOHxYFHtlpfXD_iquuZVi8-ZUhj7OFEkiG9M38y1MhXL4x2O6aLk4k0crJrTcRb9y9ZYKUzWl8s_ud2T4-YiABOlAQIDJiABIVggsJ73hjh60y0jbwTVBtCZyw59oIIwRoazaoPA5rHnbLQiWCAimMd4RFXPPFaujZoqCJsRmUWTXdRzXl2C35-Z_CpCGg","clientDataJSON":"eyJ0eXBlIjogIndlYmF1dGhuLmNyZWF0ZSIsICJjaGFsbGVuZ2UiOiAiTlU0cEZjaDBlNldGTUtqVnljcFBEZyIsICJvcmlnaW4iOiAiaHR0cHM6Ly9ob3dpZTIuZmlkby5jb20iLCAiY3Jvc3Nfb3JpZ2luIjogZmFsc2V9"},"type":"public-key"}}}

After beautifying the format,

{
   "svcinfo":{
      "did":1,
      "protocol":"FIDO2_0",
      "authtype":"PASSWORD",
      "svcusername":"svcfidouser",
      "svcpassword":"Abcd1234!"
   },
   "payload":{
      "strongkeyMetadata":{
         "version":"1.0",
         "create_location":"Sunnyvale,CA",
         "username":"johndoe",
         "origin":"https://howie2.fido.com"
      },
      "publicKeyCredential":{
         "id":"4fFgUe2Wl9cP-Kq65lWLz5lSGPs4USSIb0zfzLUyFcvjHY7pouTiTRysmtNxFv3L1lgpTNaXyz-53ZPj5iIAEw",
         "rawId":"4fFgUe2Wl9cP-Kq65lWLz5lSGPs4USSIb0zfzLUyFcvjHY7pouTiTRysmtNxFv3L1lgpTNaXyz-53ZPj5iIAEw",
         "response":{
            "attestationObject":"o2NmbXRmcGFja2VkZ2F0dFN0bXSjY2FsZyZjc2lnWEcwRQIgR7Dt7kvEQ4D37AvGi6QFM-cJWQYXj64i3KtkWtmRheUCIQD6XmhXCzawqC1xqw5a__PPMX6B23IRcMpUt2oGUBdxfGN4NWOBWQLdMIIC2TCCAcGgAwIBAgIJAPDqu31oBEyKMA0GCSqGSIb3DQEBCwUAMC4xLDAqBgNVBAMTI1l1YmljbyBVMkYgUm9vdCBDQSBTZXJpYWwgNDU3MjAwNjMxMCAXDTE0MDgwMTAwMDAwMFoYDzIwNTAwOTA0MDAwMDAwWjBvMQswCQYDVQQGEwJTRTESMBAGA1UECgwJWXViaWNvIEFCMSIwIAYDVQQLDBlBdXRoZW50aWNhdG9yIEF0dGVzdGF0aW9uMSgwJgYDVQQDDB9ZdWJpY28gVTJGIEVFIFNlcmlhbCAyMTA5NDY3Mzc2MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE5mfTO7qcRZuAnvzLaguuLFz8S9eB1XNIPZb96SUfZCzN5sIGVRTzM4JGrJlSgAAq0jivvANxttf6w7_LnnnSMKOBgTB_MBMGCisGAQQBgsQKDQEEBQQDBQQDMCIGCSsGAQQBgsQKAgQVMS4zLjYuMS40LjEuNDE0ODIuMS43MBMGCysGAQQBguUcAgEBBAQDAgQwMCEGCysGAQQBguUcAQEEBBIEEC_AV5-BE0fqsRa7Wo25ICowDAYDVR0TAQH_BAIwADANBgkqhkiG9w0BAQsFAAOCAQEAtjGoKNeTOK0pAIoNf3mjoD3PLgybH2L6z7SKnlWVd6dRbJWbZCsY8AxMdyKNGfnUQiJcEmi9IxigjGoXcwZPApnJm7JDike7Z7HQ2yUrlJZ-EgFamivp5C3UVCaIkGH-HyJW_vh23XOZMkaDcRqwbeq8b0Voavnu4YF5bCM7PtnsPcCsvfL5DahPGSfpc9YyANG49OQBOZolNF3MBKKrspOAI7RfW0JSQY0NUnWFYx9hxFbNuYsKFN4NblJ_Zz9tMk1YYSkTJ6VfxHTo5tfIcaLfZ1dIrMeY12-WevjMufFW_qB4ErY5Gjft3cbiZBELmbQ9QLUyLX78lHiLC9pJImhhdXRoRGF0YVjES_ybIkMj6soGXSAwVHmFMPZKG-S8Gt-tqPZJWxgsoddFAAAAAy_AV5-BE0fqsRa7Wo25ICoAQOHxYFHtlpfXD_iquuZVi8-ZUhj7OFEkiG9M38y1MhXL4x2O6aLk4k0crJrTcRb9y9ZYKUzWl8s_ud2T4-YiABOlAQIDJiABIVggsJ73hjh60y0jbwTVBtCZyw59oIIwRoazaoPA5rHnbLQiWCAimMd4RFXPPFaujZoqCJsRmUWTXdRzXl2C35-Z_CpCGg",
            "clientDataJSON":"eyJ0eXBlIjogIndlYmF1dGhuLmNyZWF0ZSIsICJjaGFsbGVuZ2UiOiAiTlU0cEZjaDBlNldGTUtqVnljcFBEZyIsICJvcmlnaW4iOiAiaHR0cHM6Ly9ob3dpZTIuZmlkby5jb20iLCAiY3Jvc3Nfb3JpZ2luIjogZmFsc2V9"
         },
         "type":"public-key"
      }
   }
}

But still meet signature verification error. Screenshot 2022-08-16 230513

Could you help to check if this calling restful API is legal? are the content of attestation object and client data json legal?

push2085 commented 2 years ago

Hi The contents look legal as if there was a problem with what is being sent it would have complained with a different error. The fact that it's reaching the signature verification stage tells me that the web service call is correct. At this point the problem is to figure out what the fido python library is sending the authenticator to sign. Our code is sending the signature the authdatabytes and client data bytes to verify signature and its not working.

Is there any way to get more debug logs from the python library on what it does when it recieves the create call from your application?

I was trying to set up something internal for trying out the yubico library but I couldn't get it working.

push2085 commented 2 years ago

Hi @kimo6416337,

I think I may have found the problem in the input that is being sent to the fido server. I looked at the detailed input again to see if something doesnt match and i found that the clientDataJson that is being sent in has one thing wrong. Here is what we get based on the glassfish log that you sent: { "type": "webauthn.create", "challenge": "hOaPivrns2gwfFLxrddYVg", "origin": "https://howie2.fido.com", "cross_origin": false } The cross origin parameter is not correct as the specification says it should be crossOrigin which means the client data should look like the following: { "type": "webauthn.create", "challenge": "hOaPivrns2gwfFLxrddYVg", "origin": "https://howie2.fido.com", "crossOrigin": false }

Can you modify this part of your code "client_data["cross_origin"] = result.client_data.cross_origin" and change it to "client_data["crossOrigin"] = result.client_data.cross_origin" and try again to see if the registration succeeds.

Thank you Pushkar

kimo6416337 commented 2 years ago

@push2085 Hi, thanks for your help. I will try your solution later and tell the result.

kimo6416337 commented 2 years ago

@push2085 After trying your solution, the error still happens. I am seeing the source code of python-libfido2 to figure out what it sends to the authenticator and how it handles the clientDataJSON and attestationObject.

arshadnoor commented 2 years ago

Have you posted an issue in the Python library's forum with a reference to this thread?

On 8/22/22 1:36 AM, Lighthope wrote:

@push2085 https://github.com/push2085 After trying your solution, the error still happens. I am seeing the source code of python-libfido2 to figure out what it sends to the authenticator and how it handles the clientDataJSON and attestationObject.

— Reply to this email directly, view it on GitHub https://github.com/StrongKey/fido2/issues/201#issuecomment-1222033280, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABWSVTWSAIZOWQU6TJEOHTLV2M3Y5ANCNFSM56PQJJRQ. You are receiving this because you were mentioned.Message ID: @.***>

kimo6416337 commented 2 years ago

@arshadnoor pls see https://github.com/Yubico/python-fido2/issues/152

max-smyth commented 2 years ago

Lets wait and see what Yubico has to say, Lighthope. We can respond to them if they need to know anything else. Thanks.

On 8/23/22 01:43, Lighthope wrote:

@arshadnoor https://github.com/arshadnoor pls see Yubico/python-fido2#152 https://github.com/Yubico/python-fido2/issues/152

— Reply to this email directly, view it on GitHub https://github.com/StrongKey/fido2/issues/201#issuecomment-1223751776, or unsubscribe https://github.com/notifications/unsubscribe-auth/ALLPGO3YOSWVCODHZUZ2U63V2SFLTANCNFSM56PQJJRQ. You are receiving this because you are subscribed to this thread.Message ID: @.***>

kimo6416337 commented 2 years ago

After I survey how python-fido2 sends a make-credential request to the authenticator, I find it's using CTAP2 cmd authenticatorMakeCredential (0x01). The request data is a dictionary structure with int keys and values containing sha256 hash of client data, rp info, user info, etc.

I am wondering if it's different between the signature/x509 certificate of webauthn attestation and of CTAP2?