1#![cfg(feature = "encoding")]
7
8use crate::{
9 traits::{PrivateKeyParts, PublicKeyParts},
10 RsaPrivateKey, RsaPublicKey,
11};
12use core::convert::{TryFrom, TryInto};
13use crypto_bigint::{BoxedUint, NonZero, Resize};
14use pkcs8::{
15 der::{asn1::OctetStringRef, Decode},
16 Document, EncodePrivateKey, EncodePublicKey, ObjectIdentifier, SecretDocument,
17};
18use zeroize::Zeroizing;
19
20pub const ID_RSASSA_PSS: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.2.840.113549.1.1.10");
22
23fn uint_from_slice(data: &[u8], bits: u32) -> pkcs1::Result<BoxedUint> {
26 BoxedUint::from_be_slice(data, bits).map_err(|_| pkcs1::Error::KeyMalformed)
27}
28
29impl pkcs1::DecodeRsaPrivateKey for RsaPrivateKey {
30 fn from_pkcs1_der(bytes: &[u8]) -> pkcs1::Result<Self> {
31 pkcs1::RsaPrivateKey::from_der(bytes)?.try_into()
32 }
33}
34
35impl pkcs1::DecodeRsaPublicKey for RsaPublicKey {
36 fn from_pkcs1_der(bytes: &[u8]) -> pkcs1::Result<Self> {
37 pkcs1::RsaPublicKey::from_der(bytes)?.try_into()
38 }
39}
40
41impl TryFrom<pkcs1::RsaPrivateKey<'_>> for RsaPrivateKey {
42 type Error = pkcs1::Error;
43
44 fn try_from(pkcs1_key: pkcs1::RsaPrivateKey<'_>) -> pkcs1::Result<RsaPrivateKey> {
45 use pkcs1::Error::KeyMalformed;
46
47 if pkcs1_key.version() != pkcs1::Version::TwoPrime {
49 return Err(pkcs1::Error::Version);
50 }
51
52 let bits = u32::try_from(pkcs1_key.modulus.as_bytes().len()).map_err(|_| KeyMalformed)? * 8;
53
54 let n = uint_from_slice(pkcs1_key.modulus.as_bytes(), bits)?;
55 let bits_e = u32::try_from(pkcs1_key.public_exponent.as_bytes().len())
56 .map_err(|_| pkcs1::Error::KeyMalformed)?
57 * 8;
58 let e = uint_from_slice(pkcs1_key.public_exponent.as_bytes(), bits_e)?;
59 let e = Option::from(e).ok_or(KeyMalformed)?;
60
61 let d = uint_from_slice(pkcs1_key.private_exponent.as_bytes(), bits)?;
62 let prime1 = uint_from_slice(pkcs1_key.prime1.as_bytes(), bits)?;
63 let prime2 = uint_from_slice(pkcs1_key.prime2.as_bytes(), bits)?;
64 let primes = vec![prime1, prime2];
65
66 RsaPrivateKey::from_components(n, e, d, primes).map_err(|_| KeyMalformed)
67 }
68}
69
70impl TryFrom<pkcs1::RsaPublicKey<'_>> for RsaPublicKey {
71 type Error = pkcs1::Error;
72
73 fn try_from(pkcs1_key: pkcs1::RsaPublicKey<'_>) -> pkcs1::Result<Self> {
74 use pkcs1::Error::KeyMalformed;
75
76 let bits = u32::try_from(pkcs1_key.modulus.as_bytes().len()).map_err(|_| KeyMalformed)? * 8;
77 let n = uint_from_slice(pkcs1_key.modulus.as_bytes(), bits)?;
78
79 let bits_e = u32::try_from(pkcs1_key.public_exponent.as_bytes().len())
80 .map_err(|_| KeyMalformed)?
81 * 8;
82 let e = uint_from_slice(pkcs1_key.public_exponent.as_bytes(), bits_e)?;
83
84 RsaPublicKey::new(n, e).map_err(|_| KeyMalformed)
85 }
86}
87
88impl pkcs1::EncodeRsaPrivateKey for RsaPrivateKey {
89 fn to_pkcs1_der(&self) -> pkcs1::Result<SecretDocument> {
90 if self.primes.len() > 2 {
92 return Err(pkcs1::Error::Crypto);
93 }
94
95 let modulus = self.n().to_be_bytes();
96 let public_exponent = self.e().to_be_bytes();
97 let private_exponent = Zeroizing::new(self.d().to_be_bytes());
98 let prime1 = Zeroizing::new(self.primes[0].to_be_bytes());
99 let prime2 = Zeroizing::new(self.primes[1].to_be_bytes());
100
101 let bits = self.d().bits_precision();
102
103 debug_assert!(bits >= self.primes[0].bits_vartime());
104 debug_assert!(bits >= self.primes[1].bits_vartime());
105
106 let exponent1 = Zeroizing::new(
107 (self.d()
108 % NonZero::new((&self.primes[0]).resize_unchecked(bits) - &BoxedUint::one())
109 .unwrap())
110 .to_be_bytes(),
111 );
112 let exponent2 = Zeroizing::new(
113 (self.d()
114 % NonZero::new((&self.primes[1]).resize_unchecked(bits) - &BoxedUint::one())
115 .unwrap())
116 .to_be_bytes(),
117 );
118 let coefficient = Zeroizing::new(
119 self.crt_coefficient()
120 .ok_or(pkcs1::Error::Crypto)?
121 .to_be_bytes(),
122 );
123
124 Ok(SecretDocument::encode_msg(&pkcs1::RsaPrivateKey {
125 modulus: pkcs1::UintRef::new(&modulus)?,
126 public_exponent: pkcs1::UintRef::new(&public_exponent)?,
127 private_exponent: pkcs1::UintRef::new(&private_exponent)?,
128 prime1: pkcs1::UintRef::new(&prime1)?,
129 prime2: pkcs1::UintRef::new(&prime2)?,
130 exponent1: pkcs1::UintRef::new(&exponent1)?,
131 exponent2: pkcs1::UintRef::new(&exponent2)?,
132 coefficient: pkcs1::UintRef::new(&coefficient)?,
133 other_prime_infos: None,
134 })?)
135 }
136}
137
138impl pkcs1::EncodeRsaPublicKey for RsaPublicKey {
139 fn to_pkcs1_der(&self) -> pkcs1::Result<Document> {
140 let modulus = self.n().to_be_bytes();
141 let public_exponent = self.e().to_be_bytes();
142
143 Ok(Document::encode_msg(&pkcs1::RsaPublicKey {
144 modulus: pkcs1::UintRef::new(&modulus)?,
145 public_exponent: pkcs1::UintRef::new(&public_exponent)?,
146 })?)
147 }
148}
149
150pub(crate) fn verify_algorithm_id(algorithm: &spki::AlgorithmIdentifierRef) -> spki::Result<()> {
154 match algorithm.oid {
155 pkcs1::ALGORITHM_OID => {
156 if algorithm.parameters_any()? != pkcs8::der::asn1::Null.into() {
157 return Err(spki::Error::KeyMalformed);
158 }
159 }
160 ID_RSASSA_PSS => {
161 if algorithm.parameters.is_some() {
162 return Err(spki::Error::KeyMalformed);
163 }
164 }
165 _ => return Err(spki::Error::OidUnknown { oid: algorithm.oid }),
166 };
167
168 Ok(())
169}
170
171impl TryFrom<pkcs8::PrivateKeyInfoRef<'_>> for RsaPrivateKey {
172 type Error = pkcs8::Error;
173
174 fn try_from(private_key_info: pkcs8::PrivateKeyInfoRef<'_>) -> pkcs8::Result<Self> {
175 verify_algorithm_id(&private_key_info.algorithm)?;
176
177 pkcs1::RsaPrivateKey::try_from(private_key_info.private_key)
178 .and_then(TryInto::try_into)
179 .map_err(pkcs1_error_to_pkcs8)
180 }
181}
182
183impl TryFrom<pkcs8::SubjectPublicKeyInfoRef<'_>> for RsaPublicKey {
184 type Error = spki::Error;
185
186 fn try_from(spki: pkcs8::SubjectPublicKeyInfoRef<'_>) -> spki::Result<Self> {
187 use spki::Error::KeyMalformed;
188
189 verify_algorithm_id(&spki.algorithm)?;
190
191 pkcs1::RsaPublicKey::try_from(spki.subject_public_key.as_bytes().ok_or(KeyMalformed)?)
192 .and_then(TryInto::try_into)
193 .map_err(pkcs1_error_to_spki)
194 }
195}
196
197impl EncodePrivateKey for RsaPrivateKey {
198 fn to_pkcs8_der(&self) -> pkcs8::Result<SecretDocument> {
199 let private_key =
200 pkcs1::EncodeRsaPrivateKey::to_pkcs1_der(self).map_err(pkcs1_error_to_pkcs8)?;
201
202 pkcs8::PrivateKeyInfoRef::new(
203 pkcs1::ALGORITHM_ID,
204 OctetStringRef::new(private_key.as_bytes())?,
205 )
206 .try_into()
207 }
208}
209
210impl EncodePublicKey for RsaPublicKey {
211 fn to_public_key_der(&self) -> spki::Result<Document> {
212 let subject_public_key =
213 pkcs1::EncodeRsaPublicKey::to_pkcs1_der(self).map_err(pkcs1_error_to_spki)?;
214
215 pkcs8::SubjectPublicKeyInfoRef {
216 algorithm: pkcs1::ALGORITHM_ID,
217 subject_public_key: pkcs8::der::asn1::BitStringRef::new(
218 0,
219 subject_public_key.as_ref(),
220 )?,
221 }
222 .try_into()
223 }
224}
225
226fn pkcs1_error_to_pkcs8(error: pkcs1::Error) -> pkcs8::Error {
228 match error {
229 pkcs1::Error::Asn1(e) => pkcs8::Error::Asn1(e),
230 _ => pkcs8::Error::KeyMalformed,
231 }
232}
233
234fn pkcs1_error_to_spki(error: pkcs1::Error) -> spki::Error {
236 match error {
237 pkcs1::Error::Asn1(e) => spki::Error::Asn1(e),
238 _ => spki::Error::KeyMalformed,
239 }
240}