From 20f7a268cce05cd63842adbc7a5d05d4d4cc5bc7 Mon Sep 17 00:00:00 2001 From: Teddy Wing Date: Sat, 10 Nov 2018 20:39:48 +0100 Subject: paddle::verify_signature(): Extract signature from params Make it easier on users by not requiring them to pass a signature into the method. This means they don't have to extract the `p_signature` param and base64 decode it themselves. Essentially, we want to move the code from `request` that removes the `p_signature` key and base64 decodes it into the `paddle::verify_signature()` function. We need to make the string-like type params in `verify_signature()` conform additionally to `PartialEq` and `PartialOrd`. Doing so allows us to find the key "p_signature". To remove the `p_signature` param from the iterator, we partition it into two iterators: one for the `p_signature` entry, and another for the rest. We then extract the value of `p_signature` and base64 decode it for verification. Add a new error type in case no `p_signature` entry is found in the iterator. --- license-generator/Cargo.lock | 2 +- license-generator/Cargo.toml | 1 - license-generator/paddle/Cargo.toml | 1 + license-generator/paddle/src/lib.rs | 24 +++++++++++++++++++++--- license-generator/src/errors.rs | 2 -- license-generator/src/lib.rs | 2 -- license-generator/src/request.rs | 12 ++---------- 7 files changed, 25 insertions(+), 19 deletions(-) diff --git a/license-generator/Cargo.lock b/license-generator/Cargo.lock index aecdcce..4540e25 100644 --- a/license-generator/Cargo.lock +++ b/license-generator/Cargo.lock @@ -282,7 +282,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "license-generator" version = "0.0.1" dependencies = [ - "base64 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "fastcgi 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -476,6 +475,7 @@ dependencies = [ name = "paddle" version = "0.0.1" dependencies = [ + "base64 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "openssl 0.10.15 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/license-generator/Cargo.toml b/license-generator/Cargo.toml index 3107ee8..b50bec1 100644 --- a/license-generator/Cargo.toml +++ b/license-generator/Cargo.toml @@ -3,7 +3,6 @@ name = "license-generator" version = "0.0.1" [dependencies] -base64 = "0.10.0" error-chain = "0.12.0" fastcgi = "1.0.0" log = "0.4.6" diff --git a/license-generator/paddle/Cargo.toml b/license-generator/paddle/Cargo.toml index a304aee..34af6d4 100644 --- a/license-generator/paddle/Cargo.toml +++ b/license-generator/paddle/Cargo.toml @@ -3,5 +3,6 @@ name = "paddle" version = "0.0.1" [dependencies] +base64 = "0.10.0" error-chain = "0.12.0" openssl = "0.10.15" diff --git a/license-generator/paddle/src/lib.rs b/license-generator/paddle/src/lib.rs index be10a76..6d685cd 100644 --- a/license-generator/paddle/src/lib.rs +++ b/license-generator/paddle/src/lib.rs @@ -1,14 +1,24 @@ +extern crate base64; + #[macro_use] extern crate error_chain; extern crate openssl; pub mod errors { + use base64; use openssl; error_chain! { foreign_links { + Base64(base64::DecodeError); Openssl(openssl::error::ErrorStack); } + + errors { + SignatureNotFound { + display("no signature could be found in params") + } + } } } @@ -26,21 +36,29 @@ use errors::*; // https://paddle.com/docs/reference-verifying-webhooks/ pub fn verify_signature<'a, S, I>( pem: &[u8], - signature: &[u8], params: I, ) -> Result where - S: AsRef + Deref + Display, + S: AsRef + Deref + PartialEq + PartialOrd + Display, I: IntoIterator + PartialOrd, { let rsa = Rsa::public_key_from_pem(pem)?; let pkey = PKey::from_rsa(rsa)?; let mut verifier = Verifier::new(MessageDigest::sha1(), &pkey)?; + let (signature_params, params): (Vec<_>, Vec<_>) = params + .into_iter() + .partition(|(k, _v)| k == "p_signature"); + let signature = &signature_params + .first() + .ok_or(ErrorKind::SignatureNotFound)? + .1; + let signature = base64::decode(signature.as_bytes())?; + let digest = php_serialize(params); verifier.update(digest.as_bytes())?; - Ok(verifier.verify(signature)?) + Ok(verifier.verify(&signature)?) } fn php_serialize<'a, S, I>(pairs: I) -> String diff --git a/license-generator/src/errors.rs b/license-generator/src/errors.rs index e21edd4..0799c3e 100644 --- a/license-generator/src/errors.rs +++ b/license-generator/src/errors.rs @@ -1,4 +1,3 @@ -use base64; use log; use mysql; use paddle; @@ -8,7 +7,6 @@ error_chain! { EnvVar(::std::env::VarError); Io(::std::io::Error); - Base64(base64::DecodeError); Log(log::SetLoggerError); MySql(mysql::error::Error); diff --git a/license-generator/src/lib.rs b/license-generator/src/lib.rs index e2c02b6..bf3ed57 100644 --- a/license-generator/src/lib.rs +++ b/license-generator/src/lib.rs @@ -1,5 +1,3 @@ -extern crate base64; - #[macro_use] extern crate error_chain; extern crate log; diff --git a/license-generator/src/request.rs b/license-generator/src/request.rs index 325fdec..190a756 100644 --- a/license-generator/src/request.rs +++ b/license-generator/src/request.rs @@ -1,19 +1,11 @@ -use base64; use paddle; use errors::*; use params; pub fn verified(req_params: &str) -> Result { - let mut p = params::parse(&req_params); - let signature = p.remove("p_signature"); + let p = params::parse(&req_params); let pem = include_bytes!("../private/paddle.pubkey.asc"); - match signature { - Some(signature) => { - let signature = base64::decode(signature.as_bytes())?; - Ok(paddle::verify_signature(pem, &signature, p)?) - }, - None => Ok(false), - } + Ok(paddle::verify_signature(pem, p)?) } -- cgit v1.2.3