Skip to content

Commit

Permalink
Merge pull request #135 from sebadob/impl-dpop-basics
Browse files Browse the repository at this point in the history
Impl DPoP basics
  • Loading branch information
sebadob authored Nov 1, 2023
2 parents 7f08340 + cf8ab65 commit 803e312
Show file tree
Hide file tree
Showing 16 changed files with 1,002 additions and 105 deletions.
32 changes: 31 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions rauthy-common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ rand = { workspace = true }
rand_core = { workspace = true }
redhac = { workspace = true }
regex = { workspace = true }
reqwest = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
sqlx = { workspace = true }
Expand Down
11 changes: 10 additions & 1 deletion rauthy-common/src/constants.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::DbType;
use actix_web::http::Uri;
use lazy_static::lazy_static;
use regex::Regex;
use std::env;
Expand All @@ -12,6 +13,8 @@ pub const APPLICATION_JSON: &str = "application/json";

pub const TOKEN_API_KEY: &str = "API-Key";
pub const TOKEN_BEARER: &str = "Bearer";
pub const TOKEN_DPOP: &str = "DPoP";
pub const TOKEN_DPOP_NONCE: &str = "DPoP-nonce";
pub const COOKIE_SESSION: &str = "rauthy-session";
pub const COOKIE_MFA: &str = "rauthy-mfa";
pub const COOKIE_LOCALE: &str = "locale";
Expand Down Expand Up @@ -65,7 +68,6 @@ lazy_static! {
pub static ref HA_MODE: bool =
env::var("HA_MODE").map(|s| s.to_lowercase() == "true").unwrap_or(false);

pub static ref RE_ALG: Regex = Regex::new(r"^(RS256|RS384|RS512|EdDSA)$").unwrap();
pub static ref RE_ATTR: Regex = Regex::new(r"^[a-zA-Z0-9-_/]{2,32}$").unwrap();
pub static ref RE_ATTR_DESC: Regex = Regex::new(r"^[a-zA-Z0-9-_/\s]{0,128}$").unwrap();
pub static ref RE_ALNUM: Regex = Regex::new(r"^[a-zA-Z0-9]+$").unwrap();
Expand All @@ -86,6 +88,13 @@ lazy_static! {
pub static ref RE_MFA_CODE: Regex = Regex::new(r"^[a-zA-Z0-9]{48}$").unwrap();
pub static ref RE_URI: Regex = Regex::new(r"^[a-zA-Z0-9,.:/_\-&?=~#!$'()*+%]+$").unwrap();
pub static ref RE_USER_NAME: Regex = Regex::new(r"^[a-zA-Z0-9À-ÿ-\s]{2,32}$").unwrap();
pub static ref RE_TOKEN_68: Regex = Regex::new(r"^[a-zA-Z0-9-._~+/]+=*$").unwrap();

pub static ref DPOP_TOKEN_ENDPOINT: Uri = {
let pub_url = env::var("PUB_URL").expect("PUB_URL env var is not set");
let uri = format!("https://{}/auth/v1/oidc/token", pub_url);
Uri::from_str(&uri).unwrap()
};

pub static ref PROXY_MODE: bool = env::var("PROXY_MODE")
.unwrap_or_else(|_| String::from("false"))
Expand Down
22 changes: 22 additions & 0 deletions rauthy-common/src/error_response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ use crate::constants::{APPLICATION_JSON, HEADER_HTML, HEADER_RETRY_NOT_BEFORE};
use crate::utils::build_csp_header;
use actix_multipart::MultipartError;
use actix_web::error::BlockingError;
use actix_web::http::header::ToStrError;
use actix_web::http::StatusCode;
use actix_web::{HttpResponse, HttpResponseBuilder, ResponseError};
use css_color::ParseColorError;
use derive_more::Display;
use redhac::CacheError;
use serde::{Deserialize, Serialize};
use serde_json::Error;
use std::string::FromUtf8Error;
use time::OffsetDateTime;
use tracing::{debug, error};
Expand Down Expand Up @@ -250,3 +252,23 @@ impl From<validator::ValidationErrors> for ErrorResponse {
)
}
}

impl From<serde_json::Error> for ErrorResponse {
fn from(value: Error) -> Self {
ErrorResponse::new(
ErrorResponseType::BadRequest,
format!("Payload deserialization error: {:?}", value),
)
}
}
impl From<reqwest::header::ToStrError> for ErrorResponse {
fn from(value: ToStrError) -> Self {
ErrorResponse::new(
ErrorResponseType::BadRequest,
format!(
"Request headers contained non ASCII characters: {:?}",
value
),
)
}
}
18 changes: 16 additions & 2 deletions rauthy-common/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ use rand::distributions::Alphanumeric;
use rand::Rng;
use tracing::error;

const B64_URL_SAFE: engine::GeneralPurpose = general_purpose::URL_SAFE_NO_PAD;
const B64_URL_SAFE: engine::GeneralPurpose = general_purpose::URL_SAFE;
const B64_URL_SAFE_NO_PAD: engine::GeneralPurpose = general_purpose::URL_SAFE_NO_PAD;
const B64_STD: engine::GeneralPurpose = general_purpose::STANDARD;

