Compare commits

...

63 Commits

Author SHA1 Message Date
2b3c2f24ba Merge pull request 'Update Rust crate rkyv to v0.8.15' (#156) from renovate/rkyv-0.x-lockfile into master
Some checks failed
continuous-integration/drone/push Build is failing
2026-02-13 00:27:54 +00:00
9689130176 Update Rust crate rkyv to v0.8.15
Some checks failed
continuous-integration/drone/push Build is failing
continuous-integration/drone/pr Build is failing
2026-02-13 00:27:47 +00:00
0fdec5389a Merge pull request 'Update Rust crate rand to 0.10.0' (#155) from renovate/rand-0.x into master
Some checks failed
continuous-integration/drone/push Build is failing
2026-02-09 00:27:01 +00:00
c0a8686fd0 Update Rust crate rand to 0.10.0
Some checks failed
continuous-integration/drone/push Build is failing
continuous-integration/drone/pr Build is failing
2026-02-09 00:26:58 +00:00
b09afbb431 Merge pull request 'Update Rust crate reqwest to v0.13.2' (#154) from renovate/reqwest-0.x-lockfile into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-02-07 00:27:18 +00:00
13498fdaa2 Update Rust crate reqwest to v0.13.2
Some checks failed
continuous-integration/drone/push Build is failing
continuous-integration/drone/pr Build is passing
2026-02-07 00:27:13 +00:00
823f885770 Merge pull request 'Update Rust crate thiserror to v2.0.18' (#153) from renovate/thiserror-2.x-lockfile into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-01-19 00:10:53 +00:00
387b148325 Update Rust crate thiserror to v2.0.18
Some checks failed
continuous-integration/drone/push Build is failing
continuous-integration/drone/pr Build is passing
2026-01-19 00:10:48 +00:00
e673271fb0 Merge pull request 'Update Rust crate rkyv to v0.8.14' (#152) from renovate/rkyv-0.x-lockfile into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-01-14 00:30:18 +00:00
6298c01c2e Update Rust crate rkyv to v0.8.14
Some checks failed
continuous-integration/drone/push Build is failing
continuous-integration/drone/pr Build is passing
2026-01-14 00:29:56 +00:00
db0894f99a Add missing feature in reqwest
All checks were successful
continuous-integration/drone/push Build is passing
2026-01-06 19:07:17 +01:00
66183ca51c Merge pull request 'Update Rust crate rkyv to v0.8.13' (#151) from renovate/rkyv-0.x-lockfile into master
Some checks failed
continuous-integration/drone/push Build is failing
2026-01-05 00:22:42 +00:00
e27bde8596 Update Rust crate rkyv to v0.8.13
Some checks failed
continuous-integration/drone/push Build is failing
continuous-integration/drone/pr Build is failing
2026-01-05 00:22:38 +00:00
73283f33bd Merge pull request 'Update Rust crate reqwest to 0.13.0' (#150) from renovate/reqwest-0.x into master
Some checks failed
continuous-integration/drone/push Build is failing
2025-12-31 00:30:19 +00:00
85c7200eca Update Rust crate reqwest to 0.13.0
Some checks failed
continuous-integration/drone/push Build is failing
continuous-integration/drone/pr Build is failing
2025-12-31 00:30:07 +00:00
4f06b56295 Improve error handling
All checks were successful
continuous-integration/drone/push Build is passing
2025-12-29 16:36:20 +01:00
c850288d85 Migrate from bincode to rkyv
All checks were successful
continuous-integration/drone/push Build is passing
2025-12-29 16:20:01 +01:00
b0667312e5 Merge pull request 'Update Rust crate serde_json to v1.0.148' (#149) from renovate/serde_json-1.x-lockfile into master
Some checks failed
continuous-integration/drone/push Build is failing
2025-12-28 00:29:46 +00:00
e6ab0bb9c0 Update Rust crate serde_json to v1.0.148
Some checks failed
continuous-integration/drone/push Build is failing
continuous-integration/drone/pr Build is failing
2025-12-28 00:29:40 +00:00
02db2254ce Merge pull request 'Update Rust crate serde_json to v1.0.147' (#148) from renovate/serde_json-1.x-lockfile into master
Some checks failed
continuous-integration/drone/push Build is failing
2025-12-24 00:30:16 +00:00
fd3c223b6e Update Rust crate serde_json to v1.0.147
Some checks failed
continuous-integration/drone/push Build is failing
continuous-integration/drone/pr Build is failing
2025-12-24 00:30:09 +00:00
797f7eb6d6 Merge pull request 'Update Rust crate serde_json to v1.0.146' (#147) from renovate/serde_json-1.x-lockfile into master
Some checks failed
continuous-integration/drone/push Build is failing
2025-12-23 00:30:02 +00:00
71a1f3eb96 Merge pull request 'Update Rust crate reqwest to v0.12.28' (#146) from renovate/reqwest-0.x-lockfile into master
Some checks failed
continuous-integration/drone/push Build is failing
2025-12-23 00:29:51 +00:00
81cd6d0f29 Update Rust crate serde_json to v1.0.146
Some checks failed
continuous-integration/drone/push Build is failing
continuous-integration/drone/pr Build is failing
2025-12-23 00:29:50 +00:00
beb1a14f42 Update Rust crate reqwest to v0.12.28
Some checks failed
continuous-integration/drone/push Build is failing
continuous-integration/drone/pr Build is failing
2025-12-23 00:29:45 +00:00
1ca0556673 Merge pull request 'Update Rust crate bincode to v3' (#145) from renovate/bincode-3.x into master
Some checks failed
continuous-integration/drone/push Build is failing
2025-12-17 00:30:15 +00:00
5c7e8b0c44 Update Rust crate bincode to v3
Some checks failed
continuous-integration/drone/push Build is failing
continuous-integration/drone/pr Build is failing
2025-12-17 00:30:12 +00:00
8338f03b84 Merge pull request 'Update Rust crate reqwest to v0.12.26' (#144) from renovate/reqwest-0.x-lockfile into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-12-16 00:30:13 +00:00
7c1ef45729 Update Rust crate reqwest to v0.12.26
Some checks failed
continuous-integration/drone/push Build is failing
continuous-integration/drone/pr Build is passing
2025-12-16 00:30:07 +00:00
e4571bda48 Merge pull request 'Update Rust crate reqwest to v0.12.25' (#143) from renovate/reqwest-0.x-lockfile into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-12-09 00:30:29 +00:00
5b6235392b Update Rust crate reqwest to v0.12.25
Some checks failed
continuous-integration/drone/push Build is failing
continuous-integration/drone/pr Build is passing
2025-12-09 00:30:24 +00:00
fbe38bac30 Merge pull request 'Update Rust crate log to v0.4.29' (#142) from renovate/log-0.x-lockfile into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-12-03 00:15:01 +00:00
c30fa97066 Update Rust crate log to v0.4.29
Some checks failed
continuous-integration/drone/push Build is failing
continuous-integration/drone/pr Build is passing
2025-12-03 00:14:56 +00:00
00ae093958 Merge pull request 'Update Rust crate reqwest to v0.12.24' (#141) from renovate/reqwest-0.x-lockfile into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-10-14 00:37:48 +00:00
0dc185059f Update Rust crate reqwest to v0.12.24
Some checks failed
continuous-integration/drone/push Build is failing
continuous-integration/drone/pr Build is passing
2025-10-14 00:37:43 +00:00
8a17ca3f42 Merge pull request 'Update Rust crate serde to v1.0.228' (#140) from renovate/serde-1.x-lockfile into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-09-28 00:34:58 +00:00
2afb24c4ac Update Rust crate serde to v1.0.228
Some checks failed
continuous-integration/drone/push Build is failing
continuous-integration/drone/pr Build is passing
2025-09-28 00:34:51 +00:00
d0f973a26d Merge pull request 'Update Rust crate serde to v1.0.227' (#139) from renovate/serde-1.x-lockfile into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-09-26 00:35:02 +00:00
556b5aab7d Update Rust crate serde to v1.0.227
Some checks failed
continuous-integration/drone/push Build is failing
continuous-integration/drone/pr Build is passing
2025-09-26 00:34:55 +00:00
380a033e30 Merge pull request 'Update Rust crate serde to v1.0.226' (#138) from renovate/serde-1.x-lockfile into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-09-21 00:40:02 +00:00
6f6b4e7e1e Update Rust crate serde to v1.0.226
Some checks failed
continuous-integration/drone/push Build is failing
continuous-integration/drone/pr Build is passing
2025-09-21 00:39:56 +00:00
7a5af8d60c Merge pull request 'Update Rust crate serde to v1.0.225' (#137) from renovate/serde-1.x-lockfile into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-09-17 00:35:12 +00:00
2a0f757fee Update Rust crate serde to v1.0.225
Some checks failed
continuous-integration/drone/push Build is failing
continuous-integration/drone/pr Build is passing
2025-09-17 00:35:06 +00:00
e0ff7b1b21 Merge pull request 'Update Rust crate serde to v1.0.224' (#136) from renovate/serde-1.x-lockfile into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-09-16 00:35:12 +00:00
8aaee8da13 Update Rust crate serde to v1.0.224
Some checks failed
continuous-integration/drone/push Build is failing
continuous-integration/drone/pr Build is passing
2025-09-16 00:35:06 +00:00
6403d238a5 Merge pull request 'Update Rust crate serde_json to v1.0.145' (#135) from renovate/serde_json-1.x-lockfile into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-09-15 00:35:41 +00:00
31cd9d5a21 Merge pull request 'Update Rust crate serde to v1.0.223' (#134) from renovate/serde-1.x-lockfile into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-09-15 00:35:38 +00:00
20646f0627 Update Rust crate serde_json to v1.0.145
Some checks failed
continuous-integration/drone/push Build is failing
continuous-integration/drone/pr Build is passing
2025-09-15 00:35:37 +00:00
85a8bb01e8 Update Rust crate serde to v1.0.223
Some checks failed
continuous-integration/drone/push Build is failing
continuous-integration/drone/pr Build is passing
2025-09-15 00:35:32 +00:00
d3d4e3d236 Merge pull request 'Update Rust crate serde_json to v1.0.144' (#133) from renovate/serde_json-1.x-lockfile into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-09-14 00:36:01 +00:00
8f757bcdef Merge pull request 'Update Rust crate serde to v1.0.221' (#132) from renovate/serde-1.x-lockfile into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-09-14 00:35:56 +00:00
eabff0a4aa Update Rust crate serde_json to v1.0.144
Some checks failed
continuous-integration/drone/push Build is failing
continuous-integration/drone/pr Build is passing
2025-09-14 00:35:56 +00:00
86859119ae Update Rust crate serde to v1.0.221
Some checks failed
continuous-integration/drone/push Build is failing
continuous-integration/drone/pr Build is passing
2025-09-14 00:35:51 +00:00
3fe2238be0 Merge pull request 'Update Rust crate log to v0.4.28' (#131) from renovate/log-0.x-lockfile into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-09-04 00:28:21 +00:00
b94ffeb570 Update Rust crate log to v0.4.28
Some checks failed
continuous-integration/drone/push Build is failing
continuous-integration/drone/pr Build is passing
2025-09-04 00:28:16 +00:00
e91701159a Merge pull request 'Update Rust crate serde_json to v1.0.143' (#130) from renovate/serde_json-1.x-lockfile into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-08-20 00:27:16 +00:00
491d845e30 Update Rust crate serde_json to v1.0.143
Some checks failed
continuous-integration/drone/push Build is failing
continuous-integration/drone/pr Build is passing
2025-08-20 00:27:12 +00:00
7c37d2e129 Merge pull request 'Update Rust crate reqwest to v0.12.23' (#129) from renovate/reqwest-0.x-lockfile into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-08-13 00:27:19 +00:00
dd5c4f35cf Update Rust crate reqwest to v0.12.23
Some checks failed
continuous-integration/drone/push Build is failing
continuous-integration/drone/pr Build is passing
2025-08-13 00:27:15 +00:00
d7aebe76cc Merge pull request 'Update Rust crate serde_json to v1.0.142' (#128) from renovate/serde_json-1.x-lockfile into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-08-01 00:18:17 +00:00
72f99fbd7c Update Rust crate serde_json to v1.0.142
Some checks failed
continuous-integration/drone/push Build is failing
continuous-integration/drone/pr Build is passing
2025-08-01 00:18:12 +00:00
932239bfa0 Merge pull request 'Update Rust crate rand to v0.9.2' (#127) from renovate/rand-0.x-lockfile into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-07-21 00:15:44 +00:00
396467ca05 Update Rust crate rand to v0.9.2
Some checks failed
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is failing
2025-07-21 00:15:42 +00:00
7 changed files with 1106 additions and 587 deletions

1571
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
[package]
name = "light-openid"
version = "1.0.4"
version = "1.1.0"
edition = "2021"
repository = "https://gitea.communiquons.org/pierre/light-openid"
authors = ["Pierre HUBERT <pierre.git@communiquons.org>"]
@@ -12,16 +12,17 @@ license = "GPL-2.0-or-later"
[dependencies]
log = "0.4.21"
reqwest = { version = "0.12.14", features = ["json"] }
reqwest = { version = "0.13.0", features = ["json", "form"] }
base64 = "0.22.0"
serde = { version = "1.0.198", features = ["derive"] }
serde_json = "1.0.115"
urlencoding = "2.1.3"
thiserror = "2"
# Dependencies for crypto wrapper
bincode = { version = "2.0.0-rc.3", optional = true }
rkyv = { version = "0.8.12", optional = true }
aes-gcm = { version = "0.10.3", optional = true }
rand = { version = "0.9.0", optional = true }
rand = { version = "0.10.0", optional = true }
[features]
crypto-wrapper = ["bincode", "aes-gcm", "rand"]
crypto-wrapper = ["rkyv", "aes-gcm", "rand"]

View File

@@ -6,15 +6,13 @@
//! address of the client in an encrypted way, and expires 15
//! minutes after issuance.
use std::error::Error;
use std::fmt;
use crate::crypto_wrapper::CryptoWrapper;
use crate::errors::OpenIdError;
use crate::time_utils::time;
use bincode::{Decode, Encode};
use crate::Res;
use std::net::IpAddr;
#[derive(Encode, Decode, Debug)]
#[derive(Debug, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
struct State {
ip: IpAddr,
expire: u64,
@@ -29,27 +27,13 @@ impl State {
}
}
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
enum StateError {
InvalidIp,
Expired,
}
impl Error for StateError {}
impl fmt::Display for StateError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "StateManager error {self:?}")
}
}
/// Basic state manager. Can be used to prevent CRSF by encrypting
/// a token containing a lifetime and the IP address of the user
pub struct BasicStateManager(CryptoWrapper);
impl BasicStateManager {
/// Initialize the state manager by creating a random encryption key. This function
/// should be called only one, ideally in the main function of the application
/// should be called only once, ideally in the main function of the application
pub fn new() -> Self {
Self(CryptoWrapper::new_random())
}
@@ -60,22 +44,22 @@ impl BasicStateManager {
}
/// Generate a new state
pub fn gen_state(&self, ip: IpAddr) -> Result<String, Box<dyn Error>> {
pub fn gen_state(&self, ip: IpAddr) -> Res<String> {
let state = State::new(ip);
self.0.encrypt(&state)
}
/// Validate given state on callback URL
pub fn validate_state(&self, ip: IpAddr, state: &str) -> Result<(), Box<dyn Error>> {
pub fn validate_state(&self, ip: IpAddr, state: &str) -> Res {
let state: State = self.0.decrypt(state)?;
if state.ip != ip {
return Err(Box::new(StateError::InvalidIp));
return Err(OpenIdError::StateErrorInvalidIP);
}
if state.expire < time() {
return Err(Box::new(StateError::Expired));
return Err(OpenIdError::StateErrorExpired);
}
Ok(())

View File

@@ -3,13 +3,13 @@
use base64::engine::general_purpose::STANDARD as BASE64_STANDARD;
use base64::Engine;
use std::collections::HashMap;
use std::error::Error;
use crate::primitives::{OpenIDConfig, OpenIDTokenResponse, OpenIDUserInfo};
use crate::Res;
impl OpenIDConfig {
/// Load OpenID configuration from a given .well-known/openid-configuration URL
pub async fn load_from_url(url: &str) -> Result<Self, Box<dyn Error>> {
pub async fn load_from_url(url: &str) -> Res<Self> {
Ok(reqwest::get(url).await?.json().await?)
}
@@ -37,7 +37,7 @@ impl OpenIDConfig {
client_secret: &str,
code: &str,
redirect_uri: &str,
) -> Result<(OpenIDTokenResponse, String), Box<dyn Error>> {
) -> Res<(OpenIDTokenResponse, String)> {
let authorization = BASE64_STANDARD.encode(format!("{client_id}:{client_secret}"));
let mut params = HashMap::new();
@@ -66,7 +66,7 @@ impl OpenIDConfig {
pub async fn request_user_info(
&self,
token: &OpenIDTokenResponse,
) -> Result<(OpenIDUserInfo, String), Box<dyn Error>> {
) -> Res<(OpenIDUserInfo, String)> {
let response = reqwest::Client::new()
.get(self.userinfo_endpoint.as_ref().expect(
"This client only support information retrieval through userinfo endpoint!",

View File

@@ -1,16 +1,23 @@
use crate::errors::OpenIdError;
use crate::Res;
use aes_gcm::aead::{Aead, OsRng};
use aes_gcm::{Aes256Gcm, Key, KeyInit, Nonce};
use base64::engine::general_purpose::STANDARD as BASE64_STANDARD;
use base64::Engine as _;
use bincode::{Decode, Encode};
use rand::Rng;
use std::error::Error;
use rkyv::api::high::{HighSerializer, HighValidator};
use rkyv::bytecheck::CheckBytes;
use rkyv::de::Pool;
use rkyv::rancor::Strategy;
use rkyv::ser::allocator::ArenaHandle;
use rkyv::util::AlignedVec;
use rkyv::{Archive, Deserialize, Serialize};
/// The lenght of the nonce used to initialize encryption
/// The length of the nonce used to initialize encryption
const NONCE_LEN: usize = 12;
/// CryptoWrapper is a library that can be used to encrypt and decrypt some data marked
/// that derives [Encode] and [Decode] traits using AES encryption
/// that derives [SchemaWrite] and [SchemaRead] traits using AES encryption
pub struct CryptoWrapper {
key: Key<Aes256Gcm>,
}
@@ -24,11 +31,14 @@ impl CryptoWrapper {
}
/// Encrypt some data, returning the result as a base64-encoded string
pub fn encrypt<T: Encode + Decode<()>>(&self, data: &T) -> Result<String, Box<dyn Error>> {
pub fn encrypt(
&self,
data: &impl for<'a> Serialize<HighSerializer<AlignedVec, ArenaHandle<'a>, rkyv::rancor::Error>>,
) -> Res<String> {
let aes_key = Aes256Gcm::new(&self.key);
let nonce_bytes = rand::rng().random::<[u8; NONCE_LEN]>();
let serialized_data = bincode::encode_to_vec(data, bincode::config::standard())?;
let serialized_data = rkyv::to_bytes(data)?;
let mut enc = aes_key
.encrypt(Nonce::from_slice(&nonce_bytes), serialized_data.as_slice())
@@ -39,13 +49,16 @@ impl CryptoWrapper {
}
/// Decrypt some data previously encrypted using the [`CryptoWrapper::encrypt`] method
pub fn decrypt<T: Decode<()>>(&self, input: &str) -> Result<T, Box<dyn Error>> {
pub fn decrypt<T>(&self, input: &str) -> Res<T>
where
T: Archive,
T::Archived: for<'a> CheckBytes<HighValidator<'a, rkyv::rancor::Error>>
+ Deserialize<T, Strategy<Pool, rkyv::rancor::Error>>,
{
let bytes = BASE64_STANDARD.decode(input)?;
if bytes.len() < NONCE_LEN {
return Err(Box::new(std::io::Error::other(
"Input string is smaller than nonce!",
)));
return Err(OpenIdError::DecInputStringSmallerThanNonce);
}
let (enc, nonce) = bytes.split_at(bytes.len() - NONCE_LEN);
@@ -57,22 +70,19 @@ impl CryptoWrapper {
Ok(d) => d,
Err(e) => {
log::error!("Failed to decrypt wrapped data! {e:#?}");
return Err(Box::new(std::io::Error::other(
"Failed to decrypt wrapped data!",
)));
return Err(OpenIdError::DecryptWrappedData);
}
};
Ok(bincode::decode_from_slice(&dec, bincode::config::standard())?.0)
Ok(rkyv::from_bytes(&dec)?)
}
}
#[cfg(test)]
mod test {
use crate::crypto_wrapper::CryptoWrapper;
use bincode::{Decode, Encode};
#[derive(Encode, Decode, Eq, PartialEq, Debug)]
#[derive(Eq, PartialEq, Debug, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
struct Message(String);
#[test]

24
src/errors.rs Normal file
View File

@@ -0,0 +1,24 @@
#[derive(thiserror::Error, Debug)]
pub enum OpenIdError {
#[error("Reqwest error: {0}")]
Reqwest(#[from] reqwest::Error),
#[error("Serde json error: {0}")]
SerdeJson(#[from] serde_json::Error),
#[error("Base64 decoding error: {0}")]
Base64Decode(#[from] base64::DecodeError),
#[cfg(feature = "crypto-wrapper")]
#[error("State error: invalid IP")]
StateErrorInvalidIP,
#[cfg(feature = "crypto-wrapper")]
#[error("State error: expired")]
StateErrorExpired,
#[cfg(feature = "crypto-wrapper")]
#[error("Rkyv error: {0}")]
RkyvError(#[from] rkyv::rancor::Error),
#[cfg(feature = "crypto-wrapper")]
#[error("Input string is smaller than nonce!")]
DecInputStringSmallerThanNonce,
#[cfg(feature = "crypto-wrapper")]
#[error("Failed to decrypt wrapped data!")]
DecryptWrappedData,
}

View File

@@ -4,9 +4,14 @@
//!
//! See https://gitea.communiquons.org/pierre/oidc-test-client for an example of usage of this library
use crate::errors::OpenIdError;
pub mod client;
pub mod errors;
pub mod primitives;
pub type Res<T = ()> = Result<T, OpenIdError>;
#[cfg(feature = "crypto-wrapper")]
mod time_utils;