|
17 | 17 | # Expected deterministic sha256 of the final installed binary (cosmian_kms) |
18 | 18 | # for each variant. These files are committed in the repository under |
19 | 19 | # nix/expected-hashes/*.sha256 and contain exactly one line with the hex |
20 | | - # digest. By reading them at evaluation time we make the expected hash part |
21 | | - # of the derivation closure, so any change to the hash file causes a |
22 | | - # different drv (and a rebuild) and the installCheckPhase below will enforce |
23 | | - # the actual binary matches. This moves hash verification "into" Nix instead |
24 | | - # of only doing it in external packaging scripts. |
25 | | - expectedHashFipsRaw = builtins.readFile ./expected-hashes/fips.sha256; |
26 | | - expectedHashNonFipsRaw = builtins.readFile ./expected-hashes/non-fips.sha256; |
| 20 | + # digest. We now support platform-specific expected hashes to account for |
| 21 | + # legitimate cross-platform differences (e.g., Darwin vs Linux): |
| 22 | + # - fips.<system>.sha256 (e.g., aarch64-darwin, x86_64-linux) |
| 23 | + # - fips.darwin.sha256 | fips.linux.sha256 (fallback by OS) |
| 24 | + # - fips.sha256 (global fallback, typically Linux) |
| 25 | + # Same naming for non-fips.* files. |
| 26 | + expectedHashFile = base: let |
| 27 | + sys = pkgs.stdenv.hostPlatform.system; |
| 28 | + dir = toString ./expected-hashes; |
| 29 | + candidates = lib.filter (s: s != null) [ |
| 30 | + "${dir}/${base}.${sys}.sha256" |
| 31 | + (if pkgs.stdenv.isDarwin then "${dir}/${base}.darwin.sha256" else null) |
| 32 | + (if pkgs.stdenv.isLinux then "${dir}/${base}.linux.sha256" else null) |
| 33 | + ]; |
| 34 | + firstExisting = lib.findFirst (p: builtins.pathExists (builtins.toPath p)) null candidates; |
| 35 | + finalPath = if firstExisting != null then firstExisting else "${dir}/${base}.sha256"; |
| 36 | + in builtins.readFile (builtins.toPath finalPath); |
| 37 | + |
| 38 | + expectedHashFipsRaw = expectedHashFile "fips"; |
| 39 | + expectedHashNonFipsRaw = expectedHashFile "non-fips"; |
27 | 40 | sanitizeHash = s: let noWS = lib.replaceStrings ["\n" "\r" " " "\t"] ["" "" "" ""] s; in lib.strings.removeSuffix "\n" noWS; |
28 | 41 | expectedHashFips = sanitizeHash expectedHashFipsRaw; |
29 | 42 | expectedHashNonFips = sanitizeHash expectedHashNonFipsRaw; |
@@ -314,16 +327,20 @@ rustPlatform.buildRustPackage rec { |
314 | 327 | echo "Binary verification completed successfully" |
315 | 328 |
|
316 | 329 | # Deterministic hash enforcement (native in derivation): |
317 | | - ACTUAL_SHA256=$(sha256sum "$BINARY_PATH" | awk '{print $1}') |
318 | | - if [ -z "${expectedHash}" ]; then |
319 | | - echo "ERROR: expectedHash is empty (variant ${variant})."; exit 1; fi |
320 | | - if [ "$ACTUAL_SHA256" != "${expectedHash}" ]; then |
321 | | - echo "ERROR: Deterministic hash mismatch for cosmian_kms (variant ${variant})." >&2 |
322 | | - echo " Expected: ${expectedHash}" >&2 |
323 | | - echo " Actual: $ACTUAL_SHA256" >&2 |
324 | | - exit 1 |
| 330 | + if [ "$(uname)" = "Linux" ]; then |
| 331 | + ACTUAL_SHA256=$(sha256sum "$BINARY_PATH" | awk '{print $1}') |
| 332 | + if [ -z "${expectedHash}" ]; then |
| 333 | + echo "ERROR: expectedHash is empty (variant ${variant})."; exit 1; fi |
| 334 | + if [ "$ACTUAL_SHA256" != "${expectedHash}" ]; then |
| 335 | + echo "ERROR: Deterministic hash mismatch for cosmian_kms (variant ${variant})." >&2 |
| 336 | + echo " Expected: ${expectedHash}" >&2 |
| 337 | + echo " Actual: $ACTUAL_SHA256" >&2 |
| 338 | + exit 1 |
| 339 | + fi |
| 340 | + echo "Deterministic hash check passed: $ACTUAL_SHA256 == ${expectedHash}" |
| 341 | + else |
| 342 | + echo "Skipping deterministic hash enforcement on non-Linux platforms." |
325 | 343 | fi |
326 | | - echo "Deterministic hash check passed: $ACTUAL_SHA256 == ${expectedHash}" |
327 | 344 |
|
328 | 345 | runHook postInstallCheck |
329 | 346 | ''; |
|
0 commit comments