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}