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

//! # Public Key
//!
//! This module provides utilities for handling PEM-formatted public keys
//! and converting between different PEM formats for JWT signature validation.

use pdk_core::logger::error;
use pem::{parse, Pem};

const PUBLIC_KEY_PKCS1_HEADER: &str = "-----BEGIN RSA PUBLIC KEY-----";
const PUBLIC_KEY_ECDSA_HEADER: &str = "-----BEGIN ECDSA PUBLIC KEY-----";
const PUBLIC_KEY_PKCS8_HEADER: &str = "-----BEGIN PUBLIC KEY-----";
const PUBLIC_KEY_PKCS8_FOOTER: &str = "-----END PUBLIC KEY-----";

/// Trait to convert PEM-like strings to [`Pem`].
pub trait PemLike {
    fn has_pkcs1_header(&self) -> bool;
    fn has_ecdsa_header(&self) -> bool;
    fn has_pkcs8_header(&self) -> bool;
    fn complete_to_pkcs8_pem(&mut self);
    fn encoded_pem(&self) -> Option<Pem>;
}

impl PemLike for String {
    fn has_pkcs1_header(&self) -> bool {
        self.trim().starts_with(PUBLIC_KEY_PKCS1_HEADER)
    }

    fn has_ecdsa_header(&self) -> bool {
        self.trim().starts_with(PUBLIC_KEY_ECDSA_HEADER)
    }

    fn has_pkcs8_header(&self) -> bool {
        self.trim().starts_with(PUBLIC_KEY_PKCS8_HEADER)
    }

    fn complete_to_pkcs8_pem(&mut self) {
        let mut buffer = String::from(PUBLIC_KEY_PKCS8_HEADER);
        buffer.extend(self.trim().split(' '));
        buffer.push_str(PUBLIC_KEY_PKCS8_FOOTER);

        *self = buffer;
    }

    fn encoded_pem(&self) -> Option<Pem> {
        match parse(self) {
            Ok(pem) => Some(pem),
            Err(e) => {
                error!("Error generating PEM {e:?}");
                None
            }
        }
    }
}