libsignal_protocol/
pre_key_bundle.rs

1use crate::{keys::PublicKey, raw_ptr::Raw};
2use failure::Error;
3use std::{
4    fmt::{self, Debug, Formatter},
5    ptr,
6};
7
8/// The session state used when sending a message to another user.
9#[derive(Clone)]
10pub struct PreKeyBundle {
11    pub(crate) raw: Raw<sys::session_pre_key_bundle>,
12}
13
14impl PreKeyBundle {
15    /// Get a builder struct for the [`PreKeyBundle`].
16    pub fn builder() -> PreKeyBundleBuilder { PreKeyBundleBuilder::default() }
17
18    /// Get the registration ID.
19    pub fn registration_id(&self) -> u32 {
20        unsafe {
21            sys::session_pre_key_bundle_get_registration_id(
22                self.raw.as_const_ptr(),
23            )
24        }
25    }
26
27    /// Get the device ID.
28    pub fn device_id(&self) -> i32 {
29        unsafe {
30            sys::session_pre_key_bundle_get_device_id(self.raw.as_const_ptr())
31        }
32    }
33
34    /// Get the pre-key ID.
35    pub fn pre_key_id(&self) -> u32 {
36        unsafe {
37            sys::session_pre_key_bundle_get_pre_key_id(self.raw.as_const_ptr())
38        }
39    }
40
41    /// Get the pre-key itself.
42    pub fn pre_key(&self) -> Result<PublicKey, Error> {
43        unsafe {
44            let raw = sys::session_pre_key_bundle_get_pre_key(
45                self.raw.as_const_ptr(),
46            );
47            if raw.is_null() {
48                Err(failure::err_msg("Unable to get the pre-key"))
49            } else {
50                Ok(PublicKey {
51                    raw: Raw::copied_from(raw),
52                })
53            }
54        }
55    }
56
57    /// Get the signed pre-key id.
58    pub fn signed_pre_key_id(&self) -> u32 {
59        unsafe {
60            sys::session_pre_key_bundle_get_signed_pre_key_id(
61                self.raw.as_const_ptr(),
62            )
63        }
64    }
65
66    /// Get the signed pre-key.
67    pub fn signed_pre_key(&self) -> Result<PublicKey, Error> {
68        unsafe {
69            let raw = sys::session_pre_key_bundle_get_signed_pre_key(
70                self.raw.as_const_ptr(),
71            );
72            if raw.is_null() {
73                Err(failure::err_msg("Unable to get the signed pre-key"))
74            } else {
75                Ok(PublicKey {
76                    raw: Raw::copied_from(raw),
77                })
78            }
79        }
80    }
81
82    /// Get the identity key.
83    pub fn identity_key(&self) -> Result<PublicKey, Error> {
84        unsafe {
85            let raw = sys::session_pre_key_bundle_get_identity_key(
86                self.raw.as_const_ptr(),
87            );
88            if raw.is_null() {
89                Err(failure::err_msg("Unable to get the identity key"))
90            } else {
91                Ok(PublicKey {
92                    raw: Raw::copied_from(raw),
93                })
94            }
95        }
96    }
97}
98
99impl Debug for PreKeyBundle {
100    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
101        f.debug_tuple("PreKeyBundle").finish()
102    }
103}
104
105/// A builder type for the [`PreKeyBundle`].
106#[derive(Debug, Default)]
107pub struct PreKeyBundleBuilder {
108    registration_id: Option<u32>,
109    device_id: Option<i32>,
110    pre_key_id: Option<u32>,
111    pre_key_public: Option<PublicKey>,
112    signed_pre_key_id: Option<u32>,
113    signed_pre_key_public: Option<PublicKey>,
114    signature: Option<Vec<u8>>,
115    identity_key: Option<PublicKey>,
116}
117
118impl PreKeyBundleBuilder {
119    /// Set the recipient's public pre-key.
120    pub fn pre_key(mut self, id: u32, public_key: &PublicKey) -> Self {
121        self.pre_key_id = Some(id);
122        self.pre_key_public = Some(public_key.clone());
123
124        self
125    }
126
127    /// Set the signed pre-key.
128    pub fn signed_pre_key(
129        mut self,
130        id: u32,
131        signed_public_key: &PublicKey,
132    ) -> Self {
133        self.signed_pre_key_id = Some(id);
134        self.signed_pre_key_public = Some(signed_public_key.clone());
135
136        self
137    }
138
139    /// Set the signed pre-key's signature.
140    pub fn signature(mut self, sig: &[u8]) -> Self {
141        self.signature = Some(sig.to_vec());
142        self
143    }
144
145    /// Set the registration ID.
146    pub fn registration_id(mut self, id: u32) -> Self {
147        self.registration_id = Some(id);
148        self
149    }
150
151    /// Set the device ID.
152    pub fn device_id(mut self, id: i32) -> Self {
153        self.device_id = Some(id);
154        self
155    }
156
157    /// Set the user's identity key.
158    pub fn identity_key(mut self, identity_key: &PublicKey) -> Self {
159        self.identity_key = Some(identity_key.clone());
160        self
161    }
162
163    fn get_registration_id(&self) -> Result<u32, Error> {
164        self.registration_id
165            .ok_or_else(|| failure::err_msg("a registration ID is required"))
166    }
167
168    fn get_device_id(&self) -> Result<i32, Error> {
169        self.device_id
170            .ok_or_else(|| failure::err_msg("a device ID is required"))
171    }
172
173    fn get_identity_key(&self) -> Result<*mut sys::ec_public_key, Error> {
174        match self.identity_key {
175            Some(ref key) => Ok(key.raw.as_ptr()),
176            None => Err(failure::err_msg("Identity key is required")),
177        }
178    }
179
180    fn get_pre_key(&self) -> (u32, *mut sys::ec_public_key) {
181        if let PreKeyBundleBuilder {
182            pre_key_id: Some(id),
183            pre_key_public: Some(ref public),
184            ..
185        } = self
186        {
187            (*id, public.raw.as_ptr())
188        } else {
189            (0, ptr::null_mut())
190        }
191    }
192
193    fn get_signed_pre_key(&self) -> (u32, *mut sys::ec_public_key) {
194        if let PreKeyBundleBuilder {
195            signed_pre_key_id: Some(id),
196            signed_pre_key_public: Some(ref public),
197            ..
198        } = self
199        {
200            (*id, public.raw.as_ptr())
201        } else {
202            (0, ptr::null_mut())
203        }
204    }
205
206    /// Actually build the [`PreKeyBundle`].
207    pub fn build(self) -> Result<PreKeyBundle, Error> {
208        let registration_id = self.get_registration_id()?;
209        let device_id = self.get_device_id()?;
210        let (pre_key_id, pre_key_public) = self.get_pre_key();
211        let (signed_pre_key_id, signed_pre_key_public) =
212            self.get_signed_pre_key();
213        let signature =
214            self.signature.as_ref().map(Vec::as_slice).unwrap_or(&[]);
215        let identity_key = self.get_identity_key()?;
216
217        unsafe {
218            let mut raw = ptr::null_mut();
219
220            sys::session_pre_key_bundle_create(
221                &mut raw,
222                registration_id,
223                device_id,
224                pre_key_id,
225                pre_key_public,
226                signed_pre_key_id,
227                signed_pre_key_public,
228                signature.as_ptr(),
229                signature.len(),
230                identity_key,
231            );
232            Ok(PreKeyBundle {
233                raw: Raw::from_ptr(raw),
234            })
235        }
236    }
237}