mirror of
https://github.com/uutils/coreutils.git
synced 2026-06-10 15:48:22 -07:00
util(cksum): Add support for sha2 and sha3
This commit is contained in:
@@ -8,10 +8,8 @@ cksum-after-help = DIGEST determines the digest algorithm and default output for
|
|||||||
- crc32b: (only available through cksum)
|
- crc32b: (only available through cksum)
|
||||||
- md5: (equivalent to md5sum)
|
- md5: (equivalent to md5sum)
|
||||||
- sha1: (equivalent to sha1sum)
|
- sha1: (equivalent to sha1sum)
|
||||||
- sha224: (equivalent to sha224sum)
|
- sha2: (equivalent to sha{"{224,256,384,512}"}sum)
|
||||||
- sha256: (equivalent to sha256sum)
|
- sha3: (only available through cksum)
|
||||||
- sha384: (equivalent to sha384sum)
|
|
||||||
- sha512: (equivalent to sha512sum)
|
|
||||||
- blake2b: (equivalent to b2sum)
|
- blake2b: (equivalent to b2sum)
|
||||||
- sm3: (only available through cksum)
|
- sm3: (only available through cksum)
|
||||||
|
|
||||||
|
|||||||
@@ -8,10 +8,8 @@ cksum-after-help = DIGEST détermine l'algorithme de condensé et le format de s
|
|||||||
- crc32b : (disponible uniquement via cksum)
|
- crc32b : (disponible uniquement via cksum)
|
||||||
- md5 : (équivalent à md5sum)
|
- md5 : (équivalent à md5sum)
|
||||||
- sha1 : (équivalent à sha1sum)
|
- sha1 : (équivalent à sha1sum)
|
||||||
- sha224 : (équivalent à sha224sum)
|
- sha2: (équivalent à sha{"{224,256,384,512}"}sum)
|
||||||
- sha256 : (équivalent à sha256sum)
|
- sha3 : (disponible uniquement via cksum)
|
||||||
- sha384 : (équivalent à sha384sum)
|
|
||||||
- sha512 : (équivalent à sha512sum)
|
|
||||||
- blake2b : (équivalent à b2sum)
|
- blake2b : (équivalent à b2sum)
|
||||||
- sm3 : (disponible uniquement via cksum)
|
- sm3 : (disponible uniquement via cksum)
|
||||||
|
|
||||||
|
|||||||
@@ -14,9 +14,10 @@ use std::iter;
|
|||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use uucore::checksum::{
|
use uucore::checksum::{
|
||||||
ALGORITHM_OPTIONS_BLAKE2B, ALGORITHM_OPTIONS_BSD, ALGORITHM_OPTIONS_CRC,
|
ALGORITHM_OPTIONS_BLAKE2B, ALGORITHM_OPTIONS_BSD, ALGORITHM_OPTIONS_CRC,
|
||||||
ALGORITHM_OPTIONS_CRC32B, ALGORITHM_OPTIONS_SYSV, ChecksumError, ChecksumOptions,
|
ALGORITHM_OPTIONS_CRC32B, ALGORITHM_OPTIONS_SHA2, ALGORITHM_OPTIONS_SHA3,
|
||||||
ChecksumVerbose, HashAlgorithm, LEGACY_ALGORITHMS, SUPPORTED_ALGORITHMS,
|
ALGORITHM_OPTIONS_SYSV, ChecksumError, ChecksumOptions, ChecksumVerbose, HashAlgorithm,
|
||||||
calculate_blake2b_length, detect_algo, digest_reader, perform_checksum_validation,
|
LEGACY_ALGORITHMS, SUPPORTED_ALGORITHMS, calculate_blake2b_length, detect_algo, digest_reader,
|
||||||
|
perform_checksum_validation,
|
||||||
};
|
};
|
||||||
use uucore::translate;
|
use uucore::translate;
|
||||||
|
|
||||||
@@ -382,13 +383,16 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
|||||||
|
|
||||||
let input_length = matches.get_one::<usize>(options::LENGTH);
|
let input_length = matches.get_one::<usize>(options::LENGTH);
|
||||||
|
|
||||||
let length = match input_length {
|
let length = match (input_length, algo_name) {
|
||||||
None | Some(0) => None,
|
// Length for sha2 and sha3 should be saved, it will be validated
|
||||||
Some(length) if algo_name == ALGORITHM_OPTIONS_BLAKE2B => {
|
// afterwards if necessary.
|
||||||
calculate_blake2b_length(*length)?
|
(Some(len), ALGORITHM_OPTIONS_SHA2 | ALGORITHM_OPTIONS_SHA3) => Some(*len),
|
||||||
}
|
(None | Some(0), _) => None,
|
||||||
|
// Length for Blake2b if saved only if it's not zero.
|
||||||
|
(Some(len), ALGORITHM_OPTIONS_BLAKE2B) => calculate_blake2b_length(*len)?,
|
||||||
|
// a --length flag set with any other algorithm is an error.
|
||||||
_ => {
|
_ => {
|
||||||
return Err(ChecksumError::LengthOnlyForBlake2b.into());
|
return Err(ChecksumError::LengthOnlyForBlake2bSha2Sha3.into());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ fn create_algorithm_from_flags(matches: &ArgMatches) -> UResult<HashAlgorithm> {
|
|||||||
if matches.get_flag("sha3") {
|
if matches.get_flag("sha3") {
|
||||||
match matches.get_one::<usize>("bits") {
|
match matches.get_one::<usize>("bits") {
|
||||||
Some(bits) => set_or_err(create_sha3(*bits)?)?,
|
Some(bits) => set_or_err(create_sha3(*bits)?)?,
|
||||||
None => return Err(ChecksumError::BitsRequiredForSha3.into()),
|
None => return Err(ChecksumError::LengthRequired("SHA3".into()).into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if matches.get_flag("sha3-224") {
|
if matches.get_flag("sha3-224") {
|
||||||
@@ -139,7 +139,7 @@ fn create_algorithm_from_flags(matches: &ArgMatches) -> UResult<HashAlgorithm> {
|
|||||||
create_fn: Box::new(|| Box::new(Shake128::new())),
|
create_fn: Box::new(|| Box::new(Shake128::new())),
|
||||||
bits: *bits,
|
bits: *bits,
|
||||||
})?,
|
})?,
|
||||||
None => return Err(ChecksumError::BitsRequiredForShake128.into()),
|
None => return Err(ChecksumError::LengthRequired("SHAKE128".into()).into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if matches.get_flag("shake256") {
|
if matches.get_flag("shake256") {
|
||||||
@@ -149,7 +149,7 @@ fn create_algorithm_from_flags(matches: &ArgMatches) -> UResult<HashAlgorithm> {
|
|||||||
create_fn: Box::new(|| Box::new(Shake256::new())),
|
create_fn: Box::new(|| Box::new(Shake256::new())),
|
||||||
bits: *bits,
|
bits: *bits,
|
||||||
})?,
|
})?,
|
||||||
None => return Err(ChecksumError::BitsRequiredForShake256.into()),
|
None => return Err(ChecksumError::LengthRequired("SHAKE256".into()).into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ pub const ALGORITHM_OPTIONS_CRC: &str = "crc";
|
|||||||
pub const ALGORITHM_OPTIONS_CRC32B: &str = "crc32b";
|
pub const ALGORITHM_OPTIONS_CRC32B: &str = "crc32b";
|
||||||
pub const ALGORITHM_OPTIONS_MD5: &str = "md5";
|
pub const ALGORITHM_OPTIONS_MD5: &str = "md5";
|
||||||
pub const ALGORITHM_OPTIONS_SHA1: &str = "sha1";
|
pub const ALGORITHM_OPTIONS_SHA1: &str = "sha1";
|
||||||
|
pub const ALGORITHM_OPTIONS_SHA2: &str = "sha2";
|
||||||
pub const ALGORITHM_OPTIONS_SHA3: &str = "sha3";
|
pub const ALGORITHM_OPTIONS_SHA3: &str = "sha3";
|
||||||
|
|
||||||
pub const ALGORITHM_OPTIONS_SHA224: &str = "sha224";
|
pub const ALGORITHM_OPTIONS_SHA224: &str = "sha224";
|
||||||
@@ -47,21 +48,23 @@ pub const ALGORITHM_OPTIONS_SM3: &str = "sm3";
|
|||||||
pub const ALGORITHM_OPTIONS_SHAKE128: &str = "shake128";
|
pub const ALGORITHM_OPTIONS_SHAKE128: &str = "shake128";
|
||||||
pub const ALGORITHM_OPTIONS_SHAKE256: &str = "shake256";
|
pub const ALGORITHM_OPTIONS_SHAKE256: &str = "shake256";
|
||||||
|
|
||||||
pub const SUPPORTED_ALGORITHMS: [&str; 16] = [
|
pub const SUPPORTED_ALGORITHMS: [&str; 17] = [
|
||||||
ALGORITHM_OPTIONS_SYSV,
|
ALGORITHM_OPTIONS_SYSV,
|
||||||
ALGORITHM_OPTIONS_BSD,
|
ALGORITHM_OPTIONS_BSD,
|
||||||
ALGORITHM_OPTIONS_CRC,
|
ALGORITHM_OPTIONS_CRC,
|
||||||
ALGORITHM_OPTIONS_CRC32B,
|
ALGORITHM_OPTIONS_CRC32B,
|
||||||
ALGORITHM_OPTIONS_MD5,
|
ALGORITHM_OPTIONS_MD5,
|
||||||
ALGORITHM_OPTIONS_SHA1,
|
ALGORITHM_OPTIONS_SHA1,
|
||||||
|
ALGORITHM_OPTIONS_SHA2,
|
||||||
ALGORITHM_OPTIONS_SHA3,
|
ALGORITHM_OPTIONS_SHA3,
|
||||||
|
ALGORITHM_OPTIONS_BLAKE2B,
|
||||||
|
ALGORITHM_OPTIONS_SM3,
|
||||||
|
// Extra algorithms that are not valid `cksum --algorithm`
|
||||||
ALGORITHM_OPTIONS_SHA224,
|
ALGORITHM_OPTIONS_SHA224,
|
||||||
ALGORITHM_OPTIONS_SHA256,
|
ALGORITHM_OPTIONS_SHA256,
|
||||||
ALGORITHM_OPTIONS_SHA384,
|
ALGORITHM_OPTIONS_SHA384,
|
||||||
ALGORITHM_OPTIONS_SHA512,
|
ALGORITHM_OPTIONS_SHA512,
|
||||||
ALGORITHM_OPTIONS_BLAKE2B,
|
|
||||||
ALGORITHM_OPTIONS_BLAKE3,
|
ALGORITHM_OPTIONS_BLAKE3,
|
||||||
ALGORITHM_OPTIONS_SM3,
|
|
||||||
ALGORITHM_OPTIONS_SHAKE128,
|
ALGORITHM_OPTIONS_SHAKE128,
|
||||||
ALGORITHM_OPTIONS_SHAKE256,
|
ALGORITHM_OPTIONS_SHAKE256,
|
||||||
];
|
];
|
||||||
@@ -215,20 +218,16 @@ pub enum ChecksumError {
|
|||||||
StrictNotCheck,
|
StrictNotCheck,
|
||||||
#[error("the --quiet option is meaningful only when verifying checksums")]
|
#[error("the --quiet option is meaningful only when verifying checksums")]
|
||||||
QuietNotCheck,
|
QuietNotCheck,
|
||||||
#[error("Invalid output size for SHA3 (expected 224, 256, 384, or 512)")]
|
#[error("--length required for {}", .0.quote())]
|
||||||
InvalidOutputSizeForSha3,
|
LengthRequired(String),
|
||||||
#[error("--bits required for SHA3")]
|
#[error("unknown algorithm: {0}: clap should have prevented this case")]
|
||||||
BitsRequiredForSha3,
|
UnknownAlgorithm(String),
|
||||||
#[error("--bits required for SHAKE128")]
|
|
||||||
BitsRequiredForShake128,
|
|
||||||
#[error("--bits required for SHAKE256")]
|
|
||||||
BitsRequiredForShake256,
|
|
||||||
#[error("unknown algorithm: clap should have prevented this case")]
|
|
||||||
UnknownAlgorithm,
|
|
||||||
#[error("length is not a multiple of 8")]
|
#[error("length is not a multiple of 8")]
|
||||||
InvalidLength,
|
InvalidLength,
|
||||||
#[error("--length is only supported with --algorithm=blake2b")]
|
#[error("digest length for {} must be 224, 256, 384, or 512", .0.quote())]
|
||||||
LengthOnlyForBlake2b,
|
InvalidLengthFor(String),
|
||||||
|
#[error("--length is only supported with --algorithm blake2b, sha2, or sha3")]
|
||||||
|
LengthOnlyForBlake2bSha2Sha3,
|
||||||
#[error("the --binary and --text options are meaningless when verifying checksums")]
|
#[error("the --binary and --text options are meaningless when verifying checksums")]
|
||||||
BinaryTextConflict,
|
BinaryTextConflict,
|
||||||
#[error("--text mode is only supported with --untagged")]
|
#[error("--text mode is only supported with --untagged")]
|
||||||
@@ -258,27 +257,54 @@ impl UError for ChecksumError {
|
|||||||
pub fn create_sha3(bits: usize) -> UResult<HashAlgorithm> {
|
pub fn create_sha3(bits: usize) -> UResult<HashAlgorithm> {
|
||||||
match bits {
|
match bits {
|
||||||
224 => Ok(HashAlgorithm {
|
224 => Ok(HashAlgorithm {
|
||||||
name: "SHA3_224",
|
name: "SHA3-224",
|
||||||
create_fn: Box::new(|| Box::new(Sha3_224::new())),
|
create_fn: Box::new(|| Box::new(Sha3_224::new())),
|
||||||
bits: 224,
|
bits: 224,
|
||||||
}),
|
}),
|
||||||
256 => Ok(HashAlgorithm {
|
256 => Ok(HashAlgorithm {
|
||||||
name: "SHA3_256",
|
name: "SHA3-256",
|
||||||
create_fn: Box::new(|| Box::new(Sha3_256::new())),
|
create_fn: Box::new(|| Box::new(Sha3_256::new())),
|
||||||
bits: 256,
|
bits: 256,
|
||||||
}),
|
}),
|
||||||
384 => Ok(HashAlgorithm {
|
384 => Ok(HashAlgorithm {
|
||||||
name: "SHA3_384",
|
name: "SHA3-384",
|
||||||
create_fn: Box::new(|| Box::new(Sha3_384::new())),
|
create_fn: Box::new(|| Box::new(Sha3_384::new())),
|
||||||
bits: 384,
|
bits: 384,
|
||||||
}),
|
}),
|
||||||
512 => Ok(HashAlgorithm {
|
512 => Ok(HashAlgorithm {
|
||||||
name: "SHA3_512",
|
name: "SHA3-512",
|
||||||
create_fn: Box::new(|| Box::new(Sha3_512::new())),
|
create_fn: Box::new(|| Box::new(Sha3_512::new())),
|
||||||
bits: 512,
|
bits: 512,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
_ => Err(ChecksumError::InvalidOutputSizeForSha3.into()),
|
_ => Err(ChecksumError::InvalidLengthFor("SHA3".into()).into()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn create_sha2(bits: usize) -> UResult<HashAlgorithm> {
|
||||||
|
match bits {
|
||||||
|
224 => Ok(HashAlgorithm {
|
||||||
|
name: "SHA224",
|
||||||
|
create_fn: Box::new(|| Box::new(Sha224::new())),
|
||||||
|
bits: 224,
|
||||||
|
}),
|
||||||
|
256 => Ok(HashAlgorithm {
|
||||||
|
name: "SHA256",
|
||||||
|
create_fn: Box::new(|| Box::new(Sha256::new())),
|
||||||
|
bits: 256,
|
||||||
|
}),
|
||||||
|
384 => Ok(HashAlgorithm {
|
||||||
|
name: "SHA384",
|
||||||
|
create_fn: Box::new(|| Box::new(Sha384::new())),
|
||||||
|
bits: 384,
|
||||||
|
}),
|
||||||
|
512 => Ok(HashAlgorithm {
|
||||||
|
name: "SHA512",
|
||||||
|
create_fn: Box::new(|| Box::new(Sha512::new())),
|
||||||
|
bits: 512,
|
||||||
|
}),
|
||||||
|
|
||||||
|
_ => Err(ChecksumError::InvalidLengthFor("SHA2".into()).into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -398,26 +424,10 @@ pub fn detect_algo(algo: &str, length: Option<usize>) -> UResult<HashAlgorithm>
|
|||||||
create_fn: Box::new(|| Box::new(Sha1::new())),
|
create_fn: Box::new(|| Box::new(Sha1::new())),
|
||||||
bits: 160,
|
bits: 160,
|
||||||
}),
|
}),
|
||||||
ALGORITHM_OPTIONS_SHA224 | "sha224sum" => Ok(HashAlgorithm {
|
ALGORITHM_OPTIONS_SHA224 | "sha224sum" => Ok(create_sha2(224)?),
|
||||||
name: ALGORITHM_OPTIONS_SHA224,
|
ALGORITHM_OPTIONS_SHA256 | "sha256sum" => Ok(create_sha2(256)?),
|
||||||
create_fn: Box::new(|| Box::new(Sha224::new())),
|
ALGORITHM_OPTIONS_SHA384 | "sha384sum" => Ok(create_sha2(384)?),
|
||||||
bits: 224,
|
ALGORITHM_OPTIONS_SHA512 | "sha512sum" => Ok(create_sha2(512)?),
|
||||||
}),
|
|
||||||
ALGORITHM_OPTIONS_SHA256 | "sha256sum" => Ok(HashAlgorithm {
|
|
||||||
name: ALGORITHM_OPTIONS_SHA256,
|
|
||||||
create_fn: Box::new(|| Box::new(Sha256::new())),
|
|
||||||
bits: 256,
|
|
||||||
}),
|
|
||||||
ALGORITHM_OPTIONS_SHA384 | "sha384sum" => Ok(HashAlgorithm {
|
|
||||||
name: ALGORITHM_OPTIONS_SHA384,
|
|
||||||
create_fn: Box::new(|| Box::new(Sha384::new())),
|
|
||||||
bits: 384,
|
|
||||||
}),
|
|
||||||
ALGORITHM_OPTIONS_SHA512 | "sha512sum" => Ok(HashAlgorithm {
|
|
||||||
name: ALGORITHM_OPTIONS_SHA512,
|
|
||||||
create_fn: Box::new(|| Box::new(Sha512::new())),
|
|
||||||
bits: 512,
|
|
||||||
}),
|
|
||||||
ALGORITHM_OPTIONS_BLAKE2B | "b2sum" => {
|
ALGORITHM_OPTIONS_BLAKE2B | "b2sum" => {
|
||||||
// Set default length to 512 if None
|
// Set default length to 512 if None
|
||||||
let bits = length.unwrap_or(512);
|
let bits = length.unwrap_or(512);
|
||||||
@@ -445,28 +455,38 @@ pub fn detect_algo(algo: &str, length: Option<usize>) -> UResult<HashAlgorithm>
|
|||||||
create_fn: Box::new(|| Box::new(Sm3::new())),
|
create_fn: Box::new(|| Box::new(Sm3::new())),
|
||||||
bits: 512,
|
bits: 512,
|
||||||
}),
|
}),
|
||||||
ALGORITHM_OPTIONS_SHAKE128 | "shake128sum" => {
|
algo @ (ALGORITHM_OPTIONS_SHAKE128 | "shake128sum") => {
|
||||||
let bits = length.ok_or(ChecksumError::BitsRequiredForShake128)?;
|
let bits = length.ok_or(ChecksumError::LengthRequired(algo.to_ascii_uppercase()))?;
|
||||||
Ok(HashAlgorithm {
|
Ok(HashAlgorithm {
|
||||||
name: ALGORITHM_OPTIONS_SHAKE128,
|
name: ALGORITHM_OPTIONS_SHAKE128,
|
||||||
create_fn: Box::new(|| Box::new(Shake128::new())),
|
create_fn: Box::new(|| Box::new(Shake128::new())),
|
||||||
bits,
|
bits,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
ALGORITHM_OPTIONS_SHAKE256 | "shake256sum" => {
|
algo @ (ALGORITHM_OPTIONS_SHAKE256 | "shake256sum") => {
|
||||||
let bits = length.ok_or(ChecksumError::BitsRequiredForShake256)?;
|
let bits = length.ok_or(ChecksumError::LengthRequired(algo.to_ascii_uppercase()))?;
|
||||||
Ok(HashAlgorithm {
|
Ok(HashAlgorithm {
|
||||||
name: ALGORITHM_OPTIONS_SHAKE256,
|
name: ALGORITHM_OPTIONS_SHAKE256,
|
||||||
create_fn: Box::new(|| Box::new(Shake256::new())),
|
create_fn: Box::new(|| Box::new(Shake256::new())),
|
||||||
bits,
|
bits,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
_ if algo.starts_with("sha3") => {
|
algo @ ALGORITHM_OPTIONS_SHA2 => {
|
||||||
let bits = length.ok_or(ChecksumError::BitsRequiredForSha3)?;
|
let bits = validate_sha2_sha3_length(algo, length)?;
|
||||||
|
create_sha2(bits)
|
||||||
|
}
|
||||||
|
algo @ ALGORITHM_OPTIONS_SHA3 => {
|
||||||
|
let bits = validate_sha2_sha3_length(algo, length)?;
|
||||||
create_sha3(bits)
|
create_sha3(bits)
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => Err(ChecksumError::UnknownAlgorithm.into()),
|
// TODO: `hashsum` specific, to remove once hashsum is removed.
|
||||||
|
algo @ ("sha3-224" | "sha3-256" | "sha3-384" | "sha3-512") => {
|
||||||
|
let bits: usize = algo.strip_prefix("sha3-").unwrap().parse().unwrap();
|
||||||
|
create_sha3(bits)
|
||||||
|
}
|
||||||
|
|
||||||
|
algo => Err(ChecksumError::UnknownAlgorithm(algo.into()).into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -833,7 +853,9 @@ fn identify_algo_name_and_length(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let bytes = if let Some(bitlen) = line_info.algo_bit_len {
|
let bytes = if let Some(bitlen) = line_info.algo_bit_len {
|
||||||
if algorithm != ALGORITHM_OPTIONS_BLAKE2B || bitlen % 8 != 0 {
|
match algorithm.as_str() {
|
||||||
|
ALGORITHM_OPTIONS_BLAKE2B if bitlen % 8 == 0 => Some(bitlen / 8),
|
||||||
|
ALGORITHM_OPTIONS_SHA3 if [224, 256, 384, 512].contains(&bitlen) => Some(bitlen),
|
||||||
// Either
|
// Either
|
||||||
// the algo based line is provided with a bit length
|
// the algo based line is provided with a bit length
|
||||||
// with an algorithm that does not support it (only Blake2B does).
|
// with an algorithm that does not support it (only Blake2B does).
|
||||||
@@ -842,9 +864,8 @@ fn identify_algo_name_and_length(
|
|||||||
// ^ This is illegal
|
// ^ This is illegal
|
||||||
// OR
|
// OR
|
||||||
// the given length is wrong because it's not a multiple of 8.
|
// the given length is wrong because it's not a multiple of 8.
|
||||||
return Err(LineCheckError::ImproperlyFormatted);
|
_ => return Err(LineCheckError::ImproperlyFormatted),
|
||||||
}
|
}
|
||||||
Some(bitlen / 8)
|
|
||||||
} else if algorithm == ALGORITHM_OPTIONS_BLAKE2B {
|
} else if algorithm == ALGORITHM_OPTIONS_BLAKE2B {
|
||||||
// Default length with BLAKE2b,
|
// Default length with BLAKE2b,
|
||||||
Some(64)
|
Some(64)
|
||||||
@@ -939,15 +960,24 @@ fn process_non_algo_based_line(
|
|||||||
let expected_checksum = get_expected_digest_as_hex_string(line_info, None)
|
let expected_checksum = get_expected_digest_as_hex_string(line_info, None)
|
||||||
.ok_or(LineCheckError::ImproperlyFormatted)?;
|
.ok_or(LineCheckError::ImproperlyFormatted)?;
|
||||||
|
|
||||||
// When a specific algorithm name is input, use it and use the provided bits
|
// When a specific algorithm name is input, use it and use the provided
|
||||||
// except when dealing with blake2b, where we will detect the length
|
// bits except when dealing with blake2b, sha2 and sha3, where we will
|
||||||
let (algo_name, algo_byte_len) = if cli_algo_name == ALGORITHM_OPTIONS_BLAKE2B {
|
// detect the length.
|
||||||
// division by 2 converts the length of the Blake2b checksum from hexadecimal
|
let (algo_name, algo_byte_len) = match cli_algo_name {
|
||||||
// characters to bytes, as each byte is represented by two hexadecimal characters.
|
ALGORITHM_OPTIONS_BLAKE2B => {
|
||||||
let length = Some(expected_checksum.len() / 2);
|
// division by 2 converts the length of the Blake2b checksum from
|
||||||
(ALGORITHM_OPTIONS_BLAKE2B.to_string(), length)
|
// hexadecimal characters to bytes, as each byte is represented by
|
||||||
} else {
|
// two hexadecimal characters.
|
||||||
(cli_algo_name.to_lowercase(), cli_algo_length)
|
(
|
||||||
|
ALGORITHM_OPTIONS_BLAKE2B.to_string(),
|
||||||
|
Some(expected_checksum.len() / 2),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
algo @ (ALGORITHM_OPTIONS_SHA2 | ALGORITHM_OPTIONS_SHA3) => {
|
||||||
|
// multiplication by 4 to get the number of bits
|
||||||
|
(algo.to_string(), Some(expected_checksum.len() * 4))
|
||||||
|
}
|
||||||
|
_ => (cli_algo_name.to_lowercase(), cli_algo_length),
|
||||||
};
|
};
|
||||||
|
|
||||||
let algo = detect_algo(&algo_name, algo_byte_len)?;
|
let algo = detect_algo(&algo_name, algo_byte_len)?;
|
||||||
@@ -1216,6 +1246,17 @@ pub fn calculate_blake2b_length(length: usize) -> UResult<Option<usize>> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn validate_sha2_sha3_length(algo_name: &str, length: Option<usize>) -> UResult<usize> {
|
||||||
|
match length {
|
||||||
|
Some(len @ (224 | 256 | 384 | 512)) => Ok(len),
|
||||||
|
Some(len) => {
|
||||||
|
show_error!("invalid length: '{len}'");
|
||||||
|
Err(ChecksumError::InvalidLengthFor(algo_name.to_ascii_uppercase()).into())
|
||||||
|
}
|
||||||
|
None => Err(ChecksumError::LengthRequired(algo_name.to_ascii_uppercase()).into()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn unescape_filename(filename: &[u8]) -> (Vec<u8>, &'static str) {
|
pub fn unescape_filename(filename: &[u8]) -> (Vec<u8>, &'static str) {
|
||||||
let mut unescaped = Vec::with_capacity(filename.len());
|
let mut unescaped = Vec::with_capacity(filename.len());
|
||||||
let mut byte_iter = filename.iter().peekable();
|
let mut byte_iter = filename.iter().peekable();
|
||||||
@@ -1327,19 +1368,19 @@ mod tests {
|
|||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
detect_algo(ALGORITHM_OPTIONS_SHA224, None).unwrap().name,
|
detect_algo(ALGORITHM_OPTIONS_SHA224, None).unwrap().name,
|
||||||
ALGORITHM_OPTIONS_SHA224
|
ALGORITHM_OPTIONS_SHA224.to_ascii_uppercase()
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
detect_algo(ALGORITHM_OPTIONS_SHA256, None).unwrap().name,
|
detect_algo(ALGORITHM_OPTIONS_SHA256, None).unwrap().name,
|
||||||
ALGORITHM_OPTIONS_SHA256
|
ALGORITHM_OPTIONS_SHA256.to_ascii_uppercase()
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
detect_algo(ALGORITHM_OPTIONS_SHA384, None).unwrap().name,
|
detect_algo(ALGORITHM_OPTIONS_SHA384, None).unwrap().name,
|
||||||
ALGORITHM_OPTIONS_SHA384
|
ALGORITHM_OPTIONS_SHA384.to_ascii_uppercase()
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
detect_algo(ALGORITHM_OPTIONS_SHA512, None).unwrap().name,
|
detect_algo(ALGORITHM_OPTIONS_SHA512, None).unwrap().name,
|
||||||
ALGORITHM_OPTIONS_SHA512
|
ALGORITHM_OPTIONS_SHA512.to_ascii_uppercase()
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
detect_algo(ALGORITHM_OPTIONS_BLAKE2B, None).unwrap().name,
|
detect_algo(ALGORITHM_OPTIONS_BLAKE2B, None).unwrap().name,
|
||||||
@@ -1365,12 +1406,35 @@ mod tests {
|
|||||||
.name,
|
.name,
|
||||||
ALGORITHM_OPTIONS_SHAKE256
|
ALGORITHM_OPTIONS_SHAKE256
|
||||||
);
|
);
|
||||||
assert_eq!(detect_algo("sha3_224", Some(224)).unwrap().name, "SHA3_224");
|
|
||||||
assert_eq!(detect_algo("sha3_256", Some(256)).unwrap().name, "SHA3_256");
|
|
||||||
assert_eq!(detect_algo("sha3_384", Some(384)).unwrap().name, "SHA3_384");
|
|
||||||
assert_eq!(detect_algo("sha3_512", Some(512)).unwrap().name, "SHA3_512");
|
|
||||||
|
|
||||||
assert!(detect_algo("sha3_512", None).is_err());
|
// Older versions of checksum used to detect the "sha3" prefix, but not
|
||||||
|
// anymore.
|
||||||
|
assert!(detect_algo("sha3_224", Some(224)).is_err());
|
||||||
|
assert!(detect_algo("sha3_256", Some(256)).is_err());
|
||||||
|
assert!(detect_algo("sha3_384", Some(384)).is_err());
|
||||||
|
assert!(detect_algo("sha3_512", Some(512)).is_err());
|
||||||
|
|
||||||
|
let sha3_224 = detect_algo("sha3", Some(224)).unwrap();
|
||||||
|
assert_eq!(sha3_224.name, "SHA3-224");
|
||||||
|
assert_eq!(sha3_224.bits, 224);
|
||||||
|
let sha3_256 = detect_algo("sha3", Some(256)).unwrap();
|
||||||
|
assert_eq!(sha3_256.name, "SHA3-256");
|
||||||
|
assert_eq!(sha3_256.bits, 256);
|
||||||
|
let sha3_384 = detect_algo("sha3", Some(384)).unwrap();
|
||||||
|
assert_eq!(sha3_384.name, "SHA3-384");
|
||||||
|
assert_eq!(sha3_384.bits, 384);
|
||||||
|
let sha3_512 = detect_algo("sha3", Some(512)).unwrap();
|
||||||
|
assert_eq!(sha3_512.name, "SHA3-512");
|
||||||
|
assert_eq!(sha3_512.bits, 512);
|
||||||
|
|
||||||
|
assert!(detect_algo("sha3", None).is_err());
|
||||||
|
|
||||||
|
assert_eq!(detect_algo("sha2", Some(224)).unwrap().name, "SHA224");
|
||||||
|
assert_eq!(detect_algo("sha2", Some(256)).unwrap().name, "SHA256");
|
||||||
|
assert_eq!(detect_algo("sha2", Some(384)).unwrap().name, "SHA384");
|
||||||
|
assert_eq!(detect_algo("sha2", Some(512)).unwrap().name, "SHA512");
|
||||||
|
|
||||||
|
assert!(detect_algo("sha2", None).is_err());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
@@ -336,7 +336,9 @@ fn test_length_with_wrong_algorithm() {
|
|||||||
.arg("lorem_ipsum.txt")
|
.arg("lorem_ipsum.txt")
|
||||||
.fails_with_code(1)
|
.fails_with_code(1)
|
||||||
.no_stdout()
|
.no_stdout()
|
||||||
.stderr_contains("cksum: --length is only supported with --algorithm=blake2b");
|
.stderr_contains(
|
||||||
|
"cksum: --length is only supported with --algorithm blake2b, sha2, or sha3",
|
||||||
|
);
|
||||||
|
|
||||||
new_ucmd!()
|
new_ucmd!()
|
||||||
.arg("--length=16")
|
.arg("--length=16")
|
||||||
@@ -345,7 +347,9 @@ fn test_length_with_wrong_algorithm() {
|
|||||||
.arg("foo.sums")
|
.arg("foo.sums")
|
||||||
.fails_with_code(1)
|
.fails_with_code(1)
|
||||||
.no_stdout()
|
.no_stdout()
|
||||||
.stderr_contains("cksum: --length is only supported with --algorithm=blake2b");
|
.stderr_contains(
|
||||||
|
"cksum: --length is only supported with --algorithm blake2b, sha2, or sha3",
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Giving --length to a wrong algorithm doesn't fail if the length is zero
|
/// Giving --length to a wrong algorithm doesn't fail if the length is zero
|
||||||
@@ -369,7 +373,9 @@ fn test_length_not_supported() {
|
|||||||
.arg("lorem_ipsum.txt")
|
.arg("lorem_ipsum.txt")
|
||||||
.fails_with_code(1)
|
.fails_with_code(1)
|
||||||
.no_stdout()
|
.no_stdout()
|
||||||
.stderr_contains("--length is only supported with --algorithm=blake2b");
|
.stderr_contains(
|
||||||
|
"cksum: --length is only supported with --algorithm blake2b, sha2, or sha3",
|
||||||
|
);
|
||||||
|
|
||||||
new_ucmd!()
|
new_ucmd!()
|
||||||
.arg("-l")
|
.arg("-l")
|
||||||
@@ -380,7 +386,9 @@ fn test_length_not_supported() {
|
|||||||
.arg("/tmp/xxx")
|
.arg("/tmp/xxx")
|
||||||
.fails_with_code(1)
|
.fails_with_code(1)
|
||||||
.no_stdout()
|
.no_stdout()
|
||||||
.stderr_contains("--length is only supported with --algorithm=blake2b");
|
.stderr_contains(
|
||||||
|
"cksum: --length is only supported with --algorithm blake2b, sha2, or sha3",
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
Reference in New Issue
Block a user