1mod provider;
4
5pub use provider::FixtureEncodingProvider;
6
7use hex::FromHex;
8use p256::ecdsa::SigningKey;
9
10use crate::{
11 attestation::{Attestation, AttestationConfig, Extension},
12 connection::{
13 Certificate, ConnectionInfo, HandshakeData, HandshakeDataV1_2, KeyType, ServerCertData,
14 ServerEphemKey, ServerName, ServerSignature, SignatureScheme, TlsVersion, TranscriptLength,
15 },
16 hash::HashAlgorithm,
17 request::{Request, RequestConfig},
18 signing::SignatureAlgId,
19 transcript::{
20 encoding::{EncoderSecret, EncodingProvider, EncodingTree},
21 Transcript, TranscriptCommitConfigBuilder, TranscriptCommitment,
22 },
23 CryptoProvider,
24};
25
26#[derive(Clone)]
28#[allow(missing_docs)]
29pub struct ConnectionFixture {
30 pub server_name: ServerName,
31 pub connection_info: ConnectionInfo,
32 pub server_cert_data: ServerCertData,
33}
34
35impl ConnectionFixture {
36 pub fn tlsnotary(transcript_length: TranscriptLength) -> Self {
38 ConnectionFixture {
39 server_name: ServerName::new("tlsnotary.org".to_string()),
40 connection_info: ConnectionInfo {
41 time: 1671637529,
42 version: TlsVersion::V1_2,
43 transcript_length,
44 },
45 server_cert_data: ServerCertData {
46 certs: vec![
47 Certificate(include_bytes!("fixtures/data/tlsnotary.org/ee.der").to_vec()),
48 Certificate(include_bytes!("fixtures/data/tlsnotary.org/inter.der").to_vec()),
49 Certificate(include_bytes!("fixtures/data/tlsnotary.org/ca.der").to_vec()),
50 ],
51 sig: ServerSignature {
52 scheme: SignatureScheme::RSA_PKCS1_SHA256,
53 sig: Vec::<u8>::from_hex(include_bytes!(
54 "fixtures/data/tlsnotary.org/signature"
55 ))
56 .unwrap(),
57 },
58 handshake: HandshakeData::V1_2(HandshakeDataV1_2 {
59 client_random: <[u8; 32]>::from_hex(include_bytes!(
60 "fixtures/data/tlsnotary.org/client_random"
61 ))
62 .unwrap(),
63 server_random: <[u8; 32]>::from_hex(include_bytes!(
64 "fixtures/data/tlsnotary.org/server_random"
65 ))
66 .unwrap(),
67 server_ephemeral_key: ServerEphemKey {
68 typ: KeyType::SECP256R1,
69 key: Vec::<u8>::from_hex(include_bytes!(
70 "fixtures/data/tlsnotary.org/pubkey"
71 ))
72 .unwrap(),
73 },
74 }),
75 },
76 }
77 }
78
79 pub fn appliedzkp(transcript_length: TranscriptLength) -> Self {
81 ConnectionFixture {
82 server_name: ServerName::new("appliedzkp.org".to_string()),
83 connection_info: ConnectionInfo {
84 time: 1671637529,
85 version: TlsVersion::V1_2,
86 transcript_length,
87 },
88 server_cert_data: ServerCertData {
89 certs: vec![
90 Certificate(include_bytes!("fixtures/data/appliedzkp.org/ee.der").to_vec()),
91 Certificate(include_bytes!("fixtures/data/appliedzkp.org/inter.der").to_vec()),
92 Certificate(include_bytes!("fixtures/data/appliedzkp.org/ca.der").to_vec()),
93 ],
94 sig: ServerSignature {
95 scheme: SignatureScheme::ECDSA_NISTP256_SHA256,
96 sig: Vec::<u8>::from_hex(include_bytes!(
97 "fixtures/data/appliedzkp.org/signature"
98 ))
99 .unwrap(),
100 },
101 handshake: HandshakeData::V1_2(HandshakeDataV1_2 {
102 client_random: <[u8; 32]>::from_hex(include_bytes!(
103 "fixtures/data/appliedzkp.org/client_random"
104 ))
105 .unwrap(),
106 server_random: <[u8; 32]>::from_hex(include_bytes!(
107 "fixtures/data/appliedzkp.org/server_random"
108 ))
109 .unwrap(),
110 server_ephemeral_key: ServerEphemKey {
111 typ: KeyType::SECP256R1,
112 key: Vec::<u8>::from_hex(include_bytes!(
113 "fixtures/data/appliedzkp.org/pubkey"
114 ))
115 .unwrap(),
116 },
117 }),
118 },
119 }
120 }
121
122 pub fn server_ephemeral_key(&self) -> &ServerEphemKey {
124 let HandshakeData::V1_2(HandshakeDataV1_2 {
125 server_ephemeral_key,
126 ..
127 }) = &self.server_cert_data.handshake;
128 server_ephemeral_key
129 }
130}
131
132pub fn encoding_provider(tx: &[u8], rx: &[u8]) -> impl EncodingProvider {
134 let secret = encoder_secret();
135 FixtureEncodingProvider::new(&secret, Transcript::new(tx, rx))
136}
137
138const SEED: [u8; 32] = [0; 32];
140
141const DELTA: [u8; 16] = [1; 16];
143
144pub fn encoder_secret() -> EncoderSecret {
146 EncoderSecret::new(SEED, DELTA)
147}
148
149pub fn encoder_secret_tampered_seed() -> EncoderSecret {
151 let mut seed = SEED;
152 seed[0] += 1;
153 EncoderSecret::new(seed, DELTA)
154}
155
156pub fn notary_signing_key() -> SigningKey {
158 SigningKey::from_slice(&[1; 32]).unwrap()
159}
160
161#[allow(missing_docs)]
163pub struct RequestFixture {
164 pub encoding_tree: EncodingTree,
165 pub request: Request,
166}
167
168pub fn request_fixture(
170 transcript: Transcript,
171 encodings_provider: impl EncodingProvider,
172 connection: ConnectionFixture,
173 encoding_hasher: impl HashAlgorithm,
174 extensions: Vec<Extension>,
175) -> RequestFixture {
176 let provider = CryptoProvider::default();
177 let (sent_len, recv_len) = transcript.len();
178
179 let ConnectionFixture {
180 server_name,
181 server_cert_data,
182 ..
183 } = connection;
184
185 let mut transcript_commitment_builder = TranscriptCommitConfigBuilder::new(&transcript);
186 transcript_commitment_builder
187 .commit_sent(&(0..sent_len))
188 .unwrap()
189 .commit_recv(&(0..recv_len))
190 .unwrap();
191 let transcripts_commitment_config = transcript_commitment_builder.build().unwrap();
192
193 let encoding_tree = EncodingTree::new(
195 &encoding_hasher,
196 transcripts_commitment_config.iter_encoding(),
197 &encodings_provider,
198 )
199 .unwrap();
200
201 let mut builder = RequestConfig::builder();
202
203 for extension in extensions {
204 builder.extension(extension);
205 }
206
207 let request_config = builder.build().unwrap();
208
209 let mut request_builder = Request::builder(&request_config);
210 request_builder
211 .server_name(server_name)
212 .server_cert_data(server_cert_data)
213 .transcript(transcript);
214
215 let (request, _) = request_builder.build(&provider).unwrap();
216
217 RequestFixture {
218 encoding_tree,
219 request,
220 }
221}
222
223pub fn attestation_fixture(
225 request: Request,
226 connection: ConnectionFixture,
227 signature_alg: SignatureAlgId,
228 transcript_commitments: &[TranscriptCommitment],
229) -> Attestation {
230 let ConnectionFixture {
231 connection_info,
232 server_cert_data,
233 ..
234 } = connection;
235
236 let HandshakeData::V1_2(HandshakeDataV1_2 {
237 server_ephemeral_key,
238 ..
239 }) = server_cert_data.handshake;
240
241 let mut provider = CryptoProvider::default();
242 match signature_alg {
243 SignatureAlgId::SECP256K1 => provider.signer.set_secp256k1(&[42u8; 32]).unwrap(),
244 SignatureAlgId::SECP256R1 => provider.signer.set_secp256r1(&[42u8; 32]).unwrap(),
245 _ => unimplemented!(),
246 };
247
248 let attestation_config = AttestationConfig::builder()
249 .supported_signature_algs([signature_alg])
250 .build()
251 .unwrap();
252
253 let mut attestation_builder = Attestation::builder(&attestation_config)
254 .accept_request(request)
255 .unwrap();
256
257 attestation_builder
258 .connection_info(connection_info)
259 .server_ephemeral_key(server_ephemeral_key)
260 .transcript_commitments(transcript_commitments.to_vec());
261
262 attestation_builder.build(&provider).unwrap()
263}