chore: better unimplemented voice modes handling

This commit is contained in:
kozabrada123 2024-03-09 12:59:55 +01:00
parent 00abd6e662
commit 4b7724a703
5 changed files with 102 additions and 18 deletions

View File

@ -144,6 +144,7 @@ custom_error! {
NoData = "We have not set received the necessary data to perform this operation.", NoData = "We have not set received the necessary data to perform this operation.",
// Encryption errors // Encryption errors
EncryptionModeNotImplemented{encryption_mode: String} = "Voice encryption mode {encryption_mode} is not yet implemented.",
NoKey = "Tried to encrypt / decrypt rtp data, but no key has been received yet", NoKey = "Tried to encrypt / decrypt rtp data, but no key has been received yet",
FailedEncryption = "Tried to encrypt rtp data, but failed. Most likely this is an issue chorus' nonce generation. Please open an issue on the chorus github: https://github.com/polyphony-chat/chorus/issues/new", FailedEncryption = "Tried to encrypt rtp data, but failed. Most likely this is an issue chorus' nonce generation. Please open an issue on the chorus github: https://github.com/polyphony-chat/chorus/issues/new",
FailedDecryption = "Tried to decrypt rtp data, but failed. Most likely this is an issue chorus' nonce generation. Please open an issue on the chorus github: https://github.com/polyphony-chat/chorus/issues/new", FailedDecryption = "Tried to decrypt rtp data, but failed. Most likely this is an issue chorus' nonce generation. Please open an issue on the chorus github: https://github.com/polyphony-chat/chorus/issues/new",

View File

@ -88,14 +88,40 @@ pub enum VoiceEncryptionMode {
// Officially Undocumented // Officially Undocumented
/// Not implemented yet, we have no idea what the rtpsize nonces are. /// Not implemented yet, we have no idea what the rtpsize nonces are.
Xsalsa20Poly1305LiteRtpsize, Xsalsa20Poly1305LiteRtpsize,
/// Not implemented yet /// Not implemented yet, we have no idea what the nonce is.
AeadAes256Gcm, AeadAes256Gcm,
/// Not implemented yet /// Not implemented yet, we have no idea what the rtpsize nonces are.
AeadAes256GcmRtpsize, AeadAes256GcmRtpsize,
/// Not implemented yet, we have no idea what the rtpsize nonces are. /// Not implemented yet, we have no idea what the rtpsize nonces are.
AeadXchacha20Poly1305Rtpsize, AeadXchacha20Poly1305Rtpsize,
} }
impl VoiceEncryptionMode {
/// Returns whether this encryption mode uses Xsalsa20Poly1305 encryption.
pub fn is_xsalsa20_poly1305(&self) -> bool {
match *self {
VoiceEncryptionMode::Xsalsa20Poly1305
| VoiceEncryptionMode::Xsalsa20Poly1305Lite
| VoiceEncryptionMode::Xsalsa20Poly1305Suffix
| VoiceEncryptionMode::Xsalsa20Poly1305LiteRtpsize => true,
_ => false,
}
}
/// Returns whether this encryption mode uses AeadAes256Gcm encryption.
pub fn is_aead_aes256_gcm(&self) -> bool {
match *self {
VoiceEncryptionMode::AeadAes256Gcm | VoiceEncryptionMode::AeadAes256GcmRtpsize => true,
_ => false,
}
}
/// Returns whether this encryption mode uses AeadXchacha20Poly1305 encryption.
pub fn is_aead_xchacha20_poly1305(&self) -> bool {
*self == VoiceEncryptionMode::AeadXchacha20Poly1305Rtpsize
}
}
/// The possible audio codecs to use /// The possible audio codecs to use
#[derive(Debug, Default, Serialize, Deserialize, Clone, Copy, PartialEq, Eq)] #[derive(Debug, Default, Serialize, Deserialize, Clone, Copy, PartialEq, Eq)]
#[serde(rename_all = "lowercase")] #[serde(rename_all = "lowercase")]

View File

