BryanJacobs / FIDO2Applet

FIDO2 Javacard Applet
MIT License
76 stars 15 forks source link

Fido Conformance test suite #30

Closed jasperdnar closed 1 month ago

jasperdnar commented 4 months ago

when i execute FIDO Conformance Tools v1.7.18, i see lot of errors, i am investigating it. Let me know if this is any known issue?

BryanJacobs commented 4 months ago

I last ran against test suite v1.7.17 and got 100% passes against "CTAP2.1 full feature profile".

If you don't provide your errors it's going to be difficult for me to help.

jasperdnar commented 4 months ago

I will get back to you with errors.

On Mon, May 13, 2024, 17:18 BryanJacobs @.***> wrote:

I last ran against test suite v1.7.17 and got 100% passes against "CTAP2.1 full feature profile".

If you don't provide your errors it's going to be difficult for me to help.

— Reply to this email directly, view it on GitHub https://github.com/BryanJacobs/FIDO2Applet/issues/30#issuecomment-2107365282, or unsubscribe https://github.com/notifications/unsubscribe-auth/BBJNRNKZS36SWH5DI746MJLZCCSBVAVCNFSM6AAAAABHUBLYCKVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCMBXGM3DKMRYGI . You are receiving this because you authored the thread.Message ID: @.***>

jasperdnar commented 4 months ago

NFC-1 Test CTAP2 NFC support P-1 Send FIDO applet selection command and check that authenticator succeeds. For CTAP1(U2F) compatible authenticators check that authenticator returns 0x5532465F5632(U2F_V2) in response. For CTAP2 only authenticators check that authenticator returns 0x4649444f5f325f30(FIDO_2_0) in response.

Error: For U2F compatible CTAP2 authenticators it MUST return legacy "U2F_V2" string!
    at eval (eval at compileCode (js/sandbox.js:25:26), <anonymous>:6721:27)

>This looks like applet configuration issue but i checked the code and it can be either set to U2F or FIDO?

Authr-Generic-1 Generic FIDO protocol tests P-1 Send a valid CTAP2 GetInfo request, wait for the response and check that: (a) CTAP2 responseCode is CTAP1_ERR_SUCCESS(0x00) (b) Check that version(0x01) field is presented and is set to "FIDO_2_0" (c) Check that aaguid(0x03) field is presented and is 16 bytes long & Check that aaguid(0x03) field value matches Metadata.aaguid (d) If GetInfo contains extensions(0x03) field, check that its of type SEQUENCE, and only contains STRINGS (e) If GetInfo contains options(0x04) field, check that its of type MAP (f) If GetInfo contains maxMsgSize(0x05) field, check that its of type NUMBER (g) If GetInfo contains pinUvAuthProtocols(0x06) field, check that its of type SEQUENCE, and only contains NUMBERS (h) If GetInfo contains maxCredentialCountList(0x07) check that its of type NUMBER, greater than 0 (i) If GetInfo contains maxCredentialIdLength(0x08) check that its of type NUMBER, greater than 0 (j) If GetInfo contains 'transports' (0x09) check that its of type SEQUENCE, and only contains STRINGS (k) If GetInfo contains 'algorithms'(0x0A) TODO (l) If GetInfo contains 'maxSerializedLargeBlobArray'(0x0B) (m) If GetInfo contains 'forcePINChange'(0x0C) (n) If GetInfo contains 'minPINLength'(0x0D) (o) If GetInfo contains 'firmwareVersion'(0x0E) (p) If GetInfo contains 'maxCredBlobLength'(0x0F) (q) If GetInfo contains 'maxRPIDsForSetMinPINLength'(0x10) (r) If GetInfo contains 'preferredPlatformUvAttempts'(0x11) (s) If GetInfo contains 'uvModality'(0x12) (t) If GetInfo contains 'certifications'(0x13) (u) If GetInfo contains 'remainingDiscoverableCredentials'(0x14) (v) If GetInfo contains 'vendorPrototypeConfigCommands'(0x15) (---) Check that GetInfo response equals to the metadata.authenticatorGetInfo => Included within relevant block of (*) lettered test

