libsignal_protocol/
store_context.rs

1use crate::{
2    context::ContextInner,
3    errors::{FromInternalErrorCode, InternalError},
4    raw_ptr::Raw,
5    Address, SessionRecord,
6};
7use failure::Error;
8use std::{
9    fmt::{self, Debug, Formatter},
10    ptr,
11    rc::Rc,
12};
13
14/// Something which contains state used by the signal protocol.
15///
16/// Under the hood this contains several "Stores" for various keys and session
17/// state (e.g. which identities are trusted, and their pre-keys).
18#[derive(Debug, Clone)]
19pub struct StoreContext(pub(crate) Rc<StoreContextInner>);
20
21impl StoreContext {
22    pub(crate) fn new(
23        raw: *mut sys::signal_protocol_store_context,
24        ctx: &Rc<ContextInner>,
25    ) -> StoreContext {
26        StoreContext(Rc::new(StoreContextInner {
27            raw,
28            ctx: Rc::clone(ctx),
29        }))
30    }
31
32    /// Get the registration ID.
33    pub fn registration_id(&self) -> Result<u32, Error> {
34        unsafe {
35            let mut id = 0;
36            sys::signal_protocol_identity_get_local_registration_id(
37                self.raw(),
38                &mut id,
39            )
40            .into_result()?;
41
42            Ok(id)
43        }
44    }
45
46    /// Does this store already contain a session with the provided recipient?
47    pub fn contains_session(&self, addr: &Address) -> Result<bool, Error> {
48        unsafe {
49            match sys::signal_protocol_session_contains_session(
50                self.raw(),
51                addr.raw(),
52            ) {
53                0 => Ok(false),
54                1 => Ok(true),
55                code => Err(Error::from(
56                    InternalError::from_error_code(code)
57                        .unwrap_or(InternalError::Unknown),
58                )),
59            }
60        }
61    }
62
63    /// Load the session corresponding to the provided recipient.
64    pub fn load_session(&self, addr: &Address) -> Result<SessionRecord, Error> {
65        unsafe {
66            let mut raw = ptr::null_mut();
67            sys::signal_protocol_session_load_session(
68                self.raw(),
69                &mut raw,
70                addr.raw(),
71            )
72            .into_result()?;
73
74            Ok(SessionRecord {
75                raw: Raw::from_ptr(raw),
76                ctx: Rc::clone(&self.0.ctx),
77            })
78        }
79    }
80
81    pub(crate) fn raw(&self) -> *mut sys::signal_protocol_store_context {
82        self.0.raw
83    }
84}
85
86pub(crate) struct StoreContextInner {
87    raw: *mut sys::signal_protocol_store_context,
88    // the global context must outlive `signal_protocol_store_context`
89    #[allow(dead_code)]
90    ctx: Rc<ContextInner>,
91}
92
93impl Drop for StoreContextInner {
94    fn drop(&mut self) {
95        unsafe {
96            sys::signal_protocol_store_context_destroy(self.raw);
97        }
98    }
99}
100
101impl Debug for StoreContextInner {
102    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
103        f.debug_tuple("StoreContextInner").finish()
104    }
105}