@ -148,32 +148,61 @@ impl UdpHandle {
.last_udp_encryption_nonce .last_udp_encryption_nonce
.unwrap_or_default() .unwrap_or_default()
.wrapping_add(1); .wrapping_add(1);
data_lock.last_udp_encryption_nonce = Some(nonce); data_lock.last_udp_encryption_nonce = Some(nonce);
drop(data_lock); drop(data_lock);
// TODO: Is le correct? This is not documented anywhere // TODO: Is le correct? This is not documented anywhere
let mut bytes = nonce.to_le_bytes().to_vec(); let mut bytes = nonce.to_le_bytes().to_vec();
// This is 4 bytes, it has to be 24, so we need to append 20
// This is 4 bytes, it has to be a different size, appends 0s
while bytes.len() < 24 { while bytes.len() < 24 {
bytes.push(0); bytes.push(0);
} }
bytes bytes
} }
_ => { _ => {
// TODO: Implement aead_aes256_gcm error!(
todo!("This voice encryption mode is not yet implemented."); "This voice encryption mode ({:?}) is not yet implemented.",
session_description.encryption_mode
);
return Err(VoiceUdpError::EncryptionModeNotImplemented {
encryption_mode: format!("{:?}", session_description.encryption_mode),
});
} }
}; };
let nonce = GenericArray::from_slice(&nonce_bytes);
let key = GenericArray::from_slice(&session_description.secret_key); let key = GenericArray::from_slice(&session_description.secret_key);
let encryption_result;
if session_description.encryption_mode.is_xsalsa20_poly1305() {
let nonce = GenericArray::from_slice(&nonce_bytes);
let encryptor = XSalsa20Poly1305::new(key); let encryptor = XSalsa20Poly1305::new(key);
let encryption_result = encryptor.encrypt(nonce, payload); encryption_result = encryptor.encrypt(nonce, payload);
}
// Note: currently unused because I have no idea what the AeadAes256Gcm nonce is
/*else if session_description.encryption_mode.is_aead_aes256_gcm() {
let nonce = GenericArray::from_slice(&nonce_bytes);
let encryptor = Aes256Gcm::new(key);
encryption_result = encryptor.encrypt(nonce, payload);
}*/
else {
error!(
"This voice encryption mode ({:?}) is not yet implemented.",
session_description.encryption_mode
);
return Err(VoiceUdpError::EncryptionModeNotImplemented {
encryption_mode: format!("{:?}", session_description.encryption_mode),
});
}
if encryption_result.is_err() { if encryption_result.is_err() {
// Safety: If encryption errors here, it's chorus' fault, and it makes no sense to // Safety: If encryption fails here, it's chorus' fault, and it makes no sense to
// return the error to the user. // return the error to the user.
// //
// This is not an error the user should account for, which is why we throw it here. // This is not an error the user should account for, which is why we throw it here.

View File

@ -188,7 +188,8 @@ impl UdpHandler {
return; return;
} }
_ => { _ => {
unreachable!(); error!("VUDP: Failed to decrypt voice data: {}", err);
return;
} }
} }
} }
@ -306,18 +307,45 @@ impl UdpHandler {
get_xsalsa20_poly1305_lite_nonce(packet_bytes) get_xsalsa20_poly1305_lite_nonce(packet_bytes)
} }
_ => { _ => {
// TODO: Implement aead_aes256_gcm error!(
todo!("This voice encryption mode is not yet implemented."); "This voice encryption mode ({:?}) is not yet implemented.",
session_description.encryption_mode
);
return Err(VoiceUdpError::EncryptionModeNotImplemented {
encryption_mode: format!("{:?}", session_description.encryption_mode),
});
} }
}; };
let nonce = GenericArray::from_slice(&nonce_bytes);
let key = GenericArray::from_slice(&session_description.secret_key); let key = GenericArray::from_slice(&session_description.secret_key);
let decryption_result;
if session_description.encryption_mode.is_xsalsa20_poly1305() {
let nonce = GenericArray::from_slice(&nonce_bytes);
let decryptor = XSalsa20Poly1305::new(key); let decryptor = XSalsa20Poly1305::new(key);
let decryption_result = decryptor.decrypt(nonce, ciphertext.as_ref()); decryption_result = decryptor.decrypt(nonce, ciphertext.as_ref());
}
// Note: currently unused because I have no idea what the AeadAes256Gcm nonce is
/*else if session_description.encryption_mode.is_aead_aes256_gcm() {
let nonce = GenericArray::from_slice(&nonce_bytes);
let decryptor = Aes256Gcm::new(key);
decryption_result = decryptor.decrypt(nonce, ciphertext.as_ref());
}*/
else {
error!(
"This voice encryption mode ({:?}) is not yet implemented.",
session_description.encryption_mode
);
return Err(VoiceUdpError::EncryptionModeNotImplemented {
encryption_mode: format!("{:?}", session_description.encryption_mode),
});
}
// Note: this may seem like we are throwing away valuable error handling data, // Note: this may seem like we are throwing away valuable error handling data,
// but the decryption error provides no extra info. // but the decryption error provides no extra info.