Compare commits

...

5 commits

Author SHA1 Message Date
Thomas Gideon 22bedd7049 Update badge 2022-02-19 08:36:26 -05:00
Thomas Gideon 11aa5a3f7c Increment version 2022-02-19 08:32:44 -05:00
Vincent Ambo 025b143d88 Replace usage of chrono with time crate
The time crate is the underlying crate which chrono uses for its
various operations.

Unfortunately, chrono is unmaintained and older versions of the time
crate have security vulnerabilites[0] which are unfixed in chrono[1].

The medallion code does not use any chrono-specific features and all
uses of it could be trivially replaced with the underlying time
structs.

Note that this change adds calls to `expect`. Where these calls are
made, the previous chrono functions also panicked internally if
out-of-range values were passed.

We noticed this issue while doing a similar refactoring in a program
that also uses medallion[2].

[0]: https://rustsec.org/advisories/RUSTSEC-2020-0071.html
[1]: https://rustsec.org/advisories/RUSTSEC-2020-0159.html
[2]: https://cl.tvl.fyi/c/depot/+/5311
2022-02-19 08:29:40 -05:00
Thomas Gideon 970f33d596 Remove github references 2021-12-03 14:11:02 -05:00
Thomas Gideon 8e78ba94f8 Move repository 2021-12-03 14:09:49 -05:00
4 changed files with 25 additions and 37 deletions

View file

@ -2,14 +2,13 @@
authors = ["Thomas Gideon <cmdln@thecommandline.net>"]
categories = ["cryptography", "authentication", "web-programming", "data-structures"]
description = "JWT library for rust using serde, serde_json and openssl"
documentation = "https://cmdln.github.io/medallion/"
homepage = "http://github.com/cmdln/medallion"
homepage = "https://gitea.cmdln.net/cmdln/medallion"
keywords = ["JWT", "token", "web", "JSON", "RSA"]
license = "MIT"
name = "medallion"
readme = "README.md"
repository = "http://github.com/cmdln/medallion"
version = "2.4.1"
repository = "https://gitea.cmdln.net/cmdln/medallion"
version = "2.5.0"
edition = "2018"
[badges]
[badges.travis-ci]
@ -22,4 +21,4 @@ openssl = "~0.10.15"
serde = { version = "^1.0.114", features = [ "derive" ] }
serde_json = "^1.0.55"
anyhow = "^1.0.31"
chrono = "~0.4.11"
time = "~0.3"

View file

