reorganized

This commit is contained in:
Hendrik Eeckhaut
2023-10-31 14:18:58 +01:00
parent c007965e51
commit 09ac04c9d0
27 changed files with 812 additions and 3333 deletions

1
.gitignore vendored
View File

@@ -1 +1,2 @@
/target
Cargo.lock

3287
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,45 +1,3 @@
[package]
name = "progcrypto_workshop"
version = "0.1.0"
edition = "2021"
[workspace]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
# Simple Notary server
tlsn-core = { git = "https://github.com/tlsnotary/tlsn", branch = "dev" }
tlsn-verifier = { git = "https://github.com/tlsnotary/tlsn", branch = "dev" }
p256 = { version = "0.13", features = ["ecdsa"] }
tokio = { version = "1.33.0", features = [
"rt",
"rt-multi-thread",
"macros",
"net",
"io-std",
"fs",
] }
tokio-util = { version = "0.7.9", features = ["compat"] }
tracing-subscriber = "0.3.17"
# Prover
tlsn-prover = { git = "https://github.com/tlsnotary/tlsn", branch = "dev" }
hyper = { version = "0.14", features = ["client", "http1"] }
serde_json = "1.0.107"
futures = "0.3.28"
# Verifier
elliptic-curve = { version = "0.13.5", features = ["pkcs8"] }
chrono = "0.4.31"
[[example]]
name = "simple_prover"
path = "src/simple_prover.rs"
[[example]]
name = "simple_verifier"
path = "src/simple_verifier.rs"
[[example]]
name = "simple_notary"
path = "src/simple_notary.rs"
members = ["simple", "discord", "notary"]

34
discord/Cargo.toml Normal file
View File

@@ -0,0 +1,34 @@
[package]
name = "progcrypto_workshop_discord"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
tlsn-core = { git = "https://github.com/tlsnotary/tlsn", branch = "dev" }
tlsn-verifier = { git = "https://github.com/tlsnotary/tlsn", branch = "dev" }
p256 = { version = "0.13", features = ["ecdsa"] }
tokio = { version = "1.33.0", features = [
"rt",
"rt-multi-thread",
"macros",
"net",
"io-std",
"fs",
] }
tokio-util = { version = "0.7.9", features = ["compat"] }
tracing-subscriber = "0.3.17"
tlsn-prover = { git = "https://github.com/tlsnotary/tlsn", branch = "dev" }
hyper = { version = "0.14", features = ["client", "http1"] }
serde_json = "1.0.107"
futures = "0.3.28"
elliptic-curve = { version = "0.13.5", features = ["pkcs8"] }
chrono = "0.4.31"
serde = { version = "1.0.147", features = ["derive"] }
dotenv = "0.15.0"
rustls = { version = "0.21" }
tokio-rustls = { version = "0.24.1" }
tracing = "0.1.40"
rustls-pemfile = { version = "1.0.2" }

106
discord/README.md Normal file
View File

