Skip to main content

ssh_agent_lib/proto/message/
identity.rs

1//! Data returned to the client when listing keys.
2
3use ssh_encoding::{self, CheckedSum, Decode, Encode, Reader, Writer};
4
5use super::PublicCredential;
6use crate::proto::{Error, Result};
7
8/// Data returned to the client when listing keys.
9///
10/// A list of these structures are sent in a [`Response::IdentitiesAnswer`](super::Response::IdentitiesAnswer) (`SSH_AGENT_IDENTITIES_ANSWER`) message body.
11///
12/// Described in [draft-miller-ssh-agent-14 ยง 3.5](https://www.ietf.org/archive/id/draft-miller-ssh-agent-14.html#section-3.5)
13#[derive(Clone, PartialEq, Debug)]
14pub struct Identity {
15    /// A standard public-key encoding of an underlying key.
16    pub credential: PublicCredential,
17
18    /// A human-readable comment
19    pub comment: String,
20}
21
22impl Identity {
23    pub(crate) fn decode_vec(reader: &mut impl Reader) -> Result<Vec<Self>> {
24        let len = u32::decode(reader)?;
25        let mut identities = vec![];
26
27        for _ in 0..len {
28            identities.push(Self::decode(reader)?);
29        }
30
31        Ok(identities)
32    }
33}
34
35impl Decode for Identity {
36    type Error = Error;
37
38    fn decode(reader: &mut impl Reader) -> Result<Self> {
39        let credential = reader.read_prefixed(PublicCredential::decode)?;
40        let comment = String::decode(reader)?;
41
42        Ok(Self {
43            credential,
44            comment,
45        })
46    }
47}
48
49impl Encode for Identity {
50    fn encoded_len(&self) -> ssh_encoding::Result<usize> {
51        [
52            self.credential.encoded_len_prefixed()?,
53            self.comment.encoded_len()?,
54        ]
55        .checked_sum()
56    }
57
58    fn encode(&self, writer: &mut impl Writer) -> ssh_encoding::Result<()> {
59        self.credential.encode_prefixed(writer)?;
60        self.comment.encode(writer)?;
61
62        Ok(())
63    }
64}