tlsn_core/request/
builder.rs1use crate::{
2 connection::{ServerCertData, ServerCertOpening, ServerName},
3 request::{Request, RequestConfig},
4 secrets::Secrets,
5 transcript::{Transcript, TranscriptCommitment, TranscriptSecret},
6 CryptoProvider,
7};
8
9pub struct RequestBuilder<'a> {
11 config: &'a RequestConfig,
12 server_name: Option<ServerName>,
13 server_cert_data: Option<ServerCertData>,
14 transcript: Option<Transcript>,
15 transcript_commitments: Vec<TranscriptCommitment>,
16 transcript_commitment_secrets: Vec<TranscriptSecret>,
17}
18
19impl<'a> RequestBuilder<'a> {
20 pub fn new(config: &'a RequestConfig) -> Self {
22 Self {
23 config,
24 server_name: None,
25 server_cert_data: None,
26 transcript: None,
27 transcript_commitments: Vec::new(),
28 transcript_commitment_secrets: Vec::new(),
29 }
30 }
31
32 pub fn server_name(&mut self, name: ServerName) -> &mut Self {
34 self.server_name = Some(name);
35 self
36 }
37
38 pub fn server_cert_data(&mut self, data: ServerCertData) -> &mut Self {
40 self.server_cert_data = Some(data);
41 self
42 }
43
44 pub fn transcript(&mut self, transcript: Transcript) -> &mut Self {
46 self.transcript = Some(transcript);
47 self
48 }
49
50 pub fn transcript_commitments(
52 &mut self,
53 secrets: Vec<TranscriptSecret>,
54 commitments: Vec<TranscriptCommitment>,
55 ) -> &mut Self {
56 self.transcript_commitment_secrets = secrets;
57 self.transcript_commitments = commitments;
58 self
59 }
60
61 pub fn build(
63 self,
64 provider: &CryptoProvider,
65 ) -> Result<(Request, Secrets), RequestBuilderError> {
66 let Self {
67 config,
68 server_name,
69 server_cert_data,
70 transcript,
71 transcript_commitments,
72 transcript_commitment_secrets,
73 } = self;
74
75 let signature_alg = *config.signature_alg();
76 let hash_alg = *config.hash_alg();
77
78 let hasher = provider.hash.get(&hash_alg).map_err(|_| {
79 RequestBuilderError::new(format!("unsupported hash algorithm: {hash_alg}"))
80 })?;
81
82 let server_name =
83 server_name.ok_or_else(|| RequestBuilderError::new("server name is missing"))?;
84
85 let server_cert_opening = ServerCertOpening::new(
86 server_cert_data
87 .ok_or_else(|| RequestBuilderError::new("server identity data is missing"))?,
88 );
89
90 let transcript =
91 transcript.ok_or_else(|| RequestBuilderError::new("transcript is missing"))?;
92
93 let server_cert_commitment = server_cert_opening.commit(hasher);
94
95 let extensions = config.extensions().to_vec();
96
97 let request = Request {
98 signature_alg,
99 hash_alg,
100 server_cert_commitment,
101 extensions,
102 };
103
104 let secrets = Secrets {
105 server_name,
106 server_cert_opening,
107 transcript,
108 transcript_commitments,
109 transcript_commitment_secrets,
110 };
111
112 Ok((request, secrets))
113 }
114}
115
116#[derive(Debug, thiserror::Error)]
118#[error("request builder error: {message}")]
119pub struct RequestBuilderError {
120 message: String,
121}
122
123impl RequestBuilderError {
124 fn new(message: impl Into<String>) -> Self {
125 Self {
126 message: message.into(),
127 }
128 }
129}