@@ -0,0 +1,106 @@
# Notarize Discord DMs
The `discord_dm.rs` example sets up a TLS connection with Discord and notarizes the requested DMs. The notarized session is written to a local JSON file (`discord_dm_notarized_session.json`) for easier inspection.
This involves 3 steps:
1. Configure the inputs
2. Start the (local) notary server
3. Notarize
P/S: The notary server used in this example is more functional compared to its [simple version](../simple/simple_notary.rs). The simple version is easier to integrate with from prover perspective, whereas this notary server provides additional features like TLS connection with prover, WebSocket endpoint, API endpoints for further customisation etc.
## Inputs
In this tlsn/examples/discord 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 |
| ------------- | -------------------------------------------------------------------------------- | --------------------------------------------- |
| USER_AGENT | `Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/116.0` | Look for `User-Agent` in a request headers |
| AUTHORIZATION | `MTE1NDe1Otg4N6NxNjczOTM2OA.GYbUBf.aDtcMUKDOmg6C2kxxFtlFSN1pgdMMBtpHgBBEs` | Look for `Authorization` in a request headers |
| CHANNEL_ID | `1154750485639745567` | URL |
You can obtain these parameters by opening [Discord](https://discord.com/channels/@me) 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 `/api` to filter results to Discord API requests. From there you can copy the needed information into your `.env` as indicated above.
You can find the `CHANNEL_ID` directly in the url:
`https://discord.com/channels/@me/{CHANNEL_ID)`
## Start the notary server
At the root level of this repository, run
```sh
cd 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/discord folder, run the following command:
```sh
RUST_LOG=debug,yamux=info cargo run --release --example discord_dm
```
If everything goes well, you should see output similar to the following:
```log
..
2023-09-22T14:40:51.416047Z DEBUG discord_dm: [
{
"attachments": [],
"author": {
"accent_color": null,
"avatar": "dd07631c9613240aa969d6e7916eb7ae",
"avatar_decoration_data": null,
"banner": null,
"banner_color": null,
"discriminator": "0",
"flags": 0,
"global_name": "sinu",
"id": "662709891017867273",
"public_flags": 0,
"username": "sinu_"
},
"channel_id": "1154750485639745567",
"components": [],
"content": "Hello ETHGlobal NY!!",
"edited_timestamp": null,
"embeds": [],
"flags": 0,
"id": "1154750835784429678",
"mention_everyone": false,
"mention_roles": [],
"mentions": [],
"pinned": false,
"timestamp": "2023-09-22T12:07:33.484000+00:00",
"tts": false,
"type": 0
},
..
]
2023-09-22T14:40:51.847455Z DEBUG discord_dm: Notarization complete!
```
If the transcript was too long, you may encounter the following error. This occurs because there is a default limit of notarization size to 16kB:
```
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
```
# Verifier
The `discord_dm` example also generated a proof of the transcript with the `Authorization` header redacted from the request, saved in `discord_dm_proof.json`.
We can verify this proof using the `discord_dm_verifier` by running:
```
cargo run --release --example discord_dm_verifier
```
This will verify the proof and print out the redacted transcript!

View File

@@ -0,0 +1,339 @@
/// This example shows how to notarize Discord DMs.
///
/// The example uses the notary server implemented in ../../../notary-server
use futures::AsyncWriteExt;
use hyper::{body::to_bytes, client::conn::Parts, Body, Request, StatusCode};
use rustls::{Certificate, ClientConfig, RootCertStore};
use serde::{Deserialize, Serialize};
use std::{env, ops::Range, str, sync::Arc};
use tlsn_core::proof::TlsProof;
use tokio::{io::AsyncWriteExt as _, net::TcpStream};
use tokio_rustls::TlsConnector;
use tokio_util::compat::{FuturesAsyncReadCompatExt, TokioAsyncReadCompatExt};
use tracing::debug;
use tlsn_prover::tls::{Prover, ProverConfig};
// Setting of the application server
const SERVER_DOMAIN: &str = "discord.com";
// Setting of the notary server — make sure these are the same with those in ../../../notary-server
const NOTARY_HOST: &str = "127.0.0.1";
const NOTARY_PORT: u16 = 7047;
// Configuration of notarization
const NOTARY_MAX_TRANSCRIPT_SIZE: usize = 16384;
/// Response object of the /session API
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct NotarizationSessionResponse {
pub session_id: String,
}
/// Request object of the /session API
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct NotarizationSessionRequest {
pub client_type: ClientType,
/// Maximum transcript size in bytes
pub max_transcript_size: Option<usize>,
}
/// Types of client that the prover is using
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum ClientType {
/// Client that has access to the transport layer
Tcp,
/// Client that cannot directly access transport layer, e.g. browser extension
Websocket,
}
#[tokio::main]
async fn main() {
tracing_subscriber::fmt::init();
// Load secret variables frome environment for discord server connection
dotenv::dotenv().ok();
let channel_id = env::var("CHANNEL_ID").unwrap();
let auth_token = env::var("AUTHORIZATION").unwrap();
let user_agent = env::var("USER_AGENT").unwrap();
let (notary_tls_socket, session_id) = setup_notary_connection().await;
// Basic default prover config using the session_id returned from /session endpoint just now
let config = ProverConfig::builder()
.id(session_id)
.server_dns(SERVER_DOMAIN)
.build()
.unwrap();
// Create a new prover and set up the MPC backend.
let prover = Prover::new(config)
.setup(notary_tls_socket.compat())
.await
.unwrap();
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();
// 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::handshake(tls_connection.compat())
.await
.unwrap();
// Spawn the HTTP task to be run concurrently
let connection_task = tokio::spawn(connection.without_shutdown());
// Build the HTTP request to fetch the DMs
let request = Request::builder()
.uri(format!(
"https://{SERVER_DOMAIN}/api/v9/channels/{channel_id}/messages?limit=2"
))
.header("Host", SERVER_DOMAIN)
.header("Accept", "*/*")
.header("Accept-Language", "en-US,en;q=0.5")
.header("Accept-Encoding", "identity")
.header("User-Agent", user_agent)
.header("Authorization", &auth_token)
.header("Connection", "close")
.body(Body::empty())
.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 = to_bytes(response.into_body()).await.unwrap().to_vec();
let parsed =
serde_json::from_str::<serde_json::Value>(&String::from_utf8_lossy(&payload)).unwrap();
debug!("{}", serde_json::to_string_pretty(&parsed).unwrap());
// Close the connection to the server
let mut client_socket = connection_task.await.unwrap().unwrap().io.into_inner();
client_socket.close().await.unwrap();
// The Prover task should be done now, so we can grab it.
let prover = prover_task.await.unwrap().unwrap();
// Prepare for notarization
let mut prover = prover.start_notarize();
// Identify the ranges in the transcript that contain secrets
let (public_ranges, private_ranges) =
find_ranges(prover.sent_transcript().data(), &[auth_token.as_bytes()]);
let recv_len = prover.recv_transcript().data().len();
let builder = prover.commitment_builder();
// Collect commitment ids for the outbound transcript
let mut commitment_ids = public_ranges
.iter()
.chain(private_ranges.iter())
.map(|range| builder.commit_sent(range.clone()).unwrap())
.collect::<Vec<_>>();
// Commit to the full received transcript in one shot, as we don't need to redact anything
commitment_ids.push(builder.commit_recv(0..recv_len).unwrap());
// Finalize, returning the notarized 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("discord_dm_notarized_session.json")
.await
.unwrap();
file.write_all(
serde_json::to_string_pretty(&notarized_session)
.unwrap()
.as_bytes(),
)
.await
.unwrap();
let session_proof = notarized_session.session_proof();
let mut proof_builder = notarized_session.data().build_substrings_proof();
// Reveal everything but the auth token (which was assigned commitment id 2)
proof_builder.reveal(commitment_ids[0]).unwrap();
proof_builder.reveal(commitment_ids[1]).unwrap();
proof_builder.reveal(commitment_ids[3]).unwrap();
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("discord_dm_proof.json")
.await
.unwrap();
file.write_all(serde_json::to_string_pretty(&proof).unwrap().as_bytes())
.await
.unwrap();
}
async fn setup_notary_connection() -> (tokio_rustls::client::TlsStream<TcpStream>, String) {
// Connect to the Notary via TLS-TCP
let pem_file =
str::from_utf8(include_bytes!("../../../notary/fixture/notary/rootCA.crt")).unwrap();
let mut reader = std::io::BufReader::new(pem_file.as_bytes());
let mut certificates: Vec<Certificate> = rustls_pemfile::certs(&mut reader)
.unwrap()
.into_iter()
.map(Certificate)
.collect();
let certificate = certificates.remove(0);
let mut root_store = RootCertStore::empty();
root_store.add(&certificate).unwrap();
let client_notary_config = ClientConfig::builder()
.with_safe_defaults()
.with_root_certificates(root_store)
.with_no_client_auth();
let notary_connector = TlsConnector::from(Arc::new(client_notary_config));
let notary_socket = tokio::net::TcpStream::connect((NOTARY_HOST, NOTARY_PORT))
.await
.unwrap();
let notary_tls_socket = notary_connector
// Require the domain name of notary server to be the same as that in the server cert
.connect("tlsnotaryserver.io".try_into().unwrap(), notary_socket)
.await
.unwrap();
// Attach the hyper HTTP client to the notary TLS connection to send request to the /session endpoint to configure notarization and obtain session id
let (mut request_sender, connection) = hyper::client::conn::handshake(notary_tls_socket)
.await
.unwrap();
// Spawn the HTTP task to be run concurrently
let connection_task = tokio::spawn(connection.without_shutdown());
// Build the HTTP request to configure notarization
let payload = serde_json::to_string(&NotarizationSessionRequest {
client_type: ClientType::Tcp,
max_transcript_size: Some(NOTARY_MAX_TRANSCRIPT_SIZE),
})
.unwrap();
let request = Request::builder()
.uri(format!("https://{NOTARY_HOST}:{NOTARY_PORT}/session"))
.method("POST")
.header("Host", NOTARY_HOST)
// Need to specify application/json for axum to parse it as json
.header("Content-Type", "application/json")
.body(Body::from(payload))
.unwrap();
debug!("Sending configuration request");
let configuration_response = request_sender.send_request(request).await.unwrap();
debug!("Sent configuration request");
assert!(configuration_response.status() == StatusCode::OK);
debug!("Response OK");
// Pretty printing :)
let payload = to_bytes(configuration_response.into_body())
.await
.unwrap()
.to_vec();
let notarization_response =
serde_json::from_str::<NotarizationSessionResponse>(&String::from_utf8_lossy(&payload))
.unwrap();
debug!("Notarization response: {:?}", notarization_response,);
// Send notarization request via HTTP, where the underlying TCP connection will be extracted later
let request = Request::builder()
// Need to specify the session_id so that notary server knows the right configuration to use
// as the configuration is set in the previous HTTP call
.uri(format!(
"https://{}:{}/notarize?sessionId={}",
NOTARY_HOST,
NOTARY_PORT,
notarization_response.session_id.clone()
))
.method("GET")
.header("Host", NOTARY_HOST)
.header("Connection", "Upgrade")
// Need to specify this upgrade header for server to extract tcp connection later
.header("Upgrade", "TCP")
.body(Body::empty())
.unwrap();
debug!("Sending notarization request");
let response = request_sender.send_request(request).await.unwrap();
debug!("Sent notarization request");
assert!(response.status() == StatusCode::SWITCHING_PROTOCOLS);
debug!("Switched protocol OK");
// Claim back the TLS socket after HTTP exchange is done
let Parts {
io: notary_tls_socket,
..
} = connection_task.await.unwrap().unwrap();
(notary_tls_socket, notarization_response.session_id)
}
/// Find the ranges of the public and private parts of a sequence.
///
/// Returns a tuple of `(public, private)` ranges.
fn find_ranges(seq: &[u8], sub_seq: &[&[u8]]) -> (Vec<Range<usize>>, Vec<Range<usize>>) {
let mut private_ranges = Vec::new();
for s in sub_seq {
for (idx, w) in seq.windows(s.len()).enumerate() {
if w == *s {
private_ranges.push(idx..(idx + w.len()));
}
}
}
let mut sorted_ranges = private_ranges.clone();
sorted_ranges.sort_by_key(|r| r.start);
let mut public_ranges = Vec::new();
let mut last_end = 0;
for r in sorted_ranges {
if r.start > last_end {
public_ranges.push(last_end..r.start);
}
last_end = r.end;
}
if last_end < seq.len() {
public_ranges.push(last_end..seq.len());
}
(public_ranges, private_ranges)
}

View File

@@ -0,0 +1,73 @@
use std::time::Duration;
use elliptic_curve::pkcs8::DecodePublicKey;
use tlsn_core::proof::{SessionProof, TlsProof};
/// A simple verifier which reads a proof generated by `discord_dm.rs` from "discord_dm_proof.json", verifies
/// it and prints the verified data to the console.
fn main() {
// Deserialize the proof
let proof = std::fs::read_to_string("discord_dm_proof.json").unwrap();
let proof: TlsProof = serde_json::from_str(proof.as_str()).unwrap();
let TlsProof {
// The session proof establishes the identity of the server and the commitments
// to the TLS transcript.
session,
// The substrings proof proves select portions of the transcript, while redacting
// anything the Prover chose not to disclose.
substrings,
} = proof;
// Verify the session proof against the Notary's public key
//
// This verifies the identity of the server using a default certificate verifier which trusts
// the root certificates from the `webpki-roots` crate.
session
.verify_with_default_cert_verifier(notary_pubkey())
.unwrap();
let SessionProof {
// The session header that was signed by the Notary is a succinct commitment to the TLS transcript.
header,
// This is the server name, checked against the certificate chain shared in the TLS handshake.
server_name,
..
} = session;
// The time at which the session was recorded
let time = chrono::DateTime::UNIX_EPOCH + Duration::from_secs(header.time());
// Verify the substrings proof against the session header.
//
// This returns the redacted transcripts
let (mut sent, mut recv) = substrings.verify(&header).unwrap();
// Replace the bytes which the Prover chose not to disclose with 'X'
sent.set_redacted(b'X');
recv.set_redacted(b'X');
println!("-------------------------------------------------------------------");
println!(
"Successfully verified that the bytes below came from a session with {:?} at {}.",
server_name, time
);
println!("Note that the bytes which the Prover chose not to disclose are shown as X.");
println!();
println!("Bytes sent:");
println!();
print!("{}", String::from_utf8(sent.data().to_vec()).unwrap());
println!();
println!("Bytes received:");
println!();
println!("{}", String::from_utf8(recv.data().to_vec()).unwrap());
println!("-------------------------------------------------------------------");
}
/// Returns a Notary pubkey trusted by this Verifier
fn notary_pubkey() -> p256::PublicKey {
let pem_file_path = "../notary/notary.pub";
p256::PublicKey::read_public_key_pem_file(pem_file_path).unwrap()
}

38
notary/Cargo.toml Normal file
View File

@@ -0,0 +1,38 @@
[package]
name = "progcrypto_workshop_notary"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
tlsn-core = { git = "https://github.com/tlsnotary/tlsn", branch = "dev" }
tlsn-verifier = { git = "https://github.com/tlsnotary/tlsn", branch = "dev" }
notary-server = { git = "https://github.com/tlsnotary/tlsn", branch = "dev" }
p256 = { version = "0.13", features = ["ecdsa"] }
tokio = { version = "1.33.0", features = [
"rt",
"rt-multi-thread",
"macros",
"net",
"io-std",
"fs",
] }
tokio-util = { version = "0.7.9", features = ["compat"] }
tracing-subscriber = "0.3.17"
tlsn-prover = { git = "https://github.com/tlsnotary/tlsn", branch = "dev" }
hyper = { version = "0.14", features = ["client", "http1"] }
serde_json = "1.0.107"
futures = "0.3.28"
elliptic-curve = { version = "0.13.5", features = ["pkcs8"] }
chrono = "0.4.31"
serde = { version = "1.0.147", features = ["derive"] }
dotenv = "0.15.0"
rustls = { version = "0.21" }
tokio-rustls = { version = "0.24.1" }
tracing = "0.1.40"
rustls-pemfile = { version = "1.0.2" }
eyre = "0.6.8"
structopt = "0.3.26"

17
notary/config/config.yaml Normal file
View File

@@ -0,0 +1,17 @@
server:
name: "notary-server"
host: "0.0.0.0"
port: 7047
notarization:
max-transcript-size: 16384
tls-signature:
private-key-pem-path: "./fixture/tls/notary.key"
certificate-pem-path: "./fixture/tls/notary.crt"
notary-signature:
private-key-pem-path: "./fixture/notary/notary.key"
tracing:
default-level: DEBUG

View File

@@ -0,0 +1,17 @@
-----BEGIN CERTIFICATE-----
MIICzDCCAbQCCQDDGiT0U3jAszANBgkqhkiG9w0BAQsFADAoMRIwEAYDVQQKDAl0
bHNub3RhcnkxEjAQBgNVBAMMCXRsc25vdGFyeTAeFw0yMzA2MjYxMTE2MTZaFw0y
ODA2MjQxMTE2MTZaMCgxEjAQBgNVBAoMCXRsc25vdGFyeTESMBAGA1UEAwwJdGxz
bm90YXJ5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7Vf+O9l4WNXE
Xh48MwjnvZ9wGN/Ls+jzzF1Q+J/QfXAYR/REQgJQmuk6sBgJyXUW7Dr5dKAY5tfL
rjfSaLhdMSxBH/tMepf5HVfEo6jvgk1bdR43DIZw7Z0hfuGUo6qOue8LZry2Nl+9
VZpG64quRZ///4LdMBQyXcS2yeWKU10yVNBvstKW0i8krqQfbWOIG1nu5nDg5onB
paKUvbyrLyuHLz8gzKDFezxADTugq2KRXYKIZmyRucK+kmnJnZ/k46GZ84Vju15v
ktC0CvaR9IfvLfJMAo1Y0lUR4HjQkEAfjnDFYj5B18KFxXABraVD8UxjeMbAHTjf
i1lV0yp+qQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQABxRni6FZIFeK0KCS1Nrks
ONLVPfvDSNEKpImWFFoJbaSAAankTiQM1nKTY9SRIhqG2t+xJ6c8+qe905lFFvOy
r85LMb3z2ZWs4ez6Uy6IdpSdkTULk+1huE/Y9ZqRJ5aQy7PqiHTe+mNDFmHXGdcS
azHywd4hQeRQhCBXlAG7I18uZR9DPtGaJnvZlfbpD6Iq7x3ocfGhQiV9VJS1JaQ3
Z7CJs2pa4da5FXQMAbKI2f7V5kbn3bjMp57yeYFo5wJMhEeSFqkrojR0oZDzfxW9
b0W/PI4R4d2hUvX0fwrQyXbGo8HvYDFUhlMMSF60gUNcbpF6P93tXxR2FM/hnu+T
-----END CERTIFICATE-----

View File

@@ -0,0 +1,20 @@
-----BEGIN CERTIFICATE-----
MIIDTzCCAjegAwIBAgIJALo+PtyTmxELMA0GCSqGSIb3DQEBCwUAMCgxEjAQBgNV
BAoMCXRsc25vdGFyeTESMBAGA1UEAwwJdGxzbm90YXJ5MB4XDTIzMDYyNjE2MTI1
N1oXDTI0MDYyNTE2MTI1N1owNDEYMBYGA1UECgwPdGxzbm90YXJ5c2VydmVyMRgw
FgYDVQQDDA90bHNub3RhcnlzZXJ2ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
ggEKAoIBAQCqo+rOvL/l3ehVLrOBpzQrjWClV03rl+xiDIElEcVSz017gvoHX0ti
+etBHX+plJOhVRQrO+a3QeYv7NqDnQKIMozsStClkK4MagU1114JO+z4eArfQFDv
Czq2VYwDYBmLj4Lz0y54oQLyy/O8ON/ganYaW/3quGhufo+d774m8qCjSvhdTBnL
h1GxiZKfM8PFaRmBCMGa4mViTlpmnZq7eDzLumlh8WeOTFIWmbjNL4DkMJKu/gHK
5uOCtIUkFPezIN88Pq6wC88jRihXM7hrJUofPZZKzkDpwydGxol9fS0kiMANG6L8
CUIeQhMDElCV/XiAXHi4MtH93XWjTR3VAgMBAAGjcDBuMEIGA1UdIwQ7MDmhLKQq
MCgxEjAQBgNVBAoMCXRsc25vdGFyeTESMBAGA1UEAwwJdGxzbm90YXJ5ggkAwxok
9FN4wLMwCQYDVR0TBAIwADAdBgNVHREEFjAUghJ0bHNub3RhcnlzZXJ2ZXIuaW8w
DQYJKoZIhvcNAQELBQADggEBAByvWsHE5qZYAJT1io1mwVQdXkDnlVjT/GAdu/Mx
EoUPJ9Pt/1XiS1dWXJMIZFbfOiZJBnX+sKxPpy/flaI4kbnXJY8nB5gFPkLWI7ok
V+r2iqEapsX3zrLx7x3AAM2kJbTieMLaGWe9g40wkGzmnpFJf5W8SgI2JEc4KlDo
joQJtsJa85PeOGtMsKLXnqUofDHbvDR0ab9obkh4Ngw+D1CGVXEGduCx1+SwB1jO
eDysCo+8ikyrrlzyDR1OyFJW28WVzLRJH0Z2bwldekM1RvCXqBYeLtAgNtS3Xb1w
RVP9VAx7KlmNF6kG52R2dQ1Z7J7i8JIZEkBcKjITEmpKrfE=
-----END CERTIFICATE-----

View File

@@ -0,0 +1,16 @@
-----BEGIN CERTIFICATE REQUEST-----
MIICeTCCAWECAQAwNDEYMBYGA1UECgwPdGxzbm90YXJ5c2VydmVyMRgwFgYDVQQD
DA90bHNub3RhcnlzZXJ2ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
AQCqo+rOvL/l3ehVLrOBpzQrjWClV03rl+xiDIElEcVSz017gvoHX0ti+etBHX+p
lJOhVRQrO+a3QeYv7NqDnQKIMozsStClkK4MagU1114JO+z4eArfQFDvCzq2VYwD
YBmLj4Lz0y54oQLyy/O8ON/ganYaW/3quGhufo+d774m8qCjSvhdTBnLh1GxiZKf
M8PFaRmBCMGa4mViTlpmnZq7eDzLumlh8WeOTFIWmbjNL4DkMJKu/gHK5uOCtIUk
FPezIN88Pq6wC88jRihXM7hrJUofPZZKzkDpwydGxol9fS0kiMANG6L8CUIeQhMD
ElCV/XiAXHi4MtH93XWjTR3VAgMBAAGgADANBgkqhkiG9w0BAQsFAAOCAQEAqkWE
FyI9r3cY3tXt6j0/xGYZCX3X1AGje7vcEUeYzlED32putmH96Fkia+X2CMpEwcn7
jaojJWvtAKGAk46p/cRpbPEOhLLebXn4znaeBVF5ph283WmeExRlhQml0e7kwTs9
MwSniEFKBtvq4cSqO7BM1+NXDpjauVpaACl2+E9KTE8LcGG0BvH2eJOM/yW6wZmG
ykgyMeSg5UV/i5STWlryeaGBLCCmXx4jVfkBgaXw2Zq4ve1F/qU/eQFNUPk/iRSh
aQEQIfEC0hwqEe2Nc7X6PoVd7Py/x7Bke1JP9mRI7EPoN/IT0XHanJ08tusDCcYG
omGrHBGk9mELh39TXQ==
-----END CERTIFICATE REQUEST-----

View File

@@ -0,0 +1,5 @@
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
subjectAltName = @alt_names
[alt_names]
DNS.1 = tlsnotaryserver.io

View File

@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCqo+rOvL/l3ehV
LrOBpzQrjWClV03rl+xiDIElEcVSz017gvoHX0ti+etBHX+plJOhVRQrO+a3QeYv
7NqDnQKIMozsStClkK4MagU1114JO+z4eArfQFDvCzq2VYwDYBmLj4Lz0y54oQLy
y/O8ON/ganYaW/3quGhufo+d774m8qCjSvhdTBnLh1GxiZKfM8PFaRmBCMGa4mVi
TlpmnZq7eDzLumlh8WeOTFIWmbjNL4DkMJKu/gHK5uOCtIUkFPezIN88Pq6wC88j
RihXM7hrJUofPZZKzkDpwydGxol9fS0kiMANG6L8CUIeQhMDElCV/XiAXHi4MtH9
3XWjTR3VAgMBAAECggEBAIYDgk+nMVbIdsUfjl8PAAwMVpDEBjA2+rDufSat1Dj7
EjEkZlUP5FbxTG+xSSfXxjH4bYSe4M2f9bZB4ENpNinc+YxCHadJ/0dEpJ7qa7H4
3F0veepnyqhSO2Qjv3iPKsDOjtwLSP34BibFQsDaMgk/001UXhDPj0ToJMa3GLHg
pw1G2ri4WO4NxQA354y61jBNy0D4mjHHlcnofi4iLOFr2Kf538f0RgUyw8EkZ2sE
QyqL5HpHE93qIuLzl3/NxjQNHfO99dNNl6oWzPmXGi0nPGCMith3+8dMH7QiR/sS
r2bjdusIccV3tlZqCJUdWDC/RVgVQKDV3pWBx+i/1gECgYEA19UrQAwgxaimcs7E
NXISBzm2XgOOg9e5/W5EJvObu9zflqB3CBvrdZhhl1ZR+hTAbP5rHZQHWkMMAFbD
dT+VYIqTWUCIDkFpcB7vNa41A5eIbSdz1W+V4ZdAOUuwFcaG2xQA/F37S5DvH12V
JZ4ktJQklYUKmlUXSDTDgRUiApUCgYEAymWqTJjlSi1ADa3bAENaSKGaTazoeWBF
OesnwTLYCT+Aap+3aMjnG5+gxlSbdfJ1odrahXA3VSZwUL0IvCg8HcJsvwc0Bw3/
LUpwCk2yLlq+OsOtpQSgsOVOzKzXJTEnjHBZxyInJsuTb+Kf5qn7/zvGQSNvbePT
h+YMAwGpHkECgYEAmg3DkzGU6sCYHfZLwkIrcBDXhH9RZ/XBAY2FA7B6Bjt/NApR
K+6RwBwF/HlWhgPt3V4zoqcYIGse09caKEQ8IO6Igfo3osU5txe9cjloCapNbGvu
l/fPqXfGFZ9ajhBoDVNX6MpEJgnLRD4NyQ358RKUkkyl5sa5mYZfzXECF4kCgYA+
PcmDSLmqeAPssPxaNlw7XccQAA511Q804oYVOceKAIdDQt6qUK4RpqNQmpA8U1Wt
cpok0v+RJgMAMUHQaychl7rNfC+Zw8onaW7PHFmhO7Koa6ioyKWKANqcwsJe46Df
5WUWggA8Q/qRO8Ykrz2Zng431efciWVxs2MaQZZ6gQKBgA+QdsMadsrWoqh3tCZA
uruQ7hXCfALJfgexWFAtLIwlHujXI81+YVICCutCe6riktPZ/zTz/nbEAyt7kIiz
6BF7UYGT29qu1rC0MLzjfwK9ExuMSkvy9ZXGM0bCEgANIkZ0A/zTtTeRaFFGbx6l
F1Y+ihMVuZ4rOGQbVUfQxz1F
-----END PRIVATE KEY-----

View File

@@ -0,0 +1,17 @@
-----BEGIN CERTIFICATE-----
MIICzDCCAbQCCQDDGiT0U3jAszANBgkqhkiG9w0BAQsFADAoMRIwEAYDVQQKDAl0
bHNub3RhcnkxEjAQBgNVBAMMCXRsc25vdGFyeTAeFw0yMzA2MjYxMTE2MTZaFw0y
ODA2MjQxMTE2MTZaMCgxEjAQBgNVBAoMCXRsc25vdGFyeTESMBAGA1UEAwwJdGxz
bm90YXJ5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7Vf+O9l4WNXE
Xh48MwjnvZ9wGN/Ls+jzzF1Q+J/QfXAYR/REQgJQmuk6sBgJyXUW7Dr5dKAY5tfL
rjfSaLhdMSxBH/tMepf5HVfEo6jvgk1bdR43DIZw7Z0hfuGUo6qOue8LZry2Nl+9
VZpG64quRZ///4LdMBQyXcS2yeWKU10yVNBvstKW0i8krqQfbWOIG1nu5nDg5onB
paKUvbyrLyuHLz8gzKDFezxADTugq2KRXYKIZmyRucK+kmnJnZ/k46GZ84Vju15v
ktC0CvaR9IfvLfJMAo1Y0lUR4HjQkEAfjnDFYj5B18KFxXABraVD8UxjeMbAHTjf
i1lV0yp+qQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQABxRni6FZIFeK0KCS1Nrks
ONLVPfvDSNEKpImWFFoJbaSAAankTiQM1nKTY9SRIhqG2t+xJ6c8+qe905lFFvOy
r85LMb3z2ZWs4ez6Uy6IdpSdkTULk+1huE/Y9ZqRJ5aQy7PqiHTe+mNDFmHXGdcS
azHywd4hQeRQhCBXlAG7I18uZR9DPtGaJnvZlfbpD6Iq7x3ocfGhQiV9VJS1JaQ3
Z7CJs2pa4da5FXQMAbKI2f7V5kbn3bjMp57yeYFo5wJMhEeSFqkrojR0oZDzfxW9
b0W/PI4R4d2hUvX0fwrQyXbGo8HvYDFUhlMMSF60gUNcbpF6P93tXxR2FM/hnu+T
-----END CERTIFICATE-----

View File

@@ -0,0 +1,30 @@
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIFHzBJBgkqhkiG9w0BBQ0wPDAbBgkqhkiG9w0BBQwwDgQIODItYjQ2oGICAggA
MB0GCWCGSAFlAwQBKgQQOVlpTszSmqOQ13RqJ0k9vQSCBNDOS9KT7QzKhXaSquKQ
vNylu9+hwkO2+SyVqkf82kHNezEr45r6DuxW0tQJhd93v6DMqGKS9LvFf0qshM2t
OhMD52PVvwHA4Fg4xMQORvvmHOHw7sxzrsQAWIjZ2cPpCRX2zcHYC5zwIaICBBdl
1qzUiO7n0nw77GRBUFoX0eSJPTkH42Nbc/nB+oa5t+n8mxY89Hqdh2wO5k569vkW
7ZC3FphzjPXIWk885qpZ7/O9eeR1OEhBf07PYqzar8RPDU02/lrUZ6Y+QMh69W/y
zNl7CGjy0IuDao77IFsu7rk6cBFq3uTXSyoyDoLmpkLbJEnS+ydjRyfbOjHJfG10
Ca82mBA51IFs2Werf4+hzyM1EsvlGaGz2vhUffMK2lvJjoWocCi//E2XGQb+7hdY
HOP8sEWuDRqHGtZlMpIxp1JJs5jm+7RGCtgtO/tTb5hCdCB8msqNmCugzjUtg9ZJ
z3BygoRaBVgjBPKtDNo6NHf0Hfq1NzwImed3kTJAgNqkTxpCWYxvuJOWFROvps2t
jGkpGN0S17Ee9JAdsmsz3Mr92OXi9ncig3YTCI+WwN06xjjyIVPvtGDhvP30dPft
A6B1TgeS8g3yEFPkXjDqpKYsiZm38iN+GIcncgU1ng8r1gUnDzwZHwDFPAq/PwYC
sB4CA097eEaFLz49ttcO5ZXl7/pxMYKsBsUJQIG5MQcnyUBugQB2hVT+8WPjAjQE
ocScxHfMQAofMXn+Nwv+J5WlswZjoaXdqa/GG2AKHMPbrlMBdPDADMe0KGWxSKvt
HIbvhd/i+mXS2bwNDzHRCk3GEgdgEzOBrUbxzzJiN5EhRLqxuI2VnMUu5JcjxO/k
X2X6Ekpuc0D3PKezCGC98JbtwfVb5A1vBmVaD7ZMXSLCdBU+27qq96txsKP+WRzL
kcnp3EMfTscIgJOApslwkncGar6lsgfzBVD0bQy3luPEvEfhY+UOisApYsJEkuXy
HEbALLAvSibf1+1YCq00KTd7ERboCJ4N4e5ONE8wJBLoRMvRvxbi4zZsW4sApSjP
3r2P5FuB5x2VGlYo3BFd5yzAYzPQl+dFc7wg8yDohKNOVa9XAuNgDhXG+RS7imNL
PP3BIMFuj8+uH0rLRtse+pVhXKQ9pqvgvTpvGAKzqHjFHmH9GDKTnntL3B7kjRa4
n/0DKT99iHEekvBAEN2qjIuYq0/xiSKSkVeGVksPUtZ/8V2SKdBRXnuDNlItaICW
bgZH/qCisNKx53jSv25yfoq0+rJtxLDNVuPFdKcQa97SsiUqElnxH/gwqSDLViYn
B3XsX+RKZJVNm1rqaoYf7yRFpddld4BgqUYQEj3rAyIelMGuTPSaiJxMysENnJl6
MPdfug0NoUYJC+xle4YBeMjLj2qout7kq08414ZOEF4MdR6y1oqcM1IW14nSPAdG
O40Kma3V+aTJDIOY3cbS13f9yFY0n7KrD7dZ7faXDRT81LEhEVo9RZ01PBvES6lx
amL1CxQmVrhUD3YbeKvc17tvfOa67YU+6g0ELKFoWf2/5OJyj6wchACU98JyYonr
RGKSaL2zSDiFPTUKYscsFDMZuRtXs98okwoIbK8TujHTWZnI5DrBj2XLiVwPRYiu
dkFsSOjDwjmd11CglKpiBh5a7A==
-----END ENCRYPTED PRIVATE KEY-----

View File

@@ -0,0 +1 @@
BA3E3EDC939B110B

25
notary/src/main.rs Normal file
View File

@@ -0,0 +1,25 @@
use eyre::{eyre, Result};
use structopt::StructOpt;
use tracing::debug;
use notary_server::{
init_tracing, parse_config_file, run_server, CliFields, NotaryServerError,
NotaryServerProperties,
};
#[tokio::main]
async fn main() -> Result<(), NotaryServerError> {
// Load command line arguments which contains the config file location
let cli_fields: CliFields = CliFields::from_args();
let config: NotaryServerProperties = parse_config_file(&cli_fields.config_file)?;
// Set up tracing for logging
init_tracing(&config).map_err(|err| eyre!("Failed to set up tracing: {err}"))?;
debug!(?config, "Server config loaded");
// Run the server
run_server(&config).await?;
Ok(())
}

33
simple/Cargo.toml Normal file
View File

@@ -0,0 +1,33 @@
[package]
name = "progcrypto_workshop_simple"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
# Simple Notary server
tlsn-core = { git = "https://github.com/tlsnotary/tlsn", branch = "dev" }
tlsn-verifier = { git = "https://github.com/tlsnotary/tlsn", branch = "dev" }
p256 = { version = "0.13", features = ["ecdsa"] }
tokio = { version = "1.33.0", features = [
"rt",
"rt-multi-thread",
"macros",
"net",
"io-std",
"fs",
] }
tokio-util = { version = "0.7.9", features = ["compat"] }
tracing-subscriber = "0.3.17"
# Prover
tlsn-prover = { git = "https://github.com/tlsnotary/tlsn", branch = "dev" }
hyper = { version = "0.14", features = ["client", "http1"] }
serde_json = "1.0.107"
futures = "0.3.28"
# Verifier
elliptic-curve = { version = "0.13.5", features = ["pkcs8"] }
chrono = "0.4.31"

View File

@@ -27,7 +27,8 @@ async fn main() {
println!("Listening on: {}", addr);
// Load the notary signing key
let signing_key_str = str::from_utf8(include_bytes!("./notary/notary.key")).unwrap();
let signing_key_str =
str::from_utf8(include_bytes!("../../../notary/fixture/notary/notary.key")).unwrap();
let signing_key = p256::ecdsa::SigningKey::from_pkcs8_pem(signing_key_str).unwrap();
loop {

View File

@@ -69,6 +69,7 @@ fn main() {
/// Returns a Notary pubkey trusted by this Verifier
fn notary_pubkey() -> p256::PublicKey {
let pem_file = str::from_utf8(include_bytes!("./notary/notary.pub")).unwrap();
let pem_file =
str::from_utf8(include_bytes!("../../../notary/fixture/notary/notary.pub")).unwrap();
p256::PublicKey::from_public_key_pem(pem_file).unwrap()
}

4
start_notary.sh Normal file
View File

@@ -0,0 +1,4 @@
#!/bin/sh
cd notary
cargo run --release
cd ..

2
start_simple_notary.sh Normal file
View File

@@ -0,0 +1,2 @@
#!/bin/sh
cargo run --bin simple_notary --release

BIN
tlsn-banner.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB