Line data Source code
1 : //! Tools for client/server/stored key management.
2 :
3 : use subtle::ConstantTimeEq;
4 :
5 : /// Faithfully taken from PostgreSQL.
6 : pub(crate) const SCRAM_KEY_LEN: usize = 32;
7 :
8 : /// One of the keys derived from the user's password.
9 : /// We use the same structure for all keys, i.e.
10 : /// `ClientKey`, `StoredKey`, and `ServerKey`.
11 : #[derive(Clone, Default, Eq, Debug)]
12 : #[repr(transparent)]
13 : pub(crate) struct ScramKey {
14 : bytes: [u8; SCRAM_KEY_LEN],
15 : }
16 :
17 : impl PartialEq for ScramKey {
18 8 : fn eq(&self, other: &Self) -> bool {
19 8 : self.ct_eq(other).into()
20 8 : }
21 : }
22 :
23 : impl ConstantTimeEq for ScramKey {
24 20 : fn ct_eq(&self, other: &Self) -> subtle::Choice {
25 20 : self.bytes.ct_eq(&other.bytes)
26 20 : }
27 : }
28 :
29 : impl ScramKey {
30 12 : pub(crate) fn sha256(&self) -> Self {
31 12 : super::sha256([self.as_ref()]).into()
32 12 : }
33 :
34 7 : pub(crate) fn as_bytes(&self) -> [u8; SCRAM_KEY_LEN] {
35 7 : self.bytes
36 7 : }
37 : }
38 :
39 : impl From<[u8; SCRAM_KEY_LEN]> for ScramKey {
40 : #[inline(always)]
41 60 : fn from(bytes: [u8; SCRAM_KEY_LEN]) -> Self {
42 60 : Self { bytes }
43 60 : }
44 : }
45 :
46 : impl AsRef<[u8]> for ScramKey {
47 : #[inline(always)]
48 31 : fn as_ref(&self) -> &[u8] {
49 31 : &self.bytes
50 31 : }
51 : }
|