Fixes for authentication!
parent: tbd commit: 969964d
Showing 4 changed files with 40 insertions and 11 deletions
src/connection/authentication.rs
@@ -9,7 +9,6 @@ use crate::model::authenticated::{Message, MessageHandler}; | ||
9 | 9 | |
10 | 10 | use super::wrapper::ConnectionState; |
11 | 11 | |
12 | ||
13 | 12 | pub async fn authentication_handle( |
14 | 13 | message_type: &str, |
15 | 14 | message: &NetworkMessage, |
src/connection/repository.rs
@@ -9,7 +9,7 @@ use crate::{ | ||
9 | 9 | model::authenticated::{AuthenticatedUser, Message, MessageHandler, NetworkMessage, State}, |
10 | 10 | }; |
11 | 11 | |
12 | use super::{wrapper::ConnectionState}; | |
12 | use super::wrapper::ConnectionState; | |
13 | 13 | |
14 | 14 | pub async fn repository_handle( |
15 | 15 | message_type: &str, |
src/connection/user.rs
@@ -1,6 +1,5 @@ | ||
1 | 1 | use anyhow::Error; |
2 | 2 | |
3 | ||
4 | 3 | use crate::model::authenticated::AuthenticatedUser; |
5 | 4 | use crate::model::user::User; |
6 | 5 | use crate::{ |
@@ -11,7 +10,7 @@ use crate::{ | ||
11 | 10 | model::authenticated::{Message, MessageHandler, NetworkMessage, State}, |
12 | 11 | }; |
13 | 12 | |
14 | use super::{wrapper::ConnectionState}; | |
13 | use super::wrapper::ConnectionState; | |
15 | 14 | |
16 | 15 | pub async fn user_handle( |
17 | 16 | message_type: &str, |
src/model/authenticated.rs
@@ -3,6 +3,13 @@ use std::{any::type_name, collections::HashMap, ops::Deref}; | ||
3 | 3 | use anyhow::Error; |
4 | 4 | use futures_util::Future; |
5 | 5 | use jsonwebtoken::{decode, Algorithm, DecodingKey, TokenData, Validation}; |
6 | use rsa::{ | |
7 | pkcs1::{DecodeRsaPrivateKey, DecodeRsaPublicKey}, | |
8 | pss::{Signature, SigningKey, VerifyingKey}, | |
9 | sha2::Sha256, | |
10 | signature::{RandomizedSigner, SignatureEncoding, Verifier}, | |
11 | RsaPrivateKey, RsaPublicKey, | |
12 | }; | |
6 | 13 | use serde::{de::DeserializeOwned, Deserialize, Serialize}; |
7 | 14 | use serde_json::Value; |
8 | 15 | |
@@ -102,11 +109,17 @@ pub struct InstanceAuthenticator<'a> { | ||
102 | 109 | } |
103 | 110 | |
104 | 111 | impl AuthenticationSourceProvider for InstanceAuthenticator<'_> { |
105 | fn authenticate(self, _payload: &Vec<u8>) -> AuthenticationSource { | |
112 | fn authenticate(self, payload: &Vec<u8>) -> AuthenticationSource { | |
113 | let mut rng = rand::thread_rng(); | |
114 | ||
115 | let private_key = RsaPrivateKey::from_pkcs1_pem(self.private_key).unwrap(); | |
116 | let signing_key = SigningKey::<Sha256>::new(private_key); | |
117 | let signature = signing_key.sign_with_rng(&mut rng, &payload); | |
118 | ||
106 | 119 | AuthenticationSource::Instance { |
107 | 120 | instance: self.instance, |
108 | 121 | // TODO: Actually parse signature from private key |
109 | signature: InstanceSignature(self.private_key.as_bytes().to_vec()), | |
122 | signature: InstanceSignature(signature.to_bytes().into_vec()), | |
110 | 123 | } |
111 | 124 | } |
112 | 125 | } |
@@ -136,6 +149,12 @@ impl AsRef<str> for UserAuthenticationToken { | ||
136 | 149 | #[derive(Clone, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)] |
137 | 150 | pub struct InstanceSignature(Vec<u8>); |
138 | 151 | |
152 | impl AsRef<[u8]> for InstanceSignature { | |
153 | fn as_ref(&self) -> &[u8] { | |
154 | &self.0 | |
155 | } | |
156 | } | |
157 | ||
139 | 158 | #[derive(Clone, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)] |
140 | 159 | pub enum AuthenticationSource { |
141 | 160 | User { |
@@ -234,12 +253,12 @@ impl FromMessage<ConnectionState> for AuthenticatedUser { | ||
234 | 253 | impl FromMessage<ConnectionState> for AuthenticatedInstance { |
235 | 254 | async fn from_message( |
236 | 255 | network_message: &NetworkMessage, |
237 | _state: &ConnectionState, | |
256 | state: &ConnectionState, | |
238 | 257 | ) -> Result<Self, Error> { |
239 | let message: Authenticated<HashMap<String, Value>> = | |
258 | let message: Authenticated<Value> = | |
240 | 259 | serde_json::from_slice(&network_message).map_err(|e| Error::from(e))?; |
241 | 260 | |
242 | let (instance, _signature) = message | |
261 | let (instance, signature) = message | |
243 | 262 | .source |
244 | 263 | .iter() |
245 | 264 | .filter_map(|auth| { |
@@ -257,9 +276,21 @@ impl FromMessage<ConnectionState> for AuthenticatedInstance { | ||
257 | 276 | // TODO: Instance authentication error |
258 | 277 | .ok_or_else(|| UserAuthenticationError::Missing)?; |
259 | 278 | |
260 | // TODO: Actually validate | |
279 | let public_key = public_key(instance).await?; | |
280 | let public_key = RsaPublicKey::from_pkcs1_pem(&public_key).unwrap(); | |
281 | ||
282 | let verifying_key: VerifyingKey<Sha256> = VerifyingKey::new(public_key); | |
283 | ||
284 | let message_json = serde_json::to_vec(&message.message).unwrap(); | |
285 | ||
286 | verifying_key | |
287 | .verify( | |
288 | &message_json, | |
289 | &Signature::try_from(signature.as_ref()).unwrap(), | |
290 | ) | |
291 | .unwrap(); | |
261 | 292 | |
262 | Ok(Self(instance.clone())) | |
293 | Ok(AuthenticatedInstance(instance.clone())) | |
263 | 294 | } |
264 | 295 | } |
265 | 296 |