keri_core/processor/
validator.rs

1use std::sync::Arc;
2
3#[cfg(feature = "query")]
4use chrono::{DateTime, FixedOffset};
5use serde::{Deserialize, Serialize};
6use thiserror::Error;
7
8use super::event_storage::EventStorage;
9#[cfg(feature = "query")]
10use crate::query::{key_state_notice::KeyStateNotice, reply_event::SignedReply, QueryError};
11use crate::{
12    database::{sled::SledEventDatabase, EventDatabase},
13    error::Error,
14    event::{
15        event_data::EventData,
16        sections::{
17            key_config::SignatureError,
18            seal::{EventSeal, Seal},
19        },
20        KeyEvent,
21    },
22    event_message::{
23        msg::KeriEvent,
24        signature::{Nontransferable, Signature, SignerData},
25        signed_event_message::{
26            SignedEventMessage, SignedNontransferableReceipt, SignedTransferableReceipt,
27        },
28    },
29    prefix::{BasicPrefix, IdentifierPrefix, SelfSigningPrefix},
30    state::{EventSemantics, IdentifierState},
31};
32
33#[derive(Error, Debug, Serialize, Deserialize)]
34pub enum VerificationError {
35    #[error("Faulty signatures")]
36    VerificationFailure,
37
38    #[error(transparent)]
39    SignatureError(#[from] SignatureError),
40
41    #[error("Not establishment event: {0:?}")]
42    NotEstablishment(EventSeal),
43
44    #[error("Missing signer identifier")]
45    MissingSignerId,
46
47    #[error("Needs more info: {0}")]
48    MoreInfo(#[from] MoreInfoError),
49}
50
51#[derive(Error, Debug, Serialize, Deserialize)]
52pub enum MoreInfoError {
53    #[error("Corresponding event not found: {0:?}")]
54    EventNotFound(EventSeal),
55    #[error("Unknown signer identifier: {0}")]
56    UnknownIdentifier(IdentifierPrefix),
57}
58
59pub struct EventValidator<D: EventDatabase> {
60    event_storage: EventStorage<D>,
61}
62
63impl<D: EventDatabase> EventValidator<D> {
64    pub fn new(db: Arc<SledEventDatabase>, event_database: Arc<D>) -> Self {
65        Self {
66            event_storage: EventStorage::new(event_database, db),
67        }
68    }
69
70    /// Validate Event
71    ///
72    /// Validates a Key Event against the latest state
73    /// of the Identifier and applies it to update the state
74    /// returns the updated state
75    pub fn validate_event(
76        &self,
77        signed_event: &SignedEventMessage,
78    ) -> Result<Option<IdentifierState>, Error> {
79        // Compute new state
80        let new_state = match self
81            .event_storage
82            .get_state(&signed_event.event_message.data.get_prefix())
83        {
84            Some(state) => {
85                let new_state = signed_event.event_message.apply_to(state.clone())?;
86                // In case of rotation event, check if previous next threshold is satisfied
87                if let EventData::Rot(rot) = signed_event.event_message.data.get_event_data() {
88                    let new_public_keys = rot.key_config.public_keys;
89                    state.current.next_keys_data.check_threshold(
90                        &new_public_keys,
91                        signed_event.signatures.iter().map(|sig| &sig.index),
92                    )?;
93                }
94                new_state
95            }
96            None => signed_event
97                .event_message
98                .apply_to(IdentifierState::default())?,
99        };
100        // match on verification result
101        let ver_result = new_state.current.verify(
102            &signed_event.event_message.encode()?,
103            &signed_event.signatures,
104        )?;
105        // If delegated event, check its delegator seal.
106        if let Some(seal) = self.get_delegator_seal(signed_event)? {
107            self.validate_seal(seal, &signed_event.event_message)?;
108        };
109
110        if !ver_result {
111            Err(Error::SignatureVerificationError)
112        } else {
113            // check if there are enough receipts and escrow
114            let sn = signed_event.event_message.data.get_sn();
115            let prefix = &signed_event.event_message.data.get_prefix();
116
117            let (mut couples, mut indexed) = (vec![], vec![]);
118            if let Some(rcts) = self.event_storage.get_nt_receipts(prefix, sn)? {
119                rcts.signatures.iter().for_each(|s| match s {
120                    Nontransferable::Couplet(c) => {
121                        couples.append(&mut c.clone());
122                    }
123                    Nontransferable::Indexed(signatures) => indexed.append(&mut signatures.clone()),
124                });
125            };
126            if new_state.witness_config.enough_receipts(couples, indexed)? {
127                Ok(Some(new_state))
128            } else {
129                Err(Error::NotEnoughReceiptsError)
130            }
131        }
132    }
133
134    /// Process Validator Receipt
135    ///
136    /// Checks the receipt against the receipted event
137    /// and the state of the validator, returns the state
138    /// of the identifier being receipted
139    pub fn validate_validator_receipt(
140        &self,
141        vrc: &SignedTransferableReceipt,
142    ) -> Result<Option<IdentifierState>, Error> {
143        if let Some(event) = self
144            .event_storage
145            .get_event_at_sn(&vrc.body.prefix, vrc.body.sn)
146        {
147            let kp = self
148                .event_storage
149                .get_keys_at_event(
150                    &vrc.validator_seal.prefix,
151                    vrc.validator_seal.sn,
152                    &vrc.validator_seal.event_digest(),
153                )?
154                .ok_or(Error::EventOutOfOrderError)?;
155            if kp.verify(
156                &event.signed_event_message.event_message.encode()?,
157                &vrc.signatures,
158            )? {
159                Ok(())
160            } else {
161                Err(Error::SignatureVerificationError)
162            }
163        } else {
164            Err(Error::MissingEvent)
165        }?;
166        Ok(self.event_storage.get_state(&vrc.body.prefix))
167    }
168
169    pub fn get_receipt_couplets(
170        &self,
171        rct: &SignedNontransferableReceipt,
172    ) -> Result<Vec<(BasicPrefix, SelfSigningPrefix)>, Error> {
173        let id = rct.body.prefix.clone();
174        let sn = rct.body.sn;
175        let receipted_event_digest = rct.body.receipted_event_digest.clone();
176
177        let witnesses = self
178            .event_storage
179            .compute_state_at_event(sn, &id, &receipted_event_digest)?
180            .ok_or(Error::MissingEvent)?
181            .witness_config
182            .witnesses;
183
184        let (mut couplets, mut indexed) = (vec![], vec![]);
185        rct.signatures.iter().for_each(|s| match s {
186            Nontransferable::Couplet(c) => {
187                couplets.append(&mut c.clone());
188            }
189            Nontransferable::Indexed(signatures) => indexed.append(&mut signatures.clone()),
190        });
191
192        let i = indexed
193            .into_iter()
194            .map(|sig| -> Result<_, _> {
195                Ok((
196                    witnesses
197                        .get(sig.index.current() as usize)
198                        .ok_or_else(|| Error::SemanticError("No matching witness prefix".into()))?
199                        .clone(),
200                    sig.signature,
201                ))
202            })
203            .collect::<Result<Vec<_>, Error>>()
204            .unwrap();
205        Ok(couplets.into_iter().chain(i).collect())
206    }
207
208    /// Process Witness Receipt
209    ///
210    /// Checks the receipt against the receipted event
211    /// returns the state of the Identifier being receipted,
212    /// which may have been updated by un-escrowing events
213    pub fn validate_witness_receipt(
214        &self,
215        rct: &SignedNontransferableReceipt,
216    ) -> Result<Option<IdentifierState>, Error> {
217        // get event which is being receipted
218        let id = &rct.body.prefix.to_owned();
219        if let Some(event) = self
220            .event_storage
221            .get_event_at_sn(&rct.body.prefix, rct.body.sn)
222        {
223            let serialized_event = event.signed_event_message.event_message.encode()?;
224            let signer_couplets = self.get_receipt_couplets(rct)?;
225            signer_couplets
226                .into_iter()
227                .try_for_each(|(witness, signature)| {
228                    (witness.verify(&serialized_event, &signature)?)
229                        .then_some(())
230                        .ok_or(Error::SignatureVerificationError)
231                })
232        } else {
233            // There's no receipted event id database so we can't verify signatures
234            Err(Error::MissingEvent)
235        }?;
236        Ok(self.event_storage.get_state(id))
237    }
238
239    pub fn verify(&self, data: &[u8], sig: &Signature) -> Result<(), VerificationError> {
240        match sig {
241            Signature::Transferable(signer_data, sigs) => {
242                let seal = match signer_data {
243                    SignerData::EventSeal(seal) => Ok(seal.clone()),
244                    SignerData::LastEstablishment(id) => self
245                        .event_storage
246                        .get_last_establishment_event_seal(id)
247                        .ok_or::<VerificationError>(
248                            MoreInfoError::UnknownIdentifier(id.clone()).into(),
249                        ),
250                    SignerData::JustSignatures => Err(VerificationError::MissingSignerId),
251                }?;
252                let kp = self
253                    .event_storage
254                    .get_keys_at_event(&seal.prefix, seal.sn, &seal.event_digest())
255                    .map_err(|_| VerificationError::NotEstablishment(seal.clone()))?; // error means that event wasn't found
256                match kp {
257                    Some(kp) => kp
258                        .verify(data, sigs)?
259                        .then_some(())
260                        .ok_or(VerificationError::VerificationFailure),
261                    None => Err(MoreInfoError::EventNotFound(seal).into()),
262                }
263            }
264            Signature::NonTransferable(Nontransferable::Couplet(couplets)) => couplets
265                .iter()
266                .all(|(bp, sign)| bp.verify(data, sign).unwrap())
267                .then_some(())
268                .ok_or(VerificationError::VerificationFailure),
269            Signature::NonTransferable(Nontransferable::Indexed(_sigs)) => {
270                Err(VerificationError::MissingSignerId)
271            }
272        }
273    }
274
275    /// Validate delegating event seal.
276    ///
277    /// Validates binding between delegated and delegating events. The validation
278    /// is based on delegating event seal and delegated event.
279    fn validate_seal(
280        &self,
281        seal: EventSeal,
282        delegated_event: &KeriEvent<KeyEvent>,
283    ) -> Result<(), Error> {
284        // Check if event of seal's prefix and sn is in db.
285        if let Some(event) = self.event_storage.get_event_at_sn(&seal.prefix, seal.sn) {
286            // Extract prior_digest and data field from delegating event.
287            let data = match event
288                .signed_event_message
289                .event_message
290                .data
291                .get_event_data()
292            {
293                EventData::Rot(rot) => rot.data,
294                EventData::Ixn(ixn) => ixn.data,
295                EventData::Drt(drt) => drt.data,
296                _ => return Err(Error::SemanticError("Improper event type".to_string())),
297            };
298
299            // Check if event seal list contains delegating event seal.
300            if !data.iter().any(|s| match s {
301                Seal::Event(es) => delegated_event
302                    .compare_digest(&es.event_digest())
303                    .unwrap_or(false),
304                _ => false,
305            }) {
306                return Err(Error::SemanticError(
307                    "Data field doesn't contain delegating event seal.".to_string(),
308                ));
309            };
310        } else {
311            return Err(Error::MissingDelegatingEventError);
312        }
313        Ok(())
314    }
315
316    fn get_delegator_seal(
317        &self,
318        signed_event: &SignedEventMessage,
319    ) -> Result<Option<EventSeal>, Error> {
320        // If delegated event, check its delegator seal.
321        Ok(match signed_event.event_message.data.get_event_data() {
322            EventData::Dip(dip) => {
323                let (sn, dig) = signed_event
324                    .delegator_seal
325                    .as_ref()
326                    .map(|seal| (seal.sn, seal.digest.clone()))
327                    .ok_or_else(|| Error::MissingDelegatorSealError(dip.delegator.clone()))?;
328                Some(EventSeal::new(dip.delegator, sn, dig.into()))
329            }
330            EventData::Drt(_drt) => {
331                let delegator = self
332                    .event_storage
333                    .get_state(&signed_event.event_message.data.get_prefix())
334                    .ok_or_else(|| {
335                        Error::SemanticError("Missing state of delegated identifier".into())
336                    })?
337                    .delegator
338                    .ok_or_else(|| Error::SemanticError("Missing delegator".into()))?;
339                let (sn, dig) = signed_event
340                    .delegator_seal
341                    .as_ref()
342                    .map(|seal| (seal.sn, seal.digest.clone()))
343                    .ok_or_else(|| Error::MissingDelegatorSealError(delegator.clone()))?;
344                Some(EventSeal::new(delegator, sn, dig.into()))
345            }
346            _ => None,
347        })
348    }
349}
350
351impl<D: EventDatabase> EventValidator<D> {
352    #[cfg(feature = "query")]
353    pub fn process_signed_ksn_reply(
354        &self,
355        rpy: &SignedReply,
356    ) -> Result<Option<IdentifierState>, Error> {
357        use crate::query::reply_event::{bada_logic, ReplyRoute};
358
359        let route = rpy.reply.get_route();
360        // check if signature was made by ksn creator
361        if let ReplyRoute::Ksn(signer_id, ksn) = route {
362            if rpy.signature.get_signer().ok_or(Error::MissingSigner)? != signer_id {
363                return Err(QueryError::Error("Wrong reply message signer".into()).into());
364            };
365            self.verify(&rpy.reply.encode()?, &rpy.signature)?;
366
367            rpy.reply.check_digest()?;
368            let reply_prefix = ksn.state.prefix.clone();
369
370            // check if there's previous reply to compare
371            if let Some(old_rpy) = self.event_storage.get_last_ksn_reply(
372                &reply_prefix,
373                &rpy.signature.get_signer().ok_or(Error::MissingSigner)?,
374            ) {
375                bada_logic(rpy, &old_rpy)?;
376            };
377
378            // now unpack ksn and check its details
379            self.check_ksn(&ksn, &signer_id)?;
380            Ok(Some(ksn.state))
381        } else {
382            Err(Error::SemanticError("wrong route type".into()))
383        }
384    }
385
386    #[cfg(feature = "query")]
387    pub fn check_timestamp_with_last_ksn(
388        &self,
389        new_dt: DateTime<FixedOffset>,
390        pref: &IdentifierPrefix,
391        aid: &IdentifierPrefix,
392    ) -> Result<(), Error> {
393        match self.event_storage.get_last_ksn_reply(pref, aid) {
394            Some(old_ksn) => {
395                let old_dt = old_ksn.reply.get_timestamp();
396                if old_dt > new_dt {
397                    Err(QueryError::StaleKsn.into())
398                } else {
399                    Ok(())
400                }
401            }
402            None => Err(Error::EventOutOfOrderError),
403        }
404    }
405
406    #[cfg(feature = "query")]
407    fn check_ksn(
408        &self,
409        ksn: &KeyStateNotice,
410        aid: &IdentifierPrefix,
411    ) -> Result<Option<IdentifierState>, Error> {
412        use std::cmp::Ordering;
413
414        // check ksn digest
415        let ksn_sn = ksn.state.sn;
416        let ksn_pre = ksn.state.prefix.clone();
417        let event_from_db = self
418            .event_storage
419            .get_event_at_sn(&ksn_pre, ksn_sn)
420            .ok_or(Error::EventOutOfOrderError)?
421            .signed_event_message
422            .event_message;
423        event_from_db
424            .compare_digest(&ksn.state.last_event_digest)?
425            .then_some(())
426            .ok_or::<Error>(Error::IncorrectDigest)?;
427
428        match self.check_timestamp_with_last_ksn(ksn.timestamp, &ksn_pre, aid) {
429            Err(Error::EventOutOfOrderError) => {
430                // no previous accepted ksn from that aid in db
431                Ok(())
432            }
433            e => e,
434        }?;
435
436        // check new ksn with actual database state for that prefix
437        let state = self
438            .event_storage
439            .get_state(&ksn_pre)
440            .ok_or::<Error>(Error::EventOutOfOrderError)?;
441
442        match state.sn.cmp(&ksn_sn) {
443            Ordering::Less => Err(Error::EventOutOfOrderError),
444            Ordering::Equal => Ok(Some(state)),
445            Ordering::Greater => Err(QueryError::StaleKsn.into()),
446        }
447    }
448}
449
450#[test]
451fn test_validate_seal() -> Result<(), Error> {
452    use cesrox::parse;
453    use std::{convert::TryFrom, fs, sync::Arc};
454
455    use tempfile::Builder;
456
457    use crate::{
458        database::redb::RedbDatabase,
459        event_message::signed_event_message::{Message, Notice},
460        processor::{basic_processor::BasicProcessor, Processor},
461    };
462    use tempfile::NamedTempFile;
463
464    // Create test db and event processor.
465    let root = Builder::new().prefix("test-db").tempdir().unwrap();
466    fs::create_dir_all(root.path()).unwrap();
467    let events_db_path = NamedTempFile::new().unwrap();
468    let events_database = Arc::new(RedbDatabase::new(events_db_path.path()).unwrap());
469    let db = Arc::new(SledEventDatabase::new(root.path()).unwrap());
470    let event_processor = BasicProcessor::new(events_database.clone(), Arc::clone(&db), None);
471
472    // Events and sigs are from keripy `test_delegation` test.
473    // (keripy/tests/core/test_delegating.py:#test_delegation)
474
475    // Process icp.
476    let delegator_icp_raw = br#"{"v":"KERI10JSON00012b_","t":"icp","d":"EA_SbBUZYwqLVlAAn14d6QUBQCSReJlZ755JqTgmRhXH","i":"EA_SbBUZYwqLVlAAn14d6QUBQCSReJlZ755JqTgmRhXH","s":"0","kt":"1","k":["DKiNnDmdOkcBjcAqL2FFhMZnSlPfNyGrJlCjJmX5b1nU"],"nt":"1","n":["EMP7Lg6BtehOYZt2RwOqXLNfMUiUllejAp8G_5EiANXR"],"bt":"0","b":[],"c":[],"a":[]}-AABAAArkDBeflIAo4kBsKnc754XHJvdLnf04iq-noTFEJkbv2MeIGZtx6lIfJPmRSEmFMUkFW4otRrMeBGQ0-nlhHEE"#;
477    let parsed = parse(delegator_icp_raw).unwrap().1;
478    let deserialized_icp = Message::try_from(parsed).unwrap();
479    event_processor.process(&deserialized_icp)?;
480    let delegator_id = "EA_SbBUZYwqLVlAAn14d6QUBQCSReJlZ755JqTgmRhXH".parse()?;
481
482    // Delegated inception event.
483    let dip_raw = br#"{"v":"KERI10JSON00015f_","t":"dip","d":"EHng2fV42DdKb5TLMIs6bbjFkPNmIdQ5mSFn6BTnySJj","i":"EHng2fV42DdKb5TLMIs6bbjFkPNmIdQ5mSFn6BTnySJj","s":"0","kt":"1","k":["DLitcfMnabnLt-PNCaXdVwX45wsG93Wd8eW9QiZrlKYQ"],"nt":"1","n":["EDjXvWdaNJx7pAIr72Va6JhHxc7Pf4ScYJG496ky8lK8"],"bt":"0","b":[],"c":[],"a":[],"di":"EA_SbBUZYwqLVlAAn14d6QUBQCSReJlZ755JqTgmRhXH"}-AABAABv6Q3s-1Tif-ksrx7ul9OKyOL_ZPHHp6lB9He4n6kswjm9VvHXzWB3O7RS2OQNWhx8bd3ycg9bWRPRrcKADoYC-GAB0AAAAAAAAAAAAAAAAAAAAAABEJtQndkvwnMpVGE5oVVbLWSCm-jLviGw1AOOkzBvNwsS"#;
484    let parsed = parse(dip_raw).unwrap().1;
485    let msg = Message::try_from(parsed).unwrap();
486    if let Message::Notice(Notice::Event(dip)) = msg {
487        let delegated_event_digest = dip.event_message.digest()?;
488        // Construct delegating seal.
489        let seal = EventSeal::new(delegator_id, 1, delegated_event_digest.into());
490
491        let validator = EventValidator::new(db.clone(), events_database.clone());
492        // Try to validate seal before processing delegating event
493        assert!(matches!(
494            validator.validate_seal(seal.clone(), &dip.event_message),
495            Err(Error::MissingDelegatingEventError)
496        ));
497
498        // Process delegating event.
499        let delegating_event_raw = br#"{"v":"KERI10JSON00013a_","t":"ixn","d":"EJtQndkvwnMpVGE5oVVbLWSCm-jLviGw1AOOkzBvNwsS","i":"EA_SbBUZYwqLVlAAn14d6QUBQCSReJlZ755JqTgmRhXH","s":"1","p":"EA_SbBUZYwqLVlAAn14d6QUBQCSReJlZ755JqTgmRhXH","a":[{"i":"EHng2fV42DdKb5TLMIs6bbjFkPNmIdQ5mSFn6BTnySJj","s":"0","d":"EHng2fV42DdKb5TLMIs6bbjFkPNmIdQ5mSFn6BTnySJj"}]}-AABAADFmoctrQkBbm47vuk7ejMbQ1y5vKD0Nfo8cqzbETZAlEPdbgVRSFta1-Bpv0y1RiDrCxa_0IOp906gYqDPXIwG"#;
500        let parsed = parse(delegating_event_raw).unwrap().1;
501        let deserialized_ixn = Message::try_from(parsed).unwrap();
502        event_processor.process(&deserialized_ixn)?;
503
504        // Validate seal again.
505        assert!(validator.validate_seal(seal, &dip.event_message).is_ok());
506    };
507
508    Ok(())
509}