pub struct RegisterPublicKeyRequest {
pub challenge_id: String,
pub client_data_json: Vec<u8>,
pub attestation_object: Vec<u8>,
pub device_label: String,
pub device_public_key: Vec<u8>,
pub client_operation_id: String,
pub device_binding_client_data_json: Vec<u8>,
pub device_binding_authenticator_data: Vec<u8>,
pub device_binding_signature: Vec<u8>,
pub attesting_pubkey: Vec<u8>,
pub cross_device_attestation: Vec<u8>,
}Fields§
§challenge_id: String§client_data_json: Vec<u8>Raw bytes per WebAuthn (clientDataJSON / attestationObject / authenticatorData / signature are passed verbatim; the WebAuthn lib base64url-decodes them off the wire).
attestation_object: Vec<u8>§device_label: String§device_public_key: Vec<u8>Raw 32-byte Ed25519 public key the client commits to as the
renewal anchor for this device. Distinct from the WebAuthn
credential’s attested public key (COSE-encoded, lives in
webauthn_credentials): this key lives in device_roots and
is the one mint_biscuit_keypair calls
Ed25519Signer::verify_with_public_key against on every
KeypairProof renewal. Leave empty for browser-only flows.
When non-empty, MUST be accompanied by a binding signature
(see the three device_binding_* fields). Closes
HeddleCo/weft#131.
client_operation_id: String§device_binding_client_data_json: Vec<u8>=== Device-key binding proof (HeddleCo/weft#131) ===
Required iff device_public_key is non-empty. Together these
carry a WebAuthn assertion (navigator.credentials.get()
produced immediately after create() succeeds, signed by the
same authenticator) whose challenge is
base64url(SHA256(“heddle-device-binding-v1” || 0x00 || device_public_key))
The server verifies the assertion’s signature using the COSE
public key extracted from the attestation, then persists
device_public_key as the device root. Binds the two keys
cryptographically: the renewal-path public key is only
accepted if the WebAuthn credential signs it.
device_binding_authenticator_data: Vec<u8>§device_binding_signature: Vec<u8>§attesting_pubkey: Vec<u8>=== Cross-device enrollment attestation (HeddleCo/weft#119) ===
Set when this registration is being attested by an already-enrolled
device (the OAuth-style localhost-loopback flow), rather than by a
fresh WebAuthn create() on this device. Both fields are required
together; both empty for the ordinary first-device / browser-only flow.
attesting_pubkey is the raw Ed25519 public key of the existing,
already-enrolled device that signed the attestation. The server
verifies it chains to a known, non-revoked pubkey for the same
identity and rejects unknown/revoked attesters.
cross_device_attestation is the signature, produced by the key in
attesting_pubkey, over the enrollment statement
enroll(new_pubkey, scope, expiry, nonce). The server enforces the
bounded scope (read-only vs full), the expiry (max 7d on the
attestation itself), and one-shot nonce (rejects replays). The
resulting enrollment of device_public_key is permanent until
revoked.
cross_device_attestation: Vec<u8>Trait Implementations§
Source§impl Clone for RegisterPublicKeyRequest
impl Clone for RegisterPublicKeyRequest
Source§fn clone(&self) -> RegisterPublicKeyRequest
fn clone(&self) -> RegisterPublicKeyRequest
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for RegisterPublicKeyRequest
impl Debug for RegisterPublicKeyRequest
Source§impl Default for RegisterPublicKeyRequest
impl Default for RegisterPublicKeyRequest
impl Eq for RegisterPublicKeyRequest
Source§impl Hash for RegisterPublicKeyRequest
impl Hash for RegisterPublicKeyRequest
Source§impl Message for RegisterPublicKeyRequest
impl Message for RegisterPublicKeyRequest
Source§fn encoded_len(&self) -> usize
fn encoded_len(&self) -> usize
Source§fn encode(&self, buf: &mut impl BufMut) -> Result<(), EncodeError>where
Self: Sized,
fn encode(&self, buf: &mut impl BufMut) -> Result<(), EncodeError>where
Self: Sized,
Source§fn encode_to_vec(&self) -> Vec<u8> ⓘwhere
Self: Sized,
fn encode_to_vec(&self) -> Vec<u8> ⓘwhere
Self: Sized,
Source§fn encode_length_delimited(
&self,
buf: &mut impl BufMut,
) -> Result<(), EncodeError>where
Self: Sized,
fn encode_length_delimited(
&self,
buf: &mut impl BufMut,
) -> Result<(), EncodeError>where
Self: Sized,
Source§fn encode_length_delimited_to_vec(&self) -> Vec<u8> ⓘwhere
Self: Sized,
fn encode_length_delimited_to_vec(&self) -> Vec<u8> ⓘwhere
Self: Sized,
Source§fn decode(buf: impl Buf) -> Result<Self, DecodeError>where
Self: Default,
fn decode(buf: impl Buf) -> Result<Self, DecodeError>where
Self: Default,
Source§fn decode_length_delimited(buf: impl Buf) -> Result<Self, DecodeError>where
Self: Default,
fn decode_length_delimited(buf: impl Buf) -> Result<Self, DecodeError>where
Self: Default,
Source§fn merge(&mut self, buf: impl Buf) -> Result<(), DecodeError>where
Self: Sized,
fn merge(&mut self, buf: impl Buf) -> Result<(), DecodeError>where
Self: Sized,
self. Read moreSource§fn merge_length_delimited(&mut self, buf: impl Buf) -> Result<(), DecodeError>where
Self: Sized,
fn merge_length_delimited(&mut self, buf: impl Buf) -> Result<(), DecodeError>where
Self: Sized,
self.