run.sh (31122B)
1 #!/bin/sh 2 # Driver-level checks for kit pkg distribution formats. 3 4 set -u 5 6 script_dir=$(cd "$(dirname "$0")" && pwd) 7 repo_root=$(cd "$script_dir/../.." && pwd) 8 9 KIT="${KIT:-$repo_root/build/kit}" 10 11 if [ ! -x "$KIT" ]; then 12 echo "pkg: kit binary not found at $KIT" >&2 13 exit 2 14 fi 15 16 work=$(mktemp -d "${TMPDIR:-/tmp}/kit-pkg-test.XXXXXX") 17 trap 'rm -rf "$work"' EXIT 18 19 HOME="$work/home" 20 KIT_TRUSTED_KEYS="$work/trusted_keys" 21 SOURCE_DATE_EPOCH=1 22 export HOME KIT_TRUSTED_KEYS SOURCE_DATE_EPOCH 23 mkdir -p "$HOME" "$work/in" "$work/pkg" "$work/unpack" "$work/cas" 24 25 artifacts="empty.dat one.bin dup-one.bin payload.txt chunk64.bin chunk64-copy.bin chunk64p1.bin chunk3.bin bin/tool.sh" 26 tree_id= 27 28 # Type-K mode-P kit: shared assert verbs + CAS helpers, all recording through 29 # the unified kit_* counters over $work. pkg-specific helpers (not_contains, 30 # same_artifacts, not_same_file, have_cmd) stay below. 31 KIT_KIT_DIR="$repo_root/test/lib" 32 . "$repo_root/test/lib/kit_sh_kit.sh" 33 kit_report_init 34 35 not_contains() { 36 name=$1 37 file=$2 38 needle=$3 39 if grep -F "$needle" "$file" >/dev/null 2>&1; then 40 { 41 printf 'unexpected text: %s\n' "$needle" 42 sed 's/^/file: /' "$file" 43 } > "$work/$name.diag" 44 not_ok "$name" "$work/$name.diag" 45 else 46 ok "$name" 47 fi 48 } 49 50 same_artifacts() { 51 name=$1 52 dir=$2 53 diag="$work/$name.diag" 54 : > "$diag" 55 good=1 56 for f in $artifacts; do 57 if ! cmp -s "$work/in/$f" "$dir/$f"; then 58 printf 'artifact differs or is missing: %s\n' "$f" >> "$diag" 59 good=0 60 fi 61 done 62 if [ "$good" -eq 1 ]; then 63 ok "$name" 64 else 65 not_ok "$name" "$diag" 66 fi 67 } 68 69 not_same_file() { 70 name=$1 71 left=$2 72 right=$3 73 if cmp -s "$left" "$right"; then 74 { 75 printf 'files unexpectedly match:\n' 76 printf ' left: %s\n' "$left" 77 printf ' right: %s\n' "$right" 78 } > "$work/$name.diag" 79 not_ok "$name" "$work/$name.diag" 80 else 81 ok "$name" 82 fi 83 } 84 85 have_cmd() { 86 command -v "$1" >/dev/null 2>&1 87 } 88 89 make_fixtures() { 90 : > "$work/in/empty.dat" 91 printf x > "$work/in/one.bin" 92 cp "$work/in/one.bin" "$work/in/dup-one.bin" 93 printf 'portable package deflate regression payload\n' > "$work/in/payload.txt" 94 dd if=/dev/zero of="$work/in/chunk64.bin" bs=65536 count=1 >/dev/null 2>&1 95 cp "$work/in/chunk64.bin" "$work/in/chunk64-copy.bin" 96 dd if=/dev/zero of="$work/in/chunk64p1.bin" bs=65536 count=1 >/dev/null 2>&1 97 printf y >> "$work/in/chunk64p1.bin" 98 dd if=/dev/zero of="$work/in/chunk3.bin" bs=65536 count=3 >/dev/null 2>&1 99 printf tail >> "$work/in/chunk3.bin" 100 mkdir -p "$work/in/bin" 101 { 102 printf '#!/bin/sh\n' 103 printf 'printf "tool executed\\n"\n' 104 } > "$work/in/bin/tool.sh" 105 chmod +x "$work/in/bin/tool.sh" 106 } 107 108 keyid_from_keygen() { 109 sed -n 's/.*key id \([0-9a-fA-F][0-9a-fA-F]*\)).*/\1/p' "$1" 110 } 111 112 inspect_checks() { 113 label=$1 114 out=$2 115 contains "$label-inspect-magic" "$out" "kit-package 3" 116 contains "$label-inspect-name" "$out" "name = matrix-test" 117 contains "$label-inspect-version" "$out" "version = 1.0.0" 118 contains "$label-inspect-desc" "$out" "description = package test matrix" 119 contains "$label-inspect-hash" "$out" "hash = blake2b-256" 120 contains "$label-inspect-tree-format" "$out" "tree = kit-tree-v1" 121 contains "$label-inspect-blob-format" "$out" "blob = kit-blob-v1" 122 contains "$label-inspect-output" "$out" "[output]" 123 contains "$label-inspect-output-tree" "$out" "tree = $tree_id" 124 contains "$label-inspect-empty" "$out" "path = empty.dat" 125 contains "$label-inspect-boundary" "$out" "path = chunk64p1.bin" 126 contains "$label-inspect-exec" "$out" "path = bin/tool.sh" 127 not_contains "$label-inspect-no-v2-hash" "$out" "blake2b-merkle-v1" 128 not_contains "$label-inspect-no-sha256" "$out" "sha256" 129 } 130 131 repack_targz() { 132 src=$1 133 out=$2 134 files=$(cd "$src" && find . -type f -print | sed 's#^\./##' | sort) 135 (cd "$src" && tar -czf "$out" $files) 136 } 137 138 extract_targz() { 139 pkg=$1 140 dst=$2 141 mkdir -p "$dst" 142 gzip -dc "$pkg" | tar -xf - -C "$dst" 143 } 144 145 flip_byte() { 146 file=$1 147 off=$2 148 printf '\377' | dd of="$file" bs=1 seek="$off" count=1 conv=notrunc >/dev/null 2>&1 149 } 150 151 kpkg3_field_offset() { 152 file=$1 153 idx=$2 154 perl -e ' 155 use strict; 156 use warnings; 157 my ($file, $idx) = @ARGV; 158 open my $fh, "<:raw", $file or die "$file: $!"; 159 read $fh, my $magic, 7; 160 die "bad magic" unless $magic eq "kpkg3\0\0"; 161 seek $fh, 16 + 8 * $idx, 0 or die "seek: $!"; 162 read $fh, my $b, 8; 163 die "short read" unless length($b) == 8; 164 print unpack("Q<", $b); 165 ' "$file" "$idx" 166 } 167 168 extract_kpkg3_descriptor() { 169 pkg=$1 170 out=$2 171 descriptor_off=$(kpkg3_field_offset "$pkg" 4) 172 descriptor_size=$(kpkg3_field_offset "$pkg" 5) 173 dd if="$pkg" of="$out" bs=1 skip="$descriptor_off" count="$descriptor_size" >/dev/null 2>&1 174 } 175 176 extract_kpkg3_manifest() { 177 pkg=$1 178 out=$2 179 manifest_off=$(kpkg3_field_offset "$pkg" 0) 180 manifest_size=$(kpkg3_field_offset "$pkg" 1) 181 dd if="$pkg" of="$out" bs=1 skip="$manifest_off" count="$manifest_size" >/dev/null 2>&1 182 } 183 184 descriptor_value() { 185 file=$1 186 key=$2 187 sed -n "s/^$key = //p" "$file" | sed -n '1p' 188 } 189 190 check_kpkg3_index() { 191 label=$1 192 pkg=$2 193 descriptor=$3 194 expected_compression=$4 195 196 index_off=$(descriptor_value "$descriptor" "index-offset") 197 index_size=$(descriptor_value "$descriptor" "index-size") 198 content_size=$(descriptor_value "$descriptor" "content-size") 199 empty_blob=$(tree_blob_for_path "$tree_file" "empty.dat") 200 one_blob=$(tree_blob_for_path "$tree_file" "one.bin") 201 dup_one_blob=$(tree_blob_for_path "$tree_file" "dup-one.bin") 202 chunk64_blob=$(tree_blob_for_path "$tree_file" "chunk64.bin") 203 chunk64_copy_blob=$(tree_blob_for_path "$tree_file" "chunk64-copy.bin") 204 chunk64p1_blob=$(tree_blob_for_path "$tree_file" "chunk64p1.bin") 205 chunk3_blob=$(tree_blob_for_path "$tree_file" "chunk3.bin") 206 if perl -e ' 207 use strict; 208 use warnings; 209 my ($pkg, $index_off, $index_size, $content_size, $expected_comp, 210 $empty, $one, $dup_one, $chunk64, $chunk64_copy, $chunk64p1, 211 $chunk3) = @ARGV; 212 die "duplicate one.bin blob mismatch" unless $one eq $dup_one; 213 die "duplicate chunk64 blob mismatch" unless $chunk64 eq $chunk64_copy; 214 die "bad index size" unless $index_size % 168 == 0; 215 open my $fh, "<:raw", $pkg or die "$pkg: $!"; 216 seek $fh, $index_off, 0 or die "seek: $!"; 217 read $fh, my $index, $index_size; 218 die "short index" unless length($index) == $index_size; 219 my %count; 220 my ($prev_blob, $prev_chunk) = ("", -1); 221 for (my $off = 0; $off < $index_size; $off += 168) { 222 my $rec = substr($index, $off, 168); 223 my $blob = unpack("H64", substr($rec, 0, 32)); 224 my $chunk = unpack("Q<", substr($rec, 32, 8)); 225 my $content_off = unpack("Q<", substr($rec, 40, 8)); 226 my $stored_size = unpack("Q<", substr($rec, 48, 8)); 227 my $raw_size = unpack("Q<", substr($rec, 56, 8)); 228 my $compression = unpack("V", substr($rec, 64, 4)); 229 my $reserved = unpack("V", substr($rec, 68, 4)); 230 die "reserved field is nonzero" if $reserved != 0; 231 die "wrong compression" if $compression != $expected_comp; 232 die "raw chunk size out of range" if $raw_size == 0 || $raw_size > 65536; 233 die "content range out of bounds" 234 if $content_off > $content_size || $stored_size > $content_size - $content_off; 235 if ($prev_blob ne "") { 236 my $cmp = $prev_blob cmp $blob; 237 die "index not sorted" if $cmp > 0; 238 die "chunk index not increasing" if $cmp == 0 && $chunk <= $prev_chunk; 239 die "new blob does not start at chunk 0" if $cmp < 0 && $chunk != 0; 240 } elsif ($chunk != 0) { 241 die "first blob does not start at chunk 0"; 242 } 243 $count{$blob}++; 244 ($prev_blob, $prev_chunk) = ($blob, $chunk); 245 } 246 die "unexpected record count" unless $index_size / 168 == 10; 247 die "empty blob should have no records" if exists $count{$empty}; 248 die "one-byte duplicate blob count" unless ($count{$one} // 0) == 1; 249 die "chunk64 duplicate blob count" unless ($count{$chunk64} // 0) == 1; 250 die "chunk64p1 blob count" unless ($count{$chunk64p1} // 0) == 2; 251 die "chunk3 blob count" unless ($count{$chunk3} // 0) == 4; 252 ' "$pkg" "$index_off" "$index_size" "$content_size" "$expected_compression" \ 253 "$empty_blob" "$one_blob" "$dup_one_blob" "$chunk64_blob" \ 254 "$chunk64_copy_blob" "$chunk64p1_blob" "$chunk3_blob" \ 255 > "$work/$label.out" 2> "$work/$label.err"; then 256 ok "$label" 257 else 258 not_ok "$label" "$work/$label.err" 259 fi 260 } 261 262 maybe_corrupt_native_region() { 263 label=$1 264 pkg=$2 265 descriptor=$3 266 key=$4 267 off=$(descriptor_value "$descriptor" "$key") 268 case "$off" in 269 ''|*[!0-9]*|0) 270 skip_test "$label" 271 ;; 272 *) 273 cp "$pkg" "$work/pkg/bad-$label.kpkg" 274 flip_byte "$work/pkg/bad-$label.kpkg" "$off" 275 run_fail "$label" "$KIT" pkg verify -p "$work/key.pub" \ 276 "$work/pkg/bad-$label.kpkg" 277 ;; 278 esac 279 } 280 281 run_matrix_for_package() { 282 label=$1 283 pkg=$2 284 format=$3 285 286 run_ok "$label-inspect" "$KIT" pkg inspect "$pkg" 287 inspect_checks "$label" "$work/$label-inspect.out" 288 289 run_ok "$label-verify-pubkey" "$KIT" pkg verify -p "$work/key.pub" "$pkg" 290 contains "$label-verify-output-name" "$work/$label-verify-pubkey.out" "ok: matrix-test 1.0.0" 291 292 outdir="$work/unpack/$label" 293 mkdir -p "$outdir" 294 run_ok "$label-unpack-pubkey" "$KIT" pkg unpack --verify -p "$work/key.pub" "$pkg" -C "$outdir" 295 contains "$label-unpack-verify-output-name" "$work/$label-unpack-pubkey.out" "ok: matrix-test 1.0.0" 296 same_artifacts "$label-unpack-content" "$outdir" 297 is_executable "$label-unpack-exec-mode" "$outdir/bin/tool.sh" 298 299 run_ok "$label-verify-format-override" "$KIT" pkg verify -p "$work/key.pub" --format "$format" "$pkg" 300 } 301 302 make_fixtures 303 304 run_ok "pkg-keygen" "$KIT" pkg keygen -o "$work/key" 305 keyid=$(keyid_from_keygen "$work/pkg-keygen.out") 306 if [ -n "$keyid" ]; then 307 ok "pkg-keygen-keyid" 308 else 309 echo "could not parse key id from keygen output" > "$work/pkg-keygen-keyid.diag" 310 not_ok "pkg-keygen-keyid" "$work/pkg-keygen-keyid.diag" 311 fi 312 313 printf 'detached verification payload\n' > "$work/detached.txt" 314 run_ok "pkg-detached-sign" "$KIT" pkg sign -s "$work/key.key" \ 315 --comment "authenticated detached comment" "$work/detached.txt" 316 run_ok "pkg-detached-verify-explicit-default-sig" "$KIT" pkg verify-signature \ 317 -p "$work/key.pub" "$work/detached.txt" 318 contains "pkg-detached-trusted-comment" \ 319 "$work/pkg-detached-verify-explicit-default-sig.out" \ 320 "authenticated detached comment" 321 cp "$work/detached.txt" "$work/detached-changed.txt" 322 printf tamper >> "$work/detached-changed.txt" 323 run_fail "pkg-detached-changed-file-fails" "$KIT" pkg verify-signature \ 324 -p "$work/key.pub" -x "$work/detached.txt.minisig" \ 325 "$work/detached-changed.txt" 326 run_ok "pkg-detached-wrong-keygen" "$KIT" pkg keygen -o "$work/detached-wrong" 327 run_fail "pkg-detached-wrong-key-fails" "$KIT" pkg verify-signature \ 328 -p "$work/detached-wrong.pub" "$work/detached.txt" 329 printf 'not a signature\n' > "$work/malformed.minisig" 330 run_fail "pkg-detached-malformed-fails" "$KIT" pkg verify-signature \ 331 -p "$work/key.pub" -x "$work/malformed.minisig" "$work/detached.txt" 332 333 if have_cmd minisign; then 334 run_ok "pkg-detached-kit-to-stock" minisign -Vm "$work/detached.txt" \ 335 -p "$work/key.pub" -x "$work/detached.txt.minisig" 336 run_ok "pkg-detached-stock-sign" minisign -S -W -m "$work/detached.txt" \ 337 -s "$work/key.key" -x "$work/stock.minisig" \ 338 -t "stock authenticated comment" 339 run_ok "pkg-detached-stock-to-kit" "$KIT" pkg verify-signature \ 340 -p "$work/key.pub" -x "$work/stock.minisig" "$work/detached.txt" 341 contains "pkg-detached-stock-comment" \ 342 "$work/pkg-detached-stock-to-kit.out" "stock authenticated comment" 343 else 344 skip_test "pkg-detached-minisign-interop" "minisign not installed" 345 fi 346 347 run_ok "pkg-cas-add-tree" "$KIT" cas add-tree --cas "$work/cas" --root "$work/in" 348 tree_id=$(first_hex_id "$work/pkg-cas-add-tree.out") 349 if [ -n "$tree_id" ]; then 350 ok "pkg-cas-tree-id" 351 else 352 echo "could not parse tree id from cas add-tree output" > "$work/pkg-cas-tree-id.diag" 353 not_ok "pkg-cas-tree-id" "$work/pkg-cas-tree-id.diag" 354 fi 355 tree_file=$(cas_object_path "$work/cas" tree "$tree_id") 356 assert_file_exists "pkg-cas-tree-object" "$tree_file" 357 contains "pkg-cas-tree-magic" "$tree_file" "kit-tree 1" 358 contains "pkg-cas-tree-exec-mode" "$tree_file" "mode = x" 359 contains "pkg-cas-tree-file-mode" "$tree_file" "mode = -" 360 361 run_ok "pkg-create-targz-deflate" "$KIT" pkg create \ 362 --name matrix-test --version 1.0.0 --desc "package test matrix" \ 363 --format tar.gz --cas "$work/cas" --tree "$tree_id" \ 364 -s "$work/key.key" -o "$work/pkg/matrix.tar.gz" 365 366 run_ok "pkg-create-kpkg-none" "$KIT" pkg create \ 367 --name matrix-test --version 1.0.0 --desc "package test matrix" \ 368 --format kpkg --compression none --cas "$work/cas" --tree "$tree_id" \ 369 -s "$work/key.key" -o "$work/pkg/matrix-none.kpkg" 370 371 run_ok "pkg-create-kpkg-lz4" "$KIT" pkg create \ 372 --name matrix-test --version 1.0.0 --desc "package test matrix" \ 373 --format kpkg --compression lz4-block-v1 --cas "$work/cas" --tree "$tree_id" \ 374 -s "$work/key.key" -o "$work/pkg/matrix-lz4.kpkg" 375 376 run_ok "pkg-create-root-targz" "$KIT" pkg create \ 377 --name order-test --version 1.0.0 --desc "order independence" \ 378 --format tar.gz --root "$work/in" -s "$work/key.key" \ 379 -o "$work/pkg/order-root.tar.gz" 380 run_ok "pkg-create-cas-targz" "$KIT" pkg create \ 381 --name order-test --version 1.0.0 --desc "order independence" \ 382 --format tar.gz --cas "$work/cas" --tree "$tree_id" \ 383 -s "$work/key.key" -o "$work/pkg/order-cas.tar.gz" 384 run_ok "pkg-inspect-order-targz-root" "$KIT" pkg inspect "$work/pkg/order-root.tar.gz" 385 run_ok "pkg-inspect-order-targz-cas" "$KIT" pkg inspect "$work/pkg/order-cas.tar.gz" 386 same_file "pkg-root-and-cas-manifest-match" \ 387 "$work/pkg-inspect-order-targz-root.out" \ 388 "$work/pkg-inspect-order-targz-cas.out" 389 390 run_ok "pkg-create-version-alt" "$KIT" pkg create \ 391 --name matrix-test --version 1.0.1 --desc "package test matrix" \ 392 --format tar.gz --cas "$work/cas" --tree "$tree_id" \ 393 -s "$work/key.key" -o "$work/pkg/matrix-alt-version.tar.gz" 394 run_ok "pkg-inspect-version-alt" "$KIT" pkg inspect "$work/pkg/matrix-alt-version.tar.gz" 395 contains "pkg-version-alt-tree-same" "$work/pkg-inspect-version-alt.out" "tree = $tree_id" 396 contains "pkg-version-alt-version" "$work/pkg-inspect-version-alt.out" "version = 1.0.1" 397 398 run_matrix_for_package "targz" "$work/pkg/matrix.tar.gz" "tar.gz" 399 run_matrix_for_package "kpkg-none" "$work/pkg/matrix-none.kpkg" "kpkg" 400 run_matrix_for_package "kpkg-lz4" "$work/pkg/matrix-lz4.kpkg" "kpkg" 401 402 if have_cmd perl; then 403 extract_kpkg3_descriptor "$work/pkg/matrix-none.kpkg" "$work/native-none.descriptor" 404 contains "native-descriptor-magic" "$work/native-none.descriptor" "kit-encoding 3" 405 contains "native-descriptor-tree-region" "$work/native-none.descriptor" "tree-offset = " 406 contains "native-descriptor-index-bytes" "$work/native-none.descriptor" "index-bytes = 1680" 407 check_kpkg3_index "native-none-index-shape" \ 408 "$work/pkg/matrix-none.kpkg" "$work/native-none.descriptor" 0 409 extract_kpkg3_descriptor "$work/pkg/matrix-lz4.kpkg" "$work/native-lz4.descriptor" 410 check_kpkg3_index "native-lz4-index-shape" \ 411 "$work/pkg/matrix-lz4.kpkg" "$work/native-lz4.descriptor" 1 412 extract_kpkg3_manifest "$work/pkg/matrix-none.kpkg" "$work/native-none.manifest" 413 contains "native-manifest-v3" "$work/native-none.manifest" "kit-package 3" 414 else 415 skip_test "native-descriptor-inspection" 416 fi 417 418 run_ok "pkg-create-kpkg-thin" "$KIT" pkg create \ 419 --name matrix-test --version 1.0.0 --desc "package test matrix" \ 420 --format kpkg --native-shape thin --external "$work/ext-thin" \ 421 --compression none --cas "$work/cas" --tree "$tree_id" \ 422 -s "$work/key.key" -o "$work/pkg/matrix-thin.kpkg" 423 run_ok "native-thin-inspect-encoding" "$KIT" pkg inspect --encoding \ 424 "$work/pkg/matrix-thin.kpkg" 425 contains "native-thin-tree-external" "$work/native-thin-inspect-encoding.out" \ 426 "tree-size = 0" 427 contains "native-thin-index-external" "$work/native-thin-inspect-encoding.out" \ 428 "index-size = 0" 429 contains "native-thin-content-external" "$work/native-thin-inspect-encoding.out" \ 430 "content-size = 0" 431 contains "native-thin-index-url" "$work/native-thin-inspect-encoding.out" \ 432 "index-url = index/" 433 contains "native-thin-tree-url" "$work/native-thin-inspect-encoding.out" \ 434 "url = tree/" 435 contains "native-thin-chunk-template" "$work/native-thin-inspect-encoding.out" \ 436 "template = chunk/{blob-prefix}/{blob}/{chunk}" 437 run_fail "native-thin-verify-without-external-fails" "$KIT" pkg verify \ 438 -p "$work/key.pub" "$work/pkg/matrix-thin.kpkg" 439 run_ok "native-thin-verify-external" "$KIT" pkg verify \ 440 -p "$work/key.pub" --external "$work/ext-thin" \ 441 "$work/pkg/matrix-thin.kpkg" 442 mkdir -p "$work/unpack/kpkg-thin" 443 run_ok "native-thin-unpack-external" "$KIT" pkg unpack --verify \ 444 -p "$work/key.pub" --external "$work/ext-thin" \ 445 "$work/pkg/matrix-thin.kpkg" -C "$work/unpack/kpkg-thin" 446 same_artifacts "native-thin-unpack-content" "$work/unpack/kpkg-thin" 447 is_executable "native-thin-unpack-exec-mode" \ 448 "$work/unpack/kpkg-thin/bin/tool.sh" 449 450 run_ok "pkg-create-kpkg-metadata" "$KIT" pkg create \ 451 --name matrix-test --version 1.0.0 --desc "package test matrix" \ 452 --format kpkg --native-shape metadata --external "$work/ext-metadata" \ 453 --compression none --cas "$work/cas" --tree "$tree_id" \ 454 -s "$work/key.key" -o "$work/pkg/matrix-metadata.kpkg" 455 run_fail "native-metadata-verify-without-external-fails" "$KIT" pkg verify \ 456 -p "$work/key.pub" "$work/pkg/matrix-metadata.kpkg" 457 run_ok "native-metadata-verify-external" "$KIT" pkg verify \ 458 -p "$work/key.pub" --external "$work/ext-metadata" \ 459 "$work/pkg/matrix-metadata.kpkg" 460 461 payload_blob_for_external=$(tree_blob_for_path "$tree_file" "payload.txt") 462 payload_blob_prefix=$(id_prefix "$payload_blob_for_external") 463 cp -R "$work/ext-thin" "$work/ext-thin-bad-chunk" 464 printf tamper >> "$work/ext-thin-bad-chunk/chunk/$payload_blob_prefix/$payload_blob_for_external/0" 465 run_fail "native-external-mutated-chunk-fails" "$KIT" pkg verify \ 466 -p "$work/key.pub" --external "$work/ext-thin-bad-chunk" \ 467 "$work/pkg/matrix-thin.kpkg" 468 469 cp -R "$work/ext-thin" "$work/ext-thin-bad-tree" 470 printf tamper >> "$(cas_object_path "$work/ext-thin-bad-tree" tree "$tree_id")" 471 run_fail "native-external-mutated-tree-fails" "$KIT" pkg verify \ 472 -p "$work/key.pub" --external "$work/ext-thin-bad-tree" \ 473 "$work/pkg/matrix-thin.kpkg" 474 475 if have_cmd perl; then 476 extract_kpkg3_descriptor "$work/pkg/matrix-thin.kpkg" "$work/native-thin.descriptor" 477 thin_index_rel=$(descriptor_value "$work/native-thin.descriptor" "index-url") 478 cp -R "$work/ext-thin" "$work/ext-thin-bad-index" 479 printf tamper >> "$work/ext-thin-bad-index/$thin_index_rel" 480 run_fail "native-external-mutated-index-fails" "$KIT" pkg verify \ 481 -p "$work/key.pub" --external "$work/ext-thin-bad-index" \ 482 "$work/pkg/matrix-thin.kpkg" 483 else 484 skip_test "native-external-mutated-index-fails" 485 fi 486 487 run_ok "host-gzip-accepts-kit-output" gzip -t "$work/pkg/matrix.tar.gz" 488 if gunzip -c "$work/pkg/matrix.tar.gz" > "$work/pkg/matrix.tar" 2> "$work/gunzip.err" && 489 gzip -c "$work/pkg/matrix.tar" > "$work/pkg/host.tar.gz" 2> "$work/regzip.err"; then 490 run_ok "pkg-inspect-host-gzip" "$KIT" pkg inspect "$work/pkg/host.tar.gz" 491 run_ok "pkg-verify-host-gzip" "$KIT" pkg verify -p "$work/key.pub" "$work/pkg/host.tar.gz" 492 else 493 not_ok "pkg-inspect-host-gzip" "$work/gunzip.err" 494 not_ok "pkg-verify-host-gzip" "$work/regzip.err" 495 fi 496 497 run_ok "pkg-create-infer-targz" "$KIT" pkg create \ 498 --name matrix-test --version 1.0.0 --root "$work/in" -s "$work/key.key" \ 499 -o "$work/pkg/infer.tar.gz" 500 run_ok "pkg-create-infer-kpkg" "$KIT" pkg create \ 501 --name matrix-test --version 1.0.0 --root "$work/in" -s "$work/key.key" \ 502 -o "$work/pkg/infer.kpkg" 503 run_fail "pkg-create-unknown-extension-needs-format" "$KIT" pkg create \ 504 --name matrix-test --version 1.0.0 -s "$work/key.key" \ 505 --root "$work/in" -o "$work/pkg/unknown.pkg" 506 run_ok "pkg-create-override-targz-extension" "$KIT" pkg create \ 507 --name matrix-test --version 1.0.0 --format tar.gz -s "$work/key.key" \ 508 --root "$work/in" -o "$work/pkg/override.pkg" 509 run_ok "pkg-verify-override-targz-extension" "$KIT" pkg verify -p "$work/key.pub" \ 510 --format tar.gz "$work/pkg/override.pkg" 511 run_fail "pkg-verify-wrong-format-native" "$KIT" pkg verify -p "$work/key.pub" \ 512 --format kpkg "$work/pkg/matrix.tar.gz" 513 run_fail "pkg-verify-wrong-format-portable" "$KIT" pkg verify -p "$work/key.pub" \ 514 --format tar.gz "$work/pkg/matrix-none.kpkg" 515 516 run_fail "pkg-verify-untrusted-no-key" "$KIT" pkg verify "$work/pkg/matrix.tar.gz" 517 run_ok "pkg-trust-path" "$KIT" pkg trust path 518 contains "pkg-trust-path-output" "$work/pkg-trust-path.out" "$KIT_TRUSTED_KEYS" 519 run_ok "pkg-trust-list-empty" "$KIT" pkg trust list 520 contains "pkg-trust-list-empty-message" "$work/pkg-trust-list-empty.out" "(no trusted keys" 521 run_ok "pkg-trust-add" "$KIT" pkg trust add "$work/key.pub" matrix-label 522 run_ok "pkg-trust-list-added" "$KIT" pkg trust list 523 contains "pkg-trust-list-added-key" "$work/pkg-trust-list-added.out" "$keyid" 524 contains "pkg-trust-list-added-label" "$work/pkg-trust-list-added.out" "matrix-label" 525 run_ok "pkg-verify-trusted-store" "$KIT" pkg verify "$work/pkg/matrix.tar.gz" 526 run_ok "pkg-detached-verify-trusted-store" "$KIT" pkg verify-signature \ 527 "$work/detached.txt" 528 run_ok "pkg-trust-remove" "$KIT" pkg trust remove "$keyid" 529 run_ok "pkg-trust-list-removed" "$KIT" pkg trust list 530 not_contains "pkg-trust-list-removed-key" "$work/pkg-trust-list-removed.out" "$keyid" 531 run_fail "pkg-verify-after-trust-remove" "$KIT" pkg verify "$work/pkg/matrix.tar.gz" 532 533 mkdir -p "$work/tofu-home" 534 run_ok "pkg-verify-tofu-pins" env HOME="$work/tofu-home" KIT_TRUSTED_KEYS="$work/tofu.keys" \ 535 "$KIT" pkg verify --tofu "$work/pkg/matrix.tar.gz" 536 contains "pkg-tofu-file-key" "$work/tofu.keys" "$keyid" 537 run_ok "pkg-verify-tofu-store" env HOME="$work/tofu-home" KIT_TRUSTED_KEYS="$work/tofu.keys" \ 538 "$KIT" pkg verify "$work/pkg/matrix.tar.gz" 539 540 run_ok "pkg-keygen-wrong" "$KIT" pkg keygen -o "$work/wrong" 541 run_fail "pkg-verify-wrong-pubkey" "$KIT" pkg verify -p "$work/wrong.pub" "$work/pkg/matrix.tar.gz" 542 543 if have_cmd tar; then 544 extract_targz "$work/pkg/matrix.tar.gz" "$work/tar-ok" 545 tar_tree_file=$(cas_object_path "$work/tar-ok/kit/cas" tree "$tree_id") 546 for f in kit/package.manifest kit/package.manifest.minisig kit/package.pub; do 547 safe_f=$(printf '%s\n' "$f" | sed 's#[^A-Za-z0-9_.-]#-#g') 548 if [ -f "$work/tar-ok/$f" ]; then 549 ok "portable-member-$f" 550 else 551 echo "missing tar member: $f" > "$work/portable-member-$safe_f.diag" 552 not_ok "portable-member-$f" "$work/portable-member-$safe_f.diag" 553 fi 554 done 555 assert_file_exists "portable-member-tree-object" "$tar_tree_file" 556 same_file "portable-tree-matches-cas" "$tree_file" "$tar_tree_file" 557 for f in $artifacts; do 558 blob=$(tree_blob_for_path "$tar_tree_file" "$f") 559 blob_file=$(cas_object_path "$work/tar-ok/kit/cas" blob "$blob") 560 safe_f=$(printf '%s\n' "$f" | sed 's#[^A-Za-z0-9_.-]#-#g') 561 assert_file_exists "portable-member-blob-$safe_f" "$blob_file" 562 done 563 if [ -f "$work/tar-ok/payload.txt" ] || [ -f "$work/tar-ok/bin/tool.sh" ]; then 564 echo "portable archive stored output files outside kit/cas" > "$work/portable-no-root-files.diag" 565 not_ok "portable-no-root-files" "$work/portable-no-root-files.diag" 566 else 567 ok "portable-no-root-files" 568 fi 569 570 extract_targz "$work/pkg/matrix-alt-version.tar.gz" "$work/tar-alt-version" 571 contains "portable-alt-manifest-tree-same" \ 572 "$work/tar-alt-version/kit/package.manifest" "tree = $tree_id" 573 not_same_file "portable-metadata-changes-manifest" \ 574 "$work/tar-ok/kit/package.manifest" \ 575 "$work/tar-alt-version/kit/package.manifest" 576 same_file "portable-metadata-keeps-tree-object" \ 577 "$tar_tree_file" \ 578 "$(cas_object_path "$work/tar-alt-version/kit/cas" tree "$tree_id")" 579 580 cp -R "$work/tar-ok" "$work/tar-missing-manifest" 581 rm -f "$work/tar-missing-manifest/kit/package.manifest" 582 repack_targz "$work/tar-missing-manifest" "$work/pkg/bad-missing-manifest.tar.gz" 583 run_fail "portable-missing-manifest-fails" "$KIT" pkg verify -p "$work/key.pub" \ 584 "$work/pkg/bad-missing-manifest.tar.gz" 585 586 cp -R "$work/tar-ok" "$work/tar-missing-signature" 587 rm -f "$work/tar-missing-signature/kit/package.manifest.minisig" 588 repack_targz "$work/tar-missing-signature" "$work/pkg/bad-missing-signature.tar.gz" 589 run_fail "portable-missing-signature-fails" "$KIT" pkg verify -p "$work/key.pub" \ 590 "$work/pkg/bad-missing-signature.tar.gz" 591 592 cp -R "$work/tar-ok" "$work/tar-missing-tree" 593 rm -f "$(cas_object_path "$work/tar-missing-tree/kit/cas" tree "$tree_id")" 594 repack_targz "$work/tar-missing-tree" "$work/pkg/bad-missing-tree.tar.gz" 595 run_fail "portable-missing-tree-fails" "$KIT" pkg verify -p "$work/key.pub" \ 596 "$work/pkg/bad-missing-tree.tar.gz" 597 598 payload_blob=$(tree_blob_for_path "$tar_tree_file" "payload.txt") 599 cp -R "$work/tar-ok" "$work/tar-missing-blob" 600 rm -f "$(cas_object_path "$work/tar-missing-blob/kit/cas" blob "$payload_blob")" 601 repack_targz "$work/tar-missing-blob" "$work/pkg/bad-missing-blob.tar.gz" 602 run_fail "portable-missing-blob-fails" "$KIT" pkg verify -p "$work/key.pub" \ 603 "$work/pkg/bad-missing-blob.tar.gz" 604 605 cp -R "$work/tar-ok" "$work/tar-mutated-blob" 606 printf tamper >> "$(cas_object_path "$work/tar-mutated-blob/kit/cas" blob "$payload_blob")" 607 repack_targz "$work/tar-mutated-blob" "$work/pkg/bad-mutated-blob.tar.gz" 608 run_fail "portable-mutated-blob-fails" "$KIT" pkg verify -p "$work/key.pub" \ 609 "$work/pkg/bad-mutated-blob.tar.gz" 610 611 cp -R "$work/tar-ok" "$work/tar-mutated-tree" 612 printf '\n# tamper\n' >> "$(cas_object_path "$work/tar-mutated-tree/kit/cas" tree "$tree_id")" 613 repack_targz "$work/tar-mutated-tree" "$work/pkg/bad-mutated-tree.tar.gz" 614 run_fail "portable-mutated-tree-fails" "$KIT" pkg verify -p "$work/key.pub" \ 615 "$work/pkg/bad-mutated-tree.tar.gz" 616 617 cp -R "$work/tar-ok" "$work/tar-mutated-manifest" 618 printf '\n# tamper\n' >> "$work/tar-mutated-manifest/kit/package.manifest" 619 repack_targz "$work/tar-mutated-manifest" "$work/pkg/bad-mutated-manifest.tar.gz" 620 run_fail "portable-mutated-manifest-fails" "$KIT" pkg verify -p "$work/key.pub" \ 621 "$work/pkg/bad-mutated-manifest.tar.gz" 622 else 623 skip_test "portable-tar-member-and-repack-tests" 624 fi 625 626 cp "$work/pkg/matrix.tar.gz" "$work/pkg/bad-gzip-byte.tar.gz" 627 flip_byte "$work/pkg/bad-gzip-byte.tar.gz" 0 628 run_fail "portable-corrupt-gzip-fails" "$KIT" pkg verify -p "$work/key.pub" \ 629 "$work/pkg/bad-gzip-byte.tar.gz" 630 631 cp "$work/pkg/matrix-none.kpkg" "$work/pkg/bad-native-magic.kpkg" 632 flip_byte "$work/pkg/bad-native-magic.kpkg" 0 633 run_fail "native-bad-magic-fails" "$KIT" pkg verify -p "$work/key.pub" \ 634 "$work/pkg/bad-native-magic.kpkg" 635 636 dd if="$work/pkg/matrix-none.kpkg" of="$work/pkg/bad-native-truncated.kpkg" \ 637 bs=1 count=100 >/dev/null 2>&1 638 run_fail "native-truncated-fails" "$KIT" pkg verify -p "$work/key.pub" \ 639 "$work/pkg/bad-native-truncated.kpkg" 640 641 cp "$work/pkg/matrix-none.kpkg" "$work/pkg/bad-native-manifest.kpkg" 642 if have_cmd perl; then 643 manifest_off=$(kpkg3_field_offset "$work/pkg/matrix-none.kpkg" 0) 644 flip_byte "$work/pkg/bad-native-manifest.kpkg" "$manifest_off" 645 run_fail "native-mutated-manifest-fails" "$KIT" pkg verify -p "$work/key.pub" \ 646 "$work/pkg/bad-native-manifest.kpkg" 647 else 648 skip_test "native-mutated-manifest-fails" 649 fi 650 651 if have_cmd perl; then 652 descriptor_off=$(kpkg3_field_offset "$work/pkg/matrix-none.kpkg" 4) 653 extract_kpkg3_descriptor "$work/pkg/matrix-none.kpkg" "$work/native-corrupt.descriptor" 654 655 cp "$work/pkg/matrix-none.kpkg" "$work/pkg/bad-native-descriptor.kpkg" 656 flip_byte "$work/pkg/bad-native-descriptor.kpkg" "$descriptor_off" 657 run_fail "native-mutated-descriptor-fails" "$KIT" pkg verify -p "$work/key.pub" \ 658 "$work/pkg/bad-native-descriptor.kpkg" 659 660 maybe_corrupt_native_region "native-mutated-tree-region-fails" \ 661 "$work/pkg/matrix-none.kpkg" "$work/native-corrupt.descriptor" "tree-offset" 662 maybe_corrupt_native_region "native-mutated-index-fails" \ 663 "$work/pkg/matrix-none.kpkg" "$work/native-corrupt.descriptor" "index-offset" 664 maybe_corrupt_native_region "native-mutated-content-fails" \ 665 "$work/pkg/matrix-none.kpkg" "$work/native-corrupt.descriptor" "content-offset" 666 else 667 skip_test "native-region-offset-corruption-tests" 668 fi 669 670 run_fail "pkg-create-missing-required-fails" "$KIT" pkg create \ 671 --name missing-version -s "$work/key.key" --root "$work/in" -o "$work/pkg/missing.tar.gz" 672 run_fail "pkg-create-unknown-format-fails" "$KIT" pkg create \ 673 --name matrix-test --version 1.0.0 --format nope -s "$work/key.key" \ 674 --root "$work/in" -o "$work/pkg/badformat.tar.gz" 675 run_fail "pkg-create-unknown-compression-fails" "$KIT" pkg create \ 676 --name matrix-test --version 1.0.0 --format kpkg --compression nope \ 677 -s "$work/key.key" --root "$work/in" -o "$work/pkg/badcomp.kpkg" 678 mkdir -p "$work/dup/a" "$work/dup/b" 679 printf one > "$work/dup/a/same.dat" 680 printf two > "$work/dup/b/same.dat" 681 cat > "$work/dup.map" <<EOF 682 same.dat - $work/dup/a/same.dat 683 same.dat - $work/dup/b/same.dat 684 EOF 685 run_fail "pkg-cas-duplicate-tree-path-fails" "$KIT" cas add-tree \ 686 --cas "$work/cas" --map "$work/dup.map" 687 printf unsafe > "$work/in/bad\\path.dat" 688 cat > "$work/unsafe.map" <<EOF 689 bad\\path.dat - $work/in/bad\\path.dat 690 EOF 691 run_fail "pkg-cas-unsafe-tree-path-fails" "$KIT" cas add-tree \ 692 --cas "$work/cas" --map "$work/unsafe.map" 693 run_fail "pkg-verify-missing-file-fails" "$KIT" pkg verify -p "$work/key.pub" \ 694 "$work/pkg/does-not-exist.tar.gz" 695 printf not-a-package > "$work/not-a-package.kpkg" 696 run_fail "pkg-inspect-malformed-fails" "$KIT" pkg inspect "$work/not-a-package.kpkg" 697 run_fail "pkg-trust-add-missing-pubkey-fails" "$KIT" pkg trust add 698 run_fail "pkg-trust-remove-bad-keyid-fails" "$KIT" pkg trust remove xyz 699 700 kit_summary pkg 701 kit_exit