1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
// Copyright lowRISC contributors (OpenTitan project).
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
use anyhow::{Context, Result};
use cryptoki::session::UserType;
use directories::ProjectDirs;
use serde::Deserialize;
use std::collections::HashMap;
use std::os::unix::fs::PermissionsExt;
use std::path::Path;
use crate::error::HsmError;
use crate::module;
#[derive(Deserialize)]
/// The HSM `Profile` contains authentication credentials for the named token.
///
/// The profiles file is a JSON map of profile names to per-token credentials:
/// ```ignore
/// {
/// "earlgrey": {
/// "token": "my_personal_token",
/// "user": "user",
/// "pin": "abc123"
/// }
/// }
/// ```
pub struct Profile {
/// The name of the HSM token.
pub token: String,
/// The user type to authenticate to the token.
#[serde(deserialize_with = "module::deserialize_user")]
pub user: UserType,
/// The pin for the user.
pub pin: Option<String>,
}
impl Profile {
pub fn load(filename: &Path) -> Result<HashMap<String, Profile>> {
let path = if let Some(base) = ProjectDirs::from("org", "opentitan", "hsmtool") {
base.config_dir().join(filename)
} else {
filename.to_owned()
};
let perm = path
.metadata()
.context(format!("Accessing {path:?}"))?
.permissions()
.mode()
& 0o777;
// Verify the profile is only accessible by owner.
if perm & 0o077 != 0 {
return Err(HsmError::FilePermissionError(perm)).context(format!("Accessing {path:?}"));
}
let profiles = std::fs::read_to_string(&path).context(format!("Cannot read {path:?}"))?;
Ok(serde_annotate::from_str(&profiles)?)
}
}