1use crate::{key::PublicKeyParts, BigUint, RsaPrivateKey, RsaPublicKey};
7use core::convert::{TryFrom, TryInto};
8use pkcs1::der::Encode;
9use pkcs8::{
10 DecodePrivateKey, DecodePublicKey, Document, EncodePrivateKey, EncodePublicKey, SecretDocument,
11};
12use zeroize::Zeroizing;
13
14fn verify_algorithm_id(algorithm: &pkcs8::AlgorithmIdentifier) -> 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 DecodePrivateKey for RsaPrivateKey {}
49
50impl TryFrom<pkcs8::SubjectPublicKeyInfo<'_>> for RsaPublicKey {
51 type Error = pkcs8::spki::Error;
52
53 fn try_from(spki: pkcs8::SubjectPublicKeyInfo<'_>) -> pkcs8::spki::Result<Self> {
54 verify_algorithm_id(&spki.algorithm)?;
55
56 let pkcs1_key = pkcs1::RsaPublicKey::try_from(spki.subject_public_key)?;
57 let n = BigUint::from_bytes_be(pkcs1_key.modulus.as_bytes());
58 let e = BigUint::from_bytes_be(pkcs1_key.public_exponent.as_bytes());
59 RsaPublicKey::new(n, e).map_err(|_| pkcs8::spki::Error::KeyMalformed)
60 }
61}
62
63impl DecodePublicKey for RsaPublicKey {}
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_vec()?;
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_vec()?;
112
113 pkcs8::SubjectPublicKeyInfo {
114 algorithm: pkcs1::ALGORITHM_ID,
115 subject_public_key: subject_public_key.as_ref(),
116 }
117 .try_into()
118 }
119}