1#![allow(missing_docs)]
34
35use crate::crypto_verify::EnhancedSignatureVerifier;
36use crate::encrypted_key_storage::{EncryptedKeyStorageManager, SecurityLevel};
37use crate::error::{IdentityError, SecurityError, StorageError};
38use crate::key_derivation::{DerivationPath, DerivedKey, HierarchicalKeyDerivation};
39use crate::monotonic_counter::MonotonicCounterSystem;
40use crate::peer_record::{PeerDHTRecord, PeerEndpoint, UserId};
41use crate::secure_memory::SecureString;
42use crate::{P2PError, Result};
43use argon2::{Algorithm, Argon2, Params, Version};
44use bincode;
45use chacha20poly1305::{
46 ChaCha20Poly1305,
47 aead::{Aead, KeyInit, generic_array::GenericArray},
48};
49use ed25519_dalek::{
50 Signature, Signer, SigningKey as Ed25519SigningKey, Verifier,
51 VerifyingKey as Ed25519VerifyingKey,
52};
53use hkdf;
54use rand::thread_rng;
55use serde::{Deserialize, Serialize};
56use std::collections::HashMap;
57use std::path::{Path, PathBuf};
58use std::sync::{Arc, RwLock};
59use std::time::{Duration, SystemTime, UNIX_EPOCH};
60use tokio::sync::RwLock as AsyncRwLock;
61use tracing;
62
63const IDENTITY_VERSION: u8 = 1;
65
66const DEFAULT_KEY_LIFETIME: Duration = Duration::from_secs(90 * 24 * 60 * 60);
68
69const KEY_ROTATION_WARNING: Duration = Duration::from_secs(7 * 24 * 60 * 60);
71
72const MAX_METADATA_SIZE: usize = 10240; #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
77pub enum IdentityState {
78 Creating,
80 Active,
82 Rotating,
84 Revoked,
86 Expired,
88}
89
90#[derive(Debug)]
92pub struct IdentityKeyPair {
93 pub ed25519_secret: Ed25519SigningKey,
95 pub ed25519_public: Ed25519VerifyingKey,
96 pub x25519_secret: [u8; 32],
98 pub x25519_public: [u8; 32],
99 pub created_at: u64,
101 pub expires_at: u64,
103 pub version: u32,
105}
106
107impl Clone for IdentityKeyPair {
108 fn clone(&self) -> Self {
109 let secret_bytes = self.ed25519_secret.to_bytes();
111 let ed25519_secret = Ed25519SigningKey::from_bytes(&secret_bytes);
112
113 Self {
114 ed25519_secret,
115 ed25519_public: self.ed25519_public,
116 x25519_secret: self.x25519_secret,
117 x25519_public: self.x25519_public,
118 created_at: self.created_at,
119 expires_at: self.expires_at,
120 version: self.version,
121 }
122 }
123}
124
125#[derive(Debug, Clone, Serialize, Deserialize)]
127pub struct Identity {
128 pub id: UserId,
130 pub four_word_address: String,
132 pub state: IdentityState,
134 pub display_name: Option<String>,
136 pub avatar_url: Option<String>,
138 pub bio: Option<String>,
140 pub metadata: HashMap<String, String>,
142 pub key_version: u32,
144 pub created_at: u64,
146 pub updated_at: u64,
148 pub expires_at: u64,
150 pub previous_keys: Vec<[u8; 32]>,
152 pub revocation_cert: Option<RevocationCertificate>,
154}
155
156#[derive(Debug, Clone, Serialize, Deserialize)]
158pub struct RevocationCertificate {
159 pub identity_id: UserId,
161 pub reason: RevocationReason,
163 pub revoked_at: u64,
165 pub signature: Vec<u8>,
167 pub replacement_id: Option<UserId>,
169}
170
171#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
173pub enum RevocationReason {
174 KeyCompromise,
176 UserRequested,
178 Superseded,
180 Other,
182}
183
184#[derive(Debug, Clone, Default)]
186pub struct IdentityCreationParams {
187 pub display_name: Option<String>,
189 pub avatar_url: Option<String>,
191 pub bio: Option<String>,
193 pub metadata: HashMap<String, String>,
195 pub key_lifetime: Option<Duration>,
197 pub derivation_path: Option<String>,
199}
200
201#[derive(Debug, Clone)]
203pub struct IdentityVerification {
204 pub valid: bool,
206 pub verified_at: u64,
208 pub issues: Vec<String>,
210 pub trust_level: u8,
212}
213
214#[derive(Debug, Clone, Serialize, Deserialize)]
216pub struct IdentityUpdate {
217 pub display_name: Option<String>,
219 pub avatar_url: Option<String>,
221 pub bio: Option<String>,
223 pub metadata: Option<HashMap<String, String>>,
225 pub timestamp: u64,
227 pub sequence: u64,
229 pub signature: Vec<u8>,
231}
232
233pub struct IdentityManager {
235 storage_path: PathBuf,
237 key_storage: Arc<EncryptedKeyStorageManager>,
239 key_derivation: Arc<AsyncRwLock<HierarchicalKeyDerivation>>,
241 verifier: Arc<EnhancedSignatureVerifier>,
243 counter_system: Arc<MonotonicCounterSystem>,
245 identities: Arc<RwLock<HashMap<UserId, Identity>>>,
247 key_pairs: Arc<RwLock<HashMap<UserId, IdentityKeyPair>>>,
249 background_tasks: Arc<AsyncRwLock<HashMap<UserId, tokio::task::JoinHandle<Result<()>>>>>,
251 stats: Arc<RwLock<IdentityStats>>,
253}
254
255#[derive(Debug, Clone, Default)]
257pub struct IdentityStats {
258 pub identities_created: u64,
260 pub identities_revoked: u64,
262 pub key_rotations: u64,
264 pub verifications_performed: u64,
266 pub avg_verification_time_us: u64,
268 pub active_identities: u64,
270}
271
272#[derive(Debug, Clone, Serialize, Deserialize)]
274pub struct IdentitySyncPackage {
275 pub encrypted_identity: Vec<u8>,
277 pub encrypted_keys: Vec<u8>,
279 pub timestamp: u64,
281 pub device_fingerprint: [u8; 32],
283 pub signature: Vec<u8>,
285}
286
287#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
289pub enum ProfilePermissions {
290 ReadOnly,
292 ReadWrite,
294 Admin,
296}
297
298#[derive(Debug, Clone, Serialize, Deserialize)]
300struct AccessGrant {
301 grantor_id: UserId,
303 grantee_id: UserId,
305 permissions: ProfilePermissions,
307 granted_at: u64,
309 expires_at: Option<u64>,
311}
312
313#[derive(Debug, Clone)]
315pub struct AccessInfo {
316 pub permissions: ProfilePermissions,
318 pub granted_at: u64,
320 pub expires_at: Option<u64>,
322}
323
324impl IdentityKeyPair {
325 pub fn from_derived_key(key: &DerivedKey, lifetime: Duration) -> Result<Self> {
327 let created_at = current_timestamp();
328 let expires_at = created_at + lifetime.as_secs();
329
330 Ok(Self {
331 ed25519_secret: Ed25519SigningKey::from_bytes(&key.secret_key.to_bytes()),
332 ed25519_public: key.public_key,
333 x25519_secret: key.x25519_secret,
334 x25519_public: key.x25519_public,
335 created_at,
336 expires_at,
337 version: 1,
338 })
339 }
340
341 pub fn is_expired(&self) -> bool {
343 current_timestamp() >= self.expires_at
344 }
345
346 pub fn needs_rotation(&self) -> bool {
348 let now = current_timestamp();
349 let rotation_time = self
350 .expires_at
351 .saturating_sub(KEY_ROTATION_WARNING.as_secs());
352 now >= rotation_time
353 }
354
355 pub fn sign(&self, data: &[u8]) -> Result<Signature> {
357 Ok(self.ed25519_secret.sign(data))
358 }
359
360 pub fn verify(&self, data: &[u8], signature: &Signature) -> Result<()> {
362 self.ed25519_public.verify(data, signature).map_err(|_| {
363 P2PError::Security(SecurityError::SignatureVerificationFailed(
364 "Signature verification failed".into(),
365 ))
366 })
367 }
368}
369
370impl Identity {
371 pub fn from_key_pair(
373 key_pair: &IdentityKeyPair,
374 four_word_address: String,
375 params: IdentityCreationParams,
376 ) -> Result<Self> {
377 let id = UserId::from_public_key(&key_pair.ed25519_public);
379
380 let metadata_size: usize = params.metadata.values().map(|v| v.len()).sum();
382
383 if metadata_size > MAX_METADATA_SIZE {
384 return Err(P2PError::Config(crate::error::ConfigError::InvalidValue {
385 field: "metadata_size".into(),
386
387 reason: format!("Metadata size exceeds maximum {MAX_METADATA_SIZE}").into(),
388 }));
389 }
390
391 let now = current_timestamp();
392
393 Ok(Self {
394 id,
395 four_word_address,
396 state: IdentityState::Active,
397 display_name: params.display_name,
398 avatar_url: params.avatar_url,
399 bio: params.bio,
400 metadata: params.metadata,
401 key_version: key_pair.version,
402 created_at: key_pair.created_at,
403 updated_at: now,
404 expires_at: key_pair.expires_at,
405 previous_keys: Vec::new(),
406 revocation_cert: None,
407 })
408 }
409
410 pub fn is_valid(&self) -> bool {
412 match self.state {
413 IdentityState::Active => !self.is_expired(),
414 _ => false,
415 }
416 }
417
418 pub fn is_expired(&self) -> bool {
420 current_timestamp() >= self.expires_at
421 }
422
423 pub fn to_dht_record(&self, endpoints: Vec<PeerEndpoint>) -> Result<PeerDHTRecord> {
425 let public_key =
426 ed25519_dalek::VerifyingKey::from_bytes(self.id.as_bytes()).map_err(|e| {
427 P2PError::Identity(IdentityError::InvalidFormat(
428 format!("invalid public key: {}", e).into(),
429 ))
430 })?;
431
432 Ok(PeerDHTRecord {
433 version: IDENTITY_VERSION,
434 user_id: self.id.clone(),
435 public_key,
436 sequence_number: self.updated_at,
437 name: self.display_name.clone(),
438 endpoints,
439 timestamp: self.updated_at,
440 ttl: (self.expires_at - current_timestamp()) as u32,
441 signature: ed25519_dalek::Signature::from_bytes(&[0u8; 64]), })
443 }
444
445 pub fn apply_update(&mut self, update: &IdentityUpdate) -> Result<()> {
447 if update.timestamp <= self.updated_at {
448 return Err(P2PError::Identity(
449 crate::error::IdentityError::InvalidFormat("Update timestamp is not newer".into()),
450 ));
451 }
452
453 if let Some(name) = &update.display_name {
454 self.display_name = Some(name.clone());
455 }
456
457 if let Some(avatar) = &update.avatar_url {
458 self.avatar_url = Some(avatar.clone());
459 }
460
461 if let Some(bio) = &update.bio {
462 self.bio = Some(bio.clone());
463 }
464
465 if let Some(metadata) = &update.metadata {
466 self.metadata = metadata.clone();
467 }
468
469 self.updated_at = update.timestamp;
470
471 Ok(())
472 }
473}
474
475impl IdentityManager {
476 pub async fn new<P: AsRef<Path>>(
478 storage_path: P,
479 security_level: SecurityLevel,
480 ) -> Result<Self> {
481 let storage_path = storage_path.as_ref().to_path_buf();
482
483 tokio::fs::create_dir_all(&storage_path)
485 .await
486 .map_err(|e| {
487 P2PError::Storage(StorageError::Database(
488 format!("Failed to create identity storage: {e}").into(),
489 ))
490 })?;
491
492 let key_storage = Arc::new(EncryptedKeyStorageManager::new(
494 storage_path.join("keys.enc"),
495 security_level,
496 )?);
497
498 let verifier = Arc::new(EnhancedSignatureVerifier::new());
499
500 let counter_system = MonotonicCounterSystem::new_with_sync_interval(
501 storage_path.join("counters"),
502 Duration::from_secs(60),
503 )
504 .await?;
505
506 Ok(Self {
507 storage_path,
508 key_storage,
509 key_derivation: Arc::new(AsyncRwLock::new(HierarchicalKeyDerivation::new(
510 crate::key_derivation::MasterSeed::generate()?,
511 ))),
512 verifier,
513 counter_system: Arc::new(counter_system),
514 identities: Arc::new(RwLock::new(HashMap::new())),
515 key_pairs: Arc::new(RwLock::new(HashMap::new())),
516 background_tasks: Arc::new(AsyncRwLock::new(HashMap::new())),
517 stats: Arc::new(RwLock::new(IdentityStats::default())),
518 })
519 }
520
521 pub async fn initialize(&self, password: &SecureString) -> Result<()> {
523 self.key_storage.initialize(password).await?;
524 Ok(())
525 }
526
527 pub async fn create_identity(
529 &self,
530 password: &SecureString,
531 params: IdentityCreationParams,
532 ) -> Result<Identity> {
533 let four_word_address = self.generate_four_word_address().await?;
535
536 let derivation_path = params
538 .derivation_path
539 .as_deref()
540 .unwrap_or("m/44'/0'/0'/0/0");
541
542 let path = DerivationPath::from_string(derivation_path)?;
543 let derived_key = {
544 let mut key_derivation = self.key_derivation.write().await;
545 key_derivation.derive_key(&path)?
546 };
547
548 let lifetime = params.key_lifetime.unwrap_or(DEFAULT_KEY_LIFETIME);
549 let key_pair = IdentityKeyPair::from_derived_key(&derived_key, lifetime)?;
550
551 let identity = Identity::from_key_pair(&key_pair, four_word_address, params)?;
553
554 let identity_seed = crate::key_derivation::MasterSeed::generate()?;
557
558 self.key_storage
559 .store_master_seed(&identity.id.to_string(), &identity_seed, password)
560 .await?;
561
562 {
564 let mut identities = self.identities.write().map_err(|_| {
565 P2PError::Identity(IdentityError::SystemTime("write lock failed".into()))
566 })?;
567 identities.insert(identity.id.clone(), identity.clone());
568 }
569
570 {
571 let mut key_pairs = self.key_pairs.write().map_err(|_| {
572 P2PError::Identity(IdentityError::SystemTime("write lock failed".into()))
573 })?;
574 key_pairs.insert(identity.id.clone(), key_pair);
575 }
576
577 {
579 let mut stats = self.stats.write().map_err(|_| {
580 P2PError::Identity(IdentityError::SystemTime("write lock failed".into()))
581 })?;
582 stats.identities_created += 1;
583 stats.active_identities += 1;
584 }
585
586 self.schedule_key_rotation_check(identity.id.clone())
588 .await?;
589
590 Ok(identity)
591 }
592
593 pub async fn load_identity(
595 &self,
596 identity_id: &UserId,
597 password: &SecureString,
598 ) -> Result<Identity> {
599 {
601 let identities = self.identities.read().map_err(|_| {
602 P2PError::Identity(IdentityError::SystemTime("read lock failed".into()))
603 })?;
604 if let Some(identity) = identities.get(identity_id) {
605 return Ok(identity.clone());
606 }
607 }
608
609 let encrypted_path = self.storage_path.join(format!("{identity_id}.enc"));
611 let plaintext_path = self.storage_path.join(format!("{identity_id}.json"));
612
613 let identity: Identity = if encrypted_path.exists() {
614 let encrypted_data = tokio::fs::read(&encrypted_path).await.map_err(|e| {
616 P2PError::Storage(StorageError::Database(
617 format!("Failed to read encrypted identity: {e}").into(),
618 ))
619 })?;
620
621 if encrypted_data.len() < 1 + 32 + 12 {
623 return Err(P2PError::Security(SecurityError::DecryptionFailed(
624 "Invalid encrypted file format".into(),
625 )));
626 }
627
628 let version = encrypted_data[0];
629 if version != 1 {
630 return Err(P2PError::Security(SecurityError::DecryptionFailed(
631 format!("Unsupported encryption version: {version}").into(),
632 )));
633 }
634
635 let _salt = &encrypted_data[1..33];
636 let nonce = &encrypted_data[33..45];
637 let ciphertext = &encrypted_data[45..];
638
639 let decryption_key = self
641 .derive_encryption_key_for_identity(identity_id, password)
642 .await?;
643
644 let plaintext = self.decrypt_data(
646 ciphertext,
647 &decryption_key,
648 nonce.try_into().map_err(|_| {
649 P2PError::Security(SecurityError::DecryptionFailed("Invalid nonce".into()))
650 })?,
651 )?;
652
653 serde_json::from_slice(&plaintext)
655 .map_err(|e| P2PError::Serialization(e.to_string().into()))?
656 } else if plaintext_path.exists() {
657 let identity_data = tokio::fs::read(&plaintext_path).await.map_err(|e| {
659 P2PError::Storage(StorageError::Database(
660 format!("Failed to read identity: {e}").into(),
661 ))
662 })?;
663
664 serde_json::from_slice(&identity_data)
665 .map_err(|e| P2PError::Serialization(e.to_string().into()))?
666 } else {
667 return Err(P2PError::Storage(StorageError::FileNotFound(
668 identity_id.to_string().into(),
669 )));
670 };
671
672 let master_seed = self
674 .key_storage
675 .retrieve_master_seed(&identity_id.to_string(), password)
676 .await?;
677
678 let mut key_derivation = HierarchicalKeyDerivation::new(master_seed);
679 let path = DerivationPath::from_string("m/44'/0'/0'/0/0")?;
680 let derived_key = key_derivation.derive_key(&path)?;
681
682 let key_pair = IdentityKeyPair::from_derived_key(
683 &derived_key,
684 Duration::from_secs(identity.expires_at - identity.created_at),
685 )?;
686
687 {
689 let mut identities = self.identities.write().map_err(|_| {
690 P2PError::Identity(IdentityError::SystemTime("write lock failed".into()))
691 })?;
692 identities.insert(identity.id.clone(), identity.clone());
693 }
694
695 {
696 let mut key_pairs = self.key_pairs.write().map_err(|_| {
697 P2PError::Identity(IdentityError::SystemTime("write lock failed".into()))
698 })?;
699 key_pairs.insert(identity.id.clone(), key_pair);
700 }
701
702 Ok(identity)
703 }
704
705 pub async fn verify_identity(&self, identity: &Identity) -> Result<IdentityVerification> {
707 let start_time = std::time::Instant::now();
708 let mut issues = Vec::new();
709 let mut trust_level = 100u8;
710
711 if identity.state != IdentityState::Active {
713 issues.push(format!("Identity is not active: {:?}", identity.state));
714 trust_level = 0;
715 }
716
717 if identity.is_expired() {
719 issues.push("Identity has expired".to_string());
720 trust_level = 0;
721 }
722
723 match Ed25519VerifyingKey::from_bytes(identity.id.as_bytes()) {
725 Ok(_) => {}
726 Err(e) => {
727 issues.push(format!("Invalid public key in ID: {e}"));
728 trust_level = 0;
729 }
730 }
731
732 if identity.revocation_cert.is_some() {
734 issues.push("Identity has been revoked".to_string());
735 trust_level = 0;
736 }
737
738 let metadata_size: usize = identity.metadata.values().map(|v| v.len()).sum();
740
741 if metadata_size > MAX_METADATA_SIZE {
742 issues.push("Metadata exceeds size limit".to_string());
743 trust_level = trust_level.saturating_sub(20);
744 }
745
746 {
748 let mut stats = self.stats.write().map_err(|_| {
749 P2PError::Identity(IdentityError::SystemTime("write lock failed".into()))
750 })?;
751 stats.verifications_performed += 1;
752 let elapsed = start_time.elapsed().as_micros() as u64;
753 stats.avg_verification_time_us = (stats.avg_verification_time_us + elapsed) / 2;
754 }
755
756 Ok(IdentityVerification {
757 valid: issues.is_empty(),
758 verified_at: current_timestamp(),
759 issues,
760 trust_level,
761 })
762 }
763
764 pub async fn rotate_keys(&self, identity_id: &UserId, password: &SecureString) -> Result<()> {
766 let mut identity = self.load_identity(identity_id, password).await?;
768
769 if identity.state != IdentityState::Active {
770 return Err(P2PError::Identity(
771 crate::error::IdentityError::InvalidFormat(
772 "Cannot rotate keys for inactive identity"
773 .to_string()
774 .into(),
775 ),
776 ));
777 }
778
779 identity.state = IdentityState::Rotating;
781
782 let new_version = identity.key_version + 1;
784 let path = DerivationPath::from_string(&format!("m/44'/0'/0'/0/{new_version}"))?;
785
786 let derived_key = {
787 let mut key_derivation = self.key_derivation.write().await;
788 key_derivation.derive_key(&path)?
789 };
790
791 let lifetime = Duration::from_secs(identity.expires_at - identity.created_at);
792 let mut new_key_pair = IdentityKeyPair::from_derived_key(&derived_key, lifetime)?;
793 new_key_pair.version = new_version;
794
795 let old_key_hash = *blake3::hash(identity.id.as_bytes()).as_bytes();
797 identity.previous_keys.push(old_key_hash);
798
799 identity.key_version = new_version;
801 identity.updated_at = current_timestamp();
802 identity.expires_at = new_key_pair.expires_at;
803 identity.state = IdentityState::Active;
804
805 self.save_identity(&identity, password).await?;
807
808 {
810 let mut identities = self.identities.write().map_err(|_| {
811 P2PError::Identity(IdentityError::SystemTime("write lock failed".into()))
812 })?;
813 identities.insert(identity.id.clone(), identity);
814 }
815
816 {
817 let mut key_pairs = self.key_pairs.write().map_err(|_| {
818 P2PError::Identity(IdentityError::SystemTime("write lock failed".into()))
819 })?;
820 key_pairs.insert(identity_id.clone(), new_key_pair);
821 }
822
823 {
825 let mut stats = self.stats.write().map_err(|_| {
826 P2PError::Identity(IdentityError::SystemTime("write lock failed".into()))
827 })?;
828 stats.key_rotations += 1;
829 }
830
831 Ok(())
832 }
833
834 pub async fn revoke_identity(
836 &self,
837 identity_id: &UserId,
838 password: &SecureString,
839 reason: RevocationReason,
840 replacement_id: Option<UserId>,
841 ) -> Result<RevocationCertificate> {
842 let mut identity = self.load_identity(identity_id, password).await?;
844 let key_pair = self.get_key_pair(identity_id)?;
845
846 let cert = RevocationCertificate {
848 identity_id: identity_id.clone(),
849 reason,
850 revoked_at: current_timestamp(),
851 signature: Vec::new(),
852 replacement_id,
853 };
854
855 let cert_data = bincode::serialize(&cert).map_err(|e| {
857 P2PError::Storage(StorageError::Database(
858 format!("Failed to serialize certificate: {e}").into(),
859 ))
860 })?;
861 let signature = key_pair.sign(&cert_data)?;
862
863 let mut signed_cert = cert;
864 signed_cert.signature = signature.to_bytes().to_vec();
865
866 identity.state = IdentityState::Revoked;
868 identity.revocation_cert = Some(signed_cert.clone());
869 identity.updated_at = current_timestamp();
870
871 self.save_identity(&identity, password).await?;
873
874 {
876 let mut identities = self.identities.write().map_err(|_| {
877 P2PError::Identity(IdentityError::SystemTime("write lock failed".into()))
878 })?;
879 identities.remove(identity_id);
880 }
881
882 {
883 let mut key_pairs = self.key_pairs.write().map_err(|_| {
884 P2PError::Identity(IdentityError::SystemTime("write lock failed".into()))
885 })?;
886 key_pairs.remove(identity_id);
887 }
888
889 {
891 let mut tasks = self.background_tasks.write().await;
892 if let Some(task) = tasks.remove(identity_id) {
893 task.abort();
894 }
895 }
896
897 {
899 let mut stats = self.stats.write().map_err(|_| {
900 P2PError::Identity(IdentityError::SystemTime("write lock failed".into()))
901 })?;
902 stats.identities_revoked += 1;
903 stats.active_identities = stats.active_identities.saturating_sub(1);
904 }
905
906 Ok(signed_cert)
907 }
908
909 pub fn get_stats(&self) -> IdentityStats {
911 self.stats.read().unwrap_or_else(|e| e.into_inner()).clone()
912 }
913
914 fn derive_encryption_key(&self, password: &SecureString, salt: &[u8]) -> Result<[u8; 32]> {
916 let argon2 = Argon2::new(
917 Algorithm::Argon2id,
918 Version::V0x13,
919 Params::new(64 * 1024, 3, 4, Some(32)).map_err(|e| {
920 P2PError::Security(SecurityError::KeyGenerationFailed(
921 format!("Invalid Argon2 params: {e}").into(),
922 ))
923 })?,
924 );
925
926 let mut key = [0u8; 32];
927 let password_str = password.as_str()?;
929 argon2
930 .hash_password_into(password_str.as_bytes(), salt, &mut key)
931 .map_err(|e| {
932 P2PError::Security(SecurityError::KeyGenerationFailed(
933 format!("Argon2 failed: {e}").into(),
934 ))
935 })?;
936
937 Ok(key)
938 }
939
940 fn encrypt_data(&self, data: &[u8], key: &[u8; 32], nonce: &[u8; 12]) -> Result<Vec<u8>> {
942 let cipher = ChaCha20Poly1305::new(GenericArray::from_slice(key));
943 let nonce = GenericArray::from_slice(nonce);
944
945 cipher.encrypt(nonce, data).map_err(|e| {
946 P2PError::Security(SecurityError::EncryptionFailed(
947 format!("ChaCha20Poly1305 encryption failed: {e}").into(),
948 ))
949 })
950 }
951
952 fn decrypt_data(&self, encrypted: &[u8], key: &[u8; 32], nonce: &[u8; 12]) -> Result<Vec<u8>> {
954 let cipher = ChaCha20Poly1305::new(GenericArray::from_slice(key));
955 let nonce = GenericArray::from_slice(nonce);
956
957 cipher.decrypt(nonce, encrypted).map_err(|e| {
958 P2PError::Security(SecurityError::DecryptionFailed(
959 format!("ChaCha20Poly1305 decryption failed: {e}").into(),
960 ))
961 })
962 }
963
964 async fn derive_encryption_key_for_identity(
966 &self,
967 identity_id: &UserId,
968 password: &SecureString,
969 ) -> Result<[u8; 32]> {
970 let mut hasher = blake3::Hasher::new();
972 hasher.update(b"saorsa-identity-encryption-v1");
973 hasher.update(identity_id.to_string().as_bytes());
974 let salt = hasher.finalize();
975
976 let master_seed = match self
979 .key_storage
980 .retrieve_master_seed("identity_encryption_master", password)
981 .await
982 {
983 Ok(seed) => seed,
984 Err(_) => {
985 let new_seed = crate::key_derivation::MasterSeed::generate()?;
987 self.key_storage
988 .store_master_seed("identity_encryption_master", &new_seed, password)
989 .await?;
990 new_seed
991 }
992 };
993
994 let master_key = master_seed.seed_material();
996
997 let mut key = [0u8; 32];
999 let hkdf = hkdf::Hkdf::<sha2::Sha256>::new(Some(salt.as_bytes()), master_key);
1000 hkdf.expand(b"identity-encryption", &mut key).map_err(|_| {
1001 P2PError::Security(SecurityError::KeyGenerationFailed(
1002 "HKDF expansion failed".into(),
1003 ))
1004 })?;
1005
1006 Ok(key)
1007 }
1008
1009 pub async fn create_sync_package(
1011 &self,
1012 identity_id: &UserId,
1013 password: &SecureString,
1014 device_password: &SecureString,
1015 ) -> Result<IdentitySyncPackage> {
1016 let identity = self.load_identity(identity_id, password).await?;
1018
1019 let identity_data = serde_json::to_vec(&identity)
1021 .map_err(|e| P2PError::Serialization(e.to_string().into()))?;
1022
1023 let master_seed = self
1025 .key_storage
1026 .retrieve_master_seed(&identity_id.to_string(), password)
1027 .await?;
1028
1029 let key_data = master_seed.seed_material().to_vec();
1030
1031 let mut salt = [0u8; 32];
1033 let mut nonce = [0u8; 12];
1034 rand::RngCore::fill_bytes(&mut thread_rng(), &mut salt);
1035 rand::RngCore::fill_bytes(&mut thread_rng(), &mut nonce);
1036
1037 let encryption_key = self.derive_encryption_key(device_password, &salt)?;
1039
1040 let encrypted_identity = self.encrypt_data(&identity_data, &encryption_key, &nonce)?;
1042 let encrypted_keys = self.encrypt_data(&key_data, &encryption_key, &nonce)?;
1043
1044 let mut device_fingerprint = [0u8; 32];
1046 rand::RngCore::fill_bytes(&mut thread_rng(), &mut device_fingerprint);
1047
1048 let mut final_encrypted_identity =
1050 Vec::with_capacity(salt.len() + nonce.len() + encrypted_identity.len());
1051 final_encrypted_identity.extend_from_slice(&salt);
1052 final_encrypted_identity.extend_from_slice(&nonce);
1053 final_encrypted_identity.extend_from_slice(&encrypted_identity);
1054
1055 let mut final_encrypted_keys =
1056 Vec::with_capacity(salt.len() + nonce.len() + encrypted_keys.len());
1057 final_encrypted_keys.extend_from_slice(&salt);
1058 final_encrypted_keys.extend_from_slice(&nonce);
1059 final_encrypted_keys.extend_from_slice(&encrypted_keys);
1060
1061 let package = IdentitySyncPackage {
1063 encrypted_identity: final_encrypted_identity,
1064 encrypted_keys: final_encrypted_keys,
1065 timestamp: current_timestamp(),
1066 device_fingerprint,
1067 signature: Vec::new(),
1068 };
1069
1070 let key_pair = self.get_key_pair(identity_id)?;
1072 let package_data = bincode::serialize(&package).map_err(|e| {
1073 P2PError::Storage(StorageError::Database(
1074 format!("Failed to serialize package: {e}").into(),
1075 ))
1076 })?;
1077 let signature = key_pair.sign(&package_data)?;
1078
1079 let mut signed_package = package;
1080 signed_package.signature = signature.to_bytes().to_vec();
1081
1082 Ok(signed_package)
1083 }
1084
1085 pub async fn import_sync_package(
1087 &self,
1088 package: &IdentitySyncPackage,
1089 device_password: &SecureString,
1090 storage_password: &SecureString,
1091 ) -> Result<Identity> {
1092 if package.encrypted_identity.len() < 44 || package.encrypted_keys.len() < 44 {
1094 return Err(P2PError::Security(SecurityError::DecryptionFailed(
1095 "Invalid encrypted data length".into(),
1096 )));
1097 }
1098
1099 let salt = &package.encrypted_identity[..32];
1100 let nonce = &package.encrypted_identity[32..44];
1101 let encrypted_identity_data = &package.encrypted_identity[44..];
1102 let encrypted_key_data = &package.encrypted_keys[44..];
1103
1104 let decryption_key = self.derive_encryption_key(device_password, salt)?;
1106
1107 let identity_data = self.decrypt_data(
1109 encrypted_identity_data,
1110 &decryption_key,
1111 nonce.try_into().map_err(|_| {
1112 P2PError::Security(SecurityError::DecryptionFailed(
1113 "Invalid nonce length".into(),
1114 ))
1115 })?,
1116 )?;
1117 let key_data = self.decrypt_data(
1118 encrypted_key_data,
1119 &decryption_key,
1120 nonce.try_into().map_err(|_| {
1121 P2PError::Security(SecurityError::DecryptionFailed(
1122 "Invalid nonce length".into(),
1123 ))
1124 })?,
1125 )?;
1126
1127 let identity: Identity = serde_json::from_slice(&identity_data)
1129 .map_err(|e| P2PError::Serialization(e.to_string().into()))?;
1130
1131 let master_seed = crate::key_derivation::MasterSeed::from_entropy(&key_data)?;
1133
1134 self.key_storage
1135 .store_master_seed(&identity.id.to_string(), &master_seed, storage_password)
1136 .await?;
1137
1138 self.save_identity(&identity, storage_password).await?;
1140
1141 self.load_identity(&identity.id, storage_password).await
1143 }
1144
1145 async fn generate_four_word_address(&self) -> Result<String> {
1149 Ok("alpha.bravo.charlie.delta".to_string())
1151 }
1152
1153 pub async fn migrate_existing_identities(&self, password: &SecureString) -> Result<()> {
1155 use tokio::fs;
1156
1157 let mut entries = fs::read_dir(&self.storage_path).await.map_err(|e| {
1159 P2PError::Storage(StorageError::Database(
1160 format!("Failed to read directory: {e}").into(),
1161 ))
1162 })?;
1163
1164 let mut migrated_count = 0;
1165
1166 while let Some(entry) = entries.next_entry().await.map_err(|e| {
1167 P2PError::Storage(StorageError::Database(
1168 format!("Failed to read directory entry: {e}").into(),
1169 ))
1170 })? {
1171 let path = entry.path();
1172
1173 if path.extension().and_then(|s| s.to_str()) == Some("json") {
1175 let plaintext_data = fs::read(&path).await.map_err(|e| {
1177 P2PError::Storage(StorageError::Database(
1178 format!("Failed to read file: {e}").into(),
1179 ))
1180 })?;
1181
1182 if let Ok(identity) = serde_json::from_slice::<Identity>(&plaintext_data) {
1184 self.save_identity(&identity, password).await?;
1186
1187 fs::remove_file(&path).await.map_err(|e| {
1189 P2PError::Storage(StorageError::Database(
1190 format!("Failed to remove old file: {e}").into(),
1191 ))
1192 })?;
1193
1194 migrated_count += 1;
1195 tracing::info!("Migrated identity {} to encrypted format", identity.id);
1196 }
1197 }
1198 }
1199
1200 if migrated_count > 0 {
1201 tracing::info!(
1202 "Successfully migrated {} identities to encrypted format",
1203 migrated_count
1204 );
1205 }
1206
1207 Ok(())
1208 }
1209
1210 fn get_key_pair(&self, identity_id: &UserId) -> Result<IdentityKeyPair> {
1212 let key_pairs = self.key_pairs.read().map_err(|_| {
1213 P2PError::Identity(IdentityError::SystemTime("read lock failed".into()))
1214 })?;
1215 key_pairs.get(identity_id).cloned().ok_or_else(|| {
1216 P2PError::Storage(crate::error::StorageError::FileNotFound(
1217 "key_pair_cache".into(),
1218 ))
1219 })
1220 }
1221
1222 pub async fn grant_access(
1224 &self,
1225 grantor_id: &UserId,
1226 grantee_id: &UserId,
1227 permissions: ProfilePermissions,
1228 password: &SecureString,
1229 ) -> Result<()> {
1230 let _grantor = self.load_identity(grantor_id, password).await?;
1232
1233 let grant = AccessGrant {
1235 grantor_id: grantor_id.clone(),
1236 grantee_id: grantee_id.clone(),
1237 permissions,
1238 granted_at: current_timestamp(),
1239 expires_at: None, };
1241
1242 let grant_data = serde_json::to_vec(&grant)
1244 .map_err(|e| P2PError::Serialization(e.to_string().into()))?;
1245
1246 let mut hasher = blake3::Hasher::new();
1248 hasher.update(b"saorsa-access-grant-v1");
1249 hasher.update(grantor_id.to_string().as_bytes());
1250 hasher.update(grantee_id.to_string().as_bytes());
1251 let grant_key_salt = hasher.finalize();
1252
1253 let mut grant_key = [0u8; 32];
1255 let encryption_key = self
1256 .derive_encryption_key_for_identity(grantor_id, password)
1257 .await?;
1258 let hkdf =
1259 hkdf::Hkdf::<sha2::Sha256>::new(Some(grant_key_salt.as_bytes()), &encryption_key);
1260 hkdf.expand(b"access-grant", &mut grant_key).map_err(|_| {
1261 P2PError::Security(SecurityError::KeyGenerationFailed(
1262 "HKDF expansion failed".into(),
1263 ))
1264 })?;
1265
1266 let mut nonce = [0u8; 12];
1268 rand::RngCore::fill_bytes(&mut thread_rng(), &mut nonce);
1269 let ciphertext = self.encrypt_data(&grant_data, &grant_key, &nonce)?;
1270
1271 let grant_path = self
1273 .storage_path
1274 .join("grants")
1275 .join(format!("{}-{}.grant", grantor_id, grantee_id));
1276 tokio::fs::create_dir_all(grant_path.parent().ok_or_else(|| {
1277 P2PError::Storage(StorageError::Database("Invalid grant path".into()))
1278 })?)
1279 .await
1280 .map_err(|e| {
1281 P2PError::Storage(StorageError::Database(
1282 format!("Failed to create grants directory: {e}").into(),
1283 ))
1284 })?;
1285
1286 let mut grant_file = Vec::with_capacity(12 + ciphertext.len());
1287 grant_file.extend_from_slice(&nonce);
1288 grant_file.extend_from_slice(&ciphertext);
1289
1290 tokio::fs::write(&grant_path, grant_file)
1291 .await
1292 .map_err(|e| {
1293 P2PError::Storage(StorageError::Database(
1294 format!("Failed to save access grant: {e}").into(),
1295 ))
1296 })?;
1297
1298 tracing::info!(
1299 "Granted {:?} access from {} to {}",
1300 permissions,
1301 grantor_id,
1302 grantee_id
1303 );
1304
1305 Ok(())
1306 }
1307
1308 pub async fn revoke_access(
1310 &self,
1311 grantor_id: &UserId,
1312 grantee_id: &UserId,
1313 password: &SecureString,
1314 ) -> Result<()> {
1315 let _grantor = self.load_identity(grantor_id, password).await?;
1317
1318 let grant_path = self
1320 .storage_path
1321 .join("grants")
1322 .join(format!("{}-{}.grant", grantor_id, grantee_id));
1323
1324 if grant_path.exists() {
1325 tokio::fs::remove_file(&grant_path).await.map_err(|e| {
1326 P2PError::Storage(StorageError::Database(
1327 format!("Failed to remove access grant: {e}").into(),
1328 ))
1329 })?;
1330
1331 tracing::info!("Revoked access from {} to {}", grantor_id, grantee_id);
1332 }
1333
1334 Ok(())
1335 }
1336
1337 pub async fn get_access_info(
1339 &self,
1340 grantor_id: &UserId,
1341 grantee_id: &UserId,
1342 password: &SecureString,
1343 ) -> Result<AccessInfo> {
1344 let grant_path = self
1346 .storage_path
1347 .join("grants")
1348 .join(format!("{}-{}.grant", grantor_id, grantee_id));
1349
1350 if !grant_path.exists() {
1351 return Err(P2PError::Identity(IdentityError::AccessDenied(
1352 "No access grant found".into(),
1353 )));
1354 }
1355
1356 let grant_data = tokio::fs::read(&grant_path).await.map_err(|e| {
1357 P2PError::Storage(StorageError::Database(
1358 format!("Failed to read access grant: {e}").into(),
1359 ))
1360 })?;
1361
1362 if grant_data.len() < 12 {
1363 return Err(P2PError::Security(SecurityError::DecryptionFailed(
1364 "Invalid grant file format".into(),
1365 )));
1366 }
1367
1368 let nonce = &grant_data[..12];
1369 let ciphertext = &grant_data[12..];
1370
1371 let mut hasher = blake3::Hasher::new();
1373 hasher.update(b"saorsa-access-grant-v1");
1374 hasher.update(grantor_id.to_string().as_bytes());
1375 hasher.update(grantee_id.to_string().as_bytes());
1376 let grant_key_salt = hasher.finalize();
1377
1378 let mut grant_key = [0u8; 32];
1379 let encryption_key = self
1380 .derive_encryption_key_for_identity(grantor_id, password)
1381 .await?;
1382 let hkdf =
1383 hkdf::Hkdf::<sha2::Sha256>::new(Some(grant_key_salt.as_bytes()), &encryption_key);
1384 hkdf.expand(b"access-grant", &mut grant_key).map_err(|_| {
1385 P2PError::Security(SecurityError::KeyGenerationFailed(
1386 "HKDF expansion failed".into(),
1387 ))
1388 })?;
1389
1390 let plaintext = self.decrypt_data(
1392 ciphertext,
1393 &grant_key,
1394 nonce.try_into().map_err(|_| {
1395 P2PError::Security(SecurityError::DecryptionFailed("Invalid nonce".into()))
1396 })?,
1397 )?;
1398
1399 let grant: AccessGrant = serde_json::from_slice(&plaintext)
1401 .map_err(|e| P2PError::Serialization(e.to_string().into()))?;
1402
1403 Ok(AccessInfo {
1404 permissions: grant.permissions,
1405 granted_at: grant.granted_at,
1406 expires_at: grant.expires_at,
1407 })
1408 }
1409
1410 async fn save_identity(&self, identity: &Identity, password: &SecureString) -> Result<()> {
1412 let identity_data = serde_json::to_vec(identity)
1414 .map_err(|e| P2PError::Serialization(e.to_string().into()))?;
1415
1416 let mut salt = [0u8; 32];
1418 let mut nonce = [0u8; 12];
1419 rand::RngCore::fill_bytes(&mut thread_rng(), &mut salt);
1420 rand::RngCore::fill_bytes(&mut thread_rng(), &mut nonce);
1421
1422 let encryption_key = self
1425 .derive_encryption_key_for_identity(&identity.id, password)
1426 .await?;
1427
1428 let ciphertext = self.encrypt_data(&identity_data, &encryption_key, &nonce)?;
1430
1431 let mut encrypted_file = Vec::with_capacity(1 + 32 + 12 + ciphertext.len());
1433 encrypted_file.push(1u8); encrypted_file.extend_from_slice(&salt);
1435 encrypted_file.extend_from_slice(&nonce);
1436 encrypted_file.extend_from_slice(&ciphertext);
1437
1438 let identity_path = self.storage_path.join(format!("{}.enc", identity.id));
1440 tokio::fs::write(&identity_path, encrypted_file)
1441 .await
1442 .map_err(|e| {
1443 P2PError::Storage(StorageError::Database(
1444 format!("Failed to save encrypted identity: {e}").into(),
1445 ))
1446 })?;
1447
1448 Ok(())
1449 }
1450
1451 async fn schedule_key_rotation_check(&self, identity_id: UserId) -> Result<()> {
1453 let manager = self.clone();
1454 let id_clone = identity_id.clone();
1455 let task = tokio::spawn(async move {
1456 loop {
1457 tokio::time::sleep(Duration::from_secs(3600)).await; let needs_rotation = {
1461 let key_pairs = manager.key_pairs.read().map_err(|_| {
1462 P2PError::Identity(IdentityError::SystemTime("read lock failed".into()))
1463 })?;
1464 key_pairs
1465 .get(&id_clone)
1466 .map(|kp| kp.needs_rotation())
1467 .unwrap_or(false)
1468 };
1469
1470 if needs_rotation {
1471 tracing::info!("Identity {:?} needs key rotation", id_clone);
1473 }
1474 }
1475 });
1476
1477 let mut tasks = self.background_tasks.write().await;
1478 tasks.insert(identity_id, task);
1479
1480 Ok(())
1481 }
1482}
1483
1484impl Clone for IdentityManager {
1486 fn clone(&self) -> Self {
1487 Self {
1488 storage_path: self.storage_path.clone(),
1489 key_storage: self.key_storage.clone(),
1490 key_derivation: self.key_derivation.clone(),
1491 verifier: self.verifier.clone(),
1492 counter_system: self.counter_system.clone(),
1493 identities: self.identities.clone(),
1494 key_pairs: self.key_pairs.clone(),
1495 background_tasks: self.background_tasks.clone(),
1496 stats: self.stats.clone(),
1497 }
1498 }
1499}
1500
1501fn current_timestamp() -> u64 {
1503 SystemTime::now()
1504 .duration_since(UNIX_EPOCH)
1505 .map(|d| d.as_secs())
1506 .unwrap_or(0)
1507}
1508
1509#[cfg(test)]
1510mod tests {
1511 use super::*;
1512 use tempfile::TempDir;
1513
1514 #[tokio::test]
1515 async fn test_identity_creation() -> Result<()> {
1516 let temp_dir = TempDir::new().expect("Failed to create temp directory");
1517 let manager = IdentityManager::new(temp_dir.path(), SecurityLevel::Fast).await?;
1518
1519 let password = SecureString::from_plain_str("test_password_123!").expect("Test assertion failed");
1520 manager.initialize(&password).await?;
1521
1522 let params = IdentityCreationParams {
1523 display_name: Some("Test User".to_string()),
1524 avatar_url: None,
1525 bio: Some("Test bio".to_string()),
1526 metadata: HashMap::new(),
1527 key_lifetime: None,
1528 derivation_path: None,
1529 };
1530
1531 let identity = manager.create_identity(&password, params).await?;
1532
1533 assert_eq!(identity.state, IdentityState::Active);
1534 assert_eq!(identity.display_name, Some("Test User".to_string()));
1535 assert!(identity.is_valid());
1536 Ok(())
1537 }
1538
1539 #[tokio::test]
1540 async fn test_identity_verification() -> Result<()> {
1541 let temp_dir = TempDir::new().expect("Failed to create temp directory");
1542 let manager = IdentityManager::new(temp_dir.path(), SecurityLevel::Fast).await?;
1543
1544 let password = SecureString::from_plain_str("test_password_123!").expect("Test assertion failed");
1545 manager.initialize(&password).await?;
1546
1547 let params = IdentityCreationParams::default();
1548 let identity = manager.create_identity(&password, params).await?;
1549
1550 let verification = manager.verify_identity(&identity).await?;
1551 assert!(verification.valid);
1552 assert_eq!(verification.trust_level, 100);
1553 assert!(verification.issues.is_empty());
1554 Ok(())
1555 }
1556
1557 #[tokio::test]
1558 async fn test_key_rotation() -> Result<()> {
1559 let temp_dir = TempDir::new().expect("Failed to create temp directory");
1560 let manager = IdentityManager::new(temp_dir.path(), SecurityLevel::Fast).await?;
1561
1562 let password = SecureString::from_plain_str("test_password_123!").expect("Test assertion failed");
1563 manager.initialize(&password).await?;
1564
1565 let params = IdentityCreationParams::default();
1566 let identity = manager.create_identity(&password, params).await?;
1567 let original_version = identity.key_version;
1568
1569 manager.rotate_keys(&identity.id, &password).await?;
1571
1572 let updated_identity = manager.load_identity(&identity.id, &password).await?;
1574 assert_eq!(updated_identity.key_version, original_version + 1);
1575 assert!(!updated_identity.previous_keys.is_empty());
1576 Ok(())
1577 }
1578
1579 #[tokio::test]
1580 async fn test_identity_revocation() -> Result<()> {
1581 let temp_dir = TempDir::new().expect("Failed to create temp directory");
1582 let manager = IdentityManager::new(temp_dir.path(), SecurityLevel::Fast).await?;
1583
1584 let password = SecureString::from_plain_str("test_password_123!").expect("Test assertion failed");
1585 manager.initialize(&password).await?;
1586
1587 let params = IdentityCreationParams::default();
1588 let identity = manager.create_identity(&password, params).await?;
1589
1590 let cert = manager
1592 .revoke_identity(
1593 &identity.id,
1594 &password,
1595 RevocationReason::UserRequested,
1596 None,
1597 )
1598 .await?;
1599
1600 assert_eq!(cert.reason, RevocationReason::UserRequested);
1601 assert!(!cert.signature.is_empty());
1602
1603 let revoked = manager.load_identity(&identity.id, &password).await?;
1605 assert_eq!(revoked.state, IdentityState::Revoked);
1606 assert!(!revoked.is_valid());
1607 Ok(())
1608 }
1609
1610 #[tokio::test]
1611 async fn test_multi_device_sync() -> Result<()> {
1612 let temp_dir = TempDir::new().expect("Failed to create temp directory");
1613 let manager1 =
1614 IdentityManager::new(temp_dir.path().join("device1"), SecurityLevel::Fast).await?;
1615
1616 let manager2 =
1617 IdentityManager::new(temp_dir.path().join("device2"), SecurityLevel::Fast).await?;
1618
1619 let password = SecureString::from_plain_str("test_password_123!").expect("Test assertion failed");
1620 let device_password =
1621 SecureString::from_plain_str("device_sync_password").expect("Test assertion failed");
1622
1623 manager1.initialize(&password).await?;
1624 manager2.initialize(&password).await?;
1625
1626 let params = IdentityCreationParams {
1628 display_name: Some("Sync Test User".to_string()),
1629 ..Default::default()
1630 };
1631
1632 let identity = manager1.create_identity(&password, params).await?;
1633
1634 let sync_package = manager1
1636 .create_sync_package(&identity.id, &password, &device_password)
1637 .await?;
1638
1639 let imported = manager2
1641 .import_sync_package(&sync_package, &device_password, &password)
1642 .await?;
1643
1644 assert_eq!(imported.id, identity.id);
1645 assert_eq!(imported.display_name, identity.display_name);
1646 Ok(())
1647 }
1648}
1649
1650pub mod migration;
1652
1653