1use crate::bytes::{as_mut, as_ref};
2use crate::crypto::outcome::HandshakeKeys;
3use crate::crypto::{keys::*, message::*, outcome::*, shared_secret::*};
4use crate::error::HandshakeError;
5use crate::util::send;
6
7use ssb_crypto::{ephemeral::generate_ephemeral_keypair, Keypair, NetworkKey, PublicKey};
8
9use core::mem::size_of;
10use futures_io::{AsyncRead, AsyncWrite};
11use futures_util::io::{AsyncReadExt, AsyncWriteExt};
12use std::io;
13
14pub async fn client_side<S>(
17 mut stream: S,
18 net_key: &NetworkKey,
19 keypair: &Keypair,
20 server_pk: &PublicKey,
21) -> Result<HandshakeKeys, HandshakeError<io::Error>>
22where
23 S: AsyncRead + AsyncWrite + Unpin,
24{
25 let r = try_client_side(&mut stream, net_key, keypair, server_pk).await;
26 if r.is_err() {
27 stream.close().await.unwrap_or(());
28 }
29 r
30}
31
32async fn try_client_side<S>(
33 mut stream: S,
34 net_key: &NetworkKey,
35 keypair: &Keypair,
36 server_pk: &PublicKey,
37) -> Result<HandshakeKeys, HandshakeError<io::Error>>
38where
39 S: AsyncRead + AsyncWrite + Unpin,
40{
41 use HandshakeError::*;
42
43 let server_pk = ServerPublicKey(*server_pk);
44 let (eph_pk, eph_sk) = {
45 let (p, s) = generate_ephemeral_keypair();
46 (ClientEphPublicKey(p), ClientEphSecretKey(s))
47 };
48
49 send(&mut stream, ClientHello::new(&eph_pk, &net_key)).await?;
50
51 let server_eph_pk = {
52 let mut buf = [0u8; size_of::<ServerHello>()];
53 stream.read_exact(&mut buf).await?;
54 as_mut::<ServerHello>(&mut buf)
55 .verify(&net_key)
56 .ok_or(ServerHelloVerifyFailed)?
57 };
58
59 let shared_a = SharedA::client_side(&eph_sk, &server_eph_pk).ok_or(SharedAInvalid)?;
61 let shared_b = SharedB::client_side(&eph_sk, &server_pk).ok_or(SharedBInvalid)?;
62 let shared_c = SharedC::client_side(&keypair, &server_eph_pk).ok_or(SharedCInvalid)?;
63
64 send(
66 &mut stream,
67 ClientAuth::new(&keypair, &server_pk, &net_key, &shared_a, &shared_b),
68 )
69 .await?;
70
71 let mut buf = [0u8; size_of::<ServerAccept>()];
72 stream.read_exact(&mut buf).await?;
73 as_ref::<ServerAccept>(&buf)
74 .verify(
75 &keypair, &server_pk, &net_key, &shared_a, &shared_b, &shared_c,
76 )
77 .ok_or(ServerAcceptVerifyFailed)?;
78
79 Ok(HandshakeKeys {
80 read_key: server_to_client_key(
81 &ClientPublicKey(keypair.public),
82 &net_key,
83 &shared_a,
84 &shared_b,
85 &shared_c,
86 ),
87 read_starting_nonce: starting_nonce(&net_key, &eph_pk.0),
88
89 write_key: client_to_server_key(&server_pk, &net_key, &shared_a, &shared_b, &shared_c),
90 write_starting_nonce: starting_nonce(&net_key, &server_eph_pk.0),
91
92 peer_key: server_pk.0,
93 })
94}