keepassxc-browser icon indicating copy to clipboard operation
keepassxc-browser copied to clipboard

Illegal Invocation error on getPublicKey and getPublicKeyAlgorithm calls

Open Keroosha opened this issue 1 year ago • 3 comments

Expected Behavior

Do not get Illegal Invocation error on calling getPublicKey and getPublicKeyAlgorithm methods or override them instead of inheriting from prototype

Current Behavior

If you trying to call getPublicKey or getPublicKeyAlgorithm methods from AuthenticatorAttestationResponse of KeepassXC app you will get Illegal invocation due to inheritance those functions via AuthenticatorAttestationResponse prototype

Possible Solution

Fix createAttestationResponse in passkeys.js as:

const createAttestationResponse = function(publicKey) {
    const response = {
        attestationObject: kpxcBase64ToArrayBuffer(publicKey.response.attestationObject),
        clientDataJSON: kpxcBase64ToArrayBuffer(publicKey.response.clientDataJSON),
        getAuthenticatorData: () => kpxcBase64ToArrayBuffer(publicKey.response?.authenticatorData),
        getTransports: () => [ 'internal' ]
    };

    // Prevent Illegal invocation error
    const responseWithProto = Object.setPrototypeOf(response, AuthenticatorAttestationResponse.prototype);
    responseWithProto.getPublicKey = undefined;
    responseWithProto.getPublicKeyAlgorithm = undefined;

    return responseWithProto;
};

this solution proposed via #2323 PR

Steps to Reproduce (for bugs)

  1. Initiate Registration ceremony
  2. Confirm new passkeys creation at KeepassXC interface
  3. Try to call publicKey.response.getPublicKey or publicKey.response.getPublicKeyAlgorithm in userside JS code
  4. get Illegal invocation Exception

Debug info

KeePassXC - 2.7.9 KeePassXC-Browser - 1.9.2 Operating system: Linux Browser: Chromium

Keroosha avatar Aug 23 '24 15:08 Keroosha

For background, why would those function stubs be called in the first place? Should they actually return the data indicated by the name?

droidmonkey avatar Aug 23 '24 16:08 droidmonkey

why would those function stubs be called in the first place?

Because there is no other way to verify from user code should or not you call those functions (if you trying to check response from debugger they appears as callable functions)

https://www.w3.org/TR/webauthn-3/#iface-authenticatorattestationresponse

ArrayBuffer? getPublicKey();

getPublicKey() This operation returns the DER SubjectPublicKeyInfo of the new credential, or null if this is not available. See § 5.2.1.1 Easily accessing credential data.

Keroosha avatar Aug 23 '24 16:08 Keroosha

@droidmonkey Ah, I've get what do you mean

Yeah, I didn't found publicKey in KeepassXC response to return it via AuthenticatorAttestationResponse contract

Keroosha avatar Aug 23 '24 16:08 Keroosha

Yeah, I didn't found publicKey in KeepassXC response to return it via AuthenticatorAttestationResponse contract

I think it's supposed to be parsed from publicKey.response.attestationObject (getPublicKey provides shortcut to getting public key instead of full CBOR parsing).

And according to the specification, it should return non-null:

User agents MUST be able to return a non-null value for getPublicKey() when the credential public key has a COSEAlgorithmIdentifier value of: -7 (ES256), where kty is 2 (with uncompressed points) and crv is 1 (P-256). -257 (RS256). -8 (EdDSA), where crv is 6 (Ed25519).

SagePtr avatar Sep 18 '25 13:09 SagePtr