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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
use ed25519_dalek::{
Keypair, PublicKey, Signature, SignatureError, PUBLIC_KEY_LENGTH, SECRET_KEY_LENGTH,
SIGNATURE_LENGTH,
};
use rand::rngs::OsRng;
use rand_core::RngCore;
use std::{collections::HashMap, convert::From};
type PublicKeyBytes = [u8; PUBLIC_KEY_LENGTH];
type SignatureBytes = [u8; SIGNATURE_LENGTH];
type TokenBytes = [u8; 64];
pub struct Identity {
pub name: String,
pub pkey: PublicKeyBytes,
pub sigs: HashMap<PublicKeyBytes, SignatureBytes>,
}
impl Identity {
pub fn new() -> (Identity, [u8; SECRET_KEY_LENGTH]) {
let mut csprng = OsRng {};
let keypair = Keypair::generate(&mut csprng);
(
Identity {
name: "".to_string(),
pkey: keypair.public.to_bytes(),
sigs: HashMap::new(),
},
keypair.secret.to_bytes(),
)
}
pub fn token() -> TokenBytes {
let mut rng = [0; 64];
let mut orng = rand::rngs::OsRng {};
orng.fill_bytes(&mut rng);
rng
}
pub fn auth(
&mut self,
id: PublicKeyBytes,
tk: TokenBytes,
sig: SignatureBytes,
) -> Result<(), Error> {
PublicKey::from_bytes(&self.pkey)?.verify(&tk, &Signature::from_bytes(&sig)?)?;
self.sigs.insert(id, sig);
Ok(())
}
pub fn state(&self, id: PublicKeyBytes, sig: SignatureBytes) -> Result<(), Error> {
if let Some(s) = self.sigs.get(&id) {
if s.to_vec() == sig.to_vec() {
return Ok(());
}
return Err(Error::TokenError);
}
Err(Error::TokenError)
}
pub fn update(&mut self, id: PublicKeyBytes, sig: SignatureBytes) -> Result<(), Error> {
if self.sigs.insert(id, sig).is_some() {
return Ok(());
}
Err(Error::TokenError)
}
}
impl From<PublicKeyBytes> for Identity {
fn from(b: PublicKeyBytes) -> Identity {
Identity {
name: "".to_string(),
pkey: b,
sigs: HashMap::new(),
}
}
}
#[derive(Debug)]
pub enum Error {
LoginError,
TokenError,
}
impl From<SignatureError> for Error {
fn from(_: SignatureError) -> Self {
Error::LoginError
}
}