From cf7b821a18cb28f859ee97ac7f43c70ef51ca774 Mon Sep 17 00:00:00 2001 From: Jeidnx Date: Fri, 9 Feb 2024 13:28:36 +0100 Subject: [PATCH] feat: allow signing without kid Added an option to all implementors of JwsSigner to disable adding the KID in the JWS header --- src/crypto/es256.rs | 15 ++++++++++++++- src/crypto/hs256.rs | 25 ++++++++++++++++++++++--- src/crypto/ms_oapxbc.rs | 6 ++++++ src/crypto/rs256.rs | 14 +++++++++++++- src/traits.rs | 3 +++ 5 files changed, 58 insertions(+), 5 deletions(-) diff --git a/src/crypto/es256.rs b/src/crypto/es256.rs index ffd1c7e..76f8098 100644 --- a/src/crypto/es256.rs +++ b/src/crypto/es256.rs @@ -19,6 +19,8 @@ use crate::traits::*; pub struct JwsEs256Signer { /// If the public jwk should be embeded during signing sign_option_embed_jwk: bool, + /// If the KID should be embedded during singing + sign_option_embed_kid: bool, /// The KID of this validator kid: String, /// Private Key @@ -115,6 +117,7 @@ impl JwsEs256Signer { skey, digest, sign_option_embed_jwk: false, + sign_option_embed_kid: true, }) } @@ -146,6 +149,7 @@ impl JwsEs256Signer { skey, digest, sign_option_embed_jwk: false, + sign_option_embed_kid: true, }) } @@ -168,6 +172,7 @@ impl JwsEs256Signer { skey, digest, sign_option_embed_jwk: false, + sign_option_embed_kid: true, }) } @@ -258,7 +263,8 @@ impl JwsSigner for JwsEs256Signer { // Update the alg to match. header.alg = JwaAlg::ES256; - header.kid = Some(self.kid.clone()); + // If the signer is configured to include the KID + header.kid = self.sign_option_embed_kid.then(|| self.kid.clone()); // if were were asked to ember the jwk, do so now. if self.sign_option_embed_jwk { @@ -330,6 +336,13 @@ impl JwsSigner for JwsEs256Signer { jws.post_process(jwsc) } + + fn set_sign_option_embed_kid(&self, value: bool) -> Self { + JwsEs256Signer { + sign_option_embed_kid: value, + ..self.to_owned() + } + } } /// A JWS verifier that verifies ECDSA P-256 signatures. diff --git a/src/crypto/hs256.rs b/src/crypto/hs256.rs index 305db77..10263bf 100644 --- a/src/crypto/hs256.rs +++ b/src/crypto/hs256.rs @@ -14,6 +14,8 @@ use base64::{engine::general_purpose, Engine as _}; /// A JWS signer that creates HMAC SHA256 signatures. #[derive(Clone)] pub struct JwsHs256Signer { + /// If the KID should be embedded during signing + sign_option_embed_kid: bool, /// The KID of this signer. This is the sha256 digest of the key. kid: String, /// Private Key @@ -74,7 +76,12 @@ impl JwsHs256Signer { }) .map_err(|_| JwtError::OpenSSLError)?; - Ok(JwsHs256Signer { kid, skey, digest }) + Ok(JwsHs256Signer { + kid, + skey, + digest, + sign_option_embed_kid: true, + }) } pub(crate) fn sign_inner( @@ -138,7 +145,12 @@ impl TryFrom<&[u8]> for JwsHs256Signer { JwtError::OpenSSLError })?; - Ok(JwsHs256Signer { kid, skey, digest }) + Ok(JwsHs256Signer { + kid, + skey, + digest, + sign_option_embed_kid: true, + }) } } @@ -151,7 +163,8 @@ impl JwsSigner for JwsHs256Signer { // Update the alg to match. header.alg = JwaAlg::HS256; - header.kid = Some(self.kid.clone()); + // If the signer is configured to include the KID + header.kid = self.sign_option_embed_kid.then(|| self.kid.clone()); Ok(()) } @@ -164,6 +177,12 @@ impl JwsSigner for JwsHs256Signer { self.sign_inner(jws, sign_data) } + fn set_sign_option_embed_kid(&self, value: bool) -> Self { + JwsHs256Signer { + sign_option_embed_kid: value, + ..self.to_owned() + } + } } impl JwsVerifier for JwsHs256Signer { diff --git a/src/crypto/ms_oapxbc.rs b/src/crypto/ms_oapxbc.rs index ee3dfbd..be23eae 100644 --- a/src/crypto/ms_oapxbc.rs +++ b/src/crypto/ms_oapxbc.rs @@ -258,6 +258,12 @@ impl JwsSigner for MsOapxbcSessionKeyHs256 { self.hmac_key.sign_inner(jws, sign_data) } + fn set_sign_option_embed_kid(&self, value: bool) -> Self { + MsOapxbcSessionKeyHs256 { + hmac_key: self.hmac_key.set_sign_option_embed_kid(value), + nonce: self.nonce, + } + } } pub(crate) fn nist_sp800_108_kdf_hmac_sha256( diff --git a/src/crypto/rs256.rs b/src/crypto/rs256.rs index 95ed7a8..6d59517 100644 --- a/src/crypto/rs256.rs +++ b/src/crypto/rs256.rs @@ -21,6 +21,8 @@ const RSA_SIG_SIZE: i32 = 384; pub struct JwsRs256Signer { /// If the public jwk should be embeded during signing sign_option_embed_jwk: bool, + /// If the KID should be embedded during signing + sign_option_embed_kid: bool, /// The KID of this validator kid: String, /// Private Key @@ -78,6 +80,7 @@ impl JwsRs256Signer { skey, digest, sign_option_embed_jwk: false, + sign_option_embed_kid: true, }) } @@ -108,6 +111,7 @@ impl JwsRs256Signer { skey, digest, sign_option_embed_jwk: false, + sign_option_embed_kid: true, }) } @@ -164,7 +168,8 @@ impl JwsSigner for JwsRs256Signer { // Update the alg to match. header.alg = JwaAlg::RS256; - header.kid = Some(self.kid.clone()); + // If the signer is configured to include the KID + header.kid = self.sign_option_embed_kid.then(|| self.kid.clone()); // if were were asked to ember the jwk, do so now. if self.sign_option_embed_jwk { @@ -225,6 +230,13 @@ impl JwsSigner for JwsRs256Signer { jws.post_process(jwsc) } + + fn set_sign_option_embed_kid(&self, value: bool) -> Self { + JwsRs256Signer { + sign_option_embed_kid: value, + ..self.to_owned() + } + } } /// A JWS verifier that verifies RSA SHA256 signatures. diff --git a/src/traits.rs b/src/traits.rs index 6adfaf9..450918a 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -18,6 +18,9 @@ pub trait JwsSigner { /// Perform the signature operation fn sign(&self, _jws: &V) -> Result; + + /// Enable or disable embedding the KID in the Jws header + fn set_sign_option_embed_kid(&self, value: bool) -> Self; } /// A trait defining how a JwsSigner will operate.