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