This commit is contained in:
parent
44ff1d8781
commit
75f4139dea
17 changed files with 382 additions and 131 deletions
|
|
@ -8,7 +8,7 @@ name = "server"
|
|||
path = "src/main.rs"
|
||||
|
||||
[dependencies]
|
||||
mtp = { version = "0.1.0", path = "../../", features = ["crypto", "host"] }
|
||||
mtp = { version = "0.1.0", path = "../../", features = ["crypto", "host", "files"] }
|
||||
rcgen = "0.14"
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
serde_json = { version = "1" }
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
use mtp::codec::{CommunicationType, CommunicationValue, DataType, DataTypeId, DataValue, TypeMap};
|
||||
use mtp::crypto::{
|
||||
CryptoError, Keyring, SignaturePublicKey, SignatureScheme, verify_ed25519,
|
||||
};
|
||||
use mtp::crypto::{CryptoError, Keyring, SignaturePublicKey, SignatureScheme, verify_ed25519};
|
||||
|
||||
struct Ed25519Verifier(SignaturePublicKey);
|
||||
|
||||
|
|
@ -57,7 +55,10 @@ pub fn process_and_respond(
|
|||
let enc = msg.get_data(DataType::EncryptedPayload);
|
||||
if matches!(enc, DataValue::EncryptedContainer(_)) {
|
||||
let mut dv = enc.clone();
|
||||
if dv.decrypt_into_container(host_keyring, b"demo-aad").is_some() {
|
||||
if dv
|
||||
.decrypt_into_container(host_keyring, b"demo-aad")
|
||||
.is_some()
|
||||
{
|
||||
if let Some(entries) = dv.as_container() {
|
||||
println!(" Decrypted EncryptedPayload: {:?}", entries);
|
||||
enc_status = format!("EncryptedPayload decrypted OK ({} entries)", entries.len());
|
||||
|
|
@ -93,7 +94,9 @@ pub fn process_and_respond(
|
|||
if let Some(pk_bundle) = client_pk {
|
||||
let verifier = Ed25519Verifier(pk_bundle.sig_cl_public_key.clone());
|
||||
let mut dv = secure.clone();
|
||||
if dv.decrypt_signed_encrypted_container(host_keyring, b"demo-aad").is_some()
|
||||
if dv
|
||||
.decrypt_signed_encrypted_container(host_keyring, b"demo-aad")
|
||||
.is_some()
|
||||
&& dv.verify_into_container(&verifier).is_some()
|
||||
{
|
||||
if let Some(entries) = dv.as_container() {
|
||||
|
|
|
|||
|
|
@ -1,50 +1,33 @@
|
|||
use std::fs;
|
||||
|
||||
use mtp::crypto::kem::HybridKem;
|
||||
use mtp::crypto::{Ed25519Signer, Keyring, MlDsaSigner};
|
||||
use mtp::crypto::Keyring;
|
||||
use mtp::files::{load_keyring, save_keyring, save_public_key_bundle};
|
||||
|
||||
/* Host id is fixed for the example; only the keyring itself is persisted. */
|
||||
const HOST_ID: u64 = 1;
|
||||
|
||||
pub fn load_or_generate_host_keys(
|
||||
path: &str,
|
||||
keyring_path: &str,
|
||||
) -> Result<(u64, Keyring), Box<dyn std::error::Error>> {
|
||||
if let Ok(data) = fs::read_to_string(path) {
|
||||
let json: serde_json::Value = serde_json::from_str(&data)?;
|
||||
let hid = json["host_id"].as_u64().unwrap_or(1);
|
||||
let keyring = Keyring::from_bytes(&hex::decode(json["keyring"].as_str().unwrap())?)?;
|
||||
println!("Loaded host keys (ID: {})", hid);
|
||||
return Ok((hid, keyring));
|
||||
if let Ok(keyring) = load_keyring(keyring_path) {
|
||||
println!("Loaded host keyring from {keyring_path}");
|
||||
return Ok((HOST_ID, keyring));
|
||||
}
|
||||
|
||||
let (_ed_signer, sig_sk, sig_pk) = Ed25519Signer::generate();
|
||||
let (_pq_signer, sig_pq_sk, sig_pq_pk) = MlDsaSigner::generate();
|
||||
let (kem_sk, kem_pk) = HybridKem::generate_keypair();
|
||||
let keyring = Keyring::new(kem_pk, kem_sk, sig_pq_pk, sig_pq_sk, sig_pk, sig_sk);
|
||||
|
||||
let json = serde_json::json!({
|
||||
"host_id": 1,
|
||||
"keyring": hex::encode(keyring.to_bytes()),
|
||||
});
|
||||
fs::write(path, serde_json::to_string_pretty(&json)?)?;
|
||||
println!("Generated host keys -> {path}");
|
||||
Ok((1u64, keyring))
|
||||
let keyring = Keyring::generate();
|
||||
save_keyring(&keyring, keyring_path)?;
|
||||
println!("Generated host keyring -> {keyring_path}");
|
||||
Ok((HOST_ID, keyring))
|
||||
}
|
||||
|
||||
pub fn export_host_public_keys(host_keyring: &Keyring) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let public_key_bundle_hex = hex::encode(host_keyring.public_key_bundle().as_bytes());
|
||||
let bundle = host_keyring.public_key_bundle();
|
||||
save_public_key_bundle(&bundle, "host.mpkb")?;
|
||||
|
||||
fs::write("host_public_key_bundle.hex", &public_key_bundle_hex)?;
|
||||
/* The web client fetches the bundle as hex over HTTP. */
|
||||
let bundle_hex = hex::encode(bundle.as_bytes());
|
||||
fs::write("host_public_key_bundle.hex", &bundle_hex)?;
|
||||
fs::create_dir_all("web-client/public")?;
|
||||
fs::write(
|
||||
"web-client/public/host_public_key_bundle.hex",
|
||||
&public_key_bundle_hex,
|
||||
)?;
|
||||
fs::write(
|
||||
"host_enc_kem_pk.bin",
|
||||
host_keyring.kem_public_key.as_bytes(),
|
||||
)?;
|
||||
fs::write("host_sig_pk.bin", host_keyring.sig_cl_public_key.as_bytes())?;
|
||||
fs::write(
|
||||
"host_sig_pq_pk.bin",
|
||||
host_keyring.sig_pq_public_key.as_bytes(),
|
||||
)?;
|
||||
fs::write("web-client/public/host_public_key_bundle.hex", &bundle_hex)?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
tls::export_webtransport_cert_hash(&cert_hash)?;
|
||||
println!("WebTransport certificate sha256: {cert_hash}");
|
||||
|
||||
let (_host_id, host_keyring) = keys::load_or_generate_host_keys("host_keys.json")?;
|
||||
let (_host_id, host_keyring) = keys::load_or_generate_host_keys("host.mk")?;
|
||||
keys::export_host_public_keys(&host_keyring)?;
|
||||
|
||||
// The keyring is moved into the host config; keep a copy for decrypting the
|
||||
|
|
@ -47,7 +47,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
let (clients, next_id) = clients::load_client_db("clients.json")?;
|
||||
|
||||
let clients_for_get = clients.clone();
|
||||
let get_existing_user = move |id: u64| {
|
||||
let get_existing_user = move |id: u64, _description: Option<String>| {
|
||||
let clients = clients_for_get.clone();
|
||||
Box::pin(async move {
|
||||
let result = clients.lock().unwrap().get(&id).cloned();
|
||||
|
|
@ -63,7 +63,8 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
let clients_for_register = clients.clone();
|
||||
let next_id_for_register = next_id.clone();
|
||||
let clients_path = "clients.json".to_string();
|
||||
let complete_register = move |bundle: mtp::crypto::PublicKeyBundle| {
|
||||
let complete_register = move |bundle: mtp::crypto::PublicKeyBundle,
|
||||
_description: Option<String>| {
|
||||
let db_arc = clients_for_register.clone();
|
||||
let nid_arc = next_id_for_register.clone();
|
||||
let path = clients_path.clone();
|
||||
|
|
@ -95,7 +96,11 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
cert_pem,
|
||||
key_pem,
|
||||
)
|
||||
.with_authentication(host_keyring, get_existing_user, complete_register)
|
||||
.with_authentication(
|
||||
host_keyring,
|
||||
Box::new(get_existing_user),
|
||||
Box::new(complete_register),
|
||||
)
|
||||
.with_authentication_policy(AuthenticationPolicy::ForceAuthentication);
|
||||
|
||||
let mut host = MTPHost::new(config).await?;
|
||||
|
|
|
|||
Loading…
Reference in a new issue