Skip to main content

authly_core/
pkce.rs

1use base64::{engine::general_purpose::URL_SAFE_NO_PAD, Engine as _};
2use rand::{distr::Alphanumeric, rng, Rng};
3use sha2::{Digest, Sha256};
4
5/// Proof Key for Code Exchange (PKCE) parameters.
6#[derive(Debug, Clone)]
7pub struct Pkce {
8    /// High-entropy cryptographic random string
9    pub code_verifier: String,
10    /// BASE64URL-ENCODE(SHA256(ASCII(code_verifier)))
11    pub code_challenge: String,
12}
13
14impl Pkce {
15    /// Generates a new PKCE verifier and challenge.
16    pub fn new() -> Self {
17        let code_verifier: String = rng()
18            .sample_iter(&Alphanumeric)
19            .take(64)
20            .map(char::from)
21            .collect();
22
23        let mut hasher = Sha256::new();
24        hasher.update(code_verifier.as_bytes());
25        let hash = hasher.finalize();
26
27        let code_challenge = URL_SAFE_NO_PAD.encode(hash);
28
29        Self {
30            code_verifier,
31            code_challenge,
32        }
33    }
34}
35
36impl Default for Pkce {
37    fn default() -> Self {
38        Self::new()
39    }
40}