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
use crate::{
datatypes::{MessageDirection, MessageWithType, ProtocolHandleOutput},
protocols::{
did_exchange::generate_did_exchange_protocol,
issue_credential::generate_issue_credential_protocol,
pingpong::generate_ping_pong_protocol,
present_proof::generate_present_proof_protocol,
presentation_exchange::generate_presentation_exchange_protocol,
protocol::Protocol,
},
};
pub struct ProtocolHandler {}
impl ProtocolHandler {
/// Runs all protocol handlers for a message, to prepare it for sending. Each protocol can enrich
/// the message with step specific information or can store things like communication keys.
///
/// # Arguments
/// * `message` - message string (should match message.rs/ExtendedMessage)
///
/// # Returns
/// * `ProtocolHandleOutput` - general information about the analyzed protocol step
pub fn before_send(
options: &str,
message: &str,
) -> Result<ProtocolHandleOutput, Box<dyn std::error::Error>> {
handle_protocol(options, message, MessageDirection::Send)
}
/// Runs all protocol handlers for a message, to analyze it after receiving and decryption.
/// Each protocol can enrich the message with step specific information or can store things
/// like communication keys.
///
/// # Arguments
/// * `message` - message string (should match message.rs/ExtendedMessage))
///
/// # Returns
/// * `ProtocolHandleOutput` - general information about the analyzed protocol step
pub fn after_receive(
options: &str,
message: &str,
) -> Result<ProtocolHandleOutput, Box<dyn std::error::Error>> {
handle_protocol(options, message, MessageDirection::Receive)
}
}
/// General protocol step handler for analyzing messages with a direction (incoming / outgoing).
/// It analyse the message type and checks if a step with a specific direction is configured.
/// When a step is found, the logic will be executed and no other handler will be searched.
fn handle_protocol(
options: &str,
message: &str,
direction: MessageDirection,
) -> Result<ProtocolHandleOutput, Box<dyn std::error::Error>> {
let parsed_message: MessageWithType = serde_json::from_str(message)?;
let m_type = parsed_message.r#type;
// handle multiple protocols dynamically
let protocols: [&Protocol; 5] = [
&generate_did_exchange_protocol(),
&generate_ping_pong_protocol(),
&generate_present_proof_protocol(),
&generate_issue_credential_protocol(),
&generate_presentation_exchange_protocol(),
];
// protocol results
let mut protocol_name: String = String::from("unknown");
let mut step_name: String = String::from("unknown");
let mut encrypt = true;
let mut metadata: String = String::from("{}");
let mut message_output: String = String::from(message);
for protocol in &protocols {
// check if the type includes the protocol name
if m_type.contains(&protocol.name) {
protocol_name = String::from(&protocol.name);
for x in 0..protocol.steps.len() {
let step = &protocol.steps[x];
let protocol_type = format!("{}/{}", protocol_name, step.name);
// check for configured step names and directions
if step.direction == direction && m_type.contains(&protocol_type) {
let step_outcome = (step.handler)(options, message)?;
encrypt = step_outcome.encrypt;
metadata = step_outcome.metadata;
message_output = step_outcome.message;
step_name = String::from(&step.name);
break;
}
}
}
if protocol_name != "unknown" && step_name != "unknown" {
break;
}
}
Ok(ProtocolHandleOutput {
direction,
encrypt,
protocol: protocol_name,
metadata,
message: message_output,
step: step_name,
})
}