From 35787b32389b444ec6332aa2f53d15911ee29432 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 21 Apr 2025 09:33:39 +0200 Subject: [PATCH 1/2] fix: validate encoder secret --- crates/core/src/attestation.rs | 12 ++++++- crates/prover/src/notarize.rs | 66 ++++++++++++++++++++++++++++++++-- 2 files changed, 74 insertions(+), 4 deletions(-) diff --git a/crates/core/src/attestation.rs b/crates/core/src/attestation.rs index 2fb128edc..dcef601a0 100644 --- a/crates/core/src/attestation.rs +++ b/crates/core/src/attestation.rs @@ -47,7 +47,10 @@ use crate::{ merkle::MerkleTree, presentation::PresentationBuilder, signing::{Signature, VerifyingKey}, - transcript::{encoding::EncodingCommitment, hash::PlaintextHash}, + transcript::{ + encoding::{EncoderSecret, EncodingCommitment}, + hash::PlaintextHash, + }, CryptoProvider, }; @@ -167,6 +170,13 @@ impl Body { &self.verifying_key.data } + /// Returns the encoder secret. + pub fn encoder_secret(&self) -> Option<&EncoderSecret> { + self.encoding_commitment + .as_ref() + .map(|field| &field.data.secret) + } + /// Computes the Merkle root of the attestation fields. /// /// This is only used when building an attestation. diff --git a/crates/prover/src/notarize.rs b/crates/prover/src/notarize.rs index da03ccb3e..857ad2ee2 100644 --- a/crates/prover/src/notarize.rs +++ b/crates/prover/src/notarize.rs @@ -8,8 +8,12 @@ use serio::{stream::IoStreamExt as _, SinkExt as _}; use tlsn_common::encoding; use tlsn_core::{ attestation::Attestation, + connection::TranscriptLength, request::{Request, RequestConfig}, - transcript::{encoding::EncodingTree, Transcript, TranscriptCommitConfig}, + transcript::{ + encoding::{new_encoder, Encoder, EncoderSecret, EncodingProvider, EncodingTree}, + Direction, Idx, Transcript, TranscriptCommitConfig, + }, Secrets, }; use tracing::{debug, instrument}; @@ -71,9 +75,9 @@ impl Prover { builder .server_name(self.config.server_name().clone()) .server_cert_data(server_cert_data) - .transcript(transcript); + .transcript(transcript.clone()); - if let Some(config) = transcript_commit_config { + if let Some(ref config) = transcript_commit_config { if config.has_encoding() { builder.encoding_tree( EncodingTree::new( @@ -112,6 +116,62 @@ impl Prover { .validate(&attestation) .map_err(ProverError::attestation)?; + if let Some(config) = transcript_commit_config { + if config.has_encoding() { + validate_encoder_secret( + attestation + .body + .encoder_secret() + .expect("attestation contains encoder secret"), + &transcript, + &encoding_provider, + )?; + } + } + Ok((attestation, secrets)) } } + +// Validates that the encoder `secret` is consistent with the encoding +// `provider` for the given `transcript`. +fn validate_encoder_secret( + secret: &EncoderSecret, + transcript: &Transcript, + provider: &impl EncodingProvider, +) -> Result<(), ProverError> { + let encoder = new_encoder(secret); + let TranscriptLength { sent, received } = transcript.length(); + let sent_idx = Idx::new(0..sent as usize); + let recv_idx = Idx::new(0..received as usize); + + // The transcript encoding produced by the `encoder` and the `provider` + // must match. + if provider + .provide_encoding(Direction::Sent, &sent_idx) + .expect("index is valid") + != encoder.encode_subsequence( + Direction::Sent, + &transcript + .get(Direction::Sent, &sent_idx) + .expect("index is valid"), + ) + { + return Err(ProverError::attestation("Incosistent encoder secret")); + } + + if provider + .provide_encoding(Direction::Received, &recv_idx) + .expect("index is valid") + != encoder.encode_subsequence( + Direction::Received, + &transcript + .get(Direction::Received, &recv_idx) + .expect("index is valid"), + ) + { + return Err(ProverError::attestation("Incosistent encoder secret")); + } + + Ok(()) +} From 51cf43baa8867167a37cf1a17a38cf6312136fad Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 21 Apr 2025 09:42:34 +0200 Subject: [PATCH 2/2] forbid encoding commitment when not requested --- crates/core/src/request.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/crates/core/src/request.rs b/crates/core/src/request.rs index 09b9449c2..2299a2a82 100644 --- a/crates/core/src/request.rs +++ b/crates/core/src/request.rs @@ -78,6 +78,10 @@ impl Request { "encoding commitment root does not match".to_string(), )); } + } else if attestation.body.encoding_commitment().is_some() { + return Err(InconsistentAttestation( + "encoding commitment is present even though it was not requested".to_string(), + )); } // TODO: improve the O(M*N) complexity of this check.