Skip to content

Commit

Permalink
chore: core-rewrite unit tests (#608)
Browse files Browse the repository at this point in the history
* Add tests for signing, index.

* Add error scenarios.

* Add cert tests, modify previous tests.

* Improve cert tests.

* Add tests for request.

* Fix clippy

* Fix clippy.

* Change requests test style.

* Add attestation unit tests.

* Formatting.

* Clippy.

* make data fixtures optional

---------

Co-authored-by: yuroitaki <>
Co-authored-by: sinu <[email protected]>
  • Loading branch information
yuroitaki and sinui0 authored Oct 3, 2024
1 parent 0596a9a commit 4d5102b
Show file tree
Hide file tree
Showing 8 changed files with 847 additions and 3 deletions.
5 changes: 3 additions & 2 deletions crates/core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@ edition = "2021"

[features]
default = []
fixtures = ["dep:hex"]
fixtures = ["dep:hex", "dep:tlsn-data-fixtures"]

[dependencies]
tlsn-data-fixtures = { workspace = true, optional = true }
tlsn-tls-core = { workspace = true, features = ["serde"] }
tlsn-utils = { workspace = true }

Expand All @@ -29,6 +30,7 @@ k256 = { workspace = true }
opaque-debug = { workspace = true }
p256 = { workspace = true, features = ["serde"] }
rand = { workspace = true }
rand_core = { workspace = true }
rs_merkle = { workspace = true, features = ["serde"] }
rstest = { workspace = true, optional = true }
serde = { workspace = true }
Expand All @@ -41,7 +43,6 @@ webpki-roots = { workspace = true }
[dev-dependencies]
rstest = { workspace = true }
hex = { workspace = true }
rand_core = { workspace = true }
rand_chacha = { workspace = true }
bincode = { workspace = true }
tlsn-data-fixtures = { workspace = true }
Expand Down
231 changes: 231 additions & 0 deletions crates/core/src/attestation/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -237,3 +237,234 @@ impl std::fmt::Display for AttestationBuilderError {
Ok(())
}
}

