use matter_cert::{MatterTime, TrustedRoots};
use crate::case::initiator::CaseInitiator;
use crate::case::responder::CaseResponder;
use crate::case::{CaseCredentials, ResumptionRecord};
use crate::error::Result;
use crate::pase::{PasePbkdfParams, PaseProver, PaseVerifier};
pub fn prover_with_scalar(
pin: u32,
params: PasePbkdfParams,
x_scalar: [u8; 32],
) -> Result<PaseProver> {
PaseProver::new_with_known_params_with_scalar(pin, params, x_scalar)
}
pub fn prover_with_scalar_and_random(
pin: u32,
x_scalar: [u8; 32],
initiator_random: [u8; 32],
) -> Result<PaseProver> {
PaseProver::new_with_negotiation_with_scalar(pin, x_scalar, initiator_random)
}
pub fn verifier_with_scalar(
w0: [u8; 32],
l: [u8; 65],
params: PasePbkdfParams,
y_scalar: [u8; 32],
) -> Result<PaseVerifier> {
PaseVerifier::new_with_scalar(w0, l, params, y_scalar)
}
pub fn verifier_with_scalar_and_random(
w0: [u8; 32],
l: [u8; 65],
params: PasePbkdfParams,
y_scalar: [u8; 32],
responder_random: [u8; 32],
responder_session_id: u16,
) -> Result<PaseVerifier> {
PaseVerifier::new_with_scalar_and_random(
w0,
l,
params,
y_scalar,
responder_random,
responder_session_id,
)
}
pub fn prover_with_scalar_random_and_session_id(
pin: u32,
x_scalar: [u8; 32],
initiator_random: [u8; 32],
initiator_session_id: u16,
) -> Result<PaseProver> {
PaseProver::new_with_negotiation_with_scalar_and_session_id(
pin,
x_scalar,
initiator_random,
initiator_session_id,
)
}
pub fn verifier_with_scalar_from_pin(
pin: u32,
params: PasePbkdfParams,
y_scalar: [u8; 32],
) -> Result<PaseVerifier> {
PaseVerifier::new_from_pin_with_scalar(pin, params, y_scalar)
}
pub fn case_initiator_with_eph_key(
credentials: CaseCredentials,
trusted_roots: TrustedRoots,
peer_node_id: u64,
peer_fabric_id: u64,
eph_private_key: [u8; 32],
initiator_random: [u8; 32],
now: MatterTime,
) -> Result<CaseInitiator> {
CaseInitiator::new_with_eph_and_random(
credentials,
trusted_roots,
peer_node_id,
peer_fabric_id,
eph_private_key,
initiator_random,
now,
)
}
#[allow(clippy::too_many_arguments)]
pub fn case_initiator_with_resumption_eph_key(
credentials: CaseCredentials,
trusted_roots: TrustedRoots,
peer_node_id: u64,
peer_fabric_id: u64,
record: ResumptionRecord,
eph_private_key: [u8; 32],
initiator_random: [u8; 32],
now: MatterTime,
) -> Result<CaseInitiator> {
CaseInitiator::new_with_resumption_eph_and_random(
credentials,
trusted_roots,
peer_node_id,
peer_fabric_id,
record,
eph_private_key,
initiator_random,
now,
)
}
pub fn case_responder_with_eph_key(
credentials: CaseCredentials,
trusted_roots: TrustedRoots,
eph_private_key: [u8; 32],
responder_random: [u8; 32],
now: MatterTime,
) -> Result<CaseResponder> {
CaseResponder::new_with_eph_and_random(
credentials,
trusted_roots,
eph_private_key,
responder_random,
now,
)
}
pub fn case_responder_with_eph_key_and_resumption_id(
credentials: CaseCredentials,
trusted_roots: TrustedRoots,
eph_private_key: [u8; 32],
responder_random: [u8; 32],
new_resumption_id: [u8; 16],
now: MatterTime,
) -> Result<CaseResponder> {
let mut responder = CaseResponder::new_with_eph_and_random(
credentials,
trusted_roots,
eph_private_key,
responder_random,
now,
)?;
responder.set_new_resumption_id_override(new_resumption_id);
Ok(responder)
}
#[cfg(test)]
#[allow(clippy::unwrap_used)]
mod tests {
use super::*;
use crate::pase::PaseMessageKind;
fn valid_scalar() -> [u8; 32] {
let mut s = [0u8; 32];
s[31] = 0x07;
s
}
fn test_params() -> PasePbkdfParams {
PasePbkdfParams {
iterations: 1_000,
salt: vec![0x42u8; 16],
}
}
#[test]
fn prover_with_scalar_constructs_known_params() {
let prover = prover_with_scalar(20_202_021, test_params(), valid_scalar()).unwrap();
assert!(
prover.expected_inbound().is_none(),
"after construction, prover has not yet called start()"
);
}
#[test]
fn prover_with_scalar_rejects_zero_scalar() {
let result = prover_with_scalar(20_202_021, test_params(), [0u8; 32]);
assert!(result.is_err(), "zero scalar must be rejected");
}
#[test]
fn prover_with_scalar_and_random_constructs_negotiation() {
let prover = prover_with_scalar_and_random(
20_202_021,
valid_scalar(),
[0xABu8; 32], )
.unwrap();
assert!(
prover.expected_inbound().is_none(),
"after construction, negotiation prover has not yet called start()"
);
}
#[test]
fn prover_with_scalar_and_random_rejects_zero_scalar() {
let result = prover_with_scalar_and_random(20_202_021, [0u8; 32], [0xABu8; 32]);
assert!(result.is_err(), "zero scalar must be rejected");
}
#[test]
fn verifier_with_scalar_from_pin_constructs() {
let verifier =
verifier_with_scalar_from_pin(20_202_021, test_params(), valid_scalar()).unwrap();
assert_eq!(
verifier.expected_inbound(),
Some(PaseMessageKind::PbkdfParamRequest),
"verifier should be awaiting the first inbound message"
);
}
#[test]
fn verifier_with_scalar_from_pin_rejects_zero_scalar() {
let result = verifier_with_scalar_from_pin(20_202_021, test_params(), [0u8; 32]);
assert!(result.is_err(), "zero scalar must be rejected");
}
#[test]
fn verifier_with_scalar_rejects_zero_w0() {
let result = verifier_with_scalar(
[0u8; 32], [0x04u8; 65], test_params(),
valid_scalar(),
);
assert!(result.is_err(), "zero w0 must be rejected");
}
#[test]
fn verifier_with_scalar_rejects_zero_y() {
let result = verifier_with_scalar(
valid_scalar(), [0x04u8; 65],
test_params(),
[0u8; 32], );
assert!(result.is_err(), "zero y scalar must be rejected");
}
}