Achieve first working Announce registration for Guests
This commit is contained in:
@@ -16,11 +16,11 @@ actix-tls = { version = "3.3.0", features = ["rustls-0_22"] }
|
||||
rustls = "0.22.2"
|
||||
tracing = "0.1"
|
||||
tracing-subscriber = "0.3"
|
||||
futures-util = "0.3.30"
|
||||
futures = "0.3"
|
||||
thiserror = "1.0.56"
|
||||
tokio-util = { version = "0.7.10", features = ["codec"] }
|
||||
rmp-serde = "1.1.2"
|
||||
rcgen = "0.12.1"
|
||||
rcgen = { version = "0.12.1", features = ["x509-parser"] }
|
||||
|
||||
[[bin]]
|
||||
name = "init_certs"
|
||||
|
||||
@@ -1,17 +1,37 @@
|
||||
use actix::prelude::*;
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
use libbonknet::{load_cert, load_prkey, FromServerMessage, RequiredReplyValues, FromGuestServerMessage};
|
||||
use libbonknet::{load_cert, load_prkey, FromServerMessage, RequiredReplyValues, FromGuestServerMessage, ToGuestServerMessage};
|
||||
use rustls::{RootCertStore, ServerConfig};
|
||||
use rustls::server::WebPkiClientVerifier;
|
||||
use actix_tls::accept::rustls_0_22::{Acceptor as RustlsAcceptor, TlsStream};
|
||||
use actix_server::Server;
|
||||
use actix_rt::net::TcpStream;
|
||||
use actix_service::{ServiceFactoryExt as _};
|
||||
use futures_util::{StreamExt};
|
||||
use futures::{StreamExt, SinkExt};
|
||||
use thiserror::Error;
|
||||
use tokio_util::codec::{Framed, LengthDelimitedCodec};
|
||||
use tracing::{info, error};
|
||||
use rcgen::{Certificate, CertificateParams, DnType, KeyPair};
|
||||
|
||||
struct ServerCert {
|
||||
cert: Vec<u8>,
|
||||
prkey: Vec<u8>,
|
||||
}
|
||||
|
||||
fn generate_server_cert(root_cert: &Certificate, name: &str) -> ServerCert {
|
||||
let mut params = CertificateParams::new(vec!["entity.other.host".into(), format!("bonk.server.{name}")]);
|
||||
params.distinguished_name.push(DnType::CommonName, format!("{name}"));
|
||||
params.use_authority_key_identifier_extension = true;
|
||||
params.key_usages.push(rcgen::KeyUsagePurpose::DigitalSignature);
|
||||
params
|
||||
.extended_key_usages
|
||||
.push(rcgen::ExtendedKeyUsagePurpose::ClientAuth);
|
||||
let certificate = Certificate::from_params(params).unwrap();
|
||||
let cert = certificate.serialize_der_with_signer(root_cert).unwrap();
|
||||
let prkey = certificate.serialize_private_key_der();
|
||||
ServerCert { cert, prkey }
|
||||
}
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
enum DBError {
|
||||
@@ -21,6 +41,12 @@ enum DBError {
|
||||
// GenericFailure,
|
||||
}
|
||||
|
||||
#[derive(Message)]
|
||||
#[rtype(result = "bool")]
|
||||
struct IsNameRegistered {
|
||||
name: String,
|
||||
}
|
||||
|
||||
#[derive(Message)]
|
||||
#[rtype(result = "Result<(), DBError>")]
|
||||
struct RegisterServer {
|
||||
@@ -53,6 +79,14 @@ impl Handler<RegisterServer> for ServerCertDB {
|
||||
}
|
||||
}
|
||||
|
||||
impl Handler<IsNameRegistered> for ServerCertDB {
|
||||
type Result = bool;
|
||||
|
||||
fn handle(&mut self, msg: IsNameRegistered, _ctx: &mut Self::Context) -> Self::Result {
|
||||
self.db.values().any(|x| *x == msg.name)
|
||||
}
|
||||
}
|
||||
|
||||
struct GuestServerConnection {
|
||||
stream: TlsStream<TcpStream>,
|
||||
}
|
||||
@@ -91,6 +125,7 @@ async fn main() {
|
||||
let broker_prkey_der = load_prkey("certs/broker_key.pem").unwrap();
|
||||
// SERVER ROOT
|
||||
let server_root_cert_der = load_cert("certs/server_root_cert.pem").unwrap();
|
||||
let server_root_prkey_der = load_prkey("certs/server_root_key.pem").unwrap();
|
||||
// GUESTSERVER ROOT
|
||||
let guestserver_root_cert_der = load_cert("certs/guestserver_root_cert.pem").unwrap();
|
||||
// CLIENT ROOT
|
||||
@@ -110,17 +145,25 @@ async fn main() {
|
||||
let server_acceptor = RustlsAcceptor::new(server_tlsconfig);
|
||||
|
||||
let server_root_cert_der = Arc::new(server_root_cert_der);
|
||||
let server_root_prkey = KeyPair::from_der(server_root_prkey_der.secret_pkcs8_der()).unwrap();
|
||||
let client_root_cert_der = Arc::new(client_root_cert_der);
|
||||
let guestserver_root_cert_der = Arc::new(guestserver_root_cert_der);
|
||||
let server_root_cert = Arc::new(Certificate::from_params(CertificateParams::from_ca_cert_der(
|
||||
&*server_root_cert_der,
|
||||
server_root_prkey
|
||||
).unwrap()).unwrap());
|
||||
|
||||
let server_db_addr = ServerCertDB {
|
||||
db: HashMap::new(),
|
||||
}.start();
|
||||
|
||||
Server::build()
|
||||
.bind("server-command", ("localhost", 2541), move || {
|
||||
let server_root_cert_der = Arc::clone(&server_root_cert_der);
|
||||
let client_root_cert_der = Arc::clone(&client_root_cert_der);
|
||||
let guestserver_root_cert_der = Arc::clone(&guestserver_root_cert_der);
|
||||
let _server_db_addr = ServerCertDB {
|
||||
db: HashMap::new(),
|
||||
}.start();
|
||||
let server_root_cert = Arc::clone(&server_root_cert);
|
||||
let server_db_addr = server_db_addr.clone();
|
||||
|
||||
// Set up TLS service factory
|
||||
server_acceptor
|
||||
@@ -130,6 +173,8 @@ async fn main() {
|
||||
let server_root_cert_der = Arc::clone(&server_root_cert_der);
|
||||
let client_root_cert_der = Arc::clone(&client_root_cert_der);
|
||||
let guestserver_root_cert_der = Arc::clone(&guestserver_root_cert_der);
|
||||
let server_root_cert = Arc::clone(&server_root_cert);
|
||||
let server_db_addr = server_db_addr.clone();
|
||||
async move {
|
||||
let peer_cert_der = stream.get_ref().1.peer_certificates().unwrap().last().unwrap().clone();
|
||||
if peer_cert_der == *server_root_cert_der {
|
||||
@@ -166,24 +211,51 @@ async fn main() {
|
||||
info!("Disconnection!");
|
||||
} else if peer_cert_der == *guestserver_root_cert_der {
|
||||
info!("GuestServer connection");
|
||||
let framed = Framed::new(stream, LengthDelimitedCodec::new());
|
||||
framed.for_each(|item| async move {
|
||||
match item {
|
||||
Ok(buf) => {
|
||||
use FromGuestServerMessage::*;
|
||||
let msg: FromGuestServerMessage = rmp_serde::from_slice(&buf).unwrap();
|
||||
info!("{:?}", msg);
|
||||
match msg {
|
||||
Announce { name } => {
|
||||
info!("Announced with name {}", name);
|
||||
let server_root_cert = Arc::clone(&server_root_cert);
|
||||
let codec = LengthDelimitedCodec::new();
|
||||
let mut transport = Framed::new(stream, codec);
|
||||
loop {
|
||||
match transport.next().await {
|
||||
None => {
|
||||
info!("Transport returned None");
|
||||
}
|
||||
Some(item) => {
|
||||
match item {
|
||||
Ok(buf) => {
|
||||
use FromGuestServerMessage::*;
|
||||
let msg: FromGuestServerMessage = rmp_serde::from_slice(&buf).unwrap();
|
||||
info!("{:?}", msg);
|
||||
match msg {
|
||||
Announce { name } => {
|
||||
info!("Announced with name {}", name);
|
||||
if server_db_addr.send(IsNameRegistered { name: name.clone() }).await.unwrap() {
|
||||
info!("Name {} already registered!", name);
|
||||
let reply = ToGuestServerMessage::FailedNameAlreadyOccupied;
|
||||
transport.send(rmp_serde::to_vec(&reply).unwrap().into()).await.unwrap();
|
||||
break; // Stop reading
|
||||
} else {
|
||||
let cert = generate_server_cert(&server_root_cert, name.as_str());
|
||||
server_db_addr.send(RegisterServer {
|
||||
cert: cert.cert.clone(),
|
||||
name,
|
||||
}).await.unwrap().unwrap();
|
||||
let reply = ToGuestServerMessage::OkAnnounce {
|
||||
server_cert: cert.cert,
|
||||
server_prkey: cert.prkey
|
||||
};
|
||||
transport.send(rmp_serde::to_vec(&reply).unwrap().into()).await.unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
info!("Disconnection: {:?}", e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
info!("Disconnection: {:?}", e);
|
||||
}
|
||||
}
|
||||
}).await;
|
||||
}
|
||||
} else if peer_cert_der == *client_root_cert_der {
|
||||
info!("Client connection");
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user