From e754aca9f2d956941dafa79fe182059e82314a83 Mon Sep 17 00:00:00 2001 From: Sam Stelfox Date: Thu, 8 Feb 2024 15:07:23 -0500 Subject: [PATCH] feat: locate and unlock the key if there is one matching --- src/codec/content_payload/mod.rs | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/src/codec/content_payload/mod.rs b/src/codec/content_payload/mod.rs index fb12aee..ccdc4b9 100644 --- a/src/codec/content_payload/mod.rs +++ b/src/codec/content_payload/mod.rs @@ -1,19 +1,36 @@ +use nom::error::{Error as NomError, ErrorKind, ParseError}; use nom::number::streaming::le_u8; -use nom::IResult; +use nom::{Err, IResult}; use crate::codec::crypto::{AccessKey, LockedAccessKey, SigningKey}; pub(crate) enum ContentPayload { - Private, + Private { access_key: AccessKey }, Public, } impl ContentPayload { pub(crate) fn parse_private<'a>(input: &'a [u8], key: &SigningKey) -> IResult<&'a [u8], Self> { - let _key_id = key.key_id(); let (input, key_count) = le_u8(input)?; - let (input, _escrowed_keys) = LockedAccessKey::parse_many(input, key_count)?; - Ok((input, ContentPayload::Private)) + let (input, locked_keys) = LockedAccessKey::parse_many(input, key_count)?; + + let key_id = key.key_id(); + let relevant_keys = locked_keys.into_iter().filter(|k| k.key_id == key_id); + + let mut access_key = None; + for potential_key in relevant_keys { + if let Ok(key) = potential_key.unlock(key) { + access_key = Some(key); + break; + } + } + + let access_key = match access_key { + Some(ak) => ak, + None => return Err(Err::Failure(NomError::new(input, ErrorKind::Verify))), + }; + + Ok((input, ContentPayload::Private { access_key })) } pub(crate) fn parse_public(input: &[u8]) -> IResult<&[u8], Self> {