Skip to content

Commit

Permalink
Merge pull request #157 from edytuk/v2.8.2
Browse files Browse the repository at this point in the history
Merge sylabs/sif through v2.8.2
  • Loading branch information
DrDaveD authored Oct 27, 2022
2 parents 7698e1d + 486f045 commit 40a54dc
Show file tree
Hide file tree
Showing 26 changed files with 938 additions and 1,009 deletions.
8 changes: 7 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,19 @@ jobs:
go mod tidy
git diff --exit-code -- go.mod go.sum
- name: Install govulncheck
run: go install golang.org/x/vuln/cmd/govulncheck@latest

- name: Check for vulnerabilities
run: $HOME/go/bin/govulncheck ./...

- name: Build Source
run: go build ./...

- name: Install Lint
uses: golangci/golangci-lint-action@v2
with:
version: v1.49
version: v1.50
skip-pkg-cache: true
skip-build-cache: true

Expand Down
1 change: 1 addition & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ linters:
- depguard
- dogsled
- dupl
- dupword
- errcheck
- errchkjson
- errname
Expand Down
4 changes: 1 addition & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@ module github.com/apptainer/sif/v2
go 1.18

require (
github.com/ProtonMail/go-crypto v0.0.0-20220824120805-4b6e5c587895
github.com/ProtonMail/go-crypto v0.0.0-20220930113650-c6815a8c17ad
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
github.com/hashicorp/go-multierror v1.1.1
github.com/pkg/errors v0.9.1
github.com/sebdah/goldie/v2 v2.5.3
github.com/spf13/cobra v1.6.1
Expand All @@ -22,7 +21,6 @@ require (
github.com/emirpasic/gods v1.12.0 // indirect
github.com/go-git/gcfg v1.5.0 // indirect
github.com/go-git/go-billy/v5 v5.3.1 // indirect
github.com/hashicorp/errwrap v1.0.0 // indirect
github.com/imdario/mergo v0.3.12 // indirect
github.com/inconshreveable/mousetrap v1.0.1 // indirect
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
Expand Down
8 changes: 2 additions & 6 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-20220824120805-4b6e5c587895 h1:NsReiLpErIPzRrnogAXYwSoU7txA977LjDGrbkewJbg=
github.com/ProtonMail/go-crypto v0.0.0-20220824120805-4b6e5c587895/go.mod h1:UBYPn8k0D56RtnR8RFQMjmh4KrZzWJ5o7Z9SYjossQ8=
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/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 Expand Up @@ -38,10 +38,6 @@ github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc=
Expand Down
113 changes: 52 additions & 61 deletions pkg/integrity/clearsign.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ package integrity
import (
"bytes"
"crypto"
"encoding/json"
"errors"
"io"
"time"

"github.com/ProtonMail/go-crypto/openpgp"
"github.com/ProtonMail/go-crypto/openpgp/clearsign"
Expand All @@ -23,90 +23,81 @@ import (

var errClearsignedMsgNotFound = errors.New("clearsigned message not found")

// Hash functions specified for OpenPGP in RFC4880, excluding those that are not currently
// recommended by NIST.
var supportedPGPAlgorithms = []crypto.Hash{
crypto.SHA224,
crypto.SHA256,
crypto.SHA384,
crypto.SHA512,
type clearsignEncoder struct {
e *openpgp.Entity
config *packet.Config
}

// hashAlgorithmSupported returns whether h is a supported PGP hash function.
func hashAlgorithmSupported(h crypto.Hash) bool {
for _, alg := range supportedPGPAlgorithms {
if alg == h {
return true
}
// newClearsignEncoder returns an encoder that signs messages in clear-sign format using entity e.
// If timeFunc is not nil, it is used to generate signature timestamps.
func newClearsignEncoder(e *openpgp.Entity, timeFunc func() time.Time) *clearsignEncoder {
return &clearsignEncoder{
e: e,
config: &packet.Config{
Time: timeFunc,
},
}
return false
}

// signAndEncodeJSON encodes v, clear-signs it with privateKey, and writes it to w. If config is
// nil, sensible defaults are used.
func signAndEncodeJSON(w io.Writer, v interface{}, privateKey *packet.PrivateKey, config *packet.Config) error {
if !hashAlgorithmSupported(config.Hash()) {
return errHashUnsupported
}

// Get clearsign encoder.
plaintext, err := clearsign.Encode(w, privateKey, config)
// signMessage signs the message from r in clear-sign format, and writes the result to w. On
// success, the hash function is returned.
func (en *clearsignEncoder) signMessage(w io.Writer, r io.Reader) (crypto.Hash, error) {
plaintext, err := clearsign.Encode(w, en.e.PrivateKey, en.config)
if err != nil {
return err
return 0, err
}
defer plaintext.Close()

// Wrap clearsign encoder with JSON encoder.
return json.NewEncoder(plaintext).Encode(v)
_, err = io.Copy(plaintext, r)
return en.config.Hash(), err
}

// verifyAndDecodeJSON reads the first clearsigned message in data, verifies its signature, and
// returns the signing entity any suffix of data which follows the message. The plaintext is
// unmarshalled to v (if not nil).
func verifyAndDecodeJSON(data []byte, v interface{}, kr openpgp.KeyRing) (*openpgp.Entity, []byte, error) {
// Decode clearsign block and check signature.
e, plaintext, rest, err := verifyAndDecode(data, kr)
if err != nil {
return e, rest, err
}
type clearsignDecoder struct {
kr openpgp.KeyRing
}

// Unmarshal plaintext, if requested.
if v != nil {
err = json.Unmarshal(plaintext, v)
// newClearsignDecoder returns a decoder that verifies messages in clear-sign format using key
// material from kr.
func newClearsignDecoder(kr openpgp.KeyRing) *clearsignDecoder {
return &clearsignDecoder{
kr: kr,
}
return e, rest, err
}

// verifyAndDecode reads the first clearsigned message in data, verifies its signature, and returns
// the signing entity, plaintext and suffix of data which follows the message.
func verifyAndDecode(data []byte, kr openpgp.KeyRing) (*openpgp.Entity, []byte, []byte, error) {
// verifyMessage reads a message from r, verifies its signature, and returns the message contents.
// On success, the signing entity is set in vr.
func (de *clearsignDecoder) verifyMessage(r io.Reader, h crypto.Hash, vr *VerifyResult) ([]byte, error) {
data, err := io.ReadAll(r)
if err != nil {
return nil, err
}

// Decode clearsign block.
b, rest := clearsign.Decode(data)
b, _ := clearsign.Decode(data)
if b == nil {
return nil, nil, rest, errClearsignedMsgNotFound
return nil, errClearsignedMsgNotFound
}

// Hash functions specified for OpenPGP in RFC4880, excluding those that are not currently
// recommended by NIST.
expectedHashes := []crypto.Hash{
crypto.SHA224,
crypto.SHA256,
crypto.SHA384,
crypto.SHA512,
}

// Check signature.
e, err := openpgp.CheckDetachedSignatureAndHash(
kr,
vr.e, err = openpgp.CheckDetachedSignatureAndHash(
de.kr,
bytes.NewReader(b.Bytes),
b.ArmoredSignature.Body,
supportedPGPAlgorithms,
expectedHashes,
nil,
)
return e, b.Plaintext, rest, err
}

// isLegacySignature reads the first clearsigned message in data, and returns true if the plaintext
// contains a legacy signature.
func isLegacySignature(data []byte) (bool, error) {
// Decode clearsign block.
b, _ := clearsign.Decode(data)
if b == nil {
return false, errClearsignedMsgNotFound
if err != nil {
return nil, err
}

// The plaintext of legacy signatures always begins with "SIFHASH", and non-legacy signatures
// never do, as they are JSON.
return bytes.HasPrefix(b.Plaintext, []byte("SIFHASH:\n")), nil
return b.Plaintext, err
}
Loading

0 comments on commit 40a54dc

Please sign in to comment.