fix crypto
s
This commit is contained in:
		| @@ -66,7 +66,11 @@ impl Envelope { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     pub fn from_signed_data(crypto: Crypto, data: &[u8]) -> VeilidAPIResult<Envelope> { | ||||
|     pub fn from_signed_data( | ||||
|         crypto: Crypto, | ||||
|         data: &[u8], | ||||
|         network_key: &Option<SharedSecret>, | ||||
|     ) -> VeilidAPIResult<Envelope> { | ||||
|         // Ensure we are at least the length of the envelope | ||||
|         // Silent drop here, as we use zero length packets as part of the protocol for hole punching | ||||
|         if data.len() < MIN_ENVELOPE_SIZE { | ||||
| @@ -135,9 +139,22 @@ impl Envelope { | ||||
|         let recipient_id_slice: [u8; PUBLIC_KEY_LENGTH] = data[0x4A..0x6A] | ||||
|             .try_into() | ||||
|             .map_err(VeilidAPIError::internal)?; | ||||
|         let nonce: Nonce = Nonce::new(nonce_slice); | ||||
|         let sender_id = PublicKey::new(sender_id_slice); | ||||
|         let recipient_id = PublicKey::new(recipient_id_slice); | ||||
|         let mut nonce: Nonce = Nonce::new(nonce_slice); | ||||
|         let mut sender_id = PublicKey::new(sender_id_slice); | ||||
|         let mut recipient_id = PublicKey::new(recipient_id_slice); | ||||
|  | ||||
|         // Apply network key (not the best, but it will keep networks from colliding without much overhead) | ||||
|         if let Some(nk) = network_key.as_ref() { | ||||
|             for n in 0..NONCE_LENGTH { | ||||
|                 nonce.bytes[n] ^= nk.bytes[n]; | ||||
|             } | ||||
|             for n in 0..CRYPTO_KEY_LENGTH { | ||||
|                 sender_id.bytes[n] ^= nk.bytes[n]; | ||||
|             } | ||||
|             for n in 0..CRYPTO_KEY_LENGTH { | ||||
|                 recipient_id.bytes[n] ^= nk.bytes[n]; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // Ensure sender_id and recipient_id are not the same | ||||
|         if sender_id == recipient_id { | ||||
| @@ -175,13 +192,20 @@ impl Envelope { | ||||
|         crypto: Crypto, | ||||
|         data: &[u8], | ||||
|         node_id_secret: &SecretKey, | ||||
|         network_key: &Option<SharedSecret>, | ||||
|     ) -> VeilidAPIResult<Vec<u8>> { | ||||
|         // Get DH secret | ||||
|         let vcrypto = crypto | ||||
|             .get(self.crypto_kind) | ||||
|             .expect("need to ensure only valid crypto kinds here"); | ||||
|         let dh_secret = vcrypto.cached_dh(&self.sender_id, node_id_secret)?; | ||||
|         let mut dh_secret = vcrypto.cached_dh(&self.sender_id, node_id_secret)?; | ||||
|  | ||||
|         // Apply network key | ||||
|         if let Some(nk) = network_key.as_ref() { | ||||
|             for n in 0..CRYPTO_KEY_LENGTH { | ||||
|                 dh_secret.bytes[n] ^= nk.bytes[n]; | ||||
|             } | ||||
|         } | ||||
|         // Decrypt message without authentication | ||||
|         let body = vcrypto.crypt_no_auth_aligned_8( | ||||
|             &data[0x6A..data.len() - 64], | ||||
| @@ -197,6 +221,7 @@ impl Envelope { | ||||
|         crypto: Crypto, | ||||
|         body: &[u8], | ||||
|         node_id_secret: &SecretKey, | ||||
|         network_key: &Option<SharedSecret>, | ||||
|     ) -> VeilidAPIResult<Vec<u8>> { | ||||
|         // Ensure body isn't too long | ||||
|         let envelope_size: usize = body.len() + MIN_ENVELOPE_SIZE; | ||||
| @@ -207,7 +232,7 @@ impl Envelope { | ||||
|         let vcrypto = crypto | ||||
|             .get(self.crypto_kind) | ||||
|             .expect("need to ensure only valid crypto kinds here"); | ||||
|         let dh_secret = vcrypto.cached_dh(&self.recipient_id, node_id_secret)?; | ||||
|         let mut dh_secret = vcrypto.cached_dh(&self.recipient_id, node_id_secret)?; | ||||
|  | ||||
|         // Write envelope body | ||||
|         let mut data = vec![0u8; envelope_size]; | ||||
| @@ -229,6 +254,22 @@ impl Envelope { | ||||
|         // Write recipient node id | ||||
|         data[0x4A..0x6A].copy_from_slice(&self.recipient_id.bytes); | ||||
|  | ||||
|         // Apply network key (not the best, but it will keep networks from colliding without much overhead) | ||||
|         if let Some(nk) = network_key.as_ref() { | ||||
|             for n in 0..SECRET_KEY_LENGTH { | ||||
|                 dh_secret.bytes[n] ^= nk.bytes[n]; | ||||
|             } | ||||
|             for n in 0..NONCE_LENGTH { | ||||
|                 data[0x12 + n] ^= nk.bytes[n]; | ||||
|             } | ||||
|             for n in 0..CRYPTO_KEY_LENGTH { | ||||
|                 data[0x2A + n] ^= nk.bytes[n]; | ||||
|             } | ||||
|             for n in 0..CRYPTO_KEY_LENGTH { | ||||
|                 data[0x4A + n] ^= nk.bytes[n]; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // Encrypt and authenticate message | ||||
|         let encrypted_body = vcrypto.crypt_no_auth_unaligned(body, &self.nonce.bytes, &dh_secret); | ||||
|  | ||||
|   | ||||
| @@ -3,8 +3,16 @@ use super::*; | ||||
| pub async fn test_envelope_round_trip( | ||||
|     envelope_version: EnvelopeVersion, | ||||
|     vcrypto: CryptoSystemVersion, | ||||
|     network_key: Option<SharedSecret>, | ||||
| ) { | ||||
|     info!("--- test envelope round trip ---"); | ||||
|     if network_key.is_some() { | ||||
|         info!( | ||||
|             "--- test envelope round trip {} w/network key ---", | ||||
|             vcrypto.kind() | ||||
|         ); | ||||
|     } else { | ||||
|         info!("--- test envelope round trip {} ---", vcrypto.kind()); | ||||
|     } | ||||
|  | ||||
|     // Create envelope | ||||
|     let ts = Timestamp::from(0x12345678ABCDEF69u64); | ||||
| @@ -25,15 +33,15 @@ pub async fn test_envelope_round_trip( | ||||
|  | ||||
|     // Serialize to bytes | ||||
|     let enc_data = envelope | ||||
|         .to_encrypted_data(vcrypto.crypto(), body, &sender_secret) | ||||
|         .to_encrypted_data(vcrypto.crypto(), body, &sender_secret, &network_key) | ||||
|         .expect("failed to encrypt data"); | ||||
|  | ||||
|     // Deserialize from bytes | ||||
|     let envelope2 = Envelope::from_signed_data(vcrypto.crypto(), &enc_data) | ||||
|     let envelope2 = Envelope::from_signed_data(vcrypto.crypto(), &enc_data, &network_key) | ||||
|         .expect("failed to deserialize envelope from data"); | ||||
|  | ||||
|     let body2 = envelope2 | ||||
|         .decrypt_body(vcrypto.crypto(), &enc_data, &recipient_secret) | ||||
|         .decrypt_body(vcrypto.crypto(), &enc_data, &recipient_secret, &network_key) | ||||
|         .expect("failed to decrypt envelope body"); | ||||
|  | ||||
|     // Compare envelope and body | ||||
| @@ -45,13 +53,13 @@ pub async fn test_envelope_round_trip( | ||||
|     let mut mod_enc_data = enc_data.clone(); | ||||
|     mod_enc_data[enc_data_len - 1] ^= 0x80u8; | ||||
|     assert!( | ||||
|         Envelope::from_signed_data(vcrypto.crypto(), &mod_enc_data).is_err(), | ||||
|         Envelope::from_signed_data(vcrypto.crypto(), &mod_enc_data, &network_key).is_err(), | ||||
|         "should have failed to decode envelope with modified signature" | ||||
|     ); | ||||
|     let mut mod_enc_data2 = enc_data.clone(); | ||||
|     mod_enc_data2[enc_data_len - 65] ^= 0x80u8; | ||||
|     assert!( | ||||
|         Envelope::from_signed_data(vcrypto.crypto(), &mod_enc_data2).is_err(), | ||||
|         Envelope::from_signed_data(vcrypto.crypto(), &mod_enc_data2, &network_key).is_err(), | ||||
|         "should have failed to decode envelope with modified data" | ||||
|     ); | ||||
| } | ||||
| @@ -97,7 +105,9 @@ pub async fn test_all() { | ||||
|         for v in VALID_CRYPTO_KINDS { | ||||
|             let vcrypto = crypto.get(v).unwrap(); | ||||
|  | ||||
|             test_envelope_round_trip(ev, vcrypto.clone()).await; | ||||
|             test_envelope_round_trip(ev, vcrypto.clone(), None).await; | ||||
|             test_envelope_round_trip(ev, vcrypto.clone(), Some(vcrypto.random_shared_secret())) | ||||
|                 .await; | ||||
|             test_receipt_round_trip(ev, vcrypto).await; | ||||
|         } | ||||
|     } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user