diff --git a/README.md b/README.md index bb93808..10c4d61 100644 --- a/README.md +++ b/README.md @@ -28,13 +28,13 @@ In addition to the normal base64/json decoding errors, `decode` can return two c - **WrongAlgorithmHeader**: if the alg in the header doesn't match the one given to decode ## Algorithms -Right now, only SHA256 is supported. +Right now, only SHA family is supported: SHA256, SHA384 and SHA512. ## Missing The header is currently not customisable and therefore does not support things like kid right now. ## Performance -On my thinkpad 440s for a 2 claims struct: +On my thinkpad 440s for a 2 claims struct using SHA256: ``` test bench_decode ... bench: 7,106 ns/iter (+/- 5,354) diff --git a/src/lib.rs b/src/lib.rs index a692f73..dc04787 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -10,7 +10,7 @@ extern crate crypto; use rustc_serialize::{json, Encodable, Decodable}; use rustc_serialize::base64::{self, ToBase64, FromBase64}; -use crypto::sha2::Sha256; +use crypto::sha2::{Sha256, Sha384, Sha512}; use crypto::hmac::Hmac; use crypto::mac::Mac; use crypto::digest::Digest; @@ -18,16 +18,20 @@ use crypto::digest::Digest; pub mod errors; use errors::Error; -#[derive(Debug, Copy, Clone)] +#[derive(Debug, Copy, Clone, RustcDecodable, RustcEncodable)] /// The algorithms supported for signing, so far only Hmac Sha256 pub enum Algorithm { HS256, + HS384, + HS512 } impl ToString for Algorithm { fn to_string(&self) -> String { match *self { Algorithm::HS256 => "HS256".to_owned(), + Algorithm::HS384 => "HS384".to_owned(), + Algorithm::HS512 => "HS512".to_owned(), } } } @@ -72,12 +76,17 @@ impl Header { /// Take the payload of a JWT and sign it using the algorithm given. /// Returns the base64 url safe encoded of the hmac result fn sign(data: &str, secret: &[u8], algorithm: Algorithm) -> String { - let digest = match algorithm { - Algorithm::HS256 => Sha256::new(), - }; - let mut hmac = Hmac::new(digest, secret); - hmac.input(data.as_bytes()); - hmac.result().code().to_base64(base64::URL_SAFE) + fn crypt(digest: D, data: &str, secret: &[u8]) -> String { + let mut hmac = Hmac::new(digest, secret); + hmac.input(data.as_bytes()); + hmac.result().code().to_base64(base64::URL_SAFE) + } + + match algorithm { + Algorithm::HS256 => crypt(Sha256::new(), data, secret), + Algorithm::HS384 => crypt(Sha384::new(), data, secret), + Algorithm::HS512 => crypt(Sha512::new(), data, secret), + } } /// Compares the signature given with a re-computed signature