Add Instance Authentication
parent: tbd commit: 5a042fd
Showing 4 changed files with 47 insertions and 20 deletions
src/authentication.rs
@@ -1,4 +1,4 @@ | ||
1 | use std::{error::Error, os::raw, time::SystemTime}; | |
1 | use std::{error::Error, time::SystemTime}; | |
2 | 2 | |
3 | 3 | use jsonwebtoken::{decode, encode, Algorithm, DecodingKey, EncodingKey, TokenData, Validation}; |
4 | 4 | use serde::{Deserialize, Serialize}; |
@@ -30,8 +30,18 @@ pub struct AuthenticationTokenGranter { | ||
30 | 30 | impl AuthenticationTokenGranter { |
31 | 31 | pub async fn token_request( |
32 | 32 | &mut self, |
33 | request: AuthenticationTokenRequest, | |
33 | raw_request: InstanceAuthenticated<AuthenticationTokenRequest>, | |
34 | 34 | ) -> Result<AuthenticationTokenResponse, Box<dyn Error + Send>> { |
35 | let request = raw_request.inner().await; | |
36 | ||
37 | info!("Ensuring token request is from the same instance..."); | |
38 | raw_request | |
39 | .validate(&Instance { | |
40 | url: String::from("giterated.dev"), | |
41 | }) | |
42 | .await | |
43 | .unwrap(); | |
44 | ||
35 | 45 | let secret_key = self.config["authentication"]["secret_key"] |
36 | 46 | .as_str() |
37 | 47 | .unwrap(); |
@@ -85,18 +95,26 @@ impl AuthenticationTokenGranter { | ||
85 | 95 | ) -> Result<TokenExtensionResponse, Box<dyn Error + Send>> { |
86 | 96 | let request = raw_request.inner().await; |
87 | 97 | |
88 | let server_public_key = { | |
89 | let mut file = File::open(self.config["keys"]["public"].as_str().unwrap()) | |
90 | .await | |
91 | .unwrap(); | |
98 | // let server_public_key = { | |
99 | // let mut file = File::open(self.config["keys"]["public"].as_str().unwrap()) | |
100 | // .await | |
101 | // .unwrap(); | |
92 | 102 | |
93 | let mut key = vec![]; | |
94 | file.read_to_end(&mut key).await.unwrap(); | |
103 | // let mut key = String::default(); | |
104 | // file.read_to_string(&mut key).await.unwrap(); | |
95 | 105 | |
96 | key | |
97 | }; | |
106 | // key | |
107 | // }; | |
108 | ||
109 | let server_public_key = public_key(&Instance { | |
110 | url: String::from("giterated.dev"), | |
111 | }) | |
112 | .await | |
113 | .unwrap(); | |
98 | 114 | |
99 | let verification_key = DecodingKey::from_rsa_pem(&server_public_key).unwrap(); | |
115 | println!("Our Public Key:\n{}", server_public_key); | |
116 | ||
117 | let verification_key = DecodingKey::from_rsa_pem(server_public_key.as_bytes()).unwrap(); | |
100 | 118 | |
101 | 119 | let data: TokenData<UserTokenMetadata> = decode( |
102 | 120 | &request.token, |
@@ -116,11 +134,11 @@ impl AuthenticationTokenGranter { | ||
116 | 134 | |
117 | 135 | panic!() |
118 | 136 | } |
119 | ||
120 | let requester_public_key = public_key(&data.claims.generated_for).await.unwrap(); | |
121 | ||
122 | 137 | // Validate request |
123 | raw_request.validate(requester_public_key).await.unwrap(); | |
138 | raw_request | |
139 | .validate(&data.claims.generated_for) | |
140 | .await | |
141 | .unwrap(); | |
124 | 142 | info!("Validated request for key extension"); |
125 | 143 | |
126 | 144 | let private_key = { |
src/connection.rs
@@ -395,7 +395,7 @@ pub async fn connection_worker( | ||
395 | 395 | let response = granter |
396 | 396 | .extension_request(request.clone()) |
397 | 397 | .await |
398 | .unwrap_or_else(|_| TokenExtensionResponse { new_token: None }); | |
398 | .unwrap_or(TokenExtensionResponse { new_token: None }); | |
399 | 399 | drop(granter); |
400 | 400 | |
401 | 401 | socket |
src/messages/authentication.rs
@@ -10,7 +10,7 @@ pub enum AuthenticationMessage { | ||
10 | 10 | |
11 | 11 | #[derive(Clone, Serialize, Deserialize)] |
12 | 12 | pub enum AuthenticationRequest { |
13 | AuthenticationToken(AuthenticationTokenRequest), | |
13 | AuthenticationToken(InstanceAuthenticated<AuthenticationTokenRequest>), | |
14 | 14 | TokenExtension(InstanceAuthenticated<TokenExtensionRequest>), |
15 | 15 | } |
16 | 16 |
src/messages/mod.rs
@@ -2,7 +2,6 @@ use std::{error::Error, fmt::Debug}; | ||
2 | 2 | |
3 | 3 | use rsa::{ |
4 | 4 | pkcs1::{DecodeRsaPrivateKey, DecodeRsaPublicKey}, |
5 | pkcs8::{DecodePrivateKey, DecodePublicKey}, | |
6 | 5 | pss::{Signature, SigningKey, VerifyingKey}, |
7 | 6 | sha2::Sha256, |
8 | 7 | signature::{RandomizedSigner, SignatureEncoding, Verifier}, |
@@ -87,8 +86,9 @@ impl<T: Serialize> InstanceAuthenticated<T> { | ||
87 | 86 | &self.message |
88 | 87 | } |
89 | 88 | |
90 | pub async fn validate(&self, key: String) -> Result<(), Box<dyn Error>> { | |
91 | let public_key = RsaPublicKey::from_pkcs1_pem(&key).unwrap(); | |
89 | pub async fn validate(&self, instance: &Instance) -> Result<(), Box<dyn Error>> { | |
90 | let public_key = public_key(instance).await?; | |
91 | let public_key = RsaPublicKey::from_pkcs1_pem(&public_key).unwrap(); | |
92 | 92 | |
93 | 93 | let verifying_key: VerifyingKey<Sha256> = VerifyingKey::new(public_key); |
94 | 94 | |
@@ -182,3 +182,12 @@ impl<T: Serialize> UserAuthenticated<T> { | ||
182 | 182 | Ok(()) |
183 | 183 | } |
184 | 184 | } |
185 | ||
186 | async fn public_key(instance: &Instance) -> Result<String, Box<dyn Error>> { | |
187 | let key = reqwest::get(format!("https://{}/.giterated/pubkey.pem", instance.url)) | |
188 | .await? | |
189 | .text() | |
190 | .await?; | |
191 | ||
192 | Ok(key) | |
193 | } |