From b66e509a538ccd2058b797f0d52f4f02dc853286 Mon Sep 17 00:00:00 2001 From: Akrm Al-Hakimi Date: Sun, 31 May 2026 14:51:18 -0400 Subject: [PATCH] fix(#433): require EAP-TLS key and cert in builder --- nmrs/src/api/models/tests.rs | 32 ++++++++++++++++++++++++++++++++ nmrs/src/api/models/wifi.rs | 12 ++++++++++++ 2 files changed, 44 insertions(+) diff --git a/nmrs/src/api/models/tests.rs b/nmrs/src/api/models/tests.rs index bbd8b7b7..fbf5e548 100644 --- a/nmrs/src/api/models/tests.rs +++ b/nmrs/src/api/models/tests.rs @@ -969,6 +969,38 @@ fn test_eap_options_builder_tls() { ); } +#[test] +fn test_eap_options_builder_tls_missing_private_key() { + let err = EapOptions::builder() + .identity("student@university.edu") + .method(EapMethod::Tls) + .client_cert_path("file:///etc/ssl/certs/client.pem") + .build() + .unwrap_err(); + + match err { + ConnectionError::IncompleteBuilder(message) => assert!(message.contains("private key")), + err => panic!("expected IncompleteBuilder, got {err:?}"), + } +} + +#[test] +fn test_eap_options_builder_tls_missing_client_cert() { + let err = EapOptions::builder() + .identity("student@university.edu") + .method(EapMethod::Tls) + .private_key_path("file:///etc/ssl/private/client.key") + .build() + .unwrap_err(); + + match err { + ConnectionError::IncompleteBuilder(message) => { + assert!(message.contains("client certificate")); + } + err => panic!("expected IncompleteBuilder, got {err:?}"), + } +} + #[test] fn test_eap_options_builder_path_blob_ca_cert_path() { let opts = EapOptions::builder() diff --git a/nmrs/src/api/models/wifi.rs b/nmrs/src/api/models/wifi.rs index 89b9fe7e..a5acfefd 100644 --- a/nmrs/src/api/models/wifi.rs +++ b/nmrs/src/api/models/wifi.rs @@ -773,6 +773,18 @@ impl EapOptionsBuilder { "EAP client certificate cannot be specified both as a path and blob".into(), )); } + if self.method == Some(EapMethod::Tls) { + if self.private_key_path.is_none() && self.private_key_blob.is_none() { + return Err(ConnectionError::IncompleteBuilder( + "EAP private key is required for TLS (use .private_key_path() or .private_key_blob())".into(), + )); + } + if self.client_cert_path.is_none() && self.client_cert_blob.is_none() { + return Err(ConnectionError::IncompleteBuilder( + "EAP client certificate is required for TLS (use .client_cert_path() or .client_cert_blob())".into(), + )); + } + } Ok(EapOptions { identity: self.identity.ok_or_else(|| {