1use crate::{
7 traits::{PrivateKeyParts, PublicKeyParts},
8 BigUint, RsaPrivateKey, RsaPublicKey,
9};
10use core::convert::{TryFrom, TryInto};
11use pkcs8::{der::Encode, Document, EncodePrivateKey, EncodePublicKey, SecretDocument};
12use zeroize::Zeroizing;
13
14fn verify_algorithm_id(algorithm: &pkcs8::AlgorithmIdentifierRef) -> pkcs8::spki::Result<()> {
16 algorithm.assert_algorithm_oid(pkcs1::ALGORITHM_OID)?;
17
18 if algorithm.parameters_any()? != pkcs8::der::asn1::Null.into() {
19 return Err(pkcs8::spki::Error::KeyMalformed);
20 }
21
22 Ok(())
23}
24
25impl TryFrom<pkcs8::PrivateKeyInfo<'_>> for RsaPrivateKey {
26 type Error = pkcs8::Error;
27
28 fn try_from(private_key_info: pkcs8::PrivateKeyInfo<'_>) -> pkcs8::Result<Self> {
29 verify_algorithm_id(&private_key_info.algorithm)?;
30
31 let pkcs1_key = pkcs1::RsaPrivateKey::try_from(private_key_info.private_key)?;
32
33 if pkcs1_key.version() != pkcs1::Version::TwoPrime {
35 return Err(pkcs1::Error::Version.into());
36 }
37
38 let n = BigUint::from_bytes_be(pkcs1_key.modulus.as_bytes());
39 let e = BigUint::from_bytes_be(pkcs1_key.public_exponent.as_bytes());
40 let d = BigUint::from_bytes_be(pkcs1_key.private_exponent.as_bytes());
41 let prime1 = BigUint::from_bytes_be(pkcs1_key.prime1.as_bytes());
42 let prime2 = BigUint::from_bytes_be(pkcs1_key.prime2.as_bytes());
43 let primes = vec![prime1, prime2];
44 RsaPrivateKey::from_components(n, e, d, primes).map_err(|_| pkcs8::Error::KeyMalformed)
45 }
46}
47
48impl TryFrom<pkcs8::SubjectPublicKeyInfoRef<'_>> for RsaPublicKey {
49 type Error = pkcs8::spki::Error;
50
51 fn try_from(spki: pkcs8::SubjectPublicKeyInfoRef<'_>) -> pkcs8::spki::Result<Self> {
52 verify_algorithm_id(&spki.algorithm)?;
53
54 let pkcs1_key = pkcs1::RsaPublicKey::try_from(
55 spki.subject_public_key
56 .as_bytes()
57 .ok_or(pkcs8::spki::Error::KeyMalformed)?,
58 )?;
59 let n = BigUint::from_bytes_be(pkcs1_key.modulus.as_bytes());
60 let e = BigUint::from_bytes_be(pkcs1_key.public_exponent.as_bytes());
61 RsaPublicKey::new(n, e).map_err(|_| pkcs8::spki::Error::KeyMalformed)
62 }
63}
64
65impl EncodePrivateKey for RsaPrivateKey {
66 fn to_pkcs8_der(&self) -> pkcs8::Result<SecretDocument> {
67 if self.primes.len() > 2 {
69 return Err(pkcs1::Error::Version.into());
70 }
71
72 let modulus = self.n().to_bytes_be();
73 let public_exponent = self.e().to_bytes_be();
74 let private_exponent = Zeroizing::new(self.d().to_bytes_be());
75 let prime1 = Zeroizing::new(self.primes[0].to_bytes_be());
76 let prime2 = Zeroizing::new(self.primes[1].to_bytes_be());
77 let exponent1 = Zeroizing::new((self.d() % (&self.primes[0] - 1u8)).to_bytes_be());
78 let exponent2 = Zeroizing::new((self.d() % (&self.primes[1] - 1u8)).to_bytes_be());
79 let coefficient = Zeroizing::new(
80 self.crt_coefficient()
81 .ok_or(pkcs1::Error::Crypto)?
82 .to_bytes_be(),
83 );
84
85 let private_key = pkcs1::RsaPrivateKey {
86 modulus: pkcs1::UintRef::new(&modulus)?,
87 public_exponent: pkcs1::UintRef::new(&public_exponent)?,
88 private_exponent: pkcs1::UintRef::new(&private_exponent)?,
89 prime1: pkcs1::UintRef::new(&prime1)?,
90 prime2: pkcs1::UintRef::new(&prime2)?,
91 exponent1: pkcs1::UintRef::new(&exponent1)?,
92 exponent2: pkcs1::UintRef::new(&exponent2)?,
93 coefficient: pkcs1::UintRef::new(&coefficient)?,
94 other_prime_infos: None,
95 }
96 .to_der()?;
97
98 pkcs8::PrivateKeyInfo::new(pkcs1::ALGORITHM_ID, private_key.as_ref()).try_into()
99 }
100}
101
102impl EncodePublicKey for RsaPublicKey {
103 fn to_public_key_der(&self) -> pkcs8::spki::Result<Document> {
104 let modulus = self.n().to_bytes_be();
105 let public_exponent = self.e().to_bytes_be();
106
107 let subject_public_key = pkcs1::RsaPublicKey {
108 modulus: pkcs1::UintRef::new(&modulus)?,
109 public_exponent: pkcs1::UintRef::new(&public_exponent)?,
110 }
111 .to_der()?;
112
113 pkcs8::SubjectPublicKeyInfoRef {
114 algorithm: pkcs1::ALGORITHM_ID,
115 subject_public_key: pkcs8::der::asn1::BitStringRef::new(
116 0,
117 subject_public_key.as_ref(),
118 )?,
119 }
120 .try_into()
121 }
122}