@ -1,17 +1,10 @@
Medallion
=========
[![Build Status](https://travis-ci.org/cmdln/medallion.svg?branch=master)](https://travis-ci.org/cmdln/medallion)
[![Crates.io Status](http://meritbadge.herokuapp.com/medallion)](https://crates.io/crates/medallion)
[![Documentation](https://docs.rs/medallion/badge.svg)](https://docs.rs/medallion)
[![dependency status](https://deps.rs/crate/medallion/2.4.0/status.svg)](https://deps.rs/crate/medallion/2.4.0)
[![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/cmdln/medallion/master/LICENSE)
[![dependency status](https://deps.rs/crate/medallion/2.5.0/status.svg)](https://deps.rs/crate/medallion/2.5.0)
A JWT library for rust using serde, serde_json and openssl.
## Documentation
- [Documentation](https://cmdln.github.io/medallion/)
## Usage
The library provides a `Token` type that wraps headers and claims.

View file

@ -95,8 +95,8 @@ mod tests {
use super::Algorithm::{HS256, RS512};
use crate::{DefaultPayload, DefaultToken, Header, Payload, Token};
use anyhow::Result;
use chrono::{prelude::*, Duration};
use std::convert::TryInto;
use time::{Duration, OffsetDateTime};
#[test]
pub fn raw_data() {
@ -111,11 +111,11 @@ mod tests {
#[test]
pub fn roundtrip_hmac() {
let now = Utc::now();
let now = OffsetDateTime::now_utc();
let header: Header<()> = Header::default();
let payload = DefaultPayload {
nbf: Some(now.timestamp().try_into().unwrap()),
exp: Some((now + Duration::minutes(5)).timestamp().try_into().unwrap()),
nbf: Some(now.unix_timestamp().try_into().unwrap()),
exp: Some((now + Duration::minutes(5)).unix_timestamp().try_into().unwrap()),
..DefaultPayload::default()
};
let token = Token::new(header, payload);
@ -129,7 +129,7 @@ mod tests {
#[test]
pub fn roundtrip_expired() -> Result<()> {
let now = Utc::now();
let now = OffsetDateTime::now_utc();
let token = create_for_range(now, now + Duration::minutes(-5))?;
let key = b"secret";
let raw = token.sign(key)?;
@ -142,7 +142,7 @@ mod tests {
#[test]
pub fn roundtrip_not_yet_valid() -> Result<()> {
let now = Utc::now();
let now = OffsetDateTime::now_utc();
let token = create_for_range(now + Duration::minutes(5), now + Duration::minutes(10))?;
let key = b"secret";
let raw = token.sign(key)?;
@ -175,11 +175,11 @@ mod tests {
.unwrap());
}
fn create_for_range(nbf: DateTime<Utc>, exp: DateTime<Utc>) -> Result<Token> {
fn create_for_range(nbf: OffsetDateTime, exp: OffsetDateTime) -> Result<Token> {
let header: Header = Header::default();
let payload = Payload {
nbf: Some(nbf.timestamp().try_into()?),
exp: Some(exp.timestamp().try_into()?),
nbf: Some(nbf.unix_timestamp().try_into()?),
exp: Some(exp.unix_timestamp().try_into()?),
..Payload::default()
};
Ok(Token::new(header, payload))

View file

@ -1,9 +1,9 @@
use super::Result;
use anyhow::format_err;
use base64::{decode_config, encode_config, URL_SAFE_NO_PAD};
use chrono::{DateTime, NaiveDateTime, Utc};
use serde::{de::DeserializeOwned, Deserialize, Serialize};
use serde_json::value::Value;
use time::{OffsetDateTime};
/// A default claim set, including the standard, or registered, claims and the ability to specify
/// your own as custom claims.
@ -81,23 +81,19 @@ impl<T: Serialize + DeserializeOwned> Payload<T> {
}
pub fn verify(&self) -> bool {
let now = Utc::now();
let now = OffsetDateTime::now_utc();
let nbf_verified = match self.nbf {
Some(nbf_sec) => {
let nbf = DateTime::<Utc>::from_utc(
NaiveDateTime::from_timestamp(nbf_sec as i64, 0),
Utc,
);
let nbf = OffsetDateTime::from_unix_timestamp(nbf_sec as i64)
.expect("nbf timestamp out of range");
nbf < now
}
None => true,
};
let exp_verified = match self.exp {
Some(exp_sec) => {
let exp = DateTime::<Utc>::from_utc(
NaiveDateTime::from_timestamp(exp_sec as i64, 0),
Utc,
);
let exp = OffsetDateTime::from_unix_timestamp(exp_sec as i64)
.expect("exp timestamp out of range");
now < exp
}
None => true,
@ -109,9 +105,9 @@ impl<T: Serialize + DeserializeOwned> Payload<T> {
#[cfg(test)]
mod tests {
use super::{DefaultPayload, Payload};
use chrono::{prelude::*, Duration};
use serde::{Deserialize, Serialize};
use std::default::Default;
use time::{Duration, OffsetDateTime};
#[derive(Default, Debug, Serialize, Deserialize, PartialEq)]
struct CustomClaims {
@ -211,7 +207,7 @@ mod tests {
}
fn create_with_nbf(offset: i64) -> DefaultPayload {
let nbf = (Utc::now() - Duration::minutes(offset)).timestamp();
let nbf = (OffsetDateTime::now_utc() - Duration::minutes(offset)).unix_timestamp();
DefaultPayload {
nbf: Some(nbf as u64),
..Default::default()
@ -219,7 +215,7 @@ mod tests {
}
fn create_with_exp(offset: i64) -> DefaultPayload {
let exp = (Utc::now() + Duration::minutes(offset)).timestamp();
let exp = (OffsetDateTime::now_utc() + Duration::minutes(offset)).unix_timestamp();
DefaultPayload {
exp: Some(exp as u64),
..Default::default()
@ -227,8 +223,8 @@ mod tests {
}
fn create_with_nbf_exp(nbf_offset: i64, exp_offset: i64) -> DefaultPayload {
let nbf = (Utc::now() - Duration::minutes(nbf_offset)).timestamp();
let exp = (Utc::now() + Duration::minutes(exp_offset)).timestamp();
let nbf = (OffsetDateTime::now_utc() - Duration::minutes(nbf_offset)).unix_timestamp();
let exp = (OffsetDateTime::now_utc() + Duration::minutes(exp_offset)).unix_timestamp();
DefaultPayload {
nbf: Some(nbf as u64),
exp: Some(exp as u64),