use base64::Engine;
use base64::engine::general_purpose::URL_SAFE_NO_PAD;
use elliptic_curve::SecretKey;
use jose_jwk::{Key, crypto};
use rand::{CryptoRng, RngCore, rngs::ThreadRng};
use std::cmp::Ordering;
pub fn generate_key(allowed_algos: &[String]) -> Option<Key> {
for alg in allowed_algos {
#[allow(clippy::single_match)]
match alg.as_str() {
"ES256" => {
return Some(Key::from(&crypto::Key::from(SecretKey::<p256::NistP256>::random(
&mut ThreadRng::default(),
))));
}
_ => {
}
}
}
None
}
pub fn generate_nonce() -> String {
URL_SAFE_NO_PAD.encode(get_random_values::<_, 16>(&mut ThreadRng::default()))
}
pub fn get_random_values<R, const LEN: usize>(rng: &mut R) -> [u8; LEN]
where
R: RngCore + CryptoRng,
{
let mut bytes = [0u8; LEN];
rng.fill_bytes(&mut bytes);
bytes
}
pub fn compare_algos(a: &String, b: &String) -> Ordering {
if a == "ES256K" {
return Ordering::Less;
}
if b == "ES256K" {
return Ordering::Greater;
}
for prefix in ["ES", "PS", "RS"] {
if let Some(stripped_a) = a.strip_prefix(prefix) {
if let Some(stripped_b) = b.strip_prefix(prefix) {
if let (Ok(len_a), Ok(len_b)) =
(stripped_a.parse::<u32>(), stripped_b.parse::<u32>())
{
return len_a.cmp(&len_b);
}
} else {
return Ordering::Less;
}
} else if b.starts_with(prefix) {
return Ordering::Greater;
}
}
Ordering::Equal
}