AssertionError: getInfo.aaguid MUST strictly equal to aaguid in metadata.authenticatorGetInfo.aaguid: expected '00000000000000000000000000000000' to equal '415b2e9600f54a81ae9ab141baa4c1b3'
    at n.eval (eval at compileCode (js/sandbox.js:25:26), <anonymous>:7117:16)

>This looks like Metadata issue or may be i need to use same aaguid in applet

Authr-MakeCred-Resp-1 Test registration response, and "packed" attestation P-06 If neither "x5c" nor "ecdaaKeyId" is present, then self attestation is presented, then: (a) Check that metadata statement contains "attestationRootCertificates" field, and it’s an empty ARRAY. (b) Check that metadata statement attestationFormats contains "basic_surrogate" (c) Concatenate authenticatorData and clientDataHash to signData. Using public key extracted from authenticatorData, signData verify signature in "sig" field.

AssertionError: MetadataStatement.attestationTypes MUST include "basic_surrogate": expected [ 'basic_full' ] to include 'basic_surrogate'
    at n.eval (eval at compileCode (js/sandbox.js:25:26), <anonymous>:8735:24)  

>This again looks like metadata issue but i am not fully aware of this where to define?

Discoverable Credentials(Resident-Key) Test Discoverable Credentials(Resident-Key) support P-3 FOR AUTHENTICATORS WITHOUT A DISPLAY AND EITHER UV IS TRUE OR CLIENTPIN IS USED If UV option is supported, set UV to true. Else set new pin, and run registrations with pin. Else skip this test. Send two valid CTAP2 authenticatorMakeCredential(0x01) message, "options" containg an "rk" option set to true, and if authenticator supports UV option set "uv" to true, wait for the responses, and check that Authenticator returns CTAP1_ERR_SUCCESS(0x00) error code. Send a valid CTAP2 authenticatorGetAssertion(0x02) message, with no allowList presented, wait for the response and check that Authenticator returns CTAP1_ERR_SUCCESS(0x00) error code. Check that response contains "numberOfCredentials" field that is of type Number and is set to 2. Send authenticatorGetNextAssertion(0x08), until numberOfCredentials is 1, retrieve responses and check that Authenticator returns CTAP1_ERR_SUCCESS(0x00) error code for each of the requests. Check that response.user contains all of the registered userInfo

Error: Expected authenticator to succeed with CTAP1_ERR_SUCCESS(0). Got CTAP2_ERR_KEY_STORE_FULL(40)
    at eval (eval at compileCode (js/sandbox.js:25:26), <anonymous>:2169:19)

>This looks like RK is full? where i can define number of RK in applet?

CredProtect Test CredProtect extension support P-1 Create a new discoverable credential, with "extensions" containing a valid "credProtect" extension set to userVerificationOptional(0x01), and check that Authenticator returns CTAP1_ERR_SUCCESS(0x00) error code. Send a valid GetAssertion(0x02) request with previously recorded credId and UV/UP set to false, and check that Authenticator returns CTAP1_ERR_SUCCESS(0x00) error code. Send a valid GetAssertion(0x02) request in RK mode(no credentialId), and UV/UP set to false, and check that Authenticator returns CTAP1_ERR_SUCCESS(0x00) error code.

Error: Expected authenticator to succeed with CTAP1_ERR_SUCCESS(0). Got CTAP2_ERR_KEY_STORE_FULL(40)
    at eval (eval at compileCode (js/sandbox.js:25:26), <anonymous>:2169:19)

>This looks like RK is full? where i can define number of RK in applet?

P-2 Create a new discoverable credential, with "extensions" containing valid "credProtect" extension set to userVerificationOptionalWithCredentialIDList(0x02), and check that Authenticator returns CTAP1_ERR_SUCCESS(0x00) error code. Send a valid GetAssertion(0x02) request with previously recorded credId and UV/UP set to false, and check that Authenticator returns CTAP1_ERR_SUCCESS(0x00) error code. Send a valid GetAssertion(0x02) request in RK mode(no credentialId), and UV/UP set to false, and check that Authenticator returns an error

