1 //! PKCS#1 RSA Private Keys.
2 
3 #[cfg(feature = "alloc")]
4 pub(crate) mod other_prime_info;
5 
6 use crate::{Error, Result, RsaPublicKey, Version};
7 use core::fmt;
8 use der::{
9     asn1::UintRef, Decode, DecodeValue, Encode, EncodeValue, Header, Length, Reader, Sequence, Tag,
10     Writer,
11 };
12 
13 #[cfg(feature = "alloc")]
14 use {self::other_prime_info::OtherPrimeInfo, alloc::vec::Vec, der::SecretDocument};
15 
16 #[cfg(feature = "pem")]
17 use der::pem::PemLabel;
18 
19 /// PKCS#1 RSA Private Keys as defined in [RFC 8017 Appendix 1.2].
20 ///
21 /// ASN.1 structure containing a serialized RSA private key:
22 ///
23 /// ```text
24 /// RSAPrivateKey ::= SEQUENCE {
25 ///     version           Version,
26 ///     modulus           INTEGER,  -- n
27 ///     publicExponent    INTEGER,  -- e
28 ///     privateExponent   INTEGER,  -- d
29 ///     prime1            INTEGER,  -- p
30 ///     prime2            INTEGER,  -- q
31 ///     exponent1         INTEGER,  -- d mod (p-1)
32 ///     exponent2         INTEGER,  -- d mod (q-1)
33 ///     coefficient       INTEGER,  -- (inverse of q) mod p
34 ///     otherPrimeInfos   OtherPrimeInfos OPTIONAL
35 /// }
36 /// ```
37 ///
38 /// Note: the `version` field is selected automatically based on the absence or
39 /// presence of the `other_prime_infos` field.
40 ///
41 /// [RFC 8017 Appendix 1.2]: https://datatracker.ietf.org/doc/html/rfc8017#appendix-A.1.2
42 #[derive(Clone)]
43 pub struct RsaPrivateKey<'a> {
44     /// `n`: RSA modulus.
45     pub modulus: UintRef<'a>,
46 
47     /// `e`: RSA public exponent.
48     pub public_exponent: UintRef<'a>,
49 
50     /// `d`: RSA private exponent.
51     pub private_exponent: UintRef<'a>,
52 
53     /// `p`: first prime factor of `n`.
54     pub prime1: UintRef<'a>,
55 
56     /// `q`: Second prime factor of `n`.
57     pub prime2: UintRef<'a>,
58 
59     /// First exponent: `d mod (p-1)`.
60     pub exponent1: UintRef<'a>,
61 
62     /// Second exponent: `d mod (q-1)`.
63     pub exponent2: UintRef<'a>,
64 
65     /// CRT coefficient: `(inverse of q) mod p`.
66     pub coefficient: UintRef<'a>,
67 
68     /// Additional primes `r_3`, ..., `r_u`, in order, if this is a multi-prime
69     /// RSA key (i.e. `version` is `multi`).
70     pub other_prime_infos: Option<OtherPrimeInfos<'a>>,
71 }
72 
73 impl<'a> RsaPrivateKey<'a> {
74     /// Get the public key that corresponds to this [`RsaPrivateKey`].
public_key(&self) -> RsaPublicKey<'a>75     pub fn public_key(&self) -> RsaPublicKey<'a> {
76         RsaPublicKey {
77             modulus: self.modulus,
78             public_exponent: self.public_exponent,
79         }
80     }
81 
82     /// Get the [`Version`] for this key.
83     ///
84     /// Determined by the presence or absence of the
85     /// [`RsaPrivateKey::other_prime_infos`] field.
version(&self) -> Version86     pub fn version(&self) -> Version {
87         if self.other_prime_infos.is_some() {
88             Version::Multi
89         } else {
90             Version::TwoPrime
91         }
92     }
93 }
94 
95 impl<'a> DecodeValue<'a> for RsaPrivateKey<'a> {
decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> der::Result<Self>96     fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> der::Result<Self> {
97         reader.read_nested(header.length, |reader| {
98             let version = Version::decode(reader)?;
99 
100             let result = Self {
101                 modulus: reader.decode()?,
102                 public_exponent: reader.decode()?,
103                 private_exponent: reader.decode()?,
104                 prime1: reader.decode()?,
105                 prime2: reader.decode()?,
106                 exponent1: reader.decode()?,
107                 exponent2: reader.decode()?,
108                 coefficient: reader.decode()?,
109                 other_prime_infos: reader.decode()?,
110             };
111 
112             // Ensure version is set correctly for two-prime vs multi-prime key.
113             if version.is_multi() != result.other_prime_infos.is_some() {
114                 return Err(reader.error(der::ErrorKind::Value { tag: Tag::Integer }));
115             }
116 
117             Ok(result)
118         })
119     }
120 }
121 
122 impl EncodeValue for RsaPrivateKey<'_> {
value_len(&self) -> der::Result<Length>123     fn value_len(&self) -> der::Result<Length> {
124         self.version().encoded_len()?
125             + self.modulus.encoded_len()?
126             + self.public_exponent.encoded_len()?
127             + self.private_exponent.encoded_len()?
128             + self.prime1.encoded_len()?
129             + self.prime2.encoded_len()?
130             + self.exponent1.encoded_len()?
131             + self.exponent2.encoded_len()?
132             + self.coefficient.encoded_len()?
133             + self.other_prime_infos.encoded_len()?
134     }
135 
encode_value(&self, writer: &mut impl Writer) -> der::Result<()>136     fn encode_value(&self, writer: &mut impl Writer) -> der::Result<()> {
137         self.version().encode(writer)?;
138         self.modulus.encode(writer)?;
139         self.public_exponent.encode(writer)?;
140         self.private_exponent.encode(writer)?;
141         self.prime1.encode(writer)?;
142         self.prime2.encode(writer)?;
143         self.exponent1.encode(writer)?;
144         self.exponent2.encode(writer)?;
145         self.coefficient.encode(writer)?;
146         self.other_prime_infos.encode(writer)?;
147         Ok(())
148     }
149 }
150 
151 impl<'a> Sequence<'a> for RsaPrivateKey<'a> {}
152 
153 impl<'a> From<RsaPrivateKey<'a>> for RsaPublicKey<'a> {
from(private_key: RsaPrivateKey<'a>) -> RsaPublicKey<'a>154     fn from(private_key: RsaPrivateKey<'a>) -> RsaPublicKey<'a> {
155         private_key.public_key()
156     }
157 }
158 
159 impl<'a> From<&RsaPrivateKey<'a>> for RsaPublicKey<'a> {
from(private_key: &RsaPrivateKey<'a>) -> RsaPublicKey<'a>160     fn from(private_key: &RsaPrivateKey<'a>) -> RsaPublicKey<'a> {
161         private_key.public_key()
162     }
163 }
164 
165 impl<'a> TryFrom<&'a [u8]> for RsaPrivateKey<'a> {
166     type Error = Error;
167 
try_from(bytes: &'a [u8]) -> Result<Self>168     fn try_from(bytes: &'a [u8]) -> Result<Self> {
169         Ok(Self::from_der(bytes)?)
170     }
171 }
172 
173 impl fmt::Debug for RsaPrivateKey<'_> {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result174     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
175         f.debug_struct("RsaPrivateKey")
176             .field("version", &self.version())
177             .field("modulus", &self.modulus)
178             .field("public_exponent", &self.public_exponent)
179             .finish_non_exhaustive()
180     }
181 }
182 
183 #[cfg(feature = "alloc")]
184 impl TryFrom<RsaPrivateKey<'_>> for SecretDocument {
185     type Error = Error;
186 
try_from(private_key: RsaPrivateKey<'_>) -> Result<SecretDocument>187     fn try_from(private_key: RsaPrivateKey<'_>) -> Result<SecretDocument> {
188         SecretDocument::try_from(&private_key)
189     }
190 }
191 
192 #[cfg(feature = "alloc")]
193 impl TryFrom<&RsaPrivateKey<'_>> for SecretDocument {
194     type Error = Error;
195 
try_from(private_key: &RsaPrivateKey<'_>) -> Result<SecretDocument>196     fn try_from(private_key: &RsaPrivateKey<'_>) -> Result<SecretDocument> {
197         Ok(Self::encode_msg(private_key)?)
198     }
199 }
200 
201 #[cfg(feature = "pem")]
202 impl PemLabel for RsaPrivateKey<'_> {
203     const PEM_LABEL: &'static str = "RSA PRIVATE KEY";
204 }
205 
206 /// Placeholder struct for `OtherPrimeInfos` in the no-`alloc` case.
207 ///
208 /// This type is unconstructable by design, but supports the same traits.
209 #[cfg(not(feature = "alloc"))]
210 #[derive(Clone)]
211 #[non_exhaustive]
212 pub struct OtherPrimeInfos<'a> {
213     _lifetime: core::marker::PhantomData<&'a ()>,
214 }
215 
216 #[cfg(not(feature = "alloc"))]
217 impl<'a> DecodeValue<'a> for OtherPrimeInfos<'a> {
decode_value<R: Reader<'a>>(reader: &mut R, _header: Header) -> der::Result<Self>218     fn decode_value<R: Reader<'a>>(reader: &mut R, _header: Header) -> der::Result<Self> {
219         // Placeholder decoder that always returns an error.
220         // Uses `Tag::Integer` to signal an unsupported version.
221         Err(reader.error(der::ErrorKind::Value { tag: Tag::Integer }))
222     }
223 }
224 
225 #[cfg(not(feature = "alloc"))]
226 impl EncodeValue for OtherPrimeInfos<'_> {
value_len(&self) -> der::Result<Length>227     fn value_len(&self) -> der::Result<Length> {
228         // Placeholder decoder that always returns an error.
229         // Uses `Tag::Integer` to signal an unsupported version.
230         Err(der::ErrorKind::Value { tag: Tag::Integer }.into())
231     }
232 
encode_value(&self, _writer: &mut impl Writer) -> der::Result<()>233     fn encode_value(&self, _writer: &mut impl Writer) -> der::Result<()> {
234         // Placeholder decoder that always returns an error.
235         // Uses `Tag::Integer` to signal an unsupported version.
236         Err(der::ErrorKind::Value { tag: Tag::Integer }.into())
237     }
238 }
239 
240 #[cfg(not(feature = "alloc"))]
241 impl<'a> der::FixedTag for OtherPrimeInfos<'a> {
242     const TAG: Tag = Tag::Sequence;
243 }
244 
245 /// Additional RSA prime info in a multi-prime RSA key.
246 #[cfg(feature = "alloc")]
247 pub type OtherPrimeInfos<'a> = Vec<OtherPrimeInfo<'a>>;
248