1pub mod credential;
33mod data;
34
35use derivative::Derivative;
36use fidl_fuchsia_wlan_common_security as fidl_security;
37use std::fmt::Debug;
38use std::hash::{Hash, Hasher};
39use thiserror::Error;
40
41use crate::security::wpa::credential::{Passphrase, PassphraseError, Psk, PskError};
42use crate::security::wpa::data::{CredentialData, EnterpriseData, PersonalData};
43use crate::security::{BareCredentials, SecurityError};
44
45pub use crate::security::wpa::data::AuthenticatorData;
46
47#[derive(Clone, Copy, Debug, Error, Eq, PartialEq)]
48#[non_exhaustive]
49pub enum WpaError {
50 #[error(transparent)]
51 Psk(#[from] PskError),
52 #[error(transparent)]
53 Passphrase(#[from] PassphraseError),
54}
55
56#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
62pub enum Authentication<P = (), E = ()> {
63 Personal(P),
64 Enterprise(E),
65}
66
67pub type AuthenticationDescriptor = Authentication<(), ()>;
68
69pub type Credentials = Authentication<PersonalCredentials, EnterpriseCredentials>;
74
75impl<P, E> Authentication<P, E> {
76 pub fn into_descriptor(self) -> Authentication<(), ()> {
79 match self {
80 Authentication::Personal(_) => Authentication::Personal(()),
81 Authentication::Enterprise(_) => Authentication::Enterprise(()),
82 }
83 }
84
85 pub fn into_credentials(self) -> Credentials
88 where
89 PersonalCredentials: From<P>,
90 EnterpriseCredentials: From<E>,
91 {
92 match self {
93 Authentication::Personal(personal) => Authentication::Personal(personal.into()),
94 Authentication::Enterprise(enterprise) => Authentication::Enterprise(enterprise.into()),
95 }
96 }
97
98 pub fn into_personal(self) -> Option<P> {
99 if let Authentication::Personal(personal) = self {
100 Some(personal)
101 } else {
102 None
103 }
104 }
105
106 pub fn into_enterprise(self) -> Option<E> {
107 if let Authentication::Enterprise(enterprise) = self {
108 Some(enterprise)
109 } else {
110 None
111 }
112 }
113
114 pub fn is_personal(&self) -> bool {
115 matches!(self, Authentication::Personal(_))
116 }
117
118 pub fn is_enterprise(&self) -> bool {
119 matches!(self, Authentication::Enterprise(_))
120 }
121
122 pub fn as_ref(&self) -> Authentication<&P, &E> {
123 match self {
124 Authentication::Personal(ref personal) => Authentication::Personal(personal),
125 Authentication::Enterprise(ref enterprise) => Authentication::Enterprise(enterprise),
126 }
127 }
128}
129
130impl Default for Authentication<(), ()> {
131 fn default() -> Self {
132 Authentication::Personal(())
133 }
134}
135
136impl From<Wpa1Credentials> for Authentication<Wpa1Credentials, ()> {
137 fn from(credentials: Wpa1Credentials) -> Self {
138 Authentication::Personal(credentials)
139 }
140}
141
142impl From<Wpa2PersonalCredentials> for Authentication<Wpa2PersonalCredentials, ()> {
144 fn from(credentials: Wpa2PersonalCredentials) -> Self {
145 Authentication::Personal(credentials)
146 }
147}
148
149impl From<Wpa3PersonalCredentials> for Authentication<Wpa3PersonalCredentials, ()> {
151 fn from(credentials: Wpa3PersonalCredentials) -> Self {
152 Authentication::Personal(credentials)
153 }
154}
155
156impl From<EnterpriseCredentials> for Credentials {
157 fn from(enterprise: EnterpriseCredentials) -> Self {
158 Credentials::Enterprise(enterprise)
159 }
160}
161
162impl From<PersonalCredentials> for Credentials {
163 fn from(personal: PersonalCredentials) -> Self {
164 Credentials::Personal(personal)
165 }
166}
167
168impl<P, E> From<Authentication<P, E>> for fidl_security::WpaCredentials
169where
170 P: Into<fidl_security::WpaCredentials>,
171 E: Into<fidl_security::WpaCredentials>,
172{
173 fn from(authentication: Authentication<P, E>) -> Self {
174 match authentication {
175 Authentication::Personal(personal) => personal.into(),
176 Authentication::Enterprise(_) => panic!("WPA Enterprise is unsupported"),
178 }
179 }
180}
181
182impl From<Credentials> for BareCredentials {
184 fn from(credentials: Credentials) -> Self {
185 match credentials {
186 Credentials::Personal(personal) => match personal {
187 PersonalCredentials::Passphrase(passphrase) => {
188 BareCredentials::WpaPassphrase(passphrase)
189 }
190 PersonalCredentials::Psk(psk) => BareCredentials::WpaPsk(psk),
191 },
192 Credentials::Enterprise(_) => panic!("WPA Enterprise is unsupported"),
194 }
195 }
196}
197
198#[derive(Clone, Debug, Eq, PartialEq)]
208pub enum PersonalCredentials {
209 Psk(Psk),
211 Passphrase(Passphrase),
213}
214
215impl AsRef<[u8]> for PersonalCredentials {
216 fn as_ref(&self) -> &[u8] {
217 match self {
218 PersonalCredentials::Psk(ref psk) => psk.as_ref(),
219 PersonalCredentials::Passphrase(ref passphrase) => passphrase.as_ref(),
220 }
221 }
222}
223
224impl From<Wpa1Credentials> for PersonalCredentials {
225 fn from(credentials: Wpa1Credentials) -> Self {
226 match credentials {
227 Wpa1Credentials::Psk(psk) => PersonalCredentials::Psk(psk),
228 Wpa1Credentials::Passphrase(passphrase) => PersonalCredentials::Passphrase(passphrase),
229 }
230 }
231}
232
233impl From<Wpa2PersonalCredentials> for PersonalCredentials {
234 fn from(credentials: Wpa2PersonalCredentials) -> Self {
235 match credentials {
236 Wpa2PersonalCredentials::Psk(psk) => PersonalCredentials::Psk(psk),
237 Wpa2PersonalCredentials::Passphrase(passphrase) => {
238 PersonalCredentials::Passphrase(passphrase)
239 }
240 }
241 }
242}
243
244impl From<Wpa3PersonalCredentials> for PersonalCredentials {
245 fn from(credentials: Wpa3PersonalCredentials) -> Self {
246 match credentials {
247 Wpa3PersonalCredentials::Passphrase(passphrase) => {
248 PersonalCredentials::Passphrase(passphrase)
249 }
250 }
251 }
252}
253
254impl From<PersonalCredentials> for fidl_security::WpaCredentials {
255 fn from(credentials: PersonalCredentials) -> Self {
256 match credentials {
257 PersonalCredentials::Psk(psk) => fidl_security::WpaCredentials::Psk(psk.into()),
258 PersonalCredentials::Passphrase(passphrase) => {
259 fidl_security::WpaCredentials::Passphrase(passphrase.into())
260 }
261 }
262 }
263}
264
265#[derive(Clone, Debug, Eq, PartialEq)]
266pub enum Wpa1Credentials {
267 Psk(Psk),
268 Passphrase(Passphrase),
269}
270
271impl AsRef<[u8]> for Wpa1Credentials {
272 fn as_ref(&self) -> &[u8] {
273 match self {
274 Wpa1Credentials::Psk(ref psk) => psk.as_ref(),
275 Wpa1Credentials::Passphrase(ref passphrase) => passphrase.as_ref(),
276 }
277 }
278}
279
280impl From<Passphrase> for Wpa1Credentials {
281 fn from(passphrase: Passphrase) -> Self {
282 Wpa1Credentials::Passphrase(passphrase)
283 }
284}
285
286impl From<Psk> for Wpa1Credentials {
287 fn from(psk: Psk) -> Self {
288 Wpa1Credentials::Psk(psk)
289 }
290}
291
292impl From<Wpa1Credentials> for fidl_security::WpaCredentials {
293 fn from(credentials: Wpa1Credentials) -> Self {
294 PersonalCredentials::from(credentials).into()
295 }
296}
297
298impl TryFrom<PersonalCredentials> for Wpa1Credentials {
302 type Error = SecurityError;
303
304 fn try_from(credentials: PersonalCredentials) -> Result<Self, Self::Error> {
305 match credentials {
306 PersonalCredentials::Psk(psk) => Ok(Wpa1Credentials::Psk(psk)),
307 PersonalCredentials::Passphrase(passphrase) => {
308 Ok(Wpa1Credentials::Passphrase(passphrase))
309 }
310 }
311 }
312}
313
314impl TryFrom<fidl_security::WpaCredentials> for Wpa1Credentials {
315 type Error = SecurityError;
316
317 fn try_from(credentials: fidl_security::WpaCredentials) -> Result<Self, Self::Error> {
318 match credentials {
319 fidl_security::WpaCredentials::Psk(psk) => Ok(Wpa1Credentials::Psk(Psk::from(psk))),
320 fidl_security::WpaCredentials::Passphrase(passphrase) => {
321 let passphrase = Passphrase::try_from(passphrase)?;
322 Ok(Wpa1Credentials::Passphrase(passphrase))
323 }
324 _ => panic!("unknown FIDL credentials variant"),
325 }
326 }
327}
328
329#[derive(Clone, Debug, Eq, PartialEq)]
330pub enum Wpa2PersonalCredentials {
331 Psk(Psk),
332 Passphrase(Passphrase),
333}
334
335impl AsRef<[u8]> for Wpa2PersonalCredentials {
336 fn as_ref(&self) -> &[u8] {
337 match self {
338 Wpa2PersonalCredentials::Psk(ref psk) => psk.as_ref(),
339 Wpa2PersonalCredentials::Passphrase(ref passphrase) => passphrase.as_ref(),
340 }
341 }
342}
343
344impl From<Passphrase> for Wpa2PersonalCredentials {
345 fn from(passphrase: Passphrase) -> Self {
346 Wpa2PersonalCredentials::Passphrase(passphrase)
347 }
348}
349
350impl From<Psk> for Wpa2PersonalCredentials {
351 fn from(psk: Psk) -> Self {
352 Wpa2PersonalCredentials::Psk(psk)
353 }
354}
355
356impl From<Wpa2PersonalCredentials> for fidl_security::WpaCredentials {
357 fn from(credentials: Wpa2PersonalCredentials) -> Self {
358 PersonalCredentials::from(credentials).into()
359 }
360}
361
362impl TryFrom<PersonalCredentials> for Wpa2PersonalCredentials {
366 type Error = SecurityError;
367
368 fn try_from(credentials: PersonalCredentials) -> Result<Self, Self::Error> {
369 match credentials {
370 PersonalCredentials::Psk(psk) => Ok(Wpa2PersonalCredentials::Psk(psk)),
371 PersonalCredentials::Passphrase(passphrase) => {
372 Ok(Wpa2PersonalCredentials::Passphrase(passphrase))
373 }
374 }
375 }
376}
377
378impl TryFrom<fidl_security::WpaCredentials> for Wpa2PersonalCredentials {
379 type Error = SecurityError;
380
381 fn try_from(credentials: fidl_security::WpaCredentials) -> Result<Self, Self::Error> {
382 match credentials {
383 fidl_security::WpaCredentials::Psk(psk) => {
384 Ok(Wpa2PersonalCredentials::Psk(Psk::from(psk)))
385 }
386 fidl_security::WpaCredentials::Passphrase(passphrase) => {
387 let passphrase = Passphrase::try_from(passphrase)?;
388 Ok(Wpa2PersonalCredentials::Passphrase(passphrase))
389 }
390 _ => panic!("unknown FIDL credentials variant"),
391 }
392 }
393}
394
395#[derive(Clone, Debug, Eq, PartialEq)]
396pub enum Wpa3PersonalCredentials {
397 Passphrase(Passphrase),
398}
399
400impl AsRef<[u8]> for Wpa3PersonalCredentials {
401 fn as_ref(&self) -> &[u8] {
402 match self {
403 Wpa3PersonalCredentials::Passphrase(ref passphrase) => passphrase.as_ref(),
404 }
405 }
406}
407
408impl From<Passphrase> for Wpa3PersonalCredentials {
409 fn from(passphrase: Passphrase) -> Self {
410 Wpa3PersonalCredentials::Passphrase(passphrase)
411 }
412}
413
414impl From<Wpa3PersonalCredentials> for fidl_security::WpaCredentials {
415 fn from(credentials: Wpa3PersonalCredentials) -> Self {
416 PersonalCredentials::from(credentials).into()
417 }
418}
419
420impl TryFrom<PersonalCredentials> for Wpa3PersonalCredentials {
421 type Error = SecurityError;
422
423 fn try_from(credentials: PersonalCredentials) -> Result<Self, Self::Error> {
424 match credentials {
425 PersonalCredentials::Passphrase(passphrase) => {
426 Ok(Wpa3PersonalCredentials::Passphrase(passphrase))
427 }
428 _ => Err(SecurityError::Incompatible),
429 }
430 }
431}
432
433impl TryFrom<fidl_security::WpaCredentials> for Wpa3PersonalCredentials {
434 type Error = SecurityError;
435
436 fn try_from(credentials: fidl_security::WpaCredentials) -> Result<Self, Self::Error> {
437 match credentials {
438 fidl_security::WpaCredentials::Psk(_) => Err(SecurityError::Incompatible),
439 fidl_security::WpaCredentials::Passphrase(passphrase) => {
440 let passphrase = Passphrase::try_from(passphrase)?;
441 Ok(Wpa3PersonalCredentials::Passphrase(passphrase))
442 }
443 _ => panic!("unknown FIDL credentials variant"),
444 }
445 }
446}
447
448#[derive(Clone, Debug, Eq, PartialEq)]
460pub enum EnterpriseCredentials {}
461
462impl From<()> for EnterpriseCredentials {
463 fn from(_: ()) -> Self {
464 panic!("WPA Enterprise is unsupported")
466 }
467}
468
469impl From<EnterpriseCredentials> for fidl_security::WpaCredentials {
470 fn from(_: EnterpriseCredentials) -> Self {
471 panic!("WPA Enterprise is unsupported")
473 }
474}
475
476#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
484#[repr(u8)]
485pub enum Cipher {
486 TKIP = 0,
487 CCMP = 1,
488 GCMP = 2,
489}
490
491impl From<Wpa2Cipher> for Cipher {
492 fn from(cipher: Wpa2Cipher) -> Self {
493 match cipher {
494 Wpa2Cipher::TKIP => Cipher::TKIP,
495 Wpa2Cipher::CCMP => Cipher::CCMP,
496 }
497 }
498}
499
500impl From<Wpa3Cipher> for Cipher {
501 fn from(cipher: Wpa3Cipher) -> Self {
502 match cipher {
503 Wpa3Cipher::CCMP => Cipher::CCMP,
504 Wpa3Cipher::GCMP => Cipher::GCMP,
505 }
506 }
507}
508
509#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
511#[repr(u8)]
512pub enum Wpa2Cipher {
513 TKIP = 0,
514 CCMP = 1,
515}
516
517impl TryFrom<Cipher> for Wpa2Cipher {
518 type Error = SecurityError;
519
520 fn try_from(cipher: Cipher) -> Result<Self, Self::Error> {
521 match cipher {
522 Cipher::TKIP => Ok(Wpa2Cipher::TKIP),
523 Cipher::CCMP => Ok(Wpa2Cipher::CCMP),
524 _ => Err(SecurityError::Incompatible),
525 }
526 }
527}
528
529#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
531#[repr(u8)]
532pub enum Wpa3Cipher {
533 CCMP = 1,
534 GCMP = 2,
535}
536
537impl TryFrom<Cipher> for Wpa3Cipher {
538 type Error = SecurityError;
539
540 fn try_from(cipher: Cipher) -> Result<Self, Self::Error> {
541 match cipher {
542 Cipher::CCMP => Ok(Wpa3Cipher::CCMP),
543 Cipher::GCMP => Ok(Wpa3Cipher::GCMP),
544 _ => Err(SecurityError::Incompatible),
545 }
546 }
547}
548
549#[derive(Derivative)]
566#[derivative(
567 Clone(bound = ""),
568 Copy(bound = "
569 <C::Personal as PersonalData>::Wpa1: Copy,
570 <C::Personal as PersonalData>::Wpa2: Copy,
571 <C::Personal as PersonalData>::Wpa3: Copy,
572 <C::Enterprise as EnterpriseData>::Wpa2: Copy,
573 <C::Enterprise as EnterpriseData>::Wpa3: Copy,
574 "),
575 Debug(bound = ""),
576 Eq(bound = ""),
577 PartialEq(bound = "")
578)]
579pub enum Wpa<C = ()>
580where
581 C: CredentialData,
582{
583 Wpa1 {
584 credentials: <C::Personal as PersonalData>::Wpa1,
585 },
586 Wpa2 {
587 cipher: Option<Wpa2Cipher>,
588 authentication: Authentication<
589 <C::Personal as PersonalData>::Wpa2,
590 <C::Enterprise as EnterpriseData>::Wpa2,
591 >,
592 },
593 Wpa3 {
594 cipher: Option<Wpa3Cipher>,
595 authentication: Authentication<
596 <C::Personal as PersonalData>::Wpa3,
597 <C::Enterprise as EnterpriseData>::Wpa3,
598 >,
599 },
600}
601
602impl<C> Wpa<C>
603where
604 C: CredentialData,
605{
606 pub fn into_descriptor(self) -> Wpa<()> {
609 match self {
610 Wpa::Wpa1 { .. } => Wpa::Wpa1 { credentials: () },
611 Wpa::Wpa2 { cipher, authentication } => {
612 Wpa::Wpa2 { cipher, authentication: authentication.into_descriptor() }
613 }
614 Wpa::Wpa3 { cipher, authentication } => {
615 Wpa::Wpa3 { cipher, authentication: authentication.into_descriptor() }
616 }
617 }
618 }
619
620 pub fn cipher(&self) -> Option<Cipher> {
631 match self {
632 Wpa::Wpa1 { .. } => Some(Cipher::TKIP),
633 Wpa::Wpa2 { cipher, .. } => cipher.map(Into::into),
634 Wpa::Wpa3 { cipher, .. } => cipher.map(Into::into),
635 }
636 }
637}
638
639impl<C> From<Wpa<C>> for fidl_security::Protocol
640where
641 C: CredentialData,
642{
643 fn from(wpa: Wpa<C>) -> Self {
644 match wpa {
645 Wpa::Wpa1 { .. } => fidl_security::Protocol::Wpa1,
646 Wpa::Wpa2 { authentication, .. } => match authentication {
647 Authentication::Personal(_) => fidl_security::Protocol::Wpa2Personal,
648 Authentication::Enterprise(_) => fidl_security::Protocol::Wpa2Enterprise,
649 },
650 Wpa::Wpa3 { authentication, .. } => match authentication {
651 Authentication::Personal(_) => fidl_security::Protocol::Wpa3Personal,
652 Authentication::Enterprise(_) => fidl_security::Protocol::Wpa3Enterprise,
653 },
654 }
655 }
656}
657
658pub type WpaDescriptor = Wpa<()>;
664
665impl WpaDescriptor {
666 pub fn bind(self, credentials: BareCredentials) -> Result<WpaAuthenticator, SecurityError> {
667 match credentials {
668 BareCredentials::WpaPassphrase(passphrase) => match self {
669 WpaDescriptor::Wpa1 { .. } => {
670 Ok(WpaAuthenticator::Wpa1 { credentials: passphrase.into() })
671 }
672 WpaDescriptor::Wpa2 { cipher, authentication } => Ok(WpaAuthenticator::Wpa2 {
673 cipher,
674 authentication: match authentication {
675 Authentication::Personal(_) => {
676 Ok(Authentication::Personal(passphrase.into()))
677 }
678 Authentication::Enterprise(_) => Err(SecurityError::Unsupported),
679 }?,
680 }),
681 WpaDescriptor::Wpa3 { cipher, authentication } => Ok(WpaAuthenticator::Wpa3 {
682 cipher,
683 authentication: match authentication {
684 Authentication::Personal(_) => {
685 Ok(Authentication::Personal(passphrase.into()))
686 }
687 Authentication::Enterprise(_) => Err(SecurityError::Unsupported),
688 }?,
689 }),
690 },
691 BareCredentials::WpaPsk(psk) => match self {
692 WpaDescriptor::Wpa1 { .. } => {
693 Ok(WpaAuthenticator::Wpa1 { credentials: psk.into() })
694 }
695 WpaDescriptor::Wpa2 { cipher, authentication } => Ok(WpaAuthenticator::Wpa2 {
696 cipher,
697 authentication: match authentication {
698 Authentication::Personal(_) => Ok(Authentication::Personal(psk.into())),
699 Authentication::Enterprise(_) => Err(SecurityError::Unsupported),
700 }?,
701 }),
702 WpaDescriptor::Wpa3 { .. } => Err(SecurityError::Incompatible),
703 },
704 _ => Err(SecurityError::Incompatible),
705 }
706 }
707}
708
709impl Hash for WpaDescriptor {
710 fn hash<H>(&self, state: &mut H)
711 where
712 H: Hasher,
713 {
714 match self {
715 WpaDescriptor::Wpa1 { ref credentials } => {
716 credentials.hash(state);
717 }
718 WpaDescriptor::Wpa2 { ref cipher, ref authentication } => {
719 cipher.hash(state);
720 authentication.hash(state);
721 }
722 WpaDescriptor::Wpa3 { ref cipher, ref authentication } => {
723 cipher.hash(state);
724 authentication.hash(state);
725 }
726 }
727 }
728}
729
730pub type WpaAuthenticator = Wpa<AuthenticatorData>;
735
736impl WpaAuthenticator {
737 pub fn into_credentials(self) -> Credentials {
746 match self {
747 Wpa::Wpa1 { credentials } => Authentication::Personal(credentials.into()),
748 Wpa::Wpa2 { authentication, .. } => authentication.into_credentials(),
749 Wpa::Wpa3 { authentication, .. } => authentication.into_credentials(),
750 }
751 }
752
753 pub fn to_credentials(&self) -> Credentials {
754 match self {
755 Wpa::Wpa1 { ref credentials } => Authentication::Personal(credentials.clone().into()),
756 Wpa::Wpa2 { ref authentication, .. } => authentication.clone().into_credentials(),
757 Wpa::Wpa3 { ref authentication, .. } => authentication.clone().into_credentials(),
758 }
759 }
760}
761
762#[cfg(test)]
763mod tests {
764 use fidl_fuchsia_wlan_common_security as fidl_security;
765
766 use test_case::test_case;
767
768 use crate::security::wep::{WepKey, WEP40_KEY_BYTES};
769 use crate::security::wpa::credential::{Passphrase, Psk, PSK_SIZE_BYTES};
770 use crate::security::wpa::{self};
771 use crate::security::{BareCredentials, SecurityError};
772
773 fn wep_key() -> WepKey {
774 [170u8; WEP40_KEY_BYTES].into()
775 }
776
777 fn wpa_psk() -> Psk {
778 [170u8; PSK_SIZE_BYTES].into()
779 }
780
781 fn wpa_passphrase() -> Passphrase {
782 Passphrase::try_from("password").unwrap()
783 }
784
785 trait PersonalCredentialsTestCase: Sized {
786 fn psk() -> Self;
787 fn passphrase() -> Self;
788 }
789
790 impl PersonalCredentialsTestCase for wpa::PersonalCredentials {
791 fn psk() -> Self {
792 wpa::PersonalCredentials::Psk(wpa_psk())
793 }
794
795 fn passphrase() -> Self {
796 wpa::PersonalCredentials::Passphrase(wpa_passphrase())
797 }
798 }
799
800 trait WpaCredentialsTestCase: Sized {
801 fn psk() -> Self;
802 fn passphrase() -> Self;
803 }
804
805 impl WpaCredentialsTestCase for fidl_security::WpaCredentials {
806 fn psk() -> Self {
807 fidl_security::WpaCredentials::Psk(wpa_psk().0)
808 }
809
810 fn passphrase() -> Self {
811 fidl_security::WpaCredentials::Passphrase(wpa_passphrase().into())
812 }
813 }
814
815 trait BareCredentialsTestCase: Sized {
816 fn wep_key() -> Self;
817 fn psk() -> Self;
818 fn passphrase() -> Self;
819 }
820
821 impl BareCredentialsTestCase for BareCredentials {
822 fn wep_key() -> Self {
823 BareCredentials::WepKey(wep_key())
824 }
825
826 fn psk() -> Self {
827 BareCredentials::WpaPsk(wpa_psk())
828 }
829
830 fn passphrase() -> Self {
831 BareCredentials::WpaPassphrase(wpa_passphrase())
832 }
833 }
834
835 trait WpaDescriptorTestCase: Sized {
836 const WPA1: Self;
837 const WPA2_PERSONAL: Self;
838 const WPA3_PERSONAL: Self;
839 }
840
841 impl WpaDescriptorTestCase for wpa::WpaDescriptor {
842 const WPA1: Self = wpa::WpaDescriptor::Wpa1 { credentials: () };
843 const WPA2_PERSONAL: Self = wpa::WpaDescriptor::Wpa2 {
844 cipher: None,
845 authentication: wpa::Authentication::Personal(()),
846 };
847 const WPA3_PERSONAL: Self = wpa::WpaDescriptor::Wpa3 {
848 cipher: None,
849 authentication: wpa::Authentication::Personal(()),
850 };
851 }
852
853 #[test_case(WpaCredentialsTestCase::psk() => matches Ok(wpa::Wpa1Credentials::Psk(_)))]
854 #[test_case(WpaCredentialsTestCase::passphrase() => matches
855 Ok(wpa::Wpa1Credentials::Passphrase(_))
856 )]
857 fn wpa1_credentials_from_credentials_fidl(
858 credentials: fidl_security::WpaCredentials,
859 ) -> Result<wpa::Wpa1Credentials, SecurityError> {
860 credentials.try_into()
861 }
862
863 #[test_case(WpaCredentialsTestCase::psk() => matches Ok(wpa::Wpa2PersonalCredentials::Psk(_)))]
864 #[test_case(WpaCredentialsTestCase::passphrase() => matches
865 Ok(wpa::Wpa2PersonalCredentials::Passphrase(_))
866 )]
867 fn wpa2_personal_credentials_from_credentials_fidl(
868 credentials: fidl_security::WpaCredentials,
869 ) -> Result<wpa::Wpa2PersonalCredentials, SecurityError> {
870 credentials.try_into()
871 }
872
873 #[test_case(WpaCredentialsTestCase::psk() => Err(SecurityError::Incompatible))]
874 #[test_case(WpaCredentialsTestCase::passphrase() => matches
875 Ok(wpa::Wpa3PersonalCredentials::Passphrase(_))
876 )]
877 fn wpa3_personal_credentials_from_credentials_fidl(
878 credentials: fidl_security::WpaCredentials,
879 ) -> Result<wpa::Wpa3PersonalCredentials, SecurityError> {
880 credentials.try_into()
881 }
882
883 #[test_case(PersonalCredentialsTestCase::psk() => matches Ok(wpa::Wpa1Credentials::Psk(_)))]
884 #[test_case(PersonalCredentialsTestCase::passphrase() => matches
885 Ok(wpa::Wpa1Credentials::Passphrase(_))
886 )]
887 fn wpa1_personal_credentials_from_personal_credentials(
888 credentials: wpa::PersonalCredentials,
889 ) -> Result<wpa::Wpa1Credentials, SecurityError> {
890 credentials.try_into()
891 }
892
893 #[test_case(PersonalCredentialsTestCase::psk() => Err(SecurityError::Incompatible))]
894 #[test_case(PersonalCredentialsTestCase::passphrase() => matches
895 Ok(wpa::Wpa3PersonalCredentials::Passphrase(_))
896 )]
897 fn wpa3_personal_credentials_from_personal_credentials(
898 credentials: wpa::PersonalCredentials,
899 ) -> Result<wpa::Wpa3PersonalCredentials, SecurityError> {
900 credentials.try_into()
901 }
902
903 #[test_case(wpa::Cipher::TKIP => Ok(wpa::Wpa2Cipher::TKIP))]
904 #[test_case(wpa::Cipher::CCMP => Ok(wpa::Wpa2Cipher::CCMP))]
905 #[test_case(wpa::Cipher::GCMP => Err(SecurityError::Incompatible))]
906 fn wpa2_cipher_from_cipher(cipher: wpa::Cipher) -> Result<wpa::Wpa2Cipher, SecurityError> {
907 cipher.try_into()
908 }
909
910 #[test_case(wpa::Cipher::TKIP => Err(SecurityError::Incompatible))]
911 #[test_case(wpa::Cipher::CCMP => Ok(wpa::Wpa3Cipher::CCMP))]
912 #[test_case(wpa::Cipher::GCMP => Ok(wpa::Wpa3Cipher::GCMP))]
913 fn wpa3_cipher_from_cipher(cipher: wpa::Cipher) -> Result<wpa::Wpa3Cipher, SecurityError> {
914 cipher.try_into()
915 }
916
917 #[test_case(WpaDescriptorTestCase::WPA1, BareCredentialsTestCase::psk() =>
918 Ok(wpa::WpaAuthenticator::Wpa1 {
919 credentials: wpa::Wpa1Credentials::Psk(wpa_psk()),
920 })
921 )]
922 #[test_case(WpaDescriptorTestCase::WPA2_PERSONAL, BareCredentialsTestCase::psk() =>
923 Ok(wpa::WpaAuthenticator::Wpa2 {
924 cipher: None,
925 authentication: wpa::Authentication::Personal(
926 wpa::Wpa2PersonalCredentials::Psk(wpa_psk())
927 ),
928 })
929 )]
930 #[test_case(WpaDescriptorTestCase::WPA3_PERSONAL, BareCredentialsTestCase::passphrase() =>
931 Ok(wpa::WpaAuthenticator::Wpa3 {
932 cipher: None,
933 authentication: wpa::Authentication::Personal(
934 wpa::Wpa3PersonalCredentials::Passphrase(wpa_passphrase())
935 ),
936 })
937 )]
938 #[test_case(WpaDescriptorTestCase::WPA2_PERSONAL, BareCredentialsTestCase::wep_key() =>
939 Err(SecurityError::Incompatible)
940 )]
941 #[test_case(WpaDescriptorTestCase::WPA3_PERSONAL, BareCredentialsTestCase::psk() =>
942 Err(SecurityError::Incompatible)
943 )]
944 fn wpa_bind_descriptor(
945 descriptor: wpa::WpaDescriptor,
946 credentials: BareCredentials,
947 ) -> Result<wpa::WpaAuthenticator, SecurityError> {
948 descriptor.bind(credentials)
949 }
950}