1use openauth_core::error::OpenAuthError;
2use quick_xml::events::{BytesStart, Event};
3use quick_xml::Reader;
4use time::{Duration, OffsetDateTime};
5
6use super::xml::{local_name, validate_saml_xml};
7
8#[derive(Debug, Clone, PartialEq, Eq)]
9pub struct SamlConditions {
10 pub not_before: Option<String>,
11 pub not_on_or_after: Option<String>,
12}
13
14#[derive(Debug, Clone, Copy, PartialEq, Eq)]
15pub struct TimestampValidationOptions {
16 pub clock_skew: Duration,
17 pub require_timestamps: bool,
18}
19
20impl Default for TimestampValidationOptions {
21 fn default() -> Self {
22 Self {
23 clock_skew: Duration::minutes(5),
24 require_timestamps: false,
25 }
26 }
27}
28
29#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
30pub enum SamlSecurityError {
31 #[error("SAML assertion missing required timestamp conditions")]
32 MissingTimestampConditions,
33 #[error("SAML assertion has invalid NotBefore timestamp")]
34 InvalidNotBefore,
35 #[error("SAML assertion has invalid NotOnOrAfter timestamp")]
36 InvalidNotOnOrAfter,
37 #[error("SAML assertion is not yet valid")]
38 NotYetValid,
39 #[error("SAML assertion has expired")]
40 Expired,
41 #[error("SAML signature algorithm not recognized: {0}")]
42 UnknownSignatureAlgorithm(String),
43 #[error("SAML digest algorithm not recognized: {0}")]
44 UnknownDigestAlgorithm(String),
45 #[error("SAML signature algorithm is deprecated: {0}")]
46 DeprecatedSignatureAlgorithm(String),
47 #[error("SAML digest algorithm is deprecated: {0}")]
48 DeprecatedDigestAlgorithm(String),
49 #[error("SAML signature algorithm not in allow-list: {0}")]
50 SignatureAlgorithmNotAllowed(String),
51 #[error("SAML digest algorithm not in allow-list: {0}")]
52 DigestAlgorithmNotAllowed(String),
53 #[error("SAML key encryption algorithm not recognized: {0}")]
54 UnknownKeyEncryptionAlgorithm(String),
55 #[error("SAML data encryption algorithm not recognized: {0}")]
56 UnknownDataEncryptionAlgorithm(String),
57 #[error("SAML key encryption algorithm is deprecated: {0}")]
58 DeprecatedKeyEncryptionAlgorithm(String),
59 #[error("SAML data encryption algorithm is deprecated: {0}")]
60 DeprecatedDataEncryptionAlgorithm(String),
61 #[error("SAML key encryption algorithm not in allow-list: {0}")]
62 KeyEncryptionAlgorithmNotAllowed(String),
63 #[error("SAML data encryption algorithm not in allow-list: {0}")]
64 DataEncryptionAlgorithmNotAllowed(String),
65}
66
67pub fn validate_saml_timestamp(
68 conditions: Option<&SamlConditions>,
69 options: TimestampValidationOptions,
70) -> Result<(), SamlSecurityError> {
71 let has_timestamps = conditions.is_some_and(|conditions| {
72 conditions.not_before.is_some() || conditions.not_on_or_after.is_some()
73 });
74 if !has_timestamps {
75 return if options.require_timestamps {
76 Err(SamlSecurityError::MissingTimestampConditions)
77 } else {
78 Ok(())
79 };
80 }
81
82 let Some(conditions) = conditions else {
83 return if options.require_timestamps {
84 Err(SamlSecurityError::MissingTimestampConditions)
85 } else {
86 Ok(())
87 };
88 };
89 let now = OffsetDateTime::now_utc();
90
91 if let Some(not_before) = &conditions.not_before {
92 let parsed =
93 OffsetDateTime::parse(not_before, &time::format_description::well_known::Rfc3339)
94 .map_err(|_| SamlSecurityError::InvalidNotBefore)?;
95 if now < parsed - options.clock_skew {
96 return Err(SamlSecurityError::NotYetValid);
97 }
98 }
99
100 if let Some(not_on_or_after) = &conditions.not_on_or_after {
101 let parsed = OffsetDateTime::parse(
102 not_on_or_after,
103 &time::format_description::well_known::Rfc3339,
104 )
105 .map_err(|_| SamlSecurityError::InvalidNotOnOrAfter)?;
106 if now > parsed + options.clock_skew {
107 return Err(SamlSecurityError::Expired);
108 }
109 }
110
111 Ok(())
112}
113
114#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
115#[serde(rename_all = "camelCase")]
116pub enum DeprecatedAlgorithmBehavior {
117 Reject,
118 Warn,
119 Allow,
120}
121
122#[derive(Debug, Clone, Copy, PartialEq, Eq)]
123pub enum SignatureAlgorithm {
124 RsaSha1,
125 RsaSha256,
126 RsaSha384,
127 RsaSha512,
128 EcdsaSha256,
129 EcdsaSha384,
130 EcdsaSha512,
131}
132
133impl SignatureAlgorithm {
134 pub fn as_uri(self) -> &'static str {
135 match self {
136 Self::RsaSha1 => "http://www.w3.org/2000/09/xmldsig#rsa-sha1",
137 Self::RsaSha256 => "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256",
138 Self::RsaSha384 => "http://www.w3.org/2001/04/xmldsig-more#rsa-sha384",
139 Self::RsaSha512 => "http://www.w3.org/2001/04/xmldsig-more#rsa-sha512",
140 Self::EcdsaSha256 => "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256",
141 Self::EcdsaSha384 => "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha384",
142 Self::EcdsaSha512 => "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha512",
143 }
144 }
145}
146
147pub fn validate_saml_config_algorithms(
148 signature_algorithm: Option<&str>,
149 digest_algorithm: Option<&str>,
150) -> Result<(), SamlSecurityError> {
151 validate_saml_config_algorithms_with_policy(
152 signature_algorithm,
153 digest_algorithm,
154 DeprecatedAlgorithmBehavior::Warn,
155 None,
156 None,
157 )
158}
159
160pub fn validate_saml_config_algorithms_with_policy(
161 signature_algorithm: Option<&str>,
162 digest_algorithm: Option<&str>,
163 on_deprecated: DeprecatedAlgorithmBehavior,
164 allowed_signature_algorithms: Option<&[String]>,
165 allowed_digest_algorithms: Option<&[String]>,
166) -> Result<(), SamlSecurityError> {
167 if let Some(algorithm) = signature_algorithm {
168 let normalized = normalize_signature_algorithm(algorithm);
169 if let Some(allowed) = allowed_signature_algorithms {
170 let is_allowed = allowed
171 .iter()
172 .map(|algorithm| normalize_signature_algorithm(algorithm))
173 .any(|allowed| allowed == normalized);
174 if !is_allowed {
175 return Err(SamlSecurityError::SignatureAlgorithmNotAllowed(
176 algorithm.to_owned(),
177 ));
178 }
179 } else if is_deprecated_signature_algorithm(&normalized)
180 && on_deprecated == DeprecatedAlgorithmBehavior::Reject
181 {
182 return Err(SamlSecurityError::DeprecatedSignatureAlgorithm(
183 algorithm.to_owned(),
184 ));
185 } else if !is_known_signature_algorithm(&normalized) {
186 return Err(SamlSecurityError::UnknownSignatureAlgorithm(
187 algorithm.to_owned(),
188 ));
189 }
190 }
191 if let Some(algorithm) = digest_algorithm {
192 let normalized = normalize_digest_algorithm(algorithm);
193 if let Some(allowed) = allowed_digest_algorithms {
194 let is_allowed = allowed
195 .iter()
196 .map(|algorithm| normalize_digest_algorithm(algorithm))
197 .any(|allowed| allowed == normalized);
198 if !is_allowed {
199 return Err(SamlSecurityError::DigestAlgorithmNotAllowed(
200 algorithm.to_owned(),
201 ));
202 }
203 } else if is_deprecated_digest_algorithm(&normalized)
204 && on_deprecated == DeprecatedAlgorithmBehavior::Reject
205 {
206 return Err(SamlSecurityError::DeprecatedDigestAlgorithm(
207 algorithm.to_owned(),
208 ));
209 } else if !is_known_digest_algorithm(&normalized) {
210 return Err(SamlSecurityError::UnknownDigestAlgorithm(
211 algorithm.to_owned(),
212 ));
213 }
214 }
215 Ok(())
216}
217
218#[derive(Debug, Clone, Default, PartialEq, Eq)]
219pub struct SamlRuntimeAlgorithms {
220 pub signature_algorithms: Vec<String>,
221 pub digest_algorithms: Vec<String>,
222 pub key_encryption_algorithms: Vec<String>,
223 pub data_encryption_algorithms: Vec<String>,
224}
225
226#[derive(Debug, Clone, Copy, PartialEq, Eq)]
227pub struct SamlRuntimeAlgorithmPolicy<'a> {
228 pub on_deprecated: DeprecatedAlgorithmBehavior,
229 pub allowed_signature_algorithms: Option<&'a [String]>,
230 pub allowed_digest_algorithms: Option<&'a [String]>,
231 pub allowed_key_encryption_algorithms: Option<&'a [String]>,
232 pub allowed_data_encryption_algorithms: Option<&'a [String]>,
233}
234
235impl Default for SamlRuntimeAlgorithmPolicy<'_> {
236 fn default() -> Self {
237 Self {
238 on_deprecated: DeprecatedAlgorithmBehavior::Warn,
239 allowed_signature_algorithms: None,
240 allowed_digest_algorithms: None,
241 allowed_key_encryption_algorithms: None,
242 allowed_data_encryption_algorithms: None,
243 }
244 }
245}
246
247pub fn collect_saml_runtime_algorithms(xml: &str) -> Result<SamlRuntimeAlgorithms, OpenAuthError> {
248 validate_saml_xml(xml)?;
249
250 let mut reader = Reader::from_str(xml);
251 reader.config_mut().trim_text(true);
252 let mut stack = Vec::new();
253 let mut algorithms = SamlRuntimeAlgorithms::default();
254
255 loop {
256 match reader.read_event() {
257 Ok(Event::Start(element)) => {
258 let name = local_name(element.name().as_ref())?;
259 collect_algorithm(&reader, &element, &name, &stack, &mut algorithms)?;
260 stack.push(name);
261 }
262 Ok(Event::Empty(element)) => {
263 let name = local_name(element.name().as_ref())?;
264 collect_algorithm(&reader, &element, &name, &stack, &mut algorithms)?;
265 }
266 Ok(Event::End(_)) => {
267 stack.pop();
268 }
269 Ok(Event::Eof) => break,
270 Err(error) => return Err(OpenAuthError::Api(format!("Invalid SAML XML: {error}"))),
271 Ok(_) => {}
272 }
273 }
274
275 Ok(algorithms)
276}
277
278pub fn validate_saml_runtime_algorithms(
279 algorithms: &SamlRuntimeAlgorithms,
280 policy: SamlRuntimeAlgorithmPolicy<'_>,
281) -> Result<(), SamlSecurityError> {
282 for algorithm in &algorithms.signature_algorithms {
283 validate_signature_algorithm(
284 algorithm,
285 policy.on_deprecated,
286 policy.allowed_signature_algorithms,
287 )?;
288 }
289 for algorithm in &algorithms.digest_algorithms {
290 validate_digest_algorithm(
291 algorithm,
292 policy.on_deprecated,
293 policy.allowed_digest_algorithms,
294 )?;
295 }
296 for algorithm in &algorithms.key_encryption_algorithms {
297 validate_key_encryption_algorithm(
298 algorithm,
299 policy.on_deprecated,
300 policy.allowed_key_encryption_algorithms,
301 )?;
302 }
303 for algorithm in &algorithms.data_encryption_algorithms {
304 validate_data_encryption_algorithm(
305 algorithm,
306 policy.on_deprecated,
307 policy.allowed_data_encryption_algorithms,
308 )?;
309 }
310 Ok(())
311}
312
313fn collect_algorithm(
314 reader: &Reader<&[u8]>,
315 element: &BytesStart<'_>,
316 name: &str,
317 stack: &[String],
318 algorithms: &mut SamlRuntimeAlgorithms,
319) -> Result<(), OpenAuthError> {
320 let Some(algorithm) = attr(reader, element, "Algorithm")? else {
321 return Ok(());
322 };
323 match name {
324 "SignatureMethod" => algorithms.signature_algorithms.push(algorithm),
325 "DigestMethod" => algorithms.digest_algorithms.push(algorithm),
326 "EncryptionMethod" if stack.iter().any(|item| item == "EncryptedKey") => {
327 algorithms.key_encryption_algorithms.push(algorithm);
328 }
329 "EncryptionMethod" if stack.iter().any(|item| item == "EncryptedData") => {
330 algorithms.data_encryption_algorithms.push(algorithm);
331 }
332 _ => {}
333 }
334 Ok(())
335}
336
337fn attr(
338 reader: &Reader<&[u8]>,
339 element: &BytesStart<'_>,
340 name: &str,
341) -> Result<Option<String>, OpenAuthError> {
342 for attribute in element.attributes() {
343 let attribute = attribute.map_err(|error| OpenAuthError::Api(error.to_string()))?;
344 if local_name(attribute.key.as_ref())? == name {
345 return attribute
346 .decode_and_unescape_value(reader.decoder())
347 .map(|value| Some(value.into_owned()))
348 .map_err(|error| OpenAuthError::Api(error.to_string()));
349 }
350 }
351 Ok(None)
352}
353
354fn normalize_signature_algorithm(algorithm: &str) -> String {
355 match algorithm.to_ascii_lowercase().as_str() {
356 "sha1" | "rsa-sha1" => SignatureAlgorithm::RsaSha1.as_uri().to_owned(),
357 "sha256" | "rsa-sha256" => SignatureAlgorithm::RsaSha256.as_uri().to_owned(),
358 "sha384" | "rsa-sha384" => SignatureAlgorithm::RsaSha384.as_uri().to_owned(),
359 "sha512" | "rsa-sha512" => SignatureAlgorithm::RsaSha512.as_uri().to_owned(),
360 "ecdsa-sha256" => SignatureAlgorithm::EcdsaSha256.as_uri().to_owned(),
361 "ecdsa-sha384" => SignatureAlgorithm::EcdsaSha384.as_uri().to_owned(),
362 "ecdsa-sha512" => SignatureAlgorithm::EcdsaSha512.as_uri().to_owned(),
363 _ => algorithm.to_owned(),
364 }
365}
366
367fn normalize_digest_algorithm(algorithm: &str) -> String {
368 match algorithm.to_ascii_lowercase().as_str() {
369 "sha1" => DigestAlgorithm::Sha1.as_uri().to_owned(),
370 "sha256" => DigestAlgorithm::Sha256.as_uri().to_owned(),
371 "sha384" => DigestAlgorithm::Sha384.as_uri().to_owned(),
372 "sha512" => DigestAlgorithm::Sha512.as_uri().to_owned(),
373 _ => algorithm.to_owned(),
374 }
375}
376
377fn normalize_key_encryption_algorithm(algorithm: &str) -> String {
378 match algorithm.to_ascii_lowercase().as_str() {
379 "rsa-1_5" | "rsa1_5" => KeyEncryptionAlgorithm::Rsa15.as_uri().to_owned(),
380 "rsa-oaep" | "rsa-oaep-mgf1p" => KeyEncryptionAlgorithm::RsaOaep.as_uri().to_owned(),
381 "rsa-oaep-sha256" => KeyEncryptionAlgorithm::RsaOaepSha256.as_uri().to_owned(),
382 _ => algorithm.to_owned(),
383 }
384}
385
386fn normalize_data_encryption_algorithm(algorithm: &str) -> String {
387 match algorithm.to_ascii_lowercase().as_str() {
388 "tripledes-cbc" | "3des-cbc" => DataEncryptionAlgorithm::TripleDesCbc.as_uri().to_owned(),
389 "aes128-cbc" => DataEncryptionAlgorithm::Aes128Cbc.as_uri().to_owned(),
390 "aes192-cbc" => DataEncryptionAlgorithm::Aes192Cbc.as_uri().to_owned(),
391 "aes256-cbc" => DataEncryptionAlgorithm::Aes256Cbc.as_uri().to_owned(),
392 "aes128-gcm" => DataEncryptionAlgorithm::Aes128Gcm.as_uri().to_owned(),
393 "aes192-gcm" => DataEncryptionAlgorithm::Aes192Gcm.as_uri().to_owned(),
394 "aes256-gcm" => DataEncryptionAlgorithm::Aes256Gcm.as_uri().to_owned(),
395 _ => algorithm.to_owned(),
396 }
397}
398
399fn validate_signature_algorithm(
400 algorithm: &str,
401 on_deprecated: DeprecatedAlgorithmBehavior,
402 allowed: Option<&[String]>,
403) -> Result<(), SamlSecurityError> {
404 let normalized = normalize_signature_algorithm(algorithm);
405 if let Some(allowed) = allowed {
406 let is_allowed = allowed
407 .iter()
408 .map(|algorithm| normalize_signature_algorithm(algorithm))
409 .any(|allowed| allowed == normalized);
410 if !is_allowed {
411 return Err(SamlSecurityError::SignatureAlgorithmNotAllowed(
412 algorithm.to_owned(),
413 ));
414 }
415 } else if is_deprecated_signature_algorithm(&normalized)
416 && on_deprecated == DeprecatedAlgorithmBehavior::Reject
417 {
418 return Err(SamlSecurityError::DeprecatedSignatureAlgorithm(
419 algorithm.to_owned(),
420 ));
421 } else if !is_known_signature_algorithm(&normalized) {
422 return Err(SamlSecurityError::UnknownSignatureAlgorithm(
423 algorithm.to_owned(),
424 ));
425 }
426 Ok(())
427}
428
429fn validate_digest_algorithm(
430 algorithm: &str,
431 on_deprecated: DeprecatedAlgorithmBehavior,
432 allowed: Option<&[String]>,
433) -> Result<(), SamlSecurityError> {
434 let normalized = normalize_digest_algorithm(algorithm);
435 if let Some(allowed) = allowed {
436 let is_allowed = allowed
437 .iter()
438 .map(|algorithm| normalize_digest_algorithm(algorithm))
439 .any(|allowed| allowed == normalized);
440 if !is_allowed {
441 return Err(SamlSecurityError::DigestAlgorithmNotAllowed(
442 algorithm.to_owned(),
443 ));
444 }
445 } else if is_deprecated_digest_algorithm(&normalized)
446 && on_deprecated == DeprecatedAlgorithmBehavior::Reject
447 {
448 return Err(SamlSecurityError::DeprecatedDigestAlgorithm(
449 algorithm.to_owned(),
450 ));
451 } else if !is_known_digest_algorithm(&normalized) {
452 return Err(SamlSecurityError::UnknownDigestAlgorithm(
453 algorithm.to_owned(),
454 ));
455 }
456 Ok(())
457}
458
459fn is_known_signature_algorithm(algorithm: &str) -> bool {
460 [
461 SignatureAlgorithm::RsaSha1,
462 SignatureAlgorithm::RsaSha256,
463 SignatureAlgorithm::RsaSha384,
464 SignatureAlgorithm::RsaSha512,
465 SignatureAlgorithm::EcdsaSha256,
466 SignatureAlgorithm::EcdsaSha384,
467 SignatureAlgorithm::EcdsaSha512,
468 ]
469 .into_iter()
470 .any(|known| known.as_uri() == algorithm)
471}
472
473fn is_deprecated_signature_algorithm(algorithm: &str) -> bool {
474 SignatureAlgorithm::RsaSha1.as_uri() == algorithm
475}
476
477fn is_known_digest_algorithm(algorithm: &str) -> bool {
478 [
479 DigestAlgorithm::Sha1,
480 DigestAlgorithm::Sha256,
481 DigestAlgorithm::Sha384,
482 DigestAlgorithm::Sha512,
483 ]
484 .into_iter()
485 .any(|known| known.as_uri() == algorithm)
486}
487
488fn is_deprecated_digest_algorithm(algorithm: &str) -> bool {
489 DigestAlgorithm::Sha1.as_uri() == algorithm
490}
491
492fn validate_key_encryption_algorithm(
493 algorithm: &str,
494 on_deprecated: DeprecatedAlgorithmBehavior,
495 allowed: Option<&[String]>,
496) -> Result<(), SamlSecurityError> {
497 let normalized = normalize_key_encryption_algorithm(algorithm);
498 if let Some(allowed) = allowed {
499 let is_allowed = allowed
500 .iter()
501 .map(|algorithm| normalize_key_encryption_algorithm(algorithm))
502 .any(|allowed| allowed == normalized);
503 if !is_allowed {
504 return Err(SamlSecurityError::KeyEncryptionAlgorithmNotAllowed(
505 algorithm.to_owned(),
506 ));
507 }
508 } else if is_deprecated_key_encryption_algorithm(&normalized)
509 && on_deprecated == DeprecatedAlgorithmBehavior::Reject
510 {
511 return Err(SamlSecurityError::DeprecatedKeyEncryptionAlgorithm(
512 algorithm.to_owned(),
513 ));
514 } else if !is_known_key_encryption_algorithm(&normalized) {
515 return Err(SamlSecurityError::UnknownKeyEncryptionAlgorithm(
516 algorithm.to_owned(),
517 ));
518 }
519 Ok(())
520}
521
522fn validate_data_encryption_algorithm(
523 algorithm: &str,
524 on_deprecated: DeprecatedAlgorithmBehavior,
525 allowed: Option<&[String]>,
526) -> Result<(), SamlSecurityError> {
527 let normalized = normalize_data_encryption_algorithm(algorithm);
528 if let Some(allowed) = allowed {
529 let is_allowed = allowed
530 .iter()
531 .map(|algorithm| normalize_data_encryption_algorithm(algorithm))
532 .any(|allowed| allowed == normalized);
533 if !is_allowed {
534 return Err(SamlSecurityError::DataEncryptionAlgorithmNotAllowed(
535 algorithm.to_owned(),
536 ));
537 }
538 } else if is_deprecated_data_encryption_algorithm(&normalized)
539 && on_deprecated == DeprecatedAlgorithmBehavior::Reject
540 {
541 return Err(SamlSecurityError::DeprecatedDataEncryptionAlgorithm(
542 algorithm.to_owned(),
543 ));
544 } else if !is_known_data_encryption_algorithm(&normalized) {
545 return Err(SamlSecurityError::UnknownDataEncryptionAlgorithm(
546 algorithm.to_owned(),
547 ));
548 }
549 Ok(())
550}
551
552fn is_known_key_encryption_algorithm(algorithm: &str) -> bool {
553 [
554 KeyEncryptionAlgorithm::Rsa15,
555 KeyEncryptionAlgorithm::RsaOaep,
556 KeyEncryptionAlgorithm::RsaOaepSha256,
557 ]
558 .into_iter()
559 .any(|known| known.as_uri() == algorithm)
560}
561
562fn is_deprecated_key_encryption_algorithm(algorithm: &str) -> bool {
563 KeyEncryptionAlgorithm::Rsa15.as_uri() == algorithm
564}
565
566fn is_known_data_encryption_algorithm(algorithm: &str) -> bool {
567 [
568 DataEncryptionAlgorithm::TripleDesCbc,
569 DataEncryptionAlgorithm::Aes128Cbc,
570 DataEncryptionAlgorithm::Aes192Cbc,
571 DataEncryptionAlgorithm::Aes256Cbc,
572 DataEncryptionAlgorithm::Aes128Gcm,
573 DataEncryptionAlgorithm::Aes192Gcm,
574 DataEncryptionAlgorithm::Aes256Gcm,
575 ]
576 .into_iter()
577 .any(|known| known.as_uri() == algorithm)
578}
579
580fn is_deprecated_data_encryption_algorithm(algorithm: &str) -> bool {
581 DataEncryptionAlgorithm::TripleDesCbc.as_uri() == algorithm
582}
583
584#[derive(Debug, Clone, Copy, PartialEq, Eq)]
585pub enum DigestAlgorithm {
586 Sha1,
587 Sha256,
588 Sha384,
589 Sha512,
590}
591
592impl DigestAlgorithm {
593 pub fn as_uri(self) -> &'static str {
594 match self {
595 Self::Sha1 => "http://www.w3.org/2000/09/xmldsig#sha1",
596 Self::Sha256 => "http://www.w3.org/2001/04/xmlenc#sha256",
597 Self::Sha384 => "http://www.w3.org/2001/04/xmldsig-more#sha384",
598 Self::Sha512 => "http://www.w3.org/2001/04/xmlenc#sha512",
599 }
600 }
601}
602
603#[derive(Debug, Clone, Copy, PartialEq, Eq)]
604pub enum KeyEncryptionAlgorithm {
605 Rsa15,
606 RsaOaep,
607 RsaOaepSha256,
608}
609
610impl KeyEncryptionAlgorithm {
611 pub fn as_uri(self) -> &'static str {
612 match self {
613 Self::Rsa15 => "http://www.w3.org/2001/04/xmlenc#rsa-1_5",
614 Self::RsaOaep => "http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p",
615 Self::RsaOaepSha256 => "http://www.w3.org/2009/xmlenc11#rsa-oaep",
616 }
617 }
618}
619
620#[derive(Debug, Clone, Copy, PartialEq, Eq)]
621pub enum DataEncryptionAlgorithm {
622 TripleDesCbc,
623 Aes128Cbc,
624 Aes192Cbc,
625 Aes256Cbc,
626 Aes128Gcm,
627 Aes192Gcm,
628 Aes256Gcm,
629}
630
631impl DataEncryptionAlgorithm {
632 pub fn as_uri(self) -> &'static str {
633 match self {
634 Self::TripleDesCbc => "http://www.w3.org/2001/04/xmlenc#tripledes-cbc",
635 Self::Aes128Cbc => "http://www.w3.org/2001/04/xmlenc#aes128-cbc",
636 Self::Aes192Cbc => "http://www.w3.org/2001/04/xmlenc#aes192-cbc",
637 Self::Aes256Cbc => "http://www.w3.org/2001/04/xmlenc#aes256-cbc",
638 Self::Aes128Gcm => "http://www.w3.org/2009/xmlenc11#aes128-gcm",
639 Self::Aes192Gcm => "http://www.w3.org/2009/xmlenc11#aes192-gcm",
640 Self::Aes256Gcm => "http://www.w3.org/2009/xmlenc11#aes256-gcm",
641 }
642 }
643}