tlsn_verifier/
notarize.rs

1//! This module handles the notarization phase of the verifier.
2//!
3//! The TLS verifier acts as a Notary, i.e. the verifier produces an
4//! attestation but does not verify transcript data.
5
6use super::{state::Notarize, Verifier, VerifierError};
7use rand::Rng;
8use serio::{stream::IoStreamExt, SinkExt as _};
9
10use tlsn_common::encoding;
11use tlsn_core::{
12    attestation::{Attestation, AttestationConfig},
13    request::Request,
14    transcript::encoding::EncoderSecret,
15};
16use tracing::{info, instrument};
17
18impl Verifier<Notarize> {
19    /// Notarizes the TLS session.
20    ///
21    /// # Arguments
22    ///
23    /// * `config` - The attestation configuration.
24    #[instrument(parent = &self.span, level = "debug", skip_all, err)]
25    pub async fn finalize(self, config: &AttestationConfig) -> Result<Attestation, VerifierError> {
26        let Notarize {
27            mux_ctrl,
28            mut mux_fut,
29            delta,
30            mut ctx,
31            vm,
32            server_ephemeral_key,
33            connection_info,
34            transcript_refs,
35            ..
36        } = self.state;
37
38        let encoder_secret = EncoderSecret::new(rand::rng().random(), delta.as_block().to_bytes());
39
40        let attestation = mux_fut
41            .poll_with(async {
42                let sent_keys = transcript_refs
43                    .sent()
44                    .iter()
45                    .flat_map(|plaintext| vm.get_keys(*plaintext).expect("reference is valid"))
46                    .map(|key| key.as_block());
47                let recv_keys = transcript_refs
48                    .recv()
49                    .iter()
50                    .flat_map(|plaintext| vm.get_keys(*plaintext).expect("reference is valid"))
51                    .map(|key| key.as_block());
52
53                // Convert encodings into a structured format.
54                encoding::transfer(&mut ctx, &encoder_secret, sent_keys, recv_keys).await?;
55
56                // Receive attestation request, which also contains commitments required before
57                // finalization.
58                let request: Request = ctx.io_mut().expect_next().await?;
59
60                let mut builder = Attestation::builder(config)
61                    .accept_request(request)
62                    .map_err(VerifierError::attestation)?;
63
64                builder
65                    .connection_info(connection_info)
66                    .server_ephemeral_key(server_ephemeral_key)
67                    .encoder_secret(encoder_secret);
68
69                let attestation = builder
70                    .build(self.config.crypto_provider())
71                    .map_err(VerifierError::attestation)?;
72
73                ctx.io_mut().send(attestation.clone()).await?;
74
75                info!("Sent attestation");
76
77                Ok::<_, VerifierError>(attestation)
78            })
79            .await?;
80
81        if !mux_fut.is_complete() {
82            mux_ctrl.close();
83            mux_fut.await?;
84        }
85
86        Ok(attestation)
87    }
88}