tlsn_verifier/
verify.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
//! This module handles the verification phase of the verifier.
//!
//! The TLS verifier is an application-specific verifier.

use crate::SessionInfo;

use super::{state::Verify as VerifyState, Verifier, VerifierError};
use mpz_circuits::types::Value;
use mpz_garble::{Memory, Verify};
use mpz_ot::CommittedOTSender;
use serio::stream::IoStreamExt;
use tlsn_common::msg::ServerIdentityProof;
use tlsn_core::transcript::{get_value_ids, Direction, PartialTranscript};

use tracing::{info, instrument};

impl Verifier<VerifyState> {
    /// Receives the **purported** transcript from the Prover.
    ///
    /// # Warning
    ///
    /// The content of the received transcript can not be considered authentic
    /// until after finalization.
    #[instrument(parent = &self.span, level = "info", skip_all, err)]
    pub async fn receive(&mut self) -> Result<PartialTranscript, VerifierError> {
        self.state
            .mux_fut
            .poll_with(async {
                // Receive partial transcript from the prover.
                let partial_transcript: PartialTranscript = self.state.io.expect_next().await?;

                info!("Received partial transcript from prover");

                // Check ranges.
                if partial_transcript.len_sent()
                    != self.state.connection_info.transcript_length.sent as usize
                    || partial_transcript.len_received()
                        != self.state.connection_info.transcript_length.received as usize
                {
                    return Err(VerifierError::verify(
                        "prover sent transcript with incorrect length",
                    ));
                }

                // Now verify the transcript parts which the prover wants to reveal.
                let sent_value_ids =
                    get_value_ids(Direction::Sent, partial_transcript.sent_authed());
                let recv_value_ids =
                    get_value_ids(Direction::Received, partial_transcript.received_authed());

                let value_refs = sent_value_ids
                    .chain(recv_value_ids)
                    .map(|id| {
                        self.state
                            .vm
                            .get_value(id.as_str())
                            .expect("Byte should be in VM memory")
                    })
                    .collect::<Vec<_>>();

                let values = partial_transcript
                    .iter(Direction::Sent)
                    .chain(partial_transcript.iter(Direction::Received))
                    .map(Value::U8)
                    .collect::<Vec<_>>();

                // Check that purported values are correct.
                self.state.vm.verify(&value_refs, &values).await?;

                info!("Successfully verified purported transcript");

                Ok::<_, VerifierError>(partial_transcript)
            })
            .await
    }

    /// Verifies the TLS session.
    #[instrument(parent = &self.span, level = "info", skip_all, err)]
    pub async fn finalize(self) -> Result<SessionInfo, VerifierError> {
        let VerifyState {
            mut io,
            mux_ctrl,
            mut mux_fut,
            mut vm,
            mut ot_send,
            mut ctx,
            server_ephemeral_key,
            connection_info,
            ..
        } = self.state;

        let ServerIdentityProof {
            name: server_name,
            data,
        } = mux_fut
            .poll_with(async {
                // Finalize all MPC
                ot_send.reveal(&mut ctx).await?;

                vm.finalize().await?;

                info!("Finalized all MPC");

                let identity_proof: ServerIdentityProof = io.expect_next().await?;

                Ok::<_, VerifierError>(identity_proof)
            })
            .await?;

        // Verify the server identity data.
        data.verify_with_provider(
            self.config.crypto_provider(),
            connection_info.time,
            &server_ephemeral_key,
            &server_name,
        )
        .map_err(VerifierError::verify)?;

        info!("Successfully verified session");

        if !mux_fut.is_complete() {
            mux_ctrl.mux().close();
            mux_fut.await?;
        }

        Ok(SessionInfo {
            server_name,
            connection_info,
        })
    }
}