Skip to content

Commit

Permalink
Merge pull request #158 from edytuk/v2.8.3
Browse files Browse the repository at this point in the history
Merge sylabs/sif through v2.8.3
  • Loading branch information
DrDaveD authored Nov 4, 2022
2 parents 40a54dc + bc6d879 commit 2edbdce
Show file tree
Hide file tree
Showing 16 changed files with 203 additions and 44 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module github.com/apptainer/sif/v2
go 1.18

require (
github.com/ProtonMail/go-crypto v0.0.0-20220930113650-c6815a8c17ad
github.com/ProtonMail/go-crypto v0.0.0-20221026131551-cf6655e29de4
github.com/blang/semver/v4 v4.0.0
github.com/go-git/go-git/v5 v5.4.2
github.com/google/uuid v1.3.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jB
github.com/Microsoft/go-winio v0.4.16 h1:FtSW/jqD+l4ba5iPBj9CODVtgfYAD8w2wS923g/cFDk=
github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0=
github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo=
github.com/ProtonMail/go-crypto v0.0.0-20220930113650-c6815a8c17ad h1:QeeqI2zxxgZVe11UrYFXXx6gVxPVF40ygekjBzEg4XY=
github.com/ProtonMail/go-crypto v0.0.0-20220930113650-c6815a8c17ad/go.mod h1:UBYPn8k0D56RtnR8RFQMjmh4KrZzWJ5o7Z9SYjossQ8=
github.com/ProtonMail/go-crypto v0.0.0-20221026131551-cf6655e29de4 h1:ra2OtmuW0AE5csawV4YXMNGNQQXvLRps3z2Z59OPO+I=
github.com/ProtonMail/go-crypto v0.0.0-20221026131551-cf6655e29de4/go.mod h1:UBYPn8k0D56RtnR8RFQMjmh4KrZzWJ5o7Z9SYjossQ8=
github.com/acomagu/bufpipe v1.0.3 h1:fxAGrHZTgQ9w5QqVItgzwj235/uYZYgbXitB+dLupOk=
github.com/acomagu/bufpipe v1.0.3/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4=
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA=
Expand Down
24 changes: 22 additions & 2 deletions internal/app/siftool/info.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Apptainer a Series of LF Projects LLC.
// For website terms of use, trademark policy, privacy policy and other
// project policies see https://lfprojects.org/policies
// Copyright (c) 2018-2021, Sylabs Inc. All rights reserved.
// Copyright (c) 2018-2022, Sylabs Inc. All rights reserved.
// Copyright (c) 2018, Divya Cote <[email protected]> All rights reserved.
// Copyright (c) 2017, SingularityWare, LLC. All rights reserved.
// Copyright (c) 2017, Yannick Cote <[email protected]> All rights reserved.
Expand Down Expand Up @@ -115,16 +115,25 @@ func writeList(w io.Writer, f *sif.FileImage) error {
if err == nil {
fmt.Fprintf(w, "|%s (%s/%s/%s)\n", dt, fs, pt, arch)
}

case sif.DataSignature:
ht, _, err := d.SignatureMetadata()
if err == nil {
fmt.Fprintf(w, "|%s (%s)\n", dt, ht)
}

case sif.DataCryptoMessage:
ft, mt, err := d.CryptoMessageMetadata()
if err == nil {
fmt.Fprintf(w, "|%s (%s/%s)\n", dt, ft, mt)
}

case sif.DataSBOM:
f, err := d.SBOMMetadata()
if err == nil {
fmt.Fprintf(w, "|%s (%s)\n", dt, f)
}

default:
fmt.Fprintf(w, "|%s\n", dt)
}
Expand Down Expand Up @@ -199,7 +208,10 @@ func writeInfo(w io.Writer, v sif.Descriptor) error {
}

fmt.Fprintf(tw, "\tHash Type:\t%v\n", ht)
fmt.Fprintf(tw, "\tEntity:\t%X\n", fp)

if len(fp) > 0 {
fmt.Fprintf(tw, "\tEntity:\t%X\n", fp)
}

case sif.DataCryptoMessage:
ft, mt, err := v.CryptoMessageMetadata()
Expand All @@ -209,6 +221,14 @@ func writeInfo(w io.Writer, v sif.Descriptor) error {

fmt.Fprintf(tw, "\tFormat Type:\t%v\n", ft)
fmt.Fprintf(tw, "\tMessage Type:\t%v\n", mt)

case sif.DataSBOM:
f, err := v.SBOMMetadata()
if err != nil {
return err
}

fmt.Fprintf(tw, "\tFormat:\t%v\n", f)
}

return tw.Flush()
Expand Down
15 changes: 14 additions & 1 deletion internal/app/siftool/info_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2021, Sylabs Inc. All rights reserved.
// Copyright (c) 2021-2022, Sylabs Inc. All rights reserved.
// This software is licensed under a 3-clause BSD license. Please consult the
// LICENSE file distributed with the sources of this project regarding your
// rights to use or distribute this software.
Expand Down Expand Up @@ -112,6 +112,10 @@ func TestApp_Header(t *testing.T) {
name: "OneObjectCryptMessage",
path: filepath.Join(corpus, "one-object-crypt-message.sif"),
},
{
name: "OneObjectSBOM",
path: filepath.Join(corpus, "one-object-sbom.sif"),
},
{
name: "OneGroup",
path: filepath.Join(corpus, "one-group.sif"),
Expand Down Expand Up @@ -210,6 +214,10 @@ func TestApp_List(t *testing.T) {
name: "OneObjectCryptMessage",
path: filepath.Join(corpus, "one-object-crypt-message.sif"),
},
{
name: "OneObjectSBOM",
path: filepath.Join(corpus, "one-object-sbom.sif"),
},
{
name: "OneGroup",
path: filepath.Join(corpus, "one-group.sif"),
Expand Down Expand Up @@ -299,6 +307,11 @@ func TestApp_Info(t *testing.T) {
path: filepath.Join(corpus, "one-object-crypt-message.sif"),
id: 1,
},
{
name: "SBOM",
path: filepath.Join(corpus, "one-object-sbom.sif"),
id: 1,
},
{
name: "DataPartitionRaw",
path: filepath.Join(corpus, "two-groups-signed.sif"),
Expand Down
10 changes: 9 additions & 1 deletion internal/app/siftool/modif_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Apptainer a Series of LF Projects LLC.
// For website terms of use, trademark policy, privacy policy and other
// project policies see https://lfprojects.org/policies
// Copyright (c) 2021, Sylabs Inc. All rights reserved.
// Copyright (c) 2021-2022, Sylabs Inc. All rights reserved.
// This software is licensed under a 3-clause BSD license. Please consult the
// LICENSE file distributed with the sources of this project regarding your
// rights to use or distribute this software.
Expand Down Expand Up @@ -77,6 +77,14 @@ func TestApp_Add(t *testing.T) {
sif.OptCryptoMessageMetadata(sif.FormatOpenPGP, sif.MessageClearSignature),
},
},
{
name: "SBOM",
data: []byte{0xde, 0xad, 0xbe, 0xef},
dataType: sif.DataSBOM,
opts: []sif.DescriptorInputOpt{
sif.OptSBOMMetadata(sif.SBOMFormatCycloneDXJSON),
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Version: 01
Descriptors Free: 47
Descriptors Total: 48
Descriptors Offset: 4096
Descriptors Size: 27 KiB
Data Offset: 32176
Data Size: 454 B
7 changes: 7 additions & 0 deletions internal/app/siftool/testdata/TestApp_Info/SBOM.golden
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Data Type: SBOM
ID: 1
Group ID: 1
Linked ID: NONE
Offset: 32176
Size: 454
Format: cyclonedx-json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
------------------------------------------------------------------------------
ID |GROUP |LINK |SIF POSITION (start-end) |TYPE
------------------------------------------------------------------------------
1 |1 |NONE |32176-32630 |SBOM (cyclonedx-json)
4 changes: 4 additions & 0 deletions pkg/integrity/select.go
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,10 @@ func getFingerprints(sigs []sif.Descriptor) ([][]byte, error) {
return nil, err
}

if len(fp) == 0 {
continue
}

// Check if fingerprint is already in list.
i := sort.Search(len(fps), func(i int) bool {
return bytes.Compare(fps[i], fp) >= 0
Expand Down
5 changes: 5 additions & 0 deletions pkg/sif/descriptor.go
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,11 @@ func (d Descriptor) SignatureMetadata() (ht crypto.Hash, fp []byte, err error) {
}

fp = make([]byte, 20)

if bytes.Equal(s.Entity[:len(fp)], fp) {
return ht, nil, nil // Fingerprint not present.
}

copy(fp, s.Entity[:])

return ht, fp, nil
Expand Down
59 changes: 31 additions & 28 deletions pkg/sif/descriptor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,48 +172,51 @@ func TestDescriptor_PartitionMetadata(t *testing.T) {
}

func TestDescriptor_SignatureMetadata(t *testing.T) {
s := signature{
Hashtype: hashSHA384,
}
copy(s.Entity[:], []byte{
0x12, 0x04, 0x5c, 0x8c, 0x0b, 0x10, 0x04, 0xd0, 0x58, 0xde,
0x4b, 0xed, 0xa2, 0x0c, 0x27, 0xee, 0x7f, 0xf7, 0xba, 0x84,
})

rd := rawDescriptor{
DataType: DataSignature,
}
if err := rd.setExtra(s); err != nil {
t.Fatal(err)
}

tests := []struct {
name string
rd rawDescriptor
wantHT crypto.Hash
wantFP []byte
dt DataType
ht hashType
fp []byte
wantErr error
wantHT crypto.Hash
}{
{
name: "UnexpectedDataType",
rd: rawDescriptor{
DataType: DataGeneric,
},
name: "UnexpectedDataType",
dt: DataGeneric,
wantErr: &unexpectedDataTypeError{DataGeneric, []DataType{DataSignature}},
},
{
name: "OK",
rd: rd,
wantHT: crypto.SHA384,
wantFP: []byte{
name: "Fingerprint",
dt: DataSignature,
ht: hashSHA384,
fp: []byte{
0x12, 0x04, 0x5c, 0x8c, 0x0b, 0x10, 0x04, 0xd0, 0x58, 0xde,
0x4b, 0xed, 0xa2, 0x0c, 0x27, 0xee, 0x7f, 0xf7, 0xba, 0x84,
},
wantHT: crypto.SHA384,
},
{
name: "NoFingerprint",
dt: DataSignature,
ht: hashSHA256,
wantHT: crypto.SHA256,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
d := Descriptor{raw: tt.rd}
sig := signature{
Hashtype: tt.ht,
}
copy(sig.Entity[:], tt.fp)

rd := rawDescriptor{
DataType: tt.dt,
}
if err := rd.setExtra(sig); err != nil {
t.Fatal(err)
}

d := Descriptor{raw: rd}

ht, fp, err := d.SignatureMetadata()

Expand All @@ -226,7 +229,7 @@ func TestDescriptor_SignatureMetadata(t *testing.T) {
t.Fatalf("got hash type %v, want %v", got, want)
}

if got, want := fp, tt.wantFP; !bytes.Equal(got, want) {
if got, want := fp, tt.fp; !bytes.Equal(got, want) {
t.Fatalf("got entity %v, want %v", got, want)
}
}
Expand Down
57 changes: 51 additions & 6 deletions pkg/siftool/add.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ var (
partArch *int32
signHash *int32
signEntity *string
sbomFormat *string
groupID *uint32
linkID *uint32
alignment *int
Expand All @@ -54,9 +55,9 @@ func getAddExamples(rootPath string) string {
func addFlags(fs *pflag.FlagSet) {
dataType = fs.Int("datatype", 0, `the type of data to add
[NEEDED, no default]:
1-Deffile, 2-EnvVar, 3-Labels,
4-Partition, 5-Signature, 6-GenericJSON,
7-Generic, 8-CryptoMessage`)
1-Deffile, 2-EnvVar, 3-Labels,
4-Partition, 5-Signature, 6-GenericJSON,
7-Generic, 8-CryptoMessage, 9-SBOM`)
partType = fs.Int32("parttype", 0, `the type of partition (with -datatype 4-Partition)
[NEEDED, no default]:
1-System, 2-PrimSys, 3-Data,
Expand All @@ -78,6 +79,10 @@ func addFlags(fs *pflag.FlagSet) {
signEntity = fs.String("signentity", "", `the entity that signs (with -datatype 5-Signature)
[NEEDED, no default]:
example: 433FE984155206BD962725E20E8713472A879943`)
sbomFormat = fs.String("sbomformat", "", `the SBOM format (with -datatype 9-sbom):
cyclonedx-json, cyclonedx-xml, github-json,
spdx-json, spdx-rdf, spdx-tag-value,
spdx-yaml, syft-json`)
groupID = fs.Uint32("groupid", 0, "set groupid [default: 0]")
linkID = fs.Uint32("link", 0, "set link pointer [default: 0]")
alignment = fs.Int("alignment", 0, "set alignment [default: 4096 with -datatype 4-Partition, 0 otherwise]")
Expand Down Expand Up @@ -105,6 +110,8 @@ func getDataType() (sif.DataType, error) {
return sif.DataGeneric, nil
case 8:
return sif.DataCryptoMessage, nil
case 9:
return sif.DataSBOM, nil
default:
return 0, errDataTypeRequired
}
Expand Down Expand Up @@ -160,9 +167,35 @@ func getHashType() (crypto.Hash, error) {
}
}

var errInvalidSBOMFormat = errors.New("invalid SBOM format")

func getSBOMFormat() (sif.SBOMFormat, error) {
switch *sbomFormat {
case "cyclonedx-json":
return sif.SBOMFormatCycloneDXJSON, nil
case "cyclonedx-xml":
return sif.SBOMFormatCycloneDXXML, nil
case "github", "github-json":
return sif.SBOMFormatGitHubJSON, nil
case "spdx-json":
return sif.SBOMFormatSPDXJSON, nil
case "spdx-rdf":
return sif.SBOMFormatSPDXRDF, nil
case "spdx-tag-value":
return sif.SBOMFormatSPDXTagValue, nil
case "spdx-yaml":
return sif.SBOMFormatSPDXYAML, nil
case "syft-json":
return sif.SBOMFormatSyftJSON, nil
default:
return 0, fmt.Errorf("%w: %v", errInvalidSBOMFormat, *sbomFormat)
}
}

var (
errPartitionArgs = errors.New("with partition datatype, -partfs, -parttype and -partarch must be passed")
errInvalidFingerprintLength = errors.New("invalid signing entity fingerprint length")
errSBOMArgs = errors.New("with SBOM datatype, -sbomformat must be passed")
)

func getOptions(dt sif.DataType, fs *pflag.FlagSet) ([]sif.DescriptorInputOpt, error) {
Expand All @@ -186,17 +219,17 @@ func getOptions(dt sif.DataType, fs *pflag.FlagSet) ([]sif.DescriptorInputOpt, e
opts = append(opts, sif.OptObjectName(*name))
}

if dt == sif.DataPartition {
switch dt {
case sif.DataPartition:
if *partType == 0 || *partFS == 0 || *partArch == 0 {
return nil, errPartitionArgs
}

opts = append(opts,
sif.OptPartitionMetadata(sif.FSType(*partFS), sif.PartType(*partType), getArch()),
)
}

if dt == sif.DataSignature {
case sif.DataSignature:
b, err := hex.DecodeString(*signEntity)
if err != nil {
return nil, fmt.Errorf("failed to decode signing entity fingerprint: %w", err)
Expand All @@ -214,6 +247,18 @@ func getOptions(dt sif.DataType, fs *pflag.FlagSet) ([]sif.DescriptorInputOpt, e
copy(fp, b)

opts = append(opts, sif.OptSignatureMetadata(ht, fp))

case sif.DataSBOM:
if *sbomFormat == "" {
return nil, errSBOMArgs
}

f, err := getSBOMFormat()
if err != nil {
return nil, err
}

opts = append(opts, sif.OptSBOMMetadata(f))
}

return opts, nil
Expand Down
Loading

0 comments on commit 2edbdce

Please sign in to comment.