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::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 + std::any::Any> EventValidator<D> {
64 pub fn new(event_database: Arc<D>) -> Self {
65 Self {
66 event_storage: EventStorage::new(event_database),
67 }
68 }
69}
70impl<D: EventDatabase> EventValidator<D> {
71 pub fn validate_event(
77 &self,
78 signed_event: &SignedEventMessage,
79 ) -> Result<Option<IdentifierState>, Error> {
80 let new_state = match self
82 .event_storage
83 .get_state(&signed_event.event_message.data.get_prefix())
84 {
85 Some(state) => {
86 let new_state = signed_event.event_message.apply_to(state.clone())?;
87 if let EventData::Rot(rot) = signed_event.event_message.data.get_event_data() {
89 let new_public_keys = rot.key_config.public_keys;
90 state.current.next_keys_data.check_threshold(
91 &new_public_keys,
92 signed_event.signatures.iter().map(|sig| &sig.index),
93 )?;
94 }
95 new_state
96 }
97 None => signed_event
98 .event_message
99 .apply_to(IdentifierState::default())?,
100 };
101 let ver_result = new_state.current.verify(
103 &signed_event.event_message.encode()?,
104 &signed_event.signatures,
105 )?;
106 if let Some(seal) = self.get_delegator_seal(signed_event)? {
108 self.validate_seal(seal, &signed_event.event_message)?;
109 };
110
111 if !ver_result {
112 Err(Error::SignatureVerificationError)
113 } else {
114 let sn = signed_event.event_message.data.get_sn();
116 let prefix = &signed_event.event_message.data.get_prefix();
117
118 let (mut couples, mut indexed) = (vec![], vec![]);
119 if let Some(rcts) = self.event_storage.get_nt_receipts(prefix, sn)? {
120 rcts.signatures.iter().for_each(|s| match s {
121 Nontransferable::Couplet(c) => {
122 couples.append(&mut c.clone());
123 }
124 Nontransferable::Indexed(signatures) => indexed.append(&mut signatures.clone()),
125 });
126 };
127 if new_state.witness_config.enough_receipts(couples, indexed)? {
128 Ok(Some(new_state))
129 } else {
130 Err(Error::NotEnoughReceiptsError)
131 }
132 }
133 }
134
135 pub fn validate_validator_receipt(
141 &self,
142 vrc: &SignedTransferableReceipt,
143 ) -> Result<Option<IdentifierState>, Error> {
144 if let Some(event) = self
145 .event_storage
146 .get_event_at_sn(&vrc.body.prefix, vrc.body.sn)
147 {
148 let kp = self
149 .event_storage
150 .get_keys_at_event(
151 &vrc.validator_seal.prefix,
152 vrc.validator_seal.sn,
153 &vrc.validator_seal.event_digest(),
154 )?
155 .ok_or(Error::EventOutOfOrderError)?;
156 if kp.verify(
157 &event.signed_event_message.event_message.encode()?,
158 &vrc.signatures,
159 )? {
160 Ok(())
161 } else {
162 Err(Error::SignatureVerificationError)
163 }
164 } else {
165 Err(Error::MissingEvent)
166 }?;
167 Ok(self.event_storage.get_state(&vrc.body.prefix))
168 }
169
170 pub fn get_receipt_couplets(
171 &self,
172 rct: &SignedNontransferableReceipt,
173 ) -> Result<Vec<(BasicPrefix, SelfSigningPrefix)>, Error> {
174 let id = rct.body.prefix.clone();
175 let sn = rct.body.sn;
176 let receipted_event_digest = rct.body.receipted_event_digest.clone();
177
178 let witnesses = self
179 .event_storage
180 .compute_state_at_event(sn, &id, &receipted_event_digest)?
181 .ok_or(Error::MissingEvent)?
182 .witness_config
183 .witnesses;
184
185 let (mut couplets, mut indexed) = (vec![], vec![]);
186 rct.signatures.iter().for_each(|s| match s {
187 Nontransferable::Couplet(c) => {
188 couplets.append(&mut c.clone());
189 }
190 Nontransferable::Indexed(signatures) => indexed.append(&mut signatures.clone()),
191 });
192
193 let i = indexed
194 .into_iter()
195 .map(|sig| -> Result<_, _> {
196 Ok((
197 witnesses
198 .get(sig.index.current() as usize)
199 .ok_or_else(|| Error::SemanticError("No matching witness prefix".into()))?
200 .clone(),
201 sig.signature,
202 ))
203 })
204 .collect::<Result<Vec<_>, Error>>()
205 .unwrap();
206 Ok(couplets.into_iter().chain(i).collect())
207 }
208
209 pub fn validate_witness_receipt(
215 &self,
216 rct: &SignedNontransferableReceipt,
217 ) -> Result<Option<IdentifierState>, Error> {
218 let id = &rct.body.prefix.to_owned();
220 if let Some(event) = self
221 .event_storage
222 .get_event_at_sn(&rct.body.prefix, rct.body.sn)
223 {
224 let serialized_event = event.signed_event_message.event_message.encode()?;
225 let signer_couplets = self.get_receipt_couplets(rct)?;
226 signer_couplets
227 .into_iter()
228 .try_for_each(|(witness, signature)| {
229 (witness.verify(&serialized_event, &signature)?)
230 .then_some(())
231 .ok_or(Error::SignatureVerificationError)
232 })
233 } else {
234 Err(Error::MissingEvent)
236 }?;
237 Ok(self.event_storage.get_state(id))
238 }
239
240 pub fn verify(&self, data: &[u8], sig: &Signature) -> Result<(), VerificationError> {
241 match sig {
242 Signature::Transferable(signer_data, sigs) => {
243 let seal = match signer_data {
244 SignerData::EventSeal(seal) => Ok(seal.clone()),
245 SignerData::LastEstablishment(id) => self
246 .event_storage
247 .get_last_establishment_event_seal(id)
248 .ok_or::<VerificationError>(
249 MoreInfoError::UnknownIdentifier(id.clone()).into(),
250 ),
251 SignerData::JustSignatures => Err(VerificationError::MissingSignerId),
252 }?;
253 let kp = self
254 .event_storage
255 .get_keys_at_event(&seal.prefix, seal.sn, &seal.event_digest())
256 .map_err(|_| VerificationError::NotEstablishment(seal.clone()))?; match kp {
258 Some(kp) => kp
259 .verify(data, sigs)?
260 .then_some(())
261 .ok_or(VerificationError::VerificationFailure),
262 None => Err(MoreInfoError::EventNotFound(seal).into()),
263 }
264 }
265 Signature::NonTransferable(Nontransferable::Couplet(couplets)) => couplets
266 .iter()
267 .all(|(bp, sign)| bp.verify(data, sign).unwrap())
268 .then_some(())
269 .ok_or(VerificationError::VerificationFailure),
270 Signature::NonTransferable(Nontransferable::Indexed(_sigs)) => {
271 Err(VerificationError::MissingSignerId)
272 }
273 }
274 }
275
276 fn validate_seal(
281 &self,
282 seal: EventSeal,
283 delegated_event: &KeriEvent<KeyEvent>,
284 ) -> Result<(), Error> {
285 if let Some(event) = self.event_storage.get_event_at_sn(&seal.prefix, seal.sn) {
287 let data = match event
289 .signed_event_message
290 .event_message
291 .data
292 .get_event_data()
293 {
294 EventData::Rot(rot) => rot.data,
295 EventData::Ixn(ixn) => ixn.data,
296 EventData::Drt(drt) => drt.data,
297 _ => return Err(Error::SemanticError("Improper event type".to_string())),
298 };
299
300 if !data.iter().any(|s| match s {
302 Seal::Event(es) => delegated_event
303 .compare_digest(&es.event_digest())
304 .unwrap_or(false),
305 _ => false,
306 }) {
307 return Err(Error::SemanticError(
308 "Data field doesn't contain delegating event seal.".to_string(),
309 ));
310 };
311 } else {
312 return Err(Error::MissingDelegatingEventError);
313 }
314 Ok(())
315 }
316
317 fn get_delegator_seal(
318 &self,
319 signed_event: &SignedEventMessage,
320 ) -> Result<Option<EventSeal>, Error> {
321 Ok(match signed_event.event_message.data.get_event_data() {
323 EventData::Dip(dip) => {
324 let (sn, dig) = signed_event
325 .delegator_seal
326 .as_ref()
327 .map(|seal| (seal.sn, seal.digest.clone()))
328 .ok_or_else(|| Error::MissingDelegatorSealError(dip.delegator.clone()))?;
329 Some(EventSeal::new(dip.delegator, sn, dig.into()))
330 }
331 EventData::Drt(_drt) => {
332 let delegator = self
333 .event_storage
334 .get_state(&signed_event.event_message.data.get_prefix())
335 .ok_or_else(|| {
336 Error::SemanticError("Missing state of delegated identifier".into())
337 })?
338 .delegator
339 .ok_or_else(|| Error::SemanticError("Missing delegator".into()))?;
340 let (sn, dig) = signed_event
341 .delegator_seal
342 .as_ref()
343 .map(|seal| (seal.sn, seal.digest.clone()))
344 .ok_or_else(|| Error::MissingDelegatorSealError(delegator.clone()))?;
345 Some(EventSeal::new(delegator, sn, dig.into()))
346 }
347 _ => None,
348 })
349 }
350}
351
352impl<D: EventDatabase> EventValidator<D> {
353 #[cfg(feature = "query")]
354 pub fn process_signed_ksn_reply(
355 &self,
356 rpy: &SignedReply,
357 ) -> Result<Option<IdentifierState>, Error> {
358 use crate::query::reply_event::{bada_logic, ReplyRoute};
359
360 let route = rpy.reply.get_route();
361 if let ReplyRoute::Ksn(signer_id, ksn) = route {
363 if rpy.signature.get_signer().ok_or(Error::MissingSigner)? != signer_id {
364 return Err(QueryError::Error("Wrong reply message signer".into()).into());
365 };
366 self.verify(&rpy.reply.encode()?, &rpy.signature)?;
367
368 rpy.reply.check_digest()?;
369 let reply_prefix = ksn.state.prefix.clone();
370
371 if let Some(old_rpy) = self.event_storage.get_last_ksn_reply(
373 &reply_prefix,
374 &rpy.signature.get_signer().ok_or(Error::MissingSigner)?,
375 ) {
376 bada_logic(rpy, &old_rpy)?;
377 };
378
379 self.check_ksn(&ksn, &signer_id)?;
381 Ok(Some(ksn.state))
382 } else {
383 Err(Error::SemanticError("wrong route type".into()))
384 }
385 }
386
387 #[cfg(feature = "query")]
388 pub fn check_timestamp_with_last_ksn(
389 &self,
390 new_dt: DateTime<FixedOffset>,
391 pref: &IdentifierPrefix,
392 aid: &IdentifierPrefix,
393 ) -> Result<(), Error> {
394 match self.event_storage.get_last_ksn_reply(pref, aid) {
395 Some(old_ksn) => {
396 let old_dt = old_ksn.reply.get_timestamp();
397 if old_dt > new_dt {
398 Err(QueryError::StaleKsn.into())
399 } else {
400 Ok(())
401 }
402 }
403 None => Err(Error::EventOutOfOrderError),
404 }
405 }
406
407 #[cfg(feature = "query")]
408 fn check_ksn(
409 &self,
410 ksn: &KeyStateNotice,
411 aid: &IdentifierPrefix,
412 ) -> Result<Option<IdentifierState>, Error> {
413 use std::cmp::Ordering;
414
415 let ksn_sn = ksn.state.sn;
417 let ksn_pre = ksn.state.prefix.clone();
418 let event_from_db = self
419 .event_storage
420 .get_event_at_sn(&ksn_pre, ksn_sn)
421 .ok_or(Error::EventOutOfOrderError)?
422 .signed_event_message
423 .event_message;
424 event_from_db
425 .compare_digest(&ksn.state.last_event_digest.clone().into())?
426 .then_some(())
427 .ok_or::<Error>(Error::IncorrectDigest)?;
428
429 match self.check_timestamp_with_last_ksn(ksn.timestamp, &ksn_pre, aid) {
430 Err(Error::EventOutOfOrderError) => {
431 Ok(())
433 }
434 e => e,
435 }?;
436
437 let state = self
439 .event_storage
440 .get_state(&ksn_pre)
441 .ok_or::<Error>(Error::EventOutOfOrderError)?;
442
443 match state.sn.cmp(&ksn_sn) {
444 Ordering::Less => Err(Error::EventOutOfOrderError),
445 Ordering::Equal => Ok(Some(state)),
446 Ordering::Greater => Err(QueryError::StaleKsn.into()),
447 }
448 }
449}
450
451#[test]
452fn test_validate_seal() -> Result<(), Error> {
453 use cesrox::parse;
454 use std::{convert::TryFrom, fs, sync::Arc};
455
456 use tempfile::Builder;
457
458 use crate::{
459 database::redb::RedbDatabase,
460 event_message::signed_event_message::{Message, Notice},
461 processor::{basic_processor::BasicProcessor, Processor},
462 };
463 use tempfile::NamedTempFile;
464
465 let root = Builder::new().prefix("test-db").tempdir().unwrap();
467 fs::create_dir_all(root.path()).unwrap();
468 let events_db_path = NamedTempFile::new().unwrap();
469 let events_database = Arc::new(RedbDatabase::new(events_db_path.path()).unwrap());
470 let event_processor = BasicProcessor::new(events_database.clone(), None);
471
472 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 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 let seal = EventSeal::new(delegator_id, 1, delegated_event_digest.into());
490
491 let validator = EventValidator::new(events_database.clone());
492 assert!(matches!(
494 validator.validate_seal(seal.clone(), &dip.event_message),
495 Err(Error::MissingDelegatingEventError)
496 ));
497
498 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 assert!(validator.validate_seal(seal, &dip.event_message).is_ok());
506 };
507
508 Ok(())
509}