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}