mirror of
https://github.com/tlsnotary/tlsn.git
synced 2026-01-09 14:48:13 -05:00
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:
@@ -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 {
|
||||
|
||||
@@ -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"
|
||||
@@ -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();
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
CONVERSATION_ID="20124652-973145016511139841"
|
||||
AUTH_TOKEN="670ccccccbe2bbbbbbbc1025aaaaaafa55555551"
|
||||
ACCESS_TOKEN="AAAAAAAAAAAAAAAAAAAAANRILgAA...4puTs%3D1Zv7...WjCpTnA"
|
||||
CSRF_TOKEN="77d8ef46bd57f722ea7e9f...f4235a713040bfcaac1cd6909"
|
||||
@@ -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.
|
||||
|
||||

|
||||
|
||||
## 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)
|
||||
@@ -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 = ¬arized_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 = ¬arized_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 |
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user