diff --git a/Cargo.lock b/Cargo.lock index e784f0e..e6fff7b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1005,9 +1005,9 @@ dependencies = [ [[package]] name = "darling" -version = "0.12.4" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f2c43f534ea4b0b049015d00269734195e6d3f0f6635cb692251aca6f9f8b3c" +checksum = "c0808e1bd8671fb44a113a14e13497557533369847788fa2ae912b6ebfce9fa8" dependencies = [ "darling_core", "darling_macro", @@ -1015,9 +1015,9 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.12.4" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e91455b86830a1c21799d94524df0845183fa55bafd9aa137b01c7d1065fa36" +checksum = "001d80444f28e193f30c2f293455da62dcf9a6b29918a4253152ae2b1de592cb" dependencies = [ "fnv", "ident_case", @@ -1029,9 +1029,9 @@ dependencies = [ [[package]] name = "darling_macro" -version = "0.12.4" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29b5acf0dea37a7f66f7b25d2c5e93fd46f8f6968b1a5d7a3e02e97768afc95a" +checksum = "b36230598a2d5de7ec1c6f51f72d8a99a9208daff41de2084d06e3fd3ea56685" dependencies = [ "darling_core", "quote", @@ -1071,18 +1071,18 @@ dependencies = [ [[package]] name = "derive_builder" -version = "0.10.2" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d13202debe11181040ae9063d739fa32cfcaaebe2275fe387703460ae2365b30" +checksum = "8d67778784b508018359cbc8696edb3db78160bab2c2a28ba7f56ef6932997f8" dependencies = [ "derive_builder_macro", ] [[package]] name = "derive_builder_core" -version = "0.10.2" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66e616858f6187ed828df7c64a6d71720d83767a7f19740b2d1b6fe6327b36e5" +checksum = "c11bdc11a0c47bc7d37d582b5285da6849c96681023680b906673c5707af7b0f" dependencies = [ "darling", "proc-macro2", @@ -1092,9 +1092,9 @@ dependencies = [ [[package]] name = "derive_builder_macro" -version = "0.10.2" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58a94ace95092c5acb1e97a7e846b310cfbd499652f72297da7493f618a98d73" +checksum = "ebcda35c7a396850a55ffeac740804b40ffec779b98fffbb1738f4033f0ee79e" dependencies = [ "derive_builder_core", "syn", @@ -1272,6 +1272,12 @@ dependencies = [ "instant", ] +[[package]] +name = "fiat-crypto" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a214f5bb88731d436478f3ae1f8a277b62124089ba9fb67f4f93fb100ef73c90" + [[package]] name = "figment" version = "0.10.8" @@ -2274,7 +2280,7 @@ dependencies = [ "actix-web-httpauth", "anyhow", "async-trait", - "base64 0.13.1", + "base64 0.21.0", "bincode", "chrono", "clap", @@ -2284,7 +2290,7 @@ dependencies = [ "figment_file_provider_adapter", "futures", "futures-util", - "hmac 0.10.1", + "hmac 0.12.1", "http", "image", "itertools", @@ -2307,7 +2313,7 @@ dependencies = [ "serde", "serde_bytes", "serde_json", - "sha2 0.9.9", + "sha2 0.10.6", "thiserror", "time 0.3.19", "tokio", @@ -2704,11 +2710,12 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "orion" -version = "0.16.1" +version = "0.17.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6624905ddd92e460ff0685567539ed1ac985b2dee4c92c7edcd64fce905b00c" +checksum = "f2baf7fd2e326e3895c681176788dd227fcd8369350e53c570592d8563fecbb6" dependencies = [ "ct-codecs", + "fiat-crypto", "getrandom 0.2.8", "subtle", "zeroize", diff --git a/server/Cargo.toml b/server/Cargo.toml index 5ea7d83..94ee525 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -15,37 +15,37 @@ actix-web = "4.3" actix-web-httpauth = "0.8" anyhow = "*" async-trait = "0.1" -base64 = "0.13" +base64 = "*" bincode = "1.3" cron = "*" -derive_builder = "0.10.2" +derive_builder = "0.12" figment_file_provider_adapter = "0.1" futures = "*" futures-util = "*" -hmac = "0.10" +hmac = "0.12" http = "*" -itertools = "0.10.1" +itertools = "0.10" juniper = "0.15" jwt = "0.16" lber = "0.4.1" ldap3_proto = ">=0.3.1" log = "*" -orion = "0.16" +orion = "0.17" rustls = "0.20" serde = "*" serde_json = "1" -sha2 = "0.9" +sha2 = "0.10" thiserror = "*" time = "0.3" tokio-rustls = "0.23" tokio-stream = "*" -tokio-util = "0.7.3" +tokio-util = "0.7" tracing = "*" tracing-actix-web = "0.7" tracing-attributes = "^0.1.21" tracing-log = "*" -rustls-pemfile = "1.0.0" -serde_bytes = "0.11.7" +rustls-pemfile = "1" +serde_bytes = "0.11" webpki-roots = "*" [dependencies.chrono] diff --git a/server/src/domain/handler.rs b/server/src/domain/handler.rs index 7ba11bb..ded7f7d 100644 --- a/server/src/domain/handler.rs +++ b/server/src/domain/handler.rs @@ -211,6 +211,8 @@ mockall::mock! { #[cfg(test)] mod tests { + use base64::Engine; + use super::*; #[test] fn test_uuid_time() { @@ -233,7 +235,9 @@ mod tests { #[test] fn test_jpeg_try_from_bytes() { let base64_raw = "/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAP//////////////////////////////////////////////////////////////////////////////////////2wBDAf//////////////////////////////////////////////////////////////////////////////////////wAARCADqATkDASIAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAAAAECA//EACQQAQEBAAIBBAMBAQEBAAAAAAABESExQQISUXFhgZGxocHw/8QAFQEBAQAAAAAAAAAAAAAAAAAAAAH/xAAWEQEBAQAAAAAAAAAAAAAAAAAAEQH/2gAMAwEAAhEDEQA/AMriLyCKgg1gQwCgs4FTMOdutepjQak+FzMSVqgxZdRdPPIIvH5WzzGdBriphtTeAXg2ZjKA1pqKDUGZca3foBek8gFv8Ie3fKdA1qb8s7hoL6eLVt51FsAnql3Ut1M7AWbflLMDkEMX/F6/YjK/pADFQAUNA6alYagKk72m/j9p4Bq2fDDSYKLNXPNLoHE/NT6RYC31cJxZ3yWVM+aBYi/S2ZgiAsnYJx5D21vPmqrm3PTfpQQwyAC8JZvSKDni41ZrMuUVVl+Uz9w9v/1QWrZsZ5nFPHYH+JZyureQSF5M+fJ0CAfwRAVRBQA1DAWVUayoJUWoDpsxntPsueBV4+VxhdyAtv8AjOLGpIDMLbeGvbF4iozJfr/WukAVABAXAQXEAAASzVAZdO2WNordm+emFl7XcQSNZiFtv0C9w90nhJf4mA1u+GcJFwIyAqL/AOovwgGNfSRqdIrNa29M0gKCAojU9PAMjWXpckEJFNFEAAXEUBABYz6rZ0ureQc9vyt9XxDF2QAXtABcQAs0AZywkvluJbyipifas52DcyxjlZweAO0xri/hc+wZOEKIu6nSyeToVZyWXwvCg53gW81QQ7aTNAn5dGZJPs1UXURQAUEMCXQLZE93PRZ5hPTgNMrbIzKCm52LZwCs+2M8w2g3sjPuZAXb4IsMAUACzVUGM4/K+md6vEXUUyM5PDR0IxYe6ramih0VNBrS4xoqN8Q1BFQk3yqyAsioioAAKgDSJL4/jQIn5igLrPqtOuf6oOaxbMoAltUAhhIoJiiggrPu+AaOIxtAX3JbaAIaLwi4t9X4T3fg2AFtqcrUUarP20zUDAmqoE0WRBZPNVUVEAAAAVAC8kvih2DSKxOdBqs7Z0l0gI0mKAC4AuHE7ZtBriM+744QAAAAABAFsveIttBICyaikvy1+r/Cen5rWQHIBQa4rIDRqSl5qDWqziqgAAAATA7BpGdqXb2C2+J/UgAtRQBSQtkBWb6vhLbQAAAAAEBRAAAAAUbm+GZNdPxAP+ql2Tjwx7/wIgZ8iKvBk+CJoCXii9gaqZ/qqihAAAEVABGkBFUwBftNkZ3QW34QAAABFAQAVAAAAAARVkl8gs/43sk1jL45LvHArepk+E9XTG35oLqsmIKmLAEygKg0y1AFQBUXwgAAAoBC34S3UAAABAVAAAAAABAUQAVABdRQa1PcYyit2z58M8C4ouM2NXpOEGeWtNZUatiAIoAKIoCoAoG4C9MW6dgIoAIAAAAAAACKWAgL0CAAAALiANCKioNLgM1CrLihmTafkt1EF3SZ5ZVUW4mnIKvAi5fhEURVDWVQBRAAAAAAAAQFRVyAyulgAqCKlF8IqLsEgC9mGoC+IusqCrv5ZEUVOk1RuJfwSLOOkGFi4XPCoYYrNiKauosBGi9ICstM1UAAAAAAFQ0VcTBAXUGgIqGoKhKAzRRUQUAwxoSrGRpkQA/qiosOL9oJptMRRVZa0VUqSiChE6BqMgCwqKqIogAIAqKCKgKoogg0lBFuIKgAAAKNRlf2gqsftsEtZWoAAqAACKoMqAAeSoqp39kL2AqLOlE8rEBFQARYALhigrNC9gGmooLp4TweEQFFBFAECgIoAu0ifIAqAAA//9k="; - let base64_jpeg = base64::decode(base64_raw).unwrap(); + let base64_jpeg = base64::engine::general_purpose::STANDARD + .decode(base64_raw) + .unwrap(); JpegPhoto::try_from(base64_jpeg).unwrap(); } } diff --git a/server/src/domain/sql_opaque_handler.rs b/server/src/domain/sql_opaque_handler.rs index 5a5667b..9f92b7a 100644 --- a/server/src/domain/sql_opaque_handler.rs +++ b/server/src/domain/sql_opaque_handler.rs @@ -7,6 +7,7 @@ use super::{ types::UserId, }; use async_trait::async_trait; +use base64::Engine; use lldap_auth::opaque; use sea_orm::{ActiveModelTrait, ActiveValue, EntityTrait, QuerySelect}; use secstr::SecUtf8; @@ -129,7 +130,7 @@ impl OpaqueHandler for SqlOpaqueHandler { let encrypted_state = orion::aead::seal(&secret_key, &bincode::serialize(&server_data)?)?; Ok(login::ServerLoginStartResponse { - server_data: base64::encode(encrypted_state), + server_data: base64::engine::general_purpose::STANDARD.encode(encrypted_state), credential_response: start_response.message, }) } @@ -142,7 +143,7 @@ impl OpaqueHandler for SqlOpaqueHandler { server_login, } = bincode::deserialize(&orion::aead::open( &secret_key, - &base64::decode(&request.server_data)?, + &base64::engine::general_purpose::STANDARD.decode(&request.server_data)?, )?)?; // Finish the login: this makes sure the client data is correct, and gives a session key we // don't need. @@ -170,7 +171,7 @@ impl OpaqueHandler for SqlOpaqueHandler { }; let encrypted_state = orion::aead::seal(&secret_key, &bincode::serialize(&server_data)?)?; Ok(registration::ServerRegistrationStartResponse { - server_data: base64::encode(encrypted_state), + server_data: base64::engine::general_purpose::STANDARD.encode(encrypted_state), registration_response: start_response.message, }) } @@ -183,7 +184,7 @@ impl OpaqueHandler for SqlOpaqueHandler { let secret_key = self.get_orion_secret_key()?; let registration::ServerData { username } = bincode::deserialize(&orion::aead::open( &secret_key, - &base64::decode(&request.server_data)?, + &base64::engine::general_purpose::STANDARD.decode(&request.server_data)?, )?)?; let password_file = diff --git a/server/src/domain/types.rs b/server/src/domain/types.rs index 99ee6f4..0c1d1aa 100644 --- a/server/src/domain/types.rs +++ b/server/src/domain/types.rs @@ -1,3 +1,4 @@ +use base64::Engine; use chrono::{NaiveDateTime, TimeZone}; use sea_orm::{ entity::IntoActiveValue, @@ -224,13 +225,15 @@ impl TryFrom for JpegPhoto { type Error = anyhow::Error; fn try_from(string: String) -> anyhow::Result { // The String format is in base64. - >::try_from(base64::decode(string.as_str())?) + >::try_from( + base64::engine::general_purpose::STANDARD.decode(string.as_str())?, + ) } } impl From<&JpegPhoto> for String { fn from(val: &JpegPhoto) -> Self { - base64::encode(&val.0) + base64::engine::general_purpose::STANDARD.encode(&val.0) } } diff --git a/server/src/infra/graphql/mutation.rs b/server/src/infra/graphql/mutation.rs index 5134334..dfaca57 100644 --- a/server/src/infra/graphql/mutation.rs +++ b/server/src/infra/graphql/mutation.rs @@ -12,6 +12,7 @@ use crate::{ }, }; use anyhow::Context as AnyhowContext; +use base64::Engine; use juniper::{graphql_object, FieldResult, GraphQLInputObject, GraphQLObject}; use tracing::{debug, debug_span, Instrument}; @@ -89,7 +90,7 @@ impl Mutation { let user_id = UserId::new(&user.id); let avatar = user .avatar - .map(base64::decode) + .map(|bytes| base64::engine::general_purpose::STANDARD.decode(bytes)) .transpose() .context("Invalid base64 image")? .map(JpegPhoto::try_from) @@ -146,7 +147,7 @@ impl Mutation { .ok_or_else(field_error_callback(&span, "Unauthorized user update"))?; let avatar = user .avatar - .map(base64::decode) + .map(|bytes| base64::engine::general_purpose::STANDARD.decode(bytes)) .transpose() .context("Invalid base64 image")? .map(JpegPhoto::try_from) diff --git a/server/src/infra/tcp_server.rs b/server/src/infra/tcp_server.rs index d12951c..00d131e 100644 --- a/server/src/infra/tcp_server.rs +++ b/server/src/infra/tcp_server.rs @@ -18,7 +18,7 @@ use actix_server::ServerBuilder; use actix_service::map_config; use actix_web::{dev::AppConfig, web, App, HttpResponse}; use anyhow::{Context, Result}; -use hmac::{Hmac, NewMac}; +use hmac::Hmac; use sha2::Sha512; use std::collections::HashSet; use std::path::PathBuf; @@ -80,7 +80,7 @@ fn http_config( let enable_password_reset = mail_options.enable_password_reset; cfg.app_data(web::Data::new(AppState:: { backend_handler: AccessControlledBackendHandler::new(backend_handler), - jwt_key: Hmac::new_varkey(jwt_secret.unsecure().as_bytes()).unwrap(), + jwt_key: hmac::Mac::new_from_slice(jwt_secret.unsecure().as_bytes()).unwrap(), jwt_blacklist: RwLock::new(jwt_blacklist), server_url, mail_options,