1use crypto_bigint::{BoxedUint, NonZero, Resize};
29use pkcs8::{
30 Document, SecretDocument,
31 der::{
32 Decode,
33 asn1::OctetStringRef,
34 pem::{LineEnding, PemLabel},
35 },
36};
37use rsa::{
38 RsaPrivateKey, RsaPublicKey,
39 traits::{PrivateKeyParts, PublicKeyParts},
40};
41use zeroize::Zeroizing;
42
43pub trait RsaPrivateKeyEncoding: Sized {
45 fn from_pkcs1_der(bytes: &[u8]) -> pkcs1::Result<Self>;
47 fn to_pkcs1_der(&self) -> pkcs1::Result<SecretDocument>;
49 fn from_pkcs8_der(bytes: &[u8]) -> pkcs8::Result<Self>;
51 fn to_pkcs8_der(&self) -> pkcs8::Result<SecretDocument>;
53 fn from_pkcs1_pem(pem: &str) -> pkcs1::Result<Self> {
55 let (label, doc) = SecretDocument::from_pem(pem)?;
56 pkcs1::RsaPrivateKeyRef::validate_pem_label(label)?;
57 Self::from_pkcs1_der(doc.as_bytes())
58 }
59 fn to_pkcs1_pem(&self, ending: LineEnding) -> pkcs1::Result<Zeroizing<String>> {
61 Ok(self
62 .to_pkcs1_der()?
63 .to_pem(pkcs1::RsaPrivateKeyRef::PEM_LABEL, ending)?)
64 }
65 fn from_pkcs8_pem(pem: &str) -> pkcs8::Result<Self> {
67 let (label, doc) = SecretDocument::from_pem(pem)?;
68 pkcs8::PrivateKeyInfoRef::validate_pem_label(label)?;
69 Self::from_pkcs8_der(doc.as_bytes())
70 }
71 fn to_pkcs8_pem(&self, ending: LineEnding) -> pkcs8::Result<Zeroizing<String>> {
73 Ok(self
74 .to_pkcs8_der()?
75 .to_pem(pkcs8::PrivateKeyInfoRef::PEM_LABEL, ending)?)
76 }
77 fn from_pkcs8_encrypted_der(bytes: &[u8], password: impl AsRef<[u8]>) -> pkcs8::Result<Self> {
79 let plaintext = pkcs8::EncryptedPrivateKeyInfoRef::try_from(bytes)?.decrypt(password)?;
80 Self::from_pkcs8_der(plaintext.as_bytes())
81 }
82 fn from_pkcs8_encrypted_pem(pem: &str, password: impl AsRef<[u8]>) -> pkcs8::Result<Self> {
84 let (label, doc) = SecretDocument::from_pem(pem)?;
85 pkcs8::EncryptedPrivateKeyInfoRef::validate_pem_label(label)?;
86 Self::from_pkcs8_encrypted_der(doc.as_bytes(), password)
87 }
88}
89
90pub trait RsaPublicKeyEncoding: Sized {
92 fn from_pkcs1_der(bytes: &[u8]) -> pkcs1::Result<Self>;
94 fn to_pkcs1_der(&self) -> pkcs1::Result<Document>;
96 fn from_public_key_der(bytes: &[u8]) -> pkcs8::spki::Result<Self>;
98 fn to_public_key_der(&self) -> pkcs8::spki::Result<Document>;
100 fn from_pkcs1_pem(pem: &str) -> pkcs1::Result<Self> {
102 let (label, doc) = Document::from_pem(pem)?;
103 pkcs1::RsaPublicKeyRef::validate_pem_label(label)?;
104 Self::from_pkcs1_der(doc.as_bytes())
105 }
106 fn to_pkcs1_pem(&self, ending: LineEnding) -> pkcs1::Result<String> {
108 Ok(self
109 .to_pkcs1_der()?
110 .to_pem(pkcs1::RsaPublicKeyRef::PEM_LABEL, ending)?)
111 }
112 fn from_public_key_pem(pem: &str) -> pkcs8::spki::Result<Self> {
114 let (label, doc) = Document::from_pem(pem)?;
115 pkcs8::SubjectPublicKeyInfoRef::validate_pem_label(label)?;
116 Self::from_public_key_der(doc.as_bytes())
117 }
118 fn to_public_key_pem(&self, ending: LineEnding) -> pkcs8::spki::Result<String> {
120 Ok(self
121 .to_public_key_der()?
122 .to_pem(pkcs8::SubjectPublicKeyInfoRef::PEM_LABEL, ending)?)
123 }
124}
125
126fn uint(data: &[u8], bits: u32) -> pkcs1::Result<BoxedUint> {
127 BoxedUint::from_be_slice(data, bits).map_err(|_| pkcs1::Error::KeyMalformed)
128}
129
130fn width(data: &[u8]) -> pkcs1::Result<u32> {
131 u32::try_from(data.len())
132 .ok()
133 .and_then(|n| n.checked_mul(8))
134 .ok_or(pkcs1::Error::KeyMalformed)
135}
136
137impl RsaPrivateKeyEncoding for RsaPrivateKey {
138 fn from_pkcs1_der(bytes: &[u8]) -> pkcs1::Result<Self> {
139 let key = pkcs1::RsaPrivateKeyRef::from_der(bytes)?;
140 if key.version() != pkcs1::Version::TwoPrime {
141 return Err(pkcs1::Error::Version);
142 }
143 let bits = width(key.modulus.as_bytes())?;
144 for component in [key.private_exponent, key.prime1, key.prime2] {
147 if component.as_bytes().len() > key.modulus.as_bytes().len() {
148 return Err(pkcs1::Error::KeyMalformed);
149 }
150 }
151 let n = uint(key.modulus.as_bytes(), bits)?;
152 let e = uint(
153 key.public_exponent.as_bytes(),
154 width(key.public_exponent.as_bytes())?,
155 )?;
156 let d = uint(key.private_exponent.as_bytes(), bits)?;
157 let primes = vec![
158 uint(key.prime1.as_bytes(), bits)?,
159 uint(key.prime2.as_bytes(), bits)?,
160 ];
161 Self::from_components(n, e, d, primes).map_err(|_| pkcs1::Error::KeyMalformed)
162 }
163
164 fn to_pkcs1_der(&self) -> pkcs1::Result<SecretDocument> {
165 if self.primes().len() != 2 {
166 return Err(pkcs1::Error::Crypto);
167 }
168 let modulus = self.n().to_be_bytes();
169 let public_exponent = self.e().to_be_bytes();
170 let private_exponent = Zeroizing::new(self.d().to_be_bytes());
171 let prime1 = Zeroizing::new(self.primes()[0].to_be_bytes());
172 let prime2 = Zeroizing::new(self.primes()[1].to_be_bytes());
173 let bits = self.d().bits_precision();
174 let exponent1 = Zeroizing::new(
175 (self.d()
176 % NonZero::new((&self.primes()[0]).resize_unchecked(bits) - &BoxedUint::one())
177 .unwrap())
178 .to_be_bytes(),
179 );
180 let exponent2 = Zeroizing::new(
181 (self.d()
182 % NonZero::new((&self.primes()[1]).resize_unchecked(bits) - &BoxedUint::one())
183 .unwrap())
184 .to_be_bytes(),
185 );
186 let coefficient = Zeroizing::new(
187 self.crt_coefficient()
188 .ok_or(pkcs1::Error::Crypto)?
189 .to_be_bytes(),
190 );
191 Ok(SecretDocument::encode_msg(&pkcs1::RsaPrivateKeyRef {
192 modulus: pkcs1::UintRef::new(&modulus)?,
193 public_exponent: pkcs1::UintRef::new(&public_exponent)?,
194 private_exponent: pkcs1::UintRef::new(&private_exponent)?,
195 prime1: pkcs1::UintRef::new(&prime1)?,
196 prime2: pkcs1::UintRef::new(&prime2)?,
197 exponent1: pkcs1::UintRef::new(&exponent1)?,
198 exponent2: pkcs1::UintRef::new(&exponent2)?,
199 coefficient: pkcs1::UintRef::new(&coefficient)?,
200 other_prime_infos: None,
201 })?)
202 }
203
204 fn from_pkcs8_der(bytes: &[u8]) -> pkcs8::Result<Self> {
205 let info = pkcs8::PrivateKeyInfoRef::from_der(bytes)?;
206 verify_algorithm_id(&info.algorithm)?;
207 Self::from_pkcs1_der(info.private_key.as_bytes()).map_err(private_error)
208 }
209
210 fn to_pkcs8_der(&self) -> pkcs8::Result<SecretDocument> {
211 let key = self.to_pkcs1_der().map_err(private_error)?;
212 pkcs8::PrivateKeyInfoRef::new(pkcs1::ALGORITHM_ID, OctetStringRef::new(key.as_bytes())?)
213 .try_into()
214 }
215}
216
217impl RsaPublicKeyEncoding for RsaPublicKey {
218 fn from_pkcs1_der(bytes: &[u8]) -> pkcs1::Result<Self> {
219 let key = pkcs1::RsaPublicKeyRef::from_der(bytes)?;
220 let n = uint(key.modulus.as_bytes(), width(key.modulus.as_bytes())?)?;
221 let e = uint(
222 key.public_exponent.as_bytes(),
223 width(key.public_exponent.as_bytes())?,
224 )?;
225 Self::new(n, e).map_err(|_| pkcs1::Error::KeyMalformed)
226 }
227
228 fn to_pkcs1_der(&self) -> pkcs1::Result<Document> {
229 let modulus = self.n().to_be_bytes();
230 let exponent = self.e().to_be_bytes();
231 Ok(Document::encode_msg(&pkcs1::RsaPublicKeyRef {
232 modulus: pkcs1::UintRef::new(&modulus)?,
233 public_exponent: pkcs1::UintRef::new(&exponent)?,
234 })?)
235 }
236
237 fn from_public_key_der(bytes: &[u8]) -> pkcs8::spki::Result<Self> {
238 let info = pkcs8::SubjectPublicKeyInfoRef::from_der(bytes)?;
239 verify_algorithm_id(&info.algorithm)?;
240 Self::from_pkcs1_der(
241 info.subject_public_key
242 .as_bytes()
243 .ok_or(pkcs8::spki::Error::KeyMalformed)?,
244 )
245 .map_err(public_error)
246 }
247
248 fn to_public_key_der(&self) -> pkcs8::spki::Result<Document> {
249 let key = self.to_pkcs1_der().map_err(public_error)?;
250 pkcs8::SubjectPublicKeyInfoRef {
251 algorithm: pkcs1::ALGORITHM_ID,
252 subject_public_key: pkcs8::der::asn1::BitStringRef::new(0, key.as_bytes())?,
253 }
254 .try_into()
255 }
256}
257
258fn verify_algorithm_id(algorithm: &pkcs8::AlgorithmIdentifierRef<'_>) -> pkcs8::spki::Result<()> {
259 match algorithm.oid {
260 pkcs1::ALGORITHM_OID => {
261 if algorithm.parameters_any()? != pkcs8::der::asn1::Null.into() {
264 return Err(pkcs8::spki::Error::KeyMalformed);
265 }
266 }
267 oid if oid == pkcs8::ObjectIdentifier::new_unwrap("1.2.840.113549.1.1.10") => {
268 if algorithm.parameters.is_some() {
274 return Err(pkcs8::spki::Error::KeyMalformed);
275 }
276 }
277 oid => return Err(pkcs8::spki::Error::OidUnknown { oid }),
278 }
279 Ok(())
280}
281
282fn private_error(error: pkcs1::Error) -> pkcs8::Error {
283 match error {
284 pkcs1::Error::Asn1(error) => pkcs8::Error::Asn1(error),
285 _ => pkcs8::Error::KeyMalformed(pkcs8::KeyError::Invalid),
286 }
287}
288
289fn public_error(error: pkcs1::Error) -> pkcs8::spki::Error {
290 match error {
291 pkcs1::Error::Asn1(error) => pkcs8::spki::Error::Asn1(error),
292 _ => pkcs8::spki::Error::KeyMalformed,
293 }
294}