pub fn build_csp_header(nonce: &str) -> (&str, String) {
Expand Down Expand Up @@ -118,6 +119,10 @@ pub fn base64_url_encode(input: &[u8]) -> String {
.collect()
}

pub fn base64_url_no_pad_encode(input: &[u8]) -> String {
B64_URL_SAFE_NO_PAD.encode(input)
}

pub fn base64_url_decode(b64: &str) -> Result<Vec<u8>, ErrorResponse> {
B64_URL_SAFE.decode(b64).map_err(|_| {
ErrorResponse::new(
Expand All @@ -127,6 +132,15 @@ pub fn base64_url_decode(b64: &str) -> Result<Vec<u8>, ErrorResponse> {
})
}

pub fn base64_url_no_pad_decode(b64: &str) -> Result<Vec<u8>, ErrorResponse> {
B64_URL_SAFE_NO_PAD.decode(b64).map_err(|_| {
ErrorResponse::new(
ErrorResponseType::BadRequest,
"B64 decoding error".to_string(),
)
})
}

pub fn new_store_id() -> String {
get_rand(24)
}
Expand All @@ -150,7 +164,7 @@ where
}
let body = body.unwrap();

let b64 = match B64_URL_SAFE.decode(body) {
let b64 = match B64_URL_SAFE_NO_PAD.decode(body) {
Ok(values) => values,
Err(err) => {
error!(
Expand Down
2 changes: 2 additions & 0 deletions rauthy-handlers/src/openapi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,8 @@ use utoipa::{openapi, OpenApi};
entity::clients::Client,
entity::colors::Colors,
entity::groups::Group,
entity::jwk::JwkKeyPairAlg,
entity::jwk::JwkKeyPairType,
entity::password::PasswordHashTime,
entity::password::PasswordHashTimes,
entity::roles::Role,
Expand Down
6 changes: 6 additions & 0 deletions rauthy-models/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,13 @@ chrono = { workspace = true }
css-color = { workspace = true }
derive_more = { workspace = true }
dotenvy = { workspace = true }
ed25519-compact = { version = "2.0.4", features = ["ed25519"] }
flume = { workspace = true }
futures-util = "0.3"
hex = { version = "0.4", features = ["serde"] }
hmac-sha256 = { version = "1.1.7", features = ["traits010"] }
hmac-sha512 = { version = "1.1.5", features = ["traits010", "sha384"] }
http-serde = "1.1.3"
jwt-simple = { workspace = true }
lettre = { version = "0.11", default-features = false, features = ["builder", "smtp-transport", "tokio1-rustls-tls", "tracing"] }
num_cpus = { workspace = true }
Expand Down Expand Up @@ -61,6 +65,8 @@ uuid = { version = "1", features = ["serde", "v4"] }
validator = { workspace = true }
webauthn-rs = { workspace = true }
webauthn-rs-proto = { workspace = true }
itertools = "0.11.0"
rsa = { version = "0.9.3", features = ["serde", "sha2"] }

[dev-dependencies]
pretty_assertions = "1"
Expand Down
17 changes: 7 additions & 10 deletions rauthy-models/src/entity/clients.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::app_state::{AppState, DbTxn};
use crate::entity::jwk::JwkKeyPairType;
use crate::entity::jwk::JwkKeyPairAlg;
use crate::entity::scopes::Scope;
use crate::entity::users::User;
use crate::request::NewClientRequest;
Expand Down Expand Up @@ -444,8 +444,8 @@ impl Client {
Ok((rnd, rnd_enc))
}

pub fn get_access_token_alg(&self) -> Result<JwkKeyPairType, ErrorResponse> {
JwkKeyPairType::from_str(self.access_token_alg.as_str())
pub fn get_access_token_alg(&self) -> Result<JwkKeyPairAlg, ErrorResponse> {
JwkKeyPairAlg::from_str(self.access_token_alg.as_str())
}

pub fn get_allowed_origins(&self) -> Option<Vec<String>> {
Expand Down Expand Up @@ -497,8 +497,8 @@ impl Client {
res
}

pub fn get_id_token_alg(&self) -> Result<JwkKeyPairType, ErrorResponse> {
JwkKeyPairType::from_str(self.id_token_alg.as_str())
pub fn get_id_token_alg(&self) -> Result<JwkKeyPairAlg, ErrorResponse> {
JwkKeyPairAlg::from_str(self.id_token_alg.as_str())
}

pub fn get_flows(&self) -> Vec<String> {
Expand Down Expand Up @@ -911,11 +911,8 @@ mod tests {
force_mfa: false,
};

assert_eq!(
client.get_access_token_alg().unwrap(),
JwkKeyPairType::EdDSA
);
assert_eq!(client.get_id_token_alg().unwrap(), JwkKeyPairType::RS256);
assert_eq!(client.get_access_token_alg().unwrap(), JwkKeyPairAlg::EdDSA);
assert_eq!(client.get_id_token_alg().unwrap(), JwkKeyPairAlg::RS256);

assert_eq!(
client.get_challenges(),
Expand Down
Loading

0 comments on commit 803e312

Please sign in to comment.