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!
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.
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.
The attestationObject is as below. It consists of different parts of information (fmt, authData, attStmt).
attStmt is a dictionary object.
fmt is a string.
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.
Finally, CBOR-encode the atteestationObject.
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.
Thus, can anyone help to solve the problem?
Thanks!