Error: Expected authenticator to succeed with CTAP1_ERR_SUCCESS(0). Got CTAP2_ERR_KEY_STORE_FULL(40)
    at eval (eval at compileCode (js/sandbox.js:25:26), <anonymous>:2169:19)

>This looks like RK is full? where i can define number of RK in applet?

P-3 Create a new discoverable credential, with "extensions" containg valid "credProtect" extension set to userVerificationRequired(0x03), and check that Authenticator returns CTAP1_ERR_SUCCESS(0x00) error code. Send a valid GetAssertion(0x02) request with previously recorded credId and UV/UP set to false, aand check that Authenticator returns an error Send a valid GetAssertion(0x02) request in RK mode(no credentialId), and UV/UP set to false, and check that Authenticator returns an error

Error: Expected authenticator to succeed with CTAP1_ERR_SUCCESS(0). Got CTAP2_ERR_KEY_STORE_FULL(40)
    at eval (eval at compileCode (js/sandbox.js:25:26), <anonymous>:2169:19)

>This looks like RK is full? where i can define number of RK in applet?

Authr-ClientPin1-NewPin Test authenticatorClientPin(0x06), of version 0x01 support of setPIN(0x03), changePIN(0x04) and clientpin1_ObtainPINToken(0x05) commands "after all" hook for "P-5 Send a valid CTAP2 authenticatorGetAssertion(0x02) message with pinAuth, wait for the response, and check that Authenticator returns CTAP1_ERR_SUCCESS(0x00) error code. Check that authData.flags have UV flag set "

Error: the object {
  "errorMessage": "Authenticator returned error SW_DATA_INVALID"
  "statusCode": 27012
  "statusCodeDef": "SW_DATA_INVALID"
} was thrown, throw an Error :)

>No idea about this

Authr-ClientPin1-Policy Check authenticator correctly implementing PinProtocol security policies "before all" hook for "P-1 Try setting new pin, that is of size between 5 and 63 characters, wait for the response, and check that Authenticator returns CTAP1_ERR_SUCCESS(0x00) "

Error: the object {
  "errorMessage": "Authenticator returned error SW_DATA_INVALID"
  "statusCode": 27012
  "statusCodeDef": "SW_DATA_INVALID"
} was thrown, throw an 

>No idea about this

Authr-ClientPin1-GetRetries Test authenticatorClientPin(0x06), of version 0x01 support of getRetries(0x01) command "before all" hook for "P-1 Send a valid CTAP2 authenticatorClientPin(0x01) message with getRetries(0x01) subCommand, wait for the response, and check that Authenticator returns CTAP1_ERR_SUCCESS(0x00) error code, and: (a) check that authenticatorClientPin_Response contains "retries" field (b) authenticatorClientPin_Response.retries is of type NUMBER (c) authenticatorClientPin_Response.retries is extractly 8 "

Error: the object {
  "errorMessage": "Authenticator returned error SW_DATA_INVALID"
  "statusCode": 27012
  "statusCodeDef": "SW_DATA_INVALID"
} was thrown

>No idea about this

"after all" hook for "P-3 Register a valid authenticatorMakeCred(0x01) using the valid PIN. Check that retries counter is reset and back to 8. Keep sending getPINToken with invalid pin until retries counter is 0. Send CTAP2 authenticatorClientPin(0x01) message with getPinToken(0x01) subCommand, that contains valid pinCode, and check that authenticator returns error CTAP2_ERR_PIN_BLOCKED(0x32) "

Error: the object {
  "errorMessage": "Authenticator returned error SW_DATA_INVALID"
  "statusCode": 27012
  "statusCodeDef": "SW_DATA_INVALID"
} was thrown, throw an Error :)

>No idea about this

