pub struct SignedChallengeResponse {
pub challenge_nonce: Vec<u8>,
pub public_key: Vec<u8>,
pub signature: Vec<u8>,
pub timestamp: Option<Timestamp>,
pub device_type: i32,
pub certificates: Vec<Vec<u8>>,
pub protocol_version: u32,
pub capabilities: Vec<String>,
}Expand description
Signed response to authentication challenge
Fields§
§challenge_nonce: Vec<u8>Original challenge nonce (for correlation)
public_key: Vec<u8>Responder’s Ed25519 public key (32 bytes)
signature: Vec<u8>Ed25519 signature (64 bytes). The signed byte string depends on the negotiated protocol version (ADR-065):
Version 0 (pre-rc.21+1 peers; protocol_version absent on
the wire and reads as 0 via the prost default):
signed = challenge.nonce || challenge.challenger_id || response.timestamp.seconds (u64 little-endian, 8 bytes)
Version 1 (rc.21+1+; CURRENT_PROTOCOL_VERSION at this release):
signed = challenge.nonce || challenge.challenger_id || response.timestamp.seconds (u64 little-endian, 8 bytes) || response.protocol_version (u32 little-endian, 4 bytes)
The response.timestamp.seconds value is the seconds-precision
wall-clock time the responder captured at sign time, the same
value carried in the timestamp field below — NOT the
challenger’s Challenge.timestamp. Both signer and verifier
reconstruct the byte string from response.timestamp.seconds
(and, from v1 onward, response.protocol_version), so the
signature verifies independent of how long the auth flow takes
or whether it spans a wall-clock second boundary.
Negotiation: the responder picks
negotiated = min(challenge.protocol_version, CURRENT_PROTOCOL_VERSION)
sets response.protocol_version = negotiated, and uses the
negotiated version’s byte construction. The verifier reads
response.protocol_version to know which construction to use.
A response.protocol_version value greater than the verifier’s
CURRENT_PROTOCOL_VERSION surfaces as
SecurityError::IncompatibleProtocolVersion, distinct from
InvalidSignature. Full negotiation rules and rollout
semantics: ADR-065.
timestamp: Option<Timestamp>Response creation timestamp. The seconds field is included
verbatim in the signed-message construction above; the nanos
field is informational only and is NOT covered by the signature.
device_type: i32Responder’s device type
certificates: Vec<Vec<u8>>X.509 certificate chain (DER-encoded) - optional for MVP
protocol_version: u32Negotiated protocol version covered by the signature (ADR-065).
Set by the responder to
min(challenge.protocol_version, CURRENT_PROTOCOL_VERSION).
From version 1 onward this value is included in the signed
byte string (u32 little-endian, 4 bytes), so a MITM cannot
strip the field or change its value without invalidating the
signature. A 0 here means the responder negotiated down to
the pre-version-token construction (the peer didn’t advertise
a version, defaulting to 0).
capabilities: Vec<String>Capability strings the responder advertises (ADR-065). Same
v1 semantics as Challenge.capabilities —
advertised-but-not-signed, available to consumers for soft-
policy feature flagging.
Implementations§
Source§impl SignedChallengeResponse
impl SignedChallengeResponse
Sourcepub fn device_type(&self) -> DeviceType
pub fn device_type(&self) -> DeviceType
Returns the enum value of device_type, or the default if the field is set to an invalid enum value.
Sourcepub fn set_device_type(&mut self, value: DeviceType)
pub fn set_device_type(&mut self, value: DeviceType)
Sets device_type to the provided enum value.
Trait Implementations§
Source§impl Clone for SignedChallengeResponse
impl Clone for SignedChallengeResponse
Source§fn clone(&self) -> SignedChallengeResponse
fn clone(&self) -> SignedChallengeResponse
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 SignedChallengeResponse
impl Debug for SignedChallengeResponse
Source§impl Default for SignedChallengeResponse
impl Default for SignedChallengeResponse
Source§impl<'de> Deserialize<'de> for SignedChallengeResponse
impl<'de> Deserialize<'de> for SignedChallengeResponse
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Source§impl Message for SignedChallengeResponse
impl Message for SignedChallengeResponse
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.