libsignal_protocol/messages/
pre_key_signal_message.rs

1use crate::{
2    keys::PublicKey,
3    messages::{CiphertextMessage, CiphertextType, SignalMessage},
4    raw_ptr::Raw,
5    ContextInner,
6};
7use failure::Error;
8use std::{convert::TryFrom, rc::Rc};
9
10/// A message containing everything necessary to establish a session.
11#[derive(Debug, Clone)]
12pub struct PreKeySignalMessage {
13    pub(crate) raw: Raw<sys::pre_key_signal_message>,
14    pub(crate) _ctx: Rc<ContextInner>,
15}
16
17impl PreKeySignalMessage {
18    /// Get the message format version.
19    pub fn message_version(&self) -> u8 {
20        unsafe {
21            sys::pre_key_signal_message_get_message_version(
22                self.raw.as_const_ptr(),
23            )
24        }
25    }
26
27    /// The sender's public pre-key.
28    pub fn identity_key(&self) -> PublicKey {
29        unsafe {
30            let ptr = sys::pre_key_signal_message_get_identity_key(
31                self.raw.as_const_ptr(),
32            );
33            assert!(!ptr.is_null());
34            PublicKey {
35                raw: Raw::copied_from(ptr),
36            }
37        }
38    }
39
40    /// The registration ID for this pre-key.
41    pub fn registration_id(&self) -> u32 {
42        unsafe {
43            sys::pre_key_signal_message_get_registration_id(
44                self.raw.as_const_ptr(),
45            )
46        }
47    }
48
49    /// Does this message contain a pre-key ID?
50    pub fn has_pre_key_id(&self) -> bool {
51        unsafe {
52            sys::pre_key_signal_message_has_pre_key_id(self.raw.as_const_ptr())
53                != 0
54        }
55    }
56
57    /// Get the pre-key's ID.
58    pub fn pre_key_id(&self) -> Option<u32> {
59        if !self.has_pre_key_id() {
60            return None;
61        }
62
63        unsafe {
64            Some(sys::pre_key_signal_message_get_pre_key_id(
65                self.raw.as_const_ptr(),
66            ))
67        }
68    }
69
70    /// Get the signed pre-key ID.
71    pub fn signed_pre_key_id(&self) -> u32 {
72        unsafe {
73            sys::pre_key_signal_message_get_signed_pre_key_id(
74                self.raw.as_const_ptr(),
75            )
76        }
77    }
78
79    /// Get this message's base key.
80    pub fn base_key(&self) -> PublicKey {
81        unsafe {
82            let raw = sys::pre_key_signal_message_get_base_key(
83                self.raw.as_const_ptr(),
84            );
85            assert!(!raw.is_null());
86            PublicKey {
87                raw: Raw::copied_from(raw),
88            }
89        }
90    }
91
92    /// Get the internal [`SignalMessage`].
93    pub fn signal_message(&self) -> SignalMessage {
94        unsafe {
95            let raw = sys::pre_key_signal_message_get_signal_message(
96                self.raw.as_const_ptr(),
97            );
98            assert!(!raw.is_null());
99            SignalMessage {
100                raw: Raw::copied_from(raw),
101                _ctx: Rc::clone(&self._ctx),
102            }
103        }
104    }
105}
106
107impl TryFrom<CiphertextMessage> for PreKeySignalMessage {
108    type Error = Error;
109
110    fn try_from(other: CiphertextMessage) -> Result<Self, Self::Error> {
111        if other.get_type()? != CiphertextType::PreKey {
112            Err(failure::err_msg("Expected a pre-key ciphertext message"))
113        } else {
114            // safety: the `CiphertextType` check tells us this is actually a
115            // pointer to a `pre_key_signal_message`
116            let raw = unsafe {
117                Raw::copied_from(
118                    other.raw.as_ptr() as *mut sys::pre_key_signal_message
119                )
120            };
121            Ok(PreKeySignalMessage {
122                raw,
123                _ctx: other._ctx,
124            })
125        }
126    }
127}
128
129impl From<PreKeySignalMessage> for CiphertextMessage {
130    fn from(other: PreKeySignalMessage) -> CiphertextMessage {
131        CiphertextMessage {
132            raw: other.raw.upcast(),
133            _ctx: other._ctx,
134        }
135    }
136}
137
138impl_is_a!(sys::pre_key_signal_message => sys::ciphertext_message);