ic_agent/identity/
delegated.rs1use candid::Principal;
2use der::{Decode, SliceReader};
3use ecdsa::signature::Verifier;
4use k256::Secp256k1;
5use p256::NistP256;
6use pkcs8::{spki::SubjectPublicKeyInfoRef, AssociatedOid, ObjectIdentifier};
7use sec1::{EcParameters, EncodedPoint};
8
9use crate::{agent::EnvelopeContent, Signature};
10
11use super::{error::DelegationError, Delegation, Identity, SignedDelegation};
12
13pub struct DelegatedIdentity {
15 to: Box<dyn Identity>,
16 chain: Vec<SignedDelegation>,
17 from_key: Vec<u8>,
18}
19
20impl DelegatedIdentity {
21 pub fn new(
26 from_key: Vec<u8>,
27 to: Box<dyn Identity>,
28 chain: Vec<SignedDelegation>,
29 ) -> Result<Self, DelegationError> {
30 let mut last_verified = &from_key;
31 for delegation in &chain {
32 let spki = SubjectPublicKeyInfoRef::decode(
33 &mut SliceReader::new(&last_verified[..]).map_err(|_| DelegationError::Parse)?,
34 )
35 .map_err(|_| DelegationError::Parse)?;
36 if spki.algorithm.oid == elliptic_curve::ALGORITHM_OID {
37 let Some(params) = spki.algorithm.parameters else {
38 return Err(DelegationError::UnknownAlgorithm);
39 };
40 let params = params
41 .decode_as::<EcParameters>()
42 .map_err(|_| DelegationError::Parse)?;
43 let curve = params
44 .named_curve()
45 .ok_or(DelegationError::UnknownAlgorithm)?;
46 if curve == Secp256k1::OID {
47 let pt = EncodedPoint::from_bytes(spki.subject_public_key.raw_bytes())
48 .map_err(|_| DelegationError::Parse)?;
49 let vk = k256::ecdsa::VerifyingKey::from_encoded_point(&pt)
50 .map_err(|_| DelegationError::Parse)?;
51 let sig = k256::ecdsa::Signature::try_from(&delegation.signature[..])
52 .map_err(|_| DelegationError::Parse)?;
53 vk.verify(&delegation.delegation.signable(), &sig)
54 .map_err(|_| DelegationError::BrokenChain {
55 from: last_verified.clone(),
56 to: Some(delegation.delegation.clone()),
57 })?;
58 } else if curve == NistP256::OID {
59 let pt = EncodedPoint::from_bytes(spki.subject_public_key.raw_bytes())
60 .map_err(|_| DelegationError::Parse)?;
61 let vk = p256::ecdsa::VerifyingKey::from_encoded_point(&pt)
62 .map_err(|_| DelegationError::Parse)?;
63 let sig = p256::ecdsa::Signature::try_from(&delegation.signature[..])
64 .map_err(|_| DelegationError::Parse)?;
65 vk.verify(&delegation.delegation.signable(), &sig)
66 .map_err(|_| DelegationError::BrokenChain {
67 from: last_verified.clone(),
68 to: Some(delegation.delegation.clone()),
69 })?;
70 } else {
71 return Err(DelegationError::UnknownAlgorithm);
72 }
73 } else if spki.algorithm.oid == ObjectIdentifier::new_unwrap("1.3.101.112") {
74 let vk =
75 ic_ed25519::PublicKey::deserialize_raw(spki.subject_public_key.raw_bytes())
76 .map_err(|_| DelegationError::Parse)?;
77 vk.verify_signature(&delegation.delegation.signable(), &delegation.signature[..])
78 .map_err(|_| DelegationError::BrokenChain {
79 from: last_verified.clone(),
80 to: Some(delegation.delegation.clone()),
81 })?;
82 } else {
83 return Err(DelegationError::UnknownAlgorithm);
84 }
85 last_verified = &delegation.delegation.pubkey;
86 }
87 let delegated_principal = Principal::self_authenticating(last_verified);
88 if delegated_principal != to.sender().map_err(DelegationError::IdentityError)? {
89 return Err(DelegationError::BrokenChain {
90 from: last_verified.clone(),
91 to: None,
92 });
93 }
94
95 Ok(Self::new_unchecked(from_key, to, chain))
96 }
97
98 pub fn new_unchecked(
103 from_key: Vec<u8>,
104 to: Box<dyn Identity>,
105 chain: Vec<SignedDelegation>,
106 ) -> Self {
107 Self {
108 to,
109 chain,
110 from_key,
111 }
112 }
113
114 fn chain_signature(&self, mut sig: Signature) -> Signature {
115 sig.public_key = self.public_key();
116 sig.delegations
117 .get_or_insert(vec![])
118 .extend(self.chain.iter().cloned());
119 sig
120 }
121}
122
123impl Identity for DelegatedIdentity {
124 fn sender(&self) -> Result<Principal, String> {
125 Ok(Principal::self_authenticating(&self.from_key))
126 }
127 fn public_key(&self) -> Option<Vec<u8>> {
128 Some(self.from_key.clone())
129 }
130 fn sign(&self, content: &EnvelopeContent) -> Result<Signature, String> {
131 self.to.sign(content).map(|sig| self.chain_signature(sig))
132 }
133 fn sign_delegation(&self, content: &Delegation) -> Result<Signature, String> {
134 self.to
135 .sign_delegation(content)
136 .map(|sig| self.chain_signature(sig))
137 }
138 fn sign_arbitrary(&self, content: &[u8]) -> Result<Signature, String> {
139 self.to
140 .sign_arbitrary(content)
141 .map(|sig| self.chain_signature(sig))
142 }
143 fn delegation_chain(&self) -> Vec<SignedDelegation> {
144 let mut chain = self.to.delegation_chain();
145 chain.extend(self.chain.iter().cloned());
146 chain
147 }
148}