1use super::Ed25519PublicKey;
6use crate::{Error, Result};
7use encoding::{CheckedSum, Decode, Encode, Reader, Writer};
8
9#[cfg(feature = "alloc")]
10use alloc::{borrow::ToOwned, string::String};
11
12#[cfg(feature = "ecdsa")]
13use crate::{EcdsaCurve, public::ecdsa::EcdsaNistP256PublicKey};
14
15const DEFAULT_APPLICATION_STRING: &str = "ssh:";
17
18#[cfg(feature = "ecdsa")]
21#[cfg_attr(not(feature = "alloc"), expect(missing_copy_implementations))]
22#[derive(Clone, Debug, Eq, Ord, Hash, PartialEq, PartialOrd)]
23pub struct SkEcdsaSha2NistP256 {
24 ec_point: EcdsaNistP256PublicKey,
26
27 #[cfg(feature = "alloc")]
29 application: String,
30}
31
32#[cfg(feature = "ecdsa")]
33impl SkEcdsaSha2NistP256 {
34 #[cfg(feature = "alloc")]
36 pub fn new(ec_point: EcdsaNistP256PublicKey, application: impl Into<String>) -> Self {
37 SkEcdsaSha2NistP256 {
38 ec_point,
39 application: application.into(),
40 }
41 }
42
43 #[must_use]
45 pub fn ec_point(&self) -> &EcdsaNistP256PublicKey {
46 &self.ec_point
47 }
48
49 #[cfg(not(feature = "alloc"))]
51 pub fn application(&self) -> &str {
52 DEFAULT_APPLICATION_STRING
53 }
54
55 #[cfg(feature = "alloc")]
57 #[must_use]
58 pub fn application(&self) -> &str {
59 &self.application
60 }
61}
62
63#[cfg(feature = "ecdsa")]
64impl Decode for SkEcdsaSha2NistP256 {
65 type Error = Error;
66
67 fn decode(reader: &mut impl Reader) -> Result<Self> {
68 if EcdsaCurve::decode(reader)? != EcdsaCurve::NistP256 {
69 return Err(Error::Crypto);
70 }
71
72 let mut buf = [0u8; 65];
73 let ec_point = EcdsaNistP256PublicKey::from_bytes(reader.read_byten(&mut buf)?)?;
74
75 #[cfg(not(feature = "alloc"))]
77 reader.drain_prefixed()?;
78
79 Ok(Self {
80 ec_point,
81
82 #[cfg(feature = "alloc")]
83 application: String::decode(reader)?,
84 })
85 }
86}
87
88#[cfg(feature = "ecdsa")]
89impl Encode for SkEcdsaSha2NistP256 {
90 fn encoded_len(&self) -> encoding::Result<usize> {
91 [
92 EcdsaCurve::NistP256.encoded_len()?,
93 self.ec_point.as_bytes().encoded_len()?,
94 self.application().encoded_len()?,
95 ]
96 .checked_sum()
97 }
98
99 fn encode(&self, writer: &mut impl Writer) -> encoding::Result<()> {
100 EcdsaCurve::NistP256.encode(writer)?;
101 self.ec_point.as_bytes().encode(writer)?;
102 self.application().encode(writer)?;
103 Ok(())
104 }
105}
106
107#[cfg(feature = "ecdsa")]
108impl From<EcdsaNistP256PublicKey> for SkEcdsaSha2NistP256 {
109 fn from(ec_point: EcdsaNistP256PublicKey) -> SkEcdsaSha2NistP256 {
110 SkEcdsaSha2NistP256 {
111 ec_point,
112 #[cfg(feature = "alloc")]
113 application: DEFAULT_APPLICATION_STRING.to_owned(),
114 }
115 }
116}
117
118#[cfg(feature = "ecdsa")]
119impl From<SkEcdsaSha2NistP256> for EcdsaNistP256PublicKey {
120 fn from(sk: SkEcdsaSha2NistP256) -> EcdsaNistP256PublicKey {
121 sk.ec_point
122 }
123}
124
125#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash)]
128#[cfg_attr(not(feature = "alloc"), allow(missing_copy_implementations))]
129pub struct SkEd25519 {
130 public_key: Ed25519PublicKey,
132
133 #[cfg(feature = "alloc")]
135 application: String,
136}
137
138impl SkEd25519 {
139 #[cfg(feature = "alloc")]
141 pub fn new(public_key: Ed25519PublicKey, application: impl Into<String>) -> Self {
142 SkEd25519 {
143 public_key,
144 application: application.into(),
145 }
146 }
147
148 #[must_use]
150 pub fn public_key(&self) -> &Ed25519PublicKey {
151 &self.public_key
152 }
153
154 #[cfg(not(feature = "alloc"))]
156 #[must_use]
157 pub fn application(&self) -> &str {
158 DEFAULT_APPLICATION_STRING
159 }
160
161 #[cfg(feature = "alloc")]
163 #[must_use]
164 pub fn application(&self) -> &str {
165 &self.application
166 }
167}
168
169impl Decode for SkEd25519 {
170 type Error = Error;
171
172 fn decode(reader: &mut impl Reader) -> Result<Self> {
173 let public_key = Ed25519PublicKey::decode(reader)?;
174
175 #[cfg(not(feature = "alloc"))]
177 reader.drain_prefixed()?;
178
179 Ok(Self {
180 public_key,
181
182 #[cfg(feature = "alloc")]
183 application: String::decode(reader)?,
184 })
185 }
186}
187
188impl Encode for SkEd25519 {
189 fn encoded_len(&self) -> encoding::Result<usize> {
190 [
191 self.public_key.encoded_len()?,
192 self.application().encoded_len()?,
193 ]
194 .checked_sum()
195 }
196
197 fn encode(&self, writer: &mut impl Writer) -> encoding::Result<()> {
198 self.public_key.encode(writer)?;
199 self.application().encode(writer)?;
200 Ok(())
201 }
202}
203
204impl From<Ed25519PublicKey> for SkEd25519 {
205 fn from(public_key: Ed25519PublicKey) -> SkEd25519 {
206 SkEd25519 {
207 public_key,
208 #[cfg(feature = "alloc")]
209 application: DEFAULT_APPLICATION_STRING.to_owned(),
210 }
211 }
212}
213
214impl From<SkEd25519> for Ed25519PublicKey {
215 fn from(sk: SkEd25519) -> Ed25519PublicKey {
216 sk.public_key
217 }
218}