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