1#![allow(dead_code)]
53
54use crate::encryption::{EncryptionKey, decrypt, encrypt, generate_nonce};
55use blake3::Hasher;
56use rand::RngExt as _;
57use serde::{Deserialize, Serialize};
58use std::collections::{HashMap, HashSet};
59use thiserror::Error;
60
61#[derive(Debug, Error)]
63pub enum AbeError {
64 #[error("Encryption failed: {0}")]
65 EncryptionFailed(String),
66
67 #[error("Decryption failed: {0}")]
68 DecryptionFailed(String),
69
70 #[error("Policy evaluation failed: {0}")]
71 PolicyFailed(String),
72
73 #[error("Invalid attributes: {0}")]
74 InvalidAttributes(String),
75
76 #[error("Key derivation failed: {0}")]
77 KeyDerivationFailed(String),
78
79 #[error("Serialization error: {0}")]
80 SerializationError(String),
81}
82
83pub type AbeResult<T> = Result<T, AbeError>;
85
86#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
88pub enum PolicyNode {
89 Attribute(String),
91 And(Vec<PolicyNode>),
93 Or(Vec<PolicyNode>),
95 Threshold { k: usize, children: Vec<PolicyNode> },
97}
98
99impl PolicyNode {
100 pub fn evaluate(&self, attributes: &HashSet<String>) -> bool {
102 match self {
103 PolicyNode::Attribute(attr) => attributes.contains(attr),
104 PolicyNode::And(children) => children.iter().all(|c| c.evaluate(attributes)),
105 PolicyNode::Or(children) => children.iter().any(|c| c.evaluate(attributes)),
106 PolicyNode::Threshold { k, children } => {
107 let satisfied = children.iter().filter(|c| c.evaluate(attributes)).count();
108 satisfied >= *k
109 }
110 }
111 }
112
113 pub fn get_attributes(&self) -> HashSet<String> {
115 let mut attrs = HashSet::new();
116 self.collect_attributes(&mut attrs);
117 attrs
118 }
119
120 fn collect_attributes(&self, attrs: &mut HashSet<String>) {
121 match self {
122 PolicyNode::Attribute(attr) => {
123 attrs.insert(attr.clone());
124 }
125 PolicyNode::And(children) | PolicyNode::Or(children) => {
126 for child in children {
127 child.collect_attributes(attrs);
128 }
129 }
130 PolicyNode::Threshold { children, .. } => {
131 for child in children {
132 child.collect_attributes(attrs);
133 }
134 }
135 }
136 }
137}
138
139#[derive(Debug, Clone, Serialize, Deserialize)]
141pub struct AccessPolicy {
142 root: PolicyNode,
144}
145
146impl AccessPolicy {
147 pub fn new(root: PolicyNode) -> Self {
149 Self { root }
150 }
151
152 pub fn and(nodes: Vec<PolicyNode>) -> Self {
154 Self::new(PolicyNode::And(nodes))
155 }
156
157 pub fn or(nodes: Vec<PolicyNode>) -> Self {
159 Self::new(PolicyNode::Or(nodes))
160 }
161
162 pub fn threshold(k: usize, children: Vec<PolicyNode>) -> Self {
164 Self::new(PolicyNode::Threshold { k, children })
165 }
166
167 pub fn evaluate(&self, attributes: &HashSet<String>) -> bool {
169 self.root.evaluate(attributes)
170 }
171
172 pub fn get_attributes(&self) -> HashSet<String> {
174 self.root.get_attributes()
175 }
176}
177
178#[derive(Clone)]
180pub struct MasterSecretKey {
181 seed: [u8; 32],
183}
184
185impl MasterSecretKey {
186 fn new() -> Self {
188 let mut seed = [0u8; 32];
189 rand::rng().fill(&mut seed);
190 Self { seed }
191 }
192
193 fn derive_attribute_key(&self, attribute: &str) -> [u8; 32] {
195 let mut hasher = Hasher::new();
196 hasher.update(&self.seed);
197 hasher.update(b"attribute:");
198 hasher.update(attribute.as_bytes());
199 *hasher.finalize().as_bytes()
200 }
201}
202
203#[derive(Clone, Serialize, Deserialize)]
205pub struct UserSecretKey {
206 attribute_keys: HashMap<String, [u8; 32]>,
208}
209
210impl UserSecretKey {
211 fn new(attribute_keys: HashMap<String, [u8; 32]>) -> Self {
213 Self { attribute_keys }
214 }
215
216 pub fn get_attributes(&self) -> HashSet<String> {
218 self.attribute_keys.keys().cloned().collect()
219 }
220
221 pub fn has_attribute(&self, attribute: &str) -> bool {
223 self.attribute_keys.contains_key(attribute)
224 }
225}
226
227#[derive(Clone, Serialize, Deserialize)]
229struct EncryptedDek {
230 ciphertext: Vec<u8>,
232 nonce: [u8; 12],
234}
235
236#[derive(Clone, Serialize, Deserialize)]
238pub struct AbeCiphertext {
239 policy: AccessPolicy,
241 encrypted_keys: HashMap<String, EncryptedDek>,
243 ciphertext: Vec<u8>,
245 nonce: [u8; 12],
247}
248
249impl AbeCiphertext {
250 pub fn policy(&self) -> &AccessPolicy {
252 &self.policy
253 }
254
255 pub fn to_bytes(&self) -> AbeResult<Vec<u8>> {
257 crate::codec::encode(self)
258 .map_err(|e| AbeError::SerializationError(format!("Serialization failed: {}", e)))
259 }
260
261 pub fn from_bytes(bytes: &[u8]) -> AbeResult<Self> {
263 crate::codec::decode(bytes)
264 .map_err(|e| AbeError::SerializationError(format!("Deserialization failed: {}", e)))
265 }
266}
267
268pub struct AbeAuthority {
270 master_key: MasterSecretKey,
272}
273
274impl AbeAuthority {
275 pub fn new() -> Self {
277 Self {
278 master_key: MasterSecretKey::new(),
279 }
280 }
281
282 pub fn from_master_key(seed: [u8; 32]) -> Self {
284 Self {
285 master_key: MasterSecretKey { seed },
286 }
287 }
288
289 pub fn generate_user_key(&self, attributes: &[String]) -> AbeResult<UserSecretKey> {
291 if attributes.is_empty() {
292 return Err(AbeError::InvalidAttributes(
293 "Attributes list cannot be empty".to_string(),
294 ));
295 }
296
297 let mut attribute_keys = HashMap::new();
298 for attr in attributes {
299 let key = self.master_key.derive_attribute_key(attr);
300 attribute_keys.insert(attr.clone(), key);
301 }
302
303 Ok(UserSecretKey::new(attribute_keys))
304 }
305
306 pub fn encrypt(&self, policy: &AccessPolicy, plaintext: &[u8]) -> AbeResult<AbeCiphertext> {
308 let mut dek = [0u8; 32];
310 rand::rng().fill(&mut dek);
311
312 let nonce = generate_nonce();
314
315 let encryption_key = EncryptionKey::from(dek);
317 let ciphertext = encrypt(plaintext, &encryption_key, &nonce)
318 .map_err(|e| AbeError::EncryptionFailed(format!("Failed to encrypt: {}", e)))?;
319
320 let mut encrypted_keys = HashMap::new();
322 for attr in policy.get_attributes() {
323 let attr_key = self.master_key.derive_attribute_key(&attr);
324
325 let attr_enc_key = EncryptionKey::from(attr_key);
327
328 let attr_nonce = generate_nonce();
330
331 let encrypted_dek_bytes = encrypt(&dek, &attr_enc_key, &attr_nonce)
332 .map_err(|e| AbeError::EncryptionFailed(format!("Failed to encrypt DEK: {}", e)))?;
333
334 encrypted_keys.insert(
335 attr,
336 EncryptedDek {
337 ciphertext: encrypted_dek_bytes,
338 nonce: attr_nonce,
339 },
340 );
341 }
342
343 Ok(AbeCiphertext {
344 policy: policy.clone(),
345 encrypted_keys,
346 ciphertext,
347 nonce,
348 })
349 }
350
351 pub fn decrypt(
353 &self,
354 user_key: &UserSecretKey,
355 ciphertext: &AbeCiphertext,
356 ) -> AbeResult<Vec<u8>> {
357 let user_attrs = user_key.get_attributes();
359 if !ciphertext.policy.evaluate(&user_attrs) {
360 return Err(AbeError::DecryptionFailed(
361 "User attributes do not satisfy access policy".to_string(),
362 ));
363 }
364
365 let mut dek = None;
367 for (attr, attr_key) in &user_key.attribute_keys {
368 if let Some(encrypted_dek) = ciphertext.encrypted_keys.get(attr) {
369 let attr_enc_key = EncryptionKey::from(*attr_key);
371
372 let decrypted = decrypt(
374 &encrypted_dek.ciphertext,
375 &attr_enc_key,
376 &encrypted_dek.nonce,
377 );
378
379 if let Ok(dek_bytes) = decrypted {
380 if dek_bytes.len() == 32 {
381 let mut dek_arr = [0u8; 32];
382 dek_arr.copy_from_slice(&dek_bytes);
383 dek = Some(dek_arr);
384 break;
385 }
386 }
387 }
388 }
389
390 let dek = dek.ok_or_else(|| {
391 AbeError::DecryptionFailed("Could not recover data encryption key".to_string())
392 })?;
393
394 let encryption_key = EncryptionKey::from(dek);
396 decrypt(&ciphertext.ciphertext, &encryption_key, &ciphertext.nonce)
397 .map_err(|e| AbeError::DecryptionFailed(format!("Failed to decrypt payload: {}", e)))
398 }
399
400 pub fn export_master_key(&self) -> [u8; 32] {
402 self.master_key.seed
403 }
404}
405
406impl Default for AbeAuthority {
407 fn default() -> Self {
408 Self::new()
409 }
410}
411
412#[cfg(test)]
413mod tests {
414 use super::*;
415
416 #[test]
417 fn test_policy_evaluation_single_attribute() {
418 let policy = PolicyNode::Attribute("admin".to_string());
419
420 let mut attrs = HashSet::new();
421 attrs.insert("admin".to_string());
422 assert!(policy.evaluate(&attrs));
423
424 attrs.clear();
425 attrs.insert("user".to_string());
426 assert!(!policy.evaluate(&attrs));
427 }
428
429 #[test]
430 fn test_policy_evaluation_and() {
431 let policy = PolicyNode::And(vec![
432 PolicyNode::Attribute("admin".to_string()),
433 PolicyNode::Attribute("premium".to_string()),
434 ]);
435
436 let mut attrs = HashSet::new();
437 attrs.insert("admin".to_string());
438 attrs.insert("premium".to_string());
439 assert!(policy.evaluate(&attrs));
440
441 attrs.clear();
442 attrs.insert("admin".to_string());
443 assert!(!policy.evaluate(&attrs));
444 }
445
446 #[test]
447 fn test_policy_evaluation_or() {
448 let policy = PolicyNode::Or(vec![
449 PolicyNode::Attribute("admin".to_string()),
450 PolicyNode::Attribute("moderator".to_string()),
451 ]);
452
453 let mut attrs = HashSet::new();
454 attrs.insert("admin".to_string());
455 assert!(policy.evaluate(&attrs));
456
457 attrs.clear();
458 attrs.insert("moderator".to_string());
459 assert!(policy.evaluate(&attrs));
460
461 attrs.clear();
462 attrs.insert("user".to_string());
463 assert!(!policy.evaluate(&attrs));
464 }
465
466 #[test]
467 fn test_policy_evaluation_threshold() {
468 let policy = PolicyNode::Threshold {
469 k: 2,
470 children: vec![
471 PolicyNode::Attribute("admin".to_string()),
472 PolicyNode::Attribute("moderator".to_string()),
473 PolicyNode::Attribute("premium".to_string()),
474 ],
475 };
476
477 let mut attrs = HashSet::new();
478 attrs.insert("admin".to_string());
479 attrs.insert("moderator".to_string());
480 assert!(policy.evaluate(&attrs));
481
482 attrs.clear();
483 attrs.insert("admin".to_string());
484 assert!(!policy.evaluate(&attrs));
485 }
486
487 #[test]
488 fn test_user_key_generation() {
489 let authority = AbeAuthority::new();
490 let attrs = vec!["admin".to_string(), "premium".to_string()];
491
492 let user_key = authority.generate_user_key(&attrs).unwrap();
493 assert_eq!(user_key.get_attributes().len(), 2);
494 assert!(user_key.has_attribute("admin"));
495 assert!(user_key.has_attribute("premium"));
496 assert!(!user_key.has_attribute("user"));
497 }
498
499 #[test]
500 fn test_encrypt_decrypt_simple() {
501 let authority = AbeAuthority::new();
502
503 let policy = AccessPolicy::new(PolicyNode::Attribute("premium".to_string()));
504 let user_key = authority
505 .generate_user_key(&["premium".to_string()])
506 .unwrap();
507
508 let plaintext = b"Secret premium content";
509 let ciphertext = authority.encrypt(&policy, plaintext).unwrap();
510 let decrypted = authority.decrypt(&user_key, &ciphertext).unwrap();
511
512 assert_eq!(decrypted, plaintext);
513 }
514
515 #[test]
516 fn test_encrypt_decrypt_and_policy() {
517 let authority = AbeAuthority::new();
518
519 let policy = AccessPolicy::and(vec![
520 PolicyNode::Attribute("premium".to_string()),
521 PolicyNode::Attribute("us-region".to_string()),
522 ]);
523
524 let user_key = authority
525 .generate_user_key(&["premium".to_string(), "us-region".to_string()])
526 .unwrap();
527
528 let plaintext = b"Premium US content";
529 let ciphertext = authority.encrypt(&policy, plaintext).unwrap();
530 let decrypted = authority.decrypt(&user_key, &ciphertext).unwrap();
531
532 assert_eq!(decrypted, plaintext);
533 }
534
535 #[test]
536 fn test_decrypt_fails_without_attributes() {
537 let authority = AbeAuthority::new();
538
539 let policy = AccessPolicy::new(PolicyNode::Attribute("premium".to_string()));
540 let user_key = authority.generate_user_key(&["basic".to_string()]).unwrap();
541
542 let plaintext = b"Secret premium content";
543 let ciphertext = authority.encrypt(&policy, plaintext).unwrap();
544
545 assert!(authority.decrypt(&user_key, &ciphertext).is_err());
546 }
547
548 #[test]
549 fn test_decrypt_fails_partial_and() {
550 let authority = AbeAuthority::new();
551
552 let policy = AccessPolicy::and(vec![
553 PolicyNode::Attribute("premium".to_string()),
554 PolicyNode::Attribute("us-region".to_string()),
555 ]);
556
557 let user_key = authority
559 .generate_user_key(&["premium".to_string()])
560 .unwrap();
561
562 let plaintext = b"Premium US content";
563 let ciphertext = authority.encrypt(&policy, plaintext).unwrap();
564
565 assert!(authority.decrypt(&user_key, &ciphertext).is_err());
566 }
567
568 #[test]
569 fn test_or_policy_decryption() {
570 let authority = AbeAuthority::new();
571
572 let policy = AccessPolicy::or(vec![
573 PolicyNode::Attribute("admin".to_string()),
574 PolicyNode::Attribute("premium".to_string()),
575 ]);
576
577 let user_key1 = authority.generate_user_key(&["admin".to_string()]).unwrap();
579
580 let user_key2 = authority
582 .generate_user_key(&["premium".to_string()])
583 .unwrap();
584
585 let plaintext = b"Admin or Premium content";
586 let ciphertext = authority.encrypt(&policy, plaintext).unwrap();
587
588 let decrypted1 = authority.decrypt(&user_key1, &ciphertext).unwrap();
590 assert_eq!(decrypted1, plaintext);
591
592 let decrypted2 = authority.decrypt(&user_key2, &ciphertext).unwrap();
593 assert_eq!(decrypted2, plaintext);
594 }
595
596 #[test]
597 fn test_threshold_policy() {
598 let authority = AbeAuthority::new();
599
600 let policy = AccessPolicy::threshold(
601 2,
602 vec![
603 PolicyNode::Attribute("attr1".to_string()),
604 PolicyNode::Attribute("attr2".to_string()),
605 PolicyNode::Attribute("attr3".to_string()),
606 ],
607 );
608
609 let user_key = authority
611 .generate_user_key(&["attr1".to_string(), "attr2".to_string()])
612 .unwrap();
613
614 let plaintext = b"Threshold content";
615 let ciphertext = authority.encrypt(&policy, plaintext).unwrap();
616 let decrypted = authority.decrypt(&user_key, &ciphertext).unwrap();
617
618 assert_eq!(decrypted, plaintext);
619 }
620
621 #[test]
622 fn test_complex_nested_policy() {
623 let authority = AbeAuthority::new();
624
625 let policy = AccessPolicy::and(vec![
627 PolicyNode::Or(vec![
628 PolicyNode::Attribute("admin".to_string()),
629 PolicyNode::Attribute("moderator".to_string()),
630 ]),
631 PolicyNode::Attribute("premium".to_string()),
632 ]);
633
634 let user_key = authority
635 .generate_user_key(&["moderator".to_string(), "premium".to_string()])
636 .unwrap();
637
638 let plaintext = b"Complex policy content";
639 let ciphertext = authority.encrypt(&policy, plaintext).unwrap();
640 let decrypted = authority.decrypt(&user_key, &ciphertext).unwrap();
641
642 assert_eq!(decrypted, plaintext);
643 }
644
645 #[test]
646 fn test_ciphertext_serialization() {
647 let authority = AbeAuthority::new();
648
649 let policy = AccessPolicy::new(PolicyNode::Attribute("test".to_string()));
650 let plaintext = b"Serialization test";
651 let ciphertext = authority.encrypt(&policy, plaintext).unwrap();
652
653 let bytes = ciphertext.to_bytes().unwrap();
654 let restored = AbeCiphertext::from_bytes(&bytes).unwrap();
655
656 let user_key = authority.generate_user_key(&["test".to_string()]).unwrap();
657 let decrypted = authority.decrypt(&user_key, &restored).unwrap();
658
659 assert_eq!(decrypted, plaintext);
660 }
661
662 #[test]
663 fn test_empty_attributes_fails() {
664 let authority = AbeAuthority::new();
665 let result = authority.generate_user_key(&[]);
666 assert!(result.is_err());
667 }
668
669 #[test]
670 fn test_master_key_export_import() {
671 let authority1 = AbeAuthority::new();
672 let seed = authority1.export_master_key();
673
674 let authority2 = AbeAuthority::from_master_key(seed);
675
676 let user_key = authority1.generate_user_key(&["test".to_string()]).unwrap();
678
679 let policy = AccessPolicy::new(PolicyNode::Attribute("test".to_string()));
680 let plaintext = b"Cross-authority test";
681 let ciphertext = authority2.encrypt(&policy, plaintext).unwrap();
682
683 let decrypted = authority1.decrypt(&user_key, &ciphertext).unwrap();
684 assert_eq!(decrypted, plaintext);
685 }
686
687 #[test]
688 fn test_multiple_plaintexts_same_policy() {
689 let authority = AbeAuthority::new();
690 let policy = AccessPolicy::new(PolicyNode::Attribute("premium".to_string()));
691 let user_key = authority
692 .generate_user_key(&["premium".to_string()])
693 .unwrap();
694
695 let plaintext1 = b"First message";
696 let plaintext2 = b"Second message";
697
698 let ciphertext1 = authority.encrypt(&policy, plaintext1).unwrap();
699 let ciphertext2 = authority.encrypt(&policy, plaintext2).unwrap();
700
701 let decrypted1 = authority.decrypt(&user_key, &ciphertext1).unwrap();
702 let decrypted2 = authority.decrypt(&user_key, &ciphertext2).unwrap();
703
704 assert_eq!(decrypted1, plaintext1);
705 assert_eq!(decrypted2, plaintext2);
706 }
707}