Skip to content

Commit

Permalink
add pkce verifier
Browse files Browse the repository at this point in the history
  • Loading branch information
aumetra committed Dec 13, 2024
1 parent 29d61d6 commit 11f1958
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 3 deletions.
3 changes: 3 additions & 0 deletions Cargo.lock

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

3 changes: 3 additions & 0 deletions lib/komainu/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,16 @@ version.workspace = true
license = "MIT OR Apache-2.0"

[dependencies]
base64-simd.workspace = true
bytes.workspace = true
headers.workspace = true
http.workspace = true
serde.workspace = true
serde_urlencoded.workspace = true
sha2.workspace = true
sonic-rs.workspace = true
strum.workspace = true
subtle.workspace = true
thiserror.workspace = true
tracing.workspace = true
url.workspace = true
Expand Down
9 changes: 8 additions & 1 deletion lib/komainu/src/flow/authorization.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
use super::TokenResponse;
use super::{PkcePayload, TokenResponse};
use crate::{error::Result, params::ParamStorage, Client, ClientExtractor, Error, OptionExt};
use bytes::Bytes;
use headers::HeaderMapExt;
use std::future::Future;

pub struct Authorization<'a> {
pub client: Client<'a>,
pub pkce: PkcePayload<'a>,
}

pub trait Issuer {
fn load_authorization(&self, );

fn issue_token(
&self,
client: &Client<'_>,
Expand Down
57 changes: 56 additions & 1 deletion lib/komainu/src/flow/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
use serde::Serialize;
use crate::{Error, Result};
use serde::{Deserialize, Serialize};
use sha2::{Digest, Sha256};
use std::borrow::Cow;
use strum::{AsRefStr, EnumString};
use subtle::ConstantTimeEq;

pub mod authorization;
pub mod refresh;
Expand All @@ -18,3 +22,54 @@ pub struct TokenResponse<'a> {
pub refresh_token: Cow<'a, str>,
pub expires_in: u64,
}

#[derive(AsRefStr, Deserialize, EnumString, Serialize)]
#[strum(serialize_all = "snake_case")]
pub enum PkceMethod {
None,
#[strum(serialize = "S256")]
S256,
}

#[derive(Deserialize, Serialize)]
pub struct PkcePayload<'a> {
pub challenge: Cow<'a, str>,
pub method: PkceMethod,
}

impl PkcePayload<'_> {
#[inline]
fn verify_s256(&self, code_verifier: &str) -> Result<()> {
let decoded = base64_simd::URL_SAFE
.decode_to_vec(code_verifier)
.inspect_err(|error| debug!(?error, "failed to decode pkce payload"))
.map_err(Error::body)?;

let hash = Sha256::digest(code_verifier);

if decoded.ct_eq(hash.as_slice()).into() {
Ok(())
} else {
Err(Error::Unauthorized)
}
}

#[inline]
fn verify_none(&self, code_verifier: &str) -> Result<()> {
let challenge_bytes = self.challenge.as_bytes();

if challenge_bytes.ct_eq(code_verifier.as_bytes()).into() {
Ok(())
} else {
Err(Error::Unauthorized)
}
}

#[inline]
pub fn verify(&self, code_verifier: &str) -> Result<()> {
match self.method {
PkceMethod::None => self.verify_none(code_verifier),
PkceMethod::S256 => self.verify_s256(code_verifier),
}
}
}
2 changes: 1 addition & 1 deletion lib/komainu/src/flow/refresh.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use super::TokenResponse;
use crate::{
error::{Error, Result},
Client, ClientExtractor, OptionExt,
params::ParamStorage,
Client, ClientExtractor, OptionExt,
};
use bytes::Bytes;
use headers::HeaderMapExt;
Expand Down

0 comments on commit 11f1958

Please sign in to comment.