signing random messages from user
This commit is contained in:
		
							parent
							
								
									701c2c6010
								
							
						
					
					
						commit
						60b26344d6
					
				| @ -1,11 +1,44 @@ | |||||||
| #![allow(dead_code)] | #![allow(dead_code)] | ||||||
| use ed25519_dalek::{SigningKey, VerifyingKey}; | use ed25519_dalek::{Signer, SigningKey, VerifyingKey}; | ||||||
| use once_cell::sync::Lazy; | use once_cell::sync::Lazy; | ||||||
| use std::collections::HashMap; | use std::collections::HashMap; | ||||||
| use std::sync::Mutex; | use std::sync::Mutex; | ||||||
| use std::time::SystemTime; | use std::time::SystemTime; | ||||||
| use tabled::{Table, Tabled}; | use tabled::{Table, Tabled}; | ||||||
| 
 | 
 | ||||||
|  | pub enum SigningError { | ||||||
|  |     CorruptedKey, | ||||||
|  |     KeyNotFound, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl std::fmt::Display for SigningError { | ||||||
|  |     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||||||
|  |         let error_message = match self { | ||||||
|  |             SigningError::CorruptedKey => "The public key is corrupted", | ||||||
|  |             SigningError::KeyNotFound => "Did not find the public key", | ||||||
|  |         }; | ||||||
|  |         write!(f, "{}", error_message) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl From<hex::FromHexError> for SigningError { | ||||||
|  |     fn from(_: hex::FromHexError) -> Self { | ||||||
|  |         Self::CorruptedKey | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl From<ed25519_dalek::ed25519::Error> for SigningError { | ||||||
|  |     fn from(_: ed25519_dalek::ed25519::Error) -> Self { | ||||||
|  |         Self::CorruptedKey | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl From<std::array::TryFromSliceError> for SigningError { | ||||||
|  |     fn from(_: std::array::TryFromSliceError) -> Self { | ||||||
|  |         Self::CorruptedKey | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| #[derive(Clone)] | #[derive(Clone)] | ||||||
| pub struct NodeInfo { | pub struct NodeInfo { | ||||||
|     pub pubkey: VerifyingKey, |     pub pubkey: VerifyingKey, | ||||||
| @ -27,11 +60,29 @@ pub fn remove_key(pubkey: &VerifyingKey) { | |||||||
|     keys.remove(pubkey); |     keys.remove(pubkey); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pub fn get_privkey(pubkey: &VerifyingKey) -> Option<SigningKey> { | fn get_privkey(pubkey: &VerifyingKey) -> Option<SigningKey> { | ||||||
|     let keys = KEYS.lock().unwrap(); |     let keys = KEYS.lock().unwrap(); | ||||||
|     keys.get(pubkey).cloned() |     keys.get(pubkey).cloned() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | pub fn sign_message_with_key(pubkey: &str, message: &str) -> Result<String, SigningError> { | ||||||
|  |     // Parse the hex string into a VerifyingKey
 | ||||||
|  |     let key_bytes = hex::decode(pubkey)?; | ||||||
|  |     let pubkey = VerifyingKey::from_bytes(&key_bytes.as_slice().try_into()?)?; | ||||||
|  | 
 | ||||||
|  |     // Lock the hashmap and try to get the SigningKey
 | ||||||
|  |     let key_store = KEYS.lock().unwrap(); | ||||||
|  |     let signing_key = match key_store.get(&pubkey) { | ||||||
|  |         Some(k) => k, | ||||||
|  |         None => return Err(SigningError::KeyNotFound), | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     // TODO: check if to_bytes returns the signature in a format that people can verify from bash
 | ||||||
|  |     let signature = hex::encode(signing_key.sign(message.as_bytes()).to_bytes()); | ||||||
|  | 
 | ||||||
|  |     Ok(signature) | ||||||
|  | } | ||||||
|  | 
 | ||||||
| pub fn add_node(ip: String, info: NodeInfo) { | pub fn add_node(ip: String, info: NodeInfo) { | ||||||
|     let mut nodes = NODES.lock().unwrap(); |     let mut nodes = NODES.lock().unwrap(); | ||||||
|     nodes.insert(ip, info); |     nodes.insert(ip, info); | ||||||
|  | |||||||
| @ -4,11 +4,13 @@ use rand::rngs::OsRng; | |||||||
| 
 | 
 | ||||||
| pub fn add_node(ip: String) { | pub fn add_node(ip: String) { | ||||||
|     let mut csprng = OsRng; |     let mut csprng = OsRng; | ||||||
|  |     let privkey = ed25519_dalek::SigningKey::generate(&mut csprng); | ||||||
|     database::add_node( |     database::add_node( | ||||||
|         ip, |         ip, | ||||||
|         NodeInfo { |         NodeInfo { | ||||||
|             pubkey: ed25519_dalek::SigningKey::generate(&mut csprng).verifying_key(), |             pubkey: privkey.verifying_key(), | ||||||
|             updated_at: std::time::SystemTime::now(), |             updated_at: std::time::SystemTime::now(), | ||||||
|         }, |         }, | ||||||
|     ) |     ); | ||||||
|  |     database::add_key(privkey.verifying_key(), privkey); | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,14 +1,34 @@ | |||||||
| use salvo::prelude::*; |  | ||||||
| use crate::database::get_nodes_as_html_tabe; | use crate::database::get_nodes_as_html_tabe; | ||||||
|  | use salvo::prelude::*; | ||||||
| 
 | 
 | ||||||
| #[handler] | #[handler] | ||||||
| async fn homepage() -> String { | async fn homepage() -> String { | ||||||
|     get_nodes_as_html_tabe() |     get_nodes_as_html_tabe() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | #[handler] | ||||||
|  | async fn sign(req: &mut Request) -> String { | ||||||
|  |     let pubkey = match req.query::<String>("pubkey") { | ||||||
|  |         Some(k) => k, | ||||||
|  |         None => return "pubkey must be specified as GET param".to_string(), | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     let something = match req.query::<String>("something") { | ||||||
|  |         Some(k) => k, | ||||||
|  |         None => return "something must be specified as GET param".to_string(), | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     match crate::database::sign_message_with_key(&pubkey, &something) { | ||||||
|  |         Ok(s) => s, | ||||||
|  |         Err(e) => e.to_string(), | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| pub async fn start() { | pub async fn start() { | ||||||
|     let acceptor = TcpListener::new("0.0.0.0:5800").bind().await; |     let acceptor = TcpListener::new("0.0.0.0:5800").bind().await; | ||||||
|     let router = Router::new().get(homepage); |     let router = Router::new() | ||||||
|  |         .get(homepage) | ||||||
|  |         .push(Router::with_path("sign").get(sign)); | ||||||
|     println!("{:?}", router); |     println!("{:?}", router); | ||||||
|     Server::new(acceptor).serve(router).await; |     Server::new(acceptor).serve(router).await; | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user