1use std::io;
2
3use log::{debug, warn};
4
5use crate::errors::Result;
6use crate::packet::{write_packet, Signature, UserAttribute, UserId};
7use crate::ser::Serialize;
8use crate::types::{PublicKeyTrait, Tag};
9
10#[derive(Debug, PartialEq, Eq, Clone)]
11pub struct SignedUser {
12 pub id: UserId,
13 pub signatures: Vec<Signature>,
14}
15
16impl SignedUser {
17 pub fn new(id: UserId, signatures: Vec<Signature>) -> Self {
18 let signatures = signatures
19 .into_iter()
20 .filter(|sig| {
21 if !sig.is_certification() {
22 warn!(
23 "ignoring unexpected signature {:?} after User ID packet",
24 sig.typ()
25 );
26 false
27 } else {
28 true
29 }
30 })
31 .collect();
32
33 SignedUser { id, signatures }
34 }
35
36 pub fn verify(&self, key: &impl PublicKeyTrait) -> Result<()> {
38 debug!("verify signed user {:#?}", self);
39 ensure!(!self.signatures.is_empty(), "no signatures found");
40
41 for signature in &self.signatures {
42 signature.verify_certification(key, Tag::UserId, &self.id)?;
43 }
44
45 Ok(())
46 }
47
48 pub fn verify_third_party(
50 &self,
51 signee: &impl PublicKeyTrait,
52 signer: &impl PublicKeyTrait,
53 ) -> Result<()> {
54 debug!("verify signed user {:#?} with signer {:#?}", self, signer);
55 ensure!(!self.signatures.is_empty(), "no signatures found");
56
57 for signature in &self.signatures {
58 signature.verify_third_party_certification(signee, signer, Tag::UserId, &self.id)?;
59 }
60
61 Ok(())
62 }
63
64 pub fn is_primary(&self) -> bool {
65 self.signatures.iter().any(Signature::is_primary)
66 }
67}
68
69impl Serialize for SignedUser {
70 fn to_writer<W: io::Write>(&self, writer: &mut W) -> Result<()> {
71 write_packet(writer, &self.id)?;
72 for sig in &self.signatures {
73 write_packet(writer, sig)?;
74 }
75
76 Ok(())
77 }
78}
79
80#[derive(Debug, PartialEq, Eq, Clone)]
81pub struct SignedUserAttribute {
82 pub attr: UserAttribute,
83 pub signatures: Vec<Signature>,
84}
85
86impl SignedUserAttribute {
87 pub fn new(attr: UserAttribute, signatures: Vec<Signature>) -> Self {
88 let signatures = signatures
89 .into_iter()
90 .filter(|sig| {
91 if !sig.is_certification() {
92 warn!(
93 "ignoring unexpected signature {:?} after User Attribute packet",
94 sig.typ()
95 );
96 false
97 } else {
98 true
99 }
100 })
101 .collect();
102
103 SignedUserAttribute { attr, signatures }
104 }
105
106 pub fn verify(&self, key: &impl PublicKeyTrait) -> Result<()> {
108 debug!("verify signed attribute {:?}", self);
109 ensure!(!self.signatures.is_empty(), "no signatures found");
110
111 for signature in &self.signatures {
112 signature.verify_certification(key, Tag::UserAttribute, &self.attr)?;
113 }
114
115 Ok(())
116 }
117
118 pub fn verify_third_party(
120 &self,
121 signee: &impl PublicKeyTrait,
122 signer: &impl PublicKeyTrait,
123 ) -> Result<()> {
124 debug!(
125 "verify signed attribute {:#?} with signer {:#?}",
126 self, signer
127 );
128 ensure!(!self.signatures.is_empty(), "no signatures found");
129
130 for signature in &self.signatures {
131 signature.verify_third_party_certification(
132 signee,
133 signer,
134 Tag::UserAttribute,
135 &self.attr,
136 )?;
137 }
138
139 Ok(())
140 }
141}
142
143impl Serialize for SignedUserAttribute {
144 fn to_writer<W: io::Write>(&self, writer: &mut W) -> Result<()> {
145 write_packet(writer, &self.attr)?;
146 for sig in &self.signatures {
147 write_packet(writer, sig)?;
148 }
149
150 Ok(())
151 }
152}