chore(examples): remove examples, fix bug (#585)

* chore(examples): remove examples, fix bug

* Restored Discord example

---------

Co-authored-by: Hendrik Eeckhaut <hendrik@eeckhaut.org>
This commit is contained in:
sinu.eth
2024-09-12 11:42:44 -07:00
committed by GitHub
parent 9bbb2fb66c
commit 67dc7c865d
10 changed files with 17 additions and 345 deletions

View File

@@ -51,12 +51,6 @@ impl ProtocolConfigBuilder {
}
}
impl Default for ProtocolConfig {
fn default() -> Self {
Self::builder().build().unwrap()
}
}
impl ProtocolConfig {
/// Creates a new builder for `ProtocolConfig`.
pub fn builder() -> ProtocolConfigBuilder {

View File

@@ -34,16 +34,16 @@ tracing = { workspace = true }
tracing-subscriber = { workspace = true }
[[example]]
name = "simple_prover"
path = "simple/simple_prover.rs"
name = "attestation_prover"
path = "attestation/prover.rs"
[[example]]
name = "simple_verifier"
path = "simple/simple_verifier.rs"
name = "attestation_verifier"
path = "attestation/verifier.rs"
[[example]]
name = "twitter_dm"
path = "twitter/twitter_dm.rs"
name = "interactive"
path = "interactive/interactive.rs"
[[example]]
name = "discord_dm"
@@ -51,8 +51,4 @@ path = "discord/discord_dm.rs"
[[example]]
name = "discord_dm_verifier"
path = "discord/discord_dm_verifier.rs"
[[example]]
name = "interactive"
path = "interactive/interactive.rs"
path = "discord/discord_dm_verifier.rs"

View File

@@ -5,6 +5,7 @@ use http_body_util::Empty;
use hyper::{body::Bytes, Request, StatusCode};
use hyper_util::rt::TokioIo;
use std::ops::Range;
use tlsn_common::config::ProtocolConfig;
use tlsn_core::proof::TlsProof;
use tokio::io::AsyncWriteExt as _;
use tokio_util::compat::{FuturesAsyncReadCompatExt, TokioAsyncReadCompatExt};
@@ -27,10 +28,18 @@ async fn main() {
// Start a local simple notary service
tokio::spawn(run_notary(notary_socket.compat()));
// A Prover configuration
// Prover configuration.
let config = ProverConfig::builder()
.id("example")
.server_dns(SERVER_DOMAIN)
.protocol_config(
ProtocolConfig::builder()
// Configure the limit of the data sent and received.
.max_sent_data(1024)
.max_recv_data(4096)
.build()
.unwrap(),
)
.build()
.unwrap();

View File

@@ -1,4 +0,0 @@
CONVERSATION_ID="20124652-973145016511139841"
AUTH_TOKEN="670ccccccbe2bbbbbbbc1025aaaaaafa55555551"
ACCESS_TOKEN="AAAAAAAAAAAAAAAAAAAAANRILgAA...4puTs%3D1Zv7...WjCpTnA"
CSRF_TOKEN="77d8ef46bd57f722ea7e9f...f4235a713040bfcaac1cd6909"

View File

@@ -1,102 +0,0 @@
# Notarize Twitter DMs
The `twtter_dm.rs` example sets up a TLS connection with Twitter and notarizes the requested DMs. The full received transcript is notarized in one commitment, so nothing is redacted. The resulting proof is written to a local JSON file (`twitter_dm_proof.json`) for easier inspection.
This involves 3 steps:
1. Configure the inputs
2. Start the (local) notary server
3. Notarize
## Inputs
In this tlsn/examples/twitter folder, create a `.env` file.
Then in that `.env` file, set the values of the following constants by following the format shown in this [example env file](./.env.example).
| Name | Example | Location in Request Headers Section (within Network Tab of Developer Tools) |
| --------------- | ------------------------------------------------------- | -------------------------------------------------------------------------------- |
| CONVERSATION_ID | `20124652-973145016511139841` | Look for `Referer`, then extract the `ID` in `https://twitter.com/messages/<ID>` |
| AUTH_TOKEN | `670ccccccbe2bbbbbbbc1025aaaaaafa55555551` | Look for `Cookie`, then extract the `token` in `;auth_token=<token>;` |
| ACCESS_TOKEN | `AAAAAAAAAAAAAAAAAAAAANRILgAA...4puTs%3D1Zv7...WjCpTnA` | Look for `Authorization`, then extract the `token` in `Bearer <token>` |
| CSRF_TOKEN | `77d8ef46bd57f722ea7e9f...f4235a713040bfcaac1cd6909` | Look for `X-Csrf-Token`, then copy the entire value |
You can obtain these parameters by opening [Twitter](https://twitter.com/messages/) in your browser and accessing the message history you want to notarize. Please note that notarizing only works for short transcripts at the moment, so choose a contact with a short history.
Next, open the **Developer Tools**, go to the **Network** tab, and refresh the page. Then, click on **Search** and type `uuid` as shown in the screenshot below — all of these constants should be under the **Request Headers** section. Refer to the table above on where to find each of the constant value.
![Screenshot](twitter_dm_browser.png)
## Start the notary server
1. Edit the notary server [config file](../../notary/server/config/config.yaml) to turn off TLS so that self-signed certificates can be avoided (⚠️ this is only for local development purposes — TLS must be used in production).
```yaml
tls:
enabled: false
...
```
2. Run the following at the root level of this repository to start the notary server:
```shell
cd crates/notary/server
cargo run --release
```
The notary server will now be running in the background waiting for connections.
For more information on how to configure the notary server, please refer to [this](../../notary/server/README.md#running-the-server).
## Notarize
In this tlsn/examples/twitter folder, run the following command:
```sh
RUST_LOG=DEBUG,uid_mux=INFO,yamux=INFO cargo run --release --example twitter_dm
```
If everything goes well, you should see output similar to the following:
```log
2024-06-26T08:45:15.435493Z DEBUG notary_client::client: Setting up tcp connection...
2024-06-26T08:45:15.436451Z DEBUG notary_client::client: Sending configuration request: Request { method: POST, uri: http://127.0.0.1:7047/session, version: HTTP/1.1, headers: {"host": "127.0.0.1", "content-type": "application/json"}, body: Left(Full { data: Some(b"{\"clientType\":\"Tcp\",\"maxSentData\":4096,\"maxRecvData\":16384}") }) }
2024-06-26T08:45:15.442448Z DEBUG notary_client::client: Sent configuration request
2024-06-26T08:45:15.442525Z DEBUG notary_client::client: Configuration response: NotarizationSessionResponse { session_id: "60fdaee7-fb36-420f-96e7-bfeb8732623c" }
2024-06-26T08:45:15.442532Z DEBUG notary_client::client: Sending notarization request: Request { method: GET, uri: http://127.0.0.1:7047/notarize?sessionId=60fdaee7-fb36-420f-96e7-bfeb8732623c, version: HTTP/1.1, headers: {"host": "127.0.0.1", "connection": "Upgrade", "upgrade": "TCP"}, body: Right(Empty) }
2024-06-26T08:45:15.442883Z DEBUG notary_client::client: Sent notarization request
2024-06-26T08:45:18.569677Z DEBUG setup:setup_mpc_backend: tlsn_prover::tls: MPC backend setup complete
2024-06-26T08:45:18.596747Z DEBUG twitter_dm: Sending request
2024-06-26T08:45:18.607345Z DEBUG connect:tls_connection: tls_client::client::hs: ALPN protocol is None
2024-06-26T08:45:18.607360Z DEBUG connect:tls_connection: tls_client::client::hs: Using ciphersuite Tls12(Tls12CipherSuite { suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, algorithm: AES_128_GCM })
2024-06-26T08:45:18.607528Z DEBUG connect:tls_connection: tls_client::client::tls12: ECDHE curve is ECParameters { curve_type: NamedCurve, named_group: secp256r1 }
2024-06-26T08:45:18.607539Z DEBUG connect:tls_connection: tls_client::client::tls12: Server DNS name is DnsName(DnsName(DnsName("twitter.com")))
2024-06-26T08:45:18.607838Z DEBUG connect:handle:client_key: key_exchange::exchange: received public key share from follower
2024-06-26T08:45:19.740173Z DEBUG connect:tls_connection: tls_client_async: handshake complete
2024-06-26T08:45:20.442786Z DEBUG connect:tls_connection: tls_client_async: server closed connection
2024-06-26T08:45:20.442852Z DEBUG connect:commit: tls_mpc::leader: committing to transcript
2024-06-26T08:45:23.770382Z DEBUG twitter_dm: Sent request
2024-06-26T08:45:23.770400Z DEBUG twitter_dm: Request OK
2024-06-26T08:45:23.770382Z DEBUG connect:tls_connection: tls_client_async: client shutdown
2024-06-26T08:45:23.770469Z DEBUG twitter_dm: {
"conversation_timeline": {
"entries": [
{
"message": {
...
}
},
...
],
...
}
2024-06-26T08:45:23.770497Z DEBUG connect:close_connection: tls_mpc::leader: closing connection
2024-06-26T08:45:23.770687Z DEBUG connect: tls_mpc::leader: leader actor stopped
2024-06-26T08:45:23.780574Z DEBUG finalize: tlsn_prover::tls::notarize: starting finalization
2024-06-26T08:45:23.788046Z DEBUG finalize: tlsn_prover::tls::notarize: received OT secret
2024-06-26T08:45:26.334296Z INFO finalize:poll{role=Client}:client_handle_inbound: uid_mux::yamux: remote closed connection
2024-06-26T08:45:26.334316Z INFO finalize:poll{role=Client}: uid_mux::yamux: connection complete
2024-06-26T08:45:26.334612Z DEBUG twitter_dm: Notarization complete!
```
If the transcript was too long, you may encounter the following error:
```
thread 'tokio-runtime-worker' panicked at 'called `Result::unwrap()` on an `Err` value: IOError(Custom { kind: InvalidData, error: BackendError(DecryptionError("Other: KOSReceiverActor is not setup")) })', /Users/heeckhau/tlsnotary/tlsn/tlsn/tlsn-prover/src/lib.rs:173:50
```
> **_NOTE:_** <https://explorer.tlsnotary.org/> hosts a generic proof visualizer. Drag and drop your proof into the drop zone to check and render your proof. [Notary public key](../../notary/server/fixture/notary/notary.pub)

View File

@@ -1,220 +0,0 @@
// This example shows how to notarize Twitter DMs.
//
// The example uses the notary server implemented in ../../notary/server
use http_body_util::{BodyExt, Empty};
use hyper::{body::Bytes, Request, StatusCode};
use hyper_util::rt::TokioIo;
use notary_client::{Accepted, NotarizationRequest, NotaryClient};
use std::{env, str};
use tlsn_common::config::ProtocolConfig;
use tlsn_core::{commitment::CommitmentKind, proof::TlsProof};
use tlsn_prover::tls::{Prover, ProverConfig};
use tokio::io::AsyncWriteExt as _;
use tokio_util::compat::{FuturesAsyncReadCompatExt, TokioAsyncReadCompatExt};
use tracing::debug;
// Setting of the application server
const SERVER_DOMAIN: &str = "twitter.com";
const ROUTE: &str = "i/api/1.1/dm/conversation";
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";
// Setting of the notary server — make sure these are the same with the config in ../../notary/server
const NOTARY_HOST: &str = "127.0.0.1";
const NOTARY_PORT: u16 = 7047;
// 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() {
tracing_subscriber::fmt::init();
// Load secret variables from environment for twitter server connection
dotenv::dotenv().ok();
let conversation_id = env::var("CONVERSATION_ID").unwrap();
let auth_token = env::var("AUTH_TOKEN").unwrap();
let access_token = env::var("ACCESS_TOKEN").unwrap();
let csrf_token = env::var("CSRF_TOKEN").unwrap();
// 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()
.max_sent_data(MAX_SENT_DATA)
.max_recv_data(MAX_RECV_DATA)
.build()
.unwrap();
let Accepted {
io: notary_connection,
id: session_id,
..
} = notary_client
.request_notarization(notarization_request)
.await
.unwrap();
// Configure a new prover with the unique session id returned from notary client.
let prover_config = ProverConfig::builder()
.id(session_id)
.server_dns(SERVER_DOMAIN)
.protocol_config(
ProtocolConfig::builder()
.max_sent_data(MAX_SENT_DATA)
.max_recv_data(MAX_RECV_DATA)
.build()
.unwrap(),
)
.build()
.unwrap();
// Create a new prover and set up the MPC backend.
let prover = Prover::new(prover_config)
.setup(notary_connection.compat())
.await
.unwrap();
// Open a new socket to the application server.
let client_socket = tokio::net::TcpStream::connect((SERVER_DOMAIN, 443))
.await
.unwrap();
// Bind the Prover to server connection
let (tls_connection, prover_fut) = prover.connect(client_socket.compat()).await.unwrap();
let tls_connection = TokioIo::new(tls_connection.compat());
// Spawn the Prover to be run concurrently
let prover_task = tokio::spawn(prover_fut);
// Attach the hyper HTTP client to the TLS connection
let (mut request_sender, connection) = hyper::client::conn::http1::handshake(tls_connection)
.await
.unwrap();
// Spawn the HTTP task to be run concurrently
tokio::spawn(connection);
// Build the HTTP request to fetch the DMs
let request = Request::builder()
.uri(format!(
"https://{SERVER_DOMAIN}/{ROUTE}/{conversation_id}.json"
))
.header("Host", SERVER_DOMAIN)
.header("Accept", "*/*")
.header("Accept-Encoding", "identity")
.header("Connection", "close")
.header("User-Agent", USER_AGENT)
.header("Authorization", format!("Bearer {access_token}"))
.header(
"Cookie",
format!("auth_token={auth_token}; ct0={csrf_token}"),
)
.header("Authority", SERVER_DOMAIN)
.header("X-Twitter-Auth-Type", "OAuth2Session")
.header("x-twitter-active-user", "yes")
.header("X-Csrf-Token", csrf_token.clone())
.body(Empty::<Bytes>::new())
.unwrap();
debug!("Sending request");
let response = request_sender.send_request(request).await.unwrap();
debug!("Sent request");
assert!(response.status() == StatusCode::OK, "{}", response.status());
debug!("Request 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)).unwrap();
debug!("{}", serde_json::to_string_pretty(&parsed).unwrap());
// The Prover task should be done now, so we can grab it.
let prover = prover_task.await.unwrap().unwrap();
// Upgrade the prover to an HTTP prover, and start notarization.
let mut prover = prover.to_http().unwrap().start_notarize();
// Commit to the transcript with the default committer, which will commit using BLAKE3.
prover.commit().unwrap();
// Finalize, returning the notarized HTTP session
let notarized_session = prover.finalize().await.unwrap();
debug!("Notarization complete!");
// Dump the notarized session to a file
let mut file = tokio::fs::File::create("twitter_dm.json").await.unwrap();
file.write_all(
serde_json::to_string_pretty(notarized_session.session())
.unwrap()
.as_bytes(),
)
.await
.unwrap();
let session_proof = notarized_session.session_proof();
let mut proof_builder = notarized_session.session().data().build_substrings_proof();
// Prove the request, while redacting the secrets from it.
let request = &notarized_session.transcript().requests[0];
proof_builder
.reveal_sent(&request.without_data(), CommitmentKind::Blake3)
.unwrap();
proof_builder
.reveal_sent(&request.request.target, CommitmentKind::Blake3)
.unwrap();
for header in &request.headers {
// Only reveal the host header
if header.name.as_str().eq_ignore_ascii_case("Host") {
proof_builder
.reveal_sent(header, CommitmentKind::Blake3)
.unwrap();
} else {
proof_builder
.reveal_sent(&header.without_value(), CommitmentKind::Blake3)
.unwrap();
}
}
// Prove the entire response, as we don't need to redact anything
let response = &notarized_session.transcript().responses[0];
proof_builder
.reveal_recv(response, CommitmentKind::Blake3)
.unwrap();
// Build the proof
let substrings_proof = proof_builder.build().unwrap();
let proof = TlsProof {
session: session_proof,
substrings: substrings_proof,
};
// Dump the proof to a file.
let mut file = tokio::fs::File::create("twitter_dm_proof.json")
.await
.unwrap();
file.write_all(serde_json::to_string_pretty(&proof).unwrap().as_bytes())
.await
.unwrap();
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 596 KiB

View File

@@ -16,7 +16,6 @@ pub struct ProverConfig {
#[builder(setter(strip_option), default = "default_root_store()")]
pub(crate) root_cert_store: RootCertStore,
/// Protocol configuration to be checked with the verifier.
#[builder(default)]
protocol_config: ProtocolConfig,
/// Whether the `deferred decryption` feature is toggled on from the start of the MPC-TLS
/// connection.