Documentation
¶
Overview ¶
Package hash implements the three hash forms defined by Component Manifest v1 §8: literal passthrough, file-over-bytes, and deterministic directory digests. See TASKS.md milestone M3 for scope, including the algorithm allowlist in §8.1 and the extension-filtered walk in §8.4.
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ErrEmptyDirectory = errors.New("directory digest produced no eligible files")
ErrEmptyDirectory signals that the directory-digest walk ended with zero eligible files after hidden / symlink / extension filtering (§8.4 step 3).
var ErrInvalidLiteralValue = errors.New("invalid hash value")
ErrInvalidLiteralValue signals that a literal-form `value` string is not a lowercase-hex digest of the declared algorithm's expected length. §8.1 mandates lowercase hex for producer-supplied literals.
var ErrNotRegularOrDir = errors.New("hash path is neither a regular file nor a directory")
ErrNotRegularOrDir signals that `hashes[].path` resolved to neither a regular file nor a directory. Only those two forms are valid targets for §8.3.
var ErrUnsupportedAlgorithm = errors.New("unsupported hash algorithm")
ErrUnsupportedAlgorithm signals an algorithm name outside the §8.1 allowlist — including the explicitly forbidden MD5 and SHA-1. The error message names the offending value so manifest-field validation can surface it.
Functions ¶
func Directory ¶
func Directory(manifestDir, relPath string, alg Algorithm, extensions []string, maxSize int64) (string, error)
Directory computes the §8.3 / §8.4 hash:
- If relPath resolves to a regular file, falls back to File form (§8.3 first bullet). The `extensions` filter is ignored in that case.
- If relPath resolves to a directory, runs the §8.4 deterministic walk: skip subdirs starting with '.', skip hidden files, skip symbolic links at every layer, apply case-insensitive extension filter (leading '*.' / '.' stripped), hash each remaining file with the declared algorithm, build the sorted manifest string of `<hex><SP><SP><rel-path><LF>` lines, hash that manifest, return the resulting lowercase hex digest.
A zero or negative maxSize uses safefs.DefaultMaxFileSize (10 MiB); the cap applies per regular file encountered during the walk.
func File ¶
File computes the file-form hash (§8.2): open relPath under the safefs rules — NFC path normalisation, symlink refusal, regular-file check, size cap — stream the bytes into alg.New(), and return the lowercase hex digest.
A zero or negative maxSize uses safefs.DefaultMaxFileSize (10 MiB).
func ValidateLiteralValue ¶
ValidateLiteralValue checks that v is a lowercase-hex digest of the declared algorithm's expected length (§8.1). It does not parse the value into bytes — the consumer passes the literal through to the output SBOM unchanged — but it does reject uppercase, mixed-case, and wrong-length values.
Types ¶
type Algorithm ¶
type Algorithm int
Algorithm is one of the five hash algorithms §8.1 permits. MD5, SHA-1, and any other identifier are outside the allowlist in *every* hash form — literal, file, and directory alike.
const ( SHA256 Algorithm SHA384 SHA512 SHA3_256 SHA3_512 )
func Parse ¶
Parse maps a spec `hashes[].algorithm` string to an Algorithm. Matching is case-sensitive against the canonical forms in §8.1 — producers are responsible for using the exact form. Any other value, including `MD5`, `SHA-1`, `sha-256`, or `SHA3-256`, returns ErrUnsupportedAlgorithm.
func (Algorithm) New ¶
New returns a freshly-initialised hash.Hash for this algorithm. Callers MUST have obtained Algorithm from Parse, which enforces the allowlist; using a zero-value Algorithm panics so bugs surface as crashes rather than silent MD5-style weakness.