Replace nettle with pure-rust RSA for conversions

Fixes: https://gitlab.com/openpgp-card/openpgp-card/-/issues/66
This commit is contained in:
Wiktor Kwapisiewicz 2023-02-10 12:26:57 +01:00
parent c80e549cc4
commit 5bd73d81fc
No known key found for this signature in database
GPG key ID: E68BE3B312FA33FC
2 changed files with 53 additions and 11 deletions

View file

@ -13,12 +13,12 @@ documentation = "https://docs.rs/crate/openpgp-card-sequoia"
[dependencies] [dependencies]
sequoia-openpgp = "1.4" sequoia-openpgp = "1.4"
nettle = "7"
openpgp-card = { path = "../openpgp-card", version = "0.3.3" } openpgp-card = { path = "../openpgp-card", version = "0.3.3" }
chrono = "0.4" chrono = "0.4"
anyhow = "1" anyhow = "1"
thiserror = "1" thiserror = "1"
log = "0.4" log = "0.4"
rsa = "0.8.1"
[dev-dependencies] [dev-dependencies]
openpgp-card-pcsc = { path = "../pcsc", version = "0.3" } openpgp-card-pcsc = { path = "../pcsc", version = "0.3" }

View file

@ -109,6 +109,14 @@ impl CardUploadableKey for SequoiaKey {
} }
} }
fn mpi_to_biguint(mpi: &MPI) -> rsa::BigUint {
slice_to_biguint(mpi.value())
}
fn slice_to_biguint(bytes: &[u8]) -> rsa::BigUint {
rsa::BigUint::from_bytes_be(bytes)
}
/// RSA-specific data-structure to hold private (sub)key material for upload /// RSA-specific data-structure to hold private (sub)key material for upload
/// with the `openpgp-card` crate. /// with the `openpgp-card` crate.
struct SqRSA { struct SqRSA {
@ -116,7 +124,9 @@ struct SqRSA {
n: MPI, n: MPI,
p: ProtectedMPI, p: ProtectedMPI,
q: ProtectedMPI, q: ProtectedMPI,
nettle: nettle::rsa::PrivateKey, pq: ProtectedMPI,
dp1: ProtectedMPI,
dq1: ProtectedMPI,
} }
impl SqRSA { impl SqRSA {
@ -128,10 +138,43 @@ impl SqRSA {
p: ProtectedMPI, p: ProtectedMPI,
q: ProtectedMPI, q: ProtectedMPI,
) -> Result<Self, Error> { ) -> Result<Self, Error> {
let nettle = nettle::rsa::PrivateKey::new(d.value(), p.value(), q.value(), None) let key = rsa::RsaPrivateKey::from_components(
.map_err(|e| Error::InternalError(format!("nettle error {e:?}")))?; mpi_to_biguint(&n),
mpi_to_biguint(&e),
slice_to_biguint(d.value()),
vec![slice_to_biguint(p.value()), slice_to_biguint(q.value())],
)
.map_err(|e| Error::InternalError(format!("rsa error {e:?}")))?;
Ok(Self { e, n, p, q, nettle }) let pq = key
.qinv()
.ok_or_else(|| Error::InternalError("pq value missing".into()))?
.to_biguint()
.ok_or_else(|| Error::InternalError("conversion to bigunit failed".into()))?
.to_bytes_be()
.into();
let dp1 = key
.dp()
.ok_or_else(|| Error::InternalError("dp1 value missing".into()))?
.to_bytes_be()
.into();
let dq1 = key
.dq()
.ok_or_else(|| Error::InternalError("dq1 value missing".into()))?
.to_bytes_be()
.into();
Ok(Self {
e,
n,
p,
q,
pq,
dp1,
dq1,
})
} }
} }
@ -149,16 +192,15 @@ impl RSAKey for SqRSA {
} }
fn pq(&self) -> Box<[u8]> { fn pq(&self) -> Box<[u8]> {
let (_, _, inv) = self.nettle.d_crt(); self.pq.value().into()
inv
} }
fn dp1(&self) -> Box<[u8]> { fn dp1(&self) -> Box<[u8]> {
let (dp, _, _) = self.nettle.d_crt(); self.dp1.value().into()
dp
} }
fn dq1(&self) -> Box<[u8]> { fn dq1(&self) -> Box<[u8]> {
let (_, dq, _) = self.nettle.d_crt(); self.dq1.value().into()
dq
} }
fn n(&self) -> &[u8] { fn n(&self) -> &[u8] {