vodozemac/olm/session_keys.rs
1// Copyright 2021 The Matrix.org Foundation C.I.C.
2// Copyright 2021 Damir Jelić, Denis Kasak
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16use matrix_pickle::Decode;
17use serde::{Deserialize, Serialize};
18use sha2::{Digest, Sha256};
19
20use crate::{utilities::base64_encode, Curve25519PublicKey};
21
22/// The set of keys that were used to establish the Olm Session,
23#[derive(Clone, Copy, Deserialize, Serialize, PartialEq, Eq, Decode)]
24pub struct SessionKeys {
25 /// The long-term [`Curve25519PublicKey`] of the session initiator.
26 pub identity_key: Curve25519PublicKey,
27 /// The ephemeral [`Curve25519PublicKey`] created by the session initiator
28 /// to establish the session.
29 pub base_key: Curve25519PublicKey,
30 /// The one-time [`Curve25519PublicKey`] that the initiator downloaded from
31 /// a key server, which was previously created and published by the
32 /// recipient.
33 pub one_time_key: Curve25519PublicKey,
34}
35
36impl SessionKeys {
37 /// Returns the globally unique session ID which these [`SessionKeys`] will
38 /// produce.
39 ///
40 /// A session ID is the SHA256 of the concatenation of three `SessionKeys`,
41 /// the account's identity key, the ephemeral base key and the one-time
42 /// key which is used to establish the session.
43 ///
44 /// Due to the construction, every session ID is (probabilistically)
45 /// globally unique.
46 pub fn session_id(&self) -> String {
47 let sha = Sha256::new();
48
49 let digest = sha
50 .chain_update(self.identity_key.as_bytes())
51 .chain_update(self.base_key.as_bytes())
52 .chain_update(self.one_time_key.as_bytes())
53 .finalize();
54
55 base64_encode(digest)
56 }
57}
58
59impl std::fmt::Debug for SessionKeys {
60 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
61 f.debug_struct("SessionKeys")
62 .field("identity_key", &self.identity_key.to_base64())
63 .field("base_key", &self.base_key.to_base64())
64 .field("one_time_key", &self.one_time_key.to_base64())
65 .finish()
66 }
67}