Web IDL support 3/N: response JSON serialization#155
Web IDL support 3/N: response JSON serialization#155AlfioEmanueleFresta merged 6 commits intomasterfrom
Conversation
41fbcff to
68c78a6
Compare
|
@msirringhaus — Following up on your review comment on PR #138 regarding I investigated the WebAuthn Level 3 specification and found that
This matches the behavior observed on demo.yubico.com, which always returns So the current implementation in this PR is correct — we always include
Both cases result in the same output per the spec, since This comment was written by GitHub Copilot (Claude) operating on @AlfioEmanueleFresta's instructions. |
68c78a6 to
d3c31bb
Compare
fbb40b2 to
39cca52
Compare
d3c31bb to
d97c80d
Compare
msirringhaus
left a comment
There was a problem hiding this comment.
Looking good to me. Some minor comments and questions inline.
|
|
||
| /// JSON output format options. | ||
| #[derive(Debug, Clone, Copy, Default)] | ||
| pub enum JsonFormat { |
There was a problem hiding this comment.
Is it intentional to 'reimplement' this, instead of exposing a serde_json-Value, which the user can then use and format according to whatever serde_json offers?
I don't have a strong preference for either way, just wanting to understand the reasoning better, if there is any.
There was a problem hiding this comment.
I am of two minds. Returning a Value, the caller would need add a dependency on serde_json for something as trivial as formatting. Furthermore, as JSON is in a way a technical detail of WebAuthn IDL, I feel like it should be encapsulated within libwebauthn.
Other than formatting, do we envision any other valid use case where the caller should be manipulating the JSON response?
There was a problem hiding this comment.
serde_json is in the dependency tree anyways, since we pull it it, so adding it shouldn't really hurt users. But I get that it is weird/clunky to return a type that you can only work with, if you add another dependency (or if we re-export some of serde_json).
I'm not sure about manipulating the JSON, but maybe reading? Esp. extensions? But I'm not sure right now.
I'm fine with the way it is right now, I was just curious.
There was a problem hiding this comment.
I agree with you, I'm thinking it would be best to have both methods available, eg. to_json_value as well as a convenience method to_json_string. Let's do this in a follow-up diff.
iinuwa
left a comment
There was a problem hiding this comment.
Overall, this looks good. I agree with @msirringhaus's comments. Once those are cleaned up, we should merge this and start using it
This adds the inverse of JSON request parsing - serializing WebAuthn responses back to JSON format per WebAuthn Level 3 specification. Changes: - Add WebAuthnIDLResponse trait for response-to-JSON conversion - Add RegistrationResponseJSON and AuthenticationResponseJSON models - Implement to_json() for MakeCredentialResponse and Assertion - Refactor requests to store challenge/origin/cross_origin separately - Add client_data_hash() and client_data_json() helper methods - Update all examples and tests to use new request structure - Add unit tests for response serialization Fix conflicts
|
I believe that I have properly rebased the code here and pushed it to the json-2a branch. Sorry for the trouble :/ |
|
Resolved most comments, and commented on two. Please take a look :) @iinuwa thanks for fixing the conflicts! Updated this branch from your json-2a branch. |
9226700 to
639ddfb
Compare
…json_string` (#169) Follow-up from [PR #155 discussion](#155 (comment)): expose both `serde_json::Value` and formatted `String` outputs from the response trait. - Added `to_json_value(&self, ctx) -> Result<serde_json::Value, _>` to `WebAuthnIDLResponse` - Renamed `to_json` → `to_json_string`, now delegates to `to_json_value` internally - `JsonFormat` retained on `to_json_string` for minified/pretty output ```rust // Get a serde_json::Value for programmatic access let value = assertion.to_json_value(&request)?; // Get a formatted string (same as before, renamed) let json = assertion.to_json_string(&request, JsonFormat::Prettified)?; ``` All call sites in examples and tests updated to `to_json_string`. <!-- START COPILOT CODING AGENT TIPS --> --- ✨ Let Copilot coding agent [set things up for you](https://github.com/linux-credentials/libwebauthn/issues/new?title=✨+Set+up+Copilot+instructions&body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&assignees=copilot) — coding agent works faster and does higher quality work when set up for your repo. --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: AlfioEmanueleFresta <621062+AlfioEmanueleFresta@users.noreply.github.com> Co-authored-by: Alfie Fresta <afresta@noentropy.org>
Summary
This PR is the second in a series (follows #138) and adds JSON serialization for WebAuthn responses - the inverse of the existing JSON request parsing functionality.
Changes
New Response Serialization Infrastructure
WebAuthnIDLResponsetrait - Providesto_json()andto_inner_model()methods for converting responses to JSON formatJsonFormatenum - Supports both minified and prettified JSON outputResponseSerializationError- Error type for serialization failuresNew JSON Response Models (per WebAuthn Level 3 spec)
RegistrationResponseJSON- ForMakeCredentialResponseserializationAuthenticationResponseJSON- ForAssertionserializationAuthenticatorAttestationResponseJSON- Attestation response detailsAuthenticatorAssertionResponseJSON- Assertion response detailsAuthenticationExtensionsClientOutputsJSON- Extension output serializationRequest Structure Refactoring
Refactored
MakeCredentialRequestandGetAssertionRequestto enable client data generation on-the-fly:hash: Vec<u8>withchallenge: Vec<u8>- Store raw challenge instead of pre-computed hashorigin: Stringfield - Store origin explicitlycross_origin: Option<bool>field - Optional cross-origin flagclient_data: ClientDatafield - No longer needed as separate fieldclient_data()- BuildsClientDatainternallyclient_data_hash()- Computes SHA-256 hash on demandclient_data_json()- Returns JSON bytes for response serializationImplementation Details
WebAuthnIDLResponseforMakeCredentialResponsewith full attestation object CBOR serializationWebAuthnIDLResponseforAssertionwith signature and authenticator data handlingcredProps,hmacCreateSecret,hmacGetSecret,largeBlob,prfSerializederives to attestation statement types for CBOR encodingUpdated Files
client_data_hash()Testing
webauthn_json_hid.rsexample to demonstrate JSON response outputExample Usage