Skip to content

Commit

Permalink
portal: Add verify_keyring_secret()
Browse files Browse the repository at this point in the history
This change introduces `verify_keyring_secret()` to verify the secret
associated with a keyring.
Note: we need this change for the sever side implementation. Specifically we
need this to verify the secret during prompt based keyring unlock.

Signed-off-by: Dhanuka Warusadura <[email protected]>
  • Loading branch information
warusadura committed Sep 2, 2024
1 parent 97fdd19 commit ee92166
Showing 1 changed file with 106 additions and 0 deletions.
106 changes: 106 additions & 0 deletions client/src/portal/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,47 @@ impl Keyring {
}
}

/// Verify the secret associated with a keyring.
///
/// This function supports all keyring formats (legacy and latest).
///
/// # Arguments
///
/// *`name` - The name of the keyring.
/// * `secret` - The service key, usually retrieved from the Secrets portal.
pub async fn verify_keyring_secret(name: &str, secret: Secret) -> bool {
#[cfg(feature = "tracing")]
tracing::debug!("Trying to verify {} keyring secret", name);

let keyring = match Keyring::open(name, secret).await {
Ok(keyring) => keyring,
Err(_err) => {
#[cfg(feature = "tracing")]
tracing::debug!("Wrong secret for {}: {}", name, _err);
return false;
}
};

let mut ret = false;

let items = keyring.items().await;
for item in items {
match item {
Ok(_) => {
#[cfg(feature = "tracing")]
tracing::debug!("{} keyring secret matches", name);
ret = true;
}
Err(_err) => {
#[cfg(feature = "tracing")]
tracing::debug!("Wrong secret for {}: {}", name, _err);
}
}
}

ret
}

/// Retrieve the number of items
///
/// This function will not trigger a key derivation and can therefore be
Expand Down Expand Up @@ -704,4 +745,69 @@ mod tests {

Ok(())
}

#[tokio::test]
async fn verify_keyring_secret_default() -> Result<(), Error> {
let temp_dir = tempdir()?;
let keyring_dir = temp_dir.path().join("keyrings");

fs::create_dir_all(&keyring_dir).await?;

let fixture_path = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("fixtures")
.join("default.keyring");

fs::copy(&fixture_path, &keyring_dir.join("default.keyring")).await?;

std::env::set_var("XDG_DATA_HOME", &temp_dir.path());

let password = b"test";
let secret = Secret::from(password.to_vec());

assert_eq!(
Keyring::verify_keyring_secret("default", secret).await,
true
);

let password = b"wrong";
let secret = Secret::from(password.to_vec());

assert_eq!(
Keyring::verify_keyring_secret("default", secret).await,
false
);

Ok(())
}

#[tokio::test]
async fn verify_keyring_secret_legacy() -> Result<(), Error> {
let temp_dir = tempdir()?;
let keyring_dir = temp_dir.path().join("keyrings");

fs::create_dir_all(&keyring_dir).await?;

let fixture_path = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("fixtures")
.join("legacy.keyring");

fs::copy(&fixture_path, &keyring_dir.join("legacy.keyring")).await?;

std::env::set_var("XDG_DATA_HOME", &temp_dir.path());

let password = b"test";
let secret = Secret::from(password.to_vec());

assert_eq!(Keyring::verify_keyring_secret("legacy", secret).await, true);

let password = b"wrong";
let secret = Secret::from(password.to_vec());

assert_eq!(
Keyring::verify_keyring_secret("legacy", secret).await,
false
);

Ok(())
}
}

0 comments on commit ee92166

Please sign in to comment.