diff --git a/config/config.example.toml b/config/config.example.toml index 56d4500cba..962b9293b9 100644 --- a/config/config.example.toml +++ b/config/config.example.toml @@ -88,6 +88,7 @@ host = "" # Locker host mock_locker = true # Emulate a locker locally using Postgres basilisk_host = "" # Basilisk host locker_setup = "legacy_locker" # With locker to use while in the deployed environment (eg. legacy_locker, basilisk_locker) +locker_signing_key_id = "1" # Key_id to sign basilisk hs locker [jwekey] # 4 priv/pub key pair locker_key_identifier1 = "" # key identifier for key rotation , should be same as basilisk diff --git a/crates/router/src/configs/defaults.rs b/crates/router/src/configs/defaults.rs index 4b48d4292e..cf4829a7ce 100644 --- a/crates/router/src/configs/defaults.rs +++ b/crates/router/src/configs/defaults.rs @@ -44,6 +44,7 @@ impl Default for super::settings::Locker { mock_locker: true, basilisk_host: "localhost".into(), locker_setup: super::settings::LockerSetup::LegacyLocker, + locker_signing_key_id: "1".into(), } } } diff --git a/crates/router/src/configs/settings.rs b/crates/router/src/configs/settings.rs index a8719e221a..ed33c7153e 100644 --- a/crates/router/src/configs/settings.rs +++ b/crates/router/src/configs/settings.rs @@ -167,6 +167,7 @@ pub struct Locker { pub mock_locker: bool, pub basilisk_host: String, pub locker_setup: LockerSetup, + pub locker_signing_key_id: String, } #[derive(Debug, Deserialize, Clone, Default)] diff --git a/crates/router/src/core/payment_methods/transformers.rs b/crates/router/src/core/payment_methods/transformers.rs index a1e38c8439..76226fe2bf 100644 --- a/crates/router/src/core/payment_methods/transformers.rs +++ b/crates/router/src/core/payment_methods/transformers.rs @@ -126,10 +126,6 @@ pub struct DeleteCardResponse { pub status: String, } -pub fn basilisk_hs_key_id() -> &'static str { - "1" -} - pub fn get_dotted_jwe(jwe: encryption::JweBody) -> String { let header = jwe.header; let encryption_key = jwe.encrypted_key; @@ -172,12 +168,17 @@ pub async fn get_decrypted_response_payload( let private_key = jwekey.vault_private_key.to_owned(); let jwt = get_dotted_jwe(jwe_body); - let key_id = basilisk_hs_key_id(); let alg = jwe::RSA_OAEP; - let jwe_decrypted = encryption::decrypt_jwe(&jwt, key_id, key_id, private_key, alg) - .await - .change_context(errors::VaultError::SaveCardFailed) - .attach_printable("Jwe Decryption failed for JweBody for vault")?; + + let jwe_decrypted = encryption::decrypt_jwe( + &jwt, + encryption::KeyIdCheck::SkipKeyIdCheck, + private_key, + alg, + ) + .await + .change_context(errors::VaultError::SaveCardFailed) + .attach_printable("Jwe Decryption failed for JweBody for vault")?; let jws = jwe_decrypted .parse_struct("JwsBody") @@ -282,7 +283,7 @@ pub async fn mk_add_card_request_hs( #[cfg(not(feature = "kms"))] let private_key = jwekey.vault_private_key.to_owned(); - let jws = encryption::jws_sign_payload(&payload, basilisk_hs_key_id(), private_key) + let jws = encryption::jws_sign_payload(&payload, &locker.locker_signing_key_id, private_key) .await .change_context(errors::VaultError::RequestEncodingFailed)?; @@ -435,7 +436,7 @@ pub async fn mk_get_card_request_hs( #[cfg(not(feature = "kms"))] let private_key = jwekey.vault_private_key.to_owned(); - let jws = encryption::jws_sign_payload(&payload, basilisk_hs_key_id(), private_key) + let jws = encryption::jws_sign_payload(&payload, &locker.locker_signing_key_id, private_key) .await .change_context(errors::VaultError::RequestEncodingFailed)?; @@ -527,7 +528,7 @@ pub async fn mk_delete_card_request_hs( #[cfg(not(feature = "kms"))] let private_key = jwekey.vault_private_key.to_owned(); - let jws = encryption::jws_sign_payload(&payload, basilisk_hs_key_id(), private_key) + let jws = encryption::jws_sign_payload(&payload, &locker.locker_signing_key_id, private_key) .await .change_context(errors::VaultError::RequestEncodingFailed)?; diff --git a/crates/router/src/core/payment_methods/vault.rs b/crates/router/src/core/payment_methods/vault.rs index 3f7aeb4e6b..02fe7359e6 100644 --- a/crates/router/src/core/payment_methods/vault.rs +++ b/crates/router/src/core/payment_methods/vault.rs @@ -484,8 +484,10 @@ pub async fn create_tokenize( let alg = jwe::RSA_OAEP_256; let decrypted_payload = services::decrypt_jwe( &resp.payload, - get_key_id(&state.conf.jwekey), - &resp.key_id, + services::KeyIdCheck::RequestResponseKeyId(( + get_key_id(&state.conf.jwekey), + &resp.key_id, + )), private_key, alg, ) @@ -557,8 +559,10 @@ pub async fn get_tokenized_data( let alg = jwe::RSA_OAEP_256; let decrypted_payload = services::decrypt_jwe( &resp.payload, - get_key_id(&state.conf.jwekey), - &resp.key_id, + services::KeyIdCheck::RequestResponseKeyId(( + get_key_id(&state.conf.jwekey), + &resp.key_id, + )), private_key, alg, ) diff --git a/crates/router/src/services/encryption.rs b/crates/router/src/services/encryption.rs index fe328abe08..39ad3ee995 100644 --- a/crates/router/src/services/encryption.rs +++ b/crates/router/src/services/encryption.rs @@ -138,13 +138,24 @@ pub async fn encrypt_jwe( .attach_printable("Error getting jwt string") } +pub enum KeyIdCheck<'a> { + RequestResponseKeyId((&'a str, &'a str)), + SkipKeyIdCheck, +} + pub async fn decrypt_jwe( jwt: &str, - key_id: &str, - resp_key_id: &str, + key_ids: KeyIdCheck<'_>, private_key: String, alg: jwe::alg::rsaes::RsaesJweAlgorithm, ) -> CustomResult { + if let KeyIdCheck::RequestResponseKeyId((req_key_id, resp_key_id)) = key_ids { + utils::when(req_key_id.ne(resp_key_id), || { + Err(report!(errors::EncryptionError) + .attach_printable("key_id mismatch, Error authenticating response")) + })?; + } + let decrypter = alg .decrypter_from_pem(private_key) .into_report() @@ -155,10 +166,6 @@ pub async fn decrypt_jwe( .into_report() .change_context(errors::EncryptionError) .attach_printable("Error getting Decrypted jwe")?; - utils::when(resp_key_id.ne(key_id), || { - Err(report!(errors::EncryptionError).attach_printable("Missing ciphertext blob")) - .attach_printable("key_id mismatch, Error authenticating response") - })?; String::from_utf8(dst_payload) .into_report() @@ -245,8 +252,7 @@ mod tests { let alg = jwe::RSA_OAEP_256; let payload = decrypt_jwe( &jwt, - &conf.jwekey.locker_key_identifier1, - &conf.jwekey.locker_key_identifier1, + KeyIdCheck::SkipKeyIdCheck, conf.jwekey.locker_decryption_key1.to_owned(), alg, )