1use crate::error::{self, Result};
5use crate::key_source::KeySource;
6use crate::schema::decoded::{Decoded, Hex};
7use crate::schema::{Delegations, KeyHolder, RoleId, RoleKeys, Root, Signed, Targets};
8use crate::sign::Sign;
9use snafu::{ensure, OptionExt, ResultExt};
10use std::collections::HashMap;
11
12pub(crate) type KeyList = HashMap<Decoded<Hex>, Box<dyn Sign>>;
14
15impl KeyHolder {
16 pub(crate) async fn get_keys(&self, keys: &[Box<dyn KeySource>]) -> Result<KeyList> {
18 match self {
19 Self::Delegations(delegations) => get_targets_keys(delegations, keys).await,
20 Self::Root(root) => get_root_keys(root, keys).await,
21 }
22 }
23
24 pub(crate) fn role_keys(&self, name: RoleId) -> Result<RoleKeys> {
26 match self {
27 Self::Delegations(delegations) => {
28 if let RoleId::DelegatedRole(name) = name.clone() {
29 for role in &delegations.roles {
30 if role.name == name.clone() {
31 return Ok(role.keys());
32 }
33 }
34 }
35 }
36 Self::Root(root) => {
37 if let RoleId::StandardRole(roletype) = name {
38 return Ok(root
39 .roles
40 .get(&roletype)
41 .context(error::NoRoleKeysinRootSnafu {
42 role: roletype.to_string(),
43 })?
44 .clone());
45 }
46 }
47 }
48 let role = match name {
49 RoleId::StandardRole(role) => role.to_string(),
50 RoleId::DelegatedRole(role_name) => role_name,
51 };
52 Err(error::Error::SigningKeysNotFound { role })
53 }
54
55 pub(crate) fn verify_role(&self, targets: &Signed<Targets>, name: &str) -> Result<()> {
57 match self {
58 Self::Delegations(delegations) => {
59 delegations
60 .verify_role(targets, name)
61 .context(error::VerifyRoleMetadataSnafu {
62 role: name.to_string(),
63 })
64 }
65 Self::Root(root) => root
66 .verify_role(targets)
67 .context(error::VerifyRoleMetadataSnafu {
68 role: name.to_string(),
69 }),
70 }
71 }
72}
73
74pub(crate) async fn get_root_keys(root: &Root, keys: &[Box<dyn KeySource>]) -> Result<KeyList> {
78 let mut root_keys = KeyList::new();
79
80 for source in keys {
81 let key_pair = source
83 .as_sign()
84 .await
85 .context(error::KeyPairFromKeySourceSnafu)?;
86
87 if let Some(key_id) = root.key_id(key_pair.as_ref()) {
90 root_keys.insert(key_id, key_pair);
91 }
92 }
93 ensure!(!root_keys.is_empty(), error::KeysNotFoundInRootSnafu);
94 Ok(root_keys)
95}
96
97pub(crate) async fn get_targets_keys(
101 delegations: &Delegations,
102 keys: &[Box<dyn KeySource>],
103) -> Result<KeyList> {
104 let mut delegations_keys = KeyList::new();
105 for source in keys {
106 let key_pair = source
108 .as_sign()
109 .await
110 .context(error::KeyPairFromKeySourceSnafu)?;
111 if let Some(key_id) = delegations.key_id(key_pair.as_ref()) {
114 delegations_keys.insert(key_id, key_pair);
115 }
116 }
117 Ok(delegations_keys)
118}