From 32fc926de0d08f1f430b2586411f6001b38d538e Mon Sep 17 00:00:00 2001 From: continuist Date: Sat, 1 Nov 2025 12:29:02 -0400 Subject: [PATCH] Fix encrypted dob issue --- frontend/wasm/Cargo.lock | 64 ++++++++++---------- frontend/wasm/Cargo.toml | 2 +- frontend/wasm/src/lib.rs | 2 +- passport/Cargo.lock | 2 +- passport/Cargo.toml | 2 +- passport/src/infrastructure/crypto/native.rs | 36 +++++++++-- passport/src/infrastructure/crypto/wasm.rs | 36 +++++++++-- 7 files changed, 95 insertions(+), 49 deletions(-) diff --git a/frontend/wasm/Cargo.lock b/frontend/wasm/Cargo.lock index 419e5df..d3cad73 100644 --- a/frontend/wasm/Cargo.lock +++ b/frontend/wasm/Cargo.lock @@ -415,6 +415,36 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" +[[package]] +name = "passport" +version = "0.4.1" +dependencies = [ + "async-trait", + "base64", + "bip39", + "chacha20poly1305", + "ciborium", + "ed25519-dalek", + "getrandom 0.2.16", + "gloo-storage", + "hex", + "hkdf", + "js-sys", + "rand", + "rand_core", + "serde", + "serde-wasm-bindgen", + "serde_cbor", + "serde_json", + "sha2", + "thiserror", + "uuid", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-time", + "zeroize", +] + [[package]] name = "pkcs8" version = "0.10.2" @@ -601,47 +631,15 @@ dependencies = [ "digest", ] -[[package]] -name = "sharenet-passport" -version = "0.4.0" -source = "sparse+https://git.sharenet.sh/api/packages/devteam/cargo/" -checksum = "bec9d785a802bbfcd6a84f72f2a53e50729847a68ed5f4e6ea1310177bfe4c43" -dependencies = [ - "async-trait", - "base64", - "bip39", - "chacha20poly1305", - "ciborium", - "ed25519-dalek", - "getrandom 0.2.16", - "gloo-storage", - "hex", - "hkdf", - "js-sys", - "rand", - "rand_core", - "serde", - "serde-wasm-bindgen", - "serde_cbor", - "serde_json", - "sha2", - "thiserror", - "uuid", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-time", - "zeroize", -] - [[package]] name = "sharenet-passport-wasm" version = "0.1.0" dependencies = [ "getrandom 0.2.16", + "passport", "serde", "serde-wasm-bindgen", "serde_cbor", - "sharenet-passport", "uuid", "wasm-bindgen", ] diff --git a/frontend/wasm/Cargo.toml b/frontend/wasm/Cargo.toml index 0432002..6ff3b71 100644 --- a/frontend/wasm/Cargo.toml +++ b/frontend/wasm/Cargo.toml @@ -11,7 +11,7 @@ wasm-bindgen = "0.2.105" serde = { version = "1.0", features = ["derive"] } serde-wasm-bindgen = "0.6" serde_cbor = "0.11" -sharenet-passport = { version = "0.4.0", registry = "sharenet-sh-forgejo", features = ["force-wasm"] } +passport = { path = "../../passport", features = ["force-wasm"] } # WASM-compatible random number generation getrandom = { version = "0.2", features = ["js"] } diff --git a/frontend/wasm/src/lib.rs b/frontend/wasm/src/lib.rs index d8acb33..119a6a7 100644 --- a/frontend/wasm/src/lib.rs +++ b/frontend/wasm/src/lib.rs @@ -1,4 +1,4 @@ use wasm_bindgen::prelude::*; // Re-export all functions from the sharenet-passport crate -pub use sharenet_passport::wasm::*; \ No newline at end of file +pub use passport::wasm::*; \ No newline at end of file diff --git a/passport/Cargo.lock b/passport/Cargo.lock index a570e8d..425828c 100644 --- a/passport/Cargo.lock +++ b/passport/Cargo.lock @@ -445,7 +445,7 @@ checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" [[package]] name = "passport" -version = "0.4.0" +version = "0.4.1" dependencies = [ "async-trait", "base64", diff --git a/passport/Cargo.toml b/passport/Cargo.toml index 9ad4a6d..3009148 100644 --- a/passport/Cargo.toml +++ b/passport/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "passport" -version = "0.4.0" +version = "0.4.1" publish = ["sharenet-sh-forgejo"] # Set this to whichever Cargo registry you are publishing to edition = "2021" description = "Core library for Sharenet Passport creation and management" diff --git a/passport/src/infrastructure/crypto/native.rs b/passport/src/infrastructure/crypto/native.rs index d4d16b9..cb4e28c 100644 --- a/passport/src/infrastructure/crypto/native.rs +++ b/passport/src/infrastructure/crypto/native.rs @@ -123,15 +123,29 @@ impl FileEncryptor for XChaCha20FileEncryptor { // Serialize and encrypt date of birth let date_of_birth_bytes = serde_cbor::to_vec(&date_of_birth) .map_err(|e| DomainError::CryptographicError(format!("Failed to serialize date of birth: {}", e)))?; + // Ensure we have data to encrypt (even for None values) + let date_of_birth_payload = if date_of_birth_bytes.is_empty() { + // For None values, use a minimal placeholder to ensure encryption works + vec![0u8] + } else { + date_of_birth_bytes + }; let enc_date_of_birth = cipher - .encrypt(&nonce, &*date_of_birth_bytes) + .encrypt(&nonce, &*date_of_birth_payload) .map_err(|e| DomainError::CryptographicError(format!("Date of birth encryption failed: {}", e)))?; // Serialize and encrypt default user profile ID let default_user_profile_id_bytes = serde_cbor::to_vec(&default_user_profile_id) .map_err(|e| DomainError::CryptographicError(format!("Failed to serialize default user profile ID: {}", e)))?; + // Ensure we have data to encrypt (even for None values) + let default_user_profile_id_payload = if default_user_profile_id_bytes.is_empty() { + // For None values, use a minimal placeholder to ensure encryption works + vec![0u8] + } else { + default_user_profile_id_bytes + }; let enc_default_user_profile_id = cipher - .encrypt(&nonce, &*default_user_profile_id_bytes) + .encrypt(&nonce, &*default_user_profile_id_payload) .map_err(|e| DomainError::CryptographicError(format!("Default user profile ID encryption failed: {}", e)))?; // Get current timestamp @@ -202,15 +216,25 @@ impl FileEncryptor for XChaCha20FileEncryptor { let date_of_birth_bytes = cipher .decrypt(&nonce, &*file.enc_date_of_birth) .map_err(|e| DomainError::CryptographicError(format!("Date of birth decryption failed: {}", e)))?; - let date_of_birth: Option = serde_cbor::from_slice(&date_of_birth_bytes) - .map_err(|e| DomainError::CryptographicError(format!("Failed to deserialize date of birth: {}", e)))?; + // Handle the case where we used a placeholder for None values + let date_of_birth: Option = if date_of_birth_bytes == vec![0u8] { + None + } else { + serde_cbor::from_slice(&date_of_birth_bytes) + .map_err(|e| DomainError::CryptographicError(format!("Failed to deserialize date of birth: {}", e)))? + }; // Decrypt default user profile ID let default_user_profile_id_bytes = cipher .decrypt(&nonce, &*file.enc_default_user_profile_id) .map_err(|e| DomainError::CryptographicError(format!("Default user profile ID decryption failed: {}", e)))?; - let default_user_profile_id: Option = serde_cbor::from_slice(&default_user_profile_id_bytes) - .map_err(|e| DomainError::CryptographicError(format!("Failed to deserialize default user profile ID: {}", e)))?; + // Handle the case where we used a placeholder for None values + let default_user_profile_id: Option = if default_user_profile_id_bytes == vec![0u8] { + None + } else { + serde_cbor::from_slice(&default_user_profile_id_bytes) + .map_err(|e| DomainError::CryptographicError(format!("Failed to deserialize default user profile ID: {}", e)))? + }; // Note: univ_id is stored in the PassportFile and will be used when creating the Passport Ok((seed, public_key, private_key, user_profiles, date_of_birth, default_user_profile_id)) diff --git a/passport/src/infrastructure/crypto/wasm.rs b/passport/src/infrastructure/crypto/wasm.rs index e256b6e..e596717 100644 --- a/passport/src/infrastructure/crypto/wasm.rs +++ b/passport/src/infrastructure/crypto/wasm.rs @@ -125,15 +125,29 @@ impl FileEncryptor for XChaCha20FileEncryptor { // Serialize and encrypt date of birth let date_of_birth_bytes = serde_cbor::to_vec(&date_of_birth) .map_err(|e| DomainError::CryptographicError(format!("Failed to serialize date of birth: {}", e)))?; + // Ensure we have data to encrypt (even for None values) + let date_of_birth_payload = if date_of_birth_bytes.is_empty() { + // For None values, use a minimal placeholder to ensure encryption works + vec![0u8] + } else { + date_of_birth_bytes + }; let enc_date_of_birth = cipher - .encrypt(&nonce, &*date_of_birth_bytes) + .encrypt(&nonce, &*date_of_birth_payload) .map_err(|e| DomainError::CryptographicError(format!("Date of birth encryption failed: {}", e)))?; // Serialize and encrypt default user profile ID let default_user_profile_id_bytes = serde_cbor::to_vec(&default_user_profile_id) .map_err(|e| DomainError::CryptographicError(format!("Failed to serialize default user profile ID: {}", e)))?; + // Ensure we have data to encrypt (even for None values) + let default_user_profile_id_payload = if default_user_profile_id_bytes.is_empty() { + // For None values, use a minimal placeholder to ensure encryption works + vec![0u8] + } else { + default_user_profile_id_bytes + }; let enc_default_user_profile_id = cipher - .encrypt(&nonce, &*default_user_profile_id_bytes) + .encrypt(&nonce, &*default_user_profile_id_payload) .map_err(|e| DomainError::CryptographicError(format!("Default user profile ID encryption failed: {}", e)))?; // Get current timestamp using WASM-compatible time @@ -201,15 +215,25 @@ impl FileEncryptor for XChaCha20FileEncryptor { let date_of_birth_bytes = cipher .decrypt(&nonce, &*file.enc_date_of_birth) .map_err(|e| DomainError::CryptographicError(format!("Date of birth decryption failed: {}", e)))?; - let date_of_birth: Option = serde_cbor::from_slice(&date_of_birth_bytes) - .map_err(|e| DomainError::CryptographicError(format!("Failed to deserialize date of birth: {}", e)))?; + // Handle the case where we used a placeholder for None values + let date_of_birth: Option = if date_of_birth_bytes == vec![0u8] { + None + } else { + serde_cbor::from_slice(&date_of_birth_bytes) + .map_err(|e| DomainError::CryptographicError(format!("Failed to deserialize date of birth: {}", e)))? + }; // Decrypt default user profile ID let default_user_profile_id_bytes = cipher .decrypt(&nonce, &*file.enc_default_user_profile_id) .map_err(|e| DomainError::CryptographicError(format!("Default user profile ID decryption failed: {}", e)))?; - let default_user_profile_id: Option = serde_cbor::from_slice(&default_user_profile_id_bytes) - .map_err(|e| DomainError::CryptographicError(format!("Failed to deserialize default user profile ID: {}", e)))?; + // Handle the case where we used a placeholder for None values + let default_user_profile_id: Option = if default_user_profile_id_bytes == vec![0u8] { + None + } else { + serde_cbor::from_slice(&default_user_profile_id_bytes) + .map_err(|e| DomainError::CryptographicError(format!("Failed to deserialize default user profile ID: {}", e)))? + }; // Note: univ_id is stored in the PassportFile and will be used when creating the Passport Ok((seed, public_key, private_key, user_profiles, date_of_birth, default_user_profile_id))