#[cfg(test)]
mod test {
use rstest::{fixture, rstest};
use tlsn_data_fixtures::http::{request::GET_WITH_HEADER, response::OK_JSON};

use crate::{
connection::{HandshakeData, HandshakeDataV1_2},
fixtures::{encoder_seed, encoding_provider, ConnectionFixture},
hash::Blake3,
request::RequestConfig,
transcript::{encoding::EncodingTree, Transcript, TranscriptCommitConfigBuilder},
};

use super::*;

fn request_and_connection() -> (Request, ConnectionFixture) {
let provider = CryptoProvider::default();

let transcript = Transcript::new(GET_WITH_HEADER, OK_JSON);
let (sent_len, recv_len) = transcript.len();
// Plaintext encodings which the Prover obtained from GC evaluation
let encodings_provider = encoding_provider(GET_WITH_HEADER, OK_JSON);

// At the end of the TLS connection the Prover holds the:
let ConnectionFixture {
server_name,
server_cert_data,
..
} = ConnectionFixture::tlsnotary(transcript.length());

// Prover specifies the ranges it wants to commit to.
let mut transcript_commitment_builder = TranscriptCommitConfigBuilder::new(&transcript);
transcript_commitment_builder
.commit_sent(&(0..sent_len))
.unwrap()
.commit_recv(&(0..recv_len))
.unwrap();

let transcripts_commitment_config = transcript_commitment_builder.build().unwrap();

// Prover constructs encoding tree.
let encoding_tree = EncodingTree::new(
&Blake3::default(),
transcripts_commitment_config.iter_encoding(),
&encodings_provider,
&transcript.length(),
)
.unwrap();

let request_config = RequestConfig::default();
let mut request_builder = Request::builder(&request_config);

request_builder
.server_name(server_name.clone())
.server_cert_data(server_cert_data)
.transcript(transcript.clone())
.encoding_tree(encoding_tree);
let (request, _) = request_builder.build(&provider).unwrap();

(request, ConnectionFixture::tlsnotary(transcript.length()))
}

#[fixture]
#[once]
fn default_attestation_config() -> AttestationConfig {
AttestationConfig::builder()
.supported_signature_algs([SignatureAlgId::SECP256K1])
.build()
.unwrap()
}

#[fixture]
#[once]
fn crypto_provider() -> CryptoProvider {
let mut provider = CryptoProvider::default();
provider.signer.set_secp256k1(&[42u8; 32]).unwrap();
provider
}

#[rstest]
fn test_attestation_builder_accept_unsupported_signer() {
let (request, _) = request_and_connection();
let attestation_config = AttestationConfig::builder()
.supported_signature_algs([SignatureAlgId::SECP256R1])
.build()
.unwrap();

let err = Attestation::builder(&attestation_config)
.accept_request(request)
.err()
.unwrap();
assert!(err.is_request());
}

#[rstest]
fn test_attestation_builder_accept_unsupported_hasher() {
let (request, _) = request_and_connection();

let attestation_config = AttestationConfig::builder()
.supported_signature_algs([SignatureAlgId::SECP256K1])
.supported_hash_algs([HashAlgId::KECCAK256])
.build()
.unwrap();

let err = Attestation::builder(&attestation_config)
.accept_request(request)
.err()
.unwrap();
assert!(err.is_request());
}

#[rstest]
fn test_attestation_builder_accept_unsupported_encoding_commitment() {
let (request, _) = request_and_connection();

let attestation_config = AttestationConfig::builder()
.supported_signature_algs([SignatureAlgId::SECP256K1])
.supported_fields([
FieldKind::ConnectionInfo,
FieldKind::ServerEphemKey,
FieldKind::ServerIdentityCommitment,
])
.build()
.unwrap();

let err = Attestation::builder(&attestation_config)
.accept_request(request)
.err()
.unwrap();
assert!(err.is_request());
}

#[rstest]
fn test_attestation_builder_sign_missing_signer(
default_attestation_config: &AttestationConfig,
) {
let (request, _) = request_and_connection();

let attestation_builder = Attestation::builder(default_attestation_config)
.accept_request(request.clone())
.unwrap();

let mut provider = CryptoProvider::default();
provider.signer.set_secp256r1(&[42u8; 32]).unwrap();

let err = attestation_builder.build(&provider).err().unwrap();
assert!(matches!(err.kind, ErrorKind::Config));
}

#[rstest]
fn test_attestation_builder_sign_missing_encoding_seed(
default_attestation_config: &AttestationConfig,
crypto_provider: &CryptoProvider,
) {
let (request, connection) = request_and_connection();

let mut attestation_builder = Attestation::builder(default_attestation_config)
.accept_request(request.clone())
.unwrap();

let ConnectionFixture {
connection_info,
server_cert_data,
..
} = connection;

let HandshakeData::V1_2(HandshakeDataV1_2 {
server_ephemeral_key,
..
}) = server_cert_data.handshake.clone();

attestation_builder
.connection_info(connection_info.clone())
.server_ephemeral_key(server_ephemeral_key);

let err = attestation_builder.build(crypto_provider).err().unwrap();
assert!(matches!(err.kind, ErrorKind::Field));
}

#[rstest]
fn test_attestation_builder_sign_missing_server_ephemeral_key(
default_attestation_config: &AttestationConfig,
crypto_provider: &CryptoProvider,
) {
let (request, connection) = request_and_connection();

let mut attestation_builder = Attestation::builder(default_attestation_config)
.accept_request(request.clone())
.unwrap();

let ConnectionFixture {
connection_info, ..
} = connection;

attestation_builder
.connection_info(connection_info.clone())
.encoding_seed(encoder_seed().to_vec());

let err = attestation_builder.build(crypto_provider).err().unwrap();
assert!(matches!(err.kind, ErrorKind::Field));
}

#[rstest]
fn test_attestation_builder_sign_missing_connection_info(
default_attestation_config: &AttestationConfig,
crypto_provider: &CryptoProvider,
) {
let (request, connection) = request_and_connection();

let mut attestation_builder = Attestation::builder(default_attestation_config)
.accept_request(request.clone())
.unwrap();

let ConnectionFixture {
server_cert_data, ..
} = connection;

let HandshakeData::V1_2(HandshakeDataV1_2 {
server_ephemeral_key,
..
}) = server_cert_data.handshake.clone();

attestation_builder
.server_ephemeral_key(server_ephemeral_key)
.encoding_seed(encoder_seed().to_vec());

let err = attestation_builder.build(crypto_provider).err().unwrap();
assert!(matches!(err.kind, ErrorKind::Field));
}
}
Loading

0 comments on commit 4d5102b

Please sign in to comment.