From a063edebb4968f50da41cb7d385e990449d0c7c4 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 24 Dec 2025 16:15:26 -0700 Subject: [PATCH] mcf: replace `Base64::Crypt` with `Base64::ShaCrypt` Renames the `Base64::ShaCrypt` variant to `Base64::Crypt`, removing the previous option entirely. See RustCrypto/formats#2133: the implementation of `base64ct`'s `Base64Crypt` is mistaken: it implements the Base64 alphabet used by `crypt(3)`, but the special little endian packing implemented in `Base64ShaCrypt` is ubiquitously used with this alphabet. So this simply makes `mcf::Base64::Crypt` the only option, and also the correct one for any `crypt(3)` password hash. --- base64ct/src/alphabet/shacrypt.rs | 8 +++---- mcf/src/base64.rs | 39 ++++++++++++------------------- mcf/src/lib.rs | 8 +++---- 3 files changed, 23 insertions(+), 32 deletions(-) diff --git a/base64ct/src/alphabet/shacrypt.rs b/base64ct/src/alphabet/shacrypt.rs index bf18b2bf0..e89caa7f1 100644 --- a/base64ct/src/alphabet/shacrypt.rs +++ b/base64ct/src/alphabet/shacrypt.rs @@ -5,11 +5,11 @@ use super::{Alphabet, DecodeStep, EncodeStep}; /// Little endian variant of the `crypt(3)` Base64 encoding. /// /// Used by the following schemes: -/// - md5_crypt +/// - MD5-Crypt /// - scrypt -/// - sha1_crypt -/// - sha256_crypt -/// - sha512_crypt +/// - SHA1-Crypt +/// - SHA256-Crypt +/// - SHA512-Crypt /// - yescrypt /// /// ```text diff --git a/mcf/src/base64.rs b/mcf/src/base64.rs index 50196c6e1..eff0682ee 100644 --- a/mcf/src/base64.rs +++ b/mcf/src/base64.rs @@ -2,7 +2,7 @@ #![cfg(feature = "base64")] -use base64ct::{Base64Bcrypt, Base64Crypt, Base64ShaCrypt, Encoding as _, Error as B64Error}; +use base64ct::{Base64Bcrypt, Base64ShaCrypt, Encoding as _, Error as B64Error}; #[cfg(feature = "alloc")] use alloc::{string::String, vec::Vec}; @@ -19,25 +19,21 @@ pub enum Base64 { /// ``` Bcrypt, - /// `crypt(3)` encoding. + /// `crypt(3)` Base64 encoding. /// - /// ```text - /// [.-9] [A-Z] [a-z] - /// 0x2e-0x39, 0x41-0x5a, 0x61-0x7a - /// ``` - Crypt, - - /// `crypt(3)` Base64 encoding for the following schemes: - /// - sha1_crypt, - /// - sha256_crypt, - /// - sha512_crypt, - /// - md5_crypt + /// Used by the following schemes: + /// - MD5-Crypt + /// - scrypt + /// - SHA1-Crypt + /// - SHA256-Crypt + /// - SHA512-Crypt + /// - yescrypt /// /// ```text /// [.-9] [A-Z] [a-z] /// 0x2e-0x39, 0x41-0x5a, 0x61-0x7a /// ``` - ShaCrypt, + Crypt, } impl Base64 { @@ -45,8 +41,7 @@ impl Base64 { pub fn decode(self, src: impl AsRef<[u8]>, dst: &mut [u8]) -> Result<&[u8], B64Error> { match self { Self::Bcrypt => Base64Bcrypt::decode(src, dst), - Self::Crypt => Base64Crypt::decode(src, dst), - Self::ShaCrypt => Base64ShaCrypt::decode(src, dst), + Self::Crypt => Base64ShaCrypt::decode(src, dst), } } @@ -55,8 +50,7 @@ impl Base64 { pub fn decode_vec(self, input: &str) -> Result, B64Error> { match self { Self::Bcrypt => Base64Bcrypt::decode_vec(input), - Self::Crypt => Base64Crypt::decode_vec(input), - Self::ShaCrypt => Base64ShaCrypt::decode_vec(input), + Self::Crypt => Base64ShaCrypt::decode_vec(input), } } @@ -67,8 +61,7 @@ impl Base64 { pub fn encode<'a>(self, src: &[u8], dst: &'a mut [u8]) -> Result<&'a str, B64Error> { match self { Self::Bcrypt => Base64Bcrypt::encode(src, dst), - Self::Crypt => Base64Crypt::encode(src, dst), - Self::ShaCrypt => Base64ShaCrypt::encode(src, dst), + Self::Crypt => Base64ShaCrypt::encode(src, dst), } .map_err(Into::into) } @@ -81,8 +74,7 @@ impl Base64 { pub fn encode_string(self, input: &[u8]) -> String { match self { Self::Bcrypt => Base64Bcrypt::encode_string(input), - Self::Crypt => Base64Crypt::encode_string(input), - Self::ShaCrypt => Base64ShaCrypt::encode_string(input), + Self::Crypt => Base64ShaCrypt::encode_string(input), } } @@ -90,8 +82,7 @@ impl Base64 { pub fn encoded_len(self, bytes: &[u8]) -> usize { match self { Self::Bcrypt => Base64Bcrypt::encoded_len(bytes), - Self::Crypt => Base64Crypt::encoded_len(bytes), - Self::ShaCrypt => Base64ShaCrypt::encoded_len(bytes), + Self::Crypt => Base64ShaCrypt::encoded_len(bytes), } } } diff --git a/mcf/src/lib.rs b/mcf/src/lib.rs index f8f36ca86..4fe79d992 100644 --- a/mcf/src/lib.rs +++ b/mcf/src/lib.rs @@ -433,7 +433,7 @@ mod tests { #[cfg(feature = "base64")] { - let salt_bytes = salt.decode_base64(Base64::ShaCrypt).unwrap(); + let salt_bytes = salt.decode_base64(Base64::Crypt).unwrap(); assert_eq!(EXAMPLE_SALT, salt_bytes.as_slice()); } @@ -445,7 +445,7 @@ mod tests { #[cfg(feature = "base64")] { - let hash_bytes = hash.decode_base64(Base64::ShaCrypt).unwrap(); + let hash_bytes = hash.decode_base64(Base64::Crypt).unwrap(); assert_eq!(EXAMPLE_HASH, hash_bytes.as_slice()); } @@ -456,8 +456,8 @@ mod tests { #[test] fn push_base64() { let mut hash = PasswordHash::new("$6$rounds=100000").unwrap(); - hash.push_base64(EXAMPLE_SALT, Base64::ShaCrypt); - hash.push_base64(EXAMPLE_HASH, Base64::ShaCrypt); + hash.push_base64(EXAMPLE_SALT, Base64::Crypt); + hash.push_base64(EXAMPLE_HASH, Base64::Crypt); assert_eq!(SHA512_HASH, hash.as_str()); }