use futures::{select, FutureExt}; use log::{info, warn}; use std::sync::Arc; use webrtc_dtls::{ cipher_suite::CipherSuiteId, config::{Config, ExtendedMasterSecretType}, conn::DTLSConn, }; use webrtc_util::Conn; #[async_std::main] async fn main() -> anyhow::Result<()> { env_logger::init(); eprint!("Peer: "); let mut to = String::new(); async_std::io::stdin().read_line(&mut to).await?; let addr = to.trim_end(); // eprintln!("CA cert:"); // let mut cert = String::new(); // while 0 != async_std::io::stdin().read_line(&mut cert).await? { // if cert.ends_with("-----END CERTIFICATE-----\n") { // break; // } // } // let certificates = Certificate::generate_self_signed(vec!["localhost".to_owned()]) // .ok() // .into_iter() // .collect(); fn dh(sk: &ed25519_compact::SecretKey, pk: &[u8]) -> Result, ed25519_compact::Error> { let xsk = ed25519_compact::x25519::SecretKey::from_ed25519(sk)?; let pk = ed25519_compact::PublicKey::from_slice(pk)?; let xpk = ed25519_compact::x25519::PublicKey::from_ed25519(&pk)?; let secret = xpk.dh(&xsk)?; Result::<_, ed25519_compact::Error>::Ok(secret.to_vec()) } let key = ed25519_compact::KeyPair::generate(); let my_hint = key.pk.to_vec(); let psk_fn = move |hint: &[u8]| match dh(&key.sk, hint) { Ok(v) => { info!("Ok {v:?}"); Ok(v) } Err(e) => { warn!("Err {e:?}"); Err(webrtc_dtls::Error::Other(format!( "Key exchange failed: {e}" ))) } }; let config = Config { server_name: "localhost".into(), //certificates, //insecure_skip_verify: true, extended_master_secret: ExtendedMasterSecretType::Require, psk_identity_hint: Some(my_hint), psk: Some(Arc::new(psk_fn)), cipher_suites: vec![ CipherSuiteId::Tls_Ecdhe_Ecdsa_With_Aes_128_Gcm_Sha256, CipherSuiteId::Tls_Ecdhe_Rsa_With_Aes_128_Gcm_Sha256, CipherSuiteId::Tls_Ecdhe_Ecdsa_With_Aes_256_Cbc_Sha, CipherSuiteId::Tls_Ecdhe_Rsa_With_Aes_256_Cbc_Sha, CipherSuiteId::Tls_Psk_With_Aes_128_Ccm, CipherSuiteId::Tls_Psk_With_Aes_128_Ccm_8, CipherSuiteId::Tls_Psk_With_Aes_128_Gcm_Sha256, ], ..Default::default() }; // info!("Cert {cert:?}"); // let cert = rustls_pemfile::certs(&mut cert.as_bytes())? // .into_iter() // .map(rustls::Certificate); // for c in cert { // config.roots_cas.add(&c).expect("cert"); // } let socket = tokio::net::UdpSocket::bind("0.0.0.0:0").await?; socket.connect(addr).await?; info!("On {}", socket.local_addr()?); let dtls_conn = Arc::new(DTLSConn::new(Arc::new(socket), config, true, None).await?); let dtls_conn_rcv = dtls_conn.clone(); let mut print_fut = Box::pin(async move { info!("Connected!"); let mut buf = [0; 2042]; loop { let len = dtls_conn_rcv.recv(&mut buf).await?; info!("Received {len} bytes") } anyhow::Ok(()) }) .fuse(); let mut send_fut = Box::pin(async move { loop { let mut input = String::new(); async_std::io::stdin().read_line(&mut input).await?; dtls_conn.send(input.as_bytes()).await?; } anyhow::Ok(()) }) .fuse(); select! { res = print_fut => warn!("print finished: {res:?}"), res = send_fut => warn!("send finished: {res:?}"), } Ok(()) }