├── .circleci └── config.yml ├── .codecov.yml ├── .github └── dependabot.yml ├── .gitignore ├── .golangci.yml ├── .goreleaser.yml ├── .markdownlint.json ├── .vscode └── settings.json ├── CONTRIBUTING.md ├── LICENSE.md ├── README.md ├── cmd └── siftool │ ├── doc.go │ └── siftool.go ├── doc └── sif.png ├── go.mod ├── go.sum ├── internal └── app │ └── siftool │ ├── app.go │ ├── file.go │ ├── info.go │ ├── info_test.go │ ├── modif.go │ ├── modif_test.go │ └── testdata │ ├── TestApp_Dump │ ├── One.golden │ └── Two.golden │ ├── TestApp_Header │ ├── Empty.golden │ ├── EmptyID.golden │ ├── EmptyLaunchScript.golden │ ├── OneGroup.golden │ ├── OneGroupSignedLegacy.golden │ ├── OneGroupSignedLegacyAll.golden │ ├── OneGroupSignedLegacyGroup.golden │ ├── OneGroupSignedPGP.golden │ ├── OneObjectCryptMessage.golden │ ├── OneObjectGenericJSON.golden │ ├── OneObjectOCIBlob.golden │ ├── OneObjectOCIRootIndex.golden │ ├── OneObjectSBOM.golden │ ├── OneObjectTime.golden │ ├── TwoGroups.golden │ ├── TwoGroupsSignedLegacy.golden │ ├── TwoGroupsSignedLegacyAll.golden │ ├── TwoGroupsSignedLegacyGroup.golden │ └── TwoGroupsSignedPGP.golden │ ├── TestApp_Info │ ├── CryptMessage.golden │ ├── DataPartitionEXT3.golden │ ├── DataPartitionRaw.golden │ ├── DataPartitionSquashFS.golden │ ├── DataSignature.golden │ ├── GenericJSON.golden │ ├── OCIBlob.golden │ ├── OCIRootIndex.golden │ ├── SBOM.golden │ └── Time.golden │ └── TestApp_List │ ├── Empty.golden │ ├── EmptyID.golden │ ├── EmptyLaunchScript.golden │ ├── OneGroup.golden │ ├── OneGroupSignedLegacy.golden │ ├── OneGroupSignedLegacyAll.golden │ ├── OneGroupSignedLegacyGroup.golden │ ├── OneGroupSignedPGP.golden │ ├── OneObjectCryptMessage.golden │ ├── OneObjectGenericJSON.golden │ ├── OneObjectOCIBlob.golden │ ├── OneObjectOCIRootIndex.golden │ ├── OneObjectSBOM.golden │ ├── OneObjectTime.golden │ ├── TwoGroups.golden │ ├── TwoGroupsSignedLegacy.golden │ ├── TwoGroupsSignedLegacyAll.golden │ ├── TwoGroupsSignedLegacyGroup.golden │ └── TwoGroupsSignedPGP.golden ├── pkg ├── integrity │ ├── clearsign.go │ ├── clearsign_test.go │ ├── digest.go │ ├── digest_test.go │ ├── doc.go │ ├── dsse.go │ ├── dsse_test.go │ ├── main_test.go │ ├── metadata.go │ ├── metadata_test.go │ ├── result.go │ ├── select.go │ ├── sign.go │ ├── sign_test.go │ ├── testdata │ │ ├── TestDigest_MarshalJSON │ │ │ ├── SHA224.golden │ │ │ ├── SHA256.golden │ │ │ ├── SHA384.golden │ │ │ ├── SHA512.golden │ │ │ ├── SHA512_224.golden │ │ │ └── SHA512_256.golden │ │ ├── TestGetHeaderMetadata │ │ │ ├── SHA224.golden │ │ │ ├── SHA256.golden │ │ │ ├── SHA384.golden │ │ │ ├── SHA512.golden │ │ │ ├── SHA512_224.golden │ │ │ └── SHA512_256.golden │ │ ├── TestGetImageMetadata │ │ │ ├── Object1.golden │ │ │ ├── Object2.golden │ │ │ ├── SHA224.golden │ │ │ ├── SHA256.golden │ │ │ ├── SHA384.golden │ │ │ └── SHA512.golden │ │ ├── TestGetObjectMetadata │ │ │ ├── RelativeID.golden │ │ │ ├── SHA224.golden │ │ │ ├── SHA256.golden │ │ │ ├── SHA384.golden │ │ │ ├── SHA512.golden │ │ │ ├── SHA512_224.golden │ │ │ └── SHA512_256.golden │ │ ├── Test_dsseEncoder_signMessage │ │ │ ├── ED25519.golden │ │ │ ├── Multi.golden │ │ │ ├── RSA_SHA256.golden │ │ │ ├── RSA_SHA384.golden │ │ │ └── RSA_SHA512.golden │ │ └── sources │ │ │ ├── descr-rid0.bin │ │ │ ├── descr-rid1.bin │ │ │ └── header.bin │ ├── verify.go │ └── verify_test.go ├── sif │ ├── add.go │ ├── add_test.go │ ├── arch.go │ ├── arch_test.go │ ├── buffer.go │ ├── buffer_test.go │ ├── create.go │ ├── create_test.go │ ├── delete.go │ ├── delete_test.go │ ├── descriptor.go │ ├── descriptor_input.go │ ├── descriptor_input_test.go │ ├── descriptor_test.go │ ├── load.go │ ├── load_test.go │ ├── select.go │ ├── select_test.go │ ├── set.go │ ├── set_test.go │ ├── sif.go │ ├── sif_test.go │ └── testdata │ │ ├── TestAddObject │ │ ├── Deterministic.golden │ │ ├── Empty.golden │ │ ├── EmptyAligned.golden │ │ ├── EmptyNotAligned.golden │ │ ├── ErrInsufficientCapacity.golden │ │ ├── ErrPrimaryPartition.golden │ │ ├── NotEmpty.golden │ │ ├── NotEmptyAligned.golden │ │ ├── NotEmptyNotAligned.golden │ │ └── WithTime.golden │ │ ├── TestCreateContainer │ │ ├── Empty.golden │ │ ├── EmptyCloseOnUnload.golden │ │ ├── EmptyDescriptorLimitedCapacity.golden │ │ ├── EmptyLaunchScript.golden │ │ ├── EmptyWithID.golden │ │ ├── EmptyWithTime.golden │ │ ├── OneDescriptor.golden │ │ ├── TwoDescriptors.golden │ │ ├── TwoDescriptorsAligned.golden │ │ └── TwoDescriptorsNotAligned.golden │ │ ├── TestCreateContainerAtPath │ │ ├── Empty.golden │ │ ├── EmptyDescriptorLimitedCapacity.golden │ │ ├── OneDescriptor.golden │ │ ├── TwoDescriptors.golden │ │ ├── TwoDescriptorsAligned.golden │ │ └── TwoDescriptorsNotAligned.golden │ │ ├── TestDeleteObject │ │ ├── Compact.golden │ │ ├── Deterministic.golden │ │ ├── ErrObjectNotFound.golden │ │ ├── OneCompact.golden │ │ ├── OneZero.golden │ │ ├── OneZeroCompact.golden │ │ ├── PrimaryPartition.golden │ │ ├── TwoCompact.golden │ │ ├── TwoZero.golden │ │ ├── TwoZeroCompact.golden │ │ └── WithTime.golden │ │ ├── TestDeleteObjectAndAddObject │ │ ├── Compact.golden │ │ ├── NoCompact.golden │ │ ├── Zero.golden │ │ └── ZeroCompact.golden │ │ ├── TestDeleteObjects │ │ ├── DataType.golden │ │ ├── DataTypeCompact.golden │ │ ├── ErrObjectNotFound.golden │ │ ├── NilSelectFunc.golden │ │ └── PrimaryPartitionCompact.golden │ │ ├── TestDescriptor_GetIntegrityReader │ │ ├── CreatedAt.golden │ │ ├── DataType.golden │ │ ├── Extra.golden │ │ ├── GID.golden │ │ ├── GroupID.golden │ │ ├── ID.golden │ │ ├── LinkedID.golden │ │ ├── ModifiedAt.golden │ │ ├── Name.golden │ │ ├── Offset.golden │ │ ├── RelativeID.golden │ │ ├── Size.golden │ │ ├── SizeWithPadding.golden │ │ ├── UID.golden │ │ └── Used.golden │ │ ├── TestFileImage_SetOCIBlobDigest │ │ ├── Deterministic.golden │ │ ├── One.golden │ │ ├── Two.golden │ │ └── WithTime.golden │ │ ├── TestHeader_GetIntegrityReader │ │ ├── Arch.golden │ │ ├── CreatedAt.golden │ │ ├── DataOffset.golden │ │ ├── DataSize.golden │ │ ├── DescriptorsFree.golden │ │ ├── DescriptorsOffset.golden │ │ ├── DescriptorsSize.golden │ │ ├── DescriptorsTotal.golden │ │ ├── ID.golden │ │ ├── LaunchScript.golden │ │ ├── Magic.golden │ │ ├── ModifiedAt.golden │ │ └── Version.golden │ │ ├── TestNewDescriptorInput │ │ ├── DataOCIBlob.golden │ │ ├── DataOCIRootIndex.golden │ │ ├── Empty.golden │ │ ├── OptCryptoMessageMetadata.golden │ │ ├── OptGroupID.golden │ │ ├── OptLinkedGroupID.golden │ │ ├── OptLinkedID.golden │ │ ├── OptMetadata.golden │ │ ├── OptNoGroup.golden │ │ ├── OptObjectAlignment.golden │ │ ├── OptObjectName.golden │ │ ├── OptObjectTime.golden │ │ ├── OptPartitionMetadata.golden │ │ ├── OptSBOMMetadata.golden │ │ └── OptSignatureMetadata.golden │ │ ├── TestSetMetadata │ │ ├── Deterministic.golden │ │ ├── ErrObjectNotFound.golden │ │ ├── One.golden │ │ ├── Two.golden │ │ └── WithTime.golden │ │ └── TestSetPrimPart │ │ ├── Deterministic.golden │ │ ├── ErrObjectNotFound.golden │ │ ├── One.golden │ │ ├── Two.golden │ │ └── WithTime.golden ├── siftool │ ├── add.go │ ├── add_test.go │ ├── del.go │ ├── del_test.go │ ├── dump.go │ ├── dump_test.go │ ├── header.go │ ├── header_test.go │ ├── info.go │ ├── info_test.go │ ├── list.go │ ├── list_test.go │ ├── new.go │ ├── new_test.go │ ├── setprim.go │ ├── setprim_test.go │ ├── siftool.go │ ├── siftool_test.go │ └── testdata │ │ ├── TestAddCommands │ │ ├── Add │ │ │ ├── err.golden │ │ │ └── out.golden │ │ ├── Del │ │ │ ├── err.golden │ │ │ └── out.golden │ │ ├── Dump │ │ │ ├── err.golden │ │ │ └── out.golden │ │ ├── Header │ │ │ ├── err.golden │ │ │ └── out.golden │ │ ├── Info │ │ │ ├── err.golden │ │ │ └── out.golden │ │ ├── List │ │ │ ├── err.golden │ │ │ └── out.golden │ │ ├── New │ │ │ ├── err.golden │ │ │ └── out.golden │ │ ├── SetPrim │ │ │ ├── err.golden │ │ │ └── out.golden │ │ ├── SifTool │ │ │ ├── err.golden │ │ │ └── out.golden │ │ └── SifToolExperimental │ │ │ ├── err.golden │ │ │ └── out.golden │ │ ├── Test_command_getAdd │ │ ├── DataOCIBlob │ │ │ ├── err.golden │ │ │ └── out.golden │ │ ├── DataOCIRootIndex │ │ │ ├── err.golden │ │ │ └── out.golden │ │ ├── DataPartition │ │ │ ├── err.golden │ │ │ └── out.golden │ │ └── DataSignature │ │ │ ├── err.golden │ │ │ └── out.golden │ │ ├── Test_command_getDel │ │ └── OK │ │ │ ├── err.golden │ │ │ └── out.golden │ │ ├── Test_command_getDump │ │ ├── One │ │ │ ├── err.golden │ │ │ └── out.golden │ │ └── Two │ │ │ ├── err.golden │ │ │ └── out.golden │ │ ├── Test_command_getHeader │ │ ├── Empty │ │ │ ├── err.golden │ │ │ └── out.golden │ │ ├── OneGroup │ │ │ ├── err.golden │ │ │ └── out.golden │ │ ├── OneGroupSignedLegacy │ │ │ ├── err.golden │ │ │ └── out.golden │ │ ├── OneGroupSignedLegacyAll │ │ │ ├── err.golden │ │ │ └── out.golden │ │ ├── OneGroupSignedLegacyGroup │ │ │ ├── err.golden │ │ │ └── out.golden │ │ ├── OneGroupSignedPGP │ │ │ ├── err.golden │ │ │ └── out.golden │ │ ├── TwoGroups │ │ │ ├── err.golden │ │ │ └── out.golden │ │ ├── TwoGroupsSignedLegacy │ │ │ ├── err.golden │ │ │ └── out.golden │ │ ├── TwoGroupsSignedLegacyAll │ │ │ ├── err.golden │ │ │ └── out.golden │ │ ├── TwoGroupsSignedLegacyGroup │ │ │ ├── err.golden │ │ │ └── out.golden │ │ └── TwoGroupsSignedPGP │ │ │ ├── err.golden │ │ │ └── out.golden │ │ ├── Test_command_getInfo │ │ ├── One │ │ │ ├── err.golden │ │ │ └── out.golden │ │ ├── Three │ │ │ ├── err.golden │ │ │ └── out.golden │ │ └── Two │ │ │ ├── err.golden │ │ │ └── out.golden │ │ ├── Test_command_getList │ │ ├── Empty │ │ │ ├── err.golden │ │ │ └── out.golden │ │ ├── OneGroup │ │ │ ├── err.golden │ │ │ └── out.golden │ │ ├── OneGroupSignedLegacy │ │ │ ├── err.golden │ │ │ └── out.golden │ │ ├── OneGroupSignedLegacyAll │ │ │ ├── err.golden │ │ │ └── out.golden │ │ ├── OneGroupSignedLegacyGroup │ │ │ ├── err.golden │ │ │ └── out.golden │ │ ├── OneGroupSignedPGP │ │ │ ├── err.golden │ │ │ └── out.golden │ │ ├── TwoGroups │ │ │ ├── err.golden │ │ │ └── out.golden │ │ ├── TwoGroupsSignedLegacy │ │ │ ├── err.golden │ │ │ └── out.golden │ │ ├── TwoGroupsSignedLegacyAll │ │ │ ├── err.golden │ │ │ └── out.golden │ │ ├── TwoGroupsSignedLegacyGroup │ │ │ ├── err.golden │ │ │ └── out.golden │ │ └── TwoGroupsSignedPGP │ │ │ ├── err.golden │ │ │ └── out.golden │ │ ├── Test_command_getNew │ │ └── OK │ │ │ ├── err.golden │ │ │ └── out.golden │ │ ├── Test_command_getSetPrim │ │ └── OK │ │ │ ├── err.golden │ │ │ └── out.golden │ │ └── input │ │ └── input.bin └── user │ ├── mount.go │ ├── unmount.go │ └── unmount_test.go └── test ├── images ├── empty-id.sif ├── empty-launch-script.sif ├── empty.sif ├── gen_sifs.go ├── one-group-signed-dsse.sif ├── one-group-signed-legacy-all.sif ├── one-group-signed-legacy-group.sif ├── one-group-signed-legacy.sif ├── one-group-signed-pgp.sif ├── one-group.sif ├── one-object-crypt-message.sif ├── one-object-generic-json.sif ├── one-object-oci-blob.sif ├── one-object-oci-root-index.sif ├── one-object-sbom.sif ├── one-object-time.sif ├── two-groups-signed-dsse.sif ├── two-groups-signed-legacy-all.sif ├── two-groups-signed-legacy-group.sif ├── two-groups-signed-legacy.sif ├── two-groups-signed-pgp.sif └── two-groups.sif ├── input ├── index.json ├── oci-config.json ├── root.ext3 ├── root.squashfs └── sbom.cdx.json └── keys ├── ecdsa-private.pem ├── ecdsa-public.pem ├── ed25519-private.pem ├── ed25519-public.pem ├── gen_keys.go ├── private.asc ├── rsa-private.pem └── rsa-public.pem /.codecov.yml: -------------------------------------------------------------------------------- 1 | coverage: 2 | status: 3 | patch: off 4 | project: off 5 | 6 | github_checks: false 7 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: gomod 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | target-branch: main 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | -------------------------------------------------------------------------------- /.golangci.yml: -------------------------------------------------------------------------------- 1 | version: "2" 2 | 3 | linters: 4 | default: none 5 | enable: 6 | - asciicheck 7 | - bidichk 8 | - bodyclose 9 | - containedctx 10 | - contextcheck 11 | - copyloopvar 12 | - decorder 13 | - dogsled 14 | - dupl 15 | - dupword 16 | - err113 17 | - errcheck 18 | - errchkjson 19 | - errname 20 | - errorlint 21 | - exptostd 22 | - forcetypeassert 23 | - gochecknoinits 24 | - gocritic 25 | - godot 26 | - godox 27 | - gomodguard 28 | - goprintffuncname 29 | - gosec 30 | - govet 31 | - grouper 32 | - iface 33 | - ineffassign 34 | - interfacebloat 35 | - intrange 36 | - ireturn 37 | - lll 38 | - maintidx 39 | - mirror 40 | - misspell 41 | - nilnesserr 42 | - nilnil 43 | - nolintlint 44 | - nonamedreturns 45 | - prealloc 46 | - reassign 47 | - revive 48 | - staticcheck 49 | - thelper 50 | - unconvert 51 | - unparam 52 | - unused 53 | - usetesting 54 | - whitespace 55 | settings: 56 | misspell: 57 | locale: US 58 | exclusions: 59 | presets: 60 | - comments 61 | - common-false-positives 62 | - legacy 63 | - std-error-handling 64 | 65 | formatters: 66 | enable: 67 | - gofumpt 68 | - goimports 69 | -------------------------------------------------------------------------------- /.goreleaser.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | 3 | release: 4 | prerelease: auto 5 | 6 | changelog: 7 | use: github-native 8 | 9 | gomod: 10 | proxy: true 11 | env: 12 | - GOPROXY=https://proxy.golang.org,direct 13 | - GOSUMDB=sum.golang.org 14 | 15 | builds: 16 | - id: darwin-builds 17 | binary: siftool 18 | goos: 19 | - darwin 20 | goarch: 21 | - amd64 22 | - arm64 23 | main: &build-main ./cmd/siftool 24 | mod_timestamp: &build-timestamp '{{ .CommitTimestamp }}' 25 | env: &build-env 26 | - CGO_ENABLED=0 27 | flags: &build-flags '-trimpath' 28 | ldflags: &build-ldflags | 29 | -s 30 | -w 31 | -X main.version={{ .Version }} 32 | -X main.date={{ .CommitDate }} 33 | -X main.builtBy=goreleaser 34 | -X main.commit={{ .FullCommit }} 35 | 36 | - id: linux-builds 37 | binary: siftool 38 | goos: 39 | - linux 40 | goarch: 41 | - '386' 42 | - 'amd64' 43 | - 'arm' 44 | - 'arm64' 45 | - 'mips' 46 | - 'mips64' 47 | - 'mips64le' 48 | - 'mipsle' 49 | - 'ppc64' 50 | - 'ppc64le' 51 | - 'riscv64' 52 | - 's390x' 53 | goarm: 54 | - '6' 55 | - '7' 56 | main: *build-main 57 | mod_timestamp: *build-timestamp 58 | env: *build-env 59 | flags: *build-flags 60 | ldflags: *build-ldflags 61 | 62 | archives: 63 | - id: darwin-archives 64 | ids: 65 | - darwin-builds 66 | 67 | - id: linux-archives 68 | ids: 69 | - linux-builds 70 | 71 | sboms: 72 | - documents: 73 | - '{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}{{ with .Arm }}v{{ . }}{{ end }}{{ with .Mips }}_{{ . }}{{ end }}.bom.cdx.json' 74 | artifacts: binary 75 | args: ["$artifact", "--file", "$document", "--output", "cyclonedx-json"] 76 | -------------------------------------------------------------------------------- /.markdownlint.json: -------------------------------------------------------------------------------- 1 | { 2 | "default": true, 3 | "MD013": false 4 | } 5 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "go.lintTool":"golangci-lint", 3 | "go.lintFlags": [ 4 | "--fast" 5 | ] 6 | } -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # LICENSE 2 | 3 | Copyright (c) 2018-2023, Sylabs Inc. All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, 9 | this list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | 3. Neither the name of the copyright holder nor the names of its 16 | contributors may be used to endorse or promote products derived from this 17 | software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 23 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 | POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # The Singularity Image Format (SIF) 2 | 3 | [![PkgGoDev](https://pkg.go.dev/badge/github.com/sylabs/sif/v2?status.svg)](https://pkg.go.dev/github.com/sylabs/sif/v2) 4 | [![Build Status](https://circleci.com/gh/sylabs/sif.svg?style=shield)](https://circleci.com/gh/sylabs/workflows/sif) 5 | [![Code Coverage](https://codecov.io/gh/sylabs/sif/branch/main/graph/badge.svg)](https://app.codecov.io/gh/sylabs/sif) 6 | [![Go Report Card](https://goreportcard.com/badge/github.com/sylabs/sif)](https://goreportcard.com/report/github.com/sylabs/sif) 7 | [![Powered By GoReleaser](https://img.shields.io/badge/powered%20by-goreleaser-green.svg)](https://github.com/goreleaser) 8 | 9 | This module contains an open source implementation of the Singularity Image Format (SIF) that makes it easy to create complete and encapsulated container environments stored in a single file. 10 | 11 | ![SIF Image](doc/sif.png) 12 | 13 | Unless otherwise noted, the SIF source files are distributed under the BSD-style license found in the [LICENSE.md](LICENSE.md) file. 14 | 15 | ## Install Siftool 16 | 17 | Pre-built binaries are available with the [latest release](https://github.com/sylabs/sif/releases). 18 | 19 | ## Go Version Compatibility 20 | 21 | This module aims to maintain support for the two most recent stable versions of Go. This corresponds to the Go [Release Maintenance Policy](https://go.dev/wiki/Go-Release-Cycle#release-maintenance) and [Security Policy](https://go.dev/doc/security/policy), ensuring critical bug fixes and security patches are available for all supported language versions. 22 | 23 | ## Contributing 24 | 25 | SIF and [SingularityCE](https://github.com/sylabs/singularity) are the work of many contributors. We appreciate your help! 26 | 27 | To contribute, please read the contribution guidelines found in the [CONTRIBUTING.md](CONTRIBUTING.md) file. 28 | -------------------------------------------------------------------------------- /cmd/siftool/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018, Sylabs Inc. All rights reserved. 2 | // This software is licensed under a 3-clause BSD license. Please consult the 3 | // LICENSE file distributed with the sources of this project regarding your 4 | // rights to use or distribute this software. 5 | 6 | /* 7 | Siftool is a program for Singularity Image Format (SIF) file manipulation. 8 | 9 | A set of commands are provided to display elements such as the SIF global 10 | header, the data object descriptors and to dump data objects. It is also 11 | possible to modify a SIF file via this tool via the add/del commands. 12 | */ 13 | package main 14 | -------------------------------------------------------------------------------- /cmd/siftool/siftool.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2024, Sylabs Inc. All rights reserved. 2 | // Copyright (c) 2017, SingularityWare, LLC. All rights reserved. 3 | // Copyright (c) 2017, Yannick Cote All rights reserved. 4 | // This software is licensed under a 3-clause BSD license. Please consult the 5 | // LICENSE file distributed with the sources of this project regarding your 6 | // rights to use or distribute this software. 7 | 8 | package main 9 | 10 | import ( 11 | "fmt" 12 | "io" 13 | "os" 14 | "runtime" 15 | "strconv" 16 | "text/tabwriter" 17 | 18 | "github.com/spf13/cobra" 19 | "github.com/sylabs/sif/v2/pkg/sif" 20 | "github.com/sylabs/sif/v2/pkg/siftool" 21 | ) 22 | 23 | var ( 24 | version = "unknown" 25 | date = "" 26 | builtBy = "" 27 | commit = "" 28 | ) 29 | 30 | func writeVersion(w io.Writer) error { 31 | tw := tabwriter.NewWriter(w, 0, 0, 2, ' ', 0) 32 | defer tw.Flush() 33 | 34 | fmt.Fprintf(tw, "Version:\t%v\n", version) 35 | 36 | if builtBy != "" { 37 | fmt.Fprintf(tw, "By:\t%v\n", builtBy) 38 | } 39 | 40 | if commit != "" { 41 | fmt.Fprintf(tw, "Commit:\t%v\n", commit) 42 | } 43 | 44 | if date != "" { 45 | fmt.Fprintf(tw, "Date:\t%v\n", date) 46 | } 47 | 48 | fmt.Fprintf(tw, "Runtime:\t%v (%v/%v)\n", runtime.Version(), runtime.GOOS, runtime.GOARCH) 49 | fmt.Fprintf(tw, "Spec:\t%v\n", sif.CurrentVersion) 50 | 51 | return nil 52 | } 53 | 54 | func getVersion() *cobra.Command { 55 | return &cobra.Command{ 56 | Use: "version", 57 | Short: "Display version information", 58 | Long: "Display binary version, build info and compatible SIF version(s).", 59 | Args: cobra.ExactArgs(0), 60 | RunE: func(cmd *cobra.Command, _ []string) error { 61 | return writeVersion(cmd.OutOrStdout()) 62 | }, 63 | DisableFlagsInUseLine: true, 64 | } 65 | } 66 | 67 | func main() { 68 | root := cobra.Command{ 69 | Use: "siftool", 70 | Short: "siftool is a program for Singularity Image Format (SIF) file manipulation", 71 | Long: `A set of commands are provided to display elements such as the SIF global 72 | header, the data object descriptors and to dump data objects. It is also 73 | possible to modify a SIF file via this tool via the add/del commands.`, 74 | } 75 | 76 | root.AddCommand(getVersion()) 77 | 78 | var experimental bool 79 | if val, ok := os.LookupEnv("SIFTOOL_EXPERIMENTAL"); ok { 80 | b, err := strconv.ParseBool(val) 81 | if err != nil { 82 | fmt.Fprintln(os.Stderr, "Error: failed to parse SIFTOOL_EXPERIMENTAL environment variable:", err) 83 | } 84 | experimental = b 85 | } 86 | 87 | if err := siftool.AddCommands(&root, siftool.OptWithExperimental(experimental)); err != nil { 88 | fmt.Fprintln(os.Stderr, "Error:", err) 89 | os.Exit(1) 90 | } 91 | 92 | if err := root.Execute(); err != nil { 93 | os.Exit(1) 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /doc/sif.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/doc/sif.png -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/sylabs/sif/v2 2 | 3 | go 1.23.0 4 | 5 | require ( 6 | github.com/ProtonMail/go-crypto v1.3.0 7 | github.com/google/go-containerregistry v0.20.3 8 | github.com/google/uuid v1.6.0 9 | github.com/sebdah/goldie/v2 v2.5.5 10 | github.com/sigstore/sigstore v1.9.5 11 | github.com/spf13/cobra v1.9.1 12 | github.com/spf13/pflag v1.0.6 13 | ) 14 | 15 | require ( 16 | github.com/cloudflare/circl v1.6.1 // indirect 17 | github.com/go-jose/go-jose/v4 v4.0.5 // indirect 18 | github.com/inconshreveable/mousetrap v1.1.0 // indirect 19 | github.com/kr/pretty v0.2.1 // indirect 20 | github.com/letsencrypt/boulder v0.0.0-20240620165639-de9c06129bec // indirect 21 | github.com/opencontainers/go-digest v1.0.0 // indirect 22 | github.com/pmezard/go-difflib v1.0.0 // indirect 23 | github.com/secure-systems-lab/go-securesystemslib v0.9.0 // indirect 24 | github.com/sergi/go-diff v1.2.0 // indirect 25 | github.com/sigstore/protobuf-specs v0.4.1 // indirect 26 | github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 // indirect 27 | golang.org/x/crypto v0.36.0 // indirect 28 | golang.org/x/sys v0.31.0 // indirect 29 | golang.org/x/term v0.30.0 // indirect 30 | google.golang.org/genproto/googleapis/api v0.0.0-20240520151616-dc85e6b867a5 // indirect 31 | google.golang.org/protobuf v1.36.6 // indirect 32 | gopkg.in/yaml.v3 v3.0.1 // indirect 33 | ) 34 | -------------------------------------------------------------------------------- /internal/app/siftool/app.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2021-2022, Sylabs Inc. All rights reserved. 2 | // This software is licensed under a 3-clause BSD license. Please consult the 3 | // LICENSE file distributed with the sources of this project regarding your 4 | // rights to use or distribute this software. 5 | 6 | package siftool 7 | 8 | import ( 9 | "io" 10 | "os" 11 | ) 12 | 13 | // appOpts contains configured options. 14 | type appOpts struct { 15 | out io.Writer 16 | err io.Writer 17 | } 18 | 19 | // AppOpt are used to configure optional behavior. 20 | type AppOpt func(*appOpts) error 21 | 22 | // App holds state and configured options. 23 | type App struct { 24 | opts appOpts 25 | } 26 | 27 | // OptAppOutput specifies that output should be written to w. 28 | func OptAppOutput(w io.Writer) AppOpt { 29 | return func(o *appOpts) error { 30 | o.out = w 31 | return nil 32 | } 33 | } 34 | 35 | // OptAppError specifies that errors should be written to w. 36 | func OptAppError(w io.Writer) AppOpt { 37 | return func(o *appOpts) error { 38 | o.err = w 39 | return nil 40 | } 41 | } 42 | 43 | // New creates a new App configured with opts. 44 | // 45 | // By default, application output and errors are written to os.Stdout and os.Stderr respectively. 46 | // To modify this behavior, consider using OptAppOutput and/or OptAppError. 47 | func New(opts ...AppOpt) (*App, error) { 48 | a := App{ 49 | opts: appOpts{ 50 | out: os.Stdout, 51 | err: os.Stderr, 52 | }, 53 | } 54 | 55 | for _, opt := range opts { 56 | if err := opt(&a.opts); err != nil { 57 | return nil, err 58 | } 59 | } 60 | 61 | return &a, nil 62 | } 63 | -------------------------------------------------------------------------------- /internal/app/siftool/file.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2021-2022, Sylabs Inc. All rights reserved. 2 | // This software is licensed under a 3-clause BSD license. Please consult the 3 | // LICENSE file distributed with the sources of this project regarding your 4 | // rights to use or distribute this software. 5 | 6 | package siftool 7 | 8 | import ( 9 | "os" 10 | 11 | "github.com/sylabs/sif/v2/pkg/sif" 12 | ) 13 | 14 | // withFileImage calls fn with a FileImage loaded from path. 15 | func withFileImage(path string, writable bool, fn func(*sif.FileImage) error) error { 16 | flag := os.O_RDONLY 17 | if writable { 18 | flag = os.O_RDWR 19 | } 20 | 21 | f, err := sif.LoadContainerFromPath(path, sif.OptLoadWithFlag(flag)) 22 | if err != nil { 23 | return err 24 | } 25 | 26 | err = fn(f) 27 | 28 | if uerr := f.UnloadContainer(); err == nil { 29 | err = uerr 30 | } 31 | 32 | return err 33 | } 34 | -------------------------------------------------------------------------------- /internal/app/siftool/modif.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2021, Sylabs Inc. All rights reserved. 2 | // Copyright (c) 2018, Divya Cote All rights reserved. 3 | // Copyright (c) 2017, SingularityWare, LLC. All rights reserved. 4 | // Copyright (c) 2017, Yannick Cote All rights reserved. 5 | // This software is licensed under a 3-clause BSD license. Please consult the 6 | // LICENSE file distributed with the sources of this project regarding your 7 | // rights to use or distribute this software. 8 | 9 | package siftool 10 | 11 | import ( 12 | "io" 13 | 14 | "github.com/sylabs/sif/v2/pkg/sif" 15 | ) 16 | 17 | // New creates a new empty SIF file. 18 | func (*App) New(path string) error { 19 | f, err := sif.CreateContainerAtPath(path) 20 | if err != nil { 21 | return err 22 | } 23 | 24 | return f.UnloadContainer() 25 | } 26 | 27 | // Add adds a data object to a SIF file. 28 | func (*App) Add(path string, t sif.DataType, r io.Reader, opts ...sif.DescriptorInputOpt) error { 29 | return withFileImage(path, true, func(f *sif.FileImage) error { 30 | input, err := sif.NewDescriptorInput(t, r, opts...) 31 | if err != nil { 32 | return err 33 | } 34 | 35 | return f.AddObject(input) 36 | }) 37 | } 38 | 39 | // Del deletes a specified object descriptor and data from the SIF file. 40 | func (*App) Del(path string, id uint32) error { 41 | return withFileImage(path, true, func(f *sif.FileImage) error { 42 | return f.DeleteObject(id) 43 | }) 44 | } 45 | 46 | // Setprim sets the primary system partition of the SIF file. 47 | func (*App) Setprim(path string, id uint32) error { 48 | return withFileImage(path, true, func(f *sif.FileImage) error { 49 | return f.SetPrimPart(id) 50 | }) 51 | } 52 | -------------------------------------------------------------------------------- /internal/app/siftool/modif_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2021-2025, Sylabs Inc. All rights reserved. 2 | // This software is licensed under a 3-clause BSD license. Please consult the 3 | // LICENSE file distributed with the sources of this project regarding your 4 | // rights to use or distribute this software. 5 | 6 | package siftool 7 | 8 | import ( 9 | "bytes" 10 | "crypto" 11 | "errors" 12 | "path/filepath" 13 | "testing" 14 | 15 | "github.com/sylabs/sif/v2/pkg/sif" 16 | ) 17 | 18 | func TestApp_New(t *testing.T) { 19 | a, err := New() 20 | if err != nil { 21 | t.Fatalf("failed to create app: %v", err) 22 | } 23 | 24 | path := filepath.Join(t.TempDir(), "sif") 25 | 26 | if err := a.New(path); err != nil { 27 | t.Fatal(err) 28 | } 29 | } 30 | 31 | func TestApp_Add(t *testing.T) { 32 | a, err := New() 33 | if err != nil { 34 | t.Fatalf("failed to create app: %v", err) 35 | } 36 | 37 | tests := []struct { 38 | name string 39 | data []byte 40 | dataType sif.DataType 41 | opts []sif.DescriptorInputOpt 42 | wantErr error 43 | }{ 44 | { 45 | name: "DataPartition", 46 | data: []byte{0xde, 0xad, 0xbe, 0xef}, 47 | dataType: sif.DataPartition, 48 | opts: []sif.DescriptorInputOpt{ 49 | sif.OptPartitionMetadata(sif.FsSquash, sif.PartPrimSys, "386"), 50 | }, 51 | }, 52 | { 53 | name: "DataSignature", 54 | data: []byte{0xde, 0xad, 0xbe, 0xef}, 55 | dataType: sif.DataSignature, 56 | opts: []sif.DescriptorInputOpt{ 57 | sif.OptSignatureMetadata(crypto.SHA256, []byte{ 58 | 0x12, 0x04, 0x5c, 0x8c, 0x0b, 0x10, 0x04, 0xd0, 0x58, 0xde, 59 | 0x4b, 0xed, 0xa2, 0x0c, 0x27, 0xee, 0x7f, 0xf7, 0xba, 0x84, 60 | }), 61 | }, 62 | }, 63 | { 64 | name: "CryptoMessage", 65 | data: []byte{0xde, 0xad, 0xbe, 0xef}, 66 | dataType: sif.DataCryptoMessage, 67 | opts: []sif.DescriptorInputOpt{ 68 | sif.OptCryptoMessageMetadata(sif.FormatOpenPGP, sif.MessageClearSignature), 69 | }, 70 | }, 71 | { 72 | name: "SBOM", 73 | data: []byte{0xde, 0xad, 0xbe, 0xef}, 74 | dataType: sif.DataSBOM, 75 | opts: []sif.DescriptorInputOpt{ 76 | sif.OptSBOMMetadata(sif.SBOMFormatCycloneDXJSON), 77 | }, 78 | }, 79 | { 80 | name: "OCIRootIndex", 81 | data: []byte("{}"), 82 | dataType: sif.DataOCIRootIndex, 83 | }, 84 | { 85 | name: "OCIBlob", 86 | data: []byte("{}"), 87 | dataType: sif.DataOCIBlob, 88 | }, 89 | } 90 | for _, tt := range tests { 91 | t.Run(tt.name, func(t *testing.T) { 92 | path := filepath.Join(t.TempDir(), "sif") 93 | 94 | if err := a.New(path); err != nil { 95 | t.Fatal(err) 96 | } 97 | 98 | data := bytes.NewReader(tt.data) 99 | if got, want := a.Add(path, tt.dataType, data, tt.opts...), tt.wantErr; !errors.Is(got, want) { 100 | t.Fatalf("got error %v, want %v", got, want) 101 | } 102 | }) 103 | } 104 | } 105 | 106 | func TestApp_Del(t *testing.T) { 107 | a, err := New() 108 | if err != nil { 109 | t.Fatalf("failed to create app: %v", err) 110 | } 111 | 112 | path := filepath.Join(t.TempDir(), "sif") 113 | 114 | if err := a.New(path); err != nil { 115 | t.Fatal(err) 116 | } 117 | 118 | err = a.Add(path, sif.DataGeneric, bytes.NewReader([]byte{0xde, 0xad, 0xbe, 0xef})) 119 | if err != nil { 120 | t.Fatal(err) 121 | } 122 | 123 | if err := a.Del(path, 1); err != nil { 124 | t.Fatal(err) 125 | } 126 | } 127 | 128 | func TestApp_Setprim(t *testing.T) { 129 | a, err := New() 130 | if err != nil { 131 | t.Fatalf("failed to create app: %v", err) 132 | } 133 | 134 | path := filepath.Join(t.TempDir(), "sif") 135 | 136 | if err := a.New(path); err != nil { 137 | t.Fatal(err) 138 | } 139 | 140 | err = a.Add(path, sif.DataPartition, bytes.NewReader([]byte{0xde, 0xad, 0xbe, 0xef}), 141 | sif.OptPartitionMetadata(sif.FsSquash, sif.PartSystem, "386"), 142 | ) 143 | if err != nil { 144 | t.Fatal(err) 145 | } 146 | 147 | if err := a.Setprim(path, 1); err != nil { 148 | t.Fatal(err) 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /internal/app/siftool/testdata/TestApp_Dump/One.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/internal/app/siftool/testdata/TestApp_Dump/One.golden -------------------------------------------------------------------------------- /internal/app/siftool/testdata/TestApp_Dump/Two.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/internal/app/siftool/testdata/TestApp_Dump/Two.golden -------------------------------------------------------------------------------- /internal/app/siftool/testdata/TestApp_Header/Empty.golden: -------------------------------------------------------------------------------- 1 | Version: 01 2 | Descriptors Free: 48 3 | Descriptors Total: 48 4 | Descriptors Offset: 4096 5 | Descriptors Size: 27 KiB 6 | Data Offset: 32176 7 | Data Size: 0 B 8 | -------------------------------------------------------------------------------- /internal/app/siftool/testdata/TestApp_Header/EmptyID.golden: -------------------------------------------------------------------------------- 1 | Version: 01 2 | ID: 3fa802cc-358b-45e3-bcc0-69dc7a45f9f8 3 | Descriptors Free: 48 4 | Descriptors Total: 48 5 | Descriptors Offset: 4096 6 | Descriptors Size: 27 KiB 7 | Data Offset: 32176 8 | Data Size: 0 B 9 | -------------------------------------------------------------------------------- /internal/app/siftool/testdata/TestApp_Header/EmptyLaunchScript.golden: -------------------------------------------------------------------------------- 1 | Launch Script: #!/usr/bin/env run-script 2 | Version: 01 3 | Descriptors Free: 48 4 | Descriptors Total: 48 5 | Descriptors Offset: 4096 6 | Descriptors Size: 27 KiB 7 | Data Offset: 32176 8 | Data Size: 0 B 9 | -------------------------------------------------------------------------------- /internal/app/siftool/testdata/TestApp_Header/OneGroup.golden: -------------------------------------------------------------------------------- 1 | Version: 01 2 | Primary Architecture: 386 3 | Descriptors Free: 46 4 | Descriptors Total: 48 5 | Descriptors Offset: 4096 6 | Descriptors Size: 27 KiB 7 | Data Offset: 32176 8 | Data Size: 9 KiB 9 | -------------------------------------------------------------------------------- /internal/app/siftool/testdata/TestApp_Header/OneGroupSignedLegacy.golden: -------------------------------------------------------------------------------- 1 | Launch Script: #!/usr/bin/env run-singularity 2 | Version: 01 3 | Primary Architecture: 386 4 | ID: 6ecc76b7-a497-4f7f-9ebd-8da2a04c6be1 5 | Created At: 2020-05-22 19:30:59 +0000 UTC 6 | Modified At: 2020-06-20 20:16:39 +0000 UTC 7 | Descriptors Free: 45 8 | Descriptors Total: 48 9 | Descriptors Offset: 4096 10 | Descriptors Size: 27 KiB 11 | Data Offset: 32768 12 | Data Size: 9 KiB 13 | -------------------------------------------------------------------------------- /internal/app/siftool/testdata/TestApp_Header/OneGroupSignedLegacyAll.golden: -------------------------------------------------------------------------------- 1 | Launch Script: #!/usr/bin/env run-singularity 2 | Version: 01 3 | Primary Architecture: 386 4 | ID: 6ecc76b7-a497-4f7f-9ebd-8da2a04c6be1 5 | Created At: 2020-05-22 19:30:59 +0000 UTC 6 | Modified At: 2020-06-20 20:17:15 +0000 UTC 7 | Descriptors Free: 44 8 | Descriptors Total: 48 9 | Descriptors Offset: 4096 10 | Descriptors Size: 27 KiB 11 | Data Offset: 32768 12 | Data Size: 13 KiB 13 | -------------------------------------------------------------------------------- /internal/app/siftool/testdata/TestApp_Header/OneGroupSignedLegacyGroup.golden: -------------------------------------------------------------------------------- 1 | Launch Script: #!/usr/bin/env run-singularity 2 | Version: 01 3 | Primary Architecture: 386 4 | ID: 6ecc76b7-a497-4f7f-9ebd-8da2a04c6be1 5 | Created At: 2020-05-22 19:30:59 +0000 UTC 6 | Modified At: 2020-06-20 20:16:55 +0000 UTC 7 | Descriptors Free: 45 8 | Descriptors Total: 48 9 | Descriptors Offset: 4096 10 | Descriptors Size: 27 KiB 11 | Data Offset: 32768 12 | Data Size: 9 KiB 13 | -------------------------------------------------------------------------------- /internal/app/siftool/testdata/TestApp_Header/OneGroupSignedPGP.golden: -------------------------------------------------------------------------------- 1 | Version: 01 2 | Primary Architecture: 386 3 | Descriptors Free: 45 4 | Descriptors Total: 48 5 | Descriptors Offset: 4096 6 | Descriptors Size: 27 KiB 7 | Data Offset: 32176 8 | Data Size: 10 KiB 9 | -------------------------------------------------------------------------------- /internal/app/siftool/testdata/TestApp_Header/OneObjectCryptMessage.golden: -------------------------------------------------------------------------------- 1 | Version: 01 2 | Descriptors Free: 47 3 | Descriptors Total: 48 4 | Descriptors Offset: 4096 5 | Descriptors Size: 27 KiB 6 | Data Offset: 32176 7 | Data Size: 4 B 8 | -------------------------------------------------------------------------------- /internal/app/siftool/testdata/TestApp_Header/OneObjectGenericJSON.golden: -------------------------------------------------------------------------------- 1 | Version: 01 2 | Descriptors Free: 47 3 | Descriptors Total: 48 4 | Descriptors Offset: 4096 5 | Descriptors Size: 27 KiB 6 | Data Offset: 32176 7 | Data Size: 2 B 8 | -------------------------------------------------------------------------------- /internal/app/siftool/testdata/TestApp_Header/OneObjectOCIBlob.golden: -------------------------------------------------------------------------------- 1 | Version: 01 2 | Descriptors Free: 47 3 | Descriptors Total: 48 4 | Descriptors Offset: 4096 5 | Descriptors Size: 27 KiB 6 | Data Offset: 32176 7 | Data Size: 847 B 8 | -------------------------------------------------------------------------------- /internal/app/siftool/testdata/TestApp_Header/OneObjectOCIRootIndex.golden: -------------------------------------------------------------------------------- 1 | Version: 01 2 | Descriptors Free: 47 3 | Descriptors Total: 48 4 | Descriptors Offset: 4096 5 | Descriptors Size: 27 KiB 6 | Data Offset: 32176 7 | Data Size: 706 B 8 | -------------------------------------------------------------------------------- /internal/app/siftool/testdata/TestApp_Header/OneObjectSBOM.golden: -------------------------------------------------------------------------------- 1 | Version: 01 2 | Descriptors Free: 47 3 | Descriptors Total: 48 4 | Descriptors Offset: 4096 5 | Descriptors Size: 27 KiB 6 | Data Offset: 32176 7 | Data Size: 454 B 8 | -------------------------------------------------------------------------------- /internal/app/siftool/testdata/TestApp_Header/OneObjectTime.golden: -------------------------------------------------------------------------------- 1 | Version: 01 2 | Created At: 2020-06-30 00:01:56 +0000 UTC 3 | Modified At: 2020-06-30 00:01:56 +0000 UTC 4 | Descriptors Free: 47 5 | Descriptors Total: 48 6 | Descriptors Offset: 4096 7 | Descriptors Size: 27 KiB 8 | Data Offset: 32176 9 | Data Size: 2 B 10 | -------------------------------------------------------------------------------- /internal/app/siftool/testdata/TestApp_Header/TwoGroups.golden: -------------------------------------------------------------------------------- 1 | Version: 01 2 | Primary Architecture: 386 3 | Descriptors Free: 45 4 | Descriptors Total: 48 5 | Descriptors Offset: 4096 6 | Descriptors Size: 27 KiB 7 | Data Offset: 32176 8 | Data Size: 265 KiB 9 | -------------------------------------------------------------------------------- /internal/app/siftool/testdata/TestApp_Header/TwoGroupsSignedLegacy.golden: -------------------------------------------------------------------------------- 1 | Launch Script: #!/usr/bin/env run-singularity 2 | Version: 01 3 | Primary Architecture: 386 4 | ID: 0b19ec2c-0b08-46c9-95ae-fa88cd9e48a1 5 | Created At: 2020-05-22 19:30:59 +0000 UTC 6 | Modified At: 2020-06-20 20:16:44 +0000 UTC 7 | Descriptors Free: 44 8 | Descriptors Total: 48 9 | Descriptors Offset: 4096 10 | Descriptors Size: 27 KiB 11 | Data Offset: 32768 12 | Data Size: 13 KiB 13 | -------------------------------------------------------------------------------- /internal/app/siftool/testdata/TestApp_Header/TwoGroupsSignedLegacyAll.golden: -------------------------------------------------------------------------------- 1 | Launch Script: #!/usr/bin/env run-singularity 2 | Version: 01 3 | Primary Architecture: 386 4 | ID: 0b19ec2c-0b08-46c9-95ae-fa88cd9e48a1 5 | Created At: 2020-05-22 19:30:59 +0000 UTC 6 | Modified At: 2020-06-20 20:17:19 +0000 UTC 7 | Descriptors Free: 43 8 | Descriptors Total: 48 9 | Descriptors Offset: 4096 10 | Descriptors Size: 27 KiB 11 | Data Offset: 32768 12 | Data Size: 17 KiB 13 | -------------------------------------------------------------------------------- /internal/app/siftool/testdata/TestApp_Header/TwoGroupsSignedLegacyGroup.golden: -------------------------------------------------------------------------------- 1 | Launch Script: #!/usr/bin/env run-singularity 2 | Version: 01 3 | Primary Architecture: 386 4 | ID: 0b19ec2c-0b08-46c9-95ae-fa88cd9e48a1 5 | Created At: 2020-05-22 19:30:59 +0000 UTC 6 | Modified At: 2020-06-20 20:16:58 +0000 UTC 7 | Descriptors Free: 44 8 | Descriptors Total: 48 9 | Descriptors Offset: 4096 10 | Descriptors Size: 27 KiB 11 | Data Offset: 32768 12 | Data Size: 13 KiB 13 | -------------------------------------------------------------------------------- /internal/app/siftool/testdata/TestApp_Header/TwoGroupsSignedPGP.golden: -------------------------------------------------------------------------------- 1 | Version: 01 2 | Primary Architecture: 386 3 | Descriptors Free: 43 4 | Descriptors Total: 48 5 | Descriptors Offset: 4096 6 | Descriptors Size: 27 KiB 7 | Data Offset: 32176 8 | Data Size: 266 KiB 9 | -------------------------------------------------------------------------------- /internal/app/siftool/testdata/TestApp_Info/CryptMessage.golden: -------------------------------------------------------------------------------- 1 | Data Type: Cryptographic Message 2 | ID: 1 3 | Group ID: 1 4 | Linked ID: NONE 5 | Offset: 32176 6 | Size: 4 7 | Format Type: OpenPGP 8 | Message Type: Clear Signature 9 | -------------------------------------------------------------------------------- /internal/app/siftool/testdata/TestApp_Info/DataPartitionEXT3.golden: -------------------------------------------------------------------------------- 1 | Data Type: FS 2 | ID: 3 3 | Group ID: 2 4 | Linked ID: NONE 5 | Offset: 40960 6 | Size: 262144 7 | Filesystem Type: Ext3 8 | Partition Type: System 9 | Architecture: amd64 10 | -------------------------------------------------------------------------------- /internal/app/siftool/testdata/TestApp_Info/DataPartitionRaw.golden: -------------------------------------------------------------------------------- 1 | Data Type: FS 2 | ID: 1 3 | Group ID: 1 4 | Linked ID: NONE 5 | Offset: 32768 6 | Size: 4 7 | Filesystem Type: Raw 8 | Partition Type: System 9 | Architecture: 386 10 | -------------------------------------------------------------------------------- /internal/app/siftool/testdata/TestApp_Info/DataPartitionSquashFS.golden: -------------------------------------------------------------------------------- 1 | Data Type: FS 2 | ID: 2 3 | Group ID: 1 4 | Linked ID: NONE 5 | Offset: 36864 6 | Size: 4096 7 | Filesystem Type: Squashfs 8 | Partition Type: *System 9 | Architecture: 386 10 | -------------------------------------------------------------------------------- /internal/app/siftool/testdata/TestApp_Info/DataSignature.golden: -------------------------------------------------------------------------------- 1 | Data Type: Signature 2 | ID: 4 3 | Group ID: NONE 4 | Linked ID: 1 (G) 5 | Offset: 303104 6 | Size: 1048 7 | Hash Type: SHA-256 8 | Entity: 12045C8C0B1004D058DE4BEDA20C27EE7FF7BA84 9 | -------------------------------------------------------------------------------- /internal/app/siftool/testdata/TestApp_Info/GenericJSON.golden: -------------------------------------------------------------------------------- 1 | Data Type: JSON.Generic 2 | ID: 1 3 | Group ID: 1 4 | Linked ID: NONE 5 | Offset: 32176 6 | Size: 2 7 | Name: data.json 8 | -------------------------------------------------------------------------------- /internal/app/siftool/testdata/TestApp_Info/OCIBlob.golden: -------------------------------------------------------------------------------- 1 | Data Type: OCI.Blob 2 | ID: 1 3 | Group ID: 1 4 | Linked ID: NONE 5 | Offset: 32176 6 | Size: 847 7 | Digest: sha256:a88b15e95042f7d5a1327c03c57e10bdc1cf5f5efc2968fc73c12b6f5b00c731 8 | -------------------------------------------------------------------------------- /internal/app/siftool/testdata/TestApp_Info/OCIRootIndex.golden: -------------------------------------------------------------------------------- 1 | Data Type: OCI.RootIndex 2 | ID: 1 3 | Group ID: 1 4 | Linked ID: NONE 5 | Offset: 32176 6 | Size: 706 7 | Digest: sha256:2dc692f0dcaf7e3cb30db2d5d61004e4319f13db84331b65f066481c0f94cffb 8 | -------------------------------------------------------------------------------- /internal/app/siftool/testdata/TestApp_Info/SBOM.golden: -------------------------------------------------------------------------------- 1 | Data Type: SBOM 2 | ID: 1 3 | Group ID: 1 4 | Linked ID: NONE 5 | Offset: 32176 6 | Size: 454 7 | Format: cyclonedx-json 8 | -------------------------------------------------------------------------------- /internal/app/siftool/testdata/TestApp_Info/Time.golden: -------------------------------------------------------------------------------- 1 | Data Type: JSON.Generic 2 | ID: 1 3 | Group ID: 1 4 | Linked ID: NONE 5 | Offset: 32176 6 | Size: 2 7 | Created At: 2020-06-30 00:01:56 +0000 UTC 8 | Modified At: 2020-06-30 00:01:56 +0000 UTC 9 | Name: data.json 10 | -------------------------------------------------------------------------------- /internal/app/siftool/testdata/TestApp_List/Empty.golden: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------ 2 | ID |GROUP |LINK |SIF POSITION (start-end) |TYPE 3 | ------------------------------------------------------------------------------ 4 | -------------------------------------------------------------------------------- /internal/app/siftool/testdata/TestApp_List/EmptyID.golden: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------ 2 | ID |GROUP |LINK |SIF POSITION (start-end) |TYPE 3 | ------------------------------------------------------------------------------ 4 | -------------------------------------------------------------------------------- /internal/app/siftool/testdata/TestApp_List/EmptyLaunchScript.golden: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------ 2 | ID |GROUP |LINK |SIF POSITION (start-end) |TYPE 3 | ------------------------------------------------------------------------------ 4 | -------------------------------------------------------------------------------- /internal/app/siftool/testdata/TestApp_List/OneGroup.golden: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------ 2 | ID |GROUP |LINK |SIF POSITION (start-end) |TYPE 3 | ------------------------------------------------------------------------------ 4 | 1 |1 |NONE |32768-32772 |FS (Raw/System/386) 5 | 2 |1 |NONE |36864-40960 |FS (Squashfs/*System/386) 6 | -------------------------------------------------------------------------------- /internal/app/siftool/testdata/TestApp_List/OneGroupSignedLegacy.golden: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------ 2 | ID |GROUP |LINK |SIF POSITION (start-end) |TYPE 3 | ------------------------------------------------------------------------------ 4 | 1 |1 |NONE |32768-32772 |FS (Raw/System/386) 5 | 2 |1 |NONE |36864-36868 |FS (Squashfs/*System/386) 6 | 3 |1 |2 |40960-41569 |Signature (SHA-384) 7 | -------------------------------------------------------------------------------- /internal/app/siftool/testdata/TestApp_List/OneGroupSignedLegacyAll.golden: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------ 2 | ID |GROUP |LINK |SIF POSITION (start-end) |TYPE 3 | ------------------------------------------------------------------------------ 4 | 1 |1 |NONE |32768-32772 |FS (Raw/System/386) 5 | 2 |1 |NONE |36864-36868 |FS (Squashfs/*System/386) 6 | 3 |1 |1 |40960-41569 |Signature (SHA-384) 7 | 4 |1 |2 |45056-45665 |Signature (SHA-384) 8 | -------------------------------------------------------------------------------- /internal/app/siftool/testdata/TestApp_List/OneGroupSignedLegacyGroup.golden: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------ 2 | ID |GROUP |LINK |SIF POSITION (start-end) |TYPE 3 | ------------------------------------------------------------------------------ 4 | 1 |1 |NONE |32768-32772 |FS (Raw/System/386) 5 | 2 |1 |NONE |36864-36868 |FS (Squashfs/*System/386) 6 | 3 |NONE |1 (G) |40960-41569 |Signature (SHA-384) 7 | -------------------------------------------------------------------------------- /internal/app/siftool/testdata/TestApp_List/OneGroupSignedPGP.golden: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------ 2 | ID |GROUP |LINK |SIF POSITION (start-end) |TYPE 3 | ------------------------------------------------------------------------------ 4 | 1 |1 |NONE |32768-32772 |FS (Raw/System/386) 5 | 2 |1 |NONE |36864-40960 |FS (Squashfs/*System/386) 6 | 3 |NONE |1 (G) |40960-42008 |Signature (SHA-256) 7 | -------------------------------------------------------------------------------- /internal/app/siftool/testdata/TestApp_List/OneObjectCryptMessage.golden: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------ 2 | ID |GROUP |LINK |SIF POSITION (start-end) |TYPE 3 | ------------------------------------------------------------------------------ 4 | 1 |1 |NONE |32176-32180 |Cryptographic Message (OpenPGP/Clear Signature) 5 | -------------------------------------------------------------------------------- /internal/app/siftool/testdata/TestApp_List/OneObjectGenericJSON.golden: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------ 2 | ID |GROUP |LINK |SIF POSITION (start-end) |TYPE 3 | ------------------------------------------------------------------------------ 4 | 1 |1 |NONE |32176-32178 |JSON.Generic 5 | -------------------------------------------------------------------------------- /internal/app/siftool/testdata/TestApp_List/OneObjectOCIBlob.golden: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------ 2 | ID |GROUP |LINK |SIF POSITION (start-end) |TYPE 3 | ------------------------------------------------------------------------------ 4 | 1 |1 |NONE |32176-33023 |OCI.Blob 5 | -------------------------------------------------------------------------------- /internal/app/siftool/testdata/TestApp_List/OneObjectOCIRootIndex.golden: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------ 2 | ID |GROUP |LINK |SIF POSITION (start-end) |TYPE 3 | ------------------------------------------------------------------------------ 4 | 1 |1 |NONE |32176-32882 |OCI.RootIndex 5 | -------------------------------------------------------------------------------- /internal/app/siftool/testdata/TestApp_List/OneObjectSBOM.golden: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------ 2 | ID |GROUP |LINK |SIF POSITION (start-end) |TYPE 3 | ------------------------------------------------------------------------------ 4 | 1 |1 |NONE |32176-32630 |SBOM (cyclonedx-json) 5 | -------------------------------------------------------------------------------- /internal/app/siftool/testdata/TestApp_List/OneObjectTime.golden: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------ 2 | ID |GROUP |LINK |SIF POSITION (start-end) |TYPE 3 | ------------------------------------------------------------------------------ 4 | 1 |1 |NONE |32176-32178 |JSON.Generic 5 | -------------------------------------------------------------------------------- /internal/app/siftool/testdata/TestApp_List/TwoGroups.golden: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------ 2 | ID |GROUP |LINK |SIF POSITION (start-end) |TYPE 3 | ------------------------------------------------------------------------------ 4 | 1 |1 |NONE |32768-32772 |FS (Raw/System/386) 5 | 2 |1 |NONE |36864-40960 |FS (Squashfs/*System/386) 6 | 3 |2 |NONE |40960-303104 |FS (Ext3/System/amd64) 7 | -------------------------------------------------------------------------------- /internal/app/siftool/testdata/TestApp_List/TwoGroupsSignedLegacy.golden: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------ 2 | ID |GROUP |LINK |SIF POSITION (start-end) |TYPE 3 | ------------------------------------------------------------------------------ 4 | 1 |1 |NONE |32768-32772 |FS (Raw/System/386) 5 | 2 |1 |NONE |36864-36868 |FS (Squashfs/*System/386) 6 | 3 |2 |NONE |40960-40964 |FS (Ext3/System/amd64) 7 | 4 |1 |2 |45056-45665 |Signature (SHA-384) 8 | -------------------------------------------------------------------------------- /internal/app/siftool/testdata/TestApp_List/TwoGroupsSignedLegacyAll.golden: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------ 2 | ID |GROUP |LINK |SIF POSITION (start-end) |TYPE 3 | ------------------------------------------------------------------------------ 4 | 1 |1 |NONE |32768-32772 |FS (Raw/System/386) 5 | 2 |1 |NONE |36864-36868 |FS (Squashfs/*System/386) 6 | 3 |2 |NONE |40960-40964 |FS (Ext3/System/amd64) 7 | 4 |1 |1 |45056-45665 |Signature (SHA-384) 8 | 5 |1 |2 |49152-49761 |Signature (SHA-384) 9 | -------------------------------------------------------------------------------- /internal/app/siftool/testdata/TestApp_List/TwoGroupsSignedLegacyGroup.golden: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------ 2 | ID |GROUP |LINK |SIF POSITION (start-end) |TYPE 3 | ------------------------------------------------------------------------------ 4 | 1 |1 |NONE |32768-32772 |FS (Raw/System/386) 5 | 2 |1 |NONE |36864-36868 |FS (Squashfs/*System/386) 6 | 3 |2 |NONE |40960-40964 |FS (Ext3/System/amd64) 7 | 4 |NONE |1 (G) |45056-45665 |Signature (SHA-384) 8 | -------------------------------------------------------------------------------- /internal/app/siftool/testdata/TestApp_List/TwoGroupsSignedPGP.golden: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------ 2 | ID |GROUP |LINK |SIF POSITION (start-end) |TYPE 3 | ------------------------------------------------------------------------------ 4 | 1 |1 |NONE |32768-32772 |FS (Raw/System/386) 5 | 2 |1 |NONE |36864-40960 |FS (Squashfs/*System/386) 6 | 3 |2 |NONE |40960-303104 |FS (Ext3/System/amd64) 7 | 4 |NONE |1 (G) |303104-304152 |Signature (SHA-256) 8 | 5 |NONE |2 (G) |304152-305001 |Signature (SHA-256) 9 | -------------------------------------------------------------------------------- /pkg/integrity/clearsign.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020-2024, Sylabs Inc. All rights reserved. 2 | // This software is licensed under a 3-clause BSD license. Please consult the LICENSE.md file 3 | // distributed with the sources of this project regarding your rights to use or distribute this 4 | // software. 5 | 6 | package integrity 7 | 8 | import ( 9 | "bytes" 10 | "context" 11 | "crypto" 12 | "errors" 13 | "io" 14 | 15 | "github.com/ProtonMail/go-crypto/openpgp" 16 | "github.com/ProtonMail/go-crypto/openpgp/clearsign" 17 | "github.com/ProtonMail/go-crypto/openpgp/packet" 18 | ) 19 | 20 | var errClearsignedMsgNotFound = errors.New("clearsigned message not found") 21 | 22 | type clearsignEncoder struct { 23 | e *openpgp.Entity 24 | config *packet.Config 25 | } 26 | 27 | // newClearsignEncoder returns an encoder that signs messages in clear-sign format using entity e, 28 | // according to config. 29 | func newClearsignEncoder(e *openpgp.Entity, config *packet.Config) *clearsignEncoder { 30 | return &clearsignEncoder{ 31 | e: e, 32 | config: config, 33 | } 34 | } 35 | 36 | // signMessage signs the message from r in clear-sign format, and writes the result to w. On 37 | // success, the hash function is returned. 38 | func (en *clearsignEncoder) signMessage(_ context.Context, w io.Writer, r io.Reader) (crypto.Hash, error) { 39 | plaintext, err := clearsign.Encode(w, en.e.PrivateKey, en.config) 40 | if err != nil { 41 | return 0, err 42 | } 43 | defer plaintext.Close() 44 | 45 | _, err = io.Copy(plaintext, r) 46 | return en.config.Hash(), err 47 | } 48 | 49 | type clearsignDecoder struct { 50 | kr openpgp.KeyRing 51 | } 52 | 53 | // newClearsignDecoder returns a decoder that verifies messages in clear-sign format using key 54 | // material from kr. 55 | func newClearsignDecoder(kr openpgp.KeyRing) *clearsignDecoder { 56 | return &clearsignDecoder{ 57 | kr: kr, 58 | } 59 | } 60 | 61 | // verifyMessage reads a message from r, verifies its signature, and returns the message contents. 62 | // On success, the signing entity is set in vr. 63 | func (de *clearsignDecoder) verifyMessage(_ context.Context, r io.Reader, _ crypto.Hash, vr *VerifyResult) ([]byte, error) { //nolint:lll 64 | data, err := io.ReadAll(r) 65 | if err != nil { 66 | return nil, err 67 | } 68 | 69 | // Decode clearsign block. 70 | b, _ := clearsign.Decode(data) 71 | if b == nil { 72 | return nil, errClearsignedMsgNotFound 73 | } 74 | 75 | // Hash functions specified for OpenPGP in RFC4880, excluding those that are not currently 76 | // recommended by NIST. 77 | expectedHashes := []crypto.Hash{ 78 | crypto.SHA224, 79 | crypto.SHA256, 80 | crypto.SHA384, 81 | crypto.SHA512, 82 | } 83 | 84 | // Check signature. 85 | vr.e, err = openpgp.CheckDetachedSignatureAndHash( 86 | de.kr, 87 | bytes.NewReader(b.Bytes), 88 | b.ArmoredSignature.Body, 89 | expectedHashes, 90 | nil, 91 | ) 92 | if err != nil { 93 | return nil, err 94 | } 95 | 96 | return b.Plaintext, err 97 | } 98 | 99 | // isClearsignSignature returns true if r contains a signature in clearsign format. 100 | func isClearsignSignature(r io.Reader) bool { 101 | b, err := io.ReadAll(r) 102 | if err != nil { 103 | return false 104 | } 105 | 106 | p, _ := clearsign.Decode(b) 107 | return p != nil 108 | } 109 | -------------------------------------------------------------------------------- /pkg/integrity/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020-2022, Sylabs Inc. All rights reserved. 2 | // This software is licensed under a 3-clause BSD license. Please consult the LICENSE.md file 3 | // distributed with the sources of this project regarding your rights to use or distribute this 4 | // software. 5 | 6 | /* 7 | Package integrity implements functions to add, examine, and verify digital signatures in a SIF 8 | image. 9 | 10 | # Sign 11 | 12 | To add one or more digital signatures to a SIF, create a Signer, and supply a signing PGP entity: 13 | 14 | s, err := integrity.NewSigner(f, OptSignWithEntity(e)) 15 | 16 | By default, the returned Signer will add one digital signature per group of objects in f. To 17 | override this behavior, supply additional options. For example, to apply a signature to object 18 | group 1 only: 19 | 20 | s, err := integrity.NewSigner(f, OptSignWithEntity(e), OptSignGroup(1)) 21 | 22 | Finally, to apply the signature(s): 23 | 24 | err := s.Sign() 25 | 26 | # Verify 27 | 28 | To examine and/or verify digital signatures in a SIF, create a Verifier: 29 | 30 | v, err := NewVerifier(f) 31 | 32 | If you intend to perform cryptographic verification, you must provide a source of key material: 33 | 34 | v, err := NewVerifier(f, OptVerifyWithKeyRing(kr)) 35 | 36 | By default, the returned Verifier will consider non-legacy signatures for all object groups. To 37 | override this behavior, supply additional options. For example, to consider non-legacy signatures 38 | on object group 1 only: 39 | 40 | v, err := NewVerifier(f, OptVerifyWithKeyRing(kr), OptVerifyGroup(1)) 41 | 42 | Finally, to perform cryptographic verification: 43 | 44 | err := v.Verify() 45 | */ 46 | package integrity 47 | -------------------------------------------------------------------------------- /pkg/integrity/main_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020-2023, Sylabs Inc. All rights reserved. 2 | // This software is licensed under a 3-clause BSD license. Please consult the LICENSE.md file 3 | // distributed with the sources of this project regarding your rights to use or distribute this 4 | // software. 5 | 6 | package integrity 7 | 8 | import ( 9 | "crypto" 10 | "os" 11 | "path/filepath" 12 | "testing" 13 | "time" 14 | 15 | "github.com/ProtonMail/go-crypto/openpgp" 16 | "github.com/sigstore/sigstore/pkg/cryptoutils" 17 | "github.com/sigstore/sigstore/pkg/signature" 18 | "github.com/sylabs/sif/v2/pkg/sif" 19 | ) 20 | 21 | var corpus = filepath.Join("..", "..", "test", "images") 22 | 23 | // fixedTime returns a fixed time value, useful for ensuring tests are deterministic. 24 | func fixedTime() time.Time { 25 | return time.Unix(1504657553, 0) 26 | } 27 | 28 | // loadContainer loads a container from path for read-only access. 29 | func loadContainer(t *testing.T, path string) *sif.FileImage { 30 | t.Helper() 31 | 32 | f, err := sif.LoadContainerFromPath(path, sif.OptLoadWithFlag(os.O_RDONLY)) 33 | if err != nil { 34 | t.Fatal(err) 35 | } 36 | t.Cleanup(func() { 37 | if err := f.UnloadContainer(); err != nil { 38 | t.Error(err) 39 | } 40 | }) 41 | 42 | return f 43 | } 44 | 45 | // getTestSigner returns a Signer read from the PEM file at path. 46 | func getTestSigner(t *testing.T, name string, h crypto.Hash) signature.Signer { //nolint:ireturn 47 | t.Helper() 48 | 49 | path := filepath.Join("..", "..", "test", "keys", name) 50 | 51 | sv, err := signature.LoadSignerFromPEMFile(path, h, cryptoutils.SkipPassword) 52 | if err != nil { 53 | t.Fatal(err) 54 | } 55 | 56 | return sv 57 | } 58 | 59 | // getTestVerifier returns a Verifier read from the PEM file at path. 60 | func getTestVerifier(t *testing.T, name string, h crypto.Hash) signature.Verifier { //nolint:ireturn 61 | t.Helper() 62 | 63 | sv, err := signature.LoadVerifier(getTestPublicKey(t, name), h) 64 | if err != nil { 65 | t.Fatal(err) 66 | } 67 | 68 | return sv 69 | } 70 | 71 | // getTestPublicKey returns a PublicKey read from the PEM file at path. 72 | func getTestPublicKey(t *testing.T, name string) crypto.PublicKey { 73 | t.Helper() 74 | 75 | path := filepath.Join("..", "..", "test", "keys", name) 76 | 77 | b, err := os.ReadFile(path) 78 | if err != nil { 79 | t.Fatal(err) 80 | } 81 | 82 | pub, err := cryptoutils.UnmarshalPEMToPublicKey(b) 83 | if err != nil { 84 | t.Fatal(err) 85 | } 86 | 87 | return pub 88 | } 89 | 90 | // getTestEntity returns a fixed test PGP entity. 91 | func getTestEntity(t *testing.T) *openpgp.Entity { 92 | t.Helper() 93 | 94 | f, err := os.Open(filepath.Join("..", "..", "test", "keys", "private.asc")) 95 | if err != nil { 96 | t.Fatal(err) 97 | } 98 | defer f.Close() 99 | 100 | el, err := openpgp.ReadArmoredKeyRing(f) 101 | if err != nil { 102 | t.Fatal(err) 103 | } 104 | 105 | if got, want := len(el), 1; got != want { 106 | t.Fatalf("got %v entities, want %v", got, want) 107 | } 108 | return el[0] 109 | } 110 | -------------------------------------------------------------------------------- /pkg/integrity/result.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020-2024, Sylabs Inc. All rights reserved. 2 | // This software is licensed under a 3-clause BSD license. Please consult the LICENSE.md file 3 | // distributed with the sources of this project regarding your rights to use or distribute this 4 | // software. 5 | 6 | package integrity 7 | 8 | import ( 9 | "crypto" 10 | 11 | "github.com/ProtonMail/go-crypto/openpgp" 12 | "github.com/sylabs/sif/v2/pkg/sif" 13 | ) 14 | 15 | // VerifyResult describes the results of an individual signature validation. 16 | type VerifyResult struct { 17 | sig sif.Descriptor 18 | verified []sif.Descriptor 19 | keys []crypto.PublicKey 20 | e *openpgp.Entity 21 | err error 22 | } 23 | 24 | // Signature returns the signature object associated with the result. 25 | func (r VerifyResult) Signature() sif.Descriptor { 26 | return r.sig 27 | } 28 | 29 | // Verified returns the data objects that were verified. 30 | func (r VerifyResult) Verified() []sif.Descriptor { 31 | return r.verified 32 | } 33 | 34 | // Keys returns the public key(s) used to verify the signature. 35 | func (r VerifyResult) Keys() []crypto.PublicKey { 36 | return r.keys 37 | } 38 | 39 | // Entity returns the signing entity, or nil if the signing entity could not be determined. 40 | func (r VerifyResult) Entity() *openpgp.Entity { 41 | return r.e 42 | } 43 | 44 | // Error returns an error describing the reason verification failed, or nil if verification was 45 | // successful. 46 | func (r VerifyResult) Error() error { 47 | return r.err 48 | } 49 | -------------------------------------------------------------------------------- /pkg/integrity/testdata/TestDigest_MarshalJSON/SHA224.golden: -------------------------------------------------------------------------------- 1 | "sha224:95041dd60ab08c0bf5636d50be85fe9790300f39eb84602858a9b430" 2 | -------------------------------------------------------------------------------- /pkg/integrity/testdata/TestDigest_MarshalJSON/SHA256.golden: -------------------------------------------------------------------------------- 1 | "sha256:a948904f2f0f479b8f8197694b30184b0d2ed1c1cd2a1ec0fb85d299a192a447" 2 | -------------------------------------------------------------------------------- /pkg/integrity/testdata/TestDigest_MarshalJSON/SHA384.golden: -------------------------------------------------------------------------------- 1 | "sha384:6b3b69ff0a404f28d75e98a066d3fc64fffd9940870cc68bece28545b9a75086b343d7a1366838083e4b8f3ca6fd3c80" 2 | -------------------------------------------------------------------------------- /pkg/integrity/testdata/TestDigest_MarshalJSON/SHA512.golden: -------------------------------------------------------------------------------- 1 | "sha512:db3974a97f2407b7cae1ae637c0030687a11913274d578492558e39c16c017de84eacdc8c62fe34ee4e12b4b1428817f09b6a2760c3f8a664ceae94d2434a593" 2 | -------------------------------------------------------------------------------- /pkg/integrity/testdata/TestDigest_MarshalJSON/SHA512_224.golden: -------------------------------------------------------------------------------- 1 | "sha512_224:06001bf08dfb17d2b54925116823be230e98b5c6c278303bc4909a8c" 2 | -------------------------------------------------------------------------------- /pkg/integrity/testdata/TestDigest_MarshalJSON/SHA512_256.golden: -------------------------------------------------------------------------------- 1 | "sha512_256:3d37fe58435e0d87323dee4a2c1b339ef954de63716ee79f5747f94d974f913f" 2 | -------------------------------------------------------------------------------- /pkg/integrity/testdata/TestGetHeaderMetadata/SHA224.golden: -------------------------------------------------------------------------------- 1 | {"digest":"sha224:c9a483d5cf14145c7bc90d60e0e80ef0e92453611035b1bc000e5ce2"} 2 | -------------------------------------------------------------------------------- /pkg/integrity/testdata/TestGetHeaderMetadata/SHA256.golden: -------------------------------------------------------------------------------- 1 | {"digest":"sha256:a18d8228cd6f87e7fc3559bdf6bf2e32b3663c1b1107ffddcad06f6c2a15598e"} 2 | -------------------------------------------------------------------------------- /pkg/integrity/testdata/TestGetHeaderMetadata/SHA384.golden: -------------------------------------------------------------------------------- 1 | {"digest":"sha384:10778862b725bec7b752ae1d0f13dbefbe9082afcfa690138216c0618aa149b39d157e76a925686317b4634afa0c7743"} 2 | -------------------------------------------------------------------------------- /pkg/integrity/testdata/TestGetHeaderMetadata/SHA512.golden: -------------------------------------------------------------------------------- 1 | {"digest":"sha512:6a6d35be79ba7885a2785b5384c242c2b782ec686cfe1473af16db743f6164a1637e2d562bba867a5885ef0faf5a64f75970008b96bbe545d4e875e83e922bee"} 2 | -------------------------------------------------------------------------------- /pkg/integrity/testdata/TestGetHeaderMetadata/SHA512_224.golden: -------------------------------------------------------------------------------- 1 | {"digest":"sha512_224:d5f9767e096056fcf381b801e2b0b80b33acdc09b7a7e3a1c504231e"} 2 | -------------------------------------------------------------------------------- /pkg/integrity/testdata/TestGetHeaderMetadata/SHA512_256.golden: -------------------------------------------------------------------------------- 1 | {"digest":"sha512_256:eb199aeab4047ca6430890372769681045c20b1a0a4a78b595ab62dbdfc9285f"} 2 | -------------------------------------------------------------------------------- /pkg/integrity/testdata/TestGetImageMetadata/Object1.golden: -------------------------------------------------------------------------------- 1 | {"version":1,"header":{"digest":"sha256:635fa0a14a8ef0c0351ed3e985799ed1d4f75ce973dea3cc76c99710795cc3f1"},"objects":[{"relativeId":0,"descriptorDigest":"sha256:3634ad01db0dd5482ecf685267b53d6201690438ca27c3d7ea91c971a1f41f92","objectDigest":"sha256:004dfc8da678c309de28b5386a1e9efd57f536b150c40d29b31506aa0fb17ec2"}]} 2 | -------------------------------------------------------------------------------- /pkg/integrity/testdata/TestGetImageMetadata/Object2.golden: -------------------------------------------------------------------------------- 1 | {"version":1,"header":{"digest":"sha256:635fa0a14a8ef0c0351ed3e985799ed1d4f75ce973dea3cc76c99710795cc3f1"},"objects":[{"relativeId":1,"descriptorDigest":"sha256:04b5f87c9692a54f80d10fb6af00c779763aeca29d610348854bd97cd8bf66fd","objectDigest":"sha256:9f9c4e5e131934969b4ac8f495691c70b8c6c8e3f489c2c9ab5f1af82bce0604"}]} 2 | -------------------------------------------------------------------------------- /pkg/integrity/testdata/TestGetImageMetadata/SHA224.golden: -------------------------------------------------------------------------------- 1 | {"version":1,"header":{"digest":"sha224:88ecbdbaa9bf8410c9362213ddae5e6771fd2525da3eb390300fb666"},"objects":[{"relativeId":0,"descriptorDigest":"sha224:8ac2ffbf24282ce5f49fc591eee1e0a879b0ae2a9fa813b897b94113","objectDigest":"sha224:071bce5faa03c2016d3e1e086ccb60b6ea3cabc493c9aa1013594efd"},{"relativeId":1,"descriptorDigest":"sha224:15f2307c74c24b5aff01556df7642009a968ad717514da242821b1cb","objectDigest":"sha224:1f26e23245e830c5aa90735377d43535b0a080d03981ea58e4b94372"}]} 2 | -------------------------------------------------------------------------------- /pkg/integrity/testdata/TestGetImageMetadata/SHA256.golden: -------------------------------------------------------------------------------- 1 | {"version":1,"header":{"digest":"sha256:635fa0a14a8ef0c0351ed3e985799ed1d4f75ce973dea3cc76c99710795cc3f1"},"objects":[{"relativeId":0,"descriptorDigest":"sha256:3634ad01db0dd5482ecf685267b53d6201690438ca27c3d7ea91c971a1f41f92","objectDigest":"sha256:004dfc8da678c309de28b5386a1e9efd57f536b150c40d29b31506aa0fb17ec2"},{"relativeId":1,"descriptorDigest":"sha256:04b5f87c9692a54f80d10fb6af00c779763aeca29d610348854bd97cd8bf66fd","objectDigest":"sha256:9f9c4e5e131934969b4ac8f495691c70b8c6c8e3f489c2c9ab5f1af82bce0604"}]} 2 | -------------------------------------------------------------------------------- /pkg/integrity/testdata/TestGetImageMetadata/SHA384.golden: -------------------------------------------------------------------------------- 1 | {"version":1,"header":{"digest":"sha384:92bdcff06f2cde591d8af1f0ab80687e5eccf1dfe8fe7a8a8ef4b80d28bd2c7a77bcc4abfbcfdb3fc84ec7992ed54334"},"objects":[{"relativeId":0,"descriptorDigest":"sha384:ed532e8496b916182a4185a3d12f3a6d4c59d204965ef1a732013d1c05050291ec29b48b06ba100a948468868023fb82","objectDigest":"sha384:f8722c6694c4997334525090678b2148f6263502c3eb144a44e8be0d2bfd039f4067a3f8152f94ab3af7c63acfe78ce6"},{"relativeId":1,"descriptorDigest":"sha384:de7f8e386d3c1679711711f31812d12a913b0f5202503e46e9e1c5fd36c49908c5e288a3c08e6b72285dba177596668d","objectDigest":"sha384:da6cf2d305a04a53623df94d5e74bc22aee7961a5a62b289f99db693e5a980ee276526f254f6504f9e66621ce821b977"}]} 2 | -------------------------------------------------------------------------------- /pkg/integrity/testdata/TestGetImageMetadata/SHA512.golden: -------------------------------------------------------------------------------- 1 | {"version":1,"header":{"digest":"sha512:503a1101d5a7f66e440f157576597c5ab9a3517b025259da985402f3b7de7c90c6034b8b5d3da992a9cae5b47dd355fce3f9932e92bc47422134cc5b7347e1e7"},"objects":[{"relativeId":0,"descriptorDigest":"sha512:4ccbff33c9be45cf2ba25412de4a87bd623fd48bf00598b756ea5a12a4eddb83aa93176a91a875b595750837b3ba77b5dfbbbd90e2126ca4d4828763db6dc591","objectDigest":"sha512:808e1f67ffbdbdae30946529b920a1ad6d49c0c50423bc0c9d41ece566e291b6c3e6b6839f3095fbab6bc15a5b971b07d4b8b2f22b982ce3c2b8fd05eef7e1b3"},{"relativeId":1,"descriptorDigest":"sha512:39bc9e8ecf3192e0656f0b4de529b7e6b1b0d892a6b19fd6f619bf476558bc15255ead250e440c3fe69bbf061b49c0ca0d7de18616c0b3172b2ca2d0753ef331","objectDigest":"sha512:c948c053d5494e944dc251ba774882c58c6b18dae241caa84123c779170d1ed0a22ced3af76d67c7090b668fa7d80531e5b9e3f4677b1b5aae64e8d0d24999bf"}]} 2 | -------------------------------------------------------------------------------- /pkg/integrity/testdata/TestGetObjectMetadata/RelativeID.golden: -------------------------------------------------------------------------------- 1 | {"relativeId":1,"descriptorDigest":"sha256:a1e6ca1d0cce1fbd71b186ac7a5c5a805c833ecc419a78d017558e79c0862790","objectDigest":"sha256:8b7df143d91c716ecfa5fc1730022f6b421b05cedee8fd52b1fc65a96030ad52"} 2 | -------------------------------------------------------------------------------- /pkg/integrity/testdata/TestGetObjectMetadata/SHA224.golden: -------------------------------------------------------------------------------- 1 | {"relativeId":0,"descriptorDigest":"sha224:c46f4657fbd892b26d9880c3ee8078b2af2f9e7647910b233f30a75f","objectDigest":"sha224:0570b8b9a94b1429b3ba5f4b744a174633fcbfedf6f022cf33da3e99"} 2 | -------------------------------------------------------------------------------- /pkg/integrity/testdata/TestGetObjectMetadata/SHA256.golden: -------------------------------------------------------------------------------- 1 | {"relativeId":0,"descriptorDigest":"sha256:46712c8c573850880fceb4302c729b2bd0cfb402d3422faa5ca9026b7ab89b9b","objectDigest":"sha256:8b7df143d91c716ecfa5fc1730022f6b421b05cedee8fd52b1fc65a96030ad52"} 2 | -------------------------------------------------------------------------------- /pkg/integrity/testdata/TestGetObjectMetadata/SHA384.golden: -------------------------------------------------------------------------------- 1 | {"relativeId":0,"descriptorDigest":"sha384:426b1caa794407dd42407ace724ac9372db4ad9e7fad70539ecf078481b0f68133dc1ccad812eef70d80968ec6c7b05c","objectDigest":"sha384:0ca752991753e9fcc29ebc053c86bffb8b266b69ecf82e01fbdf380d65a1e38cbdf72f623721fbe01eb8909cb7e0bb59"} 2 | -------------------------------------------------------------------------------- /pkg/integrity/testdata/TestGetObjectMetadata/SHA512.golden: -------------------------------------------------------------------------------- 1 | {"relativeId":0,"descriptorDigest":"sha512:20f27d88e15dfd9469dfbc55aa5bdb9f48293a6cba38aa920ab511cd4d12d94d294dba3c75f50ad999d226f24c1624f65b7eaab1dd2fe4da6c2c468e3b72a984","objectDigest":"sha512:39ca2b1f97c7d1d223dcb2b22cbe20c36f920aeefd201d0bf68ffc08db6d9ac608a0a202fb536d944c9d1f50cf9bd61b5bc84217212f0727a8db8a01c2fa54b7"} 2 | -------------------------------------------------------------------------------- /pkg/integrity/testdata/TestGetObjectMetadata/SHA512_224.golden: -------------------------------------------------------------------------------- 1 | {"relativeId":0,"descriptorDigest":"sha512_224:ba5b52f4337756f9efb0c7d35f16e0365ba5845b0dd9df5e9edfce3a","objectDigest":"sha512_224:b1d15ae18bb05265b44e9e0137f08078f53f5b239a78c49c2cfc2c9c"} 2 | -------------------------------------------------------------------------------- /pkg/integrity/testdata/TestGetObjectMetadata/SHA512_256.golden: -------------------------------------------------------------------------------- 1 | {"relativeId":0,"descriptorDigest":"sha512_256:aef151cf86aaab28a4e086c9e1f9d19c8f85e4eb794336d909a6844ce7fb52ef","objectDigest":"sha512_256:9a801762c512490303535d35c221e2dc1d24f5094d038041dc4303ba7ac04f0e"} 2 | -------------------------------------------------------------------------------- /pkg/integrity/testdata/Test_dsseEncoder_signMessage/ED25519.golden: -------------------------------------------------------------------------------- 1 | {"payloadType":"application/vnd.sylabs.sif-metadata+json","payload":"eyJPbmUiOjEsIlR3byI6Mn0K","signatures":[{"keyid":"SHA256:x6l8ZblpSSXGaPMCzySedWg88BwIFcz8jlPb6el0mFs","sig":"SNnYRFIhDwWjk0pxoreaNiLea6L2WAFUm4boxnv7jiBNGmvMnbCxdsHYsTRBLXvMJHwEfKGvHFJmi9VvMe4JCQ=="}]} -------------------------------------------------------------------------------- /pkg/integrity/testdata/Test_dsseEncoder_signMessage/Multi.golden: -------------------------------------------------------------------------------- 1 | {"payloadType":"application/vnd.sylabs.sif-metadata+json","payload":"eyJPbmUiOjEsIlR3byI6Mn0K","signatures":[{"keyid":"SHA256:BhCwr7qZulYcOMSl2Jt2DuYHxHNnN6th4NdMqR/PGa4","sig":"qtxC0N3TWRUOOF4nAFwf8izZMVhpGca/s0STBi2h/OU/lND9M4uPG70LMGJ+n2GhCOyKKLR5BpgtlUkBpwhsxiPDqyyXFE2/Rvu/MsNicNIal7A1E64X3iOrMmaXK7qHDY6TpwC0KlxTOsh2XHJSM/cItgebkiRn5ZaZl48/10IzMsq/nOr0k9fGdAdgeApnRAQzBuHzcSAMpz8k9ovbyecfwuNLxXk6PO3isetpFx2j1d11gNfmwE54lCQ9ZGC3hiTJVt9WLBP+xC5AGoiX9f5FQpRzQrg9xGjyfwZDF4PSE9UFfUAC4fGPdultxUPXp8afWocJwbDgZBOkUKgE2L16LtMYSPFMdmAy615Ah6AOyudDTY+6iUr8D7YFdXgkjuQOGxtk7Wh2AIwk1lTOF4nrpycNjOJawBW5AFxdjEJ0LvG/XEJgSC88RoAkQ0YdN7j5N8nNf4+bZJ+CmTXPWU0MdFVDgI59bJKUJU/lt1WM/ZEIzujCgtqYKwCc8LNl5Fruh+2nHmtsAS3bxxPv51Nbw5d8T316SBp0bhjY+R7OncQDaP2FQ+nwpUXuDX3Tr9pqMJxDgErbIATOdSaRQ3KB1iC5gzTwIikuwPIxAuB2Gb5wWGxhqqfx7iA38TpnP5x8YXsjGCseUxFjrKoj5uL1p6ayGXOPJy/D9FsQVtA="},{"keyid":"SHA256:BhCwr7qZulYcOMSl2Jt2DuYHxHNnN6th4NdMqR/PGa4","sig":"qtxC0N3TWRUOOF4nAFwf8izZMVhpGca/s0STBi2h/OU/lND9M4uPG70LMGJ+n2GhCOyKKLR5BpgtlUkBpwhsxiPDqyyXFE2/Rvu/MsNicNIal7A1E64X3iOrMmaXK7qHDY6TpwC0KlxTOsh2XHJSM/cItgebkiRn5ZaZl48/10IzMsq/nOr0k9fGdAdgeApnRAQzBuHzcSAMpz8k9ovbyecfwuNLxXk6PO3isetpFx2j1d11gNfmwE54lCQ9ZGC3hiTJVt9WLBP+xC5AGoiX9f5FQpRzQrg9xGjyfwZDF4PSE9UFfUAC4fGPdultxUPXp8afWocJwbDgZBOkUKgE2L16LtMYSPFMdmAy615Ah6AOyudDTY+6iUr8D7YFdXgkjuQOGxtk7Wh2AIwk1lTOF4nrpycNjOJawBW5AFxdjEJ0LvG/XEJgSC88RoAkQ0YdN7j5N8nNf4+bZJ+CmTXPWU0MdFVDgI59bJKUJU/lt1WM/ZEIzujCgtqYKwCc8LNl5Fruh+2nHmtsAS3bxxPv51Nbw5d8T316SBp0bhjY+R7OncQDaP2FQ+nwpUXuDX3Tr9pqMJxDgErbIATOdSaRQ3KB1iC5gzTwIikuwPIxAuB2Gb5wWGxhqqfx7iA38TpnP5x8YXsjGCseUxFjrKoj5uL1p6ayGXOPJy/D9FsQVtA="}]} -------------------------------------------------------------------------------- /pkg/integrity/testdata/Test_dsseEncoder_signMessage/RSA_SHA256.golden: -------------------------------------------------------------------------------- 1 | {"payloadType":"application/vnd.sylabs.sif-metadata+json","payload":"eyJPbmUiOjEsIlR3byI6Mn0K","signatures":[{"keyid":"SHA256:BhCwr7qZulYcOMSl2Jt2DuYHxHNnN6th4NdMqR/PGa4","sig":"qtxC0N3TWRUOOF4nAFwf8izZMVhpGca/s0STBi2h/OU/lND9M4uPG70LMGJ+n2GhCOyKKLR5BpgtlUkBpwhsxiPDqyyXFE2/Rvu/MsNicNIal7A1E64X3iOrMmaXK7qHDY6TpwC0KlxTOsh2XHJSM/cItgebkiRn5ZaZl48/10IzMsq/nOr0k9fGdAdgeApnRAQzBuHzcSAMpz8k9ovbyecfwuNLxXk6PO3isetpFx2j1d11gNfmwE54lCQ9ZGC3hiTJVt9WLBP+xC5AGoiX9f5FQpRzQrg9xGjyfwZDF4PSE9UFfUAC4fGPdultxUPXp8afWocJwbDgZBOkUKgE2L16LtMYSPFMdmAy615Ah6AOyudDTY+6iUr8D7YFdXgkjuQOGxtk7Wh2AIwk1lTOF4nrpycNjOJawBW5AFxdjEJ0LvG/XEJgSC88RoAkQ0YdN7j5N8nNf4+bZJ+CmTXPWU0MdFVDgI59bJKUJU/lt1WM/ZEIzujCgtqYKwCc8LNl5Fruh+2nHmtsAS3bxxPv51Nbw5d8T316SBp0bhjY+R7OncQDaP2FQ+nwpUXuDX3Tr9pqMJxDgErbIATOdSaRQ3KB1iC5gzTwIikuwPIxAuB2Gb5wWGxhqqfx7iA38TpnP5x8YXsjGCseUxFjrKoj5uL1p6ayGXOPJy/D9FsQVtA="}]} -------------------------------------------------------------------------------- /pkg/integrity/testdata/Test_dsseEncoder_signMessage/RSA_SHA384.golden: -------------------------------------------------------------------------------- 1 | {"payloadType":"application/vnd.sylabs.sif-metadata+json","payload":"eyJPbmUiOjEsIlR3byI6Mn0K","signatures":[{"keyid":"SHA256:BhCwr7qZulYcOMSl2Jt2DuYHxHNnN6th4NdMqR/PGa4","sig":"p30wIIYvuxg1vLuVMSBCb9HlLjCJuHcW4ORi1GHSFzFxqLMkUVcGZvLotyA+25tInLqwX8SfTXkuIM1LnvwrrjOubi2Om8Cd9gyZqYP5Dx+BsPbAEmDgBkmV/2am6voKmpXuzNlXYocyCezw+Px+oxJI3bmFMCTjkFf5q4ah5HWvDMgfpa9T7oj13iS1WtLE2W6S5yuaIu/5gGQAWrxKKIhjAGEyS9+6I9VJEP2d2hJPDyey7YatM2Z7BfukVml/IBKoYo4cz50Y5fLfA+DstjpxQzQ0t/LyuntvsMVnOEH0n1C59aEku7RTFDVoA7GKvhSnWmGr4lD/33ZHeUDSNDWGoYo2rKeWUby+Z4Jyf27AbK2TrPvB3bxjIt7EoB4yuG1bmHgv6Agf7U43o8SZxo5mWEU/HOxulNRyE/W4quoVnD3slAIAfhDoOPo1flqaWFApPj4toyCuieQq2AheJxyP//crJnI+iLy3eUVWPELbSFpD4Gg2NKJ3PjiTx2XZndy5QVguAbjQy5RmMiFZ9Hk5qmV71wGDaBsGPKIDesM8CAXu3YOkhAEa36HYg9whgPsWDWjPe0VNzoN4UqXcjsb986n2M7AHVv+XHURf9MepRPy/pjShR0xUAeRFrZz8sBlhqaIXZcPwLBNSgZ91B5y/+VOy5aeOFTtfDG4nows="}]} -------------------------------------------------------------------------------- /pkg/integrity/testdata/Test_dsseEncoder_signMessage/RSA_SHA512.golden: -------------------------------------------------------------------------------- 1 | {"payloadType":"application/vnd.sylabs.sif-metadata+json","payload":"eyJPbmUiOjEsIlR3byI6Mn0K","signatures":[{"keyid":"SHA256:BhCwr7qZulYcOMSl2Jt2DuYHxHNnN6th4NdMqR/PGa4","sig":"QgK1Nf31jAGUaF8uUHiTCQdRaXXh4tUvX1r/n8TPv+jKYhwKTrwYYMHol0gzo1m/OmhTn8XC3vZ1cuVyvhhhBjIgux2gee+7Rm9Vzu5WwDeH0haU1tgUXcGqqLSc7Udh1zkT8+peGSTytF1ZCPuDxYJhKe6b5ZkT8vbd6nC5zHOAe9PRAp+VoJg3okvQvdWgphHcdpFM4eF6h4qTi9A5BlKCkL4MCdfKJWg0T/aLNQLI7+eKxqk7mWPcraTXqPUnyptQ4z+pO6nocNaTYx6Ouh4vkiMKzokesQxTwZz+/80Y/Ig1hvcljR7VPFrCfInhKU5o7ljjB8CQEN+MaFqtFVsAatO6ttC0Msj7iozaj+Cqm0PwrysIfQaRWGkMgnFkMEhgO4aebBLNLoAVBf92oY06lNsIPQofNi6id7s0R8ch6fuQ0N/4GjmDRCfaYYS5pQuA8TYIVVBCkjzMLgjInD1QQV/MxSDRNPLOrKcnF8j6ub0iknWaDyuBsIzjIe0D4QDdOJDxzhC3G4cqtPXfnvfJaGs7n0t05Y2sT4Z/5mGKw2yAJRd4g7Ur1HawcLdN42Bt200C6yXovmpV6MZglNLUttfQBffZQOSB7nK9jkBtHZca7YsUQIas9sIBbRX3HLzNfnz3MDhjuquLo4w633ZPoY+IPmcs/3x3QVX3tU8="}]} -------------------------------------------------------------------------------- /pkg/integrity/testdata/sources/descr-rid0.bin: -------------------------------------------------------------------------------- 1 | @ -------------------------------------------------------------------------------- /pkg/integrity/testdata/sources/descr-rid1.bin: -------------------------------------------------------------------------------- 1 | @ -------------------------------------------------------------------------------- /pkg/integrity/testdata/sources/header.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/integrity/testdata/sources/header.bin -------------------------------------------------------------------------------- /pkg/sif/add.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2023, Sylabs Inc. All rights reserved. 2 | // Copyright (c) 2017, SingularityWare, LLC. All rights reserved. 3 | // Copyright (c) 2017, Yannick Cote All rights reserved. 4 | // This software is licensed under a 3-clause BSD license. Please consult the 5 | // LICENSE file distributed with the sources of this project regarding your 6 | // rights to use or distribute this software. 7 | 8 | package sif 9 | 10 | import ( 11 | "fmt" 12 | "time" 13 | ) 14 | 15 | // addOpts accumulates object add options. 16 | type addOpts struct { 17 | t time.Time 18 | } 19 | 20 | // AddOpt are used to specify object add options. 21 | type AddOpt func(*addOpts) error 22 | 23 | // OptAddDeterministic sets header/descriptor fields to values that support deterministic 24 | // modification of images. 25 | func OptAddDeterministic() AddOpt { 26 | return func(ao *addOpts) error { 27 | ao.t = time.Time{} 28 | return nil 29 | } 30 | } 31 | 32 | // OptAddWithTime specifies t as the image modification time. 33 | func OptAddWithTime(t time.Time) AddOpt { 34 | return func(ao *addOpts) error { 35 | ao.t = t 36 | return nil 37 | } 38 | } 39 | 40 | // AddObject adds a new data object and its descriptor into the specified SIF file. 41 | // 42 | // By default, the image modification time is set to the current time for non-deterministic images, 43 | // and unset otherwise. To override this, consider using OptAddDeterministic or OptAddWithTime. 44 | func (f *FileImage) AddObject(di DescriptorInput, opts ...AddOpt) error { 45 | ao := addOpts{} 46 | 47 | if !f.isDeterministic() { 48 | ao.t = time.Now() 49 | } 50 | 51 | for _, opt := range opts { 52 | if err := opt(&ao); err != nil { 53 | return fmt.Errorf("%w", err) 54 | } 55 | } 56 | 57 | // Find an unused descriptor. 58 | i := 0 59 | for _, rd := range f.rds { 60 | if !rd.Used { 61 | break 62 | } 63 | i++ 64 | } 65 | 66 | if err := f.writeDataObject(i, di, ao.t); err != nil { 67 | return fmt.Errorf("%w", err) 68 | } 69 | 70 | if err := f.writeDescriptors(); err != nil { 71 | return fmt.Errorf("%w", err) 72 | } 73 | 74 | f.h.ModifiedAt = ao.t.Unix() 75 | 76 | if err := f.writeHeader(); err != nil { 77 | return fmt.Errorf("%w", err) 78 | } 79 | 80 | return nil 81 | } 82 | -------------------------------------------------------------------------------- /pkg/sif/arch.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2021-2022, Sylabs Inc. All rights reserved. 2 | // This software is licensed under a 3-clause BSD license. Please consult the 3 | // LICENSE file distributed with the sources of this project regarding your 4 | // rights to use or distribute this software. 5 | 6 | package sif 7 | 8 | var ( 9 | hdrArchUnknown archType = [...]byte{'0', '0', '\x00'} 10 | hdrArch386 archType = [...]byte{'0', '1', '\x00'} 11 | hdrArchAMD64 archType = [...]byte{'0', '2', '\x00'} 12 | hdrArchARM archType = [...]byte{'0', '3', '\x00'} 13 | hdrArchARM64 archType = [...]byte{'0', '4', '\x00'} 14 | hdrArchPPC64 archType = [...]byte{'0', '5', '\x00'} 15 | hdrArchPPC64le archType = [...]byte{'0', '6', '\x00'} 16 | hdrArchMIPS archType = [...]byte{'0', '7', '\x00'} 17 | hdrArchMIPSle archType = [...]byte{'0', '8', '\x00'} 18 | hdrArchMIPS64 archType = [...]byte{'0', '9', '\x00'} 19 | hdrArchMIPS64le archType = [...]byte{'1', '0', '\x00'} 20 | hdrArchS390x archType = [...]byte{'1', '1', '\x00'} 21 | hdrArchRISCV64 archType = [...]byte{'1', '2', '\x00'} 22 | ) 23 | 24 | type archType [3]byte 25 | 26 | // getSIFArch returns the archType corresponding to go runtime arch. 27 | func getSIFArch(arch string) archType { 28 | archMap := map[string]archType{ 29 | "386": hdrArch386, 30 | "amd64": hdrArchAMD64, 31 | "arm": hdrArchARM, 32 | "arm64": hdrArchARM64, 33 | "ppc64": hdrArchPPC64, 34 | "ppc64le": hdrArchPPC64le, 35 | "mips": hdrArchMIPS, 36 | "mipsle": hdrArchMIPSle, 37 | "mips64": hdrArchMIPS64, 38 | "mips64le": hdrArchMIPS64le, 39 | "s390x": hdrArchS390x, 40 | "riscv64": hdrArchRISCV64, 41 | } 42 | 43 | t, ok := archMap[arch] 44 | if !ok { 45 | return hdrArchUnknown 46 | } 47 | return t 48 | } 49 | 50 | // GoArch returns the go runtime arch corresponding to t. 51 | func (t archType) GoArch() string { 52 | archMap := map[archType]string{ 53 | hdrArch386: "386", 54 | hdrArchAMD64: "amd64", 55 | hdrArchARM: "arm", 56 | hdrArchARM64: "arm64", 57 | hdrArchPPC64: "ppc64", 58 | hdrArchPPC64le: "ppc64le", 59 | hdrArchMIPS: "mips", 60 | hdrArchMIPSle: "mipsle", 61 | hdrArchMIPS64: "mips64", 62 | hdrArchMIPS64le: "mips64le", 63 | hdrArchS390x: "s390x", 64 | hdrArchRISCV64: "riscv64", 65 | } 66 | 67 | arch, ok := archMap[t] 68 | if !ok { 69 | arch = "unknown" 70 | } 71 | return arch 72 | } 73 | -------------------------------------------------------------------------------- /pkg/sif/arch_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2021, Sylabs Inc. All rights reserved. 2 | // This software is licensed under a 3-clause BSD license. Please consult the 3 | // LICENSE file distributed with the sources of this project regarding your 4 | // rights to use or distribute this software. 5 | 6 | package sif 7 | 8 | import ( 9 | "testing" 10 | ) 11 | 12 | func TestGetSIFArch(t *testing.T) { 13 | tests := []struct { 14 | name string 15 | arch string 16 | wantArch archType 17 | }{ 18 | { 19 | name: "386", 20 | arch: "386", 21 | wantArch: hdrArch386, 22 | }, 23 | { 24 | name: "ARM64", 25 | arch: "arm64", 26 | wantArch: hdrArchARM64, 27 | }, 28 | { 29 | name: "Unknown", 30 | arch: "cray", 31 | wantArch: hdrArchUnknown, 32 | }, 33 | } 34 | for _, tt := range tests { 35 | t.Run(tt.name, func(t *testing.T) { 36 | if got, want := getSIFArch(tt.arch), tt.wantArch; got != want { 37 | t.Errorf("got arch %v, want %v", got, want) 38 | } 39 | }) 40 | } 41 | } 42 | 43 | func TestArchType_GetGoArch(t *testing.T) { 44 | tests := []struct { 45 | name string 46 | arch archType 47 | wantArch string 48 | }{ 49 | { 50 | name: "386", 51 | arch: hdrArch386, 52 | wantArch: "386", 53 | }, 54 | { 55 | name: "ARM64", 56 | arch: hdrArchARM64, 57 | wantArch: "arm64", 58 | }, 59 | { 60 | name: "Unknown", 61 | arch: hdrArchUnknown, 62 | wantArch: "unknown", 63 | }, 64 | } 65 | for _, tt := range tests { 66 | t.Run(tt.name, func(t *testing.T) { 67 | if got, want := tt.arch.GoArch(), tt.wantArch; got != want { 68 | t.Errorf("got arch %v, want %v", got, want) 69 | } 70 | }) 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /pkg/sif/buffer.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2021-2022, Sylabs Inc. All rights reserved. 2 | // This software is licensed under a 3-clause BSD license. Please consult the 3 | // LICENSE file distributed with the sources of this project regarding your 4 | // rights to use or distribute this software. 5 | 6 | package sif 7 | 8 | import ( 9 | "errors" 10 | "io" 11 | ) 12 | 13 | // A Buffer is a variable-sized buffer of bytes that implements the sif.ReadWriter interface. The 14 | // zero value for Buffer is an empty buffer ready to use. 15 | type Buffer struct { 16 | buf []byte 17 | pos int64 18 | } 19 | 20 | // NewBuffer creates and initializes a new Buffer using buf as its initial contents. 21 | func NewBuffer(buf []byte) *Buffer { 22 | return &Buffer{buf: buf} 23 | } 24 | 25 | var errNegativeOffset = errors.New("negative offset") 26 | 27 | // ReadAt implements the io.ReaderAt interface. 28 | func (b *Buffer) ReadAt(p []byte, off int64) (int, error) { 29 | if off < 0 { 30 | return 0, errNegativeOffset 31 | } 32 | 33 | if off >= int64(len(b.buf)) { 34 | return 0, io.EOF 35 | } 36 | 37 | n := copy(p, b.buf[off:]) 38 | if n < len(p) { 39 | return n, io.EOF 40 | } 41 | return n, nil 42 | } 43 | 44 | var errNegativePosition = errors.New("negative position") 45 | 46 | // Write implements the io.Writer interface. 47 | func (b *Buffer) Write(p []byte) (int, error) { 48 | if b.pos < 0 { 49 | return 0, errNegativePosition 50 | } 51 | 52 | if have, need := int64(len(b.buf))-b.pos, int64(len(p)); have < need { 53 | b.buf = append(b.buf, make([]byte, need-have)...) 54 | } 55 | 56 | n := copy(b.buf[b.pos:], p) 57 | b.pos += int64(n) 58 | return n, nil 59 | } 60 | 61 | var errInvalidWhence = errors.New("invalid whence") 62 | 63 | // Seek implements the io.Seeker interface. 64 | func (b *Buffer) Seek(offset int64, whence int) (int64, error) { 65 | var abs int64 66 | 67 | switch whence { 68 | case io.SeekStart: 69 | abs = offset 70 | case io.SeekCurrent: 71 | abs = b.pos + offset 72 | case io.SeekEnd: 73 | abs = int64(len(b.buf)) + offset 74 | default: 75 | return 0, errInvalidWhence 76 | } 77 | 78 | if abs < 0 { 79 | return 0, errNegativePosition 80 | } 81 | 82 | b.pos = abs 83 | return abs, nil 84 | } 85 | 86 | var errTruncateRange = errors.New("truncation out of range") 87 | 88 | // Truncate discards all but the first n bytes from the buffer. 89 | func (b *Buffer) Truncate(n int64) error { 90 | if n < 0 || n > int64(len(b.buf)) { 91 | return errTruncateRange 92 | } 93 | 94 | b.buf = b.buf[:n] 95 | return nil 96 | } 97 | 98 | // Bytes returns the contents of the buffer. The slice is valid for use only until the next buffer 99 | // modification (that is, only until the next call to a method like ReadAt, Write, or Truncate). 100 | func (b *Buffer) Bytes() []byte { return b.buf } 101 | 102 | // Len returns the number of bytes in the buffer. 103 | func (b *Buffer) Len() int64 { return int64(len(b.buf)) } 104 | -------------------------------------------------------------------------------- /pkg/sif/load_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2024, Sylabs Inc. All rights reserved. 2 | // This software is licensed under a 3-clause BSD license. Please consult the 3 | // LICENSE file distributed with the sources of this project regarding your 4 | // rights to use or distribute this software. 5 | 6 | package sif 7 | 8 | import ( 9 | "os" 10 | "path/filepath" 11 | "testing" 12 | ) 13 | 14 | func TestLoadContainerFromPath(t *testing.T) { 15 | tests := []struct { 16 | name string 17 | path string 18 | opts []LoadOpt 19 | }{ 20 | { 21 | name: "NoOpts", 22 | path: filepath.Join(corpus, "one-group.sif"), 23 | }, 24 | { 25 | name: "ReadOnly", 26 | path: filepath.Join(corpus, "one-group.sif"), 27 | opts: []LoadOpt{OptLoadWithFlag(os.O_RDONLY)}, 28 | }, 29 | { 30 | name: "ReadWrite", 31 | path: filepath.Join(corpus, "one-group.sif"), 32 | opts: []LoadOpt{OptLoadWithFlag(os.O_RDWR)}, 33 | }, 34 | } 35 | for _, tt := range tests { 36 | t.Run(tt.name, func(t *testing.T) { 37 | f, err := LoadContainerFromPath(tt.path, tt.opts...) 38 | if err != nil { 39 | t.Fatalf("failed to load container: %v", err) 40 | } 41 | 42 | if err := f.UnloadContainer(); err != nil { 43 | t.Errorf("failed to unload container: %v", err) 44 | } 45 | }) 46 | } 47 | } 48 | 49 | func TestLoadContainer(t *testing.T) { 50 | tests := []struct { 51 | name string 52 | opts []LoadOpt 53 | }{ 54 | { 55 | name: "NoOpts", 56 | }, 57 | { 58 | name: "CloseOnUnload", 59 | opts: []LoadOpt{OptLoadWithCloseOnUnload(true)}, 60 | }, 61 | { 62 | name: "NoCloseOnUnload", 63 | opts: []LoadOpt{OptLoadWithCloseOnUnload(false)}, 64 | }, 65 | } 66 | for _, tt := range tests { 67 | t.Run(tt.name, func(t *testing.T) { 68 | rw, err := os.Open(filepath.Join(corpus, "one-group.sif")) 69 | if err != nil { 70 | t.Fatal(err) 71 | } 72 | defer rw.Close() 73 | 74 | f, err := LoadContainer(rw, tt.opts...) 75 | if err != nil { 76 | t.Fatalf("failed to load container: %v", err) 77 | } 78 | 79 | if err := f.UnloadContainer(); err != nil { 80 | t.Errorf("failed to unload container: %v", err) 81 | } 82 | }) 83 | } 84 | } 85 | 86 | func TestLoadContainerFpMock(t *testing.T) { 87 | // This test is using mockSifReadWriter to verify that the code 88 | // is not making assumptions regading the behavior of the 89 | // ReadWriter it's getting, as mockSifReadWriter implements a 90 | // very dumb buffer. This specific test could be exteded to test 91 | // for more error conditions as it would be possible to report 92 | // errors from cases where it would be otherwise hard to do so 93 | // (e.g. Seek, ReadAt or Truncate reporting errors). 94 | 95 | // Load a valid SIF file to test the happy path. 96 | content, err := os.ReadFile(filepath.Join(corpus, "one-group.sif")) 97 | if err != nil { 98 | t.Fatalf("failed to read file: %v", err) 99 | } 100 | 101 | rw := NewBuffer(content) 102 | 103 | fimg, err := LoadContainer(rw, OptLoadWithFlag(os.O_RDONLY)) 104 | if err != nil { 105 | t.Error("LoadContainerFp(fp, true):", err) 106 | } 107 | 108 | if err = fimg.UnloadContainer(); err != nil { 109 | t.Error("fimg.UnloadContainer():", err) 110 | } 111 | } 112 | 113 | func TestLoadContainerInvalidMagic(t *testing.T) { 114 | // Load a valid SIF file ... 115 | content, err := os.ReadFile(filepath.Join(corpus, "one-group.sif")) 116 | if err != nil { 117 | t.Fatalf("failed to read file: %v", err) 118 | } 119 | 120 | // ... and edit the magic to make it invalid. Instead of 121 | // exploring all kinds of invalid, simply mess with the last 122 | // byte, as this would catch off-by-one errors in the code. 123 | copy(content[hdrLaunchLen:hdrLaunchLen+hdrMagicLen], "SIF_MAGIX") 124 | 125 | rw := NewBuffer(content) 126 | 127 | fimg, err := LoadContainer(rw, OptLoadWithFlag(os.O_RDONLY)) 128 | if err == nil { 129 | // unload the container in case it's loaded, ignore 130 | // any errors 131 | _ = fimg.UnloadContainer() 132 | t.Errorf(`LoadContainerFp(fp, true) did not report an error for a container with invalid magic.`) 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /pkg/sif/sif_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2021-2024, Sylabs Inc. All rights reserved. 2 | // This software is licensed under a 3-clause BSD license. Please consult the 3 | // LICENSE file distributed with the sources of this project regarding your 4 | // rights to use or distribute this software. 5 | package sif 6 | 7 | import ( 8 | "bytes" 9 | "io" 10 | "path/filepath" 11 | "testing" 12 | 13 | "github.com/google/uuid" 14 | "github.com/sebdah/goldie/v2" 15 | ) 16 | 17 | var corpus = filepath.Join("..", "..", "test", "images") 18 | 19 | func TestHeader_GetIntegrityReader(t *testing.T) { 20 | h := header{ 21 | Magic: hdrMagic, 22 | Version: CurrentVersion.bytes(), 23 | Arch: hdrArchAMD64, 24 | ID: uuid.UUID{0xb2, 0x65, 0x9d, 0x4e, 0xbd, 0x50, 0x4e, 0xa5, 0xbd, 0x17, 0xee, 0xc5, 0xe5, 0x4f, 0x91, 0x8e}, 25 | CreatedAt: 1504657553, 26 | ModifiedAt: 1504657653, 27 | } 28 | copy(h.LaunchScript[:], "#!/usr/bin/env run-singularity\n") 29 | 30 | tests := []struct { 31 | name string 32 | modFunc func(h header) header 33 | }{ 34 | {"LaunchScript", func(h header) header { 35 | copy(h.LaunchScript[:], "#!/usr/bin/env rm\n") 36 | return h 37 | }}, 38 | {"Magic", func(h header) header { 39 | copy(h.Magic[:], "BAD_MAGIC") 40 | return h 41 | }}, 42 | {"Version", func(h header) header { 43 | copy(h.Version[:], "02") 44 | return h 45 | }}, 46 | {"Arch", func(h header) header { 47 | h.Arch = hdrArchS390x 48 | return h 49 | }}, 50 | {"ID", func(h header) header { 51 | h.ID[0]++ 52 | return h 53 | }}, 54 | {"CreatedAt", func(h header) header { 55 | h.CreatedAt++ 56 | return h 57 | }}, 58 | {"ModifiedAt", func(h header) header { 59 | h.ModifiedAt++ 60 | return h 61 | }}, 62 | {"DescriptorsFree", func(h header) header { 63 | h.DescriptorsFree++ 64 | return h 65 | }}, 66 | {"DescriptorsTotal", func(h header) header { 67 | h.DescriptorsTotal++ 68 | return h 69 | }}, 70 | {"DescriptorsOffset", func(h header) header { 71 | h.DescriptorsOffset++ 72 | return h 73 | }}, 74 | {"DescriptorsSize", func(h header) header { 75 | h.DescriptorsSize++ 76 | return h 77 | }}, 78 | {"DataOffset", func(h header) header { 79 | h.DataOffset++ 80 | return h 81 | }}, 82 | {"DataSize", func(h header) header { 83 | h.DataSize++ 84 | return h 85 | }}, 86 | } 87 | 88 | for _, tt := range tests { 89 | t.Run(tt.name, func(t *testing.T) { 90 | b := bytes.Buffer{} 91 | 92 | h := tt.modFunc(h) 93 | 94 | if _, err := io.Copy(&b, h.GetIntegrityReader()); err != nil { 95 | t.Fatal(err) 96 | } 97 | 98 | g := goldie.New(t, goldie.WithTestNameForDir(true)) 99 | g.Assert(t, tt.name, b.Bytes()) 100 | }) 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /pkg/sif/testdata/TestAddObject/Deterministic.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestAddObject/Deterministic.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestAddObject/Empty.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestAddObject/Empty.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestAddObject/EmptyAligned.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestAddObject/EmptyAligned.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestAddObject/EmptyNotAligned.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestAddObject/EmptyNotAligned.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestAddObject/ErrInsufficientCapacity.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestAddObject/ErrInsufficientCapacity.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestAddObject/ErrPrimaryPartition.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestAddObject/ErrPrimaryPartition.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestAddObject/NotEmpty.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestAddObject/NotEmpty.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestAddObject/NotEmptyAligned.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestAddObject/NotEmptyAligned.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestAddObject/NotEmptyNotAligned.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestAddObject/NotEmptyNotAligned.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestAddObject/WithTime.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestAddObject/WithTime.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestCreateContainer/Empty.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestCreateContainer/Empty.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestCreateContainer/EmptyCloseOnUnload.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestCreateContainer/EmptyCloseOnUnload.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestCreateContainer/EmptyDescriptorLimitedCapacity.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestCreateContainer/EmptyDescriptorLimitedCapacity.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestCreateContainer/EmptyLaunchScript.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestCreateContainer/EmptyLaunchScript.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestCreateContainer/EmptyWithID.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestCreateContainer/EmptyWithID.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestCreateContainer/EmptyWithTime.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestCreateContainer/EmptyWithTime.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestCreateContainer/OneDescriptor.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestCreateContainer/OneDescriptor.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestCreateContainer/TwoDescriptors.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestCreateContainer/TwoDescriptors.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestCreateContainer/TwoDescriptorsAligned.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestCreateContainer/TwoDescriptorsAligned.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestCreateContainer/TwoDescriptorsNotAligned.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestCreateContainer/TwoDescriptorsNotAligned.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestCreateContainerAtPath/Empty.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestCreateContainerAtPath/Empty.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestCreateContainerAtPath/EmptyDescriptorLimitedCapacity.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestCreateContainerAtPath/EmptyDescriptorLimitedCapacity.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestCreateContainerAtPath/OneDescriptor.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestCreateContainerAtPath/OneDescriptor.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestCreateContainerAtPath/TwoDescriptors.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestCreateContainerAtPath/TwoDescriptors.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestCreateContainerAtPath/TwoDescriptorsAligned.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestCreateContainerAtPath/TwoDescriptorsAligned.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestCreateContainerAtPath/TwoDescriptorsNotAligned.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestCreateContainerAtPath/TwoDescriptorsNotAligned.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestDeleteObject/Compact.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestDeleteObject/Compact.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestDeleteObject/Deterministic.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestDeleteObject/Deterministic.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestDeleteObject/ErrObjectNotFound.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestDeleteObject/ErrObjectNotFound.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestDeleteObject/OneCompact.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestDeleteObject/OneCompact.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestDeleteObject/OneZero.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestDeleteObject/OneZero.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestDeleteObject/OneZeroCompact.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestDeleteObject/OneZeroCompact.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestDeleteObject/PrimaryPartition.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestDeleteObject/PrimaryPartition.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestDeleteObject/TwoCompact.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestDeleteObject/TwoCompact.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestDeleteObject/TwoZero.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestDeleteObject/TwoZero.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestDeleteObject/TwoZeroCompact.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestDeleteObject/TwoZeroCompact.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestDeleteObject/WithTime.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestDeleteObject/WithTime.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestDeleteObjectAndAddObject/Compact.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestDeleteObjectAndAddObject/Compact.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestDeleteObjectAndAddObject/NoCompact.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestDeleteObjectAndAddObject/NoCompact.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestDeleteObjectAndAddObject/Zero.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestDeleteObjectAndAddObject/Zero.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestDeleteObjectAndAddObject/ZeroCompact.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestDeleteObjectAndAddObject/ZeroCompact.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestDeleteObjects/DataType.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestDeleteObjects/DataType.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestDeleteObjects/DataTypeCompact.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestDeleteObjects/DataTypeCompact.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestDeleteObjects/ErrObjectNotFound.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestDeleteObjects/ErrObjectNotFound.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestDeleteObjects/NilSelectFunc.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestDeleteObjects/NilSelectFunc.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestDeleteObjects/PrimaryPartitionCompact.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestDeleteObjects/PrimaryPartitionCompact.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestDescriptor_GetIntegrityReader/CreatedAt.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestDescriptor_GetIntegrityReader/CreatedAt.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestDescriptor_GetIntegrityReader/DataType.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestDescriptor_GetIntegrityReader/DataType.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestDescriptor_GetIntegrityReader/Extra.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestDescriptor_GetIntegrityReader/Extra.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestDescriptor_GetIntegrityReader/GID.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestDescriptor_GetIntegrityReader/GID.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestDescriptor_GetIntegrityReader/GroupID.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestDescriptor_GetIntegrityReader/GroupID.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestDescriptor_GetIntegrityReader/ID.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestDescriptor_GetIntegrityReader/ID.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestDescriptor_GetIntegrityReader/LinkedID.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestDescriptor_GetIntegrityReader/LinkedID.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestDescriptor_GetIntegrityReader/ModifiedAt.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestDescriptor_GetIntegrityReader/ModifiedAt.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestDescriptor_GetIntegrityReader/Name.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestDescriptor_GetIntegrityReader/Name.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestDescriptor_GetIntegrityReader/Offset.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestDescriptor_GetIntegrityReader/Offset.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestDescriptor_GetIntegrityReader/RelativeID.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestDescriptor_GetIntegrityReader/RelativeID.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestDescriptor_GetIntegrityReader/Size.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestDescriptor_GetIntegrityReader/Size.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestDescriptor_GetIntegrityReader/SizeWithPadding.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestDescriptor_GetIntegrityReader/SizeWithPadding.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestDescriptor_GetIntegrityReader/UID.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestDescriptor_GetIntegrityReader/UID.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestDescriptor_GetIntegrityReader/Used.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestDescriptor_GetIntegrityReader/Used.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestFileImage_SetOCIBlobDigest/Deterministic.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestFileImage_SetOCIBlobDigest/Deterministic.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestFileImage_SetOCIBlobDigest/One.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestFileImage_SetOCIBlobDigest/One.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestFileImage_SetOCIBlobDigest/Two.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestFileImage_SetOCIBlobDigest/Two.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestFileImage_SetOCIBlobDigest/WithTime.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestFileImage_SetOCIBlobDigest/WithTime.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestHeader_GetIntegrityReader/Arch.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestHeader_GetIntegrityReader/Arch.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestHeader_GetIntegrityReader/CreatedAt.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestHeader_GetIntegrityReader/CreatedAt.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestHeader_GetIntegrityReader/DataOffset.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestHeader_GetIntegrityReader/DataOffset.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestHeader_GetIntegrityReader/DataSize.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestHeader_GetIntegrityReader/DataSize.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestHeader_GetIntegrityReader/DescriptorsFree.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestHeader_GetIntegrityReader/DescriptorsFree.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestHeader_GetIntegrityReader/DescriptorsOffset.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestHeader_GetIntegrityReader/DescriptorsOffset.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestHeader_GetIntegrityReader/DescriptorsSize.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestHeader_GetIntegrityReader/DescriptorsSize.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestHeader_GetIntegrityReader/DescriptorsTotal.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestHeader_GetIntegrityReader/DescriptorsTotal.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestHeader_GetIntegrityReader/ID.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestHeader_GetIntegrityReader/ID.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestHeader_GetIntegrityReader/LaunchScript.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestHeader_GetIntegrityReader/LaunchScript.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestHeader_GetIntegrityReader/Magic.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestHeader_GetIntegrityReader/Magic.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestHeader_GetIntegrityReader/ModifiedAt.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestHeader_GetIntegrityReader/ModifiedAt.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestHeader_GetIntegrityReader/Version.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestHeader_GetIntegrityReader/Version.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestNewDescriptorInput/DataOCIBlob.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestNewDescriptorInput/DataOCIBlob.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestNewDescriptorInput/DataOCIRootIndex.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestNewDescriptorInput/DataOCIRootIndex.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestNewDescriptorInput/Empty.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestNewDescriptorInput/Empty.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestNewDescriptorInput/OptCryptoMessageMetadata.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestNewDescriptorInput/OptCryptoMessageMetadata.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestNewDescriptorInput/OptGroupID.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestNewDescriptorInput/OptGroupID.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestNewDescriptorInput/OptLinkedGroupID.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestNewDescriptorInput/OptLinkedGroupID.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestNewDescriptorInput/OptLinkedID.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestNewDescriptorInput/OptLinkedID.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestNewDescriptorInput/OptMetadata.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestNewDescriptorInput/OptMetadata.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestNewDescriptorInput/OptNoGroup.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestNewDescriptorInput/OptNoGroup.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestNewDescriptorInput/OptObjectAlignment.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestNewDescriptorInput/OptObjectAlignment.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestNewDescriptorInput/OptObjectName.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestNewDescriptorInput/OptObjectName.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestNewDescriptorInput/OptObjectTime.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestNewDescriptorInput/OptObjectTime.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestNewDescriptorInput/OptPartitionMetadata.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestNewDescriptorInput/OptPartitionMetadata.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestNewDescriptorInput/OptSBOMMetadata.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestNewDescriptorInput/OptSBOMMetadata.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestNewDescriptorInput/OptSignatureMetadata.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestNewDescriptorInput/OptSignatureMetadata.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestSetMetadata/Deterministic.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestSetMetadata/Deterministic.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestSetMetadata/ErrObjectNotFound.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestSetMetadata/ErrObjectNotFound.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestSetMetadata/One.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestSetMetadata/One.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestSetMetadata/Two.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestSetMetadata/Two.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestSetMetadata/WithTime.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestSetMetadata/WithTime.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestSetPrimPart/Deterministic.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestSetPrimPart/Deterministic.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestSetPrimPart/ErrObjectNotFound.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestSetPrimPart/ErrObjectNotFound.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestSetPrimPart/One.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestSetPrimPart/One.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestSetPrimPart/Two.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestSetPrimPart/Two.golden -------------------------------------------------------------------------------- /pkg/sif/testdata/TestSetPrimPart/WithTime.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/sif/testdata/TestSetPrimPart/WithTime.golden -------------------------------------------------------------------------------- /pkg/siftool/add_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2021-2023, Sylabs Inc. All rights reserved. 2 | // This software is licensed under a 3-clause BSD license. Please consult the 3 | // LICENSE file distributed with the sources of this project regarding your 4 | // rights to use or distribute this software. 5 | 6 | package siftool 7 | 8 | import ( 9 | "path/filepath" 10 | "testing" 11 | ) 12 | 13 | func Test_command_getAdd(t *testing.T) { 14 | tests := []struct { 15 | name string 16 | opts commandOpts 17 | flags []string 18 | }{ 19 | { 20 | name: "DataPartition", 21 | flags: []string{ 22 | "--datatype", "4", 23 | "--parttype", "2", 24 | "--partfs", "1", 25 | "--partarch", "1", 26 | }, 27 | }, 28 | { 29 | name: "DataSignature", 30 | flags: []string{ 31 | "--datatype", "5", 32 | "--signhash", "1", 33 | "--signentity", "433FE984155206BD962725E20E8713472A879943", 34 | }, 35 | }, 36 | { 37 | name: "DataOCIRootIndex", 38 | flags: []string{ 39 | "--datatype", "10", 40 | }, 41 | }, 42 | { 43 | name: "DataOCIBlob", 44 | flags: []string{ 45 | "--datatype", "11", 46 | }, 47 | }, 48 | } 49 | for _, tt := range tests { 50 | t.Run(tt.name, func(t *testing.T) { 51 | c := &command{opts: tt.opts} 52 | 53 | cmd := c.getAdd() 54 | 55 | args := []string{ 56 | makeTestSIF(t, false), 57 | filepath.Join("testdata", "input", "input.bin"), 58 | } 59 | args = append(args, tt.flags...) 60 | 61 | runCommand(t, cmd, args, nil) 62 | }) 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /pkg/siftool/del.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2024, Sylabs Inc. All rights reserved. 2 | // Copyright (c) 2017, SingularityWare, LLC. All rights reserved. 3 | // Copyright (c) 2017, Yannick Cote All rights reserved. 4 | // This software is licensed under a 3-clause BSD license. Please consult the 5 | // LICENSE file distributed with the sources of this project regarding your 6 | // rights to use or distribute this software. 7 | 8 | package siftool 9 | 10 | import ( 11 | "fmt" 12 | "strconv" 13 | 14 | "github.com/spf13/cobra" 15 | ) 16 | 17 | // getDel returns a command that deletes a data object from a SIF. 18 | func (c *command) getDel() *cobra.Command { 19 | return &cobra.Command{ 20 | Use: "del ", 21 | Short: "Delete data object", 22 | Long: "Delete a data object from a SIF image.", 23 | Example: c.opts.rootPath + " del 1 image.sif", 24 | Args: cobra.ExactArgs(2), 25 | PreRunE: c.initApp, 26 | RunE: func(_ *cobra.Command, args []string) error { 27 | id, err := strconv.ParseUint(args[0], 10, 32) 28 | if err != nil { 29 | return fmt.Errorf("while converting id: %w", err) 30 | } 31 | 32 | return c.app.Del(args[1], uint32(id)) 33 | }, 34 | DisableFlagsInUseLine: true, 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /pkg/siftool/del_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2021-2022, Sylabs Inc. All rights reserved. 2 | // This software is licensed under a 3-clause BSD license. Please consult the 3 | // LICENSE file distributed with the sources of this project regarding your 4 | // rights to use or distribute this software. 5 | 6 | package siftool 7 | 8 | import ( 9 | "testing" 10 | ) 11 | 12 | func Test_command_getDel(t *testing.T) { 13 | tests := []struct { 14 | name string 15 | opts commandOpts 16 | }{ 17 | { 18 | name: "OK", 19 | }, 20 | } 21 | for _, tt := range tests { 22 | t.Run(tt.name, func(t *testing.T) { 23 | c := &command{opts: tt.opts} 24 | 25 | cmd := c.getDel() 26 | 27 | runCommand(t, cmd, []string{"1", makeTestSIF(t, true)}, nil) 28 | }) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /pkg/siftool/dump.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2024, Sylabs Inc. All rights reserved. 2 | // Copyright (c) 2018, Divya Cote All rights reserved. 3 | // Copyright (c) 2017, SingularityWare, LLC. All rights reserved. 4 | // Copyright (c) 2017, Yannick Cote All rights reserved. 5 | // This software is licensed under a 3-clause BSD license. Please consult the 6 | // LICENSE file distributed with the sources of this project regarding your 7 | // rights to use or distribute this software. 8 | 9 | package siftool 10 | 11 | import ( 12 | "fmt" 13 | "strconv" 14 | 15 | "github.com/spf13/cobra" 16 | ) 17 | 18 | // getDump returns a command that dumps a data object from a SIF file. 19 | func (c *command) getDump() *cobra.Command { 20 | return &cobra.Command{ 21 | Use: "dump ", 22 | Short: "Dump data object", 23 | Long: "Dump a data object from a SIF image.", 24 | Example: c.opts.rootPath + " dump 1 image.sif", 25 | Args: cobra.ExactArgs(2), 26 | PreRunE: c.initApp, 27 | RunE: func(_ *cobra.Command, args []string) error { 28 | id, err := strconv.ParseUint(args[0], 10, 32) 29 | if err != nil { 30 | return fmt.Errorf("while converting id: %w", err) 31 | } 32 | 33 | return c.app.Dump(args[1], uint32(id)) 34 | }, 35 | DisableFlagsInUseLine: true, 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /pkg/siftool/dump_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2021-2023, Sylabs Inc. All rights reserved. 2 | // This software is licensed under a 3-clause BSD license. Please consult the 3 | // LICENSE file distributed with the sources of this project regarding your 4 | // rights to use or distribute this software. 5 | 6 | package siftool 7 | 8 | import ( 9 | "path/filepath" 10 | "testing" 11 | ) 12 | 13 | func Test_command_getDump(t *testing.T) { 14 | tests := []struct { 15 | name string 16 | opts commandOpts 17 | id string 18 | path string 19 | }{ 20 | { 21 | name: "One", 22 | id: "1", 23 | path: filepath.Join(corpus, "one-group.sif"), 24 | }, 25 | { 26 | name: "Two", 27 | path: filepath.Join(corpus, "one-group.sif"), 28 | id: "2", 29 | }, 30 | } 31 | for _, tt := range tests { 32 | t.Run(tt.name, func(t *testing.T) { 33 | c := &command{opts: tt.opts} 34 | 35 | cmd := c.getDump() 36 | 37 | runCommand(t, cmd, []string{tt.id, tt.path}, nil) 38 | }) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /pkg/siftool/header.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2024, Sylabs Inc. All rights reserved. 2 | // Copyright (c) 2018, Divya Cote All rights reserved. 3 | // Copyright (c) 2017, SingularityWare, LLC. All rights reserved. 4 | // Copyright (c) 2017, Yannick Cote All rights reserved. 5 | // This software is licensed under a 3-clause BSD license. Please consult the 6 | // LICENSE file distributed with the sources of this project regarding your 7 | // rights to use or distribute this software. 8 | 9 | package siftool 10 | 11 | import ( 12 | "github.com/spf13/cobra" 13 | ) 14 | 15 | // getHeader returns a command that displays the global SIF header. 16 | func (c *command) getHeader() *cobra.Command { 17 | return &cobra.Command{ 18 | Use: "header ", 19 | Short: "Display global header", 20 | Long: "Display global header from a SIF image.", 21 | Example: c.opts.rootPath + " header image.sif", 22 | Args: cobra.ExactArgs(1), 23 | PreRunE: c.initApp, 24 | RunE: func(_ *cobra.Command, args []string) error { 25 | return c.app.Header(args[0]) 26 | }, 27 | DisableFlagsInUseLine: true, 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /pkg/siftool/header_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2021-2022, Sylabs Inc. All rights reserved. 2 | // This software is licensed under a 3-clause BSD license. Please consult the 3 | // LICENSE file distributed with the sources of this project regarding your 4 | // rights to use or distribute this software. 5 | 6 | //nolint:dupl 7 | package siftool 8 | 9 | import ( 10 | "path/filepath" 11 | "testing" 12 | ) 13 | 14 | func Test_command_getHeader(t *testing.T) { 15 | tests := []struct { 16 | name string 17 | opts commandOpts 18 | path string 19 | }{ 20 | { 21 | name: "Empty", 22 | path: filepath.Join(corpus, "empty.sif"), 23 | }, 24 | { 25 | name: "OneGroup", 26 | path: filepath.Join(corpus, "one-group.sif"), 27 | }, 28 | { 29 | name: "OneGroupSignedLegacy", 30 | path: filepath.Join(corpus, "one-group-signed-legacy.sif"), 31 | }, 32 | { 33 | name: "OneGroupSignedLegacyAll", 34 | path: filepath.Join(corpus, "one-group-signed-legacy-all.sif"), 35 | }, 36 | { 37 | name: "OneGroupSignedLegacyGroup", 38 | path: filepath.Join(corpus, "one-group-signed-legacy-group.sif"), 39 | }, 40 | { 41 | name: "OneGroupSignedPGP", 42 | path: filepath.Join(corpus, "one-group-signed-pgp.sif"), 43 | }, 44 | { 45 | name: "TwoGroups", 46 | path: filepath.Join(corpus, "two-groups.sif"), 47 | }, 48 | { 49 | name: "TwoGroupsSignedLegacy", 50 | path: filepath.Join(corpus, "two-groups-signed-legacy.sif"), 51 | }, 52 | { 53 | name: "TwoGroupsSignedLegacyAll", 54 | path: filepath.Join(corpus, "two-groups-signed-legacy-all.sif"), 55 | }, 56 | { 57 | name: "TwoGroupsSignedLegacyGroup", 58 | path: filepath.Join(corpus, "two-groups-signed-legacy-group.sif"), 59 | }, 60 | { 61 | name: "TwoGroupsSignedPGP", 62 | path: filepath.Join(corpus, "two-groups-signed-pgp.sif"), 63 | }, 64 | } 65 | for _, tt := range tests { 66 | t.Run(tt.name, func(t *testing.T) { 67 | c := &command{opts: tt.opts} 68 | 69 | cmd := c.getHeader() 70 | 71 | runCommand(t, cmd, []string{tt.path}, nil) 72 | }) 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /pkg/siftool/info.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2024, Sylabs Inc. All rights reserved. 2 | // Copyright (c) 2018, Divya Cote All rights reserved. 3 | // Copyright (c) 2017, SingularityWare, LLC. All rights reserved. 4 | // Copyright (c) 2017, Yannick Cote All rights reserved. 5 | // This software is licensed under a 3-clause BSD license. Please consult the 6 | // LICENSE file distributed with the sources of this project regarding your 7 | // rights to use or distribute this software. 8 | 9 | package siftool 10 | 11 | import ( 12 | "fmt" 13 | "strconv" 14 | 15 | "github.com/spf13/cobra" 16 | ) 17 | 18 | // getInfo returns a command that displays detailed information of an object descriptor from a SIF 19 | // image. 20 | func (c *command) getInfo() *cobra.Command { 21 | return &cobra.Command{ 22 | Use: "info ", 23 | Short: "Display data object info", 24 | Long: "Display info about a data object from a SIF image.", 25 | Example: c.opts.rootPath + " info 1 image.sif", 26 | Args: cobra.ExactArgs(2), 27 | PreRunE: c.initApp, 28 | RunE: func(_ *cobra.Command, args []string) error { 29 | id, err := strconv.ParseUint(args[0], 10, 32) 30 | if err != nil { 31 | return fmt.Errorf("while converting id: %w", err) 32 | } 33 | 34 | return c.app.Info(args[1], uint32(id)) 35 | }, 36 | DisableFlagsInUseLine: true, 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /pkg/siftool/info_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2021-2022, Sylabs Inc. All rights reserved. 2 | // This software is licensed under a 3-clause BSD license. Please consult the 3 | // LICENSE file distributed with the sources of this project regarding your 4 | // rights to use or distribute this software. 5 | 6 | package siftool 7 | 8 | import ( 9 | "path/filepath" 10 | "testing" 11 | ) 12 | 13 | func Test_command_getInfo(t *testing.T) { 14 | tests := []struct { 15 | name string 16 | opts commandOpts 17 | id string 18 | path string 19 | }{ 20 | { 21 | name: "One", 22 | id: "1", 23 | path: filepath.Join(corpus, "one-group-signed-pgp.sif"), 24 | }, 25 | { 26 | name: "Two", 27 | id: "2", 28 | path: filepath.Join(corpus, "one-group-signed-pgp.sif"), 29 | }, 30 | { 31 | name: "Three", 32 | id: "3", 33 | path: filepath.Join(corpus, "one-group-signed-pgp.sif"), 34 | }, 35 | } 36 | for _, tt := range tests { 37 | t.Run(tt.name, func(t *testing.T) { 38 | c := &command{opts: tt.opts} 39 | 40 | cmd := c.getInfo() 41 | 42 | runCommand(t, cmd, []string{tt.id, tt.path}, nil) 43 | }) 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /pkg/siftool/list.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2024, Sylabs Inc. All rights reserved. 2 | // Copyright (c) 2018, Divya Cote All rights reserved. 3 | // Copyright (c) 2017, SingularityWare, LLC. All rights reserved. 4 | // Copyright (c) 2017, Yannick Cote All rights reserved. 5 | // This software is licensed under a 3-clause BSD license. Please consult the 6 | // LICENSE file distributed with the sources of this project regarding your 7 | // rights to use or distribute this software. 8 | 9 | package siftool 10 | 11 | import ( 12 | "github.com/spf13/cobra" 13 | ) 14 | 15 | // getList returns a command that lists object descriptors from a SIF image. 16 | func (c *command) getList() *cobra.Command { 17 | return &cobra.Command{ 18 | Use: "list ", 19 | Short: "List data objects", 20 | Long: "List data objects from a SIF image.", 21 | Example: c.opts.rootPath + " list image.sif", 22 | Args: cobra.ExactArgs(1), 23 | PreRunE: c.initApp, 24 | RunE: func(_ *cobra.Command, args []string) error { 25 | return c.app.List(args[0]) 26 | }, 27 | DisableFlagsInUseLine: true, 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /pkg/siftool/list_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2021-2022, Sylabs Inc. All rights reserved. 2 | // This software is licensed under a 3-clause BSD license. Please consult the 3 | // LICENSE file distributed with the sources of this project regarding your 4 | // rights to use or distribute this software. 5 | 6 | //nolint:dupl 7 | package siftool 8 | 9 | import ( 10 | "path/filepath" 11 | "testing" 12 | ) 13 | 14 | func Test_command_getList(t *testing.T) { 15 | tests := []struct { 16 | name string 17 | opts commandOpts 18 | path string 19 | }{ 20 | { 21 | name: "Empty", 22 | path: filepath.Join(corpus, "empty.sif"), 23 | }, 24 | { 25 | name: "OneGroup", 26 | path: filepath.Join(corpus, "one-group.sif"), 27 | }, 28 | { 29 | name: "OneGroupSignedLegacy", 30 | path: filepath.Join(corpus, "one-group-signed-legacy.sif"), 31 | }, 32 | { 33 | name: "OneGroupSignedLegacyAll", 34 | path: filepath.Join(corpus, "one-group-signed-legacy-all.sif"), 35 | }, 36 | { 37 | name: "OneGroupSignedLegacyGroup", 38 | path: filepath.Join(corpus, "one-group-signed-legacy-group.sif"), 39 | }, 40 | { 41 | name: "OneGroupSignedPGP", 42 | path: filepath.Join(corpus, "one-group-signed-pgp.sif"), 43 | }, 44 | { 45 | name: "TwoGroups", 46 | path: filepath.Join(corpus, "two-groups.sif"), 47 | }, 48 | { 49 | name: "TwoGroupsSignedLegacy", 50 | path: filepath.Join(corpus, "two-groups-signed-legacy.sif"), 51 | }, 52 | { 53 | name: "TwoGroupsSignedLegacyAll", 54 | path: filepath.Join(corpus, "two-groups-signed-legacy-all.sif"), 55 | }, 56 | { 57 | name: "TwoGroupsSignedLegacyGroup", 58 | path: filepath.Join(corpus, "two-groups-signed-legacy-group.sif"), 59 | }, 60 | { 61 | name: "TwoGroupsSignedPGP", 62 | path: filepath.Join(corpus, "two-groups-signed-pgp.sif"), 63 | }, 64 | } 65 | for _, tt := range tests { 66 | t.Run(tt.name, func(t *testing.T) { 67 | c := &command{opts: tt.opts} 68 | 69 | cmd := c.getList() 70 | 71 | runCommand(t, cmd, []string{tt.path}, nil) 72 | }) 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /pkg/siftool/new.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2024, Sylabs Inc. All rights reserved. 2 | // Copyright (c) 2017, SingularityWare, LLC. All rights reserved. 3 | // Copyright (c) 2017, Yannick Cote All rights reserved. 4 | // This software is licensed under a 3-clause BSD license. Please consult the 5 | // LICENSE file distributed with the sources of this project regarding your 6 | // rights to use or distribute this software. 7 | 8 | package siftool 9 | 10 | import ( 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | // getNew returns a command that creates a new, empty SIF image. 15 | func (c *command) getNew() *cobra.Command { 16 | return &cobra.Command{ 17 | Use: "new ", 18 | Short: "Create SIF image", 19 | Long: "Create a new, empty SIF image.", 20 | Example: c.opts.rootPath + " new image.sif", 21 | Args: cobra.ExactArgs(1), 22 | PreRunE: c.initApp, 23 | RunE: func(_ *cobra.Command, args []string) error { 24 | return c.app.New(args[0]) 25 | }, 26 | DisableFlagsInUseLine: true, 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /pkg/siftool/new_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2021-2025, Sylabs Inc. All rights reserved. 2 | // This software is licensed under a 3-clause BSD license. Please consult the 3 | // LICENSE file distributed with the sources of this project regarding your 4 | // rights to use or distribute this software. 5 | 6 | package siftool 7 | 8 | import ( 9 | "path/filepath" 10 | "testing" 11 | ) 12 | 13 | func Test_command_getNew(t *testing.T) { 14 | tests := []struct { 15 | name string 16 | opts commandOpts 17 | }{ 18 | { 19 | name: "OK", 20 | }, 21 | } 22 | for _, tt := range tests { 23 | t.Run(tt.name, func(t *testing.T) { 24 | path := filepath.Join(t.TempDir(), "sif") 25 | 26 | c := &command{opts: tt.opts} 27 | 28 | cmd := c.getNew() 29 | 30 | runCommand(t, cmd, []string{path}, nil) 31 | }) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /pkg/siftool/setprim.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2024, Sylabs Inc. All rights reserved. 2 | // Copyright (c) 2017, SingularityWare, LLC. All rights reserved. 3 | // Copyright (c) 2017, Yannick Cote All rights reserved. 4 | // This software is licensed under a 3-clause BSD license. Please consult the 5 | // LICENSE file distributed with the sources of this project regarding your 6 | // rights to use or distribute this software. 7 | 8 | package siftool 9 | 10 | import ( 11 | "fmt" 12 | "strconv" 13 | 14 | "github.com/spf13/cobra" 15 | ) 16 | 17 | // getSetPrim returns a command that sets the primary system partition. 18 | func (c *command) getSetPrim() *cobra.Command { 19 | return &cobra.Command{ 20 | Use: "setprim ", 21 | Short: "Set primary system partition", 22 | Long: "Set the primary system partition in a SIF image.", 23 | Example: c.opts.rootPath + " setprim 1 image.sif", 24 | Args: cobra.ExactArgs(2), 25 | PreRunE: c.initApp, 26 | RunE: func(_ *cobra.Command, args []string) error { 27 | id, err := strconv.ParseUint(args[0], 10, 32) 28 | if err != nil { 29 | return fmt.Errorf("while converting id: %w", err) 30 | } 31 | 32 | return c.app.Setprim(args[1], uint32(id)) 33 | }, 34 | DisableFlagsInUseLine: true, 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /pkg/siftool/setprim_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2021-2022, Sylabs Inc. All rights reserved. 2 | // This software is licensed under a 3-clause BSD license. Please consult the 3 | // LICENSE file distributed with the sources of this project regarding your 4 | // rights to use or distribute this software. 5 | 6 | package siftool 7 | 8 | import ( 9 | "testing" 10 | ) 11 | 12 | func Test_command_getSetPrim(t *testing.T) { 13 | tests := []struct { 14 | name string 15 | opts commandOpts 16 | }{ 17 | { 18 | name: "OK", 19 | }, 20 | } 21 | for _, tt := range tests { 22 | t.Run(tt.name, func(t *testing.T) { 23 | c := &command{opts: tt.opts} 24 | 25 | cmd := c.getSetPrim() 26 | 27 | runCommand(t, cmd, []string{"1", makeTestSIF(t, true)}, nil) 28 | }) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /pkg/siftool/siftool.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2023, Sylabs Inc. All rights reserved. 2 | // Copyright (c) 2017, SingularityWare, LLC. All rights reserved. 3 | // Copyright (c) 2017, Yannick Cote All rights reserved. 4 | // This software is licensed under a 3-clause BSD license. Please consult the 5 | // LICENSE file distributed with the sources of this project regarding your 6 | // rights to use or distribute this software. 7 | 8 | // Package siftool adds siftool commands to a parent cobra.Command. 9 | package siftool 10 | 11 | import ( 12 | "github.com/spf13/cobra" 13 | "github.com/sylabs/sif/v2/internal/app/siftool" 14 | ) 15 | 16 | // command contains options and command state. 17 | type command struct { 18 | opts commandOpts 19 | app *siftool.App 20 | } 21 | 22 | // initApp initializes the siftool app. 23 | func (c *command) initApp(cmd *cobra.Command, _ []string) error { 24 | app, err := siftool.New( 25 | siftool.OptAppOutput(cmd.OutOrStdout()), 26 | siftool.OptAppError(cmd.ErrOrStderr()), 27 | ) 28 | c.app = app 29 | 30 | return err 31 | } 32 | 33 | // commandOpts contains configured options. 34 | type commandOpts struct { 35 | rootPath string 36 | experimental bool 37 | } 38 | 39 | // CommandOpt are used to configure optional command behavior. 40 | type CommandOpt func(*commandOpts) error 41 | 42 | // OptWithExperimental enables/disables experimental commands. 43 | func OptWithExperimental(b bool) CommandOpt { 44 | return func(co *commandOpts) error { 45 | co.experimental = b 46 | return nil 47 | } 48 | } 49 | 50 | // AddCommands adds siftool commands to cmd according to opts. 51 | // 52 | // A set of commands are provided to display elements such as the SIF global 53 | // header, the data object descriptors and to dump data objects. It is also 54 | // possible to modify a SIF file via this tool via the add/del commands. 55 | func AddCommands(cmd *cobra.Command, opts ...CommandOpt) error { 56 | c := command{ 57 | opts: commandOpts{ 58 | rootPath: cmd.CommandPath(), 59 | }, 60 | } 61 | 62 | for _, opt := range opts { 63 | if err := opt(&c.opts); err != nil { 64 | return err 65 | } 66 | } 67 | 68 | cmd.AddCommand( 69 | c.getHeader(), 70 | c.getList(), 71 | c.getInfo(), 72 | c.getDump(), 73 | c.getNew(), 74 | c.getAdd(), 75 | c.getDel(), 76 | c.getSetPrim(), 77 | ) 78 | 79 | return nil 80 | } 81 | -------------------------------------------------------------------------------- /pkg/siftool/siftool_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2021-2025, Sylabs Inc. All rights reserved. 2 | // This software is licensed under a 3-clause BSD license. Please consult the 3 | // LICENSE file distributed with the sources of this project regarding your 4 | // rights to use or distribute this software. 5 | package siftool 6 | 7 | import ( 8 | "bytes" 9 | "errors" 10 | "path/filepath" 11 | "testing" 12 | 13 | "github.com/sebdah/goldie/v2" 14 | "github.com/spf13/cobra" 15 | "github.com/sylabs/sif/v2/internal/app/siftool" 16 | "github.com/sylabs/sif/v2/pkg/sif" 17 | ) 18 | 19 | var corpus = filepath.Join("..", "..", "test", "images") 20 | 21 | //nolint:thelper // Complex enough to justify keeping file/line information on error. 22 | func makeTestSIF(t *testing.T, withDataObject bool) string { 23 | app, err := siftool.New() 24 | if err != nil { 25 | t.Fatal(err) 26 | } 27 | 28 | path := filepath.Join(t.TempDir(), "sif") 29 | 30 | if err := app.New(path); err != nil { 31 | t.Fatal(err) 32 | } 33 | 34 | if withDataObject { 35 | err := app.Add(path, sif.DataPartition, bytes.NewReader([]byte{0xde, 0xad, 0xbe, 0xef}), 36 | sif.OptPartitionMetadata(sif.FsSquash, sif.PartSystem, "386"), 37 | ) 38 | if err != nil { 39 | t.Fatal(err) 40 | } 41 | } 42 | 43 | return path 44 | } 45 | 46 | //nolint:unparam 47 | func runCommand(t *testing.T, cmd *cobra.Command, args []string, wantErr error) { 48 | t.Helper() 49 | 50 | var out, err bytes.Buffer 51 | cmd.SetOut(&out) 52 | cmd.SetErr(&err) 53 | 54 | cmd.SetArgs(args) 55 | 56 | if got, want := cmd.Execute(), wantErr; !errors.Is(got, want) { 57 | t.Fatalf("got error %v, want %v", got, want) 58 | } 59 | 60 | g := goldie.New(t, 61 | goldie.WithTestNameForDir(true), 62 | goldie.WithSubTestNameForDir(true), 63 | ) 64 | g.Assert(t, "out", out.Bytes()) 65 | g.Assert(t, "err", err.Bytes()) 66 | } 67 | 68 | func TestAddCommands(t *testing.T) { 69 | tests := []struct { 70 | name string 71 | opts []CommandOpt 72 | args []string 73 | }{ 74 | { 75 | name: "SifTool", 76 | args: []string{"help"}, 77 | }, 78 | { 79 | name: "SifToolExperimental", 80 | opts: []CommandOpt{OptWithExperimental(true)}, 81 | args: []string{"help"}, 82 | }, 83 | { 84 | name: "Add", 85 | args: []string{"help", "add"}, 86 | }, 87 | { 88 | name: "Del", 89 | args: []string{"help", "del"}, 90 | }, 91 | { 92 | name: "Dump", 93 | args: []string{"help", "dump"}, 94 | }, 95 | { 96 | name: "Header", 97 | args: []string{"help", "header"}, 98 | }, 99 | { 100 | name: "Info", 101 | args: []string{"help", "info"}, 102 | }, 103 | { 104 | name: "List", 105 | args: []string{"help", "list"}, 106 | }, 107 | { 108 | name: "New", 109 | args: []string{"help", "new"}, 110 | }, 111 | { 112 | name: "SetPrim", 113 | args: []string{"help", "setprim"}, 114 | }, 115 | } 116 | for _, tt := range tests { 117 | t.Run(tt.name, func(t *testing.T) { 118 | cmd := &cobra.Command{ 119 | Use: "siftool", 120 | } 121 | 122 | if err := AddCommands(cmd, tt.opts...); err != nil { 123 | t.Fatal(err) 124 | } 125 | 126 | runCommand(t, cmd, tt.args, nil) 127 | }) 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /pkg/siftool/testdata/TestAddCommands/Add/err.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/siftool/testdata/TestAddCommands/Add/err.golden -------------------------------------------------------------------------------- /pkg/siftool/testdata/TestAddCommands/Add/out.golden: -------------------------------------------------------------------------------- 1 | Add a data object to a SIF image. 2 | 3 | Usage: 4 | siftool add [flags] 5 | 6 | Examples: 7 | siftool add image.sif recipe.def --datatype 1 8 | siftool add image.sif rootfs.squashfs --datatype 4 --parttype 1 --partfs 1 --partarch 2 9 | siftool add image.sif signature.bin --datatype 5 --signentity 433FE984155206BD962725E20E8713472A879943 --signhash 1 10 | 11 | Flags: 12 | --alignment int set alignment [default: 4096 with --datatype 4-Partition, 0 otherwise] 13 | --datatype int the type of data to add 14 | [NEEDED, no default]: 15 | 1-Deffile, 2-EnvVar, 3-Labels, 16 | 4-Partition, 5-Signature, 6-GenericJSON, 17 | 7-Generic, 8-CryptoMessage, 9-SBOM, 18 | 10-OCI.RootIndex, 11-OCI.Blob 19 | --filename string set logical filename/handle [default: input filename] 20 | --groupid uint32 set groupid [default: 0] 21 | -h, --help help for add 22 | --link uint32 set link pointer [default: 0] 23 | --partarch int32 the main architecture used (with --datatype 4-Partition) 24 | [NEEDED, no default]: 25 | 1-386, 2-amd64, 3-arm, 26 | 4-arm64, 5-ppc64, 6-ppc64le, 27 | 7-mips, 8-mipsle, 9-mips64, 28 | 10-mips64le, 11-s390x, 12-riscv64 29 | --partfs int32 the filesystem used (with --datatype 4-Partition) 30 | [NEEDED, no default]: 31 | 1-Squash, 2-Ext3, 3-ImmuObj, 32 | 4-Raw 33 | --parttype int32 the type of partition (with --datatype 4-Partition) 34 | [NEEDED, no default]: 35 | 1-System, 2-PrimSys, 3-Data, 36 | 4-Overlay 37 | --sbomformat string the SBOM format (with --datatype 9-sbom): 38 | cyclonedx-json, cyclonedx-xml, github-json, 39 | spdx-json, spdx-rdf, spdx-tag-value, 40 | spdx-yaml, syft-json 41 | --signentity string the entity that signs (with --datatype 5-Signature) 42 | [NEEDED, no default]: 43 | example: 433FE984155206BD962725E20E8713472A879943 44 | --signhash int32 the signature hash used (with --datatype 5-Signature) 45 | [NEEDED, no default]: 46 | 1-SHA256, 2-SHA384, 3-SHA512, 47 | 4-BLAKE2s_256, 5-BLAKE2b_256 48 | -------------------------------------------------------------------------------- /pkg/siftool/testdata/TestAddCommands/Del/err.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/siftool/testdata/TestAddCommands/Del/err.golden -------------------------------------------------------------------------------- /pkg/siftool/testdata/TestAddCommands/Del/out.golden: -------------------------------------------------------------------------------- 1 | Delete a data object from a SIF image. 2 | 3 | Usage: 4 | siftool del 5 | 6 | Examples: 7 | siftool del 1 image.sif 8 | 9 | Flags: 10 | -h, --help help for del 11 | -------------------------------------------------------------------------------- /pkg/siftool/testdata/TestAddCommands/Dump/err.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/siftool/testdata/TestAddCommands/Dump/err.golden -------------------------------------------------------------------------------- /pkg/siftool/testdata/TestAddCommands/Dump/out.golden: -------------------------------------------------------------------------------- 1 | Dump a data object from a SIF image. 2 | 3 | Usage: 4 | siftool dump 5 | 6 | Examples: 7 | siftool dump 1 image.sif 8 | 9 | Flags: 10 | -h, --help help for dump 11 | -------------------------------------------------------------------------------- /pkg/siftool/testdata/TestAddCommands/Header/err.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/siftool/testdata/TestAddCommands/Header/err.golden -------------------------------------------------------------------------------- /pkg/siftool/testdata/TestAddCommands/Header/out.golden: -------------------------------------------------------------------------------- 1 | Display global header from a SIF image. 2 | 3 | Usage: 4 | siftool header 5 | 6 | Examples: 7 | siftool header image.sif 8 | 9 | Flags: 10 | -h, --help help for header 11 | -------------------------------------------------------------------------------- /pkg/siftool/testdata/TestAddCommands/Info/err.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/siftool/testdata/TestAddCommands/Info/err.golden -------------------------------------------------------------------------------- /pkg/siftool/testdata/TestAddCommands/Info/out.golden: -------------------------------------------------------------------------------- 1 | Display info about a data object from a SIF image. 2 | 3 | Usage: 4 | siftool info 5 | 6 | Examples: 7 | siftool info 1 image.sif 8 | 9 | Flags: 10 | -h, --help help for info 11 | -------------------------------------------------------------------------------- /pkg/siftool/testdata/TestAddCommands/List/err.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/siftool/testdata/TestAddCommands/List/err.golden -------------------------------------------------------------------------------- /pkg/siftool/testdata/TestAddCommands/List/out.golden: -------------------------------------------------------------------------------- 1 | List data objects from a SIF image. 2 | 3 | Usage: 4 | siftool list 5 | 6 | Examples: 7 | siftool list image.sif 8 | 9 | Flags: 10 | -h, --help help for list 11 | -------------------------------------------------------------------------------- /pkg/siftool/testdata/TestAddCommands/New/err.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/siftool/testdata/TestAddCommands/New/err.golden -------------------------------------------------------------------------------- /pkg/siftool/testdata/TestAddCommands/New/out.golden: -------------------------------------------------------------------------------- 1 | Create a new, empty SIF image. 2 | 3 | Usage: 4 | siftool new 5 | 6 | Examples: 7 | siftool new image.sif 8 | 9 | Flags: 10 | -h, --help help for new 11 | -------------------------------------------------------------------------------- /pkg/siftool/testdata/TestAddCommands/SetPrim/err.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/siftool/testdata/TestAddCommands/SetPrim/err.golden -------------------------------------------------------------------------------- /pkg/siftool/testdata/TestAddCommands/SetPrim/out.golden: -------------------------------------------------------------------------------- 1 | Set the primary system partition in a SIF image. 2 | 3 | Usage: 4 | siftool setprim 5 | 6 | Examples: 7 | siftool setprim 1 image.sif 8 | 9 | Flags: 10 | -h, --help help for setprim 11 | -------------------------------------------------------------------------------- /pkg/siftool/testdata/TestAddCommands/SifTool/err.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/siftool/testdata/TestAddCommands/SifTool/err.golden -------------------------------------------------------------------------------- /pkg/siftool/testdata/TestAddCommands/SifTool/out.golden: -------------------------------------------------------------------------------- 1 | Usage: 2 | siftool [command] 3 | 4 | Available Commands: 5 | add Add data object 6 | completion Generate the autocompletion script for the specified shell 7 | del Delete data object 8 | dump Dump data object 9 | header Display global header 10 | help Help about any command 11 | info Display data object info 12 | list List data objects 13 | new Create SIF image 14 | setprim Set primary system partition 15 | 16 | Flags: 17 | -h, --help help for siftool 18 | 19 | Use "siftool [command] --help" for more information about a command. 20 | -------------------------------------------------------------------------------- /pkg/siftool/testdata/TestAddCommands/SifToolExperimental/err.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/siftool/testdata/TestAddCommands/SifToolExperimental/err.golden -------------------------------------------------------------------------------- /pkg/siftool/testdata/TestAddCommands/SifToolExperimental/out.golden: -------------------------------------------------------------------------------- 1 | Usage: 2 | siftool [command] 3 | 4 | Available Commands: 5 | add Add data object 6 | completion Generate the autocompletion script for the specified shell 7 | del Delete data object 8 | dump Dump data object 9 | header Display global header 10 | help Help about any command 11 | info Display data object info 12 | list List data objects 13 | new Create SIF image 14 | setprim Set primary system partition 15 | 16 | Flags: 17 | -h, --help help for siftool 18 | 19 | Use "siftool [command] --help" for more information about a command. 20 | -------------------------------------------------------------------------------- /pkg/siftool/testdata/Test_command_getAdd/DataOCIBlob/err.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/siftool/testdata/Test_command_getAdd/DataOCIBlob/err.golden -------------------------------------------------------------------------------- /pkg/siftool/testdata/Test_command_getAdd/DataOCIBlob/out.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/siftool/testdata/Test_command_getAdd/DataOCIBlob/out.golden -------------------------------------------------------------------------------- /pkg/siftool/testdata/Test_command_getAdd/DataOCIRootIndex/err.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/siftool/testdata/Test_command_getAdd/DataOCIRootIndex/err.golden -------------------------------------------------------------------------------- /pkg/siftool/testdata/Test_command_getAdd/DataOCIRootIndex/out.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/siftool/testdata/Test_command_getAdd/DataOCIRootIndex/out.golden -------------------------------------------------------------------------------- /pkg/siftool/testdata/Test_command_getAdd/DataPartition/err.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/siftool/testdata/Test_command_getAdd/DataPartition/err.golden -------------------------------------------------------------------------------- /pkg/siftool/testdata/Test_command_getAdd/DataPartition/out.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/siftool/testdata/Test_command_getAdd/DataPartition/out.golden -------------------------------------------------------------------------------- /pkg/siftool/testdata/Test_command_getAdd/DataSignature/err.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/siftool/testdata/Test_command_getAdd/DataSignature/err.golden -------------------------------------------------------------------------------- /pkg/siftool/testdata/Test_command_getAdd/DataSignature/out.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/siftool/testdata/Test_command_getAdd/DataSignature/out.golden -------------------------------------------------------------------------------- /pkg/siftool/testdata/Test_command_getDel/OK/err.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/siftool/testdata/Test_command_getDel/OK/err.golden -------------------------------------------------------------------------------- /pkg/siftool/testdata/Test_command_getDel/OK/out.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/siftool/testdata/Test_command_getDel/OK/out.golden -------------------------------------------------------------------------------- /pkg/siftool/testdata/Test_command_getDump/One/err.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/siftool/testdata/Test_command_getDump/One/err.golden -------------------------------------------------------------------------------- /pkg/siftool/testdata/Test_command_getDump/One/out.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/siftool/testdata/Test_command_getDump/One/out.golden -------------------------------------------------------------------------------- /pkg/siftool/testdata/Test_command_getDump/Two/err.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/siftool/testdata/Test_command_getDump/Two/err.golden -------------------------------------------------------------------------------- /pkg/siftool/testdata/Test_command_getDump/Two/out.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/siftool/testdata/Test_command_getDump/Two/out.golden -------------------------------------------------------------------------------- /pkg/siftool/testdata/Test_command_getHeader/Empty/err.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/siftool/testdata/Test_command_getHeader/Empty/err.golden -------------------------------------------------------------------------------- /pkg/siftool/testdata/Test_command_getHeader/Empty/out.golden: -------------------------------------------------------------------------------- 1 | Version: 01 2 | Descriptors Free: 48 3 | Descriptors Total: 48 4 | Descriptors Offset: 4096 5 | Descriptors Size: 27 KiB 6 | Data Offset: 32176 7 | Data Size: 0 B 8 | -------------------------------------------------------------------------------- /pkg/siftool/testdata/Test_command_getHeader/OneGroup/err.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/siftool/testdata/Test_command_getHeader/OneGroup/err.golden -------------------------------------------------------------------------------- /pkg/siftool/testdata/Test_command_getHeader/OneGroup/out.golden: -------------------------------------------------------------------------------- 1 | Version: 01 2 | Primary Architecture: 386 3 | Descriptors Free: 46 4 | Descriptors Total: 48 5 | Descriptors Offset: 4096 6 | Descriptors Size: 27 KiB 7 | Data Offset: 32176 8 | Data Size: 9 KiB 9 | -------------------------------------------------------------------------------- /pkg/siftool/testdata/Test_command_getHeader/OneGroupSignedLegacy/err.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/siftool/testdata/Test_command_getHeader/OneGroupSignedLegacy/err.golden -------------------------------------------------------------------------------- /pkg/siftool/testdata/Test_command_getHeader/OneGroupSignedLegacy/out.golden: -------------------------------------------------------------------------------- 1 | Launch Script: #!/usr/bin/env run-singularity 2 | Version: 01 3 | Primary Architecture: 386 4 | ID: 6ecc76b7-a497-4f7f-9ebd-8da2a04c6be1 5 | Created At: 2020-05-22 19:30:59 +0000 UTC 6 | Modified At: 2020-06-20 20:16:39 +0000 UTC 7 | Descriptors Free: 45 8 | Descriptors Total: 48 9 | Descriptors Offset: 4096 10 | Descriptors Size: 27 KiB 11 | Data Offset: 32768 12 | Data Size: 9 KiB 13 | -------------------------------------------------------------------------------- /pkg/siftool/testdata/Test_command_getHeader/OneGroupSignedLegacyAll/err.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/siftool/testdata/Test_command_getHeader/OneGroupSignedLegacyAll/err.golden -------------------------------------------------------------------------------- /pkg/siftool/testdata/Test_command_getHeader/OneGroupSignedLegacyAll/out.golden: -------------------------------------------------------------------------------- 1 | Launch Script: #!/usr/bin/env run-singularity 2 | Version: 01 3 | Primary Architecture: 386 4 | ID: 6ecc76b7-a497-4f7f-9ebd-8da2a04c6be1 5 | Created At: 2020-05-22 19:30:59 +0000 UTC 6 | Modified At: 2020-06-20 20:17:15 +0000 UTC 7 | Descriptors Free: 44 8 | Descriptors Total: 48 9 | Descriptors Offset: 4096 10 | Descriptors Size: 27 KiB 11 | Data Offset: 32768 12 | Data Size: 13 KiB 13 | -------------------------------------------------------------------------------- /pkg/siftool/testdata/Test_command_getHeader/OneGroupSignedLegacyGroup/err.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/siftool/testdata/Test_command_getHeader/OneGroupSignedLegacyGroup/err.golden -------------------------------------------------------------------------------- /pkg/siftool/testdata/Test_command_getHeader/OneGroupSignedLegacyGroup/out.golden: -------------------------------------------------------------------------------- 1 | Launch Script: #!/usr/bin/env run-singularity 2 | Version: 01 3 | Primary Architecture: 386 4 | ID: 6ecc76b7-a497-4f7f-9ebd-8da2a04c6be1 5 | Created At: 2020-05-22 19:30:59 +0000 UTC 6 | Modified At: 2020-06-20 20:16:55 +0000 UTC 7 | Descriptors Free: 45 8 | Descriptors Total: 48 9 | Descriptors Offset: 4096 10 | Descriptors Size: 27 KiB 11 | Data Offset: 32768 12 | Data Size: 9 KiB 13 | -------------------------------------------------------------------------------- /pkg/siftool/testdata/Test_command_getHeader/OneGroupSignedPGP/err.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/siftool/testdata/Test_command_getHeader/OneGroupSignedPGP/err.golden -------------------------------------------------------------------------------- /pkg/siftool/testdata/Test_command_getHeader/OneGroupSignedPGP/out.golden: -------------------------------------------------------------------------------- 1 | Version: 01 2 | Primary Architecture: 386 3 | Descriptors Free: 45 4 | Descriptors Total: 48 5 | Descriptors Offset: 4096 6 | Descriptors Size: 27 KiB 7 | Data Offset: 32176 8 | Data Size: 10 KiB 9 | -------------------------------------------------------------------------------- /pkg/siftool/testdata/Test_command_getHeader/TwoGroups/err.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/siftool/testdata/Test_command_getHeader/TwoGroups/err.golden -------------------------------------------------------------------------------- /pkg/siftool/testdata/Test_command_getHeader/TwoGroups/out.golden: -------------------------------------------------------------------------------- 1 | Version: 01 2 | Primary Architecture: 386 3 | Descriptors Free: 45 4 | Descriptors Total: 48 5 | Descriptors Offset: 4096 6 | Descriptors Size: 27 KiB 7 | Data Offset: 32176 8 | Data Size: 265 KiB 9 | -------------------------------------------------------------------------------- /pkg/siftool/testdata/Test_command_getHeader/TwoGroupsSignedLegacy/err.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/siftool/testdata/Test_command_getHeader/TwoGroupsSignedLegacy/err.golden -------------------------------------------------------------------------------- /pkg/siftool/testdata/Test_command_getHeader/TwoGroupsSignedLegacy/out.golden: -------------------------------------------------------------------------------- 1 | Launch Script: #!/usr/bin/env run-singularity 2 | Version: 01 3 | Primary Architecture: 386 4 | ID: 0b19ec2c-0b08-46c9-95ae-fa88cd9e48a1 5 | Created At: 2020-05-22 19:30:59 +0000 UTC 6 | Modified At: 2020-06-20 20:16:44 +0000 UTC 7 | Descriptors Free: 44 8 | Descriptors Total: 48 9 | Descriptors Offset: 4096 10 | Descriptors Size: 27 KiB 11 | Data Offset: 32768 12 | Data Size: 13 KiB 13 | -------------------------------------------------------------------------------- /pkg/siftool/testdata/Test_command_getHeader/TwoGroupsSignedLegacyAll/err.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/siftool/testdata/Test_command_getHeader/TwoGroupsSignedLegacyAll/err.golden -------------------------------------------------------------------------------- /pkg/siftool/testdata/Test_command_getHeader/TwoGroupsSignedLegacyAll/out.golden: -------------------------------------------------------------------------------- 1 | Launch Script: #!/usr/bin/env run-singularity 2 | Version: 01 3 | Primary Architecture: 386 4 | ID: 0b19ec2c-0b08-46c9-95ae-fa88cd9e48a1 5 | Created At: 2020-05-22 19:30:59 +0000 UTC 6 | Modified At: 2020-06-20 20:17:19 +0000 UTC 7 | Descriptors Free: 43 8 | Descriptors Total: 48 9 | Descriptors Offset: 4096 10 | Descriptors Size: 27 KiB 11 | Data Offset: 32768 12 | Data Size: 17 KiB 13 | -------------------------------------------------------------------------------- /pkg/siftool/testdata/Test_command_getHeader/TwoGroupsSignedLegacyGroup/err.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/siftool/testdata/Test_command_getHeader/TwoGroupsSignedLegacyGroup/err.golden -------------------------------------------------------------------------------- /pkg/siftool/testdata/Test_command_getHeader/TwoGroupsSignedLegacyGroup/out.golden: -------------------------------------------------------------------------------- 1 | Launch Script: #!/usr/bin/env run-singularity 2 | Version: 01 3 | Primary Architecture: 386 4 | ID: 0b19ec2c-0b08-46c9-95ae-fa88cd9e48a1 5 | Created At: 2020-05-22 19:30:59 +0000 UTC 6 | Modified At: 2020-06-20 20:16:58 +0000 UTC 7 | Descriptors Free: 44 8 | Descriptors Total: 48 9 | Descriptors Offset: 4096 10 | Descriptors Size: 27 KiB 11 | Data Offset: 32768 12 | Data Size: 13 KiB 13 | -------------------------------------------------------------------------------- /pkg/siftool/testdata/Test_command_getHeader/TwoGroupsSignedPGP/err.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/siftool/testdata/Test_command_getHeader/TwoGroupsSignedPGP/err.golden -------------------------------------------------------------------------------- /pkg/siftool/testdata/Test_command_getHeader/TwoGroupsSignedPGP/out.golden: -------------------------------------------------------------------------------- 1 | Version: 01 2 | Primary Architecture: 386 3 | Descriptors Free: 43 4 | Descriptors Total: 48 5 | Descriptors Offset: 4096 6 | Descriptors Size: 27 KiB 7 | Data Offset: 32176 8 | Data Size: 266 KiB 9 | -------------------------------------------------------------------------------- /pkg/siftool/testdata/Test_command_getInfo/One/err.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/siftool/testdata/Test_command_getInfo/One/err.golden -------------------------------------------------------------------------------- /pkg/siftool/testdata/Test_command_getInfo/One/out.golden: -------------------------------------------------------------------------------- 1 | Data Type: FS 2 | ID: 1 3 | Group ID: 1 4 | Linked ID: NONE 5 | Offset: 32768 6 | Size: 4 7 | Filesystem Type: Raw 8 | Partition Type: System 9 | Architecture: 386 10 | -------------------------------------------------------------------------------- /pkg/siftool/testdata/Test_command_getInfo/Three/err.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/siftool/testdata/Test_command_getInfo/Three/err.golden -------------------------------------------------------------------------------- /pkg/siftool/testdata/Test_command_getInfo/Three/out.golden: -------------------------------------------------------------------------------- 1 | Data Type: Signature 2 | ID: 3 3 | Group ID: NONE 4 | Linked ID: 1 (G) 5 | Offset: 40960 6 | Size: 1048 7 | Hash Type: SHA-256 8 | Entity: 12045C8C0B1004D058DE4BEDA20C27EE7FF7BA84 9 | -------------------------------------------------------------------------------- /pkg/siftool/testdata/Test_command_getInfo/Two/err.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/siftool/testdata/Test_command_getInfo/Two/err.golden -------------------------------------------------------------------------------- /pkg/siftool/testdata/Test_command_getInfo/Two/out.golden: -------------------------------------------------------------------------------- 1 | Data Type: FS 2 | ID: 2 3 | Group ID: 1 4 | Linked ID: NONE 5 | Offset: 36864 6 | Size: 4096 7 | Filesystem Type: Squashfs 8 | Partition Type: *System 9 | Architecture: 386 10 | -------------------------------------------------------------------------------- /pkg/siftool/testdata/Test_command_getList/Empty/err.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/siftool/testdata/Test_command_getList/Empty/err.golden -------------------------------------------------------------------------------- /pkg/siftool/testdata/Test_command_getList/Empty/out.golden: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------ 2 | ID |GROUP |LINK |SIF POSITION (start-end) |TYPE 3 | ------------------------------------------------------------------------------ 4 | -------------------------------------------------------------------------------- /pkg/siftool/testdata/Test_command_getList/OneGroup/err.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/siftool/testdata/Test_command_getList/OneGroup/err.golden -------------------------------------------------------------------------------- /pkg/siftool/testdata/Test_command_getList/OneGroup/out.golden: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------ 2 | ID |GROUP |LINK |SIF POSITION (start-end) |TYPE 3 | ------------------------------------------------------------------------------ 4 | 1 |1 |NONE |32768-32772 |FS (Raw/System/386) 5 | 2 |1 |NONE |36864-40960 |FS (Squashfs/*System/386) 6 | -------------------------------------------------------------------------------- /pkg/siftool/testdata/Test_command_getList/OneGroupSignedLegacy/err.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/siftool/testdata/Test_command_getList/OneGroupSignedLegacy/err.golden -------------------------------------------------------------------------------- /pkg/siftool/testdata/Test_command_getList/OneGroupSignedLegacy/out.golden: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------ 2 | ID |GROUP |LINK |SIF POSITION (start-end) |TYPE 3 | ------------------------------------------------------------------------------ 4 | 1 |1 |NONE |32768-32772 |FS (Raw/System/386) 5 | 2 |1 |NONE |36864-36868 |FS (Squashfs/*System/386) 6 | 3 |1 |2 |40960-41569 |Signature (SHA-384) 7 | -------------------------------------------------------------------------------- /pkg/siftool/testdata/Test_command_getList/OneGroupSignedLegacyAll/err.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/siftool/testdata/Test_command_getList/OneGroupSignedLegacyAll/err.golden -------------------------------------------------------------------------------- /pkg/siftool/testdata/Test_command_getList/OneGroupSignedLegacyAll/out.golden: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------ 2 | ID |GROUP |LINK |SIF POSITION (start-end) |TYPE 3 | ------------------------------------------------------------------------------ 4 | 1 |1 |NONE |32768-32772 |FS (Raw/System/386) 5 | 2 |1 |NONE |36864-36868 |FS (Squashfs/*System/386) 6 | 3 |1 |1 |40960-41569 |Signature (SHA-384) 7 | 4 |1 |2 |45056-45665 |Signature (SHA-384) 8 | -------------------------------------------------------------------------------- /pkg/siftool/testdata/Test_command_getList/OneGroupSignedLegacyGroup/err.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/siftool/testdata/Test_command_getList/OneGroupSignedLegacyGroup/err.golden -------------------------------------------------------------------------------- /pkg/siftool/testdata/Test_command_getList/OneGroupSignedLegacyGroup/out.golden: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------ 2 | ID |GROUP |LINK |SIF POSITION (start-end) |TYPE 3 | ------------------------------------------------------------------------------ 4 | 1 |1 |NONE |32768-32772 |FS (Raw/System/386) 5 | 2 |1 |NONE |36864-36868 |FS (Squashfs/*System/386) 6 | 3 |NONE |1 (G) |40960-41569 |Signature (SHA-384) 7 | -------------------------------------------------------------------------------- /pkg/siftool/testdata/Test_command_getList/OneGroupSignedPGP/err.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/siftool/testdata/Test_command_getList/OneGroupSignedPGP/err.golden -------------------------------------------------------------------------------- /pkg/siftool/testdata/Test_command_getList/OneGroupSignedPGP/out.golden: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------ 2 | ID |GROUP |LINK |SIF POSITION (start-end) |TYPE 3 | ------------------------------------------------------------------------------ 4 | 1 |1 |NONE |32768-32772 |FS (Raw/System/386) 5 | 2 |1 |NONE |36864-40960 |FS (Squashfs/*System/386) 6 | 3 |NONE |1 (G) |40960-42008 |Signature (SHA-256) 7 | -------------------------------------------------------------------------------- /pkg/siftool/testdata/Test_command_getList/TwoGroups/err.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/siftool/testdata/Test_command_getList/TwoGroups/err.golden -------------------------------------------------------------------------------- /pkg/siftool/testdata/Test_command_getList/TwoGroups/out.golden: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------ 2 | ID |GROUP |LINK |SIF POSITION (start-end) |TYPE 3 | ------------------------------------------------------------------------------ 4 | 1 |1 |NONE |32768-32772 |FS (Raw/System/386) 5 | 2 |1 |NONE |36864-40960 |FS (Squashfs/*System/386) 6 | 3 |2 |NONE |40960-303104 |FS (Ext3/System/amd64) 7 | -------------------------------------------------------------------------------- /pkg/siftool/testdata/Test_command_getList/TwoGroupsSignedLegacy/err.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/siftool/testdata/Test_command_getList/TwoGroupsSignedLegacy/err.golden -------------------------------------------------------------------------------- /pkg/siftool/testdata/Test_command_getList/TwoGroupsSignedLegacy/out.golden: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------ 2 | ID |GROUP |LINK |SIF POSITION (start-end) |TYPE 3 | ------------------------------------------------------------------------------ 4 | 1 |1 |NONE |32768-32772 |FS (Raw/System/386) 5 | 2 |1 |NONE |36864-36868 |FS (Squashfs/*System/386) 6 | 3 |2 |NONE |40960-40964 |FS (Ext3/System/amd64) 7 | 4 |1 |2 |45056-45665 |Signature (SHA-384) 8 | -------------------------------------------------------------------------------- /pkg/siftool/testdata/Test_command_getList/TwoGroupsSignedLegacyAll/err.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/siftool/testdata/Test_command_getList/TwoGroupsSignedLegacyAll/err.golden -------------------------------------------------------------------------------- /pkg/siftool/testdata/Test_command_getList/TwoGroupsSignedLegacyAll/out.golden: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------ 2 | ID |GROUP |LINK |SIF POSITION (start-end) |TYPE 3 | ------------------------------------------------------------------------------ 4 | 1 |1 |NONE |32768-32772 |FS (Raw/System/386) 5 | 2 |1 |NONE |36864-36868 |FS (Squashfs/*System/386) 6 | 3 |2 |NONE |40960-40964 |FS (Ext3/System/amd64) 7 | 4 |1 |1 |45056-45665 |Signature (SHA-384) 8 | 5 |1 |2 |49152-49761 |Signature (SHA-384) 9 | -------------------------------------------------------------------------------- /pkg/siftool/testdata/Test_command_getList/TwoGroupsSignedLegacyGroup/err.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/siftool/testdata/Test_command_getList/TwoGroupsSignedLegacyGroup/err.golden -------------------------------------------------------------------------------- /pkg/siftool/testdata/Test_command_getList/TwoGroupsSignedLegacyGroup/out.golden: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------ 2 | ID |GROUP |LINK |SIF POSITION (start-end) |TYPE 3 | ------------------------------------------------------------------------------ 4 | 1 |1 |NONE |32768-32772 |FS (Raw/System/386) 5 | 2 |1 |NONE |36864-36868 |FS (Squashfs/*System/386) 6 | 3 |2 |NONE |40960-40964 |FS (Ext3/System/amd64) 7 | 4 |NONE |1 (G) |45056-45665 |Signature (SHA-384) 8 | -------------------------------------------------------------------------------- /pkg/siftool/testdata/Test_command_getList/TwoGroupsSignedPGP/err.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/siftool/testdata/Test_command_getList/TwoGroupsSignedPGP/err.golden -------------------------------------------------------------------------------- /pkg/siftool/testdata/Test_command_getList/TwoGroupsSignedPGP/out.golden: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------ 2 | ID |GROUP |LINK |SIF POSITION (start-end) |TYPE 3 | ------------------------------------------------------------------------------ 4 | 1 |1 |NONE |32768-32772 |FS (Raw/System/386) 5 | 2 |1 |NONE |36864-40960 |FS (Squashfs/*System/386) 6 | 3 |2 |NONE |40960-303104 |FS (Ext3/System/amd64) 7 | 4 |NONE |1 (G) |303104-304152 |Signature (SHA-256) 8 | 5 |NONE |2 (G) |304152-305001 |Signature (SHA-256) 9 | -------------------------------------------------------------------------------- /pkg/siftool/testdata/Test_command_getNew/OK/err.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/siftool/testdata/Test_command_getNew/OK/err.golden -------------------------------------------------------------------------------- /pkg/siftool/testdata/Test_command_getNew/OK/out.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/siftool/testdata/Test_command_getNew/OK/out.golden -------------------------------------------------------------------------------- /pkg/siftool/testdata/Test_command_getSetPrim/OK/err.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/siftool/testdata/Test_command_getSetPrim/OK/err.golden -------------------------------------------------------------------------------- /pkg/siftool/testdata/Test_command_getSetPrim/OK/out.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/siftool/testdata/Test_command_getSetPrim/OK/out.golden -------------------------------------------------------------------------------- /pkg/siftool/testdata/input/input.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/pkg/siftool/testdata/input/input.bin -------------------------------------------------------------------------------- /pkg/user/mount.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022-2023, Sylabs Inc. All rights reserved. 2 | // This software is licensed under a 3-clause BSD license. Please consult the 3 | // LICENSE file distributed with the sources of this project regarding your 4 | // rights to use or distribute this software. 5 | 6 | // Deprecated: this package will be removed in a future version. 7 | package user 8 | 9 | import ( 10 | "context" 11 | "errors" 12 | "fmt" 13 | "io" 14 | "os" 15 | "os/exec" 16 | "path/filepath" 17 | 18 | "github.com/sylabs/sif/v2/pkg/sif" 19 | ) 20 | 21 | // mountSquashFS mounts the SquashFS filesystem from path at offset into mountPath. 22 | func mountSquashFS(ctx context.Context, offset int64, path, mountPath string, mo mountOpts) error { 23 | args := []string{ 24 | "-o", fmt.Sprintf("ro,offset=%d", offset), 25 | filepath.Clean(path), 26 | filepath.Clean(mountPath), 27 | } 28 | //nolint:gosec // note (gosec exclusion) - we require callers to be able to specify squashfuse not on PATH 29 | cmd := exec.CommandContext(ctx, mo.squashfusePath, args...) 30 | cmd.Stdout = mo.stdout 31 | cmd.Stderr = mo.stderr 32 | 33 | if err := cmd.Run(); err != nil { 34 | return fmt.Errorf("failed to mount: %w", err) 35 | } 36 | 37 | return nil 38 | } 39 | 40 | // mountOpts accumulates mount options. 41 | type mountOpts struct { 42 | stdout io.Writer 43 | stderr io.Writer 44 | squashfusePath string 45 | } 46 | 47 | // MountOpt are used to specify mount options. 48 | type MountOpt func(*mountOpts) error 49 | 50 | // OptMountStdout writes standard output to w. 51 | func OptMountStdout(w io.Writer) MountOpt { 52 | return func(mo *mountOpts) error { 53 | mo.stdout = w 54 | return nil 55 | } 56 | } 57 | 58 | // OptMountStderr writes standard error to w. 59 | func OptMountStderr(w io.Writer) MountOpt { 60 | return func(mo *mountOpts) error { 61 | mo.stderr = w 62 | return nil 63 | } 64 | } 65 | 66 | var errSquashfusePathInvalid = errors.New("squashfuse path must be relative or absolute") 67 | 68 | // OptMountSquashfusePath sets an explicit path to the squashfuse binary. The path must be an 69 | // absolute or relative path. 70 | func OptMountSquashfusePath(path string) MountOpt { 71 | return func(mo *mountOpts) error { 72 | if filepath.Base(path) == path { 73 | return errSquashfusePathInvalid 74 | } 75 | mo.squashfusePath = path 76 | return nil 77 | } 78 | } 79 | 80 | var errUnsupportedFSType = errors.New("unrecognized filesystem type") 81 | 82 | // Mount mounts the primary system partition of the SIF file at path into mountPath. 83 | // 84 | // Mount may start one or more underlying processes. By default, stdout and stderr of these 85 | // processes is discarded. To modify this behavior, consider using OptMountStdout and/or 86 | // OptMountStderr. 87 | // 88 | // By default, Mount searches for a squashfuse binary in the directories named by the PATH 89 | // environment variable. To override this behavior, consider using OptMountSquashfusePath(). 90 | func Mount(ctx context.Context, path, mountPath string, opts ...MountOpt) error { 91 | mo := mountOpts{ 92 | squashfusePath: "squashfuse", 93 | } 94 | 95 | for _, opt := range opts { 96 | if err := opt(&mo); err != nil { 97 | return fmt.Errorf("%w", err) 98 | } 99 | } 100 | 101 | f, err := sif.LoadContainerFromPath(path, sif.OptLoadWithFlag(os.O_RDONLY)) 102 | if err != nil { 103 | return fmt.Errorf("failed to load image: %w", err) 104 | } 105 | defer func() { _ = f.UnloadContainer() }() 106 | 107 | d, err := f.GetDescriptor(sif.WithPartitionType(sif.PartPrimSys)) 108 | if err != nil { 109 | return fmt.Errorf("failed to get partition descriptor: %w", err) 110 | } 111 | 112 | fs, _, _, err := d.PartitionMetadata() 113 | if err != nil { 114 | return fmt.Errorf("failed to get partition metadata: %w", err) 115 | } 116 | 117 | switch fs { 118 | case sif.FsSquash: 119 | return mountSquashFS(ctx, d.Offset(), path, mountPath, mo) 120 | default: 121 | return errUnsupportedFSType 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /pkg/user/unmount.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022, Sylabs Inc. All rights reserved. 2 | // This software is licensed under a 3-clause BSD license. Please consult the 3 | // LICENSE file distributed with the sources of this project regarding your 4 | // rights to use or distribute this software. 5 | 6 | package user 7 | 8 | import ( 9 | "context" 10 | "errors" 11 | "fmt" 12 | "io" 13 | "os/exec" 14 | "path/filepath" 15 | ) 16 | 17 | // unmountSquashFS unmounts the filesystem at mountPath. 18 | func unmountSquashFS(ctx context.Context, mountPath string, uo unmountOpts) error { 19 | args := []string{ 20 | "-u", 21 | filepath.Clean(mountPath), 22 | } 23 | cmd := exec.CommandContext(ctx, uo.fusermountPath, args...) //nolint:gosec 24 | cmd.Stdout = uo.stdout 25 | cmd.Stderr = uo.stderr 26 | 27 | if err := cmd.Run(); err != nil { 28 | return fmt.Errorf("failed to unmount: %w", err) 29 | } 30 | 31 | return nil 32 | } 33 | 34 | // unmountOpts accumulates unmount options. 35 | type unmountOpts struct { 36 | stdout io.Writer 37 | stderr io.Writer 38 | fusermountPath string 39 | } 40 | 41 | // UnmountOpt are used to specify unmount options. 42 | type UnmountOpt func(*unmountOpts) error 43 | 44 | // OptUnmountStdout writes standard output to w. 45 | func OptUnmountStdout(w io.Writer) UnmountOpt { 46 | return func(mo *unmountOpts) error { 47 | mo.stdout = w 48 | return nil 49 | } 50 | } 51 | 52 | // OptUnmountStderr writes standard error to w. 53 | func OptUnmountStderr(w io.Writer) UnmountOpt { 54 | return func(mo *unmountOpts) error { 55 | mo.stderr = w 56 | return nil 57 | } 58 | } 59 | 60 | var errFusermountPathInvalid = errors.New("fusermount path must be relative or absolute") 61 | 62 | // OptUnmountFusermountPath sets the path to the fusermount binary. 63 | func OptUnmountFusermountPath(path string) UnmountOpt { 64 | return func(mo *unmountOpts) error { 65 | if filepath.Base(path) == path { 66 | return errFusermountPathInvalid 67 | } 68 | mo.fusermountPath = path 69 | return nil 70 | } 71 | } 72 | 73 | // Unmount unmounts the filesystem at mountPath. 74 | // 75 | // Unmount may start one or more underlying processes. By default, stdout and stderr of these 76 | // processes is discarded. To modify this behavior, consider using OptUnmountStdout and/or 77 | // OptUnmountStderr. 78 | // 79 | // By default, Unmount searches for a fusermount binary in the directories named by the PATH 80 | // environment variable. To override this behavior, consider using OptUnmountFusermountPath(). 81 | func Unmount(ctx context.Context, mountPath string, opts ...UnmountOpt) error { 82 | uo := unmountOpts{ 83 | fusermountPath: "fusermount", 84 | } 85 | 86 | for _, opt := range opts { 87 | if err := opt(&uo); err != nil { 88 | return fmt.Errorf("%w", err) 89 | } 90 | } 91 | 92 | return unmountSquashFS(ctx, mountPath, uo) 93 | } 94 | -------------------------------------------------------------------------------- /pkg/user/unmount_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022-2025, Sylabs Inc. All rights reserved. 2 | // This software is licensed under a 3-clause BSD license. Please consult the 3 | // LICENSE file distributed with the sources of this project regarding your 4 | // rights to use or distribute this software. 5 | 6 | package user 7 | 8 | import ( 9 | "bufio" 10 | "context" 11 | "errors" 12 | "fmt" 13 | "os" 14 | "os/exec" 15 | "path/filepath" 16 | "strings" 17 | "testing" 18 | ) 19 | 20 | var corpus = filepath.Join("..", "..", "test", "images") 21 | 22 | func Test_Unmount(t *testing.T) { 23 | if _, err := exec.LookPath("squashfuse"); err != nil { 24 | t.Skip("squashfuse not found, skipping mount tests") 25 | } 26 | fusermountPath, err := exec.LookPath("fusermount") 27 | if err != nil { 28 | t.Skip("fusermount not found, skipping mount tests") 29 | } 30 | 31 | tests := []struct { 32 | name string 33 | mountSIF string 34 | mountPath string 35 | opts []UnmountOpt 36 | wantErr bool 37 | wantUnmounted bool 38 | }{ 39 | { 40 | name: "Mounted", 41 | mountSIF: filepath.Join(corpus, "one-group.sif"), 42 | mountPath: t.TempDir(), 43 | wantErr: false, 44 | wantUnmounted: true, 45 | }, 46 | { 47 | name: "NotMounted", 48 | mountSIF: "", 49 | mountPath: t.TempDir(), 50 | wantErr: true, 51 | }, 52 | { 53 | name: "NotSquashfuse", 54 | mountSIF: "", 55 | mountPath: "/dev", 56 | wantErr: true, 57 | }, 58 | { 59 | name: "FusermountBare", 60 | mountSIF: "", 61 | mountPath: t.TempDir(), 62 | opts: []UnmountOpt{OptUnmountFusermountPath("fusermount")}, 63 | wantErr: true, 64 | }, 65 | { 66 | name: "FusermountValid", 67 | mountSIF: filepath.Join(corpus, "one-group.sif"), 68 | mountPath: t.TempDir(), 69 | opts: []UnmountOpt{OptUnmountFusermountPath(fusermountPath)}, 70 | wantErr: false, 71 | wantUnmounted: true, 72 | }, 73 | } 74 | for _, tt := range tests { 75 | t.Run(tt.name, func(t *testing.T) { 76 | if tt.mountSIF != "" { 77 | err := Mount(context.Background(), tt.mountSIF, tt.mountPath) 78 | if err != nil { 79 | t.Fatal(err) 80 | } 81 | } 82 | 83 | err := Unmount(context.Background(), tt.mountPath, tt.opts...) 84 | 85 | if err != nil && !tt.wantErr { 86 | t.Errorf("Unexpected error: %s", err) 87 | } 88 | if err == nil && tt.wantErr { 89 | t.Error("Unexpected success") 90 | } 91 | 92 | mounted, err := isMounted(tt.mountPath) 93 | if err != nil { 94 | t.Fatal(err) 95 | } 96 | if tt.wantUnmounted && mounted { 97 | t.Errorf("Expected %s to be unmounted, but it is mounted", tt.mountPath) 98 | } 99 | }) 100 | } 101 | } 102 | 103 | var errBadMountInfo = errors.New("bad mount info") 104 | 105 | func isMounted(mountPath string) (bool, error) { 106 | mountPath, err := filepath.Abs(mountPath) 107 | if err != nil { 108 | return false, err 109 | } 110 | 111 | mi, err := os.Open("/proc/self/mountinfo") 112 | if err != nil { 113 | return false, fmt.Errorf("failed to open /proc/self/mountinfo: %w", err) 114 | } 115 | defer mi.Close() 116 | 117 | scanner := bufio.NewScanner(mi) 118 | for scanner.Scan() { 119 | fields := strings.Split(scanner.Text(), " ") 120 | if len(fields) < 5 { 121 | return false, fmt.Errorf("not enough mountinfo fields: %w", errBadMountInfo) 122 | } 123 | //nolint:lll 124 | // 1348 63 0:77 / /tmp/siftool-mount-956028386 ro,nosuid,nodev,relatime shared:646 - fuse.squashfuse squashfuse ro,user_id=1000,group_id=100 125 | mntTarget := fields[4] 126 | if mntTarget == mountPath { 127 | return true, nil 128 | } 129 | } 130 | return false, nil 131 | } 132 | -------------------------------------------------------------------------------- /test/images/empty-id.sif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/test/images/empty-id.sif -------------------------------------------------------------------------------- /test/images/empty-launch-script.sif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/test/images/empty-launch-script.sif -------------------------------------------------------------------------------- /test/images/empty.sif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/test/images/empty.sif -------------------------------------------------------------------------------- /test/images/one-group-signed-dsse.sif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/test/images/one-group-signed-dsse.sif -------------------------------------------------------------------------------- /test/images/one-group-signed-legacy-all.sif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/test/images/one-group-signed-legacy-all.sif -------------------------------------------------------------------------------- /test/images/one-group-signed-legacy-group.sif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/test/images/one-group-signed-legacy-group.sif -------------------------------------------------------------------------------- /test/images/one-group-signed-legacy.sif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/test/images/one-group-signed-legacy.sif -------------------------------------------------------------------------------- /test/images/one-group-signed-pgp.sif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/test/images/one-group-signed-pgp.sif -------------------------------------------------------------------------------- /test/images/one-group.sif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/test/images/one-group.sif -------------------------------------------------------------------------------- /test/images/one-object-crypt-message.sif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/test/images/one-object-crypt-message.sif -------------------------------------------------------------------------------- /test/images/one-object-generic-json.sif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/test/images/one-object-generic-json.sif -------------------------------------------------------------------------------- /test/images/one-object-oci-blob.sif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/test/images/one-object-oci-blob.sif -------------------------------------------------------------------------------- /test/images/one-object-oci-root-index.sif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/test/images/one-object-oci-root-index.sif -------------------------------------------------------------------------------- /test/images/one-object-sbom.sif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/test/images/one-object-sbom.sif -------------------------------------------------------------------------------- /test/images/one-object-time.sif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/test/images/one-object-time.sif -------------------------------------------------------------------------------- /test/images/two-groups-signed-dsse.sif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/test/images/two-groups-signed-dsse.sif -------------------------------------------------------------------------------- /test/images/two-groups-signed-legacy-all.sif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/test/images/two-groups-signed-legacy-all.sif -------------------------------------------------------------------------------- /test/images/two-groups-signed-legacy-group.sif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/test/images/two-groups-signed-legacy-group.sif -------------------------------------------------------------------------------- /test/images/two-groups-signed-legacy.sif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/test/images/two-groups-signed-legacy.sif -------------------------------------------------------------------------------- /test/images/two-groups-signed-pgp.sif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/test/images/two-groups-signed-pgp.sif -------------------------------------------------------------------------------- /test/images/two-groups.sif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/test/images/two-groups.sif -------------------------------------------------------------------------------- /test/input/index.json: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": 2, 3 | "manifests": [ 4 | { 5 | "mediaType": "application/vnd.oci.image.manifest.v1+json", 6 | "digest": "sha256:abcdef1234567890", 7 | "size": 123456, 8 | "annotations": { 9 | "org.example.label": "Sample Label" 10 | }, 11 | "platform": { 12 | "architecture": "amd64", 13 | "os": "linux" 14 | } 15 | }, 16 | { 17 | "mediaType": "application/vnd.oci.image.manifest.v1+json", 18 | "digest": "sha256:0987654321abcdef", 19 | "size": 654321, 20 | "annotations": { 21 | "org.example.label": "Another Label" 22 | }, 23 | "platform": { 24 | "architecture": "arm64", 25 | "os": "linux" 26 | } 27 | } 28 | ] 29 | } -------------------------------------------------------------------------------- /test/input/oci-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "created": "2023-03-29T18:19:24.45578926Z", 3 | "architecture": "amd64", 4 | "os": "linux", 5 | "config": { 6 | "Env": [ 7 | "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" 8 | ], 9 | "Cmd": [ 10 | "/bin/sh" 11 | ] 12 | }, 13 | "rootfs": { 14 | "type": "layers", 15 | "diff_ids": [ 16 | "sha256:f1417ff83b319fbdae6dd9cd6d8c9c88002dcd75ecf6ec201c8c6894681cf2b5" 17 | ] 18 | }, 19 | "history": [ 20 | { 21 | "created": "2023-03-29T18:19:24.348438709Z", 22 | "created_by": "/bin/sh -c #(nop) ADD file:9a4f77dfaba7fd2aa78186e4ef0e7486ad55101cefc1fabbc1b385601bb38920 in / " 23 | }, 24 | { 25 | "created": "2023-03-29T18:19:24.45578926Z", 26 | "created_by": "/bin/sh -c #(nop) CMD [\"/bin/sh\"]", 27 | "empty_layer": true 28 | } 29 | ] 30 | } -------------------------------------------------------------------------------- /test/input/root.ext3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/test/input/root.ext3 -------------------------------------------------------------------------------- /test/input/root.squashfs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylabs/sif/8514ea2d7fa147fbcb292e39f8e4f262969bcf7e/test/input/root.squashfs -------------------------------------------------------------------------------- /test/input/sbom.cdx.json: -------------------------------------------------------------------------------- 1 | { 2 | "bomFormat": "CycloneDX", 3 | "specVersion": "1.4", 4 | "serialNumber": "urn:uuid:c0e8da98-7afc-4807-89a1-928a14dcd910", 5 | "version": 1, 6 | "metadata": { 7 | "timestamp": "2022-10-21T13:27:49Z", 8 | "tools": [ 9 | { 10 | "vendor": "anchore", 11 | "name": "syft", 12 | "version": "0.59.0" 13 | } 14 | ], 15 | "component": { 16 | "bom-ref": "a0f23d5d8e46dd55", 17 | "type": "container", 18 | "name": "image.sif" 19 | } 20 | }, 21 | "components": [] 22 | } 23 | -------------------------------------------------------------------------------- /test/keys/ecdsa-private.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgutWd9qmRjyHNeXJF 3 | hFKYuLlkreSKHeG2YqQETvajpF6hRANCAASaChR3vOdhomt23dAwin2/NaPnKY0I 4 | yYgyG7mOvS+EMkuZ9STlWVgmWUOyc/mqadBKI1Rj6oAYgIhZ3uuStcOI 5 | -----END PRIVATE KEY----- 6 | -------------------------------------------------------------------------------- /test/keys/ecdsa-public.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEmgoUd7znYaJrdt3QMIp9vzWj5ymN 3 | CMmIMhu5jr0vhDJLmfUk5VlYJllDsnP5qmnQSiNUY+qAGICIWd7rkrXDiA== 4 | -----END PUBLIC KEY----- 5 | -------------------------------------------------------------------------------- /test/keys/ed25519-private.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MC4CAQAwBQYDK2VwBCIEIMJFV66nU3pWbklpTUT+jq7oCLmyGTYkfgbvZznmv8G+ 3 | -----END PRIVATE KEY----- 4 | -------------------------------------------------------------------------------- /test/keys/ed25519-public.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MCowBQYDK2VwAyEA4LypVa0tjUB5eUQeeGjllrBG7gWCIOSymuMc6fg8GB4= 3 | -----END PUBLIC KEY----- 4 | -------------------------------------------------------------------------------- /test/keys/gen_keys.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022-2023, Sylabs Inc. All rights reserved. 2 | // This software is licensed under a 3-clause BSD license. Please consult the LICENSE.md file 3 | // distributed with the sources of this project regarding your rights to use or distribute this 4 | // software. 5 | 6 | package main 7 | 8 | import ( 9 | "crypto" 10 | "crypto/ecdsa" 11 | "crypto/ed25519" 12 | "crypto/elliptic" 13 | "crypto/rand" 14 | "crypto/rsa" 15 | "fmt" 16 | "os" 17 | 18 | "github.com/sigstore/sigstore/pkg/cryptoutils" 19 | ) 20 | 21 | func writeKeys() error { 22 | keys := []struct { 23 | pubPath string 24 | priPath string 25 | keyFn func() (crypto.PublicKey, crypto.PrivateKey, error) 26 | }{ 27 | { 28 | pubPath: "ecdsa-public.pem", 29 | priPath: "ecdsa-private.pem", 30 | keyFn: func() (crypto.PublicKey, crypto.PrivateKey, error) { 31 | pri, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) 32 | if err != nil { 33 | return nil, nil, err 34 | } 35 | return pri.Public(), pri, nil 36 | }, 37 | }, 38 | { 39 | pubPath: "ed25519-public.pem", 40 | priPath: "ed25519-private.pem", 41 | keyFn: func() (crypto.PublicKey, crypto.PrivateKey, error) { 42 | return ed25519.GenerateKey(rand.Reader) 43 | }, 44 | }, 45 | { 46 | pubPath: "rsa-public.pem", 47 | priPath: "rsa-private.pem", 48 | keyFn: func() (crypto.PublicKey, crypto.PrivateKey, error) { 49 | pri, err := rsa.GenerateKey(rand.Reader, 4096) 50 | if err != nil { 51 | return nil, nil, err 52 | } 53 | return pri.Public(), pri, nil 54 | }, 55 | }, 56 | } 57 | 58 | for _, key := range keys { 59 | pub, pri, err := key.keyFn() 60 | if err != nil { 61 | return err 62 | } 63 | 64 | pem, err := cryptoutils.MarshalPublicKeyToPEM(pub) 65 | if err != nil { 66 | return err 67 | } 68 | 69 | if err := os.WriteFile(key.pubPath, pem, 0o600); err != nil { 70 | return err 71 | } 72 | 73 | if pem, err = cryptoutils.MarshalPrivateKeyToPEM(pri); err != nil { 74 | return err 75 | } 76 | 77 | if err := os.WriteFile(key.priPath, pem, 0o600); err != nil { 78 | return err 79 | } 80 | } 81 | 82 | return nil 83 | } 84 | 85 | func main() { 86 | if err := writeKeys(); err != nil { 87 | fmt.Fprintln(os.Stderr, "Error:", err) 88 | os.Exit(1) 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /test/keys/private.asc: -------------------------------------------------------------------------------- 1 | -----BEGIN PGP PRIVATE KEY BLOCK----- 2 | 3 | lQOYBF6nUPABCACmd6vggtFfkZvYHJRv/u2UfazFL78oLhD05UpqEaS90ripzPN9 4 | G30IF6WqxQHxia0nV/IqJ9Tjozs0nIaK761y69gCYbac27e1r6Pf4uCoTfOWeGVZ 5 | TYsbseu6pf8BSDLQMu1S7/P5y5BHthAep9n6zpWr6drPdt20w2HOmTWDhbGw9Sue 6 | n12BVoiyNChuT01tDcBlffXn3gN9qIWS6aJLxKbvh88LIsKWkTcFv9bEhHdh0tU8 7 | ckt1xDT6PkkZToHdOl8OqNz4Psy6oELJR1lopdto/xBuWWTsx4hBM7mnIrNdvN/W 8 | qNXzIP1UAHNG24lLaGpL410HDG6E+P/knhjdABEBAAEAB/4piJ8+L3WM2jgfhhX1 9 | EY52Z5rVQhH4NPIvIAxehZNsdyhy2TuBIfwiqj+/6VKQULD+qX82zGRd/YqWmF0r 10 | ShylGTn2cinNXjaqYq3I/QLfiz908goba3EDUnOFyMfkqn5fGu3CrTLaxtLzSXYh 11 | J/EHlkaas4jQDZDIep0rHmfPLgO1h6zWzCJEEwciK/sBWiUHm4lHIC9BHWp3oMwF 12 | HYiaj9//9+/5ofP2WfMRbf4hM83HHwOj2YFSiSOlzhFKJhhgluOzlhlNqPtqgxpP 13 | qI8a4E5hYkgMIThoIUKbW0869jSOVEY/P7h9D2rI0zH+M9T6OmaikrX83HKB699M 14 | zS5xBADIOoDWQcPDZSDf06+JIVGBJ5Rw2v6Q/DZqrOEOb8kncpyMJFbuc7GhIx3g 15 | 4ZZMzp6+c+hKdw/Mm+431nqcEUJKRvoaFRUvhAea5sRrRJtOx9CbzqyvSWvon16a 16 | 99l2Yd3mljSKfsz5sNlwZOMXj84ia8drhVdhmhynF5OLatXglQQA1NXNNwWPYSZz 17 | r4kaytnGsMJ+iKbZ8WHI52aCcX6cuRBeOget2EbwicU1NOnFpP7YiE+G8SXq73LZ 18 | 2F1QCe5boc90QDVAx8yO6hFxCf1By58YuNcgnCU+k1W0eLOul78U6mRusAPPTu9j 19 | 1es1dK4jk2oBwHUBMLOz+ZVkPvnrXSkD/2xo+U441tM1+w+9njSsS4huaobqKgvx 20 | OKy4PpWh25IjOd3ODdrKpLeR5DHdtvl0b2ph1tOTgnOrDF3lCQ9y50f46JDY+Usm 21 | /0hV9Vg7bXS6hpW36M+StuxbxNFoIcJOaStkWnOaysKQQfQ7qKu1v3yXu5woGlmM 22 | q8fAGOQ9zkOhStS0GVVuaXQgVGVzdCA8dW5pdEB0ZXN0LmNvbT6JAU4EEwEIADgC 23 | GwMFCwkIBwIGFQoJCAsCBBYCAwECHgECF4AWIQQSBFyMCxAE0FjeS+2iDCfuf/e6 24 | hAUCYnwW1gAKCRCiDCfuf/e6hNu/B/9ypP+dMhn4zqCXPNmxT/3GZ+NeTPiUF1lF 25 | BmF+cFc8LTVrJ5WFGTAfTCXFKeGsHMMu7F0CdR6pN8+gGagqouMbqsLUXbZnYyyr 26 | R3FRHDyDf3Ei9BTeygXzWKnyGMhmPmL1V+BEN4AegQeRFnfcJXHfjw01QBBkudwj 27 | EGPOmpiBcUBo9q3SSha9qUDolgwqVVTQsofn+SWQ5peKOrvMqMsVlg6dK9DVf4i0 28 | aII4G2SQ7r60YCuTu7hixTtwkKd7CJEX+MsPWU7WQp4V/+1fCMmZ3AJZaHrNE2a+ 29 | Jqme3Y+jPcFkyUWfqEc6dtzYOnzXKWCBj9uiF+4t+SknFL9xfz9snQOYBF6nUPAB 30 | CAC/yLh6jYYFrWwQp0NQJtBXsw2iK2TJ42mZdtCUeRmr82eBui+JoiCJVleQNr5O 31 | e+JFbIeI6VwxR+n8ct5jDHOP5skjVAhzPNZ7jwrrVlZbeW/BVnILEUuo6CiqJY3F 32 | CIuOncX5IAH/0jyDRkz50rFqPAAODyV5TTFCViBdtAYZZ3r4pqg5z7a4CRZmn/+A 33 | o3/27opAgt96VUkIqIQLIukiquS7ZSLcJrJxxS6QjDcy0gswdLbenG9FXtwEcUK2 34 | Jdc8IAq5WVkzE4xOcgE9JeV9L2/449MStZm/nkzFteutPWc9PpTXSDWu+H4U9+Wo 35 | ZW5OwINRe9VpNVv7UlxW80VpABEBAAEAB/wJ5Hwjki5CF7Z1y3Ls7PudMna3ET7z 36 | LQBS8q6CohaBaJ5DsktmcY71FpeQsEozuS8sPpNlLAhd4GRA6dnvyQIi/5gLcve2 37 | ngJAQFojVoJA2Kw7kE50pLE+5q7GTAaajbzJH/lIxu5jeEA300YAMu6E2NB16TEZ 38 | JzKtxcyImNMhtz434EXvPp01T8NxukBKYjfJ6cZ1hFIahFoZGZ9GemFGx2FRfM0C 39 | U/yXIYTwXUBkLaE8U6bx1cU7ujaBuu/uMN0FA+37UHBSQWh+9yiDQ0+Iq7D3WkjT 40 | AgGdQ/GAhTDVtt9Y7h4cozNvlSS/VrEyH0nJbPMCbEDoB65yim0/+N+JBADD7u0+ 41 | ajZtyW5JpE1eyucn2VDg1m34QZU0/h5bBnMy6P1zhRO/8fqIKta00y9iY7PAvYtF 42 | ivY18zrmNYmaQFAe6Cawm9/Qb2db7sbex5tMXfqKB0pItl05RKUK3BRM69iLYg76 43 | jtPSZerfSJJVGhpQmFJxa3EdcumzEyiUnm4bPQQA+pQoESGvSZ6GJPu/fGz/duOt 44 | w4TBNtMWlt2dtSVtWru6r/aVWlkAXMdvNWdSGKrEXqvxo39xIhKIW742BlqWlZ2f 45 | sJQb/9UmBFjhDg5poj+jpATQ2MFhOlSc4un+0KE7R3sz6n98S8AN76PPlPZOwgbz 46 | BCAub/+kMCQcnog75Z0EAJdYFYs/gUnvOmfoKZisIn8OZ6aa6LWqWhFCSgNU03I6 47 | +wWyEjJsbcBRBXEpuGfeVfAUDJSVSv5lJg2fOU0p3ephoiZSORaCZovXTPQgTgO0 48 | afcSUP5g8o/Tjp1QPETBd/Rd/Br5WBdfoF91ZUhblvs04qb+lswvJXYZ6caeot1E 49 | PByJATYEGAEIACACGwwWIQQSBFyMCxAE0FjeS+2iDCfuf/e6hAUCYnwXAgAKCRCi 50 | DCfuf/e6hHFVB/0b1W2AvcRRXUH4HCmapgGsmLU1k/PEVHz1FmOX+a7UDEh8moVg 51 | fVeaV9pR6gKGHs6LMH3eDxF2LNAPNzzs7V3+RjeIDvxnFkld3BSlNltR1v7uz8tl 52 | SSUX7zASAhUyT4Qq3Lvo1TdQdgK9HnZJuKzNHofUq4v71xWWIfyYSwGmu3OAtxpH 53 | /xb0bAYnrPG9hruy/ZgL2KP4Irb3a1zFBIKIjUN4iTbHpkLeNIOygbOK3GDnUTGe 54 | Q4v8IP2ZtLVMlVjYJNMOV9zNnNzP7dj+ua7rOiqbBWKZaRvG7o1YZUx7Km6xhG4y 55 | EZ/ZSGnSuqYT1FabxNxb1kR4eRMWbeDjk7uX 56 | =+DIa 57 | -----END PGP PRIVATE KEY BLOCK----- 58 | -------------------------------------------------------------------------------- /test/keys/rsa-private.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQCvfl/OFiJUHDV3 3 | RDHd9W0Jc5eC2cVxybb7RvQCQwoEjnF3s09s92XZJ9vBl1MS50/f2IdAs0H6qIgp 4 | JRlvL1WHghJrKFZn5VxNctMa4SjM9M6llReF9EBtnwRjKerMlSY/XoSmL2JKhVYA 5 | 0OkThs9wufqZv0GPzrRXFIlhSefYOEGPFKX8wMr0nFI+A4pOIFm49xGP3CVq4GEe 6 | 8Ow9GtcIf6Yb7YY01m7PzVFowMHCh3CB1nkf9lEX24k99p6qxgpYZ37OFTmwIDil 7 | 8g7kOvREqW0mN2NJv3GiJmwLY4EL6cLV+8hReuoyV8tOLtYFH0EbxliFnhpWvYu/ 8 | 5tq12YQ3+c8xnhDRVeoqla3KpHTvTHSAcN+64+0S2a+0TiiXq1ut2ZkJdefJ8L0x 9 | X9KnCVUZJPqnLdbtPsKsYv6FGvneILUDC4xd3OYzbHvPjJbgHLy2zt+JDfQiNVw8 10 | NgIFynfKs4UWji67OuNSJsMiQ6RHpv+7jKWKyJJBklMUJTLLGFBUy9LBJbaWTljl 11 | 6Hlyzo1c6pEHGg9T1x/QjtJ/n5giX4BxVkBWCZEiljulNjmr5APKKKg1Bi/rAvg+ 12 | OPT2XCMQakwX8WtSWo/PfJ6L6yfed2XdEEG1dplcgkEM6M0FD3ny19sxpUAb2TZw 13 | OcDZDG4nP3u5VTqAkBjpi/+2UBarzwIDAQABAoICAEnTjhYydYqQu2VLCPdo8c/S 14 | EuD3H/q4cwPOW4RAE4zLJ6zFgBpFEVGDVQ1hzY7cRFvUyUFMp+r8zxsQAl0luoNh 15 | EsKFm6PldykVrv1Vz0Y5jl1WFSlDEX+ML9pPnfkmnYp3BrKqqFzVLtL1D7gpNEcl 16 | 1eir7rbCrFcdypVk8+Wf9ORuOU3VBQxWXrq73ojzTwti1L6CTDNj5TeQ/rDOA7wN 17 | hyGkkJrVwpQkuaSpwllFhOz5/saVZpP0xQ2OHD2XRm7eSxgDEduoEmytIdqdenkQ 18 | FVzIXDqAERu3sigwWe9bDZ3bZ+/vF2rKSDrBtUM+XLOEg2TimA35ezrlsQhjUx1O 19 | S+NaOXzBFdXRJ7jfQTFs/puTwZW5aL/N6A+/jApgRInZ1lFyxnCEYXRlxaSyNVgz 20 | g69DwrSP8/B7wABgTN81luWuhwarbYSbhq8Vqm3xRM+sd1l1ds2GMZA/ZHZvuB1T 21 | RrU3TMasVFQkgOIl0iIKIwc0RzUq/6weLKtmxOHfxJvSgdve6jdY9iuLJJi1HhHg 22 | 1abXOxiHuhRMNqHm8ApN78VGauZnhcdr4cQNyiZ4pPaiwXo/syEuNim7gZ+ym6Lh 23 | WuHdzDIHmqFLn3Mv2GH5JgOaDkaJsMZjanl6t0Bv1gdIxgkCiaaQyhFnApDeMkLh 24 | CSViIfkzLyeUhNoaPH2hAoIBAQDl3bXfYn1Fvc8Tm8EMFEqE6g6vOrEHmwEybUAU 25 | QFijj0mS4pv1UPrlcXIbKJg7+eccicakRy2Toa9viQ17ihmV4Os5xra/dtt8Mw4N 26 | tw5+vI8T7ffNdHLtMdda/lt3sJrXL+cYj/a6EwcXcXoCbgewIFXPk1dQmjM3zHKs 27 | Wb38eZmOyacZefF7kEtIVkohdYmQBw+gfnenzSAN8QBFke25lNv2bO3crEQGqc9i 28 | WjZJpFZAW+7bo1K2EboDH/adTveCLnodjgtVaMli4MCDE18fYlxFWC2Qkf4eUocg 29 | xDa7Vjku81XdLCZsrhVsKJ4g8wCuRCpuQXyRlIxs1anQV+JHAoIBAQDDciVaF9bV 30 | jtlkHq8b0mJZfUDy3Yk6sYyfs9Umwzdunfaci7imDDO6XTcTiznLkrM5CsRaE3Na 31 | v9IvYfd2TxsnGgmxOrGyOSv9eeOIZ9q4QLxvKjDXwaOvNJqXQtOa0/2+UmUqnMMe 32 | YOaHHEKESZVelM3fQZ4jVWISnK2o6B/zwh8aN9KZK7RpePLcwGGxBdu4gxk1w5kZ 33 | XdTv1VncaUBZF3lP2mtKllMA6l0HKfHkB8SB/WAiz5cxN6J74zHPeWbW8JbbcNMt 34 | OOr3UpPBjwetXZ7p+4VDBQvvCdUDLQuyB532jpcVGp2K1aBg1/w3pgCYpSjq4Oqw 35 | m9lO9jYuO2Y5AoIBACQiK/rHgqW55plQfJInhmdKW7CT60wkw5VnsxD75HMhjRE3 36 | 6ggwCKCUqrk2MmgLKpdD2SPtxG5WljtUMfhfhxIWXyOf5w5F4s6tP+JMCk1F2r/p 37 | QnDbg01h7lZxcXNpIY3+C7fCuagaYZz/y4wiO7cl/hc5NBqJgs+cpdIN8V2Ex+y4 38 | KjpI/vrLfeoLFnAYB93KHly+RJTuG8HVRpOpEtN/YOxlxyZPNgpOGzl8sNf2q1BG 39 | o0+HZvMT6kefeKbVyPZ/09Zdg86TQET4y4pPOz61uYd1CwSUznt5waAW9/uO3EJT 40 | IgY4cHnZC6kK4YCQcmTydjEKvkgsL77T/3OuvPUCggEAFJhgqz+72cE100EQfsQK 41 | rRdv0qfZoB+5i9KtcWo82yE2LYTjrku237qW5S5UpskMrcQesMc/7p4sDeYq54Kq 42 | f9JUlyJyOy+fHRTND0CyYZwgvy4Y+4NiNkI60Bmwpq4UHQwdsQHX5cmcQTyPHdWL 43 | Me5IS3Bks6B5tzBfdF8RjuQz1tVvEcjzN/IQ1YZIRRky8ByQeYPlDDFBEQzQbVOB 44 | /mFk3S9NAw0YLg6EQw7+eGMBKBmFGeX6LquIKbnlM9G9LoUnwHQBLNDEoc9H1qu1 45 | yWUGK+3fOxK7ETNeCPmkM9xtnt+juAuX8ltUjR/1af/KLEurJiURVg72NUXoq7KC 46 | sQKCAQEAtoE56iHZxRLLsdRWmk929AF68QAOK+9QuzbzfWXNiq4bHlyRfpqts5Am 47 | 6qkngLjOrO4wAhJLjCQlUp1DwvE9bJVh9Kl1CJQGlXmzGQVbGoi17dFzebS+YYfn 48 | dYkB1ruSqUu41EnAORYUCqS9uaApub52NmLPkQ1VzOgzVNXJ6CiOpgoDT9vMb/R2 49 | KQeEuO7YRcNnN9c7VVrDKlx++IgLYD4vuqgSXwOb4kzDw6fF/0jB7+JUFfyhqlf8 50 | P+pUc69bxNoYDHtvKBIMRaALZbgIfTukSeJNuoHgzEtjse4yJIa/Sm8w3mEwUiim 51 | StayRkZIx/gRHJVzs1mmfTM7E36Dgg== 52 | -----END PRIVATE KEY----- 53 | -------------------------------------------------------------------------------- /test/keys/rsa-public.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAr35fzhYiVBw1d0Qx3fVt 3 | CXOXgtnFccm2+0b0AkMKBI5xd7NPbPdl2SfbwZdTEudP39iHQLNB+qiIKSUZby9V 4 | h4ISayhWZ+VcTXLTGuEozPTOpZUXhfRAbZ8EYynqzJUmP16Epi9iSoVWANDpE4bP 5 | cLn6mb9Bj860VxSJYUnn2DhBjxSl/MDK9JxSPgOKTiBZuPcRj9wlauBhHvDsPRrX 6 | CH+mG+2GNNZuz81RaMDBwodwgdZ5H/ZRF9uJPfaeqsYKWGd+zhU5sCA4pfIO5Dr0 7 | RKltJjdjSb9xoiZsC2OBC+nC1fvIUXrqMlfLTi7WBR9BG8ZYhZ4aVr2Lv+batdmE 8 | N/nPMZ4Q0VXqKpWtyqR070x0gHDfuuPtEtmvtE4ol6tbrdmZCXXnyfC9MV/SpwlV 9 | GST6py3W7T7CrGL+hRr53iC1AwuMXdzmM2x7z4yW4By8ts7fiQ30IjVcPDYCBcp3 10 | yrOFFo4uuzrjUibDIkOkR6b/u4ylisiSQZJTFCUyyxhQVMvSwSW2lk5Y5eh5cs6N 11 | XOqRBxoPU9cf0I7Sf5+YIl+AcVZAVgmRIpY7pTY5q+QDyiioNQYv6wL4Pjj09lwj 12 | EGpMF/FrUlqPz3yei+sn3ndl3RBBtXaZXIJBDOjNBQ958tfbMaVAG9k2cDnA2Qxu 13 | Jz97uVU6gJAY6Yv/tlAWq88CAwEAAQ== 14 | -----END PUBLIC KEY----- 15 | --------------------------------------------------------------------------------