1pub mod manager;
18
19use crate::{Result, P2PError};
20use crate::security::IPv6NodeID;
21use crate::dht::Key;
22use ed25519_dalek::{Keypair, PublicKey, Signature, Signer, Verifier};
23use rand::rngs::OsRng;
24use serde::{Deserialize, Serialize};
25use sha2::{Digest, Sha256};
26use std::collections::HashMap;
27use std::time::{Duration, SystemTime, UNIX_EPOCH};
28use uuid::Uuid;
29use aes_gcm::{Aes256Gcm, Nonce, KeyInit};
30use aes_gcm::aead::Aead;
31use blake3;
32
33pub type UserId = String;
35
36#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
38pub enum VerificationLevel {
39 Unverified,
41 SelfSigned,
43 NetworkVerified,
45 SociallyVerified,
47}
48
49#[derive(Debug, Clone, Serialize, Deserialize)]
51pub struct UserIdentity {
52 pub user_id: UserId,
54 pub public_key: Vec<u8>,
56 pub display_name_hint: String, pub three_word_address: String,
60 pub created_at: SystemTime,
62 pub version: u64,
64 pub verification_level: VerificationLevel,
66}
67
68#[derive(Debug, Clone, Serialize, Deserialize)]
70pub struct UserProfile {
71 pub display_name: String,
73 pub avatar_hash: Option<String>,
75 pub status_message: Option<String>,
77 pub created_at: SystemTime,
79 pub updated_at: SystemTime,
81 pub preferences: UserPreferences,
83 pub custom_fields: HashMap<String, String>,
85}
86
87#[derive(Debug, Clone, Serialize, Deserialize)]
89pub struct UserPreferences {
90 pub discovery: DiscoverabilitySettings,
92 pub default_permissions: ProfilePermissions,
94 pub privacy: PrivacySettings,
96}
97
98#[derive(Debug, Clone, Serialize, Deserialize)]
100pub struct ProfilePermissions {
101 pub can_see_display_name: bool,
103 pub can_see_avatar: bool,
105 pub can_see_status: bool,
107 pub can_see_contact_info: bool,
109 pub can_see_last_seen: bool,
111 pub can_see_custom_fields: bool,
113}
114
115#[derive(Debug, Clone, Serialize, Deserialize)]
117pub struct DiscoverabilitySettings {
118 pub discoverable_by_name: bool,
120 pub discoverable_by_friends: bool,
122 pub allow_contact_requests: bool,
124 pub require_mutual_friends: bool,
126 pub listed_in_directory: bool,
128}
129
130#[derive(Debug, Clone, Serialize, Deserialize)]
132pub struct PrivacySettings {
133 pub require_proof_of_humanity: bool,
135 pub max_contact_request_age: Duration,
137 pub enable_forward_secrecy: bool,
139 pub auto_rotate_keys: bool,
141 pub key_rotation_interval: Duration,
143}
144
145#[derive(Debug, Clone, Serialize, Deserialize)]
147pub struct EncryptedUserProfile {
148 pub user_id: UserId,
150 pub public_key: Vec<u8>,
152 pub encrypted_data: Vec<u8>,
154 pub nonce: [u8; 12],
156 pub access_grants: Vec<AccessGrant>,
158 pub ipv6_binding_proof: Option<IPv6BindingProof>,
160 pub signature: Vec<u8>,
162 pub updated_at: SystemTime,
164}
165
166#[derive(Debug, Clone, Serialize, Deserialize)]
168pub struct AccessGrant {
169 pub grantee_user_id: UserId,
171 pub encrypted_profile_key: Vec<u8>,
173 pub permissions: ProfilePermissions,
175 pub granted_at: SystemTime,
177 pub expires_at: Option<SystemTime>,
179 pub signature: Vec<u8>,
181}
182
183#[derive(Debug, Clone, Serialize, Deserialize)]
185pub struct IPv6BindingProof {
186 pub ipv6_identity: IPv6NodeID,
188 pub binding_signature: Vec<u8>,
190 pub mutual_signature: Vec<u8>,
192 pub created_at: SystemTime,
194}
195
196#[derive(Debug, Clone, Serialize, Deserialize)]
198pub struct IdentityChallenge {
199 pub challenge_id: String,
201 pub challenge_data: [u8; 32],
203 pub created_at: SystemTime,
205 pub expires_at: SystemTime,
207}
208
209#[derive(Debug, Clone, Serialize, Deserialize)]
211pub struct ChallengeProof {
212 pub challenge_id: String,
214 pub user_id: UserId,
216 pub signature: Vec<u8>,
218 pub timestamp: SystemTime,
220}
221
222#[derive(Debug, Clone, Serialize, Deserialize)]
224pub struct ContactRequest {
225 pub request_id: String,
227 pub from_user_id: UserId,
229 pub to_user_id: UserId,
231 pub message: Option<String>,
233 pub requested_permissions: ProfilePermissions,
235 pub sender_proof: ChallengeProof,
237 pub created_at: SystemTime,
239 pub expires_at: SystemTime,
241 pub signature: Vec<u8>,
243}
244
245#[derive(Debug, Clone, Serialize, Deserialize)]
247pub struct VerificationVoucher {
248 pub voucher_id: String,
250 pub subject_user_id: UserId,
252 pub voucher_user_id: UserId,
254 pub relationship_type: RelationshipType,
256 pub confidence: f64,
258 pub message: Option<String>,
260 pub created_at: SystemTime,
262 pub expires_at: Option<SystemTime>,
264 pub signature: Vec<u8>,
266}
267
268#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
270pub enum RelationshipType {
271 PersonalFriend,
273 Professional,
275 Family,
277 Community,
279 OnlineAcquaintance,
281 ExternalVerification,
283}
284
285impl Default for UserPreferences {
286 fn default() -> Self {
287 Self {
288 discovery: DiscoverabilitySettings {
289 discoverable_by_name: true,
290 discoverable_by_friends: true,
291 allow_contact_requests: true,
292 require_mutual_friends: false,
293 listed_in_directory: false, },
295 default_permissions: ProfilePermissions {
296 can_see_display_name: true,
297 can_see_avatar: true,
298 can_see_status: false,
299 can_see_contact_info: false,
300 can_see_last_seen: false,
301 can_see_custom_fields: false,
302 },
303 privacy: PrivacySettings {
304 require_proof_of_humanity: false,
305 max_contact_request_age: Duration::from_secs(7 * 24 * 3600), enable_forward_secrecy: true,
307 auto_rotate_keys: false,
308 key_rotation_interval: Duration::from_secs(30 * 24 * 3600), },
310 }
311 }
312}
313
314impl Default for ProfilePermissions {
315 fn default() -> Self {
316 Self {
317 can_see_display_name: true,
318 can_see_avatar: true,
319 can_see_status: false,
320 can_see_contact_info: false,
321 can_see_last_seen: false,
322 can_see_custom_fields: false,
323 }
324 }
325}
326
327impl UserIdentity {
328 pub fn new(display_name: String, three_word_address: String) -> Result<(Self, Keypair)> {
330 let mut csprng = OsRng {};
331 let keypair = Keypair::generate(&mut csprng);
332
333 let user_id = Self::derive_user_id(&keypair.public);
334 let display_name_hint = Self::create_display_name_hint(&display_name);
335
336 let identity = Self {
337 user_id,
338 public_key: keypair.public.as_bytes().to_vec(),
339 display_name_hint,
340 three_word_address,
341 created_at: SystemTime::now(),
342 version: 1,
343 verification_level: VerificationLevel::SelfSigned,
344 };
345
346 Ok((identity, keypair))
347 }
348
349 pub fn derive_user_id(public_key: &PublicKey) -> UserId {
351 let hash = Sha256::digest(public_key.as_bytes());
352 hex::encode(hash)
353 }
354
355 pub fn derive_user_id_from_bytes(public_key_bytes: &[u8]) -> UserId {
357 let hash = Sha256::digest(public_key_bytes);
358 hex::encode(hash)
359 }
360
361 fn create_display_name_hint(display_name: &str) -> String {
363 let prefix = display_name.chars().take(4).collect::<String>();
364 let hash = blake3::hash(display_name.as_bytes());
365 let hash_suffix = hex::encode(&hash.as_bytes()[..4]);
366 format!("{}:{}", prefix, hash_suffix)
367 }
368
369 pub fn verify_signature(&self, message: &[u8], signature: &Signature) -> Result<bool> {
371 let public_key = PublicKey::from_bytes(&self.public_key)
372 .map_err(|e| P2PError::Cryptography(format!("Invalid public key: {}", e)))?;
373 Ok(public_key.verify(message, signature).is_ok())
374 }
375
376 pub fn get_profile_dht_key(&self) -> Key {
378 let key_data = format!("user_profile:{}", self.user_id);
379 Key::new(key_data.as_bytes())
380 }
381
382 pub fn get_name_resolution_dht_key(display_name: &str) -> Key {
384 let key_data = format!("user_name:{}", display_name.to_lowercase());
385 Key::new(key_data.as_bytes())
386 }
387}
388
389impl UserProfile {
390 pub fn new(display_name: String) -> Self {
392 let now = SystemTime::now();
393 Self {
394 display_name,
395 avatar_hash: None,
396 status_message: None,
397 created_at: now,
398 updated_at: now,
399 preferences: UserPreferences::default(),
400 custom_fields: HashMap::new(),
401 }
402 }
403
404 pub fn update(&mut self) {
406 self.updated_at = SystemTime::now();
407 }
408
409 pub fn set_avatar(&mut self, image_data: &[u8]) {
411 self.avatar_hash = Some(hex::encode(blake3::hash(image_data).as_bytes()));
412 self.update();
413 }
414
415 pub fn apply_permissions(&self, permissions: &ProfilePermissions) -> Self {
417 let mut filtered = self.clone();
418
419 if !permissions.can_see_display_name {
420 filtered.display_name = "Hidden".to_string();
421 }
422
423 if !permissions.can_see_avatar {
424 filtered.avatar_hash = None;
425 }
426
427 if !permissions.can_see_status {
428 filtered.status_message = None;
429 }
430
431 if !permissions.can_see_custom_fields {
432 filtered.custom_fields.clear();
433 }
434
435 filtered
436 }
437}
438
439impl EncryptedUserProfile {
440 pub fn new(
442 identity: &UserIdentity,
443 profile: &UserProfile,
444 keypair: &Keypair,
445 ipv6_binding: Option<IPv6BindingProof>,
446 ) -> Result<Self> {
447 let profile_key = Self::generate_profile_key();
449
450 let profile_data = serde_json::to_vec(profile)
452 .map_err(P2PError::Serialization)?;
453
454 let (encrypted_data, nonce) = Self::encrypt_data(&profile_data, &profile_key)?;
455
456 let signature = keypair.sign(&encrypted_data).to_bytes().to_vec();
458
459 Ok(Self {
460 user_id: identity.user_id.clone(),
461 public_key: identity.public_key.clone(),
462 encrypted_data,
463 nonce,
464 access_grants: Vec::new(),
465 ipv6_binding_proof: ipv6_binding,
466 signature,
467 updated_at: SystemTime::now(),
468 })
469 }
470
471 fn generate_profile_key() -> [u8; 32] {
473 let mut key = [0u8; 32];
474 use rand::RngCore;
475 OsRng.fill_bytes(&mut key);
476 key
477 }
478
479 fn encrypt_data(data: &[u8], key: &[u8; 32]) -> Result<(Vec<u8>, [u8; 12])> {
481 let cipher = Aes256Gcm::new_from_slice(key)
482 .map_err(|e| P2PError::Cryptography(format!("Cipher initialization failed: {}", e)))?;
483
484 let mut nonce_bytes = [0u8; 12];
486 use rand::RngCore;
487 OsRng.fill_bytes(&mut nonce_bytes);
488 let nonce = Nonce::from_slice(&nonce_bytes);
489
490 let ciphertext = cipher.encrypt(nonce, data)
491 .map_err(|e| P2PError::Cryptography(format!("Profile encryption failed: {}", e)))?;
492
493 Ok((ciphertext, nonce_bytes))
494 }
495
496 fn decrypt_data(ciphertext: &[u8], key: &[u8; 32], nonce: &[u8; 12]) -> Result<Vec<u8>> {
498 let cipher = Aes256Gcm::new_from_slice(key)
499 .map_err(|e| P2PError::Cryptography(format!("Cipher initialization failed: {}", e)))?;
500 let nonce = Nonce::from_slice(nonce);
501
502 cipher.decrypt(nonce, ciphertext)
503 .map_err(|e| P2PError::Cryptography(format!("Profile decryption failed: {}", e)))
504 }
505
506 pub fn grant_access(
508 &mut self,
509 grantee_user_id: UserId,
510 grantee_public_key_bytes: &[u8],
511 permissions: ProfilePermissions,
512 profile_key: &[u8; 32],
513 granter_keypair: &Keypair,
514 ) -> Result<()> {
515 let encrypted_key = self.encrypt_key_for_user(profile_key, grantee_public_key_bytes)?;
517
518 let grant_data = format!("{}:{}:{}",
520 grantee_user_id,
521 serde_json::to_string(&permissions).unwrap_or_default(),
522 SystemTime::now().duration_since(UNIX_EPOCH).unwrap_or_default().as_secs()
523 );
524
525 let signature = granter_keypair.sign(grant_data.as_bytes()).to_bytes().to_vec();
526
527 let grant = AccessGrant {
528 grantee_user_id,
529 encrypted_profile_key: encrypted_key,
530 permissions,
531 granted_at: SystemTime::now(),
532 expires_at: None,
533 signature,
534 };
535
536 self.access_grants.retain(|g| g.grantee_user_id != grant.grantee_user_id);
538 self.access_grants.push(grant);
539
540 self.updated_at = SystemTime::now();
541 Ok(())
542 }
543
544 pub fn revoke_access(&mut self, user_id: &UserId) {
546 self.access_grants.retain(|grant| grant.grantee_user_id != *user_id);
547 self.updated_at = SystemTime::now();
548 }
549
550 pub fn decrypt_profile(&self, profile_key: &[u8; 32]) -> Result<UserProfile> {
552 let decrypted_data = Self::decrypt_data(&self.encrypted_data, profile_key, &self.nonce)?;
553
554 serde_json::from_slice(&decrypted_data)
555 .map_err(|e| P2PError::Serialization(e))
556 }
557
558 pub fn get_access_grant(&self, user_id: &UserId) -> Option<&AccessGrant> {
560 self.access_grants.iter().find(|grant| grant.grantee_user_id == *user_id)
561 }
562
563 pub fn is_grant_valid(grant: &AccessGrant) -> bool {
565 if let Some(expires_at) = grant.expires_at {
566 SystemTime::now() < expires_at
567 } else {
568 true }
570 }
571
572 pub fn verify_signature(&self) -> Result<bool> {
574 if let (Ok(signature), Ok(public_key)) = (
575 ed25519_dalek::Signature::from_bytes(&self.signature),
576 PublicKey::from_bytes(&self.public_key)
577 ) {
578 Ok(public_key.verify(&self.encrypted_data, &signature).is_ok())
579 } else {
580 Ok(false)
581 }
582 }
583
584 fn encrypt_key_for_user(&self, key: &[u8; 32], recipient_public_key_bytes: &[u8]) -> Result<Vec<u8>> {
586 let mut encrypted_key = key.to_vec();
590 let public_key_hash = Sha256::digest(recipient_public_key_bytes);
591
592 for (i, byte) in encrypted_key.iter_mut().enumerate() {
593 *byte ^= public_key_hash[i % public_key_hash.len()];
594 }
595
596 Ok(encrypted_key)
597 }
598}
599
600impl IPv6BindingProof {
601 pub fn new(
603 ipv6_identity: IPv6NodeID,
604 user_keypair: &Keypair,
605 ipv6_keypair: &ed25519_dalek::Keypair,
606 ) -> Result<Self> {
607 let binding_signature = user_keypair.sign(&ipv6_identity.public_key).to_bytes().to_vec();
609
610 let mutual_signature = ipv6_keypair.sign(user_keypair.public.as_bytes()).to_bytes().to_vec();
612
613 Ok(Self {
614 ipv6_identity,
615 binding_signature,
616 mutual_signature,
617 created_at: SystemTime::now(),
618 })
619 }
620
621 pub fn verify(&self, user_public_key_bytes: &[u8]) -> Result<bool> {
623 let user_sig_valid = if let (Ok(signature), Ok(user_public_key)) = (
625 ed25519_dalek::Signature::from_bytes(&self.binding_signature),
626 PublicKey::from_bytes(user_public_key_bytes)
627 ) {
628 user_public_key
629 .verify(&self.ipv6_identity.public_key, &signature)
630 .is_ok()
631 } else {
632 false
633 };
634
635 let ipv6_sig_valid = !self.mutual_signature.is_empty();
639
640 Ok(user_sig_valid && ipv6_sig_valid)
641 }
642}
643
644impl IdentityChallenge {
645 pub fn new(duration: Duration) -> Self {
647 let mut challenge_data = [0u8; 32];
648 use rand::RngCore;
649 OsRng.fill_bytes(&mut challenge_data);
650
651 let now = SystemTime::now();
652 Self {
653 challenge_id: Uuid::new_v4().to_string(),
654 challenge_data,
655 created_at: now,
656 expires_at: now + duration,
657 }
658 }
659
660 pub fn is_valid(&self) -> bool {
662 SystemTime::now() < self.expires_at
663 }
664
665 pub fn create_response(&self, user_id: UserId, keypair: &Keypair) -> Result<ChallengeProof> {
667 if !self.is_valid() {
668 return Err(P2PError::InvalidState("Challenge expired".to_string()));
669 }
670
671 let signature = keypair.sign(&self.challenge_data).to_bytes().to_vec();
672
673 Ok(ChallengeProof {
674 challenge_id: self.challenge_id.clone(),
675 user_id,
676 signature,
677 timestamp: SystemTime::now(),
678 })
679 }
680}
681
682impl ChallengeProof {
683 pub fn verify(&self, challenge: &IdentityChallenge, public_key_bytes: &[u8]) -> Result<bool> {
685 if self.challenge_id != challenge.challenge_id {
686 return Ok(false);
687 }
688
689 if !challenge.is_valid() {
690 return Ok(false);
691 }
692
693 if let (Ok(signature), Ok(public_key)) = (
694 ed25519_dalek::Signature::from_bytes(&self.signature),
695 PublicKey::from_bytes(public_key_bytes)
696 ) {
697 Ok(public_key.verify(&challenge.challenge_data, &signature).is_ok())
698 } else {
699 Ok(false)
700 }
701 }
702}
703
704#[cfg(test)]
705mod tests {
706 use super::*;
707 use std::str::FromStr;
708
709 fn create_test_identity() -> (UserIdentity, Keypair) {
710 UserIdentity::new(
711 "TestUser".to_string(),
712 "test.user.example".to_string(),
713 ).unwrap()
714 }
715
716 #[test]
717 fn test_user_identity_creation() {
718 let (identity, keypair) = create_test_identity();
719
720 assert_eq!(identity.display_name_hint, "Test:a665a45920");
721 assert_eq!(identity.three_word_address, "test.user.example");
722 assert_eq!(identity.verification_level, VerificationLevel::SelfSigned);
723 assert_eq!(identity.version, 1);
724 assert_eq!(identity.user_id, UserIdentity::derive_user_id(&keypair.public));
725 }
726
727 #[test]
728 fn test_user_profile_creation() {
729 let profile = UserProfile::new("Test User".to_string());
730
731 assert_eq!(profile.display_name, "Test User");
732 assert!(profile.avatar_hash.is_none());
733 assert!(profile.status_message.is_none());
734 assert_eq!(profile.preferences.discovery.discoverable_by_name, true);
735 assert_eq!(profile.preferences.default_permissions.can_see_display_name, true);
736 }
737
738 #[test]
739 fn test_encrypted_profile_creation() {
740 let (identity, keypair) = create_test_identity();
741 let profile = UserProfile::new("Test User".to_string());
742
743 let encrypted_profile = EncryptedUserProfile::new(
744 &identity,
745 &profile,
746 &keypair,
747 None,
748 ).unwrap();
749
750 assert_eq!(encrypted_profile.user_id, identity.user_id);
751 assert_eq!(encrypted_profile.public_key, identity.public_key);
752 assert!(!encrypted_profile.encrypted_data.is_empty());
753 assert!(encrypted_profile.verify_signature().unwrap());
754 }
755
756 #[test]
757 fn test_access_grant_system() {
758 let (identity1, keypair1) = create_test_identity();
759 let (identity2, _keypair2) = create_test_identity();
760 let profile = UserProfile::new("Test User".to_string());
761
762 let mut encrypted_profile = EncryptedUserProfile::new(
763 &identity1,
764 &profile,
765 &keypair1,
766 None,
767 ).unwrap();
768
769 let profile_key = EncryptedUserProfile::generate_profile_key();
770 let permissions = ProfilePermissions::default();
771
772 encrypted_profile.grant_access(
774 identity2.user_id.clone(),
775 &identity2.public_key,
776 permissions.clone(),
777 &profile_key,
778 &keypair1,
779 ).unwrap();
780
781 let grant = encrypted_profile.get_access_grant(&identity2.user_id);
783 assert!(grant.is_some());
784 assert_eq!(grant.unwrap().permissions.can_see_display_name, permissions.can_see_display_name);
785
786 encrypted_profile.revoke_access(&identity2.user_id);
788 assert!(encrypted_profile.get_access_grant(&identity2.user_id).is_none());
789 }
790
791 #[test]
792 fn test_identity_challenge() {
793 let challenge = IdentityChallenge::new(Duration::from_secs(300));
794 let (identity, keypair) = create_test_identity();
795
796 assert!(challenge.is_valid());
797
798 let proof = challenge.create_response(
799 identity.user_id.clone(),
800 &keypair,
801 ).unwrap();
802
803 assert_eq!(proof.challenge_id, challenge.challenge_id);
804 assert_eq!(proof.user_id, identity.user_id);
805 assert!(proof.verify(&challenge, &identity.public_key).unwrap());
806 }
807
808 #[test]
809 fn test_profile_permissions_filtering() {
810 let mut profile = UserProfile::new("Test User".to_string());
811 profile.status_message = Some("Hello world".to_string());
812 profile.set_avatar(b"fake_image_data");
813
814 let restricted_permissions = ProfilePermissions {
815 can_see_display_name: false,
816 can_see_avatar: false,
817 can_see_status: false,
818 ..Default::default()
819 };
820
821 let filtered_profile = profile.apply_permissions(&restricted_permissions);
822
823 assert_eq!(filtered_profile.display_name, "Hidden");
824 assert!(filtered_profile.avatar_hash.is_none());
825 assert!(filtered_profile.status_message.is_none());
826 }
827
828 #[test]
829 fn test_user_id_derivation() {
830 let (identity1, keypair1) = create_test_identity();
831 let (identity2, keypair2) = create_test_identity();
832
833 let derived_id1 = UserIdentity::derive_user_id(&keypair1.public);
835 assert_eq!(identity1.user_id, derived_id1);
836
837 assert_ne!(identity1.user_id, identity2.user_id);
839 assert_ne!(derived_id1, UserIdentity::derive_user_id(&keypair2.public));
840 }
841
842 #[test]
843 fn test_dht_key_generation() {
844 let (identity, _keypair) = create_test_identity();
845
846 let profile_key = identity.get_profile_dht_key();
847 let name_key = UserIdentity::get_name_resolution_dht_key("TestUser");
848
849 assert_eq!(profile_key, identity.get_profile_dht_key());
851 assert_eq!(name_key, UserIdentity::get_name_resolution_dht_key("TestUser"));
852
853 assert_ne!(profile_key, name_key);
855 }
856}