1use ed25519_dalek::{Signature, Signer, SigningKey, Verifier, VerifyingKey};
2use rand_core::OsRng;
3use zeroize::Zeroizing;
4
5use crate::CoreError;
6
7pub const HANDSHAKE_AUTH_NONE: u8 = 0;
9pub const HANDSHAKE_AUTH_ED25519: u8 = 1;
11
12#[derive(Clone, Eq, PartialEq)]
14pub struct IdentityKeyPair {
15 secret_key: Zeroizing<[u8; 32]>,
16 public_key: [u8; 32],
17}
18
19impl core::fmt::Debug for IdentityKeyPair {
20 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
21 f.debug_struct("IdentityKeyPair")
22 .field("public_key", &self.public_key)
23 .finish()
24 }
25}
26
27impl IdentityKeyPair {
28 pub fn generate() -> Self {
30 let signing_key = SigningKey::generate(&mut OsRng);
31 Self::from_secret_key_bytes(signing_key.to_bytes())
32 }
33
34 pub fn from_secret_key_bytes(secret_key: [u8; 32]) -> Self {
36 let signing_key = SigningKey::from_bytes(&secret_key);
37 let public_key = signing_key.verifying_key().to_bytes();
38 Self {
39 secret_key: Zeroizing::new(secret_key),
40 public_key,
41 }
42 }
43
44 pub fn public_key(&self) -> [u8; 32] {
46 self.public_key
47 }
48
49 pub fn secret_key_bytes(&self) -> [u8; 32] {
51 *self.secret_key
52 }
53
54 pub fn sign(&self, message: &[u8]) -> [u8; 64] {
56 let signing_key = SigningKey::from_bytes(&self.secret_key);
57 signing_key.sign(message).to_bytes()
58 }
59}
60
61#[derive(Clone, Copy, Debug, Eq, PartialEq)]
63pub struct PeerIdentity {
64 pub public_key: [u8; 32],
66}
67
68impl PeerIdentity {
69 pub fn new(public_key: [u8; 32]) -> Self {
71 Self { public_key }
72 }
73}
74
75#[derive(Clone, Debug, Eq, PartialEq)]
77pub struct HandshakeAuth {
78 pub identity_public_key: [u8; 32],
80 pub signature: [u8; 64],
82}
83
84impl HandshakeAuth {
85 pub fn sign(identity: &IdentityKeyPair, message: &[u8]) -> Self {
87 Self {
88 identity_public_key: identity.public_key(),
89 signature: identity.sign(message),
90 }
91 }
92
93 pub fn verify(&self, message: &[u8]) -> Result<(), CoreError> {
95 let verifying_key = VerifyingKey::from_bytes(&self.identity_public_key)
96 .map_err(|_| CoreError::InvalidPeerAuthentication)?;
97 let signature = Signature::from_bytes(&self.signature);
98 verifying_key
99 .verify(message, &signature)
100 .map_err(|_| CoreError::InvalidPeerAuthentication)
101 }
102
103 pub const fn encoded_len() -> usize {
105 32 + 64
106 }
107}
108
109#[derive(Clone, Debug, Default, Eq, PartialEq)]
111pub struct SessionAuthConfig {
112 local_identity: Option<IdentityKeyPair>,
113 peer_identity: Option<PeerIdentity>,
114 require_peer_authentication: bool,
115}
116
117impl SessionAuthConfig {
118 pub fn new() -> Self {
120 Self::default()
121 }
122
123 pub fn with_local_identity(mut self, identity: IdentityKeyPair) -> Self {
125 self.local_identity = Some(identity);
126 self
127 }
128
129 pub fn with_peer_identity(mut self, identity: PeerIdentity) -> Self {
131 self.peer_identity = Some(identity);
132 self
133 }
134
135 pub fn require_peer_authentication(mut self, require: bool) -> Self {
137 self.require_peer_authentication = require;
138 self
139 }
140
141 pub fn local_identity(&self) -> Option<&IdentityKeyPair> {
143 self.local_identity.as_ref()
144 }
145
146 pub fn peer_identity(&self) -> Option<PeerIdentity> {
148 self.peer_identity
149 }
150
151 pub fn requires_peer_authentication(&self) -> bool {
153 self.require_peer_authentication
154 }
155}