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 = ed25519_consensus::VerificationKey::try_from(
75 spki.subject_public_key.raw_bytes(),
76 )
77 .map_err(|_| DelegationError::Parse)?;
78 let sig = ed25519_consensus::Signature::try_from(&delegation.signature[..])
79 .map_err(|_| DelegationError::Parse)?;
80 vk.verify(&sig, &delegation.delegation.signable())
81 .map_err(|_| DelegationError::BrokenChain {
82 from: last_verified.clone(),
83 to: Some(delegation.delegation.clone()),
84 })?;
85 } else {
86 return Err(DelegationError::UnknownAlgorithm);
87 }
88 last_verified = &delegation.delegation.pubkey;
89 }
90 let delegated_principal = Principal::self_authenticating(last_verified);
91 if delegated_principal != to.sender().map_err(DelegationError::IdentityError)? {
92 return Err(DelegationError::BrokenChain {
93 from: last_verified.clone(),
94 to: None,
95 });
96 }
97
98 Ok(Self::new_unchecked(from_key, to, chain))
99 }
100
101 pub fn new_unchecked(
106 from_key: Vec<u8>,
107 to: Box<dyn Identity>,
108 chain: Vec<SignedDelegation>,
109 ) -> Self {
110 Self {
111 to,
112 chain,
113 from_key,
114 }
115 }
116
117 fn chain_signature(&self, mut sig: Signature) -> Signature {
118 sig.public_key = self.public_key();
119 sig.delegations
120 .get_or_insert(vec![])
121 .extend(self.chain.iter().cloned());
122 sig
123 }
124}
125
126impl Identity for DelegatedIdentity {
127 fn sender(&self) -> Result<Principal, String> {
128 Ok(Principal::self_authenticating(&self.from_key))
129 }
130 fn public_key(&self) -> Option<Vec<u8>> {
131 Some(self.from_key.clone())
132 }
133 fn sign(&self, content: &EnvelopeContent) -> Result<Signature, String> {
134 self.to.sign(content).map(|sig| self.chain_signature(sig))
135 }
136 fn sign_delegation(&self, content: &Delegation) -> Result<Signature, String> {
137 self.to
138 .sign_delegation(content)
139 .map(|sig| self.chain_signature(sig))
140 }
141 fn sign_arbitrary(&self, content: &[u8]) -> Result<Signature, String> {
142 self.to
143 .sign_arbitrary(content)
144 .map(|sig| self.chain_signature(sig))
145 }
146 fn delegation_chain(&self) -> Vec<SignedDelegation> {
147 let mut chain = self.to.delegation_chain();
148 chain.extend(self.chain.iter().cloned());
149 chain
150 }
151}