Skip to content

Ios support - #1

Open
dkackman wants to merge 38 commits into
fendent:mainfrom
dkackman:ios
Open

Ios support#1
dkackman wants to merge 38 commits into
fendent:mainfrom
dkackman:ios

Conversation

@dkackman

@dkackman dkackman commented Mar 21, 2026

Copy link
Copy Markdown

PR based on macos code

cc: @Profiidev

iOS Suppport

The main addition is iOS support which includes a detailed readme on how to get setup. The generated outputs of tauri ios init contain my team id and bundle id's etc. Can be overwritten with the setup-dev script descibed below

I also added some quality of life changes to the example app to help with my own testin. These may be of value, but if not can also be excluded without losing the ios addition.

Example App changes

apple account setup

  • added a setup-dev.sh script to populate the necessary bundle id's and entitlements etc for an individual developer. Only needs to be run once

macos local dev

  • added build-macos-dev.sh - since pnpm tauri dev won't work on macos with restricted APIsz, this automates the building, bundling and signing requirements so the app can be iterated on more easily. it digs the necessary signing data points out of the respective config files. Needs to be run to test any new code.

backend

  • surface error message from the rust backend instead of panicking
  • added some mutexes to protect against hangs
  • made relying party configurable

ui

  • Added an in app console for important messages to aid testing and debugging (this resulted in things laying out differently)
  • allow the relying party to be set in the UI

@Profiidev

Copy link
Copy Markdown

Nice work!

dkackman and others added 7 commits April 6, 2026 16:09
Empty string was serialized as Some("") by Tauri, bypassing the None
guard in auth_start and sending a 0-byte salt to the authenticator.
Pass null explicitly so Rust receives None.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
CTAP2/WebAuthn requires PRF salts to be exactly 32 bytes. Return a
clear error message rather than passing an invalid-length salt to
the authenticator, which would produce an opaque platform error.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Salt fields now show '32 bytes, base64url' as placeholder text.
Gen buttons use crypto.getRandomValues to populate each field with
a cryptographically random 32-byte salt in base64url format.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
ASAuthorizationController.delegate is a weak reference. Without storing
a strong reference to the controller, PasskeyHandler could be deallocated
before the delegate callback fires, causing a hung continuation.

Mirrors the existing iOS PasskeyHandler implementation.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
creds_ptr safety relies on Swift copying the pointer before async dispatch.
PRF clientExtensionResults are not covered by the authenticator signature
per the WebAuthn spec — document this for future readers.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
WebauthnPlugin now stores the active handler as a property and exposes
a cancel plugin command. The Rust mobile authenticator overrides cancel()
to invoke it. Previously cancel() was dead code — no stored reference
existed to call it on.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add cancel() to macOS PasskeyHandler (mirrors iOS). Store the active
handler in a module-level MainActor variable in Exports.swift and expose
webauthn_cancel as a C function. The Rust macos authenticator overrides
cancel() to call it via FFI.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@dkackman

dkackman commented Apr 6, 2026

Copy link
Copy Markdown
Author

hey guys (@fendent @Profiidev) I'm working on PRF extension support based off of this branch. Do you think the current ios support is mergable both here and then (with the macos support) into the main project?

@Profiidev

Copy link
Copy Markdown

For me it looks good but I can't merge this here

@fendent

fendent commented Apr 7, 2026

Copy link
Copy Markdown
Owner

Seems good on my end but I haven't tested it. My MacOS portion is done, happy to merge this if you're good to go with it. Though, I might request a squash first. :)

@dkackman

dkackman commented Apr 7, 2026

Copy link
Copy Markdown
Author

Seems good on my end but I haven't tested it. My MacOS portion is done, happy to merge this if you're good to go with it.

I'm good with merging if you are. and then we can see how @Profiidev feels about the combined merge in the main project

Though, I might request a squash first. :)

lol - i do like lots of mini commits. wanna just do the squash on merge option here?

@fendent

fendent commented Apr 7, 2026

Copy link
Copy Markdown
Owner

lol - i do like lots of mini commits. wanna just do the squash on merge option here?

Sounds good to me. I'll get this squashed and merged then! Thanks so much for the effort!

@fendent

fendent commented Apr 7, 2026

Copy link
Copy Markdown
Owner

@dkackman Actually, just thinking about it, if I do the squash, I think it'll attribute the commit authorship to me. Better you do it, I think, if you don't mind. That way you can write a commit message better describing your work than I would. 😄

@dkackman

dkackman commented Apr 7, 2026

Copy link
Copy Markdown
Author

@dkackman Actually, just thinking about it, if I do the squash, I think it'll attribute the commit authorship to me. Better you do it, I think, if you don't mind. That way you can write a commit message better describing your work than I would. 😄

I may have needed to to a force push instead of a merge but take a look. My git skills tail off pretty qucikly past the basics. :)

@dkackman

dkackman commented Apr 9, 2026

Copy link
Copy Markdown
Author

@fendent i think i fixed that up. i can do a new PR if you would prefer. im also good with you doing the squash on merge

The iOS plugin called PasskeyHandler.register/authenticate with PRF
parameters the iOS handler never declared, so the iOS target did not
compile. Add the parameters and the PRF request/response handling,
mirroring the macOS bridge (PRF APIs are iOS 18+).

The iOS extension decoders keyed on snake_case, but webauthn-rs-proto
serializes RequestRegistrationExtensions/RequestAuthenticationExtensions
with rename_all = "camelCase", so PRF was never enabled and salts were
never extracted. Drop the CodingKeys overrides.

PRF salts and outputs are key-derivation secrets and were written
verbatim to the debug log via {args:?} and {result:?}. Log rp_id and
completion only.

Three panics were reachable from webview-supplied input:
- PRF salts were forced into [u8; 32] with unwrap(), so any salt that
  was not exactly 32 bytes panicked while holding the manager mutex,
  poisoning it for the rest of the process. Return an error instead.
- assertion.credentials is legitimately None when a single discoverable
  credential matches; unwrap() panicked on that normal path.
- The status conversions ended in unreachable!() despite StatusUpdate
  and StatusPinUv having unmatched variants (PinIsTooShort,
  PinIsTooLong, PinNotSet, InteractiveManagement). Hitting one panicked
  the status thread, after which no PIN prompt reached the UI and the
  ceremony hung. Map the PIN variants through to new PinEvent cases and
  skip InteractiveManagement.

Also drop unwrap() on the state-callback channel send/recv so a dropped
peer surfaces as an error rather than a panic.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants