libp2p_webrtc_utils/
noise.rs1use futures::{AsyncRead, AsyncWrite, AsyncWriteExt};
22use libp2p_core::{
23 upgrade::{InboundConnectionUpgrade, OutboundConnectionUpgrade},
24 UpgradeInfo,
25};
26use libp2p_identity as identity;
27use libp2p_identity::PeerId;
28use libp2p_noise as noise;
29pub use noise::Error;
30
31use crate::fingerprint::Fingerprint;
32
33pub async fn inbound<T>(
34 id_keys: identity::Keypair,
35 stream: T,
36 client_fingerprint: Fingerprint,
37 server_fingerprint: Fingerprint,
38) -> Result<PeerId, Error>
39where
40 T: AsyncRead + AsyncWrite + Unpin + Send + 'static,
41{
42 let noise = noise::Config::new(&id_keys)
43 .unwrap()
44 .with_prologue(noise_prologue(client_fingerprint, server_fingerprint));
45 let info = noise.protocol_info().next().unwrap();
46 let (peer_id, mut channel) = noise.upgrade_outbound(stream, info).await?;
49
50 channel.close().await?;
51
52 Ok(peer_id)
53}
54
55pub async fn outbound<T>(
56 id_keys: identity::Keypair,
57 stream: T,
58 server_fingerprint: Fingerprint,
59 client_fingerprint: Fingerprint,
60) -> Result<PeerId, Error>
61where
62 T: AsyncRead + AsyncWrite + Unpin + Send + 'static,
63{
64 let noise = noise::Config::new(&id_keys)
65 .unwrap()
66 .with_prologue(noise_prologue(client_fingerprint, server_fingerprint));
67 let info = noise.protocol_info().next().unwrap();
68 let (peer_id, mut channel) = noise.upgrade_inbound(stream, info).await?;
71
72 channel.close().await?;
73
74 Ok(peer_id)
75}
76
77pub(crate) fn noise_prologue(
78 client_fingerprint: Fingerprint,
79 server_fingerprint: Fingerprint,
80) -> Vec<u8> {
81 let client = client_fingerprint.to_multihash().to_bytes();
82 let server = server_fingerprint.to_multihash().to_bytes();
83 const PREFIX: &[u8] = b"libp2p-webrtc-noise:";
84 let mut out = Vec::with_capacity(PREFIX.len() + client.len() + server.len());
85 out.extend_from_slice(PREFIX);
86 out.extend_from_slice(&client);
87 out.extend_from_slice(&server);
88 out
89}
90
91#[cfg(test)]
92mod tests {
93 use hex_literal::hex;
94
95 use super::*;
96
97 #[test]
98 fn noise_prologue_tests() {
99 let a = Fingerprint::raw(hex!(
100 "3e79af40d6059617a0d83b83a52ce73b0c1f37a72c6043ad2969e2351bdca870"
101 ));
102 let b = Fingerprint::raw(hex!(
103 "30fc9f469c207419dfdd0aab5f27a86c973c94e40548db9375cca2e915973b99"
104 ));
105
106 let prologue1 = noise_prologue(a, b);
107 let prologue2 = noise_prologue(b, a);
108
109 assert_eq!(hex::encode(prologue1), "6c69627032702d7765627274632d6e6f6973653a12203e79af40d6059617a0d83b83a52ce73b0c1f37a72c6043ad2969e2351bdca870122030fc9f469c207419dfdd0aab5f27a86c973c94e40548db9375cca2e915973b99");
110 assert_eq!(hex::encode(prologue2), "6c69627032702d7765627274632d6e6f6973653a122030fc9f469c207419dfdd0aab5f27a86c973c94e40548db9375cca2e915973b9912203e79af40d6059617a0d83b83a52ce73b0c1f37a72c6043ad2969e2351bdca870");
111 }
112}