Metadata-Stmt-1 Verify compliance of Metadata statement fields. P-3 Required Metadata.aaid, Metadata.attestationCertificateKeyIdentifiers and Metadata.supportedExtensions fields to be undefined.

AssertionError: Metadata.supportedExtensions MUST be undefined! A UAF only field!: expected [ Array(2) ] to equal undefined
    at n.eval (eval at compileCode (js/sandbox.js:25:26), <anonymous>:11559:16)

>Metadata issue but what's wrong?

P-32 REQUIRED: authenticatorGetInfo, a MAP that contains such keys: (a) Required "versions": a SEQUENCE of DOMStrings that identifying supported protocol versions. For CTAP2.0(UPV 1.0) must contain: FIDO_2_0. MUST NOT contain duplicate values nor be empty if present. (b) Required "aaguid": a DOMString hex encoded aaguid byte string. MUST match Metadata.aaguid (d) If "extensions" present: MUST be a DOMString SEQUENCE of extension identifiers. (e) If "options" present: MUST be a MAP of <DOMString/Boolean> which represents support for authenticator options (f) If "pinUvAuthProtocols" present: MUST a SEQUENCE of Numbers defining PIN protocols support. MUST NOT contain duplicate values nor be empty if present. (g) If "maxMsgSize" present: MUST be a positive integer. MUST not be 0 (h) If "maxCredentialCountInList" present: MUST be of type Number(unsigned int) and above 0 (i) If "maxCredentialIdLength" present: MUST be of type Number(unsigned int) and above 0 (j) If "transports" present: A DOMString SEQUENCE of supported transports. Defined in WebAuthn#AuthenticatorTransport enum. MUST NOT include duplicate values nor be empty if present. (k) If "algorithms" present: A SEQUENCE of PublicKeyCredentialParameters MAP. Must match Metadata.authenticationAlgorithms. MUST NOT include duplicate entries nor be empty if present. (m) If "maxSerializedLargeBlobArray" present: MUST be of type Number(unsigned int) and >= 1024 (n) If "forcePINChange" present: MUST be Boolean. If "pinUvAuthProtocols" is missing, MUST NOT be present. (o) If "minPINLength" present: MUST be positive integer. MUST NOT be 0. If "pinUvAuthProtocols" is missing, MUST NOT be present. (p) If "firmwareVersion" present: MUST be a positive integer. MUST be equal to Metadata.authenticatorVersion. (q) If "maxCredBlobLength" present: MUST be positive integer. MUST NOT be 0. MUST be at least 32. (r) If "maxRPIDsForSetMinPINLength" present: maxRPIDsForSetMinPINLength (s) If "preferredPlatformUvAttempts" present: MUST be positive integer. MUST NOT be 0. (t) If "uvModality" present: This specifies the user verification modality supported by the authenticaton (c) If "certifications" present: [TODO] (c) If "remainingDiscoverableCredentials" present: [TODO] (c) If "vendorPrototypeConfigCommands" present: [TODO]‣

AssertionError: Metadata.authenticatorGetInfo.algorithms doesn't match Metadata.authenticationAlgorithms: expected 2 to equal 1
    at n.eval (eval at compileCode (js/sandbox.js:25:26), <anonymous>:12293:20)

>No idea about this

BryanJacobs commented 4 months ago

There are four problems exposed by those errors.

  1. You are testing against an applet install that doesn't have U2F enabled. Please follow the install documentation to enable U2F. The applet code does the right thing here.
  2. Your metadata statement (MDS) doesn't match the applet. You'll need to fix it. The AAGUID can be anything you want, but needs to be the same between the applet and the MDS. Just generally fix the MDS you used.
  3. KEY_STORE_FULL means you ran out of flash on the card. The number of RKs allowed is defined by the free flash memory.
  4. SW_DATA_INVALID is something else I can't identify - this can be caused by a flakey connection between the card and the reader, or could be the result of some other problem. Address the other issues first, and if this one persists please send a trace from the debug console in the test suite - it'll include the raw bytes for the CTAP commands sent FROM THE START, which are necessary to track down this type of problem.
