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

definition of a webauthn varsig type #11

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

chunningham
Copy link

This PR specifies the format and verification process of a varsig representing the result of a Webauthn assertion, the output of a Webauthn authentication ceremony. There are still some open questions but I think the general shape is there.

@cla-bot
Copy link

cla-bot bot commented Aug 8, 2023

We require contributors to sign our Contributor License Agreement, and we don't have you on file. In order for us to review and merge your code, either PR in your signature like so if you have no other disclosures to make or reach out to one more of the codeowners (@bumblefudge @expede @oed) to get yourself added manually.

README.md Outdated
sig-bytes = OCTET
```

The Webauthn varsig header notifies the consumer that the signature is generated via webauthn. Verification must therefor rely on the [`client-data-json`][Webauthn Client Data JSON] JSON object and the [`authenticator-data`][Webauthn Authenticator Data] bytestring. The `client-data-json` object is self-describing and thus does not need to have a length prefix, however it must include the required fields as specified by the Webauthn spec. The `authenticator-data` can vary in length but must have at least 37 bytes, and so requires the `authenticator-data-length` varint to specify it's length. The length of `sig-bytes` can be known via the [`attestedCredentialData`][Webauthn Attested Credential Data] portian of the [`authenticator-data`][Webauthn Authenticator Data] byte string. In order to keep the varsig verifiable and concise, the signed payload MUST be included via CID as the `challenge` field of the [`client-data-json`][Webauthn Client Data JSON].
Copy link
Collaborator

@bumblefudge bumblefudge Aug 8, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reminder: say this isn't the PRF thing that's currently an extension but will be core webauthn some day (as per brook's comment in today's meeting)

@cla-bot cla-bot bot added the cla-signed label Oct 4, 2023

The Webauthn varsig header notifies the consumer that the signature is generated via webauthn. Verification must therefor rely on the [`client-data-json`][Webauthn Client Data JSON] JSON object and the [`authenticator-data`][Webauthn Authenticator Data] bytestring. The `client-data-json` and `authenticator-data` byte strings must conform to the formats specified by the Webauthn spec. To enable the inclusion of the varsig in a byte stream, they each require a varint-encoded length prefix (`client-data-length` and `authenticator-data-length` respectively).

The signature itself is encoded as a varsig-body, containing hash and encoding info in the `signature` field. For example, a webauthn authenticator using `P-256` keys would result in a `signature` field which is a varsig-body conforming to the [`ES256` varsig body defined in section 5.3.1](#5.3.1-example:-es256). The signed payload is included in the signed data as the `challenge` field of the `client-data-json` as a [Multihash][Multihash]. This multihash MUST be made using the result of encoding the payload according to the parameters defined by the `signature` varsig body (for example, a DAG-CBOR encoded payload must have `signature.encoding-info` set to match). The `signature` field MUST be a signature type supported by the WebAuthn specification.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why use challenge = multihash and not challenge = cid? This way we would not need the signature.encoding-info field. (Afaik, the challenge can be longer than 32 bytes).

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so that the other defined varsigs could be entirely reused instead of defining cut-down versions specific to webauthn. there will also be a tiny saving on length as the encoding won't be part of a base64 string, but that wasn't my main reason

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, it would be helpful if you provided an example here to make the discussion easier.

Not sure what you mean by "base64 string"

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will add an example 👍. For the base64 string, the client-data-json's challenge field which gets signed over is always a base64 encoding of the challenge which is passed in (as a byte array). Because the client-data-json is passed back as a byte array of what was signed, we can't repack it to make anything in there smaller.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Btw, it might make sense to sign over the CID regardless in light of #12

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the CID doesnt capture the signature algorithm though, and indeed when it comes to webauthn there is no way to embed the signature algorithm in the challenge as the authenticator selection is up to the user via the UI. I can though see how it might be useful to capture the payload encoding in the signed data

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

Successfully merging this pull request may close these issues.

None yet

3 participants