1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
/*
This module implements a similar API to what the crate `secrecy` provides.
So, why our own implementation?
First `secrecy::Secret<T>` does not put its contents in a `Box`.
Using `Box` is a general recommendation of working with secret data,
because it prevents the compiler from putting it on stack, thus avoiding possible copies on borrow.
Now, one could use `secrecy::Secret<Box<T>>`.
The problem here is that `secrecy::Secret` requires its type parameter to implement `Zeroize + Clone`.
This means that for a foreign type `F` (even if it does implement `Zeroize + Clone`)
we need to define `impl Zeroize + Clone for Box<F>`.
But the compiler does not allow impls of foreign traits on foreign types.
This means that we also need to wrap `F` in a local type, impl `Zeroize + Clone` for the wrapper,
and then for the box of the wrapper.
This is too much boilerplate.
Additionally, `secrecy::Secret<Box<T>>` means that after each `expose_secret()`
we will need to deal with opening the `Box` as well.
It's an inconvenience, albeit a minor one.
The situation may improve in the future, and `secrecy` will actually become usable.
*/
/// Adapted from: https://github.com/nucypher/rust-umbral/blob/master/umbral-pre/src/secret_box.rs
extern crate alloc;
use Box;
use fmt;
use Zeroize;
/// A container for secret data.
/// Makes the usage of secret data explicit and easy to track,
/// prevents the secret data from being put on stack,
/// and zeroizes the contents on drop.
where
T: Zeroize + Clone;