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