1#[cfg(feature = "default-resolver")]
5mod default;
6#[cfg(feature = "libsodium-resolver")]
8mod libsodium;
9#[cfg(feature = "ring-resolver")]
11mod ring;
12
13#[cfg(feature = "hfs")]
14use crate::params::KemChoice;
15#[cfg(feature = "hfs")]
16use crate::types::Kem;
17use crate::{
18 params::{CipherChoice, DHChoice, HashChoice},
19 types::{Cipher, Dh, Hash, Random},
20};
21
22#[cfg(feature = "default-resolver")]
23pub use self::default::DefaultResolver;
24#[cfg(feature = "libsodium-resolver")]
25pub use self::libsodium::SodiumResolver;
26#[cfg(feature = "ring-resolver")]
27pub use self::ring::RingResolver;
28
29pub type BoxedCryptoResolver = Box<dyn CryptoResolver + Send>;
31
32pub trait CryptoResolver {
34 fn resolve_rng(&self) -> Option<Box<dyn Random>>;
36
37 fn resolve_dh(&self, choice: &DHChoice) -> Option<Box<dyn Dh>>;
39
40 fn resolve_hash(&self, choice: &HashChoice) -> Option<Box<dyn Hash>>;
42
43 fn resolve_cipher(&self, choice: &CipherChoice) -> Option<Box<dyn Cipher>>;
45
46 #[cfg(feature = "hfs")]
48 fn resolve_kem(&self, _choice: &KemChoice) -> Option<Box<dyn Kem>> {
49 None
50 }
51}
52
53pub struct FallbackResolver {
57 preferred: BoxedCryptoResolver,
58 fallback: BoxedCryptoResolver,
59}
60
61impl FallbackResolver {
62 pub fn new(preferred: BoxedCryptoResolver, fallback: BoxedCryptoResolver) -> Self {
64 Self { preferred, fallback }
65 }
66}
67
68impl CryptoResolver for FallbackResolver {
69 fn resolve_rng(&self) -> Option<Box<dyn Random>> {
70 self.preferred.resolve_rng().or_else(|| self.fallback.resolve_rng())
71 }
72
73 fn resolve_dh(&self, choice: &DHChoice) -> Option<Box<dyn Dh>> {
74 self.preferred.resolve_dh(choice).or_else(|| self.fallback.resolve_dh(choice))
75 }
76
77 fn resolve_hash(&self, choice: &HashChoice) -> Option<Box<dyn Hash>> {
78 self.preferred.resolve_hash(choice).or_else(|| self.fallback.resolve_hash(choice))
79 }
80
81 fn resolve_cipher(&self, choice: &CipherChoice) -> Option<Box<dyn Cipher>> {
82 self.preferred.resolve_cipher(choice).or_else(|| self.fallback.resolve_cipher(choice))
83 }
84
85 #[cfg(feature = "hfs")]
86 fn resolve_kem(&self, choice: &KemChoice) -> Option<Box<dyn Kem>> {
87 self.preferred.resolve_kem(choice).or_else(|| self.fallback.resolve_kem(choice))
88 }
89}