1use std::sync::Arc;
3
4use crate::{agent::EnvelopeContent, export::Principal};
5
6pub(crate) mod anonymous;
7pub(crate) mod basic;
8pub(crate) mod delegated;
9pub(crate) mod error;
10pub(crate) mod info_aware;
11pub(crate) mod prime256v1;
12pub(crate) mod secp256k1;
13
14#[doc(inline)]
15pub use anonymous::AnonymousIdentity;
16#[doc(inline)]
17pub use basic::BasicIdentity;
18#[doc(inline)]
19pub use delegated::DelegatedIdentity;
20#[doc(inline)]
21pub use error::DelegationError;
22#[doc(inline)]
23pub use ic_transport_types::{Delegation, SenderInfo, SignedDelegation};
24#[doc(inline)]
25pub use info_aware::InfoAwareIdentity;
26#[doc(inline)]
27pub use prime256v1::Prime256v1Identity;
28#[doc(inline)]
29pub use secp256k1::Secp256k1Identity;
30
31#[cfg(feature = "pem")]
32#[doc(inline)]
33pub use error::PemError;
34
35#[derive(Clone, Debug)]
37pub struct Signature {
38 pub public_key: Option<Vec<u8>>,
40 pub signature: Option<Vec<u8>>,
42 pub delegations: Option<Vec<SignedDelegation>>,
44}
45
46pub trait Identity: Send + Sync {
52 fn sender(&self) -> Result<Principal, String>;
56
57 fn public_key(&self) -> Option<Vec<u8>>;
61
62 fn sign(&self, content: &EnvelopeContent) -> Result<Signature, String>;
66
67 fn sign_delegation(&self, content: &Delegation) -> Result<Signature, String> {
73 let _ = content; Err(String::from("unsupported"))
75 }
76
77 fn sign_arbitrary(&self, content: &[u8]) -> Result<Signature, String> {
81 let _ = content; Err(String::from("unsupported"))
83 }
84
85 fn delegation_chain(&self) -> Vec<SignedDelegation> {
88 vec![]
89 }
90
91 fn sender_info(&self) -> Option<SenderInfo> {
95 None
96 }
97}
98
99macro_rules! delegating_impl {
100 ($implementor:ty, $name:ident => $self_expr:expr) => {
101 impl Identity for $implementor {
102 fn sender(&$name) -> Result<Principal, String> {
103 $self_expr.sender()
104 }
105
106 fn public_key(&$name) -> Option<Vec<u8>> {
107 $self_expr.public_key()
108 }
109
110 fn sign(&$name, content: &EnvelopeContent) -> Result<Signature, String> {
111 $self_expr.sign(content)
112 }
113
114 fn sign_delegation(&$name, content: &Delegation) -> Result<Signature, String> {
115 $self_expr.sign_delegation(content)
116 }
117
118 fn sign_arbitrary(&$name, content: &[u8]) -> Result<Signature, String> {
119 $self_expr.sign_arbitrary(content)
120 }
121
122 fn delegation_chain(&$name) -> Vec<SignedDelegation> {
123 $self_expr.delegation_chain()
124 }
125
126 fn sender_info(&$name) -> Option<SenderInfo> {
127 $self_expr.sender_info()
128 }
129 }
130 };
131}
132
133delegating_impl!(Box<dyn Identity>, self => **self);
134delegating_impl!(Arc<dyn Identity>, self => **self);
135delegating_impl!(&dyn Identity, self => *self);
136
137#[cfg(feature = "pem")]
143fn parse_ec_pkcs8_key_bytes(
144 der_bytes: &[u8],
145 expected_curve: pkcs8::der::asn1::ObjectIdentifier,
146 curve_name: &str,
147) -> Result<Vec<u8>, error::PemError> {
148 use pkcs8::{
149 der::{Decode, Encode},
150 PrivateKeyInfo,
151 };
152
153 let mut truncated: Vec<u8>;
154 let pki = match PrivateKeyInfo::from_der(der_bytes) {
155 Ok(pki) => pki,
156 Err(e) => {
157 truncated = der_bytes.to_vec();
160 if truncated.len() >= 52 && truncated[48..52] == *b"\xA1\x23\x03\x21" {
161 truncated.truncate(48);
162 truncated[1] = 46;
163 truncated[4] = 0;
164 PrivateKeyInfo::from_der(&truncated).map_err(|_| e)?
165 } else {
166 return Err(e.into());
167 }
168 }
169 };
170 if pki.algorithm.oid != elliptic_curve::ALGORITHM_OID {
171 return Err(error::PemError::InvalidPrivateKey(format!(
172 "expected EC algorithm OID {}, found {}",
173 elliptic_curve::ALGORITHM_OID,
174 pki.algorithm.oid,
175 )));
176 }
177 let curve_oid = pki
178 .algorithm
179 .parameters_oid()
180 .map_err(|_| pkcs8::Error::KeyMalformed)?;
181 if curve_oid != expected_curve {
182 return Err(error::PemError::UnsupportedKeyCurve(
183 curve_name.to_string(),
184 curve_oid.to_der().unwrap_or_default(),
185 ));
186 }
187 Ok(pki.private_key.to_vec())
188}