1use crate::binding::MAX_DEFLATE_RAW_DECODE_BYTES;
2use crate::constants::MessageSignatureOrder;
3use crate::entity::SignatureConfig;
4use crate::error::SamlError;
5use crate::template::LoginResponseTemplate;
6use crate::xml::XmlLimits;
7
8use super::algorithms::{
9 DataEncryptionAlgorithm, KeyEncryptionAlgorithm, SignatureAlgorithm, TransformAlgorithm,
10};
11
12#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
14pub enum AssertionSignaturePolicy {
15 RequireSigned,
17 #[default]
19 AllowUnsignedForCompatibility,
20}
21
22#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
24pub enum MessageSignaturePolicy {
25 RequireSigned,
27 #[default]
29 AllowUnsignedForCompatibility,
30}
31
32#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
34pub enum AuthnRequestSigningPolicy {
35 Sign,
37 #[default]
39 DoNotSignForCompatibility,
40}
41
42#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
44pub enum AuthnRequestValidationPolicy {
45 RequireSigned,
47 #[default]
49 AllowUnsignedForCompatibility,
50}
51
52#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
54pub enum LogoutSignaturePolicy {
55 #[default]
57 RequireSigned,
58 AllowUnsignedForCompatibility,
60}
61
62#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
64pub enum AudienceValidationPolicy {
65 #[default]
67 Validate,
68 SkipForCompatibility,
70}
71
72#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
74pub enum NameIdCreationPolicy {
75 AllowCreate,
77 #[default]
79 DoNotAllowCreate,
80}
81
82#[derive(Debug, Clone, PartialEq, Eq)]
84pub struct SpValidationPolicy {
85 pub assertions: AssertionSignaturePolicy,
87 pub messages: MessageSignaturePolicy,
89 pub authn_requests: AuthnRequestSigningPolicy,
91 pub audience: AudienceValidationPolicy,
93 pub name_id_creation: NameIdCreationPolicy,
95 pub logout: LogoutPolicy,
97}
98
99impl SpValidationPolicy {
100 pub fn strict() -> Self {
102 Self {
103 assertions: AssertionSignaturePolicy::RequireSigned,
104 messages: MessageSignaturePolicy::RequireSigned,
105 authn_requests: AuthnRequestSigningPolicy::Sign,
106 audience: AudienceValidationPolicy::Validate,
107 name_id_creation: NameIdCreationPolicy::DoNotAllowCreate,
108 logout: LogoutPolicy::strict(),
109 }
110 }
111
112 pub fn compatibility() -> Self {
114 Self {
115 assertions: AssertionSignaturePolicy::AllowUnsignedForCompatibility,
116 messages: MessageSignaturePolicy::AllowUnsignedForCompatibility,
117 authn_requests: AuthnRequestSigningPolicy::DoNotSignForCompatibility,
118 audience: AudienceValidationPolicy::SkipForCompatibility,
119 name_id_creation: NameIdCreationPolicy::DoNotAllowCreate,
120 logout: LogoutPolicy::compatibility(),
121 }
122 }
123}
124
125impl Default for SpValidationPolicy {
126 fn default() -> Self {
127 Self::compatibility()
128 }
129}
130
131#[derive(Debug, Clone, PartialEq, Eq)]
133pub struct IdpValidationPolicy {
134 pub authn_requests: AuthnRequestValidationPolicy,
136 pub logout: LogoutPolicy,
138}
139
140impl IdpValidationPolicy {
141 pub fn strict() -> Self {
143 Self {
144 authn_requests: AuthnRequestValidationPolicy::RequireSigned,
145 logout: LogoutPolicy::strict(),
146 }
147 }
148
149 pub fn compatibility() -> Self {
151 Self {
152 authn_requests: AuthnRequestValidationPolicy::AllowUnsignedForCompatibility,
153 logout: LogoutPolicy::compatibility(),
154 }
155 }
156}
157
158impl Default for IdpValidationPolicy {
159 fn default() -> Self {
160 Self::compatibility()
161 }
162}
163
164#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
166pub struct LogoutPolicy {
167 pub requests: LogoutSignaturePolicy,
169 pub responses: LogoutSignaturePolicy,
171}
172
173impl LogoutPolicy {
174 pub fn strict() -> Self {
176 Self {
177 requests: LogoutSignaturePolicy::RequireSigned,
178 responses: LogoutSignaturePolicy::RequireSigned,
179 }
180 }
181
182 pub fn compatibility() -> Self {
184 Self {
185 requests: LogoutSignaturePolicy::AllowUnsignedForCompatibility,
186 responses: LogoutSignaturePolicy::AllowUnsignedForCompatibility,
187 }
188 }
189}
190
191#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
193pub enum AssertionEncryptionPolicy {
194 #[default]
196 PlaintextAssertions,
197 EncryptAssertions,
199}
200
201#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
223pub struct XmlEncryptionPolicy {
224 pub assertions: AssertionEncryptionPolicy,
226 allow_insecure_software_rsa_key_transport_decryption: bool,
227}
228
229impl XmlEncryptionPolicy {
230 pub fn encrypt_assertions() -> Self {
232 Self {
233 assertions: AssertionEncryptionPolicy::EncryptAssertions,
234 ..Self::default()
235 }
236 }
237
238 pub fn allow_insecure_software_rsa_key_transport_decryption() -> Self {
241 Self {
242 allow_insecure_software_rsa_key_transport_decryption: true,
243 ..Self::default()
244 }
245 }
246
247 pub fn with_insecure_software_rsa_key_transport_decryption_allowed(mut self) -> Self {
249 self.allow_insecure_software_rsa_key_transport_decryption = true;
250 self
251 }
252
253 pub(super) fn allows_insecure_software_rsa_key_transport_decryption(self) -> bool {
254 self.allow_insecure_software_rsa_key_transport_decryption
255 }
256}
257
258#[derive(Debug, Clone, Copy, PartialEq, Eq)]
282pub struct XmlPolicy {
283 pub clock_drifts: (i64, i64),
285 pub redirect_inflate_max_bytes: usize,
288 pub limits: XmlLimits,
290 pub encryption: XmlEncryptionPolicy,
292}
293
294impl Default for XmlPolicy {
295 fn default() -> Self {
296 Self {
297 clock_drifts: (0, 0),
298 redirect_inflate_max_bytes: MAX_DEFLATE_RAW_DECODE_BYTES,
299 limits: XmlLimits::default(),
300 encryption: XmlEncryptionPolicy::default(),
301 }
302 }
303}
304
305#[derive(Debug, Clone, PartialEq, Eq)]
307pub struct AlgorithmPolicy {
308 pub signature: SignatureAlgorithm,
310 pub data_encryption: DataEncryptionAlgorithm,
312 pub key_encryption: KeyEncryptionAlgorithm,
314 pub message_signing_order: MessageSignatureOrder,
316 pub signed_reference_transforms: Vec<TransformAlgorithm>,
318}
319
320impl Default for AlgorithmPolicy {
321 fn default() -> Self {
322 Self {
323 signature: SignatureAlgorithm::default(),
324 data_encryption: DataEncryptionAlgorithm::default(),
325 key_encryption: KeyEncryptionAlgorithm::default(),
326 message_signing_order: MessageSignatureOrder::SignThenEncrypt,
327 signed_reference_transforms: vec![
328 TransformAlgorithm::EnvelopedSignature,
329 TransformAlgorithm::ExclusiveCanonicalization,
330 ],
331 }
332 }
333}
334
335#[derive(Debug, Clone)]
337pub struct TemplatePolicy {
338 pub relay_state: String,
340 pub tag_prefix_protocol: String,
342 pub tag_prefix_assertion: String,
344 pub tag_prefix_encrypted_assertion: String,
346 pub login_response_template: Option<LoginResponseTemplate>,
348 pub login_request_template: Option<String>,
350 pub logout_request_template: Option<String>,
352 pub logout_response_template: Option<String>,
354 pub signature_config: Option<SignatureConfig>,
356}
357
358impl Default for TemplatePolicy {
359 fn default() -> Self {
360 Self {
361 relay_state: String::new(),
362 tag_prefix_protocol: "samlp".to_string(),
363 tag_prefix_assertion: "saml".to_string(),
364 tag_prefix_encrypted_assertion: "saml".to_string(),
365 login_response_template: None,
366 login_request_template: None,
367 logout_request_template: None,
368 logout_response_template: None,
369 signature_config: None,
370 }
371 }
372}
373pub(super) fn authn_request_signing_enabled(policy: AuthnRequestSigningPolicy) -> bool {
374 matches!(policy, AuthnRequestSigningPolicy::Sign)
375}
376
377pub(super) fn authn_request_signature_required(policy: AuthnRequestValidationPolicy) -> bool {
378 matches!(policy, AuthnRequestValidationPolicy::RequireSigned)
379}
380
381pub(super) fn assertion_signature_required(policy: AssertionSignaturePolicy) -> bool {
382 matches!(policy, AssertionSignaturePolicy::RequireSigned)
383}
384
385pub(super) fn message_signature_required(policy: MessageSignaturePolicy) -> bool {
386 matches!(policy, MessageSignaturePolicy::RequireSigned)
387}
388
389pub(super) fn logout_signature_required(policy: LogoutSignaturePolicy) -> Result<bool, SamlError> {
390 match policy {
391 LogoutSignaturePolicy::RequireSigned => Ok(true),
392 LogoutSignaturePolicy::AllowUnsignedForCompatibility => Ok(false),
393 }
394}
395pub(super) fn name_id_creation_allowed(policy: NameIdCreationPolicy) -> bool {
396 matches!(policy, NameIdCreationPolicy::AllowCreate)
397}
398
399pub(super) fn audience_validation_enabled(policy: AudienceValidationPolicy) -> bool {
400 matches!(policy, AudienceValidationPolicy::Validate)
401}