Skip to content

definition of a webauthn varsig type#11

Draft
chunningham wants to merge 2 commits intoChainAgnostic:mainfrom
chunningham:feat/webauthn-sig
Draft

definition of a webauthn varsig type#11
chunningham wants to merge 2 commits intoChainAgnostic:mainfrom
chunningham:feat/webauthn-sig

Conversation

@chunningham
Copy link
Copy Markdown

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
Copy Markdown

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.

Comment thread 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
Copy Markdown
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
Comment thread README.md

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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I think it is worth calling out that challenge should be Base64url encoded multihash for clarity

Comment thread README.md
``` abnf
webauthn-varsig = webauthn-varsig-header client-data-length client-data-json authenticator-data-length authenticator-data signature

webauthn-varsig-header = TODO
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Can we put some placeholder code here ?

Comment thread README.md
client-data-json = *OCTET
authenticator-data-length = 1*unsigned-varint
authenticator-data = *OCTET
signature = varsig-body
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Can we avoid recursion here by unpacking this so it can have webauthn within webauthn ?

Gozala pushed a commit to dialog-db/dialog-db that referenced this pull request Feb 13, 2026
Implements the WebAuthn varsig extension (ChainAgnostic/varsig#11) with
P-256 ECDSA as the inner algorithm, the dominant passkey signature type.

dialog-varsig:
- New `webauthn` algorithm module with `WebAuthnP256` type using multicodec
  tags [0xec, 0x1200, 0x300001] (ECDSA + P-256 + WebAuthn wrapper marker)
- `WebAuthnSignature` type carrying clientDataJSON, authenticatorData, and
  inner ECDSA signature bytes with varint-length-prefixed wire encoding
- Feature: `webauthn_p256`

dialog-credentials:
- `WebAuthnVerifier`: full verification pipeline (challenge validation via
  SHA-256 multihash, authenticatorData binding, ECDSA P-256 verification)
  working on both native and WASM
- `WebAuthnKeyResolver`: did:key resolution for P-256 keys (0x1200 multicodec)
- DID encoding/decoding with base58btc + P-256 compressed point
- Feature: `webauthn` (+ `web-integration-tests` for browser testing)

Tests: 31 new tests covering signature encoding roundtrips, algorithm tag
parsing, full verification pipeline, challenge mismatch detection, tamper
resistance, DID roundtrips, and integration tests with computed test vectors.

https://claude.ai/code/session_01AWD2GCRvx94V3tfsnEvCGR
Gozala pushed a commit to dialog-db/dialog-db that referenced this pull request Feb 13, 2026
Implements the WebAuthn varsig extension (ChainAgnostic/varsig#11) with
P-256 ECDSA as the inner algorithm, the dominant passkey signature type.

dialog-varsig:
- New `webauthn` algorithm module with `WebAuthnP256` type using multicodec
  tags [0xec, 0x1200, 0x300001] (ECDSA + P-256 + WebAuthn wrapper marker)
- `WebAuthnSignature` type carrying clientDataJSON, authenticatorData, and
  inner ECDSA signature bytes with varint-length-prefixed wire encoding
- Feature: `webauthn_p256`

dialog-credentials:
- `WebAuthnVerifier`: full verification pipeline (challenge validation via
  SHA-256 multihash, authenticatorData binding, ECDSA P-256 verification)
  working on both native and WASM
- `WebAuthnKeyResolver`: did:key resolution for P-256 keys (0x1200 multicodec)
- DID encoding/decoding with base58btc + P-256 compressed point
- Feature: `webauthn` (+ `web-integration-tests` for browser testing)

Tests: 31 new tests covering signature encoding roundtrips, algorithm tag
parsing, full verification pipeline, challenge mismatch detection, tamper
resistance, DID roundtrips, and integration tests with computed test vectors.

https://claude.ai/code/session_01AWD2GCRvx94V3tfsnEvCGR
Gozala pushed a commit to dialog-db/dialog-db that referenced this pull request Feb 13, 2026
Implements the WebAuthn varsig extension (ChainAgnostic/varsig#11) with
P-256 ECDSA as the inner algorithm, the dominant passkey signature type.

dialog-varsig:
- New `webauthn` algorithm module with `WebAuthnP256` type using multicodec
  tags [0xec, 0x1200, 0x300001] (ECDSA + P-256 + WebAuthn wrapper marker)
- `WebAuthnSignature` type carrying clientDataJSON, authenticatorData, and
  inner ECDSA signature bytes with varint-length-prefixed wire encoding
- Feature: `webauthn_p256`

dialog-credentials:
- `WebAuthnVerifier`: full verification pipeline (challenge validation via
  SHA-256 multihash, authenticatorData binding, ECDSA P-256 verification)
  working on both native and WASM
- `WebAuthnKeyResolver`: did:key resolution for P-256 keys (0x1200 multicodec)
- DID encoding/decoding with base58btc + P-256 compressed point
- Feature: `webauthn` (+ `web-integration-tests` for browser testing)

Tests: 31 new tests covering signature encoding roundtrips, algorithm tag
parsing, full verification pipeline, challenge mismatch detection, tamper
resistance, DID roundtrips, and integration tests with computed test vectors.

https://claude.ai/code/session_01AWD2GCRvx94V3tfsnEvCGR
NiKrause added a commit to NiKrause/iso-repo that referenced this pull request Feb 24, 2026
Restructure the WebAuthn varsig wire format per Gozala's suggestion
(ChainAgnostic/varsig#11) to avoid recursion:

- Header: prefix version innerAlgorithm curve webauthnMarker (removed
  multihashCode, multihashLength, payloadEncoding from header)
- Body: clientData before authData (swapped order)
- Body: signatureHashAlgorithm + encodingInfo moved to body before
  raw signature bytes
- Encoder accepts optional EncodeOptions for custom hash/encoding
- Decoder returns signatureHashAlgorithm/encodingInfo instead of
  multihashCode/multihashLength
- Added wire-format, custom options, and backwards-compat tests
- Documented ABNF wire format in readme
- Bumped version to 0.2.0 (breaking change)

Closes #1
NiKrause added a commit to NiKrause/iso-repo that referenced this pull request Feb 24, 2026
…sive wire format

Add iso-webauthn-varsig package implementing the non-recursive WebAuthn
varsig layout per Gozala's suggestion on ChainAgnostic/varsig#11.

Wire format:
  header: prefix version innerAlgorithm curve webauthnMarker
  body:   clientDataLen clientDataJSON authDataLen authenticatorData
          signatureHashAlgorithm encodingInfo signatureBytes

Features:
- Encoder/decoder for Ed25519 and P-256 WebAuthn varsig
- Optional EncodeOptions for custom signatureHashAlgorithm/encodingInfo
- WebAuthn assertion verifier (node + browser)
- Full test suite (8 node + 8 browser tests)
- ABNF wire format documented in readme

Ref: ChainAgnostic/varsig#11
Ref: #1
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.

4 participants