1 use crate::{oids, AlgorithmIdentifier};
2 use picky_asn1::wrapper::{IntegerAsn1, OctetStringAsn1Container};
3 #[cfg(not(feature = "legacy"))]
4 use serde::Deserialize;
5 use serde::{de, ser, Serialize};
6 use std::fmt;
7 
8 /// [Public-Key Cryptography Standards (PKCS) #8](https://tools.ietf.org/html/rfc5208#section-5)
9 ///
10 /// # Section 5
11 ///
12 /// Private-key information shall have ASN.1 type PrivateKeyInfo:
13 ///
14 /// ```not_rust
15 /// PrivateKeyInfo ::= SEQUENCE {
16 ///      version                   Version,
17 ///      privateKeyAlgorithm       PrivateKeyAlgorithmIdentifier,
18 ///      privateKey                PrivateKey,
19 ///      attributes           [0]  IMPLICIT Attributes OPTIONAL }
20 ///
21 ///   Version ::= INTEGER
22 ///
23 ///   PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier
24 ///
25 ///   PrivateKey ::= OCTET STRING
26 ///
27 ///   Attributes ::= SET OF Attribute
28 /// ```
29 ///
30 /// The fields of type PrivateKeyInfo have the following meanings:
31 ///
32 /// `version` is the syntax version number, for compatibility with
33 /// future revisions of this document.  It shall be 0 for this version
34 /// of the document.
35 ///
36 /// `privateKeyAlgorithm` identifies the private-key algorithm.  One
37 /// example of a private-key algorithm is PKCS #1's rsaEncryption.
38 ///
39 /// `privateKey` is an octet string whose contents are the value of the
40 /// private key.  The interpretation of the contents is defined in the
41 /// registration of the private-key algorithm.  For an RSA private
42 /// key, for example, the contents are a BER encoding of a value of
43 /// type RSAPrivateKey.
44 ///
45 /// `attributes` is a set of attributes.  These are the extended
46 /// information that is encrypted along with the private-key
47 /// information.
48 #[derive(Serialize, Debug, Clone, PartialEq)]
49 pub struct PrivateKeyInfo {
50     pub version: u8,
51     pub private_key_algorithm: AlgorithmIdentifier,
52     pub private_key: PrivateKeyValue,
53     //pub attributes
54 }
55 
56 impl PrivateKeyInfo {
new_rsa_encryption( modulus: IntegerAsn1, public_exponent: IntegerAsn1, private_exponent: IntegerAsn1, primes: (IntegerAsn1, IntegerAsn1), exponents: (IntegerAsn1, IntegerAsn1), coefficient: IntegerAsn1, ) -> Self57     pub fn new_rsa_encryption(
58         modulus: IntegerAsn1,
59         public_exponent: IntegerAsn1,
60         private_exponent: IntegerAsn1,
61         primes: (IntegerAsn1, IntegerAsn1),
62         exponents: (IntegerAsn1, IntegerAsn1),
63         coefficient: IntegerAsn1,
64     ) -> Self {
65         let private_key = PrivateKeyValue::RSA(
66             RSAPrivateKey {
67                 version: vec![0].into(),
68                 modulus,
69                 public_exponent,
70                 private_exponent,
71                 prime_1: primes.0,
72                 prime_2: primes.1,
73                 exponent_1: exponents.0,
74                 exponent_2: exponents.1,
75                 coefficient,
76             }
77             .into(),
78         );
79 
80         Self {
81             version: 0,
82             private_key_algorithm: AlgorithmIdentifier::new_rsa_encryption(),
83             private_key,
84         }
85     }
86 }
87 
88 impl<'de> de::Deserialize<'de> for PrivateKeyInfo {
deserialize<D>(deserializer: D) -> Result<Self, <D as de::Deserializer<'de>>::Error> where D: de::Deserializer<'de>,89     fn deserialize<D>(deserializer: D) -> Result<Self, <D as de::Deserializer<'de>>::Error>
90     where
91         D: de::Deserializer<'de>,
92     {
93         struct Visitor;
94 
95         impl<'de> de::Visitor<'de> for Visitor {
96             type Value = PrivateKeyInfo;
97 
98             fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
99                 formatter.write_str("a valid DER-encoded PrivateKeyInfo (pkcs8)")
100             }
101 
102             fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
103             where
104                 A: de::SeqAccess<'de>,
105             {
106                 let version = seq_next_element!(seq, PrivateKeyInfo, "version");
107                 if version != 0 {
108                     return Err(serde_invalid_value!(
109                         PrivateKeyInfo,
110                         "unsupported version (valid version number: 0)",
111                         "a supported PrivateKeyInfo"
112                     ));
113                 }
114 
115                 let private_key_algorithm: AlgorithmIdentifier =
116                     seq_next_element!(seq, PrivateKeyInfo, "private key algorithm");
117                 let private_key = if private_key_algorithm.is_a(oids::rsa_encryption()) {
118                     PrivateKeyValue::RSA(seq_next_element!(seq, PrivateKeyInfo, "rsa oid"))
119                 } else {
120                     return Err(serde_invalid_value!(
121                         PrivateKeyInfo,
122                         "unsupported algorithm",
123                         "a supported algorithm"
124                     ));
125                 };
126 
127                 Ok(PrivateKeyInfo {
128                     version,
129                     private_key_algorithm,
130                     private_key,
131                 })
132             }
133         }
134 
135         deserializer.deserialize_seq(Visitor)
136     }
137 }
138 
139 #[derive(Debug, PartialEq, Clone)]
140 pub enum PrivateKeyValue {
141     RSA(OctetStringAsn1Container<RSAPrivateKey>),
142 }
143 
144 impl ser::Serialize for PrivateKeyValue {
serialize<S>(&self, serializer: S) -> Result<<S as ser::Serializer>::Ok, <S as ser::Serializer>::Error> where S: ser::Serializer,145     fn serialize<S>(&self, serializer: S) -> Result<<S as ser::Serializer>::Ok, <S as ser::Serializer>::Error>
146     where
147         S: ser::Serializer,
148     {
149         match self {
150             PrivateKeyValue::RSA(rsa) => rsa.serialize(serializer),
151         }
152     }
153 }
154 
155 /// [PKCS #1: RSA Cryptography Specifications Version 2.2](https://tools.ietf.org/html/rfc8017.html#appendix-A.1.2)
156 ///
157 /// # Section A.1.2
158 ///
159 /// An RSA private key should be represented with the ASN.1 type RSAPrivateKey:
160 ///
161 /// ```not_rust
162 ///      RSAPrivateKey ::= SEQUENCE {
163 ///          version           Version,
164 ///          modulus           INTEGER,  -- n
165 ///          publicExponent    INTEGER,  -- e
166 ///          privateExponent   INTEGER,  -- d
167 ///          prime1            INTEGER,  -- p
168 ///          prime2            INTEGER,  -- q
169 ///          exponent1         INTEGER,  -- d mod (p-1)
170 ///          exponent2         INTEGER,  -- d mod (q-1)
171 ///          coefficient       INTEGER,  -- (inverse of q) mod p
172 ///          otherPrimeInfos   OtherPrimeInfos OPTIONAL
173 ///      }
174 /// ```
175 #[derive(Serialize, Debug, Clone, PartialEq)]
176 #[cfg_attr(not(feature = "legacy"), derive(Deserialize))]
177 pub struct RSAPrivateKey {
178     pub version: IntegerAsn1,
179     pub modulus: IntegerAsn1,
180     pub public_exponent: IntegerAsn1,
181     pub private_exponent: IntegerAsn1,
182     pub prime_1: IntegerAsn1,
183     pub prime_2: IntegerAsn1,
184     pub exponent_1: IntegerAsn1,
185     pub exponent_2: IntegerAsn1,
186     pub coefficient: IntegerAsn1,
187 }
188 
189 #[cfg(feature = "legacy")]
190 impl<'de> de::Deserialize<'de> for RSAPrivateKey {
deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: de::Deserializer<'de>,191     fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
192     where
193         D: de::Deserializer<'de>,
194     {
195         struct Visitor;
196 
197         impl<'de> de::Visitor<'de> for Visitor {
198             type Value = RSAPrivateKey;
199 
200             fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
201                 formatter.write_str("struct RSAPrivateKey with 6 or 9 elements")
202             }
203 
204             fn visit_seq<V>(self, mut seq: V) -> Result<Self::Value, V::Error>
205             where
206                 V: de::SeqAccess<'de>,
207             {
208                 let version: IntegerAsn1 = seq.next_element()?.ok_or_else(|| de::Error::invalid_length(0, &self))?;
209                 let modulus: IntegerAsn1 = seq.next_element()?.ok_or_else(|| de::Error::invalid_length(1, &self))?;
210                 let public_exponent: IntegerAsn1 =
211                     seq.next_element()?.ok_or_else(|| de::Error::invalid_length(2, &self))?;
212                 let private_exponent: IntegerAsn1 =
213                     seq.next_element()?.ok_or_else(|| de::Error::invalid_length(3, &self))?;
214                 let prime_1: IntegerAsn1 = seq.next_element()?.ok_or_else(|| de::Error::invalid_length(4, &self))?;
215                 let prime_2: IntegerAsn1 = seq.next_element()?.ok_or_else(|| de::Error::invalid_length(5, &self))?;
216 
217                 let (exponent_1, exponent_2, coefficient) = if let Some(exponent_1) = seq.next_element()? {
218                     let exponent_2 = seq.next_element()?.ok_or_else(|| de::Error::invalid_length(7, &self))?;
219                     let coefficient = seq.next_element()?.ok_or_else(|| de::Error::invalid_length(8, &self))?;
220                     (exponent_1, exponent_2, coefficient)
221                 } else {
222                     use num_bigint_dig::{BigUint, ModInverse};
223 
224                     // conversion to num_bigint_dig format BigUint
225                     let private_exponent = BigUint::from_bytes_be(private_exponent.as_unsigned_bytes_be());
226                     let prime_1 = BigUint::from_bytes_be(prime_1.as_unsigned_bytes_be());
227                     let prime_2 = BigUint::from_bytes_be(prime_2.as_unsigned_bytes_be());
228 
229                     let exponent_1 = &private_exponent % (&prime_1 - 1u8);
230                     let exponent_2 = &private_exponent % (&prime_2 - 1u8);
231 
232                     let coefficient = prime_2
233                         .mod_inverse(prime_1)
234                         .ok_or_else(|| {
235                             de::Error::invalid_value(
236                                 de::Unexpected::Other("[RSAPrivateKey] no modular inverse for prime 1"),
237                                 &"an invertible prime 1 value",
238                             )
239                         })?
240                         .to_biguint()
241                         .ok_or_else(|| {
242                             de::Error::invalid_value(
243                                 de::Unexpected::Other("[RSAPrivateKey] BigUint conversion failed"),
244                                 &"a valid prime 1 value",
245                             )
246                         })?;
247 
248                     // conversion to IntegerAsn1
249                     let exponent_1 = IntegerAsn1::from_bytes_be_unsigned(exponent_1.to_bytes_be());
250                     let exponent_2 = IntegerAsn1::from_bytes_be_unsigned(exponent_2.to_bytes_be());
251                     let coefficient = IntegerAsn1::from_bytes_be_unsigned(coefficient.to_bytes_be());
252 
253                     (exponent_1, exponent_2, coefficient)
254                 };
255 
256                 Ok(RSAPrivateKey {
257                     version,
258                     modulus,
259                     public_exponent,
260                     private_exponent,
261                     prime_1,
262                     prime_2,
263                     exponent_1,
264                     exponent_2,
265                     coefficient,
266                 })
267             }
268         }
269 
270         deserializer.deserialize_seq(Visitor)
271     }
272 }
273 
274 impl RSAPrivateKey {
275     #[deprecated(note = "field is now public")]
modulus(&self) -> &IntegerAsn1276     pub fn modulus(&self) -> &IntegerAsn1 {
277         &self.modulus
278     }
279 
280     #[deprecated(note = "field is now public")]
public_exponent(&self) -> &IntegerAsn1281     pub fn public_exponent(&self) -> &IntegerAsn1 {
282         &self.public_exponent
283     }
284 
285     #[deprecated(note = "field is now public")]
private_exponent(&self) -> &IntegerAsn1286     pub fn private_exponent(&self) -> &IntegerAsn1 {
287         &self.private_exponent
288     }
289 
290     #[deprecated(note = "field is now public")]
prime_1(&self) -> &IntegerAsn1291     pub fn prime_1(&self) -> &IntegerAsn1 {
292         &self.prime_1
293     }
294 
295     #[deprecated(note = "field is now public")]
prime_2(&self) -> &IntegerAsn1296     pub fn prime_2(&self) -> &IntegerAsn1 {
297         &self.prime_2
298     }
299 
300     #[deprecated(note = "field is now public")]
primes(&self) -> (&IntegerAsn1, &IntegerAsn1)301     pub fn primes(&self) -> (&IntegerAsn1, &IntegerAsn1) {
302         (&self.prime_1, &self.prime_2)
303     }
304 
305     #[deprecated(note = "field is now public")]
exponent_1(&self) -> &IntegerAsn1306     pub fn exponent_1(&self) -> &IntegerAsn1 {
307         &self.exponent_1
308     }
309 
310     #[deprecated(note = "field is now public")]
exponent_2(&self) -> &IntegerAsn1311     pub fn exponent_2(&self) -> &IntegerAsn1 {
312         &self.exponent_2
313     }
314 
315     #[deprecated(note = "field is now public")]
exponents(&self) -> (&IntegerAsn1, &IntegerAsn1)316     pub fn exponents(&self) -> (&IntegerAsn1, &IntegerAsn1) {
317         (&self.exponent_1, &self.exponent_2)
318     }
319 
320     #[deprecated(note = "field is now public")]
coefficient(&self) -> &IntegerAsn1321     pub fn coefficient(&self) -> &IntegerAsn1 {
322         &self.coefficient
323     }
324 
325     #[deprecated(note = "field is now public")]
into_public_components(self) -> (IntegerAsn1, IntegerAsn1)326     pub fn into_public_components(self) -> (IntegerAsn1, IntegerAsn1) {
327         (self.modulus, self.public_exponent)
328     }
329 }
330 
331 #[cfg(test)]
332 mod tests {
333     use super::*;
334 
335     #[test]
pkcs_8_private_key()336     fn pkcs_8_private_key() {
337         let encoded = base64::decode(
338             "MIIBVgIBADANBgkqhkiG9w0BAQEFAASCAUAwggE8AgEAAkEAq7BFUpkGp3+LQmlQ\
339              Yx2eqzDV+xeG8kx/sQFV18S5JhzGeIJNA72wSeukEPojtqUyX2J0CciPBh7eqclQ\
340              2zpAswIDAQABAkAgisq4+zRdrzkwH1ITV1vpytnkO/NiHcnePQiOW0VUybPyHoGM\
341              /jf75C5xET7ZQpBe5kx5VHsPZj0CBb3b+wSRAiEA2mPWCBytosIU/ODRfq6EiV04\
342              lt6waE7I2uSPqIC20LcCIQDJQYIHQII+3YaPqyhGgqMexuuuGx+lDKD6/Fu/JwPb\
343              5QIhAKthiYcYKlL9h8bjDsQhZDUACPasjzdsDEdq8inDyLOFAiEAmCr/tZwA3qeA\
344              ZoBzI10DGPIuoKXBd3nk/eBxPkaxlEECIQCNymjsoI7GldtujVnr1qT+3yedLfHK\
345              srDVjIT3LsvTqw==",
346         )
347         .expect("invalid base64");
348 
349         let modulus = IntegerAsn1::from(encoded[35..100].to_vec());
350         let public_exponent = IntegerAsn1::from(encoded[102..105].to_vec());
351         let private_exponent = IntegerAsn1::from(encoded[107..171].to_vec());
352         let prime_1 = IntegerAsn1::from(encoded[173..206].to_vec());
353         let prime_2 = IntegerAsn1::from(encoded[208..241].to_vec());
354         let exponent_1 = IntegerAsn1::from(encoded[243..276].to_vec());
355         let exponent_2 = IntegerAsn1::from(encoded[278..311].to_vec());
356         let coefficient = IntegerAsn1::from(encoded[313..346].to_vec());
357 
358         let private_key = PrivateKeyInfo::new_rsa_encryption(
359             modulus,
360             public_exponent,
361             private_exponent,
362             (prime_1, prime_2),
363             (exponent_1, exponent_2),
364             coefficient,
365         );
366         check_serde!(private_key: PrivateKeyInfo in encoded);
367     }
368 
369     #[test]
370     #[cfg(feature = "legacy")]
old_broken_key_legacy_support()371     fn old_broken_key_legacy_support() {
372         // Version previous to picky-asn1-x509 6.0.0 could generate weird keys with negative values
373         // https://github.com/Devolutions/picky-rs/issues/53
374         // We want to support these for now.
375 
376         let encoded = base64::decode(
377             "MIIDMAIBADANBgkqhkiG9w0BAQEFAASCAxowggMWAgEAAoIBAOB9jOJvCkMHOc98Q\
378              GPFikxAvBKANkme5f/nNuNnEnbefoKDFkS6ElfqASAAkIHxUREnRvBTTa6b+qba/0\
379              DhBuXsYGCl8VF0pUE4JGujv1HIi5aRCar0WmY66s7DJ4uR3Nk9Jy0WeRiH4yyzEIG\
380              8+6QDu4d/U6slWTmE8eZtQEE7rz4FGpQU9OhrGM3xJOIIbLX/xU2SFt83Xs3JREEt\
381              bfrXQpSxAHmtwvlBKpeZacrcobm6eQKsoI2MIg3LFvoHs0+40dadm14ngpgwx4qqk\
382              bG34jvWH13OhHRweFGNkQpcg99rlzZYkCM13e9EcmirQ9XYHuB5pHS31eznolZKbx\
383              cCAwEAAQKCAQCrPFlopxaGxk48jCR5dkbln0NWQWInigMazf06PHcDIPgTCXbE+cH\
384              gOWieRo/z7mTN1s3vpztMA0KQX9/wVzVx0Ho7fpiyb21WcEKnsIHRGk4PjZZ4Rmdm\
385              L27IRGg3uA1jz5fAdrHsGksY34Wp0MOJ+ibjViY2GAkVLOlvwMoQds6eNIGO88T5O\
386              fcmvutjK43ObU1vgx2ptTaLNAVczEE5VHqcLx4GZPv6k71afOQfIDQerIpsGb4gvr\
387              1JdwYKb4z02z2SaNIA3Vly0q5s4r8uU36eg9z65utu93M7zI7f8/MX2byZ2Jz4b3T\
388              nH10FURmbPoNQH/O2T0TbtT4M1y0xAoGA72JW0IcFxze7j7PPaP6cQN1IXvFDZUFF\
389              dZHqFI8+4VPcv3EKTs+iQflM7pqtRuEWtwonIn3f7CGOx317uKwpVsZvfnDhXCUPJ\
390              Q3pns7KgaROGXyruFFQ9gl6XsXGK02Wop9nX0/iRK3ruwZ4uJwDioEYcvGw+ocqAc\
391              yOdodNnpUCgYDwEo/sPJNaPOzc7fpaQr2PUUJ3ksL0ncGRO2h1JGYgDtWe5u1srSI\
392              DlpM2NdYSZyT04ebOF2SqNUBwY3LB1tPOFnjYwCutp4c75OYhOor7TodZHlzt3GeQ\
393              ntUw6XbHX0ohTgs4u2NXwOTq5yKeW4VYzuevN5ksF8GoW2noalpn+w==",
394         )
395         .unwrap();
396 
397         picky_asn1_der::from_bytes::<PrivateKeyInfo>(&encoded).unwrap();
398     }
399 }
400