jasperdnar commented 4 months ago

Thanks, let me do this.

jasperdnar commented 4 months ago

from the code... when we select applet...

 if (alwaysUv || attestationData == null || filledAttestationData < attestationData.length) {
            // ... but we DON'T implement U2F with alwaysUv, so we can send the CTAP2-only response type
            sendByteArray(apdu, CannedCBOR.FIDO_2_RESPONSE, (short) CannedCBOR.FIDO_2_RESPONSE.length);
        } else {
            sendByteArray(apdu, CannedCBOR.U2F_V2_RESPONSE, (short) CannedCBOR.U2F_V2_RESPONSE.length);
        }

This means it will either return U2FV2 or F I D O 2 _ 0 but test expects legacy data and test expect U2F_V2

BryanJacobs commented 4 months ago

Yes. If the attestation certificate is correctly installed and the alwaysUv feature disabled, U2F_V2 will be returned in response to applet selection.

Since you didn't follow the installation instructions to provide an attestation certificate and enable U2F, the authenticator returns FIDO_2_0.

This is as it should be.

If you were to enable basic attestation, things would be different.

jasperdnar commented 4 months ago

i am trying to run install_attestation_cert.py but i am getting...

Could not find any FIDO PC/SC devices!

But i have omnikey reader connected Then i tried to print command(to run manually) by modifying the code to... print(binascii.hexlify(cbor.encode(at_bytes))) but it looks like i need to CBOR 0x46 as well? is there API already available in python?

BryanJacobs commented 4 months ago

You need to send a valid CTAP command to the device. The documentation for the bytes around the command itself is at https://fidoalliance.org/specs/fido-v2.2-rd-20230321/fido-client-to-authenticator-protocol-v2.2-rd-20230321.html#nfc .

I can't/won't help with whatever is making your PC/SC device not available to pyscard, that's just too far away from anything related to the applet here at all.

jasperdnar commented 4 months ago

could you please help me and just drop the sample command may be from log that is being executed in running install_attestation_cert.py

BryanJacobs commented 4 months ago

No, but I'm willing to help you read, within limits.

Screenshot 2024-05-14 at 16-01-56 Client to Authenticator Protocol (CTAP) Screenshot 2024-05-14 at 16-02-09 Client to Authenticator Protocol (CTAP)

jasperdnar commented 4 months ago

Thanks, got it working, running test now

jasperdnar commented 4 months ago

when i execute test cases and got pop up for display support i hit cancel after that it just start sending 0x6984 for get info...

[NFC] ---> DATA SENT: 00a4040008a0000006472f000100
C:\Users\AppData\Local\Programs\fido-conformance-tools-electron\resources\app.asar\dependencies\transports\nfcdep.js:243 [NFC] <--- DATA RECEIVED: 5532465f56329000
C:\Users\AppData\Local\Programs\fido-conformance-tools-electron\resources\app.asar\dependencies\transports\nfcdep.js:211 [NFC] RECEIVED  SW_NO_ERROR
C:\Users\AppData\Local\Programs\fido-conformance-tools-electron\resources\app.asar\dependencies\transports\nfcdep.js:238 [NFC] ---> DATA SENT: 80100000010700
C:\Users\AppData\Local\Programs\fido-conformance-tools-electron\resources\app.asar\dependencies\transports\nfcdep.js:243 [NFC] <--- DATA RECEIVED: 6984
BryanJacobs commented 4 months ago

80100000010700 is a CTAP authenticator reset command, not a get-info.

BryanJacobs commented 4 months ago

