Skip to main content

vitaminc_aead/
typed.rs

1//! Statically typed decryption as sinks.
2//!
3//! A type that can be decrypted names the [`Sink`] that builds it
4//! ([`Decrypt`]). A scalar target is one function from a scalar, logical
5//! plus physical, to the type, or `None` to refuse it ([`FromScalar`]);
6//! every such type gets its sink for free. Containers push each child into
7//! the parent through the child's own sink.
8//!
9//! Integer targets read the value, not the width: a `u32` accepts an `i8`
10//! leaf holding 34 and refuses one holding -1. The width is a host-fidelity
11//! hint. `Option<T>` reads null and `undefined` as `None` and defers
12//! anything else to `T`. A typed null (see [`Sink::typed_null`]) is `None`
13//! for an `Option<T>` whose `T` reads values of its type
14//! ([`Decrypt::reads_null`]); any other target refuses it as the wrong
15//! kind, and never reads it as a zero. `HashMap<String, T>` and `BTreeMap<String, T>`
16//! read a map, each value through `T`'s sink.
17//!
18//! `Protected<T>` is a target for every `T` that implements
19//! [`DecryptProtected`]: any scalar target that can be wiped, and a
20//! `Vec<T>` or `Option<T>` of such targets, nested to any depth. A
21//! protected target is built inside its wrapper from the start, so a walk
22//! that fails part way wipes whatever it had already decoded.
23//!
24//! A struct's sink is what `#[derive(Decrypt)]` generates, out of the
25//! pieces here: a map sink with one slot per field, whose `entry` hands
26//! back [`Either`] of the fields' own sinks ([`Forward`] for a sealed
27//! field, [`Clear`] for a passthrough one). A newtype's sink is its inner
28//! type's, [`Wrapped`] so the result is rewrapped. A field decoded before
29//! a later entry is refused is dropped as an ordinary value, so a secret
30//! field should be a `Protected<T>`, which wipes itself, whatever the
31//! struct around it does.
32//!
33//! Nothing here knows whether the cipher was sync or async: the opened tree
34//! is walked after every await has completed.
35//!
36//! [`Decrypt`] is re-exported from the crate root.
37
38use core::marker::PhantomData;
39use std::collections::{BTreeMap, HashMap};
40
41use vitaminc_protected::{Controlled, Protected};
42use zeroize::Zeroize;
43
44use crate::plaintext::{
45    Encrypt, Error, FixedType, Float, Logical, MapSink, Physical, SeqSink, Sink, SourceError,
46};
47use crate::seal::{AsyncCipher, Cipher, Node};
48use crate::walk::{decrypt_into, decrypt_into_async, DecryptError};
49use crate::IntoAad;
50
51/// Derive [`Decrypt`] for a struct or a fieldless enum: the sink that builds
52/// it. A struct reads a map keyed by field name; a fieldless enum reads an
53/// int leaf holding the variant's discriminant. Takes the same
54/// `#[aead(...)]` attributes as [`Encrypt`](macro@crate::Encrypt).
55#[doc(inline)]
56pub use vitaminc_aead_derive::Decrypt;
57
58/// Why a typed target refused what it was given.
59///
60/// Non-exhaustive, so a target can add refusals without a breaking change.
61#[derive(Debug, thiserror::Error)]
62#[non_exhaustive]
63pub enum DecodeError {
64    /// The ciphertext holds something other than the named kind.
65    #[error("expected {0}")]
66    Expected(&'static str),
67    /// A map holds a key the target has no field for.
68    #[error("unknown key {0:?}")]
69    UnknownKey(String),
70    /// A map holds the same key twice.
71    #[error("duplicate key {0:?}")]
72    DuplicateKey(String),
73    /// A map is missing the named field.
74    #[error("missing field {0:?}")]
75    MissingField(&'static str),
76    /// The source stopped the walk (only reachable through a passthrough).
77    #[error("source failed: {0}")]
78    Source(#[source] SourceError),
79}
80
81impl DecodeError {
82    /// A map holds `key`, which the target has no field for.
83    pub fn unknown_key(key: &str) -> Self {
84        Self::UnknownKey(key.to_owned())
85    }
86
87    /// A map holds `key` twice.
88    pub fn duplicate_key(key: &str) -> Self {
89        Self::DuplicateKey(key.to_owned())
90    }
91}
92
93impl Error for DecodeError {
94    fn source(error: SourceError) -> Self {
95        Self::Source(error)
96    }
97}
98
99/// A type that can be decrypted: it names the sink that builds it.
100pub trait Decrypt: Sized {
101    type Sink: Sink<Ok = Self, Error = DecodeError>;
102
103    fn sink() -> Self::Sink;
104
105    /// Whether an `Option<Self>` reads a typed null of `ty` as `None`: for
106    /// a scalar target, whether it reads a value of `ty` (see
107    /// [`FromScalar::FIXED`]), so a `None` reads back wherever a `Some`
108    /// does, a widened field included. `false`, the default, for a target
109    /// that is not a scalar, whose `Option` then refuses every typed null.
110    fn reads_null(_: FixedType) -> bool {
111        false
112    }
113}
114
115/// Decrypt into `T`.
116pub fn decrypt<'a, T, C, A>(
117    cipher: &C,
118    node: Node<C::Leaf>,
119    aad: A,
120) -> Result<T, DecryptError<DecodeError, C::Error>>
121where
122    T: Decrypt,
123    C: Cipher,
124    A: IntoAad<'a>,
125{
126    decrypt_into(cipher, node, aad, T::sink())
127}
128
129/// Decrypt into `T` through an async cipher. Gives the same result as
130/// [`decrypt`] for the same ciphertext.
131pub async fn decrypt_async<'a, T, C, A>(
132    cipher: &C,
133    node: Node<C::Leaf>,
134    aad: A,
135) -> Result<T, DecryptError<DecodeError, C::Error>>
136where
137    T: Decrypt,
138    C: AsyncCipher,
139    A: IntoAad<'a>,
140{
141    decrypt_into_async(cipher, node, aad, T::sink()).await
142}
143
144/// A type that decodes from one scalar.
145pub trait FromScalar: Sized {
146    /// What the type is called in a refusal.
147    const EXPECTED: &'static str;
148    /// A fixed type whose typed null an `Option<Self>` reads as `None`
149    /// even though `from_scalar` refuses that type's zero.
150    ///
151    /// An `Option<Self>` reads a typed null of any type whose zero
152    /// `from_scalar` accepts ([`Width::zero`](crate::Width::zero)): every
153    /// type it reads a value of, for the built-in targets, so a `u64`
154    /// field reads a `u32` field's `None` as it reads its values. Only a
155    /// target that refuses zero needs this, to read its own `None`: a
156    /// fieldless enum with no variant at zero sets it to its
157    /// [`Encrypt::FIXED`].
158    const FIXED: Option<FixedType> = None;
159    fn from_scalar(ty: Option<Logical>, value: Physical<'_>) -> Option<Self>;
160
161    /// Decode straight into `Protected`: the seam `Protected<T>`'s target
162    /// goes through. The default decodes, then wraps, which leaves no bare
163    /// copy for a type that moves by pointer (`String`, `Vec<u8>`) and only
164    /// a stack copy of a small scalar. A type that would otherwise pass
165    /// through a bare temporary (`[u8; N]`) overrides it to build in place.
166    fn from_scalar_protected(ty: Option<Logical>, value: Physical<'_>) -> Option<Protected<Self>>
167    where
168        Self: Zeroize,
169    {
170        Self::from_scalar(ty, value).map(Protected::new)
171    }
172}
173
174/// The sink for any [`FromScalar`] type. Refuses containers and passthrough.
175pub struct ScalarSink<T>(PhantomData<T>);
176
177impl<T: FromScalar> Sink for ScalarSink<T> {
178    type Ok = T;
179    type Error = DecodeError;
180    type Seq = Never<T>;
181    type Map = Never<T>;
182
183    fn scalar(self, ty: Option<Logical>, v: Physical<'_>) -> Result<T, DecodeError> {
184        T::from_scalar(ty, v).ok_or(DecodeError::Expected(T::EXPECTED))
185    }
186
187    /// An absent value is not a value, whatever its type.
188    fn typed_null(self, _: FixedType) -> Result<T, DecodeError> {
189        Err(DecodeError::Expected(T::EXPECTED))
190    }
191
192    fn seq(self, _: Option<usize>) -> Result<Never<T>, DecodeError> {
193        Err(DecodeError::Expected(T::EXPECTED))
194    }
195
196    fn map(self, _: Option<usize>) -> Result<Never<T>, DecodeError> {
197        Err(DecodeError::Expected(T::EXPECTED))
198    }
199
200    fn passthrough<P: Encrypt + Clone>(self, _: P) -> Result<T, DecodeError> {
201        Err(DecodeError::Expected(T::EXPECTED))
202    }
203}
204
205impl<T: FromScalar> Decrypt for T {
206    type Sink = ScalarSink<T>;
207    fn sink() -> ScalarSink<T> {
208        ScalarSink(PhantomData)
209    }
210
211    fn reads_null(ty: FixedType) -> bool {
212        T::FIXED == Some(ty) || T::from_scalar(ty.logical(), ty.width().zero()).is_some()
213    }
214}
215
216/// A sink nothing is ever walked into: the element and entry type of a
217/// container sink that hands out none, such as [`Never`] and the map sink
218/// of a derived struct with no fields. Uninhabited, so it cannot be built.
219pub enum Nothing {}
220
221impl Sink for Nothing {
222    type Ok = ();
223    type Error = DecodeError;
224    type Seq = Never<()>;
225    type Map = Never<()>;
226
227    fn scalar(self, _: Option<Logical>, _: Physical<'_>) -> Result<(), DecodeError> {
228        match self {}
229    }
230
231    fn typed_null(self, _: FixedType) -> Result<(), DecodeError> {
232        match self {}
233    }
234
235    fn seq(self, _: Option<usize>) -> Result<Never<()>, DecodeError> {
236        match self {}
237    }
238
239    fn map(self, _: Option<usize>) -> Result<Never<()>, DecodeError> {
240        match self {}
241    }
242
243    fn passthrough<P: Encrypt + Clone>(self, _: P) -> Result<(), DecodeError> {
244        match self {}
245    }
246}
247
248/// Container sinks for a target that has none. Never built.
249pub enum Never<T> {
250    #[doc(hidden)]
251    _Never(core::convert::Infallible, PhantomData<T>),
252}
253
254impl<T> Never<T> {
255    fn absurd<R>(&self) -> R {
256        match *self {
257            Never::_Never(never, _) => match never {},
258        }
259    }
260}
261
262impl<T> SeqSink for Never<T> {
263    type Ok = T;
264    type Error = DecodeError;
265    type Element<'s>
266        = Nothing
267    where
268        Self: 's;
269
270    fn element(&mut self) -> Result<Nothing, DecodeError> {
271        self.absurd()
272    }
273
274    fn end(self) -> Result<T, DecodeError> {
275        self.absurd()
276    }
277}
278
279impl<T> MapSink for Never<T> {
280    type Ok = T;
281    type Error = DecodeError;
282    type Entry<'s>
283        = Nothing
284    where
285        Self: 's;
286
287    fn entry(&mut self, _: &str) -> Result<Nothing, DecodeError> {
288        self.absurd()
289    }
290
291    fn end(self) -> Result<T, DecodeError> {
292        self.absurd()
293    }
294}
295
296macro_rules! int_target {
297    ($($ty:ty),* $(,)?) => {
298        $(
299            impl FromScalar for $ty {
300                const EXPECTED: &'static str = stringify!($ty);
301                fn from_scalar(ty: Option<Logical>, v: Physical<'_>) -> Option<Self> {
302                    match (ty, v) {
303                        (None, Physical::Int(i)) => i
304                            .to_i128()
305                            .and_then(|v| Self::try_from(v).ok())
306                            .or_else(|| i.to_u128().and_then(|v| Self::try_from(v).ok())),
307                        _ => None,
308                    }
309                }
310            }
311        )*
312    };
313}
314
315// `u8` is not a target for the same reason it is not a source: `Vec<u8>` is
316// a byte leaf, and the generic `Vec<T>` sequence target must not overlap it.
317int_target!(i8, i16, i32, i64, i128, u16, u32, u64, u128);
318
319impl FromScalar for bool {
320    const EXPECTED: &'static str = "bool";
321    fn from_scalar(ty: Option<Logical>, v: Physical<'_>) -> Option<Self> {
322        match (ty, v) {
323            (None, Physical::Bool(b)) => Some(b),
324            _ => None,
325        }
326    }
327}
328
329impl FromScalar for f32 {
330    const EXPECTED: &'static str = "f32";
331    fn from_scalar(ty: Option<Logical>, v: Physical<'_>) -> Option<Self> {
332        match (ty, v) {
333            (None, Physical::Float(Float::F32(f))) => Some(f),
334            _ => None,
335        }
336    }
337}
338
339/// Widening from `f32` is exact, so an `f64` target accepts both widths.
340impl FromScalar for f64 {
341    const EXPECTED: &'static str = "f64";
342    fn from_scalar(ty: Option<Logical>, v: Physical<'_>) -> Option<Self> {
343        match (ty, v) {
344            (None, Physical::Float(Float::F64(f))) => Some(f),
345            (None, Physical::Float(Float::F32(f))) => Some(f.into()),
346            _ => None,
347        }
348    }
349}
350
351impl FromScalar for String {
352    const EXPECTED: &'static str = "string";
353    fn from_scalar(ty: Option<Logical>, v: Physical<'_>) -> Option<Self> {
354        match (ty, v) {
355            (None, Physical::Text(s)) => Some(s.to_owned()),
356            _ => None,
357        }
358    }
359}
360
361/// `Vec<u8>` is a byte leaf, as it is on the source side.
362impl FromScalar for Vec<u8> {
363    const EXPECTED: &'static str = "bytes";
364    fn from_scalar(ty: Option<Logical>, v: Physical<'_>) -> Option<Self> {
365        match (ty, v) {
366            (None, Physical::Bytes(b)) => Some(b.to_vec()),
367            _ => None,
368        }
369    }
370}
371
372impl<const N: usize> FromScalar for [u8; N] {
373    const EXPECTED: &'static str = "byte array";
374    fn from_scalar(ty: Option<Logical>, v: Physical<'_>) -> Option<Self> {
375        match (ty, v) {
376            (None, Physical::Bytes(b)) => b.try_into().ok(),
377            _ => None,
378        }
379    }
380
381    /// Built in place inside the wrapper, so the array never passes through a bare temporary.
382    /// The wrapper holds the bytes inline, so a later move can still leave an unwiped copy on the stack.
383    fn from_scalar_protected(ty: Option<Logical>, v: Physical<'_>) -> Option<Protected<Self>> {
384        match (ty, v) {
385            (None, Physical::Bytes(b)) if b.len() == N => {
386                let mut out = Protected::new([0u8; N]);
387                out.risky_inner_mut().copy_from_slice(b);
388                Some(out)
389            }
390            _ => None,
391        }
392    }
393}
394
395#[cfg(feature = "chrono")]
396mod chrono_targets {
397    use super::*;
398    use crate::plaintext::kinds::chrono as conv;
399    use ::chrono::{DateTime, NaiveDate, Utc};
400
401    impl FromScalar for NaiveDate {
402        const EXPECTED: &'static str = "date";
403        fn from_scalar(ty: Option<Logical>, v: Physical<'_>) -> Option<Self> {
404            match (ty, v) {
405                (Some(Logical::Date), Physical::Int(days)) => conv::date(days),
406                _ => None,
407            }
408        }
409    }
410
411    /// Any unit: a JavaScript `Date` in milliseconds decodes as well as a
412    /// Rust timestamp in nanoseconds.
413    impl FromScalar for DateTime<Utc> {
414        const EXPECTED: &'static str = "timestamp";
415        fn from_scalar(ty: Option<Logical>, v: Physical<'_>) -> Option<Self> {
416            match (ty, v) {
417                (Some(Logical::Timestamp(unit)), Physical::Int(count)) => {
418                    conv::timestamp(unit, count)
419                }
420                _ => None,
421            }
422        }
423    }
424}
425
426#[cfg(feature = "rust_decimal")]
427impl FromScalar for rust_decimal::Decimal {
428    const EXPECTED: &'static str = "decimal";
429    fn from_scalar(ty: Option<Logical>, v: Physical<'_>) -> Option<Self> {
430        match (ty, v) {
431            (Some(Logical::Decimal { scale }), Physical::Int(mantissa)) => {
432                crate::plaintext::kinds::decimal::decimal(scale, mantissa)
433            }
434            _ => None,
435        }
436    }
437}
438
439#[cfg(feature = "uuid")]
440impl FromScalar for uuid::Uuid {
441    const EXPECTED: &'static str = "uuid";
442    fn from_scalar(ty: Option<Logical>, v: Physical<'_>) -> Option<Self> {
443        match (ty, v) {
444            (Some(Logical::Uuid), Physical::Bytes(b)) => uuid::Uuid::from_slice(b).ok(),
445            _ => None,
446        }
447    }
448}
449
450/// Somewhere a finished child goes.
451pub trait Put<T> {
452    fn put(self, value: T);
453}
454
455/// The next slot of a sequence.
456pub struct Push<'s, T>(pub &'s mut Vec<T>);
457
458impl<T> Put<T> for Push<'_, T> {
459    fn put(self, value: T) {
460        self.0.push(value);
461    }
462}
463
464/// A map entry: the key it arrived under.
465pub struct Insert<'s, M>(pub &'s mut M, pub String);
466
467impl<T> Put<T> for Insert<'_, HashMap<String, T>> {
468    fn put(self, value: T) {
469        self.0.insert(self.1, value);
470    }
471}
472
473impl<T> Put<T> for Insert<'_, BTreeMap<String, T>> {
474    fn put(self, value: T) {
475        self.0.insert(self.1, value);
476    }
477}
478
479/// A single slot, such as a struct field.
480pub struct Slot<'s, T>(pub &'s mut Option<T>);
481
482impl<T> Put<T> for Slot<'_, T> {
483    fn put(self, value: T) {
484        *self.0 = Some(value);
485    }
486}
487
488/// `T`'s own sink, with its result handed to `O` instead of returned.
489/// This is how every container decodes a child: `Forward(T::sink(), slot)`.
490pub struct Forward<T: Decrypt, O>(pub T::Sink, pub O);
491
492impl<T: Decrypt, O: Put<T>> Sink for Forward<T, O> {
493    type Ok = ();
494    type Error = DecodeError;
495    type Seq = ForwardEnd<T, <T::Sink as Sink>::Seq, O>;
496    type Map = ForwardEnd<T, <T::Sink as Sink>::Map, O>;
497
498    fn scalar(self, ty: Option<Logical>, v: Physical<'_>) -> Result<(), DecodeError> {
499        self.1.put(self.0.scalar(ty, v)?);
500        Ok(())
501    }
502
503    fn typed_null(self, ty: FixedType) -> Result<(), DecodeError> {
504        self.1.put(self.0.typed_null(ty)?);
505        Ok(())
506    }
507
508    fn seq(self, len: Option<usize>) -> Result<Self::Seq, DecodeError> {
509        Ok(ForwardEnd(self.0.seq(len)?, self.1, PhantomData))
510    }
511
512    fn map(self, len: Option<usize>) -> Result<Self::Map, DecodeError> {
513        Ok(ForwardEnd(self.0.map(len)?, self.1, PhantomData))
514    }
515
516    fn passthrough<P: Encrypt + Clone>(self, value: P) -> Result<(), DecodeError> {
517        self.1.put(self.0.passthrough(value)?);
518        Ok(())
519    }
520}
521
522/// A container sink whose `end` hands its result to `O`.
523pub struct ForwardEnd<T, Q, O>(Q, O, PhantomData<T>);
524
525impl<T, Q: SeqSink<Ok = T, Error = DecodeError>, O: Put<T>> SeqSink for ForwardEnd<T, Q, O> {
526    type Ok = ();
527    type Error = DecodeError;
528    type Element<'e>
529        = Q::Element<'e>
530    where
531        Self: 'e;
532
533    fn element(&mut self) -> Result<Self::Element<'_>, DecodeError> {
534        self.0.element()
535    }
536
537    fn end(self) -> Result<(), DecodeError> {
538        self.1.put(self.0.end()?);
539        Ok(())
540    }
541}
542
543impl<T, Q: MapSink<Ok = T, Error = DecodeError>, O: Put<T>> MapSink for ForwardEnd<T, Q, O> {
544    type Ok = ();
545    type Error = DecodeError;
546    type Entry<'e>
547        = Q::Entry<'e>
548    where
549        Self: 'e;
550
551    fn entry(&mut self, key: &str) -> Result<Self::Entry<'_>, DecodeError> {
552        self.0.entry(key)
553    }
554
555    fn end(self) -> Result<(), DecodeError> {
556        self.1.put(self.0.end()?);
557        Ok(())
558    }
559}
560
561/// One of two sinks. The sink a derived struct hands out for an entry is
562/// one of its fields' sinks, which have different types, so `entry`
563/// returns them as a chain of `Either`s. The two sides share an error;
564/// the result is whichever side ran, which nobody reads, since an entry
565/// sink writes into its parent. The chain composes through containers:
566/// the `Seq` of an `Either` is an `Either` of the two `Seq`s, and so on
567/// down.
568pub enum Either<L, R> {
569    Left(L),
570    Right(R),
571}
572
573impl<L: Sink, R: Sink<Error = L::Error>> Sink for Either<L, R> {
574    type Ok = Either<L::Ok, R::Ok>;
575    type Error = L::Error;
576    type Seq = Either<L::Seq, R::Seq>;
577    type Map = Either<L::Map, R::Map>;
578
579    fn scalar(self, ty: Option<Logical>, v: Physical<'_>) -> Result<Self::Ok, Self::Error> {
580        match self {
581            Either::Left(l) => l.scalar(ty, v).map(Either::Left),
582            Either::Right(r) => r.scalar(ty, v).map(Either::Right),
583        }
584    }
585
586    fn typed_null(self, ty: FixedType) -> Result<Self::Ok, Self::Error> {
587        match self {
588            Either::Left(l) => l.typed_null(ty).map(Either::Left),
589            Either::Right(r) => r.typed_null(ty).map(Either::Right),
590        }
591    }
592
593    fn seq(self, len: Option<usize>) -> Result<Self::Seq, Self::Error> {
594        match self {
595            Either::Left(l) => l.seq(len).map(Either::Left),
596            Either::Right(r) => r.seq(len).map(Either::Right),
597        }
598    }
599
600    fn map(self, len: Option<usize>) -> Result<Self::Map, Self::Error> {
601        match self {
602            Either::Left(l) => l.map(len).map(Either::Left),
603            Either::Right(r) => r.map(len).map(Either::Right),
604        }
605    }
606
607    fn passthrough<P: Encrypt + Clone>(self, value: P) -> Result<Self::Ok, Self::Error> {
608        match self {
609            Either::Left(l) => l.passthrough(value).map(Either::Left),
610            Either::Right(r) => r.passthrough(value).map(Either::Right),
611        }
612    }
613}
614
615impl<L: SeqSink, R: SeqSink<Error = L::Error>> SeqSink for Either<L, R> {
616    type Ok = Either<L::Ok, R::Ok>;
617    type Error = L::Error;
618    type Element<'s>
619        = Either<L::Element<'s>, R::Element<'s>>
620    where
621        Self: 's;
622
623    fn element(&mut self) -> Result<Self::Element<'_>, Self::Error> {
624        match self {
625            Either::Left(l) => l.element().map(Either::Left),
626            Either::Right(r) => r.element().map(Either::Right),
627        }
628    }
629
630    fn end(self) -> Result<Self::Ok, Self::Error> {
631        match self {
632            Either::Left(l) => l.end().map(Either::Left),
633            Either::Right(r) => r.end().map(Either::Right),
634        }
635    }
636}
637
638impl<L: MapSink, R: MapSink<Error = L::Error>> MapSink for Either<L, R> {
639    type Ok = Either<L::Ok, R::Ok>;
640    type Error = L::Error;
641    type Entry<'s>
642        = Either<L::Entry<'s>, R::Entry<'s>>
643    where
644        Self: 's;
645
646    fn entry(&mut self, key: &str) -> Result<Self::Entry<'_>, Self::Error> {
647        match self {
648            Either::Left(l) => l.entry(key).map(Either::Left),
649            Either::Right(r) => r.entry(key).map(Either::Right),
650        }
651    }
652
653    fn end(self) -> Result<Self::Ok, Self::Error> {
654        match self {
655            Either::Left(l) => l.end().map(Either::Left),
656            Either::Right(r) => r.end().map(Either::Right),
657        }
658    }
659}
660
661/// A passthrough target: `T` built from a subtree that travelled in the
662/// clear, with the result handed to `O`. A derived struct uses it for a
663/// `#[aead(passthrough)]` field. The subtree is walked into `T`'s own sink,
664/// so it decodes exactly as a sealed `T` would; what it refuses is a
665/// sealed value where a passthrough was expected, since the two are not
666/// interchangeable. Nothing here is authenticated.
667pub struct Clear<T: Decrypt, O>(O, PhantomData<T>);
668
669impl<T: Decrypt, O: Put<T>> Clear<T, O> {
670    pub fn new(out: O) -> Self {
671        Self(out, PhantomData)
672    }
673}
674
675impl<T: Decrypt, O: Put<T>> Sink for Clear<T, O> {
676    type Ok = ();
677    type Error = DecodeError;
678    type Seq = Never<()>;
679    type Map = Never<()>;
680
681    fn scalar(self, _: Option<Logical>, _: Physical<'_>) -> Result<(), DecodeError> {
682        Err(DecodeError::Expected("passthrough"))
683    }
684
685    fn typed_null(self, _: FixedType) -> Result<(), DecodeError> {
686        Err(DecodeError::Expected("passthrough"))
687    }
688
689    fn seq(self, _: Option<usize>) -> Result<Never<()>, DecodeError> {
690        Err(DecodeError::Expected("passthrough"))
691    }
692
693    fn map(self, _: Option<usize>) -> Result<Never<()>, DecodeError> {
694        Err(DecodeError::Expected("passthrough"))
695    }
696
697    fn passthrough<P: Encrypt + Clone>(self, value: P) -> Result<(), DecodeError> {
698        self.0.put(value.visit(T::sink())?);
699        Ok(())
700    }
701}
702
703/// A conversion applied to a sink's result: what a newtype's sink does to
704/// its inner type's result. Fallible, so a newtype whose conversion can
705/// refuse a value (a length-checked string, say) is one `Rewrap` impl, with
706/// the refusal reported as a [`DecodeError`].
707pub trait Rewrap<T> {
708    type Output;
709    fn rewrap(value: T) -> Result<Self::Output, DecodeError>;
710}
711
712/// `S` with its result passed through `W`. A derived newtype's sink is
713/// `Wrapped<Inner::Sink, W>` for a `W` that rewraps the inner value.
714pub struct Wrapped<S, W>(S, PhantomData<W>);
715
716impl<S, W> Wrapped<S, W> {
717    pub fn new(sink: S) -> Self {
718        Self(sink, PhantomData)
719    }
720}
721
722impl<S: Sink<Error = DecodeError>, W: Rewrap<S::Ok>> Sink for Wrapped<S, W> {
723    type Ok = W::Output;
724    type Error = DecodeError;
725    type Seq = WrappedEnd<S::Seq, W>;
726    type Map = WrappedEnd<S::Map, W>;
727
728    fn scalar(self, ty: Option<Logical>, v: Physical<'_>) -> Result<W::Output, DecodeError> {
729        self.0.scalar(ty, v).and_then(W::rewrap)
730    }
731
732    fn typed_null(self, ty: FixedType) -> Result<W::Output, DecodeError> {
733        self.0.typed_null(ty).and_then(W::rewrap)
734    }
735
736    fn seq(self, len: Option<usize>) -> Result<Self::Seq, DecodeError> {
737        Ok(WrappedEnd(self.0.seq(len)?, PhantomData))
738    }
739
740    fn map(self, len: Option<usize>) -> Result<Self::Map, DecodeError> {
741        Ok(WrappedEnd(self.0.map(len)?, PhantomData))
742    }
743
744    fn passthrough<P: Encrypt + Clone>(self, value: P) -> Result<W::Output, DecodeError> {
745        self.0.passthrough(value).and_then(W::rewrap)
746    }
747}
748
749/// A container sink whose `end` passes its result through `W`.
750pub struct WrappedEnd<Q, W>(Q, PhantomData<W>);
751
752impl<Q: SeqSink<Error = DecodeError>, W: Rewrap<Q::Ok>> SeqSink for WrappedEnd<Q, W> {
753    type Ok = W::Output;
754    type Error = DecodeError;
755    type Element<'e>
756        = Q::Element<'e>
757    where
758        Self: 'e;
759
760    fn element(&mut self) -> Result<Self::Element<'_>, DecodeError> {
761        self.0.element()
762    }
763
764    fn end(self) -> Result<W::Output, DecodeError> {
765        self.0.end().and_then(W::rewrap)
766    }
767}
768
769impl<Q: MapSink<Error = DecodeError>, W: Rewrap<Q::Ok>> MapSink for WrappedEnd<Q, W> {
770    type Ok = W::Output;
771    type Error = DecodeError;
772    type Entry<'e>
773        = Q::Entry<'e>
774    where
775        Self: 'e;
776
777    fn entry(&mut self, key: &str) -> Result<Self::Entry<'_>, DecodeError> {
778        self.0.entry(key)
779    }
780
781    fn end(self) -> Result<W::Output, DecodeError> {
782        self.0.end().and_then(W::rewrap)
783    }
784}
785
786/// `Vec<T>`: a sequence, each element decoded by `T`'s sink.
787pub struct List<T>(PhantomData<T>);
788
789impl<T: Decrypt> Sink for List<T> {
790    type Ok = Vec<T>;
791    type Error = DecodeError;
792    type Seq = ListSeq<T>;
793    type Map = Never<Vec<T>>;
794
795    fn scalar(self, _: Option<Logical>, _: Physical<'_>) -> Result<Vec<T>, DecodeError> {
796        Err(DecodeError::Expected("sequence"))
797    }
798
799    fn typed_null(self, _: FixedType) -> Result<Vec<T>, DecodeError> {
800        Err(DecodeError::Expected("sequence"))
801    }
802
803    fn seq(self, len: Option<usize>) -> Result<ListSeq<T>, DecodeError> {
804        Ok(ListSeq(Vec::with_capacity(len.unwrap_or(0).min(1024))))
805    }
806
807    fn map(self, _: Option<usize>) -> Result<Never<Vec<T>>, DecodeError> {
808        Err(DecodeError::Expected("sequence"))
809    }
810
811    fn passthrough<P: Encrypt + Clone>(self, _: P) -> Result<Vec<T>, DecodeError> {
812        Err(DecodeError::Expected("sequence"))
813    }
814}
815
816pub struct ListSeq<T>(Vec<T>);
817
818impl<T: Decrypt> SeqSink for ListSeq<T> {
819    type Ok = Vec<T>;
820    type Error = DecodeError;
821    type Element<'s>
822        = Forward<T, Push<'s, T>>
823    where
824        Self: 's;
825
826    fn element(&mut self) -> Result<Self::Element<'_>, DecodeError> {
827        Ok(Forward(T::sink(), Push(&mut self.0)))
828    }
829
830    fn end(self) -> Result<Vec<T>, DecodeError> {
831        Ok(self.0)
832    }
833}
834
835impl<T: Decrypt> Decrypt for Vec<T> {
836    type Sink = List<T>;
837    fn sink() -> List<T> {
838        List(PhantomData)
839    }
840}
841
842/// `HashMap<String, T>` and `BTreeMap<String, T>`: a map, each value
843/// decoded by `T`'s sink. The walk has already refused repeated keys.
844pub struct Dict<M>(PhantomData<M>);
845
846/// The entries of a [`Dict`].
847pub struct DictEntries<M>(M);
848
849macro_rules! dict_target {
850    ($($map:ident),*) => {
851        $(
852            impl<T: Decrypt> Sink for Dict<$map<String, T>> {
853                type Ok = $map<String, T>;
854                type Error = DecodeError;
855                type Seq = Never<$map<String, T>>;
856                type Map = DictEntries<$map<String, T>>;
857
858                fn scalar(self, _: Option<Logical>, _: Physical<'_>) -> Result<Self::Ok, DecodeError> {
859                    Err(DecodeError::Expected("map"))
860                }
861
862                fn typed_null(self, _: FixedType) -> Result<Self::Ok, DecodeError> {
863                    Err(DecodeError::Expected("map"))
864                }
865
866                fn seq(self, _: Option<usize>) -> Result<Self::Seq, DecodeError> {
867                    Err(DecodeError::Expected("map"))
868                }
869
870                fn map(self, _: Option<usize>) -> Result<Self::Map, DecodeError> {
871                    Ok(DictEntries($map::new()))
872                }
873
874                fn passthrough<P: Encrypt + Clone>(self, _: P) -> Result<Self::Ok, DecodeError> {
875                    Err(DecodeError::Expected("map"))
876                }
877            }
878
879            impl<T: Decrypt> MapSink for DictEntries<$map<String, T>> {
880                type Ok = $map<String, T>;
881                type Error = DecodeError;
882                type Entry<'s>
883                    = Forward<T, Insert<'s, $map<String, T>>>
884                where
885                    Self: 's;
886
887                fn entry(&mut self, key: &str) -> Result<Self::Entry<'_>, DecodeError> {
888                    Ok(Forward(T::sink(), Insert(&mut self.0, key.to_owned())))
889                }
890
891                fn end(self) -> Result<Self::Ok, DecodeError> {
892                    Ok(self.0)
893                }
894            }
895
896            impl<T: Decrypt> Decrypt for $map<String, T> {
897                type Sink = Dict<$map<String, T>>;
898                fn sink() -> Self::Sink {
899                    Dict(PhantomData)
900                }
901            }
902        )*
903    };
904}
905
906dict_target!(HashMap, BTreeMap);
907
908/// `Option<T>`: null and `undefined` are `None`; anything else is `T`.
909/// A typed null is `None` if `T` reads values of its type
910/// ([`Decrypt::reads_null`]), and otherwise refused by `T`'s sink as the
911/// wrong kind.
912///
913/// Since `None` is written as null, `Option<Option<T>>` cannot tell
914/// `Some(None)` from `None`: both read back as `None`.
915pub struct Optional<T: Decrypt>(T::Sink);
916
917impl<T: Decrypt> Sink for Optional<T> {
918    type Ok = Option<T>;
919    type Error = DecodeError;
920    type Seq = Some_<T, <T::Sink as Sink>::Seq>;
921    type Map = Some_<T, <T::Sink as Sink>::Map>;
922
923    fn scalar(self, ty: Option<Logical>, v: Physical<'_>) -> Result<Option<T>, DecodeError> {
924        match (ty, v) {
925            (None | Some(Logical::Undefined), Physical::Null) => Ok(None),
926            _ => self.0.scalar(ty, v).map(Some),
927        }
928    }
929
930    fn typed_null(self, ty: FixedType) -> Result<Option<T>, DecodeError> {
931        if T::reads_null(ty) {
932            return Ok(None);
933        }
934        self.0.typed_null(ty).map(Some)
935    }
936
937    fn seq(self, len: Option<usize>) -> Result<Self::Seq, DecodeError> {
938        Ok(Some_(self.0.seq(len)?, PhantomData))
939    }
940
941    fn map(self, len: Option<usize>) -> Result<Self::Map, DecodeError> {
942        Ok(Some_(self.0.map(len)?, PhantomData))
943    }
944
945    fn passthrough<P: Encrypt + Clone>(self, value: P) -> Result<Option<T>, DecodeError> {
946        self.0.passthrough(value).map(Some)
947    }
948}
949
950/// A container sink whose result is wrapped in `Some`.
951pub struct Some_<T, Q>(Q, PhantomData<T>);
952
953impl<T, Q: SeqSink<Ok = T, Error = DecodeError>> SeqSink for Some_<T, Q> {
954    type Ok = Option<T>;
955    type Error = DecodeError;
956    type Element<'e>
957        = Q::Element<'e>
958    where
959        Self: 'e;
960
961    fn element(&mut self) -> Result<Self::Element<'_>, DecodeError> {
962        self.0.element()
963    }
964
965    fn end(self) -> Result<Option<T>, DecodeError> {
966        self.0.end().map(Some)
967    }
968}
969
970impl<T, Q: MapSink<Ok = T, Error = DecodeError>> MapSink for Some_<T, Q> {
971    type Ok = Option<T>;
972    type Error = DecodeError;
973    type Entry<'e>
974        = Q::Entry<'e>
975    where
976        Self: 'e;
977
978    fn entry(&mut self, key: &str) -> Result<Self::Entry<'_>, DecodeError> {
979        self.0.entry(key)
980    }
981
982    fn end(self) -> Result<Option<T>, DecodeError> {
983        self.0.end().map(Some)
984    }
985}
986
987impl<T: Decrypt> Decrypt for Option<T> {
988    type Sink = Optional<T>;
989    fn sink() -> Optional<T> {
990        Optional(T::sink())
991    }
992
993    fn reads_null(ty: FixedType) -> bool {
994        T::reads_null(ty)
995    }
996}
997
998/// A type that can be decrypted straight into `Protected<Self>`: it names
999/// the sink that builds the wrapped value.
1000///
1001/// This is what makes `Protected<T>` a target. Scalars build in place
1002/// through [`FromScalar::from_scalar_protected`]; `Vec<T>` and `Option<T>`
1003/// build inside the wrapper from the first element, so a failure part way
1004/// wipes what was already decoded. A struct target opts in with its own
1005/// impl (the orphan rule lets the crate that defines the struct write it).
1006pub trait DecryptProtected: Decrypt + Zeroize {
1007    type ProtectedSink: Sink<Ok = Protected<Self>, Error = DecodeError>;
1008    fn protected_sink() -> Self::ProtectedSink;
1009}
1010
1011impl<T: DecryptProtected> Decrypt for Protected<T> {
1012    type Sink = T::ProtectedSink;
1013    fn sink() -> T::ProtectedSink {
1014        T::protected_sink()
1015    }
1016
1017    fn reads_null(ty: FixedType) -> bool {
1018        T::reads_null(ty)
1019    }
1020}
1021
1022/// Any scalar target that can be wiped, read into `Protected`. A heap
1023/// type (`String`, `Vec<u8>`) is copied once, into the wrapper's buffer.
1024/// An inline type (an integer, `[u8; N]`) moves by value, so a move can
1025/// leave an unwiped copy on the stack. The opened leaf's buffer is wiped
1026/// when it drops.
1027impl<T: FromScalar + Zeroize> DecryptProtected for T {
1028    type ProtectedSink = ScalarProtected<T>;
1029    fn protected_sink() -> ScalarProtected<T> {
1030        ScalarProtected(PhantomData)
1031    }
1032}
1033
1034/// The sink for `Protected<T>` of a [`FromScalar`] type. Refuses
1035/// containers and passthrough, as [`ScalarSink`] does.
1036pub struct ScalarProtected<T>(PhantomData<T>);
1037
1038impl<T: FromScalar + Zeroize> Sink for ScalarProtected<T> {
1039    type Ok = Protected<T>;
1040    type Error = DecodeError;
1041    type Seq = Never<Protected<T>>;
1042    type Map = Never<Protected<T>>;
1043
1044    fn scalar(self, ty: Option<Logical>, v: Physical<'_>) -> Result<Protected<T>, DecodeError> {
1045        T::from_scalar_protected(ty, v).ok_or(DecodeError::Expected(T::EXPECTED))
1046    }
1047
1048    fn typed_null(self, _: FixedType) -> Result<Protected<T>, DecodeError> {
1049        Err(DecodeError::Expected(T::EXPECTED))
1050    }
1051
1052    fn seq(self, _: Option<usize>) -> Result<Self::Seq, DecodeError> {
1053        Err(DecodeError::Expected(T::EXPECTED))
1054    }
1055
1056    fn map(self, _: Option<usize>) -> Result<Self::Map, DecodeError> {
1057        Err(DecodeError::Expected(T::EXPECTED))
1058    }
1059
1060    fn passthrough<P: Encrypt + Clone>(self, _: P) -> Result<Protected<T>, DecodeError> {
1061        Err(DecodeError::Expected(T::EXPECTED))
1062    }
1063}
1064
1065/// `Protected<Vec<T>>`: a sequence built inside the wrapper, each element
1066/// decoded by `Protected<T>`'s sink, so nested containers are protected
1067/// too.
1068///
1069/// `T` needs [`DecryptProtected`], as `Vec<T>` needs [`Decrypt`]; neither
1070/// covers `u8`, so this does not overlap `Vec<u8>`, the byte leaf.
1071impl<T: DecryptProtected> DecryptProtected for Vec<T> {
1072    type ProtectedSink = ProtectedList<T>;
1073    fn protected_sink() -> ProtectedList<T> {
1074        ProtectedList(PhantomData)
1075    }
1076}
1077
1078/// The sink for `Protected<Vec<T>>`.
1079pub struct ProtectedList<T>(PhantomData<T>);
1080
1081impl<T: DecryptProtected> Sink for ProtectedList<T> {
1082    type Ok = Protected<Vec<T>>;
1083    type Error = DecodeError;
1084    type Seq = ProtectedListSeq<T>;
1085    type Map = Never<Protected<Vec<T>>>;
1086
1087    fn scalar(self, _: Option<Logical>, _: Physical<'_>) -> Result<Self::Ok, DecodeError> {
1088        Err(DecodeError::Expected("sequence"))
1089    }
1090
1091    fn typed_null(self, _: FixedType) -> Result<Self::Ok, DecodeError> {
1092        Err(DecodeError::Expected("sequence"))
1093    }
1094
1095    fn seq(self, len: Option<usize>) -> Result<ProtectedListSeq<T>, DecodeError> {
1096        let items = Vec::with_capacity(len.unwrap_or(0).min(1024));
1097        Ok(ProtectedListSeq(Protected::new(items)))
1098    }
1099
1100    fn map(self, _: Option<usize>) -> Result<Self::Map, DecodeError> {
1101        Err(DecodeError::Expected("sequence"))
1102    }
1103
1104    fn passthrough<P: Encrypt + Clone>(self, _: P) -> Result<Self::Ok, DecodeError> {
1105        Err(DecodeError::Expected("sequence"))
1106    }
1107}
1108
1109/// The elements of a [`ProtectedList`], kept inside the wrapper. Dropped
1110/// part way, it zeroizes every element decoded so far.
1111pub struct ProtectedListSeq<T: Zeroize>(Protected<Vec<T>>);
1112
1113impl<T: DecryptProtected> SeqSink for ProtectedListSeq<T> {
1114    type Ok = Protected<Vec<T>>;
1115    type Error = DecodeError;
1116    type Element<'s>
1117        = Forward<Protected<T>, ProtectedPush<'s, T>>
1118    where
1119        Self: 's;
1120
1121    fn element(&mut self) -> Result<Self::Element<'_>, DecodeError> {
1122        Ok(Forward(
1123            T::protected_sink(),
1124            ProtectedPush(self.0.risky_inner_mut()),
1125        ))
1126    }
1127
1128    fn end(self) -> Result<Protected<Vec<T>>, DecodeError> {
1129        Ok(self.0)
1130    }
1131}
1132
1133/// The next slot of a protected sequence. A full vector grows into a new
1134/// buffer and wipes the old one, since a `Vec` that regrows by itself
1135/// frees its old buffer with the elements' bytes still in it.
1136pub struct ProtectedPush<'s, T: Zeroize>(&'s mut Vec<T>);
1137
1138impl<T: Zeroize> Put<Protected<T>> for ProtectedPush<'_, T> {
1139    fn put(self, value: Protected<T>) {
1140        if self.0.len() == self.0.capacity() {
1141            let mut grown = Vec::with_capacity(self.0.capacity().max(4) * 2);
1142            grown.append(self.0);
1143            // `append` moved the elements out; wipe the bytes they left.
1144            self.0.zeroize();
1145            *self.0 = grown;
1146        }
1147        self.0.push(value.risky_unwrap());
1148    }
1149}
1150
1151/// `Protected<Option<T>>`: null and `undefined` are `None`; anything else
1152/// is built by `Protected<T>`'s sink and moved into the wrapper's `Some`.
1153impl<T: DecryptProtected> DecryptProtected for Option<T> {
1154    type ProtectedSink = ProtectedOptional<T>;
1155    fn protected_sink() -> ProtectedOptional<T> {
1156        ProtectedOptional(T::protected_sink())
1157    }
1158}
1159
1160/// The sink for `Protected<Option<T>>`.
1161pub struct ProtectedOptional<T: DecryptProtected>(T::ProtectedSink);
1162
1163impl<T: DecryptProtected> Sink for ProtectedOptional<T> {
1164    type Ok = Protected<Option<T>>;
1165    type Error = DecodeError;
1166    type Seq = SomeProtected<T, <T::ProtectedSink as Sink>::Seq>;
1167    type Map = SomeProtected<T, <T::ProtectedSink as Sink>::Map>;
1168
1169    fn scalar(self, ty: Option<Logical>, v: Physical<'_>) -> Result<Self::Ok, DecodeError> {
1170        match (ty, v) {
1171            (None | Some(Logical::Undefined), Physical::Null) => Ok(Protected::new(None)),
1172            _ => self.0.scalar(ty, v).map(some),
1173        }
1174    }
1175
1176    fn typed_null(self, ty: FixedType) -> Result<Self::Ok, DecodeError> {
1177        if T::reads_null(ty) {
1178            return Ok(Protected::new(None));
1179        }
1180        self.0.typed_null(ty).map(some)
1181    }
1182
1183    fn seq(self, len: Option<usize>) -> Result<Self::Seq, DecodeError> {
1184        Ok(SomeProtected(self.0.seq(len)?, PhantomData))
1185    }
1186
1187    fn map(self, len: Option<usize>) -> Result<Self::Map, DecodeError> {
1188        Ok(SomeProtected(self.0.map(len)?, PhantomData))
1189    }
1190
1191    fn passthrough<P: Encrypt + Clone>(self, value: P) -> Result<Self::Ok, DecodeError> {
1192        self.0.passthrough(value).map(some)
1193    }
1194}
1195
1196/// Move a protected value into a protected `Some`.
1197fn some<T: Zeroize>(value: Protected<T>) -> Protected<Option<T>> {
1198    value.map(Some)
1199}
1200
1201/// Any sink, with its result moved into `Protected` when it is done: the
1202/// simplest [`DecryptProtected`] sink for a struct target, as
1203/// `Wrap(MyStruct::sink())`.
1204///
1205/// The value is built bare and wrapped at the end, so a walk that fails
1206/// part way drops what it had built without wiping it. A target that holds
1207/// secrets in its own fields can do better by building each field inside
1208/// its own wrapper, as [`ProtectedList`] does.
1209pub struct Wrap<S>(pub S);
1210
1211impl<S> Sink for Wrap<S>
1212where
1213    S: Sink<Error = DecodeError>,
1214    S::Ok: Zeroize,
1215{
1216    type Ok = Protected<S::Ok>;
1217    type Error = DecodeError;
1218    type Seq = WrapEnd<S::Seq>;
1219    type Map = WrapEnd<S::Map>;
1220
1221    fn scalar(self, ty: Option<Logical>, v: Physical<'_>) -> Result<Self::Ok, DecodeError> {
1222        self.0.scalar(ty, v).map(Protected::new)
1223    }
1224
1225    fn typed_null(self, ty: FixedType) -> Result<Self::Ok, DecodeError> {
1226        self.0.typed_null(ty).map(Protected::new)
1227    }
1228
1229    fn seq(self, len: Option<usize>) -> Result<Self::Seq, DecodeError> {
1230        Ok(WrapEnd(self.0.seq(len)?))
1231    }
1232
1233    fn map(self, len: Option<usize>) -> Result<Self::Map, DecodeError> {
1234        Ok(WrapEnd(self.0.map(len)?))
1235    }
1236
1237    fn passthrough<P: Encrypt + Clone>(self, value: P) -> Result<Self::Ok, DecodeError> {
1238        self.0.passthrough(value).map(Protected::new)
1239    }
1240}
1241
1242/// A container sink whose result is moved into `Protected` at its end.
1243pub struct WrapEnd<Q>(Q);
1244
1245impl<Q> SeqSink for WrapEnd<Q>
1246where
1247    Q: SeqSink<Error = DecodeError>,
1248    Q::Ok: Zeroize,
1249{
1250    type Ok = Protected<Q::Ok>;
1251    type Error = DecodeError;
1252    type Element<'e>
1253        = Q::Element<'e>
1254    where
1255        Self: 'e;
1256
1257    fn element(&mut self) -> Result<Self::Element<'_>, DecodeError> {
1258        self.0.element()
1259    }
1260
1261    fn end(self) -> Result<Self::Ok, DecodeError> {
1262        self.0.end().map(Protected::new)
1263    }
1264}
1265
1266impl<Q> MapSink for WrapEnd<Q>
1267where
1268    Q: MapSink<Error = DecodeError>,
1269    Q::Ok: Zeroize,
1270{
1271    type Ok = Protected<Q::Ok>;
1272    type Error = DecodeError;
1273    type Entry<'e>
1274        = Q::Entry<'e>
1275    where
1276        Self: 'e;
1277
1278    fn entry(&mut self, key: &str) -> Result<Self::Entry<'_>, DecodeError> {
1279        self.0.entry(key)
1280    }
1281
1282    fn end(self) -> Result<Self::Ok, DecodeError> {
1283        self.0.end().map(Protected::new)
1284    }
1285}
1286
1287/// A container sink whose protected result is moved into a protected
1288/// `Some`.
1289pub struct SomeProtected<T, Q>(Q, PhantomData<T>);
1290
1291impl<T, Q> SeqSink for SomeProtected<T, Q>
1292where
1293    T: Zeroize,
1294    Q: SeqSink<Ok = Protected<T>, Error = DecodeError>,
1295{
1296    type Ok = Protected<Option<T>>;
1297    type Error = DecodeError;
1298    type Element<'e>
1299        = Q::Element<'e>
1300    where
1301        Self: 'e;
1302
1303    fn element(&mut self) -> Result<Self::Element<'_>, DecodeError> {
1304        self.0.element()
1305    }
1306
1307    fn end(self) -> Result<Protected<Option<T>>, DecodeError> {
1308        self.0.end().map(some)
1309    }
1310}
1311
1312impl<T, Q> MapSink for SomeProtected<T, Q>
1313where
1314    T: Zeroize,
1315    Q: MapSink<Ok = Protected<T>, Error = DecodeError>,
1316{
1317    type Ok = Protected<Option<T>>;
1318    type Error = DecodeError;
1319    type Entry<'e>
1320        = Q::Entry<'e>
1321    where
1322        Self: 'e;
1323
1324    fn entry(&mut self, key: &str) -> Result<Self::Entry<'_>, DecodeError> {
1325        self.0.entry(key)
1326    }
1327
1328    fn end(self) -> Result<Protected<Option<T>>, DecodeError> {
1329        self.0.end().map(some)
1330    }
1331}
1332
1333#[cfg(test)]
1334mod tests {
1335    use super::*;
1336    use crate::plaintext::{Int, Raw, Width};
1337    use crate::seal::mock::{Mock, Remote};
1338    use crate::{encrypt, encrypt_async};
1339    use futures_executor::block_on;
1340
1341    fn round_trip<T: Decrypt>(
1342        p: impl Encrypt,
1343    ) -> Result<T, DecryptError<DecodeError, crate::seal::mock::Refused>> {
1344        decrypt(&Mock, encrypt(p, &Mock, "ctx").expect("encrypts"), "ctx")
1345    }
1346
1347    fn expected<T>(
1348        r: Result<T, DecryptError<DecodeError, crate::seal::mock::Refused>>,
1349    ) -> &'static str {
1350        match r {
1351            Err(DecryptError::Sink(DecodeError::Expected(what))) => what,
1352            Err(other) => panic!("{other:?}"),
1353            Ok(_) => panic!("decoded"),
1354        }
1355    }
1356
1357    #[test]
1358    fn scalars_round_trip() {
1359        assert_eq!(round_trip::<u32>(34u32).expect("u32"), 34);
1360        assert_eq!(round_trip::<i128>(-5i64).expect("i128"), -5);
1361        assert!(round_trip::<bool>(true).expect("bool"));
1362        assert_eq!(round_trip::<f64>(2.5f64).expect("f64"), 2.5);
1363        assert_eq!(round_trip::<f64>(2.5f32).expect("f64 from f32"), 2.5);
1364        assert_eq!(round_trip::<String>("Ada").expect("string"), "Ada");
1365        assert_eq!(round_trip::<Vec<u8>>(vec![1u8, 2]).expect("bytes"), [1, 2]);
1366        assert_eq!(round_trip::<[u8; 2]>(vec![1u8, 2]).expect("array"), [1, 2]);
1367        assert_eq!(
1368            round_trip::<Protected<String>>(Protected::new(String::from("pw")))
1369                .expect("protected")
1370                .risky_ref(),
1371            "pw"
1372        );
1373        assert_eq!(
1374            round_trip::<Protected<Vec<u8>>>(vec![9u8])
1375                .expect("protected")
1376                .risky_ref(),
1377            &[9]
1378        );
1379    }
1380
1381    #[test]
1382    fn integer_targets_read_the_value_not_the_width() {
1383        assert_eq!(round_trip::<u32>(34i8).expect("widens"), 34);
1384        assert_eq!(round_trip::<i8>(34u64).expect("narrows"), 34);
1385        assert_eq!(
1386            round_trip::<u128>(Raw(None, Physical::Int(Int::U128(u128::MAX)))).expect("u128"),
1387            u128::MAX
1388        );
1389        assert_eq!(expected(round_trip::<u32>(-1i8)), "u32");
1390        assert_eq!(expected(round_trip::<i8>(300u16)), "i8");
1391        assert_eq!(
1392            expected(round_trip::<i128>(Raw(
1393                None,
1394                Physical::Int(Int::U128(u128::MAX))
1395            ))),
1396            "i128"
1397        );
1398    }
1399
1400    #[test]
1401    fn the_wrong_kind_is_refused_by_name() {
1402        assert_eq!(expected(round_trip::<String>(34u32)), "string");
1403        assert_eq!(expected(round_trip::<u32>("34")), "u32");
1404        assert_eq!(expected(round_trip::<f32>(2.5f64)), "f32");
1405        assert_eq!(expected(round_trip::<bool>(vec![true])), "bool");
1406        assert_eq!(expected(round_trip::<Vec<u32>>(34u32)), "sequence");
1407        assert_eq!(expected(round_trip::<[u8; 4]>(vec![1u8, 2])), "byte array");
1408        // A logical type is not its physical value.
1409        assert_eq!(
1410            expected(round_trip::<i32>(Raw(
1411                Some(Logical::Date),
1412                Physical::Int(Int::I32(0))
1413            ))),
1414            "i32"
1415        );
1416    }
1417
1418    #[test]
1419    fn containers_round_trip() {
1420        assert_eq!(
1421            round_trip::<Vec<String>>(vec!["Ada", "Grace"]).expect("strings"),
1422            ["Ada", "Grace"]
1423        );
1424        assert_eq!(
1425            round_trip::<Vec<Vec<u32>>>(vec![vec![1u32, 2], vec![], vec![3]]).expect("nested"),
1426            [vec![1, 2], vec![], vec![3]]
1427        );
1428        assert_eq!(
1429            round_trip::<Vec<u32>>(Vec::<u32>::new()).expect("empty"),
1430            Vec::<u32>::new()
1431        );
1432    }
1433
1434    /// A typed null as a host would describe it.
1435    struct Null(FixedType);
1436
1437    impl Encrypt for Null {
1438        fn visit<S: Sink>(self, sink: S) -> Result<S::Ok, S::Error> {
1439            sink.typed_null(self.0)
1440        }
1441    }
1442
1443    fn plain(width: Width) -> FixedType {
1444        FixedType::plain(width).expect("fixed")
1445    }
1446
1447    #[test]
1448    fn a_typed_null_reads_as_none_for_an_option_of_a_type_that_reads_its_values() {
1449        // Sealed by `Option<T>`'s own `None`, and read back by it.
1450        assert_eq!(round_trip::<Option<u32>>(None::<u32>).expect("u32"), None);
1451        assert_eq!(round_trip::<Option<i8>>(None::<i8>).expect("i8"), None);
1452        assert_eq!(round_trip::<Option<f32>>(None::<f32>).expect("f32"), None);
1453        assert_eq!(
1454            round_trip::<Option<Option<i64>>>(None::<i64>).expect("nested"),
1455            None
1456        );
1457        assert_eq!(
1458            round_trip::<Vec<Option<u16>>>(vec![None, Some(3u16)]).expect("elements"),
1459            [None, Some(3)]
1460        );
1461        // A widened field reads its old `None`s as it reads its old values.
1462        assert_eq!(round_trip::<Option<u64>>(None::<u32>).expect("wider"), None);
1463        assert_eq!(
1464            round_trip::<Option<i8>>(None::<u64>).expect("narrower"),
1465            None
1466        );
1467        assert_eq!(round_trip::<Option<f64>>(None::<f32>).expect("f64"), None);
1468    }
1469
1470    #[test]
1471    fn a_typed_null_of_a_type_the_target_does_not_read_is_the_wrong_kind() {
1472        let u32_null = || Null(plain(Width::U32));
1473        assert_eq!(expected(round_trip::<Option<f32>>(u32_null())), "f32");
1474        assert_eq!(expected(round_trip::<Option<String>>(u32_null())), "string");
1475        assert_eq!(expected(round_trip::<Option<Vec<u8>>>(u32_null())), "bytes");
1476        assert_eq!(
1477            expected(round_trip::<Option<Vec<u32>>>(u32_null())),
1478            "sequence"
1479        );
1480        assert_eq!(expected(round_trip::<Option<f32>>(None::<f64>)), "f32");
1481        assert_eq!(expected(round_trip::<Option<u32>>(None::<f32>)), "u32");
1482        // A logical type over the same int is not that int.
1483        let date = FixedType::new(Some(Logical::Date), Width::I32).expect("fixed");
1484        assert_eq!(expected(round_trip::<Option<i32>>(Null(date))), "i32");
1485    }
1486
1487    #[test]
1488    fn a_typed_null_is_not_a_value() {
1489        assert_eq!(expected(round_trip::<u32>(None::<u32>)), "u32");
1490        assert_eq!(expected(round_trip::<f64>(None::<f64>)), "f64");
1491        assert_eq!(expected(round_trip::<Vec<u32>>(None::<u32>)), "sequence");
1492        assert_eq!(
1493            expected(round_trip::<HashMap<String, u32>>(None::<u32>)),
1494            "map"
1495        );
1496        assert_eq!(expected(round_trip::<Protected<u32>>(None::<u32>)), "u32");
1497    }
1498
1499    #[test]
1500    fn the_plain_null_still_reads_as_none_for_any_option() {
1501        // What every writer sealed before typed nulls, and still seals for
1502        // a type with no fixed width.
1503        assert_eq!(
1504            round_trip::<Option<u32>>(Raw(None, Physical::Null)).expect("u32"),
1505            None
1506        );
1507        assert_eq!(
1508            round_trip::<Protected<Option<u32>>>(Raw(None, Physical::Null))
1509                .expect("protected")
1510                .risky_ref(),
1511            &None
1512        );
1513    }
1514
1515    #[test]
1516    fn a_protected_option_reads_its_typed_null() {
1517        assert_eq!(
1518            round_trip::<Protected<Option<u32>>>(None::<u32>)
1519                .expect("none")
1520                .risky_ref(),
1521            &None
1522        );
1523        assert_eq!(
1524            expected(round_trip::<Protected<Option<f32>>>(None::<u32>)),
1525            "f32"
1526        );
1527    }
1528
1529    /// What every built-in source seals for `None`, its target reads back.
1530    #[test]
1531    fn every_target_reads_its_own_sources_none() {
1532        fn own<T: Encrypt + Decrypt>() {
1533            let ty = <T as Encrypt>::FIXED.expect("fixed width");
1534            assert!(<T as Decrypt>::reads_null(ty), "{ty:?}");
1535            assert!(<Option<T> as Decrypt>::reads_null(ty), "{ty:?}");
1536        }
1537        own::<i8>();
1538        own::<i16>();
1539        own::<i32>();
1540        own::<i64>();
1541        own::<i128>();
1542        own::<u16>();
1543        own::<u32>();
1544        own::<u64>();
1545        own::<u128>();
1546        own::<f32>();
1547        own::<f64>();
1548        // And a type with no fixed width reads none.
1549        assert!(!<String as Decrypt>::reads_null(plain(Width::U32)));
1550        assert!(!<Vec<u32> as Decrypt>::reads_null(plain(Width::U32)));
1551        assert!(!<bool as Decrypt>::reads_null(plain(Width::U8)));
1552        // `Option` and `Protected` read whatever their inner target reads.
1553        assert!(!<Option<String> as Decrypt>::reads_null(plain(Width::U32)));
1554        assert!(<Protected<u32> as Decrypt>::reads_null(plain(Width::U32)));
1555        assert!(!<Protected<String> as Decrypt>::reads_null(plain(
1556            Width::U32
1557        )));
1558    }
1559
1560    #[test]
1561    fn option_reads_null_and_undefined_as_none() {
1562        assert_eq!(round_trip::<Option<u32>>(None::<u32>).expect("none"), None);
1563        assert_eq!(
1564            round_trip::<Option<u32>>(Some(7u32)).expect("some"),
1565            Some(7)
1566        );
1567        assert_eq!(
1568            round_trip::<Option<u32>>(Raw(Some(Logical::Undefined), Physical::Null))
1569                .expect("undefined"),
1570            None
1571        );
1572        assert_eq!(
1573            round_trip::<Option<Vec<u32>>>(Some(vec![1u32])).expect("some seq"),
1574            Some(vec![1])
1575        );
1576        assert_eq!(
1577            round_trip::<Vec<Option<u32>>>(vec![Some(1u32), None]).expect("options"),
1578            [Some(1), None]
1579        );
1580        assert_eq!(expected(round_trip::<Option<u32>>("x")), "u32");
1581    }
1582
1583    #[test]
1584    fn a_typed_target_works_through_an_async_cipher() {
1585        let remote = Remote::new(true);
1586        let sealed = block_on(encrypt_async(vec![1u32, 2], &remote, ())).expect("encrypts");
1587        let out: Vec<u32> = block_on(decrypt_async(&remote, sealed, ())).expect("decrypts");
1588        assert_eq!(out, [1, 2]);
1589        assert_eq!(remote.calls(), 2);
1590    }
1591
1592    #[test]
1593    fn sync_and_async_decrypt_agree() {
1594        let mut value = BTreeMap::new();
1595        value.insert(String::from("a"), vec![Some(1u32), None]);
1596        value.insert(String::from("b"), vec![]);
1597        // The mock is deterministic, so both are the same ciphertext.
1598        let sealed = || encrypt(value.clone(), &Mock, "ctx").expect("encrypts");
1599        let sync: BTreeMap<String, Vec<Option<u32>>> =
1600            decrypt(&Mock, sealed(), "ctx").expect("sync");
1601        let remote = Remote::new(true);
1602        let async_: BTreeMap<String, Vec<Option<u32>>> =
1603            block_on(decrypt_async(&remote, sealed(), "ctx")).expect("async");
1604        assert_eq!(sync, async_);
1605        assert_eq!(sync, value);
1606    }
1607
1608    #[test]
1609    fn maps_round_trip() {
1610        let mut hash = HashMap::new();
1611        hash.insert(String::from("a"), 1u32);
1612        hash.insert(String::from("b"), 2u32);
1613        assert_eq!(
1614            round_trip::<HashMap<String, u32>>(hash.clone()).expect("hash"),
1615            hash
1616        );
1617        let mut tree = BTreeMap::new();
1618        tree.insert("xs", vec![String::from("Ada")]);
1619        tree.insert("ys", vec![]);
1620        let back = round_trip::<BTreeMap<String, Vec<String>>>(tree).expect("tree");
1621        assert_eq!(back["xs"], ["Ada"]);
1622        assert!(back["ys"].is_empty());
1623        assert!(
1624            round_trip::<HashMap<String, u32>>(HashMap::<String, u32>::new())
1625                .expect("empty")
1626                .is_empty()
1627        );
1628        assert_eq!(
1629            expected(round_trip::<HashMap<String, u32>>(vec![1u32])),
1630            "map"
1631        );
1632        assert_eq!(expected(round_trip::<BTreeMap<String, u32>>(1u32)), "map");
1633        // A map's value of the wrong kind is refused by the value's name.
1634        let mut bad = BTreeMap::new();
1635        bad.insert("a", "x");
1636        assert_eq!(expected(round_trip::<BTreeMap<String, u32>>(bad)), "u32");
1637    }
1638
1639    #[test]
1640    fn any_wipeable_scalar_reads_into_protected() {
1641        assert_eq!(
1642            *round_trip::<Protected<u64>>(34u64)
1643                .expect("u64")
1644                .risky_ref(),
1645            34
1646        );
1647        assert_eq!(
1648            round_trip::<Protected<[u8; 32]>>([7u8; 32])
1649                .expect("array")
1650                .risky_ref(),
1651            &[7; 32]
1652        );
1653        assert_eq!(
1654            expected(round_trip::<Protected<[u8; 4]>>(vec![1u8, 2])),
1655            "byte array"
1656        );
1657        assert_eq!(expected(round_trip::<Protected<u64>>("x")), "u64");
1658    }
1659
1660    #[test]
1661    fn a_scalar_target_refuses_a_map_and_a_passthrough() {
1662        let mut map = BTreeMap::new();
1663        map.insert("a", 1u32);
1664        assert_eq!(expected(round_trip::<u32>(map)), "u32");
1665
1666        // A passthrough is unauthenticated, so it must never stand in for a
1667        // sealed leaf.
1668        #[derive(Clone)]
1669        struct Clear;
1670        impl Encrypt for Clear {
1671            fn visit<S: Sink>(self, sink: S) -> Result<S::Ok, S::Error> {
1672                let mut seq = sink.seq(Some(2))?;
1673                seq.element()?.passthrough(7u16)?;
1674                8u16.visit(seq.element()?)?;
1675                seq.end()
1676            }
1677        }
1678        assert_eq!(expected(round_trip::<Vec<u16>>(Clear)), "u16");
1679        assert_eq!(expected(round_trip::<Vec<Option<u16>>>(Clear)), "u16");
1680    }
1681
1682    #[test]
1683    fn nested_maps_are_handed_up_to_their_container() {
1684        let mut row = BTreeMap::new();
1685        row.insert(String::from("a"), 1u32);
1686        let rows = vec![row.clone(), row.clone()];
1687        assert_eq!(
1688            round_trip::<Vec<BTreeMap<String, u32>>>(rows.clone()).expect("decodes"),
1689            rows
1690        );
1691        assert_eq!(
1692            round_trip::<Option<BTreeMap<String, u32>>>(Some(row.clone())).expect("decodes"),
1693            Some(row)
1694        );
1695    }
1696
1697    #[test]
1698    fn a_list_target_refuses_a_passthrough() {
1699        struct Clear;
1700        impl Encrypt for Clear {
1701            fn visit<S: Sink>(self, sink: S) -> Result<S::Ok, S::Error> {
1702                sink.passthrough(vec![1u16])
1703            }
1704        }
1705        assert_eq!(expected(round_trip::<Vec<u16>>(Clear)), "sequence");
1706    }
1707
1708    #[test]
1709    fn f32_reads_only_an_f32() {
1710        assert_eq!(round_trip::<f32>(1.5f32).expect("decodes"), 1.5);
1711        assert_eq!(expected(round_trip::<f32>(1.5f64)), "f32");
1712    }
1713
1714    /// `Clear` only accepts a passthrough, and decodes it through the
1715    /// target's own sink.
1716    #[test]
1717    fn clear_decodes_a_passthrough_and_nothing_else() {
1718        let mut held = None;
1719        Clear::<Vec<u16>, _>::new(Slot(&mut held))
1720            .passthrough(vec![1u16, 2])
1721            .expect("decodes");
1722        assert_eq!(held, Some(vec![1, 2]));
1723        let refused = |r: Result<(), DecodeError>| {
1724            assert!(matches!(r, Err(DecodeError::Expected("passthrough"))))
1725        };
1726        let mut held: Option<u16> = None;
1727        refused(Clear::<u16, _>::new(Slot(&mut held)).scalar(None, Physical::Null));
1728        refused(Clear::<u16, _>::new(Slot(&mut held)).typed_null(plain(Width::U16)));
1729        refused(Clear::<u16, _>::new(Slot(&mut held)).seq(None).map(|_| ()));
1730        refused(Clear::<u16, _>::new(Slot(&mut held)).map(None).map(|_| ()));
1731        assert!(matches!(
1732            Clear::<u16, _>::new(Slot(&mut held)).passthrough("x"),
1733            Err(DecodeError::Expected("u16"))
1734        ));
1735    }
1736
1737    /// A newtype's conversion can refuse a value, and the refusal comes
1738    /// out as the sink's error wherever it happens: on a scalar, or at the
1739    /// end of a container.
1740    #[test]
1741    fn a_wrap_can_refuse_what_it_is_handed() {
1742        struct AtMostTwo;
1743        impl Rewrap<Vec<u16>> for AtMostTwo {
1744            type Output = Vec<u16>;
1745            fn rewrap(v: Vec<u16>) -> Result<Vec<u16>, DecodeError> {
1746                (v.len() <= 2)
1747                    .then_some(v)
1748                    .ok_or(DecodeError::Expected("at most two"))
1749            }
1750        }
1751        struct Even;
1752        impl Rewrap<u16> for Even {
1753            type Output = u16;
1754            fn rewrap(v: u16) -> Result<u16, DecodeError> {
1755                v.is_multiple_of(2)
1756                    .then_some(v)
1757                    .ok_or(DecodeError::Expected("even"))
1758            }
1759        }
1760        let short = vec![1u16, 2].visit(Wrapped::<_, AtMostTwo>::new(Vec::<u16>::sink()));
1761        assert_eq!(short.expect("two"), [1, 2]);
1762        let long = vec![1u16, 2, 3].visit(Wrapped::<_, AtMostTwo>::new(Vec::<u16>::sink()));
1763        assert!(matches!(long, Err(DecodeError::Expected("at most two"))));
1764        assert_eq!(
1765            4u16.visit(Wrapped::<_, Even>::new(u16::sink()))
1766                .expect("even"),
1767            4
1768        );
1769        assert!(matches!(
1770            5u16.visit(Wrapped::<_, Even>::new(u16::sink())),
1771            Err(DecodeError::Expected("even"))
1772        ));
1773        assert!(matches!(
1774            DecodeError::unknown_key("k"),
1775            DecodeError::UnknownKey(k) if k == "k"
1776        ));
1777        assert!(matches!(
1778            DecodeError::duplicate_key("k"),
1779            DecodeError::DuplicateKey(k) if k == "k"
1780        ));
1781    }
1782
1783    #[test]
1784    fn a_slot_holds_what_is_put() {
1785        let mut held = None;
1786        Slot(&mut held).put(3u8);
1787        assert_eq!(held, Some(3));
1788    }
1789
1790    #[test]
1791    fn some_none_reads_back_as_none() {
1792        assert_eq!(
1793            round_trip::<Option<Option<u32>>>(Some(None::<u32>)).expect("decodes"),
1794            None
1795        );
1796        assert_eq!(
1797            round_trip::<Option<Option<u32>>>(Some(Some(1u32))).expect("decodes"),
1798            Some(Some(1))
1799        );
1800    }
1801
1802    #[test]
1803    fn decode_errors_are_std_errors() {
1804        let e: Box<dyn core::error::Error> = Box::new(DecodeError::Expected("u32"));
1805        assert_eq!(e.to_string(), "expected u32");
1806        assert!(core::error::Error::source(&DecodeError::Expected("u32")).is_none());
1807        let source = DecodeError::Source(SourceError::new(core::fmt::Error));
1808        assert!(core::error::Error::source(&source).is_some());
1809    }
1810
1811    #[cfg(feature = "chrono")]
1812    #[test]
1813    fn chrono_targets_accept_any_unit() {
1814        use crate::plaintext::TimeUnit;
1815        use ::chrono::{DateTime, NaiveDate};
1816        let date = NaiveDate::from_ymd_opt(2024, 2, 29).expect("date");
1817        assert_eq!(round_trip::<NaiveDate>(date).expect("date"), date);
1818        let ts = DateTime::from_timestamp(1_700_000_000, 123_456_789).expect("ts");
1819        assert_eq!(round_trip::<DateTime<_>>(ts).expect("ts"), ts);
1820        // A JavaScript `Date` is milliseconds.
1821        let js = Raw(
1822            Some(Logical::Timestamp(TimeUnit::Millis)),
1823            Physical::Int(Int::I64(1_700_000_000_123)),
1824        );
1825        assert_eq!(
1826            round_trip::<DateTime<_>>(js).expect("ms"),
1827            DateTime::from_timestamp(1_700_000_000, 123_000_000).expect("ts")
1828        );
1829        assert_eq!(expected(round_trip::<NaiveDate>(0i32)), "date");
1830    }
1831
1832    #[cfg(feature = "rust_decimal")]
1833    #[test]
1834    fn decimal_round_trips_with_its_scale() {
1835        let d: rust_decimal::Decimal = "1.50".parse().expect("decimal");
1836        let back = round_trip::<rust_decimal::Decimal>(d).expect("decimal");
1837        assert_eq!(back, d);
1838        assert_eq!(back.scale(), 2);
1839        assert_eq!(
1840            expected(round_trip::<rust_decimal::Decimal>(150u32)),
1841            "decimal"
1842        );
1843    }
1844
1845    #[cfg(feature = "uuid")]
1846    #[test]
1847    fn uuid_round_trips() {
1848        let id = uuid::Uuid::from_bytes([5; 16]);
1849        assert_eq!(round_trip::<uuid::Uuid>(id).expect("uuid"), id);
1850        assert_eq!(expected(round_trip::<uuid::Uuid>(vec![5u8; 16])), "uuid");
1851    }
1852
1853    #[test]
1854    fn a_map_target_refuses_a_passthrough() {
1855        struct Clear;
1856        impl Encrypt for Clear {
1857            fn visit<S: Sink>(self, sink: S) -> Result<S::Ok, S::Error> {
1858                let mut map = BTreeMap::new();
1859                map.insert("a", 1u16);
1860                sink.passthrough(map)
1861            }
1862        }
1863        assert_eq!(expected(round_trip::<HashMap<String, u16>>(Clear)), "map");
1864        assert_eq!(expected(round_trip::<BTreeMap<String, u16>>(Clear)), "map");
1865    }
1866
1867    #[test]
1868    fn byte_targets_refuse_a_uuid_leaf() {
1869        let uuid = || Raw(Some(Logical::Uuid), Physical::Bytes(&[5; 16]));
1870        assert_eq!(expected(round_trip::<Vec<u8>>(uuid())), "bytes");
1871        assert_eq!(expected(round_trip::<[u8; 16]>(uuid())), "byte array");
1872        assert_eq!(
1873            expected(round_trip::<Protected<[u8; 16]>>(uuid())),
1874            "byte array"
1875        );
1876    }
1877
1878    #[cfg(feature = "chrono")]
1879    #[test]
1880    fn chrono_targets_refuse_the_other_logical_types() {
1881        use crate::plaintext::TimeUnit;
1882        use ::chrono::{DateTime, NaiveDate, Utc};
1883        let date = NaiveDate::from_ymd_opt(2024, 2, 29).expect("date");
1884        let ts = DateTime::from_timestamp(1_700_000_000, 0).expect("ts");
1885        assert_eq!(expected(round_trip::<DateTime<Utc>>(date)), "timestamp");
1886        assert_eq!(
1887            expected(round_trip::<DateTime<Utc>>(1_700_000_000i64)),
1888            "timestamp"
1889        );
1890        assert_eq!(expected(round_trip::<NaiveDate>(ts)), "date");
1891
1892        let instant = DateTime::from_timestamp(2, 0).expect("timestamp");
1893        for (unit, count) in [
1894            (TimeUnit::Seconds, 2),
1895            (TimeUnit::Millis, 2_000),
1896            (TimeUnit::Micros, 2_000_000),
1897            (TimeUnit::Nanos, 2_000_000_000),
1898        ] {
1899            let raw = Raw(
1900                Some(Logical::Timestamp(unit)),
1901                Physical::Int(Int::I64(count)),
1902            );
1903            assert_eq!(round_trip::<DateTime<Utc>>(raw).expect("unit"), instant);
1904        }
1905    }
1906
1907    #[test]
1908    fn a_wrong_aad_fails_before_the_target_is_checked() {
1909        let sealed = || encrypt(34u32, &Mock, "ctx").expect("encrypts");
1910        assert!(matches!(
1911            decrypt::<String, _, _>(&Mock, sealed(), "other"),
1912            Err(DecryptError::Cipher(_))
1913        ));
1914        assert!(matches!(
1915            decrypt::<Vec<u32>, _, _>(&Mock, sealed(), "other"),
1916            Err(DecryptError::Cipher(_))
1917        ));
1918        let remote = Remote::new(true);
1919        // With the right AAD the async path decrypts, so the next
1920        // assertion is about the AAD and nothing else.
1921        assert_eq!(
1922            block_on(decrypt_async::<u32, _, _>(&remote, sealed(), "ctx")).expect("decrypts"),
1923            34
1924        );
1925        assert!(matches!(
1926            block_on(decrypt_async::<String, _, _>(&remote, sealed(), "other")),
1927            Err(DecryptError::Cipher(_))
1928        ));
1929    }
1930
1931    #[test]
1932    fn a_null_is_refused_where_no_option_is_expected() {
1933        assert_eq!(expected(round_trip::<u32>(None::<u32>)), "u32");
1934        assert_eq!(expected(round_trip::<String>(None::<String>)), "string");
1935        assert_eq!(
1936            expected(round_trip::<Vec<u32>>(None::<Vec<u32>>)),
1937            "sequence"
1938        );
1939        assert_eq!(
1940            expected(round_trip::<Vec<u32>>(vec![Some(1u32), None])),
1941            "u32"
1942        );
1943        assert_eq!(
1944            expected(round_trip::<u32>(Raw(
1945                Some(Logical::Undefined),
1946                Physical::Null
1947            ))),
1948            "u32"
1949        );
1950    }
1951
1952    #[test]
1953    fn a_list_target_refuses_a_map() {
1954        let mut map = BTreeMap::new();
1955        map.insert("a", 1u32);
1956        assert_eq!(expected(round_trip::<Vec<u32>>(map)), "sequence");
1957    }
1958
1959    #[test]
1960    fn number_targets_refuse_the_other_number_kinds() {
1961        assert_eq!(expected(round_trip::<u32>(true)), "u32");
1962        assert_eq!(expected(round_trip::<i64>(1.0f64)), "i64");
1963        assert_eq!(expected(round_trip::<i64>(1.0f32)), "i64");
1964        assert_eq!(expected(round_trip::<f64>(1i64)), "f64");
1965        assert_eq!(expected(round_trip::<f32>(1u32)), "f32");
1966    }
1967
1968    #[test]
1969    fn integer_targets_accept_their_limits_and_nothing_past_them() {
1970        assert_eq!(round_trip::<i8>(i8::MIN).expect("i8"), i8::MIN);
1971        assert_eq!(round_trip::<i8>(127i32).expect("i8"), i8::MAX);
1972        assert_eq!(expected(round_trip::<i8>(-129i32)), "i8");
1973        assert_eq!(expected(round_trip::<i8>(128i32)), "i8");
1974        assert_eq!(round_trip::<u64>(u64::MAX).expect("u64"), u64::MAX);
1975        assert_eq!(expected(round_trip::<u64>(u128::from(u64::MAX) + 1)), "u64");
1976        assert_eq!(round_trip::<u128>(u128::MAX).expect("u128"), u128::MAX);
1977        assert_eq!(expected(round_trip::<u128>(-1i8)), "u128");
1978        assert_eq!(round_trip::<i128>(i128::MIN).expect("i128"), i128::MIN);
1979        assert_eq!(expected(round_trip::<i128>(u128::MAX)), "i128");
1980    }
1981
1982    #[test]
1983    fn a_source_error_displays_its_message() {
1984        assert_eq!(
1985            DecodeError::Source(SourceError::msg("getter threw")).to_string(),
1986            "source failed: getter threw"
1987        );
1988        assert_eq!(DecodeError::Expected("u32").to_string(), "expected u32");
1989    }
1990
1991    #[test]
1992    fn protected_containers_round_trip() {
1993        let ints = round_trip::<Protected<Vec<u32>>>(vec![1u32, 2, 3]).expect("decrypts");
1994        assert_eq!(ints.risky_ref(), &[1, 2, 3]);
1995        let some = round_trip::<Protected<Option<String>>>(Some("pw")).expect("decrypts");
1996        assert_eq!(some.risky_ref().as_deref(), Some("pw"));
1997        let none = round_trip::<Protected<Option<String>>>(None::<&str>).expect("decrypts");
1998        assert_eq!(none.risky_ref(), &None);
1999        let undefined =
2000            round_trip::<Protected<Option<u32>>>(Raw(Some(Logical::Undefined), Physical::Null))
2001                .expect("decrypts");
2002        assert_eq!(undefined.risky_ref(), &None);
2003        // Nested to any depth, containers inside options and the reverse.
2004        let nested = round_trip::<Protected<Vec<Vec<String>>>>(vec![vec!["a", "b"], vec![]])
2005            .expect("decrypts");
2006        assert_eq!(
2007            nested.risky_ref(),
2008            &[vec![String::from("a"), String::from("b")], vec![]]
2009        );
2010        let list = round_trip::<Protected<Option<Vec<u32>>>>(Some(vec![7u32])).expect("decrypts");
2011        assert_eq!(list.risky_ref(), &Some(vec![7]));
2012        let arrays = round_trip::<Protected<Vec<Option<[u8; 2]>>>>(vec![Some([1u8, 2]), None])
2013            .expect("decrypts");
2014        assert_eq!(arrays.risky_ref(), &[Some([1, 2]), None]);
2015        // `Vec<u8>` is still the byte leaf, not a sequence of `u8`.
2016        let bytes = round_trip::<Protected<Vec<u8>>>(vec![9u8, 8]).expect("decrypts");
2017        assert_eq!(bytes.risky_ref(), &[9, 8]);
2018    }
2019
2020    #[test]
2021    fn protected_containers_refuse_what_their_bare_forms_refuse() {
2022        let mut map = BTreeMap::new();
2023        map.insert("a", 1u32);
2024        assert_eq!(expected(round_trip::<Protected<Vec<u32>>>(map)), "sequence");
2025        assert_eq!(
2026            expected(round_trip::<Protected<Vec<u32>>>(1u32)),
2027            "sequence"
2028        );
2029        assert_eq!(
2030            expected(round_trip::<Protected<Vec<u32>>>(vec!["x"])),
2031            "u32"
2032        );
2033        assert_eq!(expected(round_trip::<Protected<Option<u32>>>("x")), "u32");
2034        assert_eq!(
2035            expected(round_trip::<Protected<Option<Vec<u32>>>>(1u32)),
2036            "sequence"
2037        );
2038        struct Clear;
2039        impl Encrypt for Clear {
2040            fn visit<S: Sink>(self, sink: S) -> Result<S::Ok, S::Error> {
2041                sink.passthrough(vec![1u32])
2042            }
2043        }
2044        assert_eq!(
2045            expected(round_trip::<Protected<Vec<u32>>>(Clear)),
2046            "sequence"
2047        );
2048        assert_eq!(expected(round_trip::<Protected<Option<u32>>>(Clear)), "u32");
2049        assert_eq!(expected(round_trip::<Protected<u32>>(Clear)), "u32");
2050        assert_eq!(expected(round_trip::<Protected<u32>>(vec![1u32])), "u32");
2051        let mut map = BTreeMap::new();
2052        map.insert("a", 1u32);
2053        assert_eq!(expected(round_trip::<Protected<u32>>(map)), "u32");
2054    }
2055
2056    std::thread_local! {
2057        static WIPES: core::cell::Cell<usize> = const { core::cell::Cell::new(0) };
2058    }
2059
2060    /// A scalar target that counts its wipes.
2061    struct Wiped(u32);
2062
2063    impl Zeroize for Wiped {
2064        fn zeroize(&mut self) {
2065            self.0 = 0;
2066            WIPES.with(|w| w.set(w.get() + 1));
2067        }
2068    }
2069
2070    impl FromScalar for Wiped {
2071        const EXPECTED: &'static str = "wiped";
2072        fn from_scalar(ty: Option<Logical>, v: Physical<'_>) -> Option<Self> {
2073            u32::from_scalar(ty, v).map(Wiped)
2074        }
2075    }
2076
2077    #[test]
2078    fn a_protected_list_that_fails_part_way_wipes_what_it_decoded() {
2079        let source = vec![
2080            Raw(None, Physical::Int(Int::U32(1))),
2081            Raw(None, Physical::Int(Int::U32(2))),
2082            Raw(None, Physical::Text("x")),
2083        ];
2084        WIPES.with(|w| w.set(0));
2085        let result = round_trip::<Protected<Vec<Wiped>>>(source);
2086        assert_eq!(expected(result), "wiped");
2087        assert_eq!(WIPES.with(|w| w.get()), 2);
2088    }
2089
2090    /// A sequence that does not say how long it is.
2091    struct Unsized(u32);
2092
2093    impl Encrypt for Unsized {
2094        fn visit<S: Sink>(self, sink: S) -> Result<S::Ok, S::Error> {
2095            let mut seq = sink.seq(None)?;
2096            for i in 0..self.0 {
2097                i.visit(seq.element()?)?;
2098            }
2099            seq.end()
2100        }
2101    }
2102
2103    #[test]
2104    fn a_protected_list_grows_by_doubling_into_a_fresh_buffer() {
2105        let decode = |n| {
2106            Unsized(n)
2107                .visit(<Protected<Vec<u32>> as Decrypt>::sink())
2108                .expect("decodes")
2109        };
2110        let five = decode(5);
2111        assert_eq!(five.risky_ref(), &[0, 1, 2, 3, 4]);
2112        assert_eq!(five.risky_ref().capacity(), 8);
2113        let nine = decode(9);
2114        assert_eq!(nine.risky_ref(), &(0..9).collect::<Vec<_>>());
2115        assert_eq!(nine.risky_ref().capacity(), 16);
2116    }
2117
2118    /// A struct target written by hand, as `#[derive(Decrypt)]` will write
2119    /// one: a map with one field, opted into `Protected` through `Wrap`.
2120    #[derive(Debug, PartialEq)]
2121    struct Point {
2122        x: u32,
2123    }
2124
2125    impl Zeroize for Point {
2126        fn zeroize(&mut self) {
2127            self.x.zeroize();
2128        }
2129    }
2130
2131    struct PointSink;
2132    struct PointFields(Option<u32>);
2133
2134    impl Sink for PointSink {
2135        type Ok = Point;
2136        type Error = DecodeError;
2137        type Seq = Never<Point>;
2138        type Map = PointFields;
2139
2140        fn scalar(self, _: Option<Logical>, _: Physical<'_>) -> Result<Point, DecodeError> {
2141            Err(DecodeError::Expected("point"))
2142        }
2143
2144        fn typed_null(self, _: FixedType) -> Result<Point, DecodeError> {
2145            Err(DecodeError::Expected("point"))
2146        }
2147
2148        fn seq(self, _: Option<usize>) -> Result<Never<Point>, DecodeError> {
2149            Err(DecodeError::Expected("point"))
2150        }
2151
2152        fn map(self, _: Option<usize>) -> Result<PointFields, DecodeError> {
2153            Ok(PointFields(None))
2154        }
2155
2156        fn passthrough<P: Encrypt + Clone>(self, _: P) -> Result<Point, DecodeError> {
2157            Err(DecodeError::Expected("point"))
2158        }
2159    }
2160
2161    impl MapSink for PointFields {
2162        type Ok = Point;
2163        type Error = DecodeError;
2164        type Entry<'s> = Forward<u32, Slot<'s, u32>>;
2165
2166        fn entry(&mut self, key: &str) -> Result<Self::Entry<'_>, DecodeError> {
2167            match key {
2168                "x" => Ok(Forward(u32::sink(), Slot(&mut self.0))),
2169                _ => Err(DecodeError::Expected("point")),
2170            }
2171        }
2172
2173        fn end(self) -> Result<Point, DecodeError> {
2174            self.0
2175                .map(|x| Point { x })
2176                .ok_or(DecodeError::Expected("point"))
2177        }
2178    }
2179
2180    impl Decrypt for Point {
2181        type Sink = PointSink;
2182        fn sink() -> PointSink {
2183            PointSink
2184        }
2185    }
2186
2187    impl DecryptProtected for Point {
2188        type ProtectedSink = Wrap<PointSink>;
2189        fn protected_sink() -> Wrap<PointSink> {
2190            Wrap(PointSink)
2191        }
2192    }
2193
2194    #[test]
2195    fn a_struct_target_opts_into_protected_through_wrap() {
2196        let point = || {
2197            let mut map = BTreeMap::new();
2198            map.insert("x", 3u32);
2199            map
2200        };
2201        let p = round_trip::<Protected<Point>>(point()).expect("decrypts");
2202        assert_eq!(p.risky_ref(), &Point { x: 3 });
2203        let some = round_trip::<Protected<Option<Point>>>(Some(point())).expect("decrypts");
2204        assert_eq!(some.risky_ref(), &Some(Point { x: 3 }));
2205        let list = round_trip::<Protected<Vec<Point>>>(vec![point()]).expect("decrypts");
2206        assert_eq!(list.risky_ref(), &[Point { x: 3 }]);
2207        assert_eq!(expected(round_trip::<Protected<Point>>(1u32)), "point");
2208        assert_eq!(
2209            expected(round_trip::<Protected<Point>>(vec![1u32])),
2210            "point"
2211        );
2212        let mut extra = point();
2213        extra.insert("y", 4u32);
2214        assert_eq!(expected(round_trip::<Protected<Point>>(extra)), "point");
2215    }
2216
2217    #[test]
2218    fn wrap_moves_any_sink_result_into_protected() {
2219        let n = Wrap(u32::sink())
2220            .scalar(None, Physical::Int(Int::U32(5)))
2221            .expect("decodes");
2222        assert_eq!(n.risky_ref(), &5);
2223        assert!(matches!(
2224            Wrap(u32::sink()).passthrough(5u32),
2225            Err(DecodeError::Expected("u32"))
2226        ));
2227        let list = vec![1u32, 2]
2228            .visit(Wrap(<Vec<u32>>::sink()))
2229            .expect("decodes");
2230        assert_eq!(list.risky_ref(), &[1, 2]);
2231    }
2232}