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 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 struct ScramKey {
14 : bytes: [u8; SCRAM_KEY_LEN],
15 : }
16 :
17 : impl PartialEq for ScramKey {
18 16 : fn eq(&self, other: &Self) -> bool {
19 16 : self.ct_eq(other).into()
20 16 : }
21 : }
22 :
23 : impl ConstantTimeEq for ScramKey {
24 40 : fn ct_eq(&self, other: &Self) -> subtle::Choice {
25 40 : self.bytes.ct_eq(&other.bytes)
26 40 : }
27 : }
28 :
29 : impl ScramKey {
30 24 : pub fn sha256(&self) -> Self {
31 24 : super::sha256([self.as_ref()]).into()
32 24 : }
33 :
34 14 : pub fn as_bytes(&self) -> [u8; SCRAM_KEY_LEN] {
35 14 : self.bytes
36 14 : }
37 : }
38 :
39 : impl From<[u8; SCRAM_KEY_LEN]> for ScramKey {
40 : #[inline(always)]
41 120 : fn from(bytes: [u8; SCRAM_KEY_LEN]) -> Self {
42 120 : Self { bytes }
43 120 : }
44 : }
45 :
46 : impl AsRef<[u8]> for ScramKey {
47 : #[inline(always)]
48 62 : fn as_ref(&self) -> &[u8] {
49 62 : &self.bytes
50 62 : }
51 : }
|