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