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

ambee/giterated

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

Fixes

Amber - ⁨2⁩ years ago

parent: tbd commit: ⁨74f247e

⁨src/messages/mod.rs⁩ - ⁨2585⁩ bytes
Raw
1 use std::{error::Error, fmt::Debug};
2
3 use rsa::{
4 pkcs8::{DecodePrivateKey, DecodePublicKey},
5 pss::{Signature, SigningKey, VerifyingKey},
6 sha2::Sha256,
7 signature::{RandomizedSigner, SignatureEncoding, Verifier},
8 RsaPrivateKey, RsaPublicKey,
9 };
10 use serde::{Deserialize, Serialize};
11
12 use crate::handshake::HandshakeMessage;
13
14 use self::{authentication::AuthenticationMessage, repository::RepositoryMessage};
15
16 pub mod authentication;
17 pub mod issues;
18 pub mod repository;
19 pub mod user;
20
21 #[derive(Clone, Serialize, Deserialize)]
22 pub enum MessageKind {
23 Handshake(HandshakeMessage),
24 Repository(RepositoryMessage),
25 Authentication(AuthenticationMessage),
26 }
27
28 /// An authenticated message.
29 ///
30 /// Includes the message, with a digest generated with
31 /// our private key.
32 #[derive(Serialize, Deserialize)]
33 pub struct Authenticated<T: Serialize> {
34 #[serde(flatten)]
35 message: T,
36 token: String,
37 digest: Vec<u8>,
38 }
39
40 impl<T> Clone for Authenticated<T>
41 where
42 T: Clone + Serialize,
43 {
44 fn clone(&self) -> Self {
45 Self {
46 message: self.message.clone(),
47 token: self.token.clone(),
48 digest: self.digest.clone(),
49 }
50 }
51 }
52
53 impl<T> Debug for Authenticated<T>
54 where
55 T: Debug + Serialize,
56 {
57 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
58 f.debug_struct("Authenticated")
59 .field("message", &self.message)
60 .field("token", &self.token)
61 .field("digest", &self.digest)
62 .finish()
63 }
64 }
65
66 impl<T: Serialize> Authenticated<T> {
67 pub fn new(message: T, token: String, private_key: String) -> Result<Self, Box<dyn Error>> {
68 let mut rng = rand::thread_rng();
69
70 let private_key = RsaPrivateKey::from_pkcs8_pem(&private_key)?;
71 let signing_key = SigningKey::<Sha256>::new(private_key);
72
73 let message_json = serde_json::to_vec(&message)?;
74
75 let signature = signing_key.sign_with_rng(&mut rng, &message_json);
76
77 Ok(Self {
78 message,
79 token,
80 digest: signature.to_vec(),
81 })
82 }
83
84 pub async fn inner(&self) -> &T {
85 &self.message
86 }
87
88 pub async fn validate(&self, key: String) -> Result<(), Box<dyn Error>> {
89 let public_key = RsaPublicKey::from_public_key_pem(&key)?;
90
91 let verifying_key: VerifyingKey<Sha256> = VerifyingKey::new(public_key);
92
93 let message_json = serde_json::to_vec(&self.message)?;
94
95 verifying_key.verify(&message_json, &Signature::try_from(self.digest.as_ref())?)?;
96
97 Ok(())
98 }
99 }
100