JavaScript is disabled, refresh for a better experience. ambee/giterated

ambee/giterated

Git repository hosting, collaboration, and discovery for the Fediverse.

Add more aggressive key caching

Amber - ⁨2⁩ years ago

parent: tbd commit: ⁨5bc92ad

⁨giterated-daemon/src/authentication.rs⁩ - ⁨4916⁩ bytes
Raw
1 use anyhow::Error;
2 use giterated_models::{
3 messages::authentication::{AuthenticationTokenResponse, TokenExtensionResponse},
4 model::{
5 authenticated::{UserAuthenticationToken, UserTokenMetadata},
6 instance::Instance,
7 user::User,
8 },
9 };
10 use jsonwebtoken::{decode, encode, Algorithm, DecodingKey, EncodingKey, TokenData, Validation};
11 use std::{sync::Arc, time::SystemTime};
12 use tokio::{fs::File, io::AsyncReadExt, sync::Mutex};
13 use toml::Table;
14
15 use crate::keys::PublicKeyCache;
16
17 pub struct AuthenticationTokenGranter {
18 pub config: Table,
19 pub instance: Instance,
20 }
21
22 impl AuthenticationTokenGranter {
23 async fn private_key(&self) -> Vec<u8> {
24 let _secret_key = self.config["authentication"]["secret_key"]
25 .as_str()
26 .unwrap();
27 let mut file = File::open(
28 self.config["giterated"]["keys"]["private"]
29 .as_str()
30 .unwrap(),
31 )
32 .await
33 .unwrap();
34
35 let mut key = vec![];
36 file.read_to_end(&mut key).await.unwrap();
37
38 key
39 }
40
41 pub(crate) async fn create_token_for(
42 &mut self,
43 user: &User,
44 generated_for: &Instance,
45 ) -> String {
46 let private_key = self.private_key().await;
47
48 let encoding_key = EncodingKey::from_rsa_pem(&private_key).unwrap();
49
50 let claims = UserTokenMetadata {
51 user: user.clone(),
52 generated_for: generated_for.clone(),
53 exp: (SystemTime::UNIX_EPOCH.elapsed().unwrap()
54 + std::time::Duration::from_secs(24 * 60 * 60))
55 .as_secs(),
56 };
57
58 encode(
59 &jsonwebtoken::Header::new(Algorithm::RS256),
60 &claims,
61 &encoding_key,
62 )
63 .unwrap()
64 }
65
66 pub async fn token_request(
67 &mut self,
68 issued_for: impl ToOwned<Owned = Instance>,
69 username: String,
70 _password: String,
71 ) -> Result<AuthenticationTokenResponse, Error> {
72 let private_key = {
73 let mut file = File::open(
74 self.config["giterated"]["keys"]["private"]
75 .as_str()
76 .unwrap(),
77 )
78 .await
79 .unwrap();
80
81 let mut key = vec![];
82 file.read_to_end(&mut key).await.unwrap();
83
84 key
85 };
86
87 let encoding_key = EncodingKey::from_rsa_pem(&private_key).unwrap();
88
89 let claims = UserTokenMetadata {
90 user: User {
91 username,
92 instance: self.instance.clone(),
93 },
94 generated_for: issued_for.to_owned(),
95 exp: (SystemTime::UNIX_EPOCH.elapsed().unwrap()
96 + std::time::Duration::from_secs(24 * 60 * 60))
97 .as_secs(),
98 };
99
100 let token = encode(
101 &jsonwebtoken::Header::new(Algorithm::RS256),
102 &claims,
103 &encoding_key,
104 )
105 .unwrap();
106
107 Ok(AuthenticationTokenResponse {
108 token: UserAuthenticationToken::from(token),
109 })
110 }
111
112 pub async fn extension_request(
113 &mut self,
114 issued_for: &Instance,
115 key_cache: &Arc<Mutex<PublicKeyCache>>,
116 token: UserAuthenticationToken,
117 ) -> Result<TokenExtensionResponse, Error> {
118 let mut key_cache = key_cache.lock().await;
119 let server_public_key = key_cache.get(issued_for).await?;
120 drop(key_cache);
121
122 let verification_key = DecodingKey::from_rsa_pem(server_public_key.as_bytes()).unwrap();
123
124 let data: TokenData<UserTokenMetadata> = decode(
125 token.as_ref(),
126 &verification_key,
127 &Validation::new(Algorithm::RS256),
128 )
129 .unwrap();
130
131 if data.claims.generated_for != *issued_for {
132 panic!()
133 }
134
135 info!("Token Extension Request Token validated");
136
137 let private_key = {
138 let mut file = File::open(
139 self.config["giterated"]["keys"]["private"]
140 .as_str()
141 .unwrap(),
142 )
143 .await
144 .unwrap();
145
146 let mut key = vec![];
147 file.read_to_end(&mut key).await.unwrap();
148
149 key
150 };
151
152 let encoding_key = EncodingKey::from_rsa_pem(&private_key).unwrap();
153
154 let claims = UserTokenMetadata {
155 // TODO: Probably exploitable
156 user: data.claims.user,
157 generated_for: issued_for.clone(),
158 exp: (SystemTime::UNIX_EPOCH.elapsed().unwrap()
159 + std::time::Duration::from_secs(24 * 60 * 60))
160 .as_secs(),
161 };
162
163 let token = encode(
164 &jsonwebtoken::Header::new(Algorithm::RS256),
165 &claims,
166 &encoding_key,
167 )
168 .unwrap();
169
170 Ok(TokenExtensionResponse {
171 new_token: Some(token),
172 })
173 }
174 }
175