From 52f5f74460ec5a66bac9cee37cfc4d82de66addf Mon Sep 17 00:00:00 2001 From: Adam Hughes <9903835+tri-adam@users.noreply.github.com> Date: Thu, 15 Sep 2022 17:40:11 +0000 Subject: [PATCH 1/4] feat: SBOM support in siftool Modify 'add' command to support adding SBOM data object and format (via '--sbomformat' option. Modify 'info'/'list' commands to output SBOM details. Signed-off-by: Edita Kizinevic --- internal/app/siftool/info.go | 19 ++++++- internal/app/siftool/modif_test.go | 10 +++- pkg/siftool/add.go | 57 +++++++++++++++++-- .../testdata/TestAddCommands/Add/out.golden | 10 +++- 4 files changed, 85 insertions(+), 11 deletions(-) diff --git a/internal/app/siftool/info.go b/internal/app/siftool/info.go index 6f17e410..2979da95 100644 --- a/internal/app/siftool/info.go +++ b/internal/app/siftool/info.go @@ -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 All rights reserved. // Copyright (c) 2017, SingularityWare, LLC. All rights reserved. // Copyright (c) 2017, Yannick Cote All rights reserved. @@ -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) } @@ -209,6 +218,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() diff --git a/internal/app/siftool/modif_test.go b/internal/app/siftool/modif_test.go index 815932ca..5730e401 100644 --- a/internal/app/siftool/modif_test.go +++ b/internal/app/siftool/modif_test.go @@ -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. @@ -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) { diff --git a/pkg/siftool/add.go b/pkg/siftool/add.go index 6ee41cbd..e3cb760a 100644 --- a/pkg/siftool/add.go +++ b/pkg/siftool/add.go @@ -31,6 +31,7 @@ var ( partArch *int32 signHash *int32 signEntity *string + sbomFormat *string groupID *uint32 linkID *uint32 alignment *int @@ -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, @@ -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]") @@ -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 } @@ -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) { @@ -186,7 +219,8 @@ 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 } @@ -194,9 +228,8 @@ func getOptions(dt sif.DataType, fs *pflag.FlagSet) ([]sif.DescriptorInputOpt, e 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) @@ -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 diff --git a/pkg/siftool/testdata/TestAddCommands/Add/out.golden b/pkg/siftool/testdata/TestAddCommands/Add/out.golden index 5f8e2399..3f39697a 100644 --- a/pkg/siftool/testdata/TestAddCommands/Add/out.golden +++ b/pkg/siftool/testdata/TestAddCommands/Add/out.golden @@ -12,9 +12,9 @@ Flags: --alignment int set alignment [default: 4096 with -datatype 4-Partition, 0 otherwise] --datatype int 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 --filename string set logical filename/handle [default: input filename] --groupid uint32 set groupid [default: 0] -h, --help help for add @@ -33,6 +33,10 @@ Flags: [NEEDED, no default]: 1-System, 2-PrimSys, 3-Data, 4-Overlay + --sbomformat string the SBOM format (with -datatype 9-sbom): + cyclonedx-json, cyclonedx-xml, github-json, + spdx-json, spdx-rdf, spdx-tag-value, + spdx-yaml, syft-json --signentity string the entity that signs (with -datatype 5-Signature) [NEEDED, no default]: example: 433FE984155206BD962725E20E8713472A879943 From 7aeda3b5699e05587d7e80d01f78938cfda240f3 Mon Sep 17 00:00:00 2001 From: Adam Hughes <9903835+tri-adam@users.noreply.github.com> Date: Fri, 21 Oct 2022 14:17:38 +0000 Subject: [PATCH 2/4] test: add unit tests for SBOM functionality Add SIF with SBOM to test corpus. Add siftool unit tests to cover SBOM functionality. Signed-off-by: Edita Kizinevic --- internal/app/siftool/info_test.go | 15 +++++++++++- .../TestApp_Header/OneObjectSBOM.golden | 7 ++++++ .../siftool/testdata/TestApp_Info/SBOM.golden | 7 ++++++ .../TestApp_List/OneObjectSBOM.golden | 4 ++++ test/gen_sifs.go | 17 ++++++++++++++ test/images/one-object-sbom.sif | Bin 0 -> 32630 bytes test/input/sbom.cdx.json | 22 ++++++++++++++++++ 7 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 internal/app/siftool/testdata/TestApp_Header/OneObjectSBOM.golden create mode 100644 internal/app/siftool/testdata/TestApp_Info/SBOM.golden create mode 100644 internal/app/siftool/testdata/TestApp_List/OneObjectSBOM.golden create mode 100755 test/images/one-object-sbom.sif create mode 100644 test/input/sbom.cdx.json diff --git a/internal/app/siftool/info_test.go b/internal/app/siftool/info_test.go index 04206e4c..2ac93f0c 100644 --- a/internal/app/siftool/info_test.go +++ b/internal/app/siftool/info_test.go @@ -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. @@ -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"), @@ -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"), @@ -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"), diff --git a/internal/app/siftool/testdata/TestApp_Header/OneObjectSBOM.golden b/internal/app/siftool/testdata/TestApp_Header/OneObjectSBOM.golden new file mode 100644 index 00000000..6d2c2541 --- /dev/null +++ b/internal/app/siftool/testdata/TestApp_Header/OneObjectSBOM.golden @@ -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 diff --git a/internal/app/siftool/testdata/TestApp_Info/SBOM.golden b/internal/app/siftool/testdata/TestApp_Info/SBOM.golden new file mode 100644 index 00000000..e77d60f6 --- /dev/null +++ b/internal/app/siftool/testdata/TestApp_Info/SBOM.golden @@ -0,0 +1,7 @@ + Data Type: SBOM + ID: 1 + Group ID: 1 + Linked ID: NONE + Offset: 32176 + Size: 454 + Format: cyclonedx-json diff --git a/internal/app/siftool/testdata/TestApp_List/OneObjectSBOM.golden b/internal/app/siftool/testdata/TestApp_List/OneObjectSBOM.golden new file mode 100644 index 00000000..00cddaa7 --- /dev/null +++ b/internal/app/siftool/testdata/TestApp_List/OneObjectSBOM.golden @@ -0,0 +1,4 @@ +------------------------------------------------------------------------------ +ID |GROUP |LINK |SIF POSITION (start-end) |TYPE +------------------------------------------------------------------------------ +1 |1 |NONE |32176-32630 |SBOM (cyclonedx-json) diff --git a/test/gen_sifs.go b/test/gen_sifs.go index 60c82db3..62cf90a4 100755 --- a/test/gen_sifs.go +++ b/test/gen_sifs.go @@ -62,6 +62,17 @@ func generateImages() error { ) } + objectSBOM := func() (sif.DescriptorInput, error) { + b, err := os.ReadFile(filepath.Join("input", "sbom.cdx.json")) + if err != nil { + return sif.DescriptorInput{}, err + } + + return sif.NewDescriptorInput(sif.DataSBOM, bytes.NewReader(b), + sif.OptSBOMMetadata(sif.SBOMFormatCycloneDXJSON), + ) + } + partSystem := func() (sif.DescriptorInput, error) { return sif.NewDescriptorInput(sif.DataPartition, bytes.NewReader([]byte{0xfa, 0xce, 0xfe, 0xed}), @@ -137,6 +148,12 @@ func generateImages() error { objectCryptoMessage, }, }, + { + path: "one-object-sbom.sif", + diFns: []func() (sif.DescriptorInput, error){ + objectSBOM, + }, + }, // Images with two partitions in one group. { diff --git a/test/images/one-object-sbom.sif b/test/images/one-object-sbom.sif new file mode 100755 index 0000000000000000000000000000000000000000..339cde2a45feb0c26994ca0104fa32ee8824950a GIT binary patch literal 32630 zcmeI$L2J}N6u|NH*gg3XmYkb)l4ji`C#6#9K`)9FrN}fh(ZD8Il5Am-z58+cDf)Tz z6Rb0n7^Q+YVGsYn@?hr8dvAX^O+4@4&)ciZPp@CRy1MX0=n3(6@@f6;$Ki1B#`tv1 zm@=OX3-{F+_d|R*850QzAbs+uUP%_?~b~Z-ZG7KmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0 z009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{ z1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0k1fv>aq+`nzA z%ciYl?`L!WVwbO*TED#Z&+J~e(fNDbc4brB-Ea|)>$)xF`pvew)vevwwsp4MmMY7I zPLxcOU?qz@h!e32l2nF48YMD}Rj$%d3?=TSvY~5L>0T+TE_` z|6Kn)nlBd1bRqn)@ZQB6JFjV*H`T^i)fR3T*(@5(pw)#fD@75VtEEbG{7k9ka%$oC qyNzp{H+3(|+87Qc&G}z5m6iOg7hPEly=~{cbDFxke|$6B&wc{Q9FtT4 literal 0 HcmV?d00001 diff --git a/test/input/sbom.cdx.json b/test/input/sbom.cdx.json new file mode 100644 index 00000000..e4e722aa --- /dev/null +++ b/test/input/sbom.cdx.json @@ -0,0 +1,22 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "serialNumber": "urn:uuid:c0e8da98-7afc-4807-89a1-928a14dcd910", + "version": 1, + "metadata": { + "timestamp": "2022-10-21T13:27:49Z", + "tools": [ + { + "vendor": "anchore", + "name": "syft", + "version": "0.59.0" + } + ], + "component": { + "bom-ref": "a0f23d5d8e46dd55", + "type": "container", + "name": "image.sif" + } + }, + "components": [] +} From 03ad9c69f8732a136361fd5bbd9ff8265e72af52 Mon Sep 17 00:00:00 2001 From: Adam Hughes <9903835+tri-adam@users.noreply.github.com> Date: Thu, 27 Oct 2022 20:08:39 +0000 Subject: [PATCH 3/4] fix: handle signatures without fingerprints Handle cases where fingerprint is not set in signature descriptor. Signed-off-by: Edita Kizinevic --- internal/app/siftool/info.go | 5 ++- pkg/integrity/select.go | 4 +++ pkg/sif/descriptor.go | 5 +++ pkg/sif/descriptor_test.go | 59 +++++++++++++++++++----------------- 4 files changed, 44 insertions(+), 29 deletions(-) diff --git a/internal/app/siftool/info.go b/internal/app/siftool/info.go index 2979da95..20a14931 100644 --- a/internal/app/siftool/info.go +++ b/internal/app/siftool/info.go @@ -208,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() diff --git a/pkg/integrity/select.go b/pkg/integrity/select.go index 981e7aaf..f0e6c530 100644 --- a/pkg/integrity/select.go +++ b/pkg/integrity/select.go @@ -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 diff --git a/pkg/sif/descriptor.go b/pkg/sif/descriptor.go index 83fc9caf..05d96a1a 100644 --- a/pkg/sif/descriptor.go +++ b/pkg/sif/descriptor.go @@ -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 diff --git a/pkg/sif/descriptor_test.go b/pkg/sif/descriptor_test.go index 6046951f..c128eddf 100644 --- a/pkg/sif/descriptor_test.go +++ b/pkg/sif/descriptor_test.go @@ -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() @@ -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) } } From bc6d8797a194f125b4fafeabc7e1843018f62236 Mon Sep 17 00:00:00 2001 From: Adam Hughes <9903835+tri-adam@users.noreply.github.com> Date: Thu, 27 Oct 2022 20:41:00 +0000 Subject: [PATCH 4/4] deps: bump github.com/ProtonMail/go-crypto from v0.0.0-20220930113650-c6815a8c17ad to v0.0.0-20221026131551-cf6655e29de4 Signed-off-by: Edita Kizinevic --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 626cec2d..cfe80427 100644 --- a/go.mod +++ b/go.mod @@ -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 diff --git a/go.sum b/go.sum index 916b3504..dfb0077a 100644 --- a/go.sum +++ b/go.sum @@ -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=