1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
use crate::{key::PublicKeyParts, BigUint, RsaPrivateKey, RsaPublicKey};
use num_bigint::ModInverse;
use pkcs1::{
FromRsaPrivateKey, FromRsaPublicKey, RsaPrivateKeyDocument, RsaPublicKeyDocument,
ToRsaPrivateKey, ToRsaPublicKey,
};
use zeroize::Zeroizing;
impl FromRsaPrivateKey for RsaPrivateKey {
fn from_pkcs1_private_key(pkcs1_key: pkcs1::RsaPrivateKey<'_>) -> pkcs1::Result<Self> {
let n = BigUint::from_bytes_be(pkcs1_key.modulus.as_bytes());
let e = BigUint::from_bytes_be(pkcs1_key.public_exponent.as_bytes());
let d = BigUint::from_bytes_be(pkcs1_key.private_exponent.as_bytes());
let prime1 = BigUint::from_bytes_be(pkcs1_key.prime1.as_bytes());
let prime2 = BigUint::from_bytes_be(pkcs1_key.prime2.as_bytes());
let primes = vec![prime1, prime2];
Ok(RsaPrivateKey::from_components(n, e, d, primes))
}
}
impl FromRsaPublicKey for RsaPublicKey {
fn from_pkcs1_public_key(pkcs1_key: pkcs1::RsaPublicKey<'_>) -> pkcs1::Result<Self> {
let n = BigUint::from_bytes_be(pkcs1_key.modulus.as_bytes());
let e = BigUint::from_bytes_be(pkcs1_key.public_exponent.as_bytes());
RsaPublicKey::new(n, e).map_err(|_| pkcs1::Error::Crypto)
}
}
impl ToRsaPrivateKey for RsaPrivateKey {
fn to_pkcs1_der(&self) -> pkcs1::Result<RsaPrivateKeyDocument> {
if self.primes.len() > 2 {
return Err(pkcs1::Error::Version);
}
let modulus = self.n().to_bytes_be();
let public_exponent = self.e().to_bytes_be();
let private_exponent = Zeroizing::new(self.d().to_bytes_be());
let prime1 = Zeroizing::new(self.primes[0].to_bytes_be());
let prime2 = Zeroizing::new(self.primes[1].to_bytes_be());
let exponent1 = Zeroizing::new((self.d() % (&self.primes[0] - 1u8)).to_bytes_be());
let exponent2 = Zeroizing::new((self.d() % (&self.primes[1] - 1u8)).to_bytes_be());
let coefficient = Zeroizing::new(
(&self.primes[1])
.mod_inverse(&self.primes[0])
.ok_or(pkcs1::Error::Crypto)?
.to_bytes_be()
.1,
);
Ok(pkcs1::RsaPrivateKey {
version: pkcs1::Version::TwoPrime,
modulus: pkcs1::UIntBytes::new(&modulus)?,
public_exponent: pkcs1::UIntBytes::new(&public_exponent)?,
private_exponent: pkcs1::UIntBytes::new(&private_exponent)?,
prime1: pkcs1::UIntBytes::new(&prime1)?,
prime2: pkcs1::UIntBytes::new(&prime2)?,
exponent1: pkcs1::UIntBytes::new(&exponent1)?,
exponent2: pkcs1::UIntBytes::new(&exponent2)?,
coefficient: pkcs1::UIntBytes::new(&coefficient)?,
}
.to_der())
}
}
impl ToRsaPublicKey for RsaPublicKey {
fn to_pkcs1_der(&self) -> pkcs1::Result<RsaPublicKeyDocument> {
let modulus = self.n().to_bytes_be();
let public_exponent = self.e().to_bytes_be();
Ok(pkcs1::RsaPublicKey {
modulus: pkcs1::UIntBytes::new(&modulus)?,
public_exponent: pkcs1::UIntBytes::new(&public_exponent)?,
}
.to_der())
}
}