Skip to content

Commit 2c12922

Browse files
authored
mcf: make base64 an optional (on-by-default) feature (#2032)
1 parent 17d792f commit 2c12922

File tree

6 files changed

+38
-24
lines changed

6 files changed

+38
-24
lines changed

mcf/Cargo.toml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,12 @@ in the form `${id}$...`
1515
"""
1616

1717
[dependencies]
18-
base64ct = { version = "1.7", features = ["alloc"] }
18+
base64ct = { version = "1.7", optional = true }
1919

2020
[dev-dependencies]
2121
hex-literal = "1"
2222

2323
[features]
24-
default = ["alloc"]
25-
alloc = []
24+
default = ["alloc", "base64"]
25+
alloc = ["base64ct?/alloc"]
26+
base64 = ["dep:base64ct"]

mcf/src/base64.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
//! Base64 encoding variants.
22
3+
#![cfg(feature = "base64")]
4+
35
use base64ct::{Base64Bcrypt, Base64Crypt, Base64ShaCrypt, Encoding as _, Error as B64Error};
46

57
#[cfg(feature = "alloc")]

mcf/src/error.rs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,6 @@ pub type Result<T> = core::result::Result<T, Error>;
1010
#[non_exhaustive]
1111
pub struct Error {}
1212

13-
impl From<base64ct::Error> for Error {
14-
fn from(_: base64ct::Error) -> Error {
15-
Error {}
16-
}
17-
}
18-
1913
impl core::error::Error for Error {}
2014

2115
impl fmt::Display for Error {

mcf/src/fields.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
//! Fields of an MCF password hash, delimited by `$`
22
3-
use crate::{Base64, Error, Result};
3+
use crate::{Error, Result};
44
use core::fmt;
55

6-
#[cfg(feature = "alloc")]
6+
#[cfg(feature = "base64")]
7+
use crate::Base64;
8+
#[cfg(all(feature = "alloc", feature = "base64"))]
79
use alloc::vec::Vec;
810

911
/// MCF field delimiter: `$`.
@@ -70,14 +72,15 @@ impl<'a> Field<'a> {
7072
}
7173

7274
/// Decode Base64 into the provided output buffer.
75+
#[cfg(feature = "base64")]
7376
pub fn decode_base64_into(self, base64_variant: Base64, out: &mut [u8]) -> Result<&[u8]> {
74-
Ok(base64_variant.decode(self.0, out)?)
77+
base64_variant.decode(self.0, out).map_err(|_| Error {})
7578
}
7679

7780
/// Decode this field as the provided Base64 variant.
78-
#[cfg(feature = "alloc")]
81+
#[cfg(all(feature = "alloc", feature = "base64"))]
7982
pub fn decode_base64(self, base64_variant: Base64) -> Result<Vec<u8>> {
80-
Ok(base64_variant.decode_vec(self.0)?)
83+
base64_variant.decode_vec(self.0).map_err(|_| Error {})
8184
}
8285

8386
/// Validate a field in the password hash is well-formed.

mcf/src/lib.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,13 @@ mod base64;
2020
mod error;
2121
mod fields;
2222

23-
pub use base64::Base64;
2423
pub use error::{Error, Result};
2524
pub use fields::{Field, Fields};
2625

2726
#[cfg(feature = "alloc")]
2827
pub use allocating::PasswordHash;
28+
#[cfg(feature = "base64")]
29+
pub use base64::Base64;
2930

3031
/// Debug message used in panics when invariants aren't properly held.
3132
const INVARIANT_MSG: &str = "should be ensured valid by constructor";
@@ -93,12 +94,13 @@ impl<'a> TryFrom<&'a str> for PasswordHashRef<'a> {
9394

9495
#[cfg(feature = "alloc")]
9596
mod allocating {
96-
use crate::{
97-
Base64, Error, Field, Fields, PasswordHashRef, Result, fields, validate, validate_id,
98-
};
97+
use crate::{Error, Field, Fields, PasswordHashRef, Result, fields, validate, validate_id};
9998
use alloc::string::String;
10099
use core::{fmt, str};
101100

101+
#[cfg(feature = "base64")]
102+
use crate::Base64;
103+
102104
/// Password hash encoded in the Modular Crypt Format (MCF). Owned form with builder
103105
/// functionality.
104106
///
@@ -166,6 +168,7 @@ mod allocating {
166168

167169
/// Encode the given data as the specified variant of Base64 and push it onto the password
168170
/// hash string, first adding a `$` delimiter.
171+
#[cfg(feature = "base64")]
169172
pub fn push_base64(&mut self, field: &[u8], base64_encoding: Base64) {
170173
self.0.push(fields::DELIMITER);
171174
self.0.push_str(&base64_encoding.encode_string(field));

mcf/tests/mcf.rs

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,16 @@
22
33
#![cfg(feature = "alloc")]
44

5-
use hex_literal::hex;
6-
use mcf::{Base64, PasswordHash};
5+
use mcf::PasswordHash;
6+
7+
#[cfg(feature = "base64")]
8+
use {hex_literal::hex, mcf::Base64};
79

810
const SHA512_HASH: &str = "$6$rounds=100000$exn6tVc2j/MZD8uG$BI1Xh8qQSK9J4m14uwy7abn.ctj/TIAzlaVCto0MQrOFIeTXsc1iwzH16XEWo/a7c7Y9eVJvufVzYAs4EsPOy0";
911

12+
#[cfg(feature = "base64")]
1013
const EXAMPLE_SALT: &[u8] = &hex!("6a3f237988126f80958fa24b");
14+
#[cfg(feature = "base64")]
1115
const EXAMPLE_HASH: &[u8] = &hex!(
1216
"0d358cad62739eb554863c183aef27e6390368fe061fc5fcb1193a392d60dcad4594fa8d383ab8fc3f0dc8088974602668422e6a58edfa1afe24831b10be69be"
1317
);
@@ -47,21 +51,28 @@ fn parse_sha512_hash() {
4751
let salt = fields.next().unwrap();
4852
assert_eq!("exn6tVc2j/MZD8uG", salt.as_str());
4953

50-
let salt_bytes = salt.decode_base64(Base64::ShaCrypt).unwrap();
51-
assert_eq!(EXAMPLE_SALT, salt_bytes.as_slice());
54+
#[cfg(feature = "base64")]
55+
{
56+
let salt_bytes = salt.decode_base64(Base64::ShaCrypt).unwrap();
57+
assert_eq!(EXAMPLE_SALT, salt_bytes.as_slice());
58+
}
5259

5360
let hash = fields.next().unwrap();
5461
assert_eq!(
5562
"BI1Xh8qQSK9J4m14uwy7abn.ctj/TIAzlaVCto0MQrOFIeTXsc1iwzH16XEWo/a7c7Y9eVJvufVzYAs4EsPOy0",
5663
hash.as_str()
5764
);
5865

59-
let hash_bytes = hash.decode_base64(Base64::ShaCrypt).unwrap();
60-
assert_eq!(EXAMPLE_HASH, hash_bytes.as_slice());
66+
#[cfg(feature = "base64")]
67+
{
68+
let hash_bytes = hash.decode_base64(Base64::ShaCrypt).unwrap();
69+
assert_eq!(EXAMPLE_HASH, hash_bytes.as_slice());
70+
}
6171

6272
assert_eq!(None, fields.next());
6373
}
6474

75+
#[cfg(feature = "base64")]
6576
#[test]
6677
fn push_fields() {
6778
let mut hash = PasswordHash::new("$6$rounds=100000").unwrap();

0 commit comments

Comments
 (0)