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;
17use encoding::{CheckedSum, Decode, Encode, Reader, Writer};
18use subtle::{Choice, ConstantTimeEq};
19
20/// An opaque private key.
21///
22/// The encoded representation of an `OpaquePrivateKeyBytes` consists of a 4-byte length prefix,
23/// followed by its byte representation.
24#[derive(Clone)]
25pub struct OpaquePrivateKeyBytes(Vec<u8>);
26
27/// An opaque keypair.
28///
29/// The encoded representation of an `OpaqueKeypair` consists of the encoded representation of its
30/// [`OpaquePublicKey`] followed by the encoded representation of its [`OpaquePrivateKeyBytes`].
31#[derive(Clone)]
32pub struct OpaqueKeypair {
33    /// The opaque private key
34    pub private: OpaquePrivateKeyBytes,
35    /// The opaque public key
36    pub public: OpaquePublicKey,
37}
38
39/// The underlying representation of an [`OpaqueKeypair`].
40///
41/// The encoded representation of an `OpaqueKeypairBytes` consists of the encoded representation of
42/// its [`OpaquePublicKeyBytes`] followed by the encoded representation of its
43/// [`OpaquePrivateKeyBytes`].
44pub struct OpaqueKeypairBytes {
45    /// The opaque private key
46    pub private: OpaquePrivateKeyBytes,
47    /// The opaque public key
48    pub public: OpaquePublicKeyBytes,
49}
50
51impl OpaqueKeypair {
52    /// Create a new `OpaqueKeypair`.
53    pub fn new(private_key: Vec<u8>, public: OpaquePublicKey) -> Self {
54        Self {
55            private: OpaquePrivateKeyBytes(private_key),
56            public,
57        }
58    }
59
60    /// Get the [`Algorithm`] for this key type.
61    pub fn algorithm(&self) -> Algorithm {
62        self.public.algorithm()
63    }
64
65    /// Decode [`OpaqueKeypair`] for the specified algorithm.
66    pub(super) fn decode_as(reader: &mut impl Reader, algorithm: Algorithm) -> Result<Self> {
67        let key = OpaqueKeypairBytes::decode(reader)?;
68        let public = OpaquePublicKey {
69            algorithm,
70            key: key.public,
71        };
72
73        Ok(Self {
74            public,
75            private: key.private,
76        })
77    }
78}
79
80impl From<Vec<u8>> for OpaquePrivateKeyBytes {
81    fn from(bytes: Vec<u8>) -> Self {
82        Self(bytes)
83    }
84}
85
86impl Decode for OpaquePrivateKeyBytes {
87    type Error = Error;
88
89    fn decode(reader: &mut impl Reader) -> Result<Self> {
90        let len = usize::decode(reader)?;
91        let mut bytes = vec![0; len];
92        reader.read(&mut bytes)?;
93        Ok(Self(bytes))
94    }
95}
96
97impl Decode for OpaqueKeypairBytes {
98    type Error = Error;
99
100    fn decode(reader: &mut impl Reader) -> Result<Self> {
101        let public = OpaquePublicKeyBytes::decode(reader)?;
102        let private = OpaquePrivateKeyBytes::decode(reader)?;
103
104        Ok(Self { public, private })
105    }
106}
107
108impl Encode for OpaqueKeypair {
109    fn encoded_len(&self) -> encoding::Result<usize> {
110        [self.public.encoded_len()?, self.private.encoded_len()?].checked_sum()
111    }
112
113    fn encode(&self, writer: &mut impl Writer) -> encoding::Result<()> {
114        self.public.encode(writer)?;
115        self.private.encode(writer)?;
116
117        Ok(())
118    }
119}
120
121impl ConstantTimeEq for OpaqueKeypair {
122    fn ct_eq(&self, other: &Self) -> Choice {
123        Choice::from((self.public == other.public) as u8) & self.private.ct_eq(&other.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
137impl From<&OpaqueKeypair> for OpaquePublicKey {
138    fn from(keypair: &OpaqueKeypair) -> OpaquePublicKey {
139        keypair.public.clone()
140    }
141}
142
143impl fmt::Debug for OpaqueKeypair {
144    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
145        f.debug_struct("OpaqueKeypair")
146            .field("public", &self.public)
147            .finish_non_exhaustive()
148    }
149}
150
151impl ConstantTimeEq for OpaquePrivateKeyBytes {
152    fn ct_eq(&self, other: &Self) -> Choice {
153        self.as_ref().ct_eq(other.as_ref())
154    }
155}
156
157impl AsRef<[u8]> for OpaquePrivateKeyBytes {
158    fn as_ref(&self) -> &[u8] {
159        &self.0
160    }
161}