ic_auth_client/key.rs
1//! Key management functionality for cryptographic operations.
2//!
3//! The module defines types for handling cryptographic keys that can contain both
4//! raw key material and identity interfaces. This is particularly useful when working
5//! with the Internet Computer (IC) agent where you need both access to raw keys
6//! and the ability to use them as identities for signing operations.
7//!
8//! # Main Types
9//!
10//! - [`Key`] - An enum that can represent either a key with raw bytes or just an identity
11//! - [`KeyWithRaw`] - A struct that contains both raw key bytes and the associated identity
12//! - [`BaseKeyType`] - An enum representing supported key types (currently only Ed25519)
13//!
14//! # Examples
15//!
16//! ```rust
17//! use ic_auth_client::key::{Key, KeyWithRaw};
18//!
19//! // Create a key from raw bytes
20//! let raw_key = [0u8; 32]; // Your actual key bytes
21//! let key_with_raw = KeyWithRaw::new(raw_key);
22//! let key = Key::WithRaw(key_with_raw);
23//!
24//! // Use the key as an identity
25//! let identity = key.as_arc_identity();
26//!
27//! // Get public key bytes
28//! if let Some(public_key) = key.public_key() {
29//! println!("Public key: {:?}", public_key);
30//! }
31//! ```
32
33use crate::ArcIdentity;
34use ic_agent::identity::{BasicIdentity, Identity};
35use serde::{Deserialize, Serialize};
36use std::{fmt, sync::Arc};
37
38const ED25519_KEY_LABEL: &str = "Ed25519";
39
40/// A key that contains both the raw key bytes and the associated identity.
41///
42/// This struct wraps a 32-byte key with its corresponding identity implementation,
43/// providing access to both the raw key material and the identity interface.
44#[derive(Clone, Debug)]
45pub struct KeyWithRaw {
46 pub(crate) key: [u8; 32],
47 pub(crate) identity: ArcIdentity,
48}
49
50impl KeyWithRaw {
51 /// Creates a new `KeyWithRaw` from a raw 32-byte key.
52 ///
53 /// # Arguments
54 ///
55 /// * `raw_key` - A 32-byte array containing the raw key material
56 ///
57 /// # Returns
58 ///
59 /// A new `KeyWithRaw` instance with the key and its associated Ed25519 identity
60 pub fn new(raw_key: [u8; 32]) -> Self {
61 KeyWithRaw {
62 key: raw_key,
63 identity: ArcIdentity::Ed25519(Arc::new(BasicIdentity::from_raw_key(&raw_key))),
64 }
65 }
66
67 /// Returns a reference to the raw key bytes.
68 ///
69 /// # Returns
70 ///
71 /// A reference to the 32-byte raw key array
72 pub fn raw_key(&self) -> &[u8; 32] {
73 &self.key
74 }
75}
76
77/// Represents a cryptographic key that can be either a raw key with its bytes or just an identity.
78///
79/// This enum allows for flexible key handling where sometimes you need access to the raw key
80/// material and sometimes you only need the identity interface.
81#[derive(Clone, Debug)]
82pub enum Key {
83 /// A key that includes both raw key bytes and the identity
84 WithRaw(KeyWithRaw),
85 /// A key that only provides the identity interface without raw bytes
86 Identity(ArcIdentity),
87}
88
89impl Key {
90 /// Returns the key as an `Arc<dyn Identity>` for use with the IC agent.
91 ///
92 /// # Returns
93 ///
94 /// An `Arc<dyn Identity>` that can be used for signing operations
95 pub fn as_arc_identity(&self) -> Arc<dyn Identity> {
96 match self {
97 Key::WithRaw(key) => key.identity.as_arc_identity(),
98 Key::Identity(identity) => identity.as_arc_identity(),
99 }
100 }
101
102 /// Returns the public key bytes if available.
103 ///
104 /// # Returns
105 ///
106 /// An `Option<Vec<u8>>` containing the public key bytes, or `None` if not available
107 pub fn public_key(&self) -> Option<Vec<u8>> {
108 match self {
109 Key::WithRaw(key) => key.identity.public_key(),
110 Key::Identity(identity) => identity.public_key(),
111 }
112 }
113}
114
115impl From<Key> for ArcIdentity {
116 fn from(key: Key) -> Self {
117 match key {
118 Key::WithRaw(key) => key.identity,
119 Key::Identity(identity) => identity,
120 }
121 }
122}
123
124impl From<&Key> for ArcIdentity {
125 fn from(key: &Key) -> Self {
126 match key {
127 Key::WithRaw(key) => key.identity.clone(),
128 Key::Identity(identity) => identity.clone(),
129 }
130 }
131}
132
133impl From<ArcIdentity> for Key {
134 fn from(identity: ArcIdentity) -> Self {
135 Key::Identity(identity)
136 }
137}
138
139impl From<&ArcIdentity> for Key {
140 fn from(identity: &ArcIdentity) -> Self {
141 Key::Identity(identity.clone())
142 }
143}
144
145/// Enum representing the type of base key used for the identity.
146///
147/// Currently, only Ed25519 is supported.
148#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize, Default)]
149pub enum BaseKeyType {
150 /// Ed25519 base key type.
151 #[default]
152 Ed25519,
153}
154
155impl fmt::Display for BaseKeyType {
156 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
157 match self {
158 BaseKeyType::Ed25519 => write!(f, "{}", ED25519_KEY_LABEL),
159 }
160 }
161}