97 lines
2.7 KiB
C#
97 lines
2.7 KiB
C#
using Microsoft.Extensions.Options;
|
|
|
|
namespace StellaOps.Scanner.Analyzers.Native;
|
|
|
|
/// <summary>
|
|
/// Options for ELF section hash extraction.
|
|
/// </summary>
|
|
public sealed class ElfSectionHashOptions
|
|
{
|
|
/// <summary>
|
|
/// Whether section hashing is enabled.
|
|
/// </summary>
|
|
public bool Enabled { get; set; } = true;
|
|
|
|
/// <summary>
|
|
/// Section names to include (e.g., .text, .rodata, .data).
|
|
/// </summary>
|
|
public IList<string> Sections { get; } = new List<string>
|
|
{
|
|
".text",
|
|
".rodata",
|
|
".data",
|
|
".symtab",
|
|
".dynsym"
|
|
};
|
|
|
|
/// <summary>
|
|
/// Hash algorithms to compute (sha256 required, blake3 optional).
|
|
/// </summary>
|
|
public IList<string> Algorithms { get; } = new List<string>
|
|
{
|
|
"sha256"
|
|
};
|
|
|
|
/// <summary>
|
|
/// Maximum section size to hash (bytes).
|
|
/// </summary>
|
|
public long MaxSectionSizeBytes { get; set; } = 100 * 1024 * 1024;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Validates <see cref="ElfSectionHashOptions"/>.
|
|
/// </summary>
|
|
public sealed class ElfSectionHashOptionsValidator : IValidateOptions<ElfSectionHashOptions>
|
|
{
|
|
private static readonly HashSet<string> AllowedAlgorithms = new(StringComparer.OrdinalIgnoreCase)
|
|
{
|
|
"sha256",
|
|
"blake3"
|
|
};
|
|
|
|
public ValidateOptionsResult Validate(string? name, ElfSectionHashOptions options)
|
|
{
|
|
ArgumentNullException.ThrowIfNull(options);
|
|
|
|
if (!options.Enabled)
|
|
{
|
|
return ValidateOptionsResult.Success;
|
|
}
|
|
|
|
if (options.MaxSectionSizeBytes <= 0)
|
|
{
|
|
return ValidateOptionsResult.Fail("MaxSectionSizeBytes must be greater than zero.");
|
|
}
|
|
|
|
var sections = options.Sections
|
|
.Where(section => !string.IsNullOrWhiteSpace(section))
|
|
.Select(section => section.Trim())
|
|
.ToArray();
|
|
|
|
if (sections.Length == 0)
|
|
{
|
|
return ValidateOptionsResult.Fail("At least one section name must be configured.");
|
|
}
|
|
|
|
if (options.Algorithms.Count == 0 ||
|
|
!options.Algorithms.Any(alg => string.Equals(alg?.Trim(), "sha256", StringComparison.OrdinalIgnoreCase)))
|
|
{
|
|
return ValidateOptionsResult.Fail("Algorithms must include sha256.");
|
|
}
|
|
|
|
var invalid = options.Algorithms
|
|
.Where(alg => !string.IsNullOrWhiteSpace(alg))
|
|
.Select(alg => alg.Trim())
|
|
.Where(alg => !AllowedAlgorithms.Contains(alg))
|
|
.Distinct(StringComparer.OrdinalIgnoreCase)
|
|
.ToArray();
|
|
|
|
if (invalid.Length > 0)
|
|
{
|
|
return ValidateOptionsResult.Fail($"Unsupported algorithms: {string.Join(", ", invalid)}");
|
|
}
|
|
|
|
return ValidateOptionsResult.Success;
|
|
}
|
|
}
|