summaryrefslogtreecommitdiff
path: root/webhook/src/handler/signature.rs
diff options
context:
space:
mode:
Diffstat (limited to 'webhook/src/handler/signature.rs')
-rw-r--r--webhook/src/handler/signature.rs47
1 files changed, 18 insertions, 29 deletions
diff --git a/webhook/src/handler/signature.rs b/webhook/src/handler/signature.rs
index c12f9e8..748fa6a 100644
--- a/webhook/src/handler/signature.rs
+++ b/webhook/src/handler/signature.rs
@@ -1,5 +1,8 @@
use common::prometheus::{Counter, HistogramVec, labels, opts, register_counter, register_histogram_vec};
-use libsodium_sys::crypto_sign_ed25519_verify_detached;
+use ed25519_dalek::PublicKey;
+use ed25519_dalek::Verifier;
+use ed25519_dalek::Signature;
+use std::convert::TryInto;
lazy_static::lazy_static! {
static ref SIGNATURE_TIME_HISTOGRAM: HistogramVec = register_histogram_vec!(
@@ -8,43 +11,29 @@ lazy_static::lazy_static! {
&["signature"]
).unwrap();
- static ref SIGNATURE_BODY_COUNTER: Counter = register_counter!(opts!(
- "nova_webhook_",
- "",
+ static ref SIGNATURE_COUNTER: Counter = register_counter!(opts!(
+ "nova_webhook_signatures_verify",
+ "number of signatures verification issued by the service",
labels! {"handler" => "webhook_main"}
)).unwrap();
}
-/// Checks the signature of a given data using the hex signature and the public key.
-pub fn validate_signature(hex_public_key: &str, data: &Vec<u8>, hex_signature: &str) -> bool {
- SIGNATURE_BODY_COUNTER.inc();
+fn demo<T, const N: usize>(v: Vec<T>) -> [T; N] {
+ v.try_into()
+ .unwrap_or_else(|v: Vec<T>| panic!("Expected a Vec of length {} but it was {}", N, v.len()))
+}
+
+pub fn validate_signature(public_key: &PublicKey, data: &Vec<u8>, hex_signature: &str) -> bool {
+ SIGNATURE_COUNTER.inc();
let timer = SIGNATURE_TIME_HISTOGRAM.with_label_values(&["webhook_main"]).start_timer();
- // First, we need to check if the signature & private key is valid base64.
let signature_result = hex::decode(hex_signature);
- let public_key_result = hex::decode(hex_public_key);
let mut result = false;
- if signature_result.is_ok() && public_key_result.is_ok() {
- // Since we now have the signatures in u8 vectors. We will initialize all the
- // parameters for the ffi call to sodium.
- let signature_pointer = signature_result.unwrap();
- let private_key_pointer = public_key_result.unwrap();
-
- let data_pointer = data.as_ptr();
- let data_len = data.len() as u64;
-
- // A ffi call is considered unsafe by the Rust compiler
- // we assume all the parameters are correct for the call
- unsafe {
- // If the signature is valid, sodium will return 0
- result = crypto_sign_ed25519_verify_detached(
- signature_pointer.as_ptr(),
- data_pointer,
- data_len,
- private_key_pointer.as_ptr(),
- ) == 0;
- }
+ if let Ok(signature) = signature_result {
+ let sig = Signature::from(demo(signature));
+
+ result = public_key.verify(data, &sig).is_ok();
}
timer.observe_duration();