tss_esapi/abstraction/
public.rs1use crate::interface_types::ecc::EccCurve;
5use crate::structures::Public;
6use crate::utils::PublicKey as TpmPublicKey;
7use crate::{Error, WrapperErrorKind};
8
9use core::convert::TryFrom;
10use elliptic_curve::{
11 generic_array::typenum::Unsigned,
12 sec1::{EncodedPoint, FromEncodedPoint, ModulusSize, ToEncodedPoint},
13 AffinePoint, CurveArithmetic, FieldBytesSize, PublicKey,
14};
15
16use x509_cert::spki::SubjectPublicKeyInfoOwned;
17
18#[cfg(feature = "rsa")]
19use {
20 crate::structures::RsaExponent,
21 rsa::{BigUint, RsaPublicKey},
22};
23
24#[cfg(any(
25 feature = "p192",
26 feature = "p224",
27 feature = "p256",
28 feature = "p384",
29 feature = "p521",
30 feature = "rsa",
31 feature = "sm2"
32))]
33use pkcs8::EncodePublicKey;
34
35#[cfg(feature = "rsa")]
38const RSA_DEFAULT_EXP: u64 = 65537;
39
40impl<C> TryFrom<&Public> for PublicKey<C>
41where
42 C: CurveArithmetic + AssociatedTpmCurve,
43 FieldBytesSize<C>: ModulusSize,
44 AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
45{
46 type Error = Error;
47
48 fn try_from(value: &Public) -> Result<Self, Self::Error> {
49 match value {
50 Public::Ecc {
51 parameters, unique, ..
52 } => {
53 if parameters.ecc_curve() != C::TPM_CURVE {
54 return Err(Error::local_error(WrapperErrorKind::InvalidParam));
55 }
56
57 let x = unique.x().as_bytes();
58 let y = unique.y().as_bytes();
59
60 if x.len() != FieldBytesSize::<C>::USIZE {
61 return Err(Error::local_error(WrapperErrorKind::InvalidParam));
62 }
63 if y.len() != FieldBytesSize::<C>::USIZE {
64 return Err(Error::local_error(WrapperErrorKind::InvalidParam));
65 }
66
67 let encoded_point =
68 EncodedPoint::<C>::from_affine_coordinates(x.into(), y.into(), false);
69 let public_key = PublicKey::<C>::try_from(&encoded_point)
70 .map_err(|_| Error::local_error(WrapperErrorKind::InvalidParam))?;
71
72 Ok(public_key)
73 }
74 _ => Err(Error::local_error(WrapperErrorKind::UnsupportedParam)),
75 }
76 }
77}
78
79#[cfg(feature = "rsa")]
80impl TryFrom<&Public> for RsaPublicKey {
81 type Error = Error;
82
83 fn try_from(value: &Public) -> Result<Self, Self::Error> {
84 match value {
85 Public::Rsa {
86 unique, parameters, ..
87 } => {
88 let exponent = match parameters.exponent() {
89 RsaExponent::ZERO_EXPONENT => BigUint::from(RSA_DEFAULT_EXP),
90 _ => BigUint::from(parameters.exponent().value()),
91 };
92 let modulus = BigUint::from_bytes_be(unique.as_bytes());
93
94 let public_key = RsaPublicKey::new(modulus, exponent)
95 .map_err(|_| Error::local_error(WrapperErrorKind::InvalidParam))?;
96
97 Ok(public_key)
98 }
99 _ => Err(Error::local_error(WrapperErrorKind::UnsupportedParam)),
100 }
101 }
102}
103
104impl TryFrom<&Public> for SubjectPublicKeyInfoOwned {
105 type Error = Error;
106
107 fn try_from(value: &Public) -> Result<Self, Self::Error> {
115 match value {
116 #[cfg(feature = "rsa")]
117 Public::Rsa { .. } => {
118 let public_key = RsaPublicKey::try_from(value)?;
119
120 Ok(public_key
121 .to_public_key_der()
122 .map_err(|_| Error::local_error(WrapperErrorKind::InvalidParam))?
123 .decode_msg::<Self>()
124 .map_err(|_| Error::local_error(WrapperErrorKind::InvalidParam))?)
125 }
126 #[allow(unused)]
127 Public::Ecc { parameters, .. } => {
128 macro_rules! read_key {
129 ($key_type:ty) => {
130 if parameters.ecc_curve() == <$key_type>::TPM_CURVE {
131 let public_key = PublicKey::<$key_type>::try_from(value)?;
132
133 return public_key
134 .to_public_key_der()
135 .map_err(|_| Error::local_error(WrapperErrorKind::InvalidParam))?
136 .decode_msg::<Self>()
137 .map_err(|_| Error::local_error(WrapperErrorKind::InvalidParam));
138 }
139 };
140 }
141
142 #[cfg(feature = "p192")]
143 read_key!(p192::NistP192);
144 #[cfg(feature = "p224")]
145 read_key!(p224::NistP224);
146 #[cfg(feature = "p256")]
147 read_key!(p256::NistP256);
148 #[cfg(feature = "p384")]
149 read_key!(p384::NistP384);
150 #[cfg(feature = "p521")]
151 read_key!(p521::NistP521);
152 #[cfg(feature = "sm2")]
153 read_key!(sm2::Sm2);
154
155 Err(Error::local_error(WrapperErrorKind::UnsupportedParam))
156 }
157 _ => Err(Error::local_error(WrapperErrorKind::UnsupportedParam)),
158 }
159 }
160}
161
162impl<C> TryFrom<&TpmPublicKey> for PublicKey<C>
163where
164 C: CurveArithmetic + AssociatedTpmCurve,
165 FieldBytesSize<C>: ModulusSize,
166 AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
167{
168 type Error = Error;
169
170 fn try_from(value: &TpmPublicKey) -> Result<Self, Self::Error> {
171 match value {
172 TpmPublicKey::Ecc { x, y } => {
173 let x = x.as_slice();
174 let y = y.as_slice();
175
176 if x.len() != FieldBytesSize::<C>::USIZE {
179 return Err(Error::local_error(WrapperErrorKind::InvalidParam));
180 }
181 if y.len() != FieldBytesSize::<C>::USIZE {
182 return Err(Error::local_error(WrapperErrorKind::InvalidParam));
183 }
184
185 let encoded_point =
186 EncodedPoint::<C>::from_affine_coordinates(x.into(), y.into(), false);
187 let public_key = PublicKey::<C>::try_from(&encoded_point)
188 .map_err(|_| Error::local_error(WrapperErrorKind::InvalidParam))?;
189
190 Ok(public_key)
191 }
192 _ => Err(Error::local_error(WrapperErrorKind::UnsupportedParam)),
193 }
194 }
195}
196
197#[cfg(feature = "rsa")]
198impl TryFrom<&TpmPublicKey> for RsaPublicKey {
199 type Error = Error;
200
201 fn try_from(value: &TpmPublicKey) -> Result<Self, Self::Error> {
202 match value {
203 TpmPublicKey::Rsa(modulus) => {
204 let exponent = BigUint::from(RSA_DEFAULT_EXP);
205 let modulus = BigUint::from_bytes_be(modulus.as_slice());
206
207 let public_key = RsaPublicKey::new(modulus, exponent)
208 .map_err(|_| Error::local_error(WrapperErrorKind::InvalidParam))?;
209
210 Ok(public_key)
211 }
212 _ => Err(Error::local_error(WrapperErrorKind::UnsupportedParam)),
213 }
214 }
215}
216
217pub trait AssociatedTpmCurve {
219 const TPM_CURVE: EccCurve;
221}
222
223#[cfg(feature = "p192")]
224impl AssociatedTpmCurve for p192::NistP192 {
225 const TPM_CURVE: EccCurve = EccCurve::NistP192;
226}
227
228#[cfg(feature = "p224")]
229impl AssociatedTpmCurve for p224::NistP224 {
230 const TPM_CURVE: EccCurve = EccCurve::NistP224;
231}
232
233#[cfg(feature = "p256")]
234impl AssociatedTpmCurve for p256::NistP256 {
235 const TPM_CURVE: EccCurve = EccCurve::NistP256;
236}
237
238#[cfg(feature = "p384")]
239impl AssociatedTpmCurve for p384::NistP384 {
240 const TPM_CURVE: EccCurve = EccCurve::NistP384;
241}
242
243#[cfg(feature = "p521")]
244impl AssociatedTpmCurve for p521::NistP521 {
245 const TPM_CURVE: EccCurve = EccCurve::NistP521;
246}
247
248#[cfg(feature = "sm2")]
249impl AssociatedTpmCurve for sm2::Sm2 {
250 const TPM_CURVE: EccCurve = EccCurve::Sm2P256;
251}