1use crate::{
6 channel::{Channel, ChannelDuplex, ChannelRole},
7 error::{BuilderError, Error},
8 handshake::HandshakeState,
9 key::{KeyAgreement, KeyGenerator, KeyType},
10 nonce::NonceGenerator,
11 params::Params,
12 prologue::Prologue,
13 session::Session,
14 tag::{Tag, TaggedData},
15 transport::TransportOrder,
16};
17use core::marker::PhantomData;
18use strobe_rs::{SecParam, Strobe};
19
20pub struct Builder<K, PG, NG, T, N, P, S, SS>
23where
24 K: KeyType + KeyGenerator<T, P, S> + KeyAgreement<T, P, S, SS>,
25 PG: Prologue,
26 NG: NonceGenerator<T, N>,
27 T: Tag,
28 N: TaggedData<T>,
29 P: TaggedData<T>,
30 S: TaggedData<T>,
31 SS: TaggedData<T>,
32{
33 params: Params<K, T, P, S, SS>,
35 prologue: PG,
37 nonce_generator: NG,
39 local_static_secret_key: S,
41 local_static_public_key: P,
43 local_ephemeral_secret_key: S,
45 local_ephemeral_public_key: P,
47 remote_static_public_key: P,
49 pre_shared_key: SS,
51 msg_order: TransportOrder,
53 _t: PhantomData<T>,
55 _n: PhantomData<N>,
56}
57
58impl<K, PG, NG, T, N, P, S, SS> Builder<K, PG, NG, T, N, P, S, SS>
59where
60 K: KeyType + KeyGenerator<T, P, S> + KeyAgreement<T, P, S, SS>,
61 PG: Prologue,
62 NG: NonceGenerator<T, N>,
63 T: Tag,
64 N: TaggedData<T>,
65 P: TaggedData<T>,
66 S: TaggedData<T>,
67 SS: TaggedData<T>,
68{
69 pub fn new(params: &Params<K, T, P, S, SS>, nonce_generator: &NG) -> Self {
71 Builder {
72 params: params.clone(),
73 prologue: PG::default(),
74 nonce_generator: nonce_generator.clone(),
75 local_static_secret_key: S::default(),
76 local_static_public_key: P::default(),
77 local_ephemeral_secret_key: S::default(),
78 local_ephemeral_public_key: P::default(),
79 remote_static_public_key: P::default(),
80 pre_shared_key: SS::default(),
81 msg_order: TransportOrder::InOrder,
82 _t: PhantomData,
83 _n: PhantomData,
84 }
85 }
86
87 pub fn with_prologue(mut self, data: &PG) -> Self {
89 self.prologue = data.clone();
90 self
91 }
92
93 pub fn local_static_secret_key(mut self, key: &S) -> Self {
95 self.local_static_secret_key = key.clone();
96 self
97 }
98
99 pub fn local_static_public_key(mut self, key: &P) -> Self {
101 self.local_static_public_key = key.clone();
102 self
103 }
104
105 pub fn local_ephemeral_secret_key(mut self, key: &S) -> Self {
107 self.local_ephemeral_secret_key = key.clone();
108 self
109 }
110
111 pub fn local_ephemeral_public_key(mut self, key: &P) -> Self {
113 self.local_ephemeral_public_key = key.clone();
114 self
115 }
116
117 pub fn remote_static_public_key(mut self, key: &P) -> Self {
119 self.remote_static_public_key = key.clone();
120 self
121 }
122
123 pub fn pre_shared_key(mut self, key: &SS) -> Self {
125 self.pre_shared_key = key.clone();
126 self
127 }
128
129 pub fn msg_order(mut self, order: &TransportOrder) -> Self {
131 self.msg_order = *order;
132 self
133 }
134
135 pub fn build_initiator(self) -> Result<Session<K, PG, NG, T, N, P, S, SS>, Error> {
137 self.build(&ChannelRole::Initiator)
138 }
139
140 pub fn build_responder(self) -> Result<Session<K, PG, NG, T, N, P, S, SS>, Error> {
142 self.build(&ChannelRole::Responder)
143 }
144
145 pub fn build(self, role: &ChannelRole) -> Result<Session<K, PG, NG, T, N, P, S, SS>, Error> {
147 if self.local_static_secret_key.get_tag().get_data_length() == 0
148 && self.params.handshake.needs_local_static_key(role)
149 {
150 return Err(Error::Builder(BuilderError::MissingLocalSecretKey));
151 }
152
153 if self.remote_static_public_key.get_tag().get_data_length() == 0
154 && self.params.handshake.needs_remote_static_key(role)
155 {
156 return Err(Error::Builder(BuilderError::MissingRemotePublicKey));
157 }
158
159 if self.pre_shared_key.get_tag().get_data_length() == 0
160 && self.params.handshake.needs_pre_shared_key(role)
161 {
162 return Err(Error::Builder(BuilderError::MissingPreSharedKey));
163 }
164
165 let strobe = Strobe::new(format!("{}", self.params).as_bytes(), SecParam::B256);
167
168 let hs = HandshakeState::new(self.params.handshake, role, &ChannelDuplex::Full);
170
171 let channel = Channel::new(&strobe, &hs, &self.nonce_generator, self.msg_order, false);
173
174 Ok(Session::Handshake {
175 params: self.params,
176 channel,
177 prologue: self.prologue,
178 sp: self.local_static_public_key,
179 ss: self.local_static_secret_key,
180 ep: self.local_ephemeral_public_key,
181 es: self.local_ephemeral_secret_key,
182 rs: self.remote_static_public_key,
183 re: P::default(),
184 psk: self.pre_shared_key,
185 prf: [0u8; 32],
186 })
187 }
188}