takproto 0.4.2

Rust library for TAK (Team Awareness Kit) Protocol - send CoT messages to TAK servers with mTLS support
Documentation
//! Test client certificate authentication with invalid/self-signed server cert
//!
//! This example demonstrates that client authentication (mTLS) now works
//! correctly even when using danger_accept_invalid_certs().
//!
//! Use Case: Your TAK server has a self-signed certificate, but you still
//! need to authenticate with a client certificate.
//!
//! Usage:
//! ```
//! cargo run --example test_client_cert_with_invalid_server --features openssl-p12 -- \
//!     <server:port> <server_name> <p12_file> <password>
//! ```

use takproto::helpers::contact;
use takproto::{CotEventBuilder, TakClient, TlsConfigBuilder};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let args: Vec<String> = std::env::args().collect();
    if args.len() < 5 {
        eprintln!(
            "Usage: {} <server:port> <server_name> <p12_file> <password>",
            args[0]
        );
        std::process::exit(1);
    }

    let server_addr = &args[1];
    let server_name = &args[2];
    let p12_file = &args[3];
    let password = &args[4];

    println!("===================================================");
    println!("Testing: Client Auth + Accept Invalid Server Cert");
    println!("===================================================");
    println!("Server: {}", server_addr);
    println!("P12 File: {}", p12_file);
    println!("\n⚠️  Accepting invalid server certificates (testing only!)");
    println!("✓ Client certificate will still be sent for authentication\n");

    // Build TLS config that:
    // 1. Loads client certificate from P12 file
    // 2. Accepts invalid/self-signed server certificates
    println!("Loading P12 and configuring TLS...");
    let tls_config = TlsConfigBuilder::new()
        .with_p12(p12_file, password)?
        .danger_accept_invalid_certs(true) // Accept self-signed server cert
        .build()?;
    println!("✓ TLS configuration created\n");

    // Connect to TAK server
    println!("Connecting to {}...", server_addr);
    let mut client = TakClient::connect_tls(server_addr, server_name, tls_config).await?;
    println!("✓ Connected! (Client cert was accepted)\n");

    // Negotiate protocol
    println!("Negotiating protocol...");
    client.negotiate_protocol(1, 60).await?;
    println!("✓ Protocol negotiated (protobuf mode)\n");

    // Send a test event
    println!("Sending test event...");
    let event = CotEventBuilder::new()
        .uid("CLIENT-CERT-TEST")
        .cot_type("a-f-G-U-C")
        .lat_lon(39.377445, -76.832160)
        .hae(10.0)
        .ce_le(9.9, 9.9)
        .how("m-g")
        .stale_minutes(5)
        .with_contact(contact("ClientCertTest", None))
        .build()?;

    client.send_cot_event(event).await?;
    println!("✓ Event sent successfully!\n");

    println!("===================================================");
    println!("✅ SUCCESS!");
    println!("===================================================");
    println!("Client certificate authentication works correctly");
    println!("even when accepting invalid server certificates.");
    println!("\nCheck your TAK client for 'CLIENT-CERT-TEST' marker.");

    Ok(())
}