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

ambee/giterated

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

Add token extension

Amber - ⁨2⁩ years ago

parent: tbd commit: ⁨86d028f

⁨src/messages/mod.rs⁩ - ⁨4875⁩ bytes
Raw
1 use std::{error::Error, fmt::Debug};
2
3 use rsa::{
4 pkcs1::{DecodeRsaPrivateKey, DecodeRsaPublicKey},
5 pkcs8::{DecodePrivateKey, DecodePublicKey},
6 pss::{Signature, SigningKey, VerifyingKey},
7 sha2::Sha256,
8 signature::{RandomizedSigner, SignatureEncoding, Verifier},
9 RsaPrivateKey, RsaPublicKey,
10 };
11 use serde::{Deserialize, Serialize};
12
13 use crate::{handshake::HandshakeMessage, model::instance::Instance};
14
15 use self::{authentication::AuthenticationMessage, repository::RepositoryMessage};
16
17 pub mod authentication;
18 pub mod issues;
19 pub mod repository;
20 pub mod user;
21
22 #[derive(Clone, Serialize, Deserialize)]
23 pub enum MessageKind {
24 Handshake(HandshakeMessage),
25 Repository(RepositoryMessage),
26 Authentication(AuthenticationMessage),
27 }
28
29 /// An authenticated message, where the instance is authenticating
30 /// a request it is making for itself.
31 #[derive(Serialize, Deserialize)]
32 pub struct InstanceAuthenticated<T: Serialize> {
33 message: T,
34 instance: Instance,
35 signature: Vec<u8>,
36 }
37
38 impl<T> Clone for InstanceAuthenticated<T>
39 where
40 T: Clone + Serialize,
41 {
42 fn clone(&self) -> Self {
43 Self {
44 message: self.message.clone(),
45 instance: self.instance.clone(),
46 signature: self.signature.clone(),
47 }
48 }
49 }
50
51 impl<T> Debug for InstanceAuthenticated<T>
52 where
53 T: Debug + Serialize,
54 {
55 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
56 f.debug_struct("Authenticated")
57 .field("message", &self.message)
58 .field("instance", &self.instance)
59 .field("signature", &self.signature)
60 .finish()
61 }
62 }
63
64 impl<T: Serialize> InstanceAuthenticated<T> {
65 pub fn new(
66 message: T,
67 instance: Instance,
68 private_key: String,
69 ) -> Result<Self, Box<dyn Error>> {
70 let mut rng = rand::thread_rng();
71
72 let private_key = RsaPrivateKey::from_pkcs1_pem(&private_key)?;
73 let signing_key = SigningKey::<Sha256>::new(private_key);
74
75 let message_json = serde_json::to_vec(&message)?;
76
77 let signature = signing_key.sign_with_rng(&mut rng, &message_json);
78
79 Ok(Self {
80 message,
81 instance,
82 signature: signature.to_vec(),
83 })
84 }
85
86 pub async fn inner(&self) -> &T {
87 &self.message
88 }
89
90 pub async fn validate(&self, key: String) -> Result<(), Box<dyn Error>> {
91 let public_key = RsaPublicKey::from_pkcs1_pem(&key).unwrap();
92
93 let verifying_key: VerifyingKey<Sha256> = VerifyingKey::new(public_key);
94
95 let message_json = serde_json::to_vec(&self.message).unwrap();
96
97 verifying_key
98 .verify(
99 &message_json,
100 &Signature::try_from(self.signature.as_ref()).unwrap(),
101 )
102 .unwrap();
103
104 Ok(())
105 }
106 }
107
108 /// An authenticated message.
109 ///
110 /// Includes the message, with a digest generated with
111 /// our private key.
112 #[derive(Serialize, Deserialize)]
113 pub struct UserAuthenticated<T: Serialize> {
114 #[serde(flatten)]
115 message: T,
116 token: String,
117 digest: Vec<u8>,
118 }
119
120 impl<T> Clone for UserAuthenticated<T>
121 where
122 T: Clone + Serialize,
123 {
124 fn clone(&self) -> Self {
125 Self {
126 message: self.message.clone(),
127 token: self.token.clone(),
128 digest: self.digest.clone(),
129 }
130 }
131 }
132
133 impl<T> Debug for UserAuthenticated<T>
134 where
135 T: Debug + Serialize,
136 {
137 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
138 f.debug_struct("Authenticated")
139 .field("message", &self.message)
140 .field("token", &self.token)
141 .field("digest", &self.digest)
142 .finish()
143 }
144 }
145
146 impl<T: Serialize> UserAuthenticated<T> {
147 pub fn new(message: T, token: String, private_key: String) -> Result<Self, Box<dyn Error>> {
148 let mut rng = rand::thread_rng();
149
150 let private_key = RsaPrivateKey::from_pkcs1_pem(&private_key)?;
151 let signing_key = SigningKey::<Sha256>::new(private_key);
152
153 let message_json = serde_json::to_vec(&message)?;
154
155 let signature = signing_key.sign_with_rng(&mut rng, &message_json);
156
157 Ok(Self {
158 message,
159 token,
160 digest: signature.to_vec(),
161 })
162 }
163
164 pub async fn inner(&self) -> &T {
165 &self.message
166 }
167
168 pub async fn validate(&self, key: String) -> Result<(), Box<dyn Error>> {
169 let public_key = RsaPublicKey::from_pkcs1_pem(&key).unwrap();
170
171 let verifying_key: VerifyingKey<Sha256> = VerifyingKey::new(public_key);
172
173 let message_json = serde_json::to_vec(&self.message).unwrap();
174
175 verifying_key
176 .verify(
177 &message_json,
178 &Signature::try_from(self.digest.as_ref()).unwrap(),
179 )
180 .unwrap();
181
182 Ok(())
183 }
184 }
185