Skip to content

Commit

Permalink
wip: example rewrite with fixture
Browse files Browse the repository at this point in the history
  • Loading branch information
heeckhau committed Oct 23, 2024
1 parent 8ac45b3 commit ef43cba
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 21 deletions.
1 change: 1 addition & 0 deletions crates/examples/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ tlsn-verifier = { workspace = true }
tlsn-formats = { workspace = true }
tlsn-tls-core = { workspace = true }
tls-server-fixture = { workspace = true }
tlsn-server-fixture = { workspace = true }

bincode = { workspace = true }
chrono = { workspace = true }
Expand Down
25 changes: 18 additions & 7 deletions crates/examples/attestation/README.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,28 @@
## Simple Attestation Example: Notarize Public Data from example.com (Rust) <a name="rust-simple"></a>

This example demonstrates the simplest possible use case for TLSNotary:
1. Fetch <https://example.com/> and acquire an attestation of its content.
This example demonstrates the simplest possible use case for TLSNotary. We will run a Server, Prover and Notary.

1. Notarize a request from the test server and acquire an attestation of its content.
2. Create a verifiable presentation using the attestation, while redacting the value of a header.
3. Verify the presentation.

### 1. Notarize <https://example.com/>

Run the `prove` binary.

```shell
cargo run --release --example attestation_prove
```
1. Run the test server:
```sh
PORT=4000 cargo run --bin tlsn-server-fixture
```
2. Run the notary server:
```
cd crates/notary/server
cargo run -r -- --tls-enabled false
```
3. Run the `prove` binary.
```shell
SERVER_PORT=4000 cargo run --release --example attestation_prove
```

TODO : DEBUG: RUST_LOG=debug,yamux=info,uid_mux=info

If the notarization was successful, you should see this output in the console:

Expand Down
86 changes: 74 additions & 12 deletions crates/examples/attestation/prove.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,50 +2,99 @@
// an HTTP request sent to example.com. The attestation and secrets are saved to
// disk.

use http_body_util::Empty;
use std::env;

use http_body_util::{BodyExt, Empty};
use hyper::{body::Bytes, Request, StatusCode};
use hyper_util::rt::TokioIo;
use tokio_util::compat::{FuturesAsyncReadCompatExt, TokioAsyncReadCompatExt};

use notary_client::{Accepted, NotarizationRequest, NotaryClient};
use tls_server_fixture::SERVER_DOMAIN;
use tlsn_common::config::ProtocolConfig;
use tlsn_core::{request::RequestConfig, transcript::TranscriptCommitConfig};
use tlsn_examples::run_notary;
use tlsn_formats::http::{DefaultHttpCommitter, HttpCommit, HttpTranscript};
use tlsn_formats::{
http::{DefaultHttpCommitter, HttpCommit, HttpTranscript},
json::{DefaultJsonCommitter, JsonCommit},
};
use tlsn_prover::{Prover, ProverConfig};
use tlsn_server_fixture::DEFAULT_FIXTURE_PORT;
use tracing::debug;

// Setting of the application server
const USER_AGENT: &str = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36";
// Maximum number of bytes that can be sent from prover to server
const MAX_SENT_DATA: usize = 1 << 12;
// Maximum number of bytes that can be received by prover from server
const MAX_RECV_DATA: usize = 1 << 14;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
tracing_subscriber::fmt::init();

let (prover_socket, notary_socket) = tokio::io::duplex(1 << 16);
let notary_host: String = env::var("NOTARY_HOST").unwrap_or("127.0.0.1".into());
let notary_port: u16 = env::var("NOTARY_PORT")
.map(|port| port.parse().expect("port should be valid integer"))
.unwrap_or(7047);
let server_host: String = env::var("SERVER_HOST").unwrap_or("127.0.0.1".into());
let server_port: u16 = env::var("SERVER_PORT")
.map(|port| port.parse().expect("port should be valid integer"))
.unwrap_or(DEFAULT_FIXTURE_PORT);

let auth_token = "random_auth_token";

// Build a client to connect to the notary server.
let notary_client = NotaryClient::builder()
.host(notary_host)
.port(notary_port)
// WARNING: Always use TLS to connect to notary server, except if notary is running locally
// e.g. this example, hence `enable_tls` is set to False (else it always defaults to True).
.enable_tls(false)
.build()
.unwrap();

