Skip to main content

ssh_key/private/
opaque.rs

1//! Opaque private keys.
2//!
3//! [`OpaqueKeypair`] represents a keypair meant to be used with an algorithm unknown to this
4//! crate, i.e. keypairs that use a custom algorithm as specified in [RFC4251 § 6].
5//!
6//! They are said to be opaque, because the meaning of their underlying byte representation is not
7//! specified.
8//!
9//! [RFC4251 § 6]: https://www.rfc-editor.org/rfc/rfc4251.html#section-6
10
11use crate::{
12    Algorithm, Error, Result,
13    public::{OpaquePublicKey, OpaquePublicKeyBytes},
14};
15use alloc::vec::Vec;
16use core::fmt::{self, Debug};
17use ctutils::{Choice, CtEq};
18use encoding::{CheckedSum, Decode, Encode, Reader, Writer};
19
20/// An opaque keypair.
21///
22/// The encoded representation of an `OpaqueKeypair` consists of the encoded representation of its
23/// [`OpaquePublicKey`] followed by the encoded representation of its [`OpaquePrivateKeyBytes`].
24#[derive(Clone)]
25pub struct OpaqueKeypair {
26    /// The opaque private key
27    pub private: OpaquePrivateKeyBytes,
28    /// The opaque public key
29    pub public: OpaquePublicKey,
30}
31
32impl OpaqueKeypair {
33    /// Create a new `OpaqueKeypair`.
34    #[must_use]
35    pub fn new(private_key: Vec<u8>, public: OpaquePublicKey) -> Self {
36        Self {
37            private: OpaquePrivateKeyBytes(private_key),
38            public,
39        }
40    }
41
42    /// Get the [`Algorithm`] for this key type.
43    #[must_use]
44    pub fn algorithm(&self) -> Algorithm {
45        self.public.algorithm()
46    }
47
48    /// Decode [`OpaqueKeypair`] for the specified algorithm.
49    pub(super) fn decode_as(reader: &mut impl Reader, algorithm: Algorithm) -> Result<Self> {
50        let key = OpaqueKeypairBytes::decode(reader)?;
51        let public = OpaquePublicKey {
52            algorithm,
53            key: key.public,
54        };
55
56        Ok(Self {
57            public,
58            private: key.private,
59        })
60    }
61}
62
63impl CtEq for OpaqueKeypair {
64    fn ct_eq(&self, other: &Self) -> Choice {
65        Choice::from(u8::from(self.public == other.public)) & self.private.ct_eq(&other.private)
66    }
67}
68
69impl Debug for OpaqueKeypair {
70    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
71        f.debug_struct("OpaqueKeypair")
72            .field("public", &self.public)
73            .finish_non_exhaustive()
74    }
75}
76
77impl Encode for OpaqueKeypair {
78    fn encoded_len(&self) -> encoding::Result<usize> {
79        [self.public.encoded_len()?, self.private.encoded_len()?].checked_sum()
80    }
81
82    fn encode(&self, writer: &mut impl Writer) -> encoding::Result<()> {
83        self.public.encode(writer)?;
84        self.private.encode(writer)?;
85
86        Ok(())
87    }
88}
89
90impl From<&OpaqueKeypair> for OpaquePublicKey {
91    fn from(keypair: &OpaqueKeypair) -> OpaquePublicKey {
92        keypair.public.clone()
93    }
94}
95
96/// The underlying representation of an [`OpaqueKeypair`].
97///
98/// The encoded representation of an `OpaqueKeypairBytes` consists of the encoded representation of
99/// its [`OpaquePublicKeyBytes`] followed by the encoded representation of its
100/// [`OpaquePrivateKeyBytes`].
101pub struct OpaqueKeypairBytes {
102    /// The opaque private key
103    pub private: OpaquePrivateKeyBytes,
104    /// The opaque public key
105    pub public: OpaquePublicKeyBytes,
106}
107
108impl Debug for OpaqueKeypairBytes {
109    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
110        f.debug_struct("OpaqueKeypairBytes")
111            .field("public", &self.public)
112            .finish_non_exhaustive()
113    }
114}
115
116impl Decode for OpaqueKeypairBytes {
117    type Error = Error;
118
119    fn decode(reader: &mut impl Reader) -> Result<Self> {
120        let public = OpaquePublicKeyBytes::decode(reader)?;
121        let private = OpaquePrivateKeyBytes::decode(reader)?;
122
123        Ok(Self { public, private })
124    }
125}
126
127impl Encode for OpaquePrivateKeyBytes {
128    fn encoded_len(&self) -> encoding::Result<usize> {
129        self.0.encoded_len()
130    }
131
132    fn encode(&self, writer: &mut impl Writer) -> encoding::Result<()> {
133        self.0.encode(writer)
134    }
135}
136
137/// An opaque private key.
138///
139/// The encoded representation of an `OpaquePrivateKeyBytes` consists of a 4-byte length prefix,
140/// followed by its byte representation.
141#[derive(Clone)]
142pub struct OpaquePrivateKeyBytes(Vec<u8>);
143
144impl AsRef<[u8]> for OpaquePrivateKeyBytes {
145    fn as_ref(&self) -> &[u8] {
146        &self.0
147    }
148}
149
150impl CtEq for OpaquePrivateKeyBytes {
151    fn ct_eq(&self, other: &Self) -> Choice {
152        self.as_ref().ct_eq(other.as_ref())
153    }
154}
155
156impl Debug for OpaquePrivateKeyBytes {
157    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
158        f.debug_struct("OpaquePrivateKeyBytes")
159            .finish_non_exhaustive()
160    }
161}
162
163impl Decode for OpaquePrivateKeyBytes {
164    type Error = Error;
165
166    fn decode(reader: &mut impl Reader) -> Result<Self> {
167        Ok(Self(Vec::decode(reader)?))
168    }
169}
170
171impl From<Vec<u8>> for OpaquePrivateKeyBytes {
172    fn from(bytes: Vec<u8>) -> Self {
173        Self(bytes)
174    }
175}