Update to serde 1.0 (#4)

* Try updating service to 1.0

* Strip bounds from structs

* Clean bounds from Default impl

* Remove pem files, clean up some documentation

* Add badges, categories
This commit is contained in:
Thomas Gideon 2017-08-10 09:39:35 -04:00 committed by GitHub
parent a265a703d6
commit 42824a133e
11 changed files with 65 additions and 92 deletions

View file

@ -73,8 +73,7 @@ fn verify_rsa(signature: &str, data: &str, key: &[u8], digest: MessageDigest) ->
#[cfg(test)]
pub mod tests {
use header::Algorithm;
use std::io::{Error, Read};
use std::fs::File;
use openssl;
use super::{sign, verify};
#[test]
@ -90,17 +89,17 @@ pub mod tests {
}
#[test]
pub fn sign_data_rsa() {
pub fn sign_and_verify_data_rsa() {
let header = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9";
let claims = "eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9";
let real_sig = "nXdpIkFQYZXZ0VlJjHmAc5_aewHCCJpT5jP1fpexUCF_9m3NxlC7uYNXAl6NKno520oh9wVT4VV_vmPeEin7BnnoIJNPcImWcUzkYpLTrDBntiF9HCuqFaniuEVzlf8dVlRJgo8QxhmUZEjyDFjPZXZxPlPV1LD6hrtItxMKZbh1qoNY3OL7Mwo-WuSRQ0mmKj-_y3weAmx_9EaTLY639uD8-o5iZxIIf85U4e55Wdp-C9FJ4RxyHpjgoG8p87IbChfleSdWcZL3NZuxjRCHVWgS1uYG0I-LqBWpWyXnJ1zk6-w4tfxOYpZFMOIyq4tY2mxJQ78Kvcu8bTO7UdI7iA";
let data = format!("{}.{}", header, claims);
let key = load_pem("./examples/privateKey.pem").unwrap();
let keypair = openssl::rsa::Rsa::generate(2048).unwrap();
let sig = sign(&*data, key.as_bytes(), &Algorithm::RS256);
let sig = sign(&*data, &keypair.private_key_to_pem().unwrap(), &Algorithm::RS256).unwrap();
assert_eq!(sig.unwrap(), real_sig);
assert!(verify(&sig, &*data, &keypair.public_key_to_pem().unwrap(), &Algorithm::RS256).unwrap());
}
#[test]
@ -112,22 +111,4 @@ pub mod tests {
assert!(verify(target, &*data, "secret".as_bytes(), &Algorithm::HS256).unwrap());
}
#[test]
pub fn verify_data_rsa() {
let header = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9";
let claims = "eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9";
let real_sig = "nXdpIkFQYZXZ0VlJjHmAc5_aewHCCJpT5jP1fpexUCF_9m3NxlC7uYNXAl6NKno520oh9wVT4VV_vmPeEin7BnnoIJNPcImWcUzkYpLTrDBntiF9HCuqFaniuEVzlf8dVlRJgo8QxhmUZEjyDFjPZXZxPlPV1LD6hrtItxMKZbh1qoNY3OL7Mwo-WuSRQ0mmKj-_y3weAmx_9EaTLY639uD8-o5iZxIIf85U4e55Wdp-C9FJ4RxyHpjgoG8p87IbChfleSdWcZL3NZuxjRCHVWgS1uYG0I-LqBWpWyXnJ1zk6-w4tfxOYpZFMOIyq4tY2mxJQ78Kvcu8bTO7UdI7iA";
let data = format!("{}.{}", header, claims);
let key = load_pem("./examples/publicKey.pub").unwrap();
assert!(verify(&real_sig, &*data, key.as_bytes(), &Algorithm::RS256).unwrap());
}
pub fn load_pem(keypath: &str) -> Result<String, Error> {
let mut key_file = File::open(keypath)?;
let mut key = String::new();
key_file.read_to_string(&mut key)?;
Ok(key)
}
}

View file

@ -7,10 +7,15 @@ use openssl::error::ErrorStack;
#[derive(Debug)]
pub enum Error {
/// Custom, Medallion specific errors.
Custom(String),
/// String encoding errors.
Utf8(FromUtf8Error),
/// Base64 encoding or decoding errors.
Base64(Base64Error),
/// JSON parsing or stringifying errors.
JSON(serde_json::Error),
/// Errors from RSA operations.
Crypto(ErrorStack),
}

View file

@ -31,6 +31,7 @@ pub enum Algorithm {
}
impl<T: Serialize + DeserializeOwned> Header<T> {
/// Decode from base64.
pub fn from_base64(raw: &str) -> Result<Header<T>> {
let data = decode_config(raw, URL_SAFE_NO_PAD)?;
let own: Header<T> = serde_json::from_slice(&data)?;

View file

@ -1,6 +1,11 @@
#![crate_name = "medallion"]
#![crate_type = "lib"]
#![doc(html_root_url = "https://commandline.github.io/medallion/")]
///! A crate for working with JSON WebTokens that use OpenSSL for RSA signing and encryption and
///! serde and serde_json for JSON encoding and decoding.
///!
///! Tries to support the standard uses for JWTs while providing reasonable ways to extend,
///! primarily by adding custom headers and claims to tokens.
extern crate base64;
extern crate openssl;
extern crate serde;
@ -23,8 +28,8 @@ mod crypt;
pub type Result<T> = std::result::Result<T, Error>;
/// A convenient type that bins the same type parameter for the custom claims, an empty tuple, as
/// DefaultPayload so that the two aliases may be used together to reduce boilerplate when not
/// A convenient type that binds the same type parameter for the custom claims, an empty tuple, as
/// DefaultPayload so that the two aliases may be used together to reduce boilerplate when no
/// custom claims are needed.
pub type DefaultToken<H> = Token<H, ()>;
@ -54,7 +59,7 @@ impl<H, C> Token<H, C>
let pieces: Vec<_> = raw.split('.').collect();
Ok(Token {
raw: Some(raw.into()),
raw: Some(raw.to_owned()),
header: Header::from_base64(pieces[0])?,
payload: Payload::from_base64(pieces[1])?,
})
@ -98,7 +103,7 @@ impl<H, C> PartialEq for Token<H, C>
#[cfg(test)]
mod tests {
use {DefaultPayload, DefaultToken, Header};
use crypt::tests::load_pem;
use openssl;
use std::default::Default;
use time::{self, Duration, Tm};
use super::Algorithm::{HS256, RS512};
@ -158,15 +163,14 @@ mod tests {
#[test]
pub fn roundtrip_rsa() {
let rsa_keypair = openssl::rsa::Rsa::generate(2048).unwrap();
let header: Header<()> = Header { alg: RS512, ..Default::default() };
let token = DefaultToken { header: header, ..Default::default() };
let private_key = load_pem("./examples/privateKey.pem").unwrap();
let raw = token.sign(private_key.as_bytes()).unwrap();
let raw = token.sign(&rsa_keypair.private_key_to_pem().unwrap()).unwrap();
let same = DefaultToken::parse(&*raw).unwrap();
assert_eq!(token, same);
let public_key = load_pem("./examples/publicKey.pub").unwrap();
assert!(same.verify(public_key.as_bytes()).unwrap());
assert!(same.verify(&rsa_keypair.public_key_to_pem().unwrap()).unwrap());
}
fn create_for_range(nbf: Tm, exp: Tm) -> DefaultToken<()> {