// Send requests for configuration and notarization to the notary server.
let notarization_request = NotarizationRequest::builder()
// We must configure the amount of data we expect to exchange beforehand, which will
// be preprocessed prior to the connection. Reducing these limits will improve
// performance.
.max_sent_data(MAX_SENT_DATA)
.max_recv_data(MAX_RECV_DATA)
.build()?;

// Start a local simple notary service
tokio::spawn(run_notary(notary_socket.compat()));
let Accepted {
io: notary_connection,
id: _session_id,
..
} = notary_client
.request_notarization(notarization_request)
.await
.expect("Could not connect to notary. Make sure it is running.");

// Set up protocol configuration for prover.
// Prover configuration.
let config = ProverConfig::builder()
let prover_config = ProverConfig::builder()
.server_name(SERVER_DOMAIN)
.protocol_config(
ProtocolConfig::builder()
// We must configure the amount of data we expect to exchange beforehand, which will
// be preprocessed prior to the connection. Reducing these limits will improve
// performance.
.max_sent_data(1024)
.max_recv_data(4096)
.max_sent_data(MAX_SENT_DATA)
.max_recv_data(MAX_RECV_DATA)
.build()?,
)
.crypto_provider(tlsn_examples::get_crypto_provider_with_server_fixture())
.build()?;

// Create a new prover and perform necessary setup.
let prover = Prover::new(config).setup(prover_socket.compat()).await?;
let prover = Prover::new(prover_config)
.setup(notary_connection.compat())
.await?;

// Open a TCP connection to the server.
let client_socket = tokio::net::TcpStream::connect(("localhost", 4000)).await?;
let client_socket = tokio::net::TcpStream::connect((server_host, server_port)).await?;

// Bind the prover to the server connection.
// The returned `mpc_tls_connection` is an MPC TLS connection to the server: all
Expand All @@ -66,13 +115,15 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {

// Build a simple HTTP request with common headers
let request = Request::builder()
// .uri("/protected")
.uri("/formats/html")
.header("Host", SERVER_DOMAIN)
.header("Accept", "*/*")
// Using "identity" instructs the Server not to use compression for its HTTP response.
// TLSNotary tooling does not support compression.
.header("Accept-Encoding", "identity")
.header("Connection", "close")
.header("Authorization", auth_token)
.header("User-Agent", USER_AGENT)
.body(Empty::<Bytes>::new())?;

Expand All @@ -85,6 +136,13 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {

assert!(response.status() == StatusCode::OK);

// Pretty printing :)
let payload = response.into_body().collect().await.unwrap().to_bytes();
// let parsed =
// serde_json::from_str::<serde_json::Value>(&String::from_utf8_lossy(&payload))?;
let parsed = String::from_utf8_lossy(&payload);
debug!("{}", serde_json::to_string_pretty(&parsed).unwrap());

// The prover task should be done now, so we can await it.
let prover = prover_task.await??;

Expand All @@ -97,14 +155,18 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Commit to the transcript.
let mut builder = TranscriptCommitConfig::builder(prover.transcript());

//FIXME: JSON?
// DefaultJsonCommitter::default().commit_value(&mut builder, value, direction);
DefaultHttpCommitter::default().commit_transcript(&mut builder, &transcript)?;

prover.transcript_commit(builder.build()?);

// Request an attestation.
let config = RequestConfig::default();
let request_config = RequestConfig::default();

let (attestation, secrets) = prover.finalize(&request_config).await?;

let (attestation, secrets) = prover.finalize(&config).await?;
println!("Notarization complete!");

// Write the attestation to disk.
tokio::fs::write(
Expand Down
2 changes: 2 additions & 0 deletions crates/server-fixture/server/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ use hyper::header;

use tlsn_server_fixture_certs::*;

pub const DEFAULT_FIXTURE_PORT: u16 = 3000;

struct AppState {
shutdown: Option<oneshot::Sender<()>>,
}
Expand Down
4 changes: 2 additions & 2 deletions crates/server-fixture/server/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use std::{env, io};

use tlsn_server_fixture::bind;
use tlsn_server_fixture::{bind, DEFAULT_FIXTURE_PORT};
use tokio::net::TcpListener;
use tokio_util::compat::TokioAsyncWriteCompatExt;

#[tokio::main]
async fn main() -> io::Result<()> {
let port = env::var("PORT").unwrap_or_else(|_| "3000".to_string());
let port = env::var("PORT").unwrap_or_else(|_| DEFAULT_FIXTURE_PORT.to_string());
let listener = TcpListener::bind(&format!("0.0.0.0:{port}")).await?;

loop {
Expand Down

0 comments on commit ef43cba

Please sign in to comment.