libsignal_protocol/
session_cipher.rs

1use crate::{
2    context::{Context, ContextInner},
3    errors::FromInternalErrorCode,
4    messages::CiphertextMessage,
5    raw_ptr::Raw,
6    store_context::{StoreContext, StoreContextInner},
7    Address,
8};
9
10use failure::Error;
11use std::{
12    fmt::{self, Debug, Formatter},
13    ptr,
14    rc::Rc,
15};
16
17/// The cipher context used for encryption.
18pub struct SessionCipher {
19    raw: *mut sys::session_cipher,
20    _ctx: Rc<ContextInner>,
21    _store_ctx: Rc<StoreContextInner>,
22    _addr: Address,
23}
24
25impl SessionCipher {
26    /// Create a new cipher for sending messages to the addressed recipient.
27    pub fn new(
28        ctx: &Context,
29        store_ctx: &StoreContext,
30        address: &Address,
31    ) -> Result<SessionCipher, Error> {
32        unsafe {
33            let mut raw = ptr::null_mut();
34            sys::session_cipher_create(
35                &mut raw,
36                store_ctx.raw(),
37                address.raw(),
38                ctx.raw(),
39            )
40            .into_result()?;
41
42            Ok(SessionCipher {
43                raw,
44                _store_ctx: Rc::clone(&store_ctx.0),
45                _ctx: Rc::clone(&ctx.0),
46                _addr: address.clone(),
47            })
48        }
49    }
50
51    /// Encrypt a message.
52    pub fn encrypt(&self, message: &[u8]) -> Result<CiphertextMessage, Error> {
53        unsafe {
54            let mut raw = ptr::null_mut();
55            sys::session_cipher_encrypt(
56                self.raw,
57                message.as_ptr(),
58                message.len(),
59                &mut raw,
60            )
61            .into_result()?;
62
63            Ok(CiphertextMessage {
64                raw: Raw::from_ptr(raw),
65                _ctx: Rc::clone(&self._ctx),
66            })
67        }
68    }
69}
70
71impl Drop for SessionCipher {
72    fn drop(&mut self) {
73        unsafe {
74            sys::session_cipher_free(self.raw);
75        }
76    }
77}
78
79impl Debug for SessionCipher {
80    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
81        f.debug_tuple("SessionCipher").finish()
82    }
83}