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