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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
use async_trait::async_trait;

use crate::{ScramResult, ScramErrorCode};

use crate::scram_ierror;

/// A trait which contains a functions that should be used on the program
/// side which utilizes this crate. Those functions should return data 
/// from your TLS crate:
/// * TLS endpoint cert hash
/// * TLS unique
/// * TLS exporter data
/// 
/// By defualt each function returns error: [ScramErrorCode::ChanBindNotImplemented]
/// 
/// Functions must return a raw data retreived form your TLS library.
pub trait ScramCbHelper
{
    /// This function returns (on success) a TLS endpoint cert data.
    /// For example from function: native_tls::TlsStream::tls_server_end_point()
    /// To indicate error, use macros: HELPER_ERROR_CLIENT or HELPER_ERROR_SERVER
    fn get_tls_server_endpoint(&self) -> ScramResult<Vec<u8>>
    {
        scram_ierror!(
            ScramErrorCode::ChanBindNotImplemented, 
            "`tls_server_endpoint` not implemented!"
        );
    }

    /// This function returns (on success) a TLS unique data.
    /// To indicate error, use macros: HELPER_ERROR_CLIENT or HELPER_ERROR_SERVER
    fn get_tls_unique(&self) -> ScramResult<Vec<u8>>
    {
        scram_ierror!(
            ScramErrorCode::ChanBindNotImplemented, 
            "`tls_unique` not implemented!"
        );
    }

    /// This function returns (on success) a TLS exporter (TLS 1.3) data.
    /// To indicate error, use macros: HELPER_ERROR_CLIENT or HELPER_ERROR_SERVER
    fn get_tls_exporter(&self) -> ScramResult<Vec<u8>>
    {
        scram_ierror!(
            ScramErrorCode::ChanBindNotImplemented, 
            "`tls_exporter` not implemented!"
        );
    }
}

/// An `async` trait which contains a functions that should be used on the program
/// side which utilizes this crate. Those functions should return data 
/// from your TLS crate:
/// * TLS endpoint cert hash
/// * TLS unique
/// * TLS exporter data
/// 
/// By defualt each function returns error: ScramErrorCode::ChanBindNotImplemented
#[async_trait]
pub trait AsyncScramCbHelper: Sync
{
    /// This function returns (on success) a TLS endpoint cert data.
    /// For example from function: native_tls::TlsStream::tls_server_end_point()
    /// To indicate error, use macros: HELPER_ERROR_CLIENT or HELPER_ERROR_SERVER
    async fn get_tls_server_endpoint(&self) -> ScramResult<Vec<u8>>
    {
        {
            scram_ierror!(
                ScramErrorCode::ChanBindNotImplemented, 
                "`tls_server_endpoint` not implemented!"
            );
        }
    }

    /// This function returns (on success) a TLS unique data.
    /// To indicate error, use macros: HELPER_ERROR_CLIENT or HELPER_ERROR_SERVER
    async fn get_tls_unique(&self) -> ScramResult<Vec<u8>>
    {
        scram_ierror!(
            ScramErrorCode::ChanBindNotImplemented, 
            "`tls_unique` not implemented!"
        );
    }

    /// This function returns (on success) a TLS exporter (TLS 1.3) data.
    /// To indicate error, use macros: HELPER_ERROR_CLIENT or HELPER_ERROR_SERVER
    async fn get_tls_exporter(&self) -> ScramResult<Vec<u8>>
    {
        scram_ierror!(
            ScramErrorCode::ChanBindNotImplemented, 
            "`tls_exporter` not implemented!"
        );
    }
}

/// Use this macro in functions of trais [ScramCbHelper], [AsyncScramCbHelper]
/// on client side in order to indicate that this type of channel bind is not supported!
#[macro_export]
macro_rules!  HELPER_UNSUP_CLIENT
{
    ($cbt:expr) => (
        $crate::scram_ierror!(
            $crate::scram_error::ScramErrorCode::ChanBindNotImplemented, 
            "`{}` not implemented!", $cbt
        );
    )
}

/// Use this macro in functions of trais [ScramCbHelper], [AsyncScramCbHelper]
/// on server side in order to indicate that this type of channel bind is not supported!
#[macro_export]
macro_rules!  HELPER_UNSUP_SERVER
{
    ($cbt:expr) => (
        $crate::scram_error!(
            $crate::scram_error::ScramErrorCode::MalformedScramMsg, 
            $crate::scram_error::ScramServerError::UnsupportedChannelBindingType,
            "`{}` unsupported channel bind type!", $cbt
        );
    )
}

/// Use this macro in functions of trais [ScramCbHelper], [AsyncScramCbHelper]
/// on client side in order to indicate that the data is not possible to retrive
#[macro_export]
macro_rules!  HELPER_ERROR_CLIENT
{
    ($cbt:expr, $($arg:tt)*) => (
        $crate::scram_ierror!(
            $crate::scram_error::ScramErrorCode::ExternalError, 
            "`{}` error: '{}'", $cbt, format!($($arg)*)
        );
    )
}

/// Use this macro in functions of trais [ScramCbHelper], [AsyncScramCbHelper]
/// on server side in order to indicate that the data is not possible to retrive
#[macro_export]
macro_rules!  HELPER_ERROR_SERVER
{
    ($cbt:expr, $($arg:tt)*) => (
        $crate::scram_error!(
            $crate::scram_error::ScramErrorCode::ExternalError, 
            $crate::scram_error::ScramServerError::OtherError,
            "`{}` error: '{}'", $cbt, format!($($arg)*)
        );
    )
}