1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
// Copyright 2021 The Matrix.org Foundation C.I.C.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! Cryptographic identities used in Matrix.
//!
//! There are two types of cryptographic identities in Matrix.
//!
//! 1. Devices, which are backed by [device keys], they represent each
//! individual log in by an E2EE capable Matrix client. We represent devices
//! using the [`Device`] struct.
//!
//! 2. User identities, which are backed by [cross signing keys]. The user
//! identity represent a unique E2EE capable identity of any given user. This
//! identity is generally created and uploaded to the server by the first E2EE
//! capable client the user logs in with. We represent user identities using the
//! [`UserIdentity`] struct.
//!
//! A [`Device`] or an [`UserIdentity`] can be used to inspect the public keys
//! of the device or identity, or it can be used to initiate a interactive
//! verification flow. They can also be manually marked as verified.
//!
//! # Examples
//!
//! Verifying a device is pretty straightforward:
//!
//! ```no_run
//! # use std::convert::TryFrom;
//! # use matrix_sdk::{Client, ruma::UserId};
//! # use url::Url;
//! # use futures::executor::block_on;
//! # let alice = UserId::try_from("@alice:example.org").unwrap();
//! # let homeserver = Url::parse("http://example.com").unwrap();
//! # let client = Client::new(homeserver).unwrap();
//! # block_on(async {
//! let device = client.get_device(&alice, "DEVICEID".into()).await?;
//!
//! if let Some(device) = device {
//!     // Let's request the device to be verified.
//!     let verification = device.request_verification().await?;
//!
//!     // Actually this is taking too long.
//!     verification.cancel().await?;
//!
//!     // Let's just mark it as verified.
//!     device.verify().await?;
//! }
//! # anyhow::Result::<()>::Ok(()) });
//! ```
//!
//! Verifying a user identity works largely the same:
//!
//! ```no_run
//! # use std::convert::TryFrom;
//! # use matrix_sdk::{Client, ruma::UserId};
//! # use url::Url;
//! # use futures::executor::block_on;
//! # let alice = UserId::try_from("@alice:example.org").unwrap();
//! # let homeserver = Url::parse("http://example.com").unwrap();
//! # let client = Client::new(homeserver).unwrap();
//! # block_on(async {
//! let user = client.get_user_identity(&alice).await?;
//!
//! if let Some(user) = user {
//!     // Let's request the user to be verified.
//!     let verification = user.request_verification().await?;
//!
//!     // Actually this is taking too long.
//!     verification.cancel().await?;
//!
//!     // Let's just mark it as verified.
//!     user.verify().await?;
//! }
//! # anyhow::Result::<()>::Ok(()) });
//! ```
//!
//! [cross signing keys]: https://spec.matrix.org/unstable/client-server-api/#cross-signing
//! [device keys]: https://spec.matrix.org/unstable/client-server-api/#device-keys

mod devices;
mod users;

pub use devices::{Device, UserDevices};
pub use matrix_sdk_base::crypto::MasterPubkey;
pub use users::UserIdentity;

/// Error for the manual verification step, when we manually sign users or
/// devices.
#[derive(thiserror::Error, Debug)]
pub enum ManualVerifyError {
    /// Error that happens when we try to upload the user or device signature.
    #[error(transparent)]
    Http(#[from] crate::HttpError),
    /// Error that happens when we try to sign the user or device.
    #[error(transparent)]
    Signature(#[from] matrix_sdk_base::crypto::SignatureError),
}

/// Error when requesting a verification.
#[derive(thiserror::Error, Debug)]
pub enum RequestVerificationError {
    /// An ordinary error coming from the SDK, i.e. when we fail to send out a
    /// HTTP request or if there's an error with the storage layer.
    #[error(transparent)]
    Sdk(#[from] crate::Error),
    /// Verifying other users requires having a DM open with them, this error
    /// signals that we didn't have a DM and that we failed to create one.
    #[error("Couldn't create a DM with user {0} where the verification should take place")]
    RoomCreation(ruma::UserId),
}