refactor: Change config private key type to K256Secret

Reviewed-on: #30
Reviewed-by: Amjad Alsharafi <me@amjad.alsharafi.dev>
Signed-off-by: Awiteb <a@4rs.nl>
This commit is contained in:
Awiteb 2024-07-24 01:17:13 +03:00
parent 672d7a2d3c
commit a01f4add0c
Signed by: awiteb
GPG key ID: 3F6B55640AA6682F
7 changed files with 31 additions and 28 deletions

View file

@ -71,11 +71,10 @@ pub async fn signature_check(
}; };
if !utils::is_valid_nonce(&signature, &depot.nonce_cache()).await if !utils::is_valid_nonce(&signature, &depot.nonce_cache()).await
|| !utils::is_valid_signature( || !depot.config().server.private_key.verify(
&sender_public_key,
&depot.config().server.private_key,
&signature,
data.as_bytes(), data.as_bytes(),
&signature,
&sender_public_key,
) )
{ {
write_err("Invalid signature", UNAUTHORIZED); write_err("Invalid signature", UNAUTHORIZED);

View file

@ -22,8 +22,7 @@ use chrono::Utc;
use logcall::logcall; use logcall::logcall;
use oxidetalis_config::Postgres; use oxidetalis_config::Postgres;
use oxidetalis_core::{ use oxidetalis_core::{
cipher::K256Secret, types::{PublicKey, Signature},
types::{PrivateKey, PublicKey, Signature},
PUBLIC_KEY_HEADER, PUBLIC_KEY_HEADER,
SIGNATURE_HEADER, SIGNATURE_HEADER,
}; };
@ -50,16 +49,6 @@ pub(crate) async fn is_valid_nonce(signature: &Signature, nonce_cache: &NonceCac
new_timestamp && unused_nonce new_timestamp && unused_nonce
} }
/// Returns true if the given signature is valid.
pub(crate) fn is_valid_signature(
signer: &PublicKey,
private_key: &PrivateKey,
signature: &Signature,
data: &[u8],
) -> bool {
K256Secret::from_privkey(private_key).verify(data, signature, signer)
}
/// Extract the sender public key from the request /// Extract the sender public key from the request
/// ///
/// Returns the public key of the sender extracted from the request, or the /// Returns the public key of the sender extracted from the request, or the

View file

@ -23,7 +23,7 @@ use chrono::Utc;
use errors::{WsError, WsResult}; use errors::{WsError, WsResult};
use futures::{channel::mpsc, FutureExt, StreamExt, TryStreamExt}; use futures::{channel::mpsc, FutureExt, StreamExt, TryStreamExt};
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use oxidetalis_core::{cipher::K256Secret, types::PublicKey}; use oxidetalis_core::types::PublicKey;
use oxidetalis_entities::prelude::*; use oxidetalis_entities::prelude::*;
use salvo::{ use salvo::{
handler, handler,
@ -102,9 +102,7 @@ pub async fn user_connected(
let db_conn = depot.db_conn(); let db_conn = depot.db_conn();
let public_key = let public_key =
utils::extract_public_key(req).expect("The public key was checked in the middleware"); utils::extract_public_key(req).expect("The public key was checked in the middleware");
// FIXME: The config should hold `K256Secret` not `PrivateKey` let shared_secret = depot.config().server.private_key.shared_secret(&public_key);
let shared_secret =
K256Secret::from_privkey(&depot.config().server.private_key).shared_secret(&public_key);
WebSocketUpgrade::new() WebSocketUpgrade::new()
.upgrade(req, res, move |ws| { .upgrade(req, res, move |ws| {

View file

@ -25,10 +25,7 @@
pub(crate) mod server { pub(crate) mod server {
use std::net::{IpAddr, Ipv4Addr}; use std::net::{IpAddr, Ipv4Addr};
use oxidetalis_core::{ use oxidetalis_core::{cipher::K256Secret, types::Size};
cipher::K256Secret,
types::{PrivateKey, Size},
};
pub fn name() -> String { pub fn name() -> String {
"example.com".to_owned() "example.com".to_owned()
@ -39,8 +36,8 @@ pub(crate) mod server {
pub const fn port() -> u16 { pub const fn port() -> u16 {
7294 7294
} }
pub fn private_key() -> PrivateKey { pub fn private_key() -> K256Secret {
K256Secret::new().privkey() K256Secret::new()
} }
pub const fn nonce_cache_size() -> Size { pub const fn nonce_cache_size() -> Size {
Size::MB(1) Size::MB(1)

View file

@ -23,7 +23,7 @@
use std::{fs, io::Error as IoError, net::IpAddr, path::Path}; use std::{fs, io::Error as IoError, net::IpAddr, path::Path};
use derivative::Derivative; use derivative::Derivative;
use oxidetalis_core::types::{PrivateKey, Size}; use oxidetalis_core::{cipher::K256Secret, types::Size};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use toml::{de::Error as TomlDeError, ser::Error as TomlSerError}; use toml::{de::Error as TomlDeError, ser::Error as TomlSerError};
@ -66,7 +66,7 @@ pub struct Server {
pub port: u16, pub port: u16,
/// Server keypair /// Server keypair
#[derivative(Default(value = "defaults::server::private_key()"))] #[derivative(Default(value = "defaults::server::private_key()"))]
pub private_key: PrivateKey, pub private_key: K256Secret,
/// Nonce cache limit /// Nonce cache limit
#[derivative(Default(value = "defaults::server::nonce_cache_size()"))] #[derivative(Default(value = "defaults::server::nonce_cache_size()"))]
pub nonce_cache_size: Size, pub nonce_cache_size: Size,

View file

@ -72,6 +72,7 @@ type HmacSha256 = hmac::Hmac<sha2::Sha256>;
/// An wrapper around the k256 crate to provide a simple API for ecdh key /// An wrapper around the k256 crate to provide a simple API for ecdh key
/// exchange and keypair generation. /// exchange and keypair generation.
#[derive(Clone)]
pub struct K256Secret { pub struct K256Secret {
/// The private key scalar /// The private key scalar
scalar: NonZeroScalar, scalar: NonZeroScalar,

View file

@ -25,6 +25,7 @@ use base58::FromBase58;
use serde::{de::Error as DeError, Deserialize, Serialize}; use serde::{de::Error as DeError, Deserialize, Serialize};
use super::{PrivateKey, PublicKey, Signature}; use super::{PrivateKey, PublicKey, Signature};
use crate::cipher::K256Secret;
impl<'de> Deserialize<'de> for PrivateKey { impl<'de> Deserialize<'de> for PrivateKey {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
@ -99,3 +100,21 @@ impl Serialize for Signature {
serializer.serialize_str(self.to_string().as_str()) serializer.serialize_str(self.to_string().as_str())
} }
} }
impl Serialize for K256Secret {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
PrivateKey::serialize(&self.privkey(), serializer)
}
}
impl<'de> Deserialize<'de> for K256Secret {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
Ok(Self::from_privkey(&PrivateKey::deserialize(deserializer)?))
}
}