wacore_libsignal/protocol/state/
bundle.rs1use std::clone::Clone;
7
8use crate::protocol::state::{PreKeyId, SignedPreKeyId};
9use crate::protocol::{DeviceId, IdentityKey, PublicKey, Result, SignalProtocolError};
10
11#[derive(Clone)]
12struct SignedPreKey {
13 id: SignedPreKeyId,
14 public_key: PublicKey,
15 signature: Vec<u8>,
16}
17
18impl SignedPreKey {
19 fn new(id: SignedPreKeyId, public_key: PublicKey, signature: Vec<u8>) -> Self {
20 Self {
21 id,
22 public_key,
23 signature,
24 }
25 }
26}
27
28pub struct PreKeyBundleContent {
33 pub registration_id: Option<u32>,
34 pub device_id: Option<DeviceId>,
35 pub pre_key_id: Option<PreKeyId>,
36 pub pre_key_public: Option<PublicKey>,
37 pub ec_pre_key_id: Option<SignedPreKeyId>,
38 pub ec_pre_key_public: Option<PublicKey>,
39 pub ec_pre_key_signature: Option<Vec<u8>>,
40 pub identity_key: Option<IdentityKey>,
41}
42
43impl From<PreKeyBundle> for PreKeyBundleContent {
44 fn from(bundle: PreKeyBundle) -> Self {
45 Self {
46 registration_id: Some(bundle.registration_id),
47 device_id: Some(bundle.device_id),
48 pre_key_id: bundle.pre_key_id,
49 pre_key_public: bundle.pre_key_public,
50 ec_pre_key_id: Some(bundle.ec_signed_pre_key.id),
51 ec_pre_key_public: Some(bundle.ec_signed_pre_key.public_key),
52 ec_pre_key_signature: Some(bundle.ec_signed_pre_key.signature),
53 identity_key: Some(bundle.identity_key),
54 }
55 }
56}
57
58impl TryFrom<PreKeyBundleContent> for PreKeyBundle {
59 type Error = SignalProtocolError;
60
61 fn try_from(content: PreKeyBundleContent) -> Result<Self> {
62 let bundle = PreKeyBundle::new(
63 content.registration_id.ok_or_else(|| {
64 SignalProtocolError::InvalidArgument("registration_id is required".to_string())
65 })?,
66 content.device_id.ok_or_else(|| {
67 SignalProtocolError::InvalidArgument("device_id is required".to_string())
68 })?,
69 content.pre_key_id.zip(content.pre_key_public),
70 content.ec_pre_key_id.ok_or_else(|| {
71 SignalProtocolError::InvalidArgument("signed_pre_key_id is required".to_string())
72 })?,
73 content.ec_pre_key_public.ok_or_else(|| {
74 SignalProtocolError::InvalidArgument(
75 "signed_pre_key_public is required".to_string(),
76 )
77 })?,
78 content.ec_pre_key_signature.ok_or_else(|| {
79 SignalProtocolError::InvalidArgument(
80 "signed_pre_key_signature is required".to_string(),
81 )
82 })?,
83 content.identity_key.ok_or_else(|| {
84 SignalProtocolError::InvalidArgument("identity_key is required".to_string())
85 })?,
86 )?;
87
88 Ok(bundle)
89 }
90}
91
92#[derive(Clone)]
93pub struct PreKeyBundle {
94 registration_id: u32,
95 device_id: DeviceId,
96 pre_key_id: Option<PreKeyId>,
97 pre_key_public: Option<PublicKey>,
98 ec_signed_pre_key: SignedPreKey,
99 identity_key: IdentityKey,
100}
101
102impl PreKeyBundle {
103 pub fn new(
104 registration_id: u32,
105 device_id: DeviceId,
106 pre_key: Option<(PreKeyId, PublicKey)>,
107 signed_pre_key_id: SignedPreKeyId,
108 signed_pre_key_public: PublicKey,
109 signed_pre_key_signature: Vec<u8>,
110 identity_key: IdentityKey,
111 ) -> Result<Self> {
112 let (pre_key_id, pre_key_public) = match pre_key {
113 None => (None, None),
114 Some((id, key)) => (Some(id), Some(key)),
115 };
116
117 let ec_signed_pre_key = SignedPreKey::new(
118 signed_pre_key_id,
119 signed_pre_key_public,
120 signed_pre_key_signature,
121 );
122
123 Ok(Self {
124 registration_id,
125 device_id,
126 pre_key_id,
127 pre_key_public,
128 ec_signed_pre_key,
129 identity_key,
130 })
131 }
132
133 pub fn registration_id(&self) -> Result<u32> {
134 Ok(self.registration_id)
135 }
136
137 pub fn device_id(&self) -> Result<DeviceId> {
138 Ok(self.device_id)
139 }
140
141 pub fn pre_key_id(&self) -> Result<Option<PreKeyId>> {
142 Ok(self.pre_key_id)
143 }
144
145 pub fn pre_key_public(&self) -> Result<Option<PublicKey>> {
146 Ok(self.pre_key_public)
147 }
148
149 pub fn signed_pre_key_id(&self) -> Result<SignedPreKeyId> {
150 Ok(self.ec_signed_pre_key.id)
151 }
152
153 pub fn signed_pre_key_public(&self) -> Result<PublicKey> {
154 Ok(self.ec_signed_pre_key.public_key)
155 }
156
157 pub fn signed_pre_key_signature(&self) -> Result<&[u8]> {
158 Ok(self.ec_signed_pre_key.signature.as_ref())
159 }
160
161 pub fn identity_key(&self) -> Result<&IdentityKey> {
162 Ok(&self.identity_key)
163 }
164
165 pub fn modify<F>(self, modify: F) -> Result<Self>
166 where
167 F: FnOnce(&mut PreKeyBundleContent),
168 {
169 let mut content = self.into();
170 modify(&mut content);
171 content.try_into()
172 }
173}