-
Notifications
You must be signed in to change notification settings - Fork 69
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
317 additions
and
336 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
// Ignore files from examples. | ||
*.tlsn |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
// This example demonstrates how to build a verifiable presentation from an | ||
// attestation and the corresponding connection secrets. See the `prove.rs` | ||
// example to learn how to acquire an attestation from a Notary. | ||
|
||
use tlsn_core::{attestation::Attestation, presentation::Presentation, CryptoProvider, Secrets}; | ||
use tlsn_formats::http::HttpTranscript; | ||
|
||
fn main() -> Result<(), Box<dyn std::error::Error>> { | ||
// Read attestation from disk. | ||
let attestation: Attestation = | ||
bincode::deserialize(&std::fs::read("example.attestation.tlsn")?)?; | ||
|
||
// Read secrets from disk. | ||
let secrets: Secrets = bincode::deserialize(&std::fs::read("example.secrets.tlsn")?)?; | ||
|
||
// Parse the HTTP transcript. | ||
let transcript = HttpTranscript::parse(secrets.transcript())?; | ||
|
||
// Build a transcript proof. | ||
let mut builder = secrets.transcript_proof_builder(); | ||
|
||
let request = &transcript.requests[0]; | ||
// Reveal the structure of the request without the headers or body. | ||
builder.reveal_sent(&request.without_data())?; | ||
// Reveal the request target. | ||
builder.reveal_sent(&request.request.target)?; | ||
// Reveal all headers except the value of the User-Agent header. | ||
for header in &request.headers { | ||
if !header.name.as_str().eq_ignore_ascii_case("User-Agent") { | ||
builder.reveal_sent(header)?; | ||
} else { | ||
builder.reveal_sent(&header.without_value())?; | ||
} | ||
} | ||
// Reveal the entire response. | ||
builder.reveal_recv(&transcript.responses[0])?; | ||
|
||
let transcript_proof = builder.build()?; | ||
|
||
// Use default crypto provider to build the presentation. | ||
let provider = CryptoProvider::default(); | ||
|
||
let mut builder = attestation.presentation_builder(&provider); | ||
|
||
builder | ||
.identity_proof(secrets.identity_proof()) | ||
.transcript_proof(transcript_proof); | ||
|
||
let presentation: Presentation = builder.build()?; | ||
|
||
// Write the presentation to disk. | ||
std::fs::write( | ||
"example.presentation.tlsn", | ||
bincode::serialize(&presentation)?, | ||
)?; | ||
|
||
println!("Presentation built successfully!"); | ||
println!("The presentation has been written to `example.presentation.tlsn`."); | ||
|
||
Ok(()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
// This example demonstrates how to use the Prover to acquire an attestation for | ||
// an HTTP request sent to example.com. The attestation and secrets are saved to | ||
// disk. | ||
|
||
use http_body_util::Empty; | ||
use hyper::{body::Bytes, Request, StatusCode}; | ||
use hyper_util::rt::TokioIo; | ||
use tokio::io::AsyncWriteExt as _; | ||
use tokio_util::compat::{FuturesAsyncReadCompatExt, TokioAsyncReadCompatExt}; | ||
|
||
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_prover::{Prover, ProverConfig}; | ||
|
||
// Setting of the application server | ||
const SERVER_DOMAIN: &str = "example.com"; | ||
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"; | ||
|
||
#[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); | ||
|
||
// Start a local simple notary service | ||
tokio::spawn(run_notary(notary_socket.compat())); | ||
|
||
// Prover configuration. | ||
let 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) | ||
.build()?, | ||
) | ||
.build()?; | ||
|
||
// Create a new prover and perform necessary setup. | ||
let prover = Prover::new(config).setup(prover_socket.compat()).await?; | ||
|
||
// Open a TCP connection to the server. | ||
let client_socket = tokio::net::TcpStream::connect((SERVER_DOMAIN, 443)).await?; | ||
|
||
// Bind the prover to the server connection. | ||
// The returned `mpc_tls_connection` is an MPC TLS connection to the server: all | ||
// data written to/read from it will be encrypted/decrypted using MPC with | ||
// the notary. | ||
let (mpc_tls_connection, prover_fut) = prover.connect(client_socket.compat()).await?; | ||
let mpc_tls_connection = TokioIo::new(mpc_tls_connection.compat()); | ||
|
||
// Spawn the prover task to be run concurrently in the background. | ||
let prover_task = tokio::spawn(prover_fut); | ||
|
||
// Attach the hyper HTTP client to the connection. | ||
let (mut request_sender, connection) = | ||
hyper::client::conn::http1::handshake(mpc_tls_connection).await?; | ||
|
||
// Spawn the HTTP task to be run concurrently in the background. | ||
tokio::spawn(connection); | ||
|
||
// Build a simple HTTP request with common headers | ||
let request = Request::builder() | ||
.uri("/") | ||
.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("User-Agent", USER_AGENT) | ||
.body(Empty::<Bytes>::new())?; | ||
|
||
println!("Starting an MPC TLS connection with the server"); | ||
|
||
// Send the request to the server and wait for the response. | ||
let response = request_sender.send_request(request).await?; | ||
|
||
println!("Got a response from the server"); | ||
|
||
assert!(response.status() == StatusCode::OK); | ||
|
||
// The prover task should be done now, so we can await it. | ||
let prover = prover_task.await??; | ||
|
||
// Prepare for notarization. | ||
let mut prover = prover.start_notarize(); | ||
|
||
// Parse the HTTP transcript. | ||
let transcript = HttpTranscript::parse(prover.transcript())?; | ||
|
||
// Commit to the transcript. | ||
let mut builder = TranscriptCommitConfig::builder(prover.transcript()); | ||
|
||
DefaultHttpCommitter::default().commit_transcript(&mut builder, &transcript)?; | ||
|
||
prover.transcript_commit(builder.build()?); | ||
|
||
// Request an attestation. | ||
let config = RequestConfig::default(); | ||
|
||
let (attestation, secrets) = prover.finalize(&config).await?; | ||
|
||
// Write the attestation to disk. | ||
let mut file = tokio::fs::File::create("example.attestation.tlsn").await?; | ||
file.write_all(&bincode::serialize(&attestation)?).await?; | ||
|
||
// Write the secrets to disk. | ||
let mut file = tokio::fs::File::create("example.secrets.tlsn") | ||
.await | ||
.unwrap(); | ||
file.write_all(&bincode::serialize(&secrets)?).await?; | ||
|
||
println!("Notarization completed successfully!"); | ||
println!( | ||
"The attestation has been written to `example.attestation.tlsn` and the \ | ||
corresponding secrets to `example.secrets.tlsn`." | ||
); | ||
|
||
Ok(()) | ||
} |
Oops, something went wrong.