mls_rs_core/identity/
provider.rs

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
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// Copyright by contributors to this project.
// SPDX-License-Identifier: (Apache-2.0 OR MIT)

use crate::{error::IntoAnyError, extension::ExtensionList, group::GroupContext, time::MlsTime};
#[cfg(mls_build_async)]
use alloc::boxed::Box;
use alloc::vec::Vec;

use super::{CredentialType, SigningIdentity};

#[derive(Clone, Copy, PartialEq, Eq, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize,))]
#[non_exhaustive]
pub enum MemberValidationContext<'a> {
    ForCommit {
        current_context: &'a GroupContext,
        new_extensions: &'a ExtensionList,
    },
    ForNewGroup {
        current_context: &'a GroupContext,
    },
    None,
}

impl MemberValidationContext<'_> {
    pub fn new_extensions(&self) -> Option<&ExtensionList> {
        match self {
            Self::ForCommit { new_extensions, .. } => Some(*new_extensions),
            Self::ForNewGroup { current_context } => Some(&current_context.extensions),
            Self::None => None,
        }
    }
}

/// Identity system that can be used to validate a
/// [`SigningIdentity`](mls-rs-core::identity::SigningIdentity)
#[cfg_attr(not(mls_build_async), maybe_async::must_be_sync)]
#[cfg_attr(mls_build_async, maybe_async::must_be_async)]
pub trait IdentityProvider: Send + Sync {
    /// Error type that this provider returns on internal failure.
    type Error: IntoAnyError;

    /// Determine if `signing_identity` is valid for a group member.
    ///
    /// A `timestamp` value can optionally be supplied to aid with validation
    /// of a [`Credential`](mls-rs-core::identity::Credential) that requires
    /// time based context. For example, X.509 certificates can become expired.
    async fn validate_member(
        &self,
        signing_identity: &SigningIdentity,
        timestamp: Option<MlsTime>,
        context: MemberValidationContext<'_>,
    ) -> Result<(), Self::Error>;

    /// Determine if `signing_identity` is valid for an external sender in
    /// the ExternalSendersExtension stored in the group context.
    ///
    /// A `timestamp` value can optionally be supplied to aid with validation
    /// of a [`Credential`](mls-rs-core::identity::Credential) that requires
    /// time based context. For example, X.509 certificates can become expired.
    async fn validate_external_sender(
        &self,
        signing_identity: &SigningIdentity,
        timestamp: Option<MlsTime>,
        extensions: Option<&ExtensionList>,
    ) -> Result<(), Self::Error>;

    /// A unique identifier for `signing_identity`.
    ///
    /// The MLS protocol requires that each member of a group has a unique
    /// set of identifiers according to the application.
    async fn identity(
        &self,
        signing_identity: &SigningIdentity,
        extensions: &ExtensionList,
    ) -> Result<Vec<u8>, Self::Error>;

    /// Determines if `successor` can remove `predecessor` as part of an external commit.
    ///
    /// The MLS protocol allows for removal of an existing member when adding a
    /// new member via external commit. This function determines if a removal
    /// should be allowed by providing the target member to be removed as
    /// `predecessor` and the new member as `successor`.
    async fn valid_successor(
        &self,
        predecessor: &SigningIdentity,
        successor: &SigningIdentity,
        extensions: &ExtensionList,
    ) -> Result<bool, Self::Error>;

    /// Credential types that are supported by this provider.
    fn supported_types(&self) -> Vec<CredentialType>;
}