mirror of
https://github.com/signalapp/libsignal.git
synced 2024-09-20 20:03:07 +02:00
protocol: Remove dedicated errors for bad root and chain keys
Enforce that directly-created keys have the right length, which pushes the error to the lazy deserialization code in a session. If the lengths are wrong there, the session is corrupt.
This commit is contained in:
parent
1ed7d739cc
commit
3c7a225ce8
@ -63,8 +63,6 @@ impl From<&SignalFfiError> for SignalErrorCode {
|
||||
| SignalFfiError::Signal(SignalProtocolError::InternalError(_))
|
||||
| SignalFfiError::DeviceTransfer(DeviceTransferError::InternalError(_))
|
||||
| SignalFfiError::Signal(SignalProtocolError::FfiBindingError(_))
|
||||
| SignalFfiError::Signal(SignalProtocolError::InvalidChainKeyLength(_))
|
||||
| SignalFfiError::Signal(SignalProtocolError::InvalidRootKeyLength(_))
|
||||
| SignalFfiError::Signal(SignalProtocolError::InvalidCipherCryptographicParameters(
|
||||
_,
|
||||
_,
|
||||
|
@ -209,10 +209,8 @@ fn throw_error(env: &JNIEnv, error: SignalJniError) {
|
||||
| SignalJniError::Signal(SignalProtocolError::InternalError(_))
|
||||
| SignalJniError::DeviceTransfer(DeviceTransferError::InternalError(_))
|
||||
| SignalJniError::DeviceTransfer(DeviceTransferError::KeyDecodingFailed)
|
||||
| SignalJniError::Signal(SignalProtocolError::InvalidChainKeyLength(_))
|
||||
| SignalJniError::Signal(SignalProtocolError::InvalidCipherCryptographicParameters(_, _))
|
||||
| SignalJniError::Signal(SignalProtocolError::InvalidMacKeyLength(_))
|
||||
| SignalJniError::Signal(SignalProtocolError::InvalidRootKeyLength(_))
|
||||
| SignalJniError::Signal(SignalProtocolError::ProtobufEncodingError(_)) => {
|
||||
jni_class_name!(java.lang.RuntimeException)
|
||||
}
|
||||
|
@ -61,11 +61,6 @@ pub enum SignalProtocolError {
|
||||
/// invalid signed prekey identifier
|
||||
InvalidSignedPreKeyId,
|
||||
|
||||
/// invalid root key length <{0}>
|
||||
InvalidRootKeyLength(usize),
|
||||
/// invalid chain key length <{0}>
|
||||
InvalidChainKeyLength(usize),
|
||||
|
||||
/// invalid MAC key length <{0}>
|
||||
InvalidMacKeyLength(usize),
|
||||
/// invalid cipher key length <{0}> or nonce length <{1}>
|
||||
|
@ -6,6 +6,8 @@
|
||||
mod keys;
|
||||
mod params;
|
||||
|
||||
use std::convert::TryInto;
|
||||
|
||||
pub use self::keys::{ChainKey, MessageKeys, RootKey};
|
||||
pub use self::params::{AliceSignalProtocolParameters, BobSignalProtocolParameters};
|
||||
use crate::proto::storage::SessionStructure;
|
||||
@ -19,9 +21,10 @@ fn derive_keys(secret_input: &[u8]) -> Result<(RootKey, ChainKey)> {
|
||||
hkdf::Hkdf::<sha2::Sha256>::new(None, secret_input)
|
||||
.expand(b"WhisperText", &mut secrets)
|
||||
.expect("valid length");
|
||||
let (root_key_bytes, chain_key_bytes) = secrets.split_at(32);
|
||||
|
||||
let root_key = RootKey::new(&secrets[0..32])?;
|
||||
let chain_key = ChainKey::new(&secrets[32..64], 0)?;
|
||||
let root_key = RootKey::new(root_key_bytes.try_into().expect("correct length"));
|
||||
let chain_key = ChainKey::new(chain_key_bytes.try_into().expect("correct length"), 0);
|
||||
|
||||
Ok((root_key, chain_key))
|
||||
}
|
||||
|
@ -81,15 +81,8 @@ impl ChainKey {
|
||||
const MESSAGE_KEY_SEED: [u8; 1] = [0x01u8];
|
||||
const CHAIN_KEY_SEED: [u8; 1] = [0x02u8];
|
||||
|
||||
pub fn new(key: &[u8], index: u32) -> Result<Self> {
|
||||
if key.len() != 32 {
|
||||
return Err(SignalProtocolError::InvalidChainKeyLength(key.len()));
|
||||
}
|
||||
|
||||
Ok(Self {
|
||||
key: *array_ref![key, 0, 32],
|
||||
index,
|
||||
})
|
||||
pub fn new(key: [u8; 32], index: u32) -> Self {
|
||||
Self { key, index }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@ -127,13 +120,8 @@ pub struct RootKey {
|
||||
}
|
||||
|
||||
impl RootKey {
|
||||
pub fn new(key: &[u8]) -> Result<Self> {
|
||||
if key.len() != 32 {
|
||||
return Err(SignalProtocolError::InvalidRootKeyLength(key.len()));
|
||||
}
|
||||
Ok(Self {
|
||||
key: *array_ref![key, 0, 32],
|
||||
})
|
||||
pub fn new(key: [u8; 32]) -> Self {
|
||||
Self { key }
|
||||
}
|
||||
|
||||
pub fn key(&self) -> &[u8; 32] {
|
||||
@ -196,7 +184,7 @@ mod tests {
|
||||
0xa2, 0x46, 0xd1, 0x5d,
|
||||
];
|
||||
|
||||
let chain_key = ChainKey::new(&seed, 0)?;
|
||||
let chain_key = ChainKey::new(seed, 0);
|
||||
assert_eq!(&seed, chain_key.key());
|
||||
assert_eq!(&message_key, chain_key.message_keys()?.cipher_key());
|
||||
assert_eq!(&mac_key, chain_key.message_keys()?.mac_key());
|
||||
|
@ -3,6 +3,8 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
//
|
||||
|
||||
use std::convert::TryInto;
|
||||
|
||||
use prost::Message;
|
||||
|
||||
use crate::ratchet::{ChainKey, MessageKeys, RootKey};
|
||||
@ -115,10 +117,10 @@ impl SessionState {
|
||||
}
|
||||
|
||||
pub(crate) fn root_key(&self) -> Result<RootKey> {
|
||||
if self.session.root_key.len() != 32 {
|
||||
return Err(SignalProtocolError::InvalidProtobufEncoding);
|
||||
}
|
||||
RootKey::new(&self.session.root_key)
|
||||
let root_key_bytes = self.session.root_key[..]
|
||||
.try_into()
|
||||
.map_err(|_| SignalProtocolError::InvalidProtobufEncoding)?;
|
||||
Ok(RootKey::new(root_key_bytes))
|
||||
}
|
||||
|
||||
pub(crate) fn set_root_key(&mut self, root_key: &RootKey) -> Result<()> {
|
||||
@ -190,10 +192,10 @@ impl SessionState {
|
||||
Some((chain, _)) => match chain.chain_key {
|
||||
None => Err(SignalProtocolError::InvalidProtobufEncoding),
|
||||
Some(c) => {
|
||||
if c.key.len() != 32 {
|
||||
return Err(SignalProtocolError::InvalidProtobufEncoding);
|
||||
}
|
||||
Ok(Some(ChainKey::new(&c.key, c.index)?))
|
||||
let chain_key_bytes = c.key[..]
|
||||
.try_into()
|
||||
.map_err(|_| SignalProtocolError::InvalidProtobufEncoding)?;
|
||||
Ok(Some(ChainKey::new(chain_key_bytes, c.index)))
|
||||
}
|
||||
},
|
||||
}
|
||||
@ -262,7 +264,11 @@ impl SessionState {
|
||||
SignalProtocolError::InvalidState("get_sender_chain_key", "No chain key".to_owned())
|
||||
})?;
|
||||
|
||||
ChainKey::new(&chain_key.key, chain_key.index)
|
||||
let chain_key_bytes = chain_key.key[..]
|
||||
.try_into()
|
||||
.map_err(|_| SignalProtocolError::InvalidProtobufEncoding)?;
|
||||
|
||||
Ok(ChainKey::new(chain_key_bytes, chain_key.index))
|
||||
}
|
||||
|
||||
pub(crate) fn get_sender_chain_key_bytes(&self) -> Result<Vec<u8>> {
|
||||
|
Loading…
Reference in New Issue
Block a user