From aea9ec9267931cc065e06099065aa17e3eb02fa0 Mon Sep 17 00:00:00 2001 From: eason <30045503+Eason0729@users.noreply.github.com> Date: Mon, 11 Dec 2023 18:26:10 +0800 Subject: [PATCH] fix: :bug: remove ring --- backend/Cargo.lock | 146 +++++++++++++++++++++++++++++-- backend/Cargo.toml | 5 +- backend/src/controller/crypto.rs | 70 +++++++-------- backend/src/controller/token.rs | 11 +-- backend/src/init/db.rs | 33 +++---- backend/src/init/mod.rs | 14 ++- backend/src/server.rs | 47 +++------- 7 files changed, 216 insertions(+), 110 deletions(-) diff --git a/backend/Cargo.lock b/backend/Cargo.lock index 96c794ff..cae2a721 100644 --- a/backend/Cargo.lock +++ b/backend/Cargo.lock @@ -338,6 +338,7 @@ version = "0.1.0" dependencies = [ "base64", "bincode", + "blake2", "chrono", "crossbeam-queue", "dashmap", @@ -345,6 +346,7 @@ dependencies = [ "entity", "futures", "hickory-resolver", + "k256", "leaky-bucket", "log", "opentelemetry", @@ -356,7 +358,8 @@ dependencies = [ "prost 0.12.3", "prost-types", "quick_cache", - "ring 0.17.5", + "rand", + "rand_hc", "sea-orm", "serde", "spin 0.9.8", @@ -388,6 +391,12 @@ dependencies = [ "rustc-demangle", ] +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + [[package]] name = "base64" version = "0.21.5" @@ -447,6 +456,15 @@ dependencies = [ "wyz", ] +[[package]] +name = "blake2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" +dependencies = [ + "digest", +] + [[package]] name = "block-buffer" version = "0.10.2" @@ -724,11 +742,23 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "crypto-bigint" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "generic-array", + "rand_core", + "subtle", + "zeroize", +] + [[package]] name = "crypto-common" -version = "0.1.3" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57952ca27b5e3606ff4dd79b0020231aaf9d6aa76dc05fd30137538c50bd3ce8" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array", "typenum", @@ -859,6 +889,20 @@ version = "0.15.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" +[[package]] +name = "ecdsa" +version = "0.16.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +dependencies = [ + "der", + "digest", + "elliptic-curve", + "rfc6979", + "signature", + "spki", +] + [[package]] name = "either" version = "1.6.1" @@ -868,6 +912,25 @@ dependencies = [ "serde", ] +[[package]] +name = "elliptic-curve" +version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +dependencies = [ + "base16ct", + "crypto-bigint", + "digest", + "ff", + "generic-array", + "group", + "pkcs8", + "rand_core", + "sec1", + "subtle", + "zeroize", +] + [[package]] name = "entity" version = "0.1.0" @@ -949,6 +1012,16 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" +[[package]] +name = "ff" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +dependencies = [ + "rand_core", + "subtle", +] + [[package]] name = "fixedbitset" version = "0.4.2" @@ -1120,12 +1193,13 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.14.5" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", + "zeroize", ] [[package]] @@ -1163,6 +1237,17 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff", + "rand_core", + "subtle", +] + [[package]] name = "h2" version = "0.3.19" @@ -1546,6 +1631,20 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "k256" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f01b677d82ef7a676aa37e099defd83a28e15687112cafdd112d60236b6115b" +dependencies = [ + "cfg-if", + "ecdsa", + "elliptic-curve", + "once_cell", + "sha2", + "signature", +] + [[package]] name = "kv-log-macro" version = "1.0.7" @@ -2393,6 +2492,15 @@ dependencies = [ "getrandom", ] +[[package]] +name = "rand_hc" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b363d4f6370f88d62bf586c80405657bde0f0e1b8945d47d2ad59b906cb4f54" +dependencies = [ + "rand_core", +] + [[package]] name = "redox_syscall" version = "0.3.5" @@ -2460,6 +2568,16 @@ dependencies = [ "quick-error", ] +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "subtle", +] + [[package]] name = "ring" version = "0.16.20" @@ -2809,6 +2927,20 @@ version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct", + "der", + "generic-array", + "pkcs8", + "subtle", + "zeroize", +] + [[package]] name = "security-framework" version = "2.9.2" @@ -4271,6 +4403,6 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" diff --git a/backend/Cargo.toml b/backend/Cargo.toml index f983e5d3..6713fa25 100644 --- a/backend/Cargo.toml +++ b/backend/Cargo.toml @@ -17,7 +17,6 @@ prost-types = "0.12.3" entity = { path = "./entity" } chrono = "0.4.26" thiserror = "1.0.44" -ring = "^0.17" derive_builder = "0.12.0" futures = "0.3.29" bincode = "1.3.3" @@ -30,6 +29,10 @@ hickory-resolver = "0.24.0" crossbeam-queue = "0.3.8" dashmap = "5.5.3" tracing-opentelemetry = "0.22.0" +rand = "0.8.5" +rand_hc = "0.3.2" +blake2 = "0.10.6" +k256 = "0.13.2" # a lot of opentelemetry dependencies opentelemetry = {version="0.21.0", features = ["metrics"]} opentelemetry_sdk = { version = "0.21.1", features = ["rt-tokio","metrics"] } diff --git a/backend/src/controller/crypto.rs b/backend/src/controller/crypto.rs index 01f12d11..5c11c39e 100644 --- a/backend/src/controller/crypto.rs +++ b/backend/src/controller/crypto.rs @@ -1,11 +1,12 @@ -use ring::{ - digest, rand, - signature::{self, KeyPair}, -}; +use rand::SeedableRng; +use rand_hc::Hc128Rng; use serde::{de::DeserializeOwned, Serialize}; +use spin::Mutex; use tracing::Span; +use k256::{SecretKey, Secp256k1, PublicKey}; use crate::{init::config::GlobalConfig, report_internal}; +use blake2::{Blake2b512, Digest}; type Result = std::result::Result; @@ -15,6 +16,10 @@ pub enum Error { Bincode(#[from] bincode::Error), #[error("Invalid signature")] InvalidSignature, + #[error("Encode error")] + Encode, + #[error("Decode error")] + Decode, } impl From for tonic::Status { @@ -22,13 +27,17 @@ impl From for tonic::Status { match value { Error::Bincode(_) => report_internal!(debug, "`{}`", value), Error::InvalidSignature => report_internal!(trace, "`{}`", value), + Error::Encode => report_internal!(trace, "`{}`", value), + Error::Decode => tonic::Status::invalid_argument("signature is invalid"), } } } pub struct CryptoController { - signer: signature::Ed25519KeyPair, salt: Vec, + rng: Mutex, + secret:SecretKey, + public:PublicKey, } #[derive(PartialEq, Eq)] @@ -49,12 +58,16 @@ impl From for Vec { impl CryptoController { #[tracing::instrument(parent=span,name="crypto_construct",level = "info",skip_all)] pub fn new(config: &GlobalConfig, span: &Span) -> Self { - let rng = rand::SystemRandom::new(); - let pkcs8_bytes = signature::Ed25519KeyPair::generate_pkcs8(&rng).unwrap(); - let signer = signature::Ed25519KeyPair::from_pkcs8(pkcs8_bytes.as_ref()).unwrap(); - let salt = config.database.salt.as_bytes().to_vec(); - Self { signer, salt } + + let mut rng = Hc128Rng::from_entropy(); + let secret=SecretKey::random(&mut rng); + let public=secret.public_key(); + Self { + salt, + rng: Mutex::new(rng), + secret,public + } } #[tracing::instrument(name = "crypto_hasheq_controller", level = "debug", skip_all)] pub fn hash_eq(&self, src: &str, tar: &[u8]) -> bool { @@ -69,42 +82,21 @@ impl CryptoController { } #[tracing::instrument(name = "crypto_hash_controller", level = "debug", skip_all)] pub fn hash(&self, src: &str) -> HashValue { - let hashed = digest::digest( - &digest::SHA256, - &[src.as_bytes(), self.salt.as_slice()].concat(), - ) - .as_ref() - .to_vec(); - HashValue(hashed) - } - #[tracing::instrument(level = "trace", skip_all)] - pub fn sign(&self, src: &str) -> Vec { - self.signer.sign(src.as_bytes()).as_ref().to_vec() - } - #[tracing::instrument(level = "trace", skip_all)] - pub fn verify(&self, src: &[u8], signature: &[u8]) -> bool { - let peer_public_key = signature::UnparsedPublicKey::new( - &signature::ED25519, - self.signer.public_key().as_ref(), - ); - peer_public_key.verify(src, signature).is_ok() + let mut hasher = Blake2b512::new(); + hasher.update(&[src.as_bytes(), self.salt.as_slice()].concat()); + + let hashed = hasher.finalize(); + HashValue(hashed.to_vec()) } #[tracing::instrument(level = "trace", skip_all)] pub fn encode(&self, obj: M) -> Result> { let mut raw = bincode::serialize(&obj)?; - let signature = self.signer.sign(&raw); - raw.extend(signature.as_ref()); - - Ok(raw) + todo!() } #[tracing::instrument(level = "trace", skip_all)] - pub fn decode(&self, raw: &[u8]) -> Result { - let (raw, signature) = raw.split_at(raw.len() - 64); - if !self.verify(raw, signature) { - return Err(Error::InvalidSignature); - } - Ok(bincode::deserialize(raw)?) + pub fn decode(&self, raw: Vec) -> Result { + todo!() } } diff --git a/backend/src/controller/token.rs b/backend/src/controller/token.rs index 68de1750..c97d0799 100644 --- a/backend/src/controller/token.rs +++ b/backend/src/controller/token.rs @@ -1,10 +1,12 @@ use chrono::{Duration, Local, NaiveDateTime}; use entity::token; use quick_cache::sync::Cache; -use ring::rand::*; +use rand::{Rng, SeedableRng}; +use rand_hc::Hc128Rng; use sea_orm::{ ActiveModelTrait, ActiveValue, ColumnTrait, DatabaseTransaction, EntityTrait, QueryFilter, }; +use spin::Mutex; use std::sync::Arc; use tokio::time; use tracing::{instrument, Instrument, Span}; @@ -62,7 +64,7 @@ impl From for CachedToken { pub struct TokenController { #[cfg(feature = "single-instance")] cache: Cache, - rand: SystemRandom, + rng: Mutex, cache_meter: RateMetrics<30>, } @@ -75,7 +77,7 @@ impl TokenController { let self_ = Arc::new(Self { #[cfg(feature = "single-instance")] cache, - rand: SystemRandom::new(), + rng: Mutex::new(Hc128Rng::from_entropy()), cache_meter: RateMetrics::new("hitrate_token"), }); tokio::spawn(async move { @@ -103,8 +105,7 @@ impl TokenController { ) -> Result<(String, NaiveDateTime), Error> { let db = DB.get().unwrap(); - let rand = generate(&self.rand).unwrap(); - let rand: Rand = rand.expose(); + let rand: Rand = { self.rng.lock().gen() }; let expiry = (Local::now() + dur).naive_local(); diff --git a/backend/src/init/db.rs b/backend/src/init/db.rs index 30b66b86..22567b3f 100644 --- a/backend/src/init/db.rs +++ b/backend/src/init/db.rs @@ -1,4 +1,3 @@ -use ring::digest; use sea_orm::{ ActiveModelTrait, ActiveValue, Database, DatabaseConnection, EntityTrait, PaginatorTrait, }; @@ -6,31 +5,35 @@ use sea_orm::{ use tokio::sync::OnceCell; use super::config::{self}; -use crate::controller::token::UserPermBytes; +use crate::controller::{crypto::CryptoController, token::UserPermBytes}; pub static DB: OnceCell = OnceCell::const_new(); -pub async fn init(config: &config::Database) { +pub async fn init(config: &config::Database, crypto: &CryptoController) { // sqlite://database/backend.sqlite?mode=rwc let uri = format!("sqlite://{}?mode=rwc&cache=private", config.path.clone()); let db = Database::connect(&uri) .await .expect("fail connecting to database"); - init_user(config, &db).await; + init_user(config, &db, crypto).await; DB.set(db).ok(); } -fn hash(config: &config::Database, src: &str) -> Vec { - digest::digest( - &digest::SHA256, - &[src.as_bytes(), config.salt.as_bytes()].concat(), - ) - .as_ref() - .to_vec() -} - -pub async fn init_user(config: &config::Database, db: &DatabaseConnection) { +// fn hash(config: &config::Database, src: &str) -> Vec { +// digest::digest( +// &digest::SHA256, +// &[src.as_bytes(), config.salt.as_bytes()].concat(), +// ) +// .as_ref() +// .to_vec() +// } + +pub async fn init_user( + config: &config::Database, + db: &DatabaseConnection, + crypto: &CryptoController, +) { if entity::user::Entity::find().count(db).await.unwrap() != 0 { return; } @@ -50,7 +53,7 @@ pub async fn init_user(config: &config::Database, db: &DatabaseConnection) { entity::user::ActiveModel { permission: ActiveValue::Set(perm.0), username: ActiveValue::Set("admin".to_owned()), - password: ActiveValue::Set(hash(config, "admin")), + password: ActiveValue::Set(crypto.hash("admin").into()), ..Default::default() } .insert(db) diff --git a/backend/src/init/mod.rs b/backend/src/init/mod.rs index 9a7d4fb8..943919b9 100644 --- a/backend/src/init/mod.rs +++ b/backend/src/init/mod.rs @@ -1,12 +1,10 @@ -use self::{config::GlobalConfig, logger::OtelGuard}; - pub mod config; pub mod db; pub mod logger; -pub async fn new() -> (GlobalConfig, OtelGuard) { - let config = config::init().await; - let olp_guard = logger::init(&config); - db::init(&config.database).await; - (config, olp_guard) -} +// pub async fn new() -> (GlobalConfig, OtelGuard) { +// let config = config::init().await; +// let olp_guard = logger::init(&config); +// db::init(&config.database).await; +// (config, olp_guard) +// } diff --git a/backend/src/server.rs b/backend/src/server.rs index 6efa20c2..712f4ad8 100644 --- a/backend/src/server.rs +++ b/backend/src/server.rs @@ -12,7 +12,6 @@ use crate::{ user_set_server::UserSetServer, }, init::{ - self, config::{self, GlobalConfig}, logger::{self, OtelGuard}, }, @@ -27,54 +26,32 @@ pub struct Server { pub crypto: crypto::CryptoController, pub metrics: metrics::MetricsController, config: GlobalConfig, - // identity: transport::Identity, otel_guard: OtelGuard, } impl Server { pub async fn new() -> Arc { + let span = span!(Level::INFO, "server_construct"); + let config = config::init().await; - let otel_guard = logger::init(&config); - let config1 = config.database.clone(); - // let config2 = config.grpc.public_pem.clone(); - // let config3 = config.grpc.private_pem.clone(); - let config4 = config.judger.clone(); + let crypto = crypto::CryptoController::new(&config, &span); + crate::init::db::init(&config.database, &crypto).await; - let span = span!(Level::INFO, "server_construct"); - let span1 = span.clone(); + let otel_guard = logger::init(&config); - let (_, submit) = tokio::try_join!( - tokio::spawn( - async move { init::db::init(&config1).await } - .instrument(span!(parent:span.clone(),Level::INFO,"construct_database")) - ), - // tokio::spawn( - // async move { fs::read_to_string(&config2).await } - // .instrument(span!(parent:span.clone(),Level::INFO,"load_tls")) - // ), - // tokio::spawn( - // async move { fs::read_to_string(&config3).await } - // .instrument(span!(parent:span.clone(),Level::INFO,"load_tls")) - // ), - tokio::spawn(async move { - judger::JudgerController::new(config4, &span1) - .in_current_span() - .await - }) - ) - .unwrap(); + let config4 = config.judger.clone(); - // let identity = transport::Identity::from_pem( - // cert.expect("public key.pem not found"), - // key.expect("privite key.pem not found"), - // ); + let submit = judger::JudgerController::new(config4, &span) + .in_current_span() + .await + .unwrap(); Arc::new(Server { token: token::TokenController::new(&span), - judger: Arc::new(submit.unwrap()), + judger: Arc::new(submit), dup: duplicate::DupController::new(&span), - crypto: crypto::CryptoController::new(&config, &span), + crypto, metrics: metrics::MetricsController::new(&otel_guard.meter_provider), config, // identity,