libsignal_protocol/messages/
ciphertext_message.rs

1use crate::{raw_ptr::Raw, Buffer, ContextInner, Serializable};
2use failure::Error;
3use std::{convert::TryFrom, rc::Rc};
4
5// For rustdoc link resolution
6#[allow(unused_imports)]
7use crate::messages::{PreKeySignalMessage, SignalMessage};
8
9/// The type of ciphertext message.
10#[derive(Debug, Copy, Clone, PartialEq)]
11pub enum CiphertextType {
12    /// A [`SignalMessage`].
13    Signal = 2,
14    /// A [`PreKeySignalMessage`].
15    PreKey = 3,
16    /// A sender key message.
17    SenderKey = 4,
18    /// A sender key distribution message.
19    SenderKeyDistribution = 5,
20}
21
22/// The base class for a ciphertext message.
23///
24/// See also:
25///
26/// - [`SignalMessage`]
27/// - [`PreKeySignalMessage`]
28#[derive(Debug, Clone)]
29pub struct CiphertextMessage {
30    pub(crate) raw: Raw<sys::ciphertext_message>,
31    pub(crate) _ctx: Rc<ContextInner>,
32}
33
34impl CiphertextMessage {
35    /// Which type of message is this?
36    pub fn get_type(&self) -> Result<CiphertextType, Error> {
37        unsafe {
38            let ty = sys::ciphertext_message_get_type(self.raw.as_ptr());
39
40            match u32::try_from(ty).unwrap() {
41                sys::CIPHERTEXT_PREKEY_TYPE => Ok(CiphertextType::PreKey),
42                sys::CIPHERTEXT_SIGNAL_TYPE => Ok(CiphertextType::Signal),
43                sys::CIPHERTEXT_SENDERKEY_TYPE => Ok(CiphertextType::SenderKey),
44                sys::CIPHERTEXT_SENDERKEY_DISTRIBUTION_TYPE => {
45                    Ok(CiphertextType::SenderKeyDistribution)
46                },
47                other => Err(failure::format_err!(
48                    "Unknown ciphertext type: {}",
49                    other
50                )),
51            }
52        }
53    }
54}
55
56impl Serializable for CiphertextMessage {
57    fn deserialize(_data: &[u8]) -> Result<Self, failure::Error>
58    where
59        Self: Sized,
60    {
61        unimplemented!()
62    }
63
64    fn serialize(&self) -> Result<Buffer, failure::Error> {
65        unsafe {
66            // get a reference to the *cached* serialized message
67            let buffer =
68                sys::ciphertext_message_get_serialized(self.raw.as_const_ptr());
69
70            if buffer.is_null() {
71                return Err(failure::err_msg(
72                    "Unable to serialize the message",
73                ));
74            }
75
76            let temporary_not_owned_buffer = Buffer::from_raw(buffer);
77            let copied = temporary_not_owned_buffer.clone();
78
79            // We don't want to free our reference to the serialized message!
80            std::mem::forget(temporary_not_owned_buffer);
81
82            Ok(copied)
83        }
84    }
85}