pdk-jwt-lib 1.10.0

PDK JWT Library
Documentation
// Copyright (c) 2026, Salesforce, Inc.,
// All rights reserved.
// For full license text, see the LICENSE.txt file

//! JWT signing algorithms and key lengths
//!
//! This module defines the supported JWT signing algorithms and their corresponding
//! key lengths. It provides type-safe representations for algorithm selection
//! and key length validation.
//!

use serde::Deserialize;
use std::convert::TryFrom;

use crate::error::jwt_error::JWTError;

/// List of possible JWT signing key lengths.
/// __Note: not all algorithms support all key lengths__
#[derive(Debug, Deserialize, Clone, Eq, PartialEq, Copy)]
#[serde(try_from = "&str")]
pub enum SigningKeyLength {
    Len256,
    Len384,
    Len512,
}

impl TryFrom<&str> for SigningKeyLength {
    type Error = JWTError;

    fn try_from(value: &str) -> Result<Self, Self::Error> {
        match value {
            "256" => Ok(SigningKeyLength::Len256),
            "384" => Ok(SigningKeyLength::Len384),
            "512" => Ok(SigningKeyLength::Len512),
            _ => Err(JWTError::SigningKeyLengthParseFailed),
        }
    }
}

/// List of possible JWT signing algorithms.
/// __See [JWT signing algorithms specification (RFC 7518)](https://datatracker.ietf.org/doc/html/rfc7518#section-3.1)__
#[derive(Debug, Deserialize, Clone, Copy, Eq, PartialEq)]
#[serde(try_from = "&str")]
pub enum SigningAlgorithm {
    /// RSA signing algorithm. Requires verifying key to validate tokens. Supports key lengths 256, 384 and 512
    Rsa,
    /// HMAC with SHA-2 signing algorithm. Requires signing secret key to validate tokens. Supports key lengths 256, 384 and 512
    #[cfg(not(any(feature = "fips", fips)))]
    Hmac,
    /// ECDSA signing algorithm. Requires verifying key to validate tokens. Supports key lengths 256 and 384
    Es,
}

impl TryFrom<&str> for SigningAlgorithm {
    type Error = JWTError;

    fn try_from(value: &str) -> Result<Self, Self::Error> {
        match value {
            "rsa" => Ok(SigningAlgorithm::Rsa),
            #[cfg(not(any(feature = "fips", fips)))]
            "hmac" => Ok(SigningAlgorithm::Hmac),
            "es" => Ok(SigningAlgorithm::Es),
            _ => Err(JWTError::SigningAlgorithmParseFailed),
        }
    }
}

#[cfg(test)]
mod test {
    use super::{SigningAlgorithm, SigningKeyLength};
    use crate::api::error::JWTError;
    use std::convert::TryFrom;

    #[test]
    fn try_from_algorithm() {
        #[cfg(not(any(feature = "fips", fips)))]
        assert_eq!(
            SigningAlgorithm::try_from("hmac").unwrap(),
            SigningAlgorithm::Hmac
        );
        assert_eq!(
            SigningAlgorithm::try_from("rsa").unwrap(),
            SigningAlgorithm::Rsa
        );
        assert_eq!(
            SigningAlgorithm::try_from("es").unwrap(),
            SigningAlgorithm::Es
        );
        assert_eq!(
            SigningAlgorithm::try_from("HMAC").unwrap_err(),
            JWTError::SigningAlgorithmParseFailed
        );
    }

    #[test]
    fn try_from_length() {
        assert_eq!(
            SigningKeyLength::try_from("256").unwrap(),
            SigningKeyLength::Len256
        );
        assert_eq!(
            SigningKeyLength::try_from("384").unwrap(),
            SigningKeyLength::Len384
        );
        assert_eq!(
            SigningKeyLength::try_from("512").unwrap(),
            SigningKeyLength::Len512
        );
        assert_eq!(
            SigningKeyLength::try_from("257").unwrap_err(),
            JWTError::SigningKeyLengthParseFailed
        );
    }
}