LemmyNet/activitypub-federation-rust

Make sure http signing is not blocking tokio

phiresky opened this issue · 3 comments

Right now this lambda:

move |signing_string| {
let mut signer = Signer::new(MessageDigest::sha256(), &private_key)
.context("instantiating signer")?;
signer
.update(signing_string.as_bytes())
.context("updating signer")?;
Ok(Base64.encode(signer.sign_to_vec().context("sign to vec")?))
as Result<_, anyhow::Error>

is passed to here: https://git.asonix.dog/asonix/http-signature-normalization/src/commit/85bbcb0bae2f976d08dfddad3d5050ffae149732/reqwest/src/lib.rs#L249

which seems to run it in the main async runtime. But signing is a potentially expensive operation and should probably run inside tokio::spawn. I've messaged asonix, the author of the library to confirm since if true it's probably not fixable here since the lambda is synchronous.

I don't really know what I'm talking about, but according to openssl speed rsa a signing operation with a 2048-bit RSA key takes around 0.3ms. according to https://ryhl.io/blog/async-what-is-blocking/ , stuff in the async runtime threads shouldn't block for more than 0.1ms.

The same goes for the verification function maybe:

.verify(|signature, signing_string| -> anyhow::Result<bool> {
debug!(
"Verifying with key {}, message {}",
&public_key, &signing_string
);
let public_key = PKey::public_key_from_pem(public_key.as_bytes())?;
let mut verifier = Verifier::new(MessageDigest::sha256(), &public_key)?;
verifier.update(signing_string.as_bytes())?;
Ok(verifier.verify(&Base64.decode(signature)?)?)
})
.map_err(Error::other)?;
if verified {
debug!("verified signature for {}", uri);
Ok(())
} else {
Err(ActivitySignatureInvalid)
}
}

That one should actually be fixable here since the verify function can return a Future