Hint:

 if (attestationData != null && filledAttestationData < attestationData.length &&                                                                                                                           
                transientStorage.getChainIncomingReadOffset() > 0 &&                                                                                                                                               
                bufferMem[0] == FIDOConstants.CMD_INSTALL_CERTS                                                                                                                                                    
            ) {                                                                                                                                                                                                    
            // Still waiting to receive more cert data                                                                                                                                                             
            final short amtRead = apdu.setIncomingAndReceive();                                                                                                                                                    

            final short lc = apdu.getIncomingLength();                                                                                                                                                             
            if (lc == 0) {                                                                                                                                                                                         
                ISOException.throwIt(ISO7816.SW_DATA_INVALID);                                                                                                                                                     
            }      
jasperdnar commented 4 months ago

CMD_INSTALL_CERTS might not be sent by Fido tests? and test before this are passed.

jasperdnar commented 4 months ago

little more log...

a40173766f79616765636f6e6e656374696f6e2e74660258201c7124ba4aecca15788a6c8a2f2344ba6c3a4d7fc1838a06e3fe9bcfeca205210381a26269645870d731e4d68492585a74846a64d9046a62859bc610a6bc260c39c2d2828023ee228ce9cd432a2e3bd49e46276e6a01b450c1ba35b9500c6f69813fb3c2642d456c7218cc1b67590e95e32f82c15e12f0a608563f3f1eecdb610e50e136bb07917edd217283a66579cbdd25eadcd9bba07764747970656a7075626c69632d6b657905a1676d616b65546561f5
C:\Users\Asus\AppData\Local\Programs\fido-conformance-tools-electron\resources\app.asar\dependencies\transports\nfcdep.js:238 [NFC] ---> DATA SENT: 00a4040008a0000006472f000100
C:\Users\Asus\AppData\Local\Programs\fido-conformance-tools-electron\resources\app.asar\dependencies\transports\nfcdep.js:243 [NFC] <--- DATA RECEIVED: 5532465f56329000
C:\Users\Asus\AppData\Local\Programs\fido-conformance-tools-electron\resources\app.asar\dependencies\transports\nfcdep.js:211 [NFC] RECEIVED  SW_NO_ERROR
C:\Users\Asus\AppData\Local\Programs\fido-conformance-tools-electron\resources\app.asar\dependencies\transports\nfcdep.js:238 [NFC] ---> DATA SENT: 80100000cd02a40173766f79616765636f6e6e656374696f6e2e74660258201c7124ba4aecca15788a6c8a2f2344ba6c3a4d7fc1838a06e3fe9bcfeca205210381a26269645870d731e4d68492585a74846a64d9046a62859bc610a6bc260c39c2d2828023ee228ce9cd432a2e3bd49e46276e6a01b450c1ba35b9500c6f69813fb3c2642d456c7218cc1b67590e95e32f82c15e12f0a608563f3f1eecdb610e50e136bb07917edd217283a66579cbdd25eadcd9bba07764747970656a7075626c69632d6b657905a1676d616b65546561f500
C:\Users\Asus\AppData\Local\Programs\fido-conformance-tools-electron\resources\app.asar\dependencies\transports\nfcdep.js:243 [NFC] <--- DATA RECEIVED: 00a301a26269645870d731e4d68492585a74846a64d9046a62859bc610a6bc260c39c2d2828023ee228ce9cd432a2e3bd49e46276e6a01b450c1ba35b9500c6f69813fb3c2642d456c7218cc1b67590e95e32f82c15e12f0a608563f3f1eecdb610e50e136bb07917edd217283a66579cbdd25eadcd9bba07764747970656a7075626c69632d6b6579025825148da27c106d4a5bc4736d538ff2af54a13a885faae6191dc786fbab5113b4e7010000001a035846304402206b1a08e19e07d65bdfbb8e51a669fc320ed6ba54f8d8af919852b674298eeec202204e5860ca4c7bc27964dd3031c0d5bae8be2ec52ae4781da810b7a56cb3e84f939000
C:\Users\Asus\AppData\Local\Programs\fido-conformance-tools-electron\resources\app.asar\dependencies\transports\nfcdep.js:211 [NFC] RECEIVED  SW_NO_ERROR
VM225:2172 {statusCode: 0, type: "GetAssertion", cborResponse: {…}, cborResponseStruct: {…}, cborBuffer: Uint8Array(249), …}
controller.js:448 Test started: P-2

        If authenticator supports "up" option, send a valid CTAP2 authenticatorGetAssertion(0x02) message, options.up set to true, wait for the response, check that Authenticator returns CTAP1_ERR_SUCCESS(0x00) error code, and check that authenticatorData.flags have UP flag set

VM225:2296 Generating test PUAT...
VM225:2298 Promise {<pending>}
C:\Users\Asus\AppData\Local\Programs\fido-conformance-tools-electron\resources\app.asar\dependencies\transports\nfcdep.js:122 [NFC] Selected protocol "2" for reader "OMNIKEY CardMan 3x21 0"
C:\Users\Asus\AppData\Local\Programs\fido-conformance-tools-electron\resources\app.asar\dependencies\transports\nfcdep.js:148 [NFC] Selected protocol "2" for reader "OMNIKEY CardMan 3x21 0"
controller.js:448 Test started: P-3

        If authenticator supports "uv" option, send a valid CTAP2 authenticatorGetAssertion(0x02) message, options.uv set to true, wait for the response, check that Authenticator returns CTAP1_ERR_SUCCESS(0x00) error code, and check that authenticatorData.flags have UV flag set

VM225:2296 Generating test PUAT...
VM225:2298 Promise {<pending>}
2C:\Users\Asus\AppData\Local\Programs\fido-conformance-tools-electron\resources\app.asar\dependencies\transports\nfcdep.js:148 [NFC] Selected protocol "2" for reader "OMNIKEY CardMan 3x21 0"
VM225:2089 Sending CTAP CMD: Reset...
VM225:2090 
C:\Users\Asus\AppData\Local\Programs\fido-conformance-tools-electron\resources\app.asar\dependencies\transports\nfcdep.js:238 [NFC] ---> DATA SENT: 00a4040008a0000006472f000100
C:\Users\Asus\AppData\Local\Programs\fido-conformance-tools-electron\resources\app.asar\dependencies\transports\nfcdep.js:243 [NFC] <--- DATA RECEIVED: 5532465f56329000
C:\Users\Asus\AppData\Local\Programs\fido-conformance-tools-electron\resources\app.asar\dependencies\transports\nfcdep.js:211 [NFC] RECEIVED  SW_NO_ERROR
C:\Users\Asus\AppData\Local\Programs\fido-conformance-tools-electron\resources\app.asar\dependencies\transports\nfcdep.js:238 [NFC] ---> DATA SENT: 80100000010700
C:\Users\Asus\AppData\Local\Programs\fido-conformance-tools-electron\resources\app.asar\dependencies\transports\nfcdep.js:243 [NFC] <--- DATA RECEIVED: 6984
C:\Users\Asus\AppData\Local\Programs\fido-conformance-tools-electron\resources\app.asar\dependencies\transports\nfcdep.js:211 [NFC] RECEIVED  SW_DATA_INVALID
C:\Users\Asus\AppData\Local\Programs\fido-conformance-tools-electron\resources\app.asar\dependencies\transports\nfcdep.js:122 [NFC] Selected protocol "2" for reader "OMNIKEY CardMan 3x21 0"
C:\Users\Asus\AppData\Local\Programs\fido-conformance-tools-electron\resources\app.asar\dependencies\transports
BryanJacobs commented 4 months ago

The applet itself generates a 0x6984 response to a reset command when an exception is thrown around line 5451. That can happen if your card runs out of RAM or commit-buffer storage.

What smartcard are you running this on?

jasperdnar commented 4 months ago

oh!, I have NXP JCOP 4 card. I should try with removing all other applets. I think RK should be fixed it should not be based on whatever free memory since in business use case card can have multiple applets.

BryanJacobs commented 4 months ago

I used to use a fixed number of RKs, but now they are allocated in small batches (10 at a time). Whenever the user tries to add one when a batch is full, a new batch of ten is allocated (or a failure returned if there is no space).

When you reset the card, you must have enough flash available to allocate ten new keys - 2k-ish - or the reset will fail like you observed.

jasperdnar commented 4 months ago

i think i should make a pull request to make it configurable.

jasperdnar commented 4 months ago

else in this way it will make card unusable for customer if they keep adding RK?

BryanJacobs commented 4 months ago

This is already configurable. You can change NUM_RESIDENT_KEY_SLOTS_PER_BATCH.

The reason a reset needs to allocate memory is that we don't want to "half-reset". Like, a failed reset should leave all existing keys intact, and a successful reset needs to not have the old keys left over. So we need the buffer of fresh-and-clean new keys before the reset can complete.

If the user completely 100% fills the card flash with RKs, only two operations will fail:

  1. Resetting the card (UNTIL they remove some RKs! Deleting will work)
  2. Adding new RKs

Everything else keeps working.

jasperdnar commented 4 months ago

everytime we do authenticator RESET at line no 5455 residentKeys = new ResidentKeyData[NUM_RESIDENT_KEY_SLOTS_PER_BATCH];

this will create eeprom array everytime and will eat all eeprom?

BryanJacobs commented 4 months ago

everytime we do authenticator RESET at line no 5455 residentKeys = new ResidentKeyData[NUM_RESIDENT_KEY_SLOTS_PER_BATCH];

this will create eeprom array everytime and will eat all eeprom?

At the bottom of the method, garbage collection is requested.

We could skip re-allocating if the size of the array is already the minimum, but I think it's better to be safe and let the JCOP4 OS ensure that the old keys and their data are destroyed.

jasperdnar commented 4 months ago

similarly here in 1072

 residentKeys[targetRKSlot] = new ResidentKeyData(
                        random, key, symmetricWrapper,
                        scratchPublicKeyBuffer, (short)(scratchPublicKeyOffset + 1), (short)(KEY_POINT_LENGTH * 2),
                        buffer, credBlobIdx, effectiveCredBlobLen,
                        uniqueRP

Hopefully garbage collector should work but in my case when i execute all of the tests at once i always get error at RK test cases if i execute them individually then they are fine.

jasperdnar commented 4 months ago

NUM_RESIDENT_KEY_SLOTS_PER_BATCH this set to 4 to check if my card has not enough memory

BryanJacobs commented 4 months ago

similarly here in 1072

That's wrapped in a try-catch for exactly this reason: if you have no flash remaining, KEY_STORE_FULL gets returned.

Hopefully garbage collector should work but in my case when i execute all of the tests at once i always get error at RK test cases if i execute them individually then they are fine.

I don't think it's likely that a real user will do a reset over and over again in close proximity, without letting the garbage collector work.

If I were you, for running the tests I would just allow a bit more available space on the card. It's perfectly possible for the app to use fixed memory only (that's how it used to work...) but I think the convenience of being able to use all remaining flash for RKs instead of only some arbitrary max is worth the risk of running out if the user loads the card up with too many applets.

jasperdnar commented 4 months ago

i am mostly thinking as user experience, RK may get full and then user need to RESET all instead we should stop user in the very beginning?

BryanJacobs commented 4 months ago

i am mostly thinking as user experience, RK may get full and then user need to RESET all instead we should stop user in the very beginning?

The user is stopped from creating a new key if the remaining space is less than APPROXIMATE_STORAGE_PER_RESIDENT_KEY (which is larger than the allocation attempt in the reset function). So the only ways to fill it 100% entirely are:

If the user does either of those things, the way out is to delete resident keys, not to reset the applet. There's never a situation where a reset is forced.

This is a trade-off, and I think it's worthwhile to retain the ability to create as many keys as the card can fit. I'll consider adding an install parameter to pre-allocate a certain number of resident keys, but I don't consider this an issue that's likely to be a user experience problem.

BryanJacobs commented 1 month ago

Closing as it's been several months, and the applet still passes the conformance tests.