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::AsUintRef, 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::RsaPrivateKeyRef::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::RsaPublicKeyRef::from_der(bytes)?.try_into()
38 }
39}
40
41impl<U: AsUintRef> TryFrom<pkcs1::RsaPrivateKey<U>> for RsaPrivateKey {
42 type Error = pkcs1::Error;
43
44 fn try_from(pkcs1_key: pkcs1::RsaPrivateKey<U>) -> 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_uint_ref().as_bytes().len())
53 .map_err(|_| KeyMalformed)?
54 * 8;
55
56 let n = uint_from_slice(pkcs1_key.modulus.as_uint_ref().as_bytes(), bits)?;
57 let bits_e = u32::try_from(pkcs1_key.public_exponent.as_uint_ref().as_bytes().len())
58 .map_err(|_| pkcs1::Error::KeyMalformed)?
59 * 8;
60 let e = uint_from_slice(pkcs1_key.public_exponent.as_uint_ref().as_bytes(), bits_e)?;
61 let e = Option::from(e).ok_or(KeyMalformed)?;
62
63 let d = uint_from_slice(pkcs1_key.private_exponent.as_uint_ref().as_bytes(), bits)?;
64 let prime1 = uint_from_slice(pkcs1_key.prime1.as_uint_ref().as_bytes(), bits)?;
65 let prime2 = uint_from_slice(pkcs1_key.prime2.as_uint_ref().as_bytes(), bits)?;
66 let primes = vec![prime1, prime2];
67
68 RsaPrivateKey::from_components(n, e, d, primes).map_err(|_| KeyMalformed)
69 }
70}
71
72impl<U: AsUintRef> TryFrom<pkcs1::RsaPublicKey<U>> for RsaPublicKey {
73 type Error = pkcs1::Error;
74
75 fn try_from(pkcs1_key: pkcs1::RsaPublicKey<U>) -> pkcs1::Result<Self> {
76 use pkcs1::Error::KeyMalformed;
77
78 let bits = u32::try_from(pkcs1_key.modulus.as_uint_ref().as_bytes().len())
79 .map_err(|_| KeyMalformed)?
80 * 8;
81 let n = uint_from_slice(pkcs1_key.modulus.as_uint_ref().as_bytes(), bits)?;
82
83 let bits_e = u32::try_from(pkcs1_key.public_exponent.as_uint_ref().as_bytes().len())
84 .map_err(|_| KeyMalformed)?
85 * 8;
86 let e = uint_from_slice(pkcs1_key.public_exponent.as_uint_ref().as_bytes(), bits_e)?;
87
88 RsaPublicKey::new(n, e).map_err(|_| KeyMalformed)
89 }
90}
91
92impl pkcs1::EncodeRsaPrivateKey for RsaPrivateKey {
93 fn to_pkcs1_der(&self) -> pkcs1::Result<SecretDocument> {
94 if self.primes.len() > 2 {
96 return Err(pkcs1::Error::Crypto);
97 }
98
99 let modulus = self.n().to_be_bytes();
100 let public_exponent = self.e().to_be_bytes();
101 let private_exponent = Zeroizing::new(self.d().to_be_bytes());
102 let prime1 = Zeroizing::new(self.primes[0].to_be_bytes());
103 let prime2 = Zeroizing::new(self.primes[1].to_be_bytes());
104
105 let bits = self.d().bits_precision();
106
107 debug_assert!(bits >= self.primes[0].bits_vartime());
108 debug_assert!(bits >= self.primes[1].bits_vartime());
109
110 let exponent1 = Zeroizing::new(
111 (self.d()
112 % NonZero::new((&self.primes[0]).resize_unchecked(bits) - &BoxedUint::one())
113 .unwrap())
114 .to_be_bytes(),
115 );
116 let exponent2 = Zeroizing::new(
117 (self.d()
118 % NonZero::new((&self.primes[1]).resize_unchecked(bits) - &BoxedUint::one())
119 .unwrap())
120 .to_be_bytes(),
121 );
122 let coefficient = Zeroizing::new(
123 self.crt_coefficient()
124 .ok_or(pkcs1::Error::Crypto)?
125 .to_be_bytes(),
126 );
127
128 Ok(SecretDocument::encode_msg(&pkcs1::RsaPrivateKey {
129 modulus: pkcs1::UintRef::new(&modulus)?,
130 public_exponent: pkcs1::UintRef::new(&public_exponent)?,
131 private_exponent: pkcs1::UintRef::new(&private_exponent)?,
132 prime1: pkcs1::UintRef::new(&prime1)?,
133 prime2: pkcs1::UintRef::new(&prime2)?,
134 exponent1: pkcs1::UintRef::new(&exponent1)?,
135 exponent2: pkcs1::UintRef::new(&exponent2)?,
136 coefficient: pkcs1::UintRef::new(&coefficient)?,
137 other_prime_infos: None,
138 })?)
139 }
140}
141
142impl pkcs1::EncodeRsaPublicKey for RsaPublicKey {
143 fn to_pkcs1_der(&self) -> pkcs1::Result<Document> {
144 let modulus = self.n().to_be_bytes();
145 let public_exponent = self.e().to_be_bytes();
146
147 Ok(Document::encode_msg(&pkcs1::RsaPublicKeyRef {
148 modulus: pkcs1::UintRef::new(&modulus)?,
149 public_exponent: pkcs1::UintRef::new(&public_exponent)?,
150 })?)
151 }
152}
153
154pub(crate) fn verify_algorithm_id(algorithm: &spki::AlgorithmIdentifierRef) -> spki::Result<()> {
158 match algorithm.oid {
159 pkcs1::ALGORITHM_OID => {
160 if algorithm.parameters_any()? != pkcs8::der::asn1::Null.into() {
161 return Err(spki::Error::KeyMalformed);
162 }
163 }
164 ID_RSASSA_PSS => {
165 if algorithm.parameters.is_some() {
166 return Err(spki::Error::KeyMalformed);
167 }
168 }
169 _ => return Err(spki::Error::OidUnknown { oid: algorithm.oid }),
170 };
171
172 Ok(())
173}
174
175impl TryFrom<pkcs8::PrivateKeyInfoRef<'_>> for RsaPrivateKey {
176 type Error = pkcs8::Error;
177
178 fn try_from(private_key_info: pkcs8::PrivateKeyInfoRef<'_>) -> pkcs8::Result<Self> {
179 verify_algorithm_id(&private_key_info.algorithm)?;
180
181 pkcs1::RsaPrivateKeyRef::try_from(private_key_info.private_key)
182 .and_then(TryInto::try_into)
183 .map_err(pkcs1_error_to_pkcs8)
184 }
185}
186
187impl TryFrom<pkcs8::SubjectPublicKeyInfoRef<'_>> for RsaPublicKey {
188 type Error = spki::Error;
189
190 fn try_from(spki: pkcs8::SubjectPublicKeyInfoRef<'_>) -> spki::Result<Self> {
191 use spki::Error::KeyMalformed;
192
193 verify_algorithm_id(&spki.algorithm)?;
194
195 pkcs1::RsaPublicKeyRef::try_from(spki.subject_public_key.as_bytes().ok_or(KeyMalformed)?)
196 .and_then(TryInto::try_into)
197 .map_err(pkcs1_error_to_spki)
198 }
199}
200
201impl EncodePrivateKey for RsaPrivateKey {
202 fn to_pkcs8_der(&self) -> pkcs8::Result<SecretDocument> {
203 let private_key =
204 pkcs1::EncodeRsaPrivateKey::to_pkcs1_der(self).map_err(pkcs1_error_to_pkcs8)?;
205
206 pkcs8::PrivateKeyInfoRef::new(
207 pkcs1::ALGORITHM_ID,
208 OctetStringRef::new(private_key.as_bytes())?,
209 )
210 .try_into()
211 }
212}
213
214impl EncodePublicKey for RsaPublicKey {
215 fn to_public_key_der(&self) -> spki::Result<Document> {
216 let subject_public_key =
217 pkcs1::EncodeRsaPublicKey::to_pkcs1_der(self).map_err(pkcs1_error_to_spki)?;
218
219 pkcs8::SubjectPublicKeyInfoRef {
220 algorithm: pkcs1::ALGORITHM_ID,
221 subject_public_key: pkcs8::der::asn1::BitStringRef::new(
222 0,
223 subject_public_key.as_ref(),
224 )?,
225 }
226 .try_into()
227 }
228}
229
230fn pkcs1_error_to_pkcs8(error: pkcs1::Error) -> pkcs8::Error {
232 match error {
233 pkcs1::Error::Asn1(e) => pkcs8::Error::Asn1(e),
234 _ => pkcs8::KeyError::Invalid.into(),
235 }
236}
237
238fn pkcs1_error_to_spki(error: pkcs1::Error) -> spki::Error {
240 match error {
241 pkcs1::Error::Asn1(e) => spki::Error::Asn1(e),
242 _ => spki::Error::KeyMalformed,
243 }
244}