From c59825b2fd344e5d60ff45b07c02082a7f3c81d9 Mon Sep 17 00:00:00 2001 From: Ty Date: Sat, 29 Jul 2023 18:29:18 -0600 Subject: [PATCH] Adjust to new fingerprint algorithm --- crates/asp/Cargo.toml | 2 +- crates/asp/src/utils/jwk.rs | 39 ++++++++++++++++++++++++------------- 2 files changed, 27 insertions(+), 14 deletions(-) diff --git a/crates/asp/Cargo.toml b/crates/asp/Cargo.toml index d60ce66..9789acb 100644 --- a/crates/asp/Cargo.toml +++ b/crates/asp/Cargo.toml @@ -15,7 +15,7 @@ openssl = "0.10.55" reqwest = "0.11.18" serde = { version = "1.0.164", features = ["derive"] } serde-email = "2.0.0" -serde_json = "1.0.99" +serde_json = { version = "1.0.99", features = ["preserve_order"] } sha2 = "0.10.7" thiserror = "1.0.40" tokio = { version = "1.28.2", features = ["macros", "rt-multi-thread"] } diff --git a/crates/asp/src/utils/jwk.rs b/crates/asp/src/utils/jwk.rs index ffd349a..aba1413 100644 --- a/crates/asp/src/utils/jwk.rs +++ b/crates/asp/src/utils/jwk.rs @@ -1,5 +1,5 @@ use anyhow::{bail, Context}; -use data_encoding::{BASE32_NOPAD, BASE64URL_NOPAD, BASE64_NOPAD}; +use data_encoding::{BASE32_NOPAD, BASE64_NOPAD}; use josekit::{ jwe::JweHeader, jwe::{self, alg::aesgcmkw::AesgcmkwJweAlgorithm::A256gcmkw}, @@ -10,6 +10,7 @@ use josekit::{ jws::ES256, }; use openssl::pkey::PKey; +use serde_json::Map; use sha2::{Digest, Sha512}; pub trait JwtExt { @@ -22,18 +23,30 @@ pub trait JwtExt { impl JwtExt for Jwk { fn get_fingerprint(&self) -> anyhow::Result { - // Get the "x" value of the JWK - let fingerprint = self - .parameter("x") - .context(r#"Jwk "x" parameter was not present"#)?; - // Base64url decode the "x" value and use that as the public key value - let fingerprint = BASE64URL_NOPAD - .decode( - // The as_str() can be unwrapped safely because it is impossible to create a Jwk struct where the "x" value is not a string - fingerprint.as_str().unwrap().as_bytes(), - ) - .unwrap(); // The decode() can be unwrapped safely because it is impossible to create a Jwk struct where the "x" value is not base64url decodable - // Sha512 hash the public key + // Construct a JSON object with only the "crv", "kty", "x", and potentially "y" values + let fingerprint: String = { + let mut map = Map::new(); + map.insert( + "crv".to_string(), + self.curve() + .context("Key did not contain a 'crv' value")? + .into(), + ); + map.insert("kty".to_string(), self.key_type().into()); + map.insert( + "x".to_string(), + self.parameter("x") + .context("Key did not contain an 'x' value")? + .clone(), + ); + if let Some(y) = self.parameter("y") { + map.insert("y".to_string(), y.clone()); + } + + serde_json::to_string(&map) + .context("Unable to serialize key into ordered, minimal JSON")? + }; + // Sha512 hash the JSON let fingerprint: Vec = { let mut hash = Sha512::new(); hash.update(fingerprint);