Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ BOOTSTRAP_CACHE="c7afb99ad"

# ci dependency versions
QUILL_VERSION = latest
GOLANG_CI_VERSION = v1.49.0
GOLANG_CI_VERSION = v1.52.2
GOBOUNCER_VERSION = v0.4.0
GORELEASER_VERSION = v1.11.5
GOSIMPORTS_VERSION = v0.3.2
Expand Down
3 changes: 1 addition & 2 deletions cmd/quill/cli/commands/extract_certificates.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,8 @@ func extractCertificates(binPath string, leaf bool) (string, error) {
if leaf && c.Parsed.IsCA {
log.WithFields("signer", i+1, "certificate", j+1, "cn", c.Parsed.Subject.CommonName).Tracef("skipping certificate")
continue
} else {
log.WithFields("signer", i+1, "certificate", j+1, "cn", c.Parsed.Subject.CommonName).Tracef("parsed certificate")
}
log.WithFields("signer", i+1, "certificate", j+1, "cn", c.Parsed.Subject.CommonName).Tracef("parsed certificate")

decodedCerts = append(decodedCerts, pem.Block{
Type: "CERTIFICATE",
Expand Down
2 changes: 1 addition & 1 deletion cmd/quill/cli/commands/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
"github.com/anchore/quill/internal/version"
)

func Version(app *application.Application) *cobra.Command {
func Version(_ *application.Application) *cobra.Command {
var format string

cmd := &cobra.Command{
Expand Down
5 changes: 1 addition & 4 deletions cmd/quill/cli/options/describe.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,5 @@ func (o *Describe) AddFlags(flags *pflag.FlagSet) {
}

func (o *Describe) BindFlags(flags *pflag.FlagSet, v *viper.Viper) error {
if err := Bind(v, "describe.detail", flags.Lookup("detail")); err != nil {
return err
}
return nil
return Bind(v, "describe.detail", flags.Lookup("detail"))
}
5 changes: 1 addition & 4 deletions cmd/quill/cli/options/extract_certificates.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,5 @@ func (o *ExtractCertificates) AddFlags(flags *pflag.FlagSet) {
}

func (o *ExtractCertificates) BindFlags(flags *pflag.FlagSet, v *viper.Viper) error {
if err := Bind(v, "extract-certificates.leaf", flags.Lookup("leaf")); err != nil {
return err
}
return nil
return Bind(v, "extract-certificates.leaf", flags.Lookup("leaf"))
}
5 changes: 1 addition & 4 deletions cmd/quill/cli/options/format.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,5 @@ func (o *Format) AddFlags(flags *pflag.FlagSet) {
}

func (o *Format) BindFlags(flags *pflag.FlagSet, v *viper.Viper) error {
if err := Bind(v, "output", flags.Lookup("output")); err != nil {
return err
}
return nil
return Bind(v, "output", flags.Lookup("output"))
}
6 changes: 1 addition & 5 deletions cmd/quill/cli/options/keychain.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,5 @@ func (o *Keychain) AddFlags(flags *pflag.FlagSet) {
}

func (o *Keychain) BindFlags(flags *pflag.FlagSet, v *viper.Viper) error {
if err := Bind(v, "keychain.path", flags.Lookup("keychain-path")); err != nil {
return err
}

return nil
return Bind(v, "keychain.path", flags.Lookup("keychain-path"))
}
6 changes: 1 addition & 5 deletions cmd/quill/cli/options/notary.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,5 @@ func (o *Notary) BindFlags(flags *pflag.FlagSet, v *viper.Viper) error {
if err := Bind(v, "notary.key-id", flags.Lookup("notary-key-id")); err != nil {
return err
}
if err := Bind(v, "notary.key", flags.Lookup("notary-key")); err != nil {
return err
}

return nil
return Bind(v, "notary.key", flags.Lookup("notary-key"))
}
4 changes: 2 additions & 2 deletions cmd/quill/cli/options/p12.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ func (o *P12) Redact() {
log.Redact(o.Password)
}

func (o *P12) AddFlags(flags *pflag.FlagSet) {
func (o *P12) AddFlags(_ *pflag.FlagSet) {
}

func (o *P12) BindFlags(flags *pflag.FlagSet, v *viper.Viper) error {
func (o *P12) BindFlags(_ *pflag.FlagSet, v *viper.Viper) error {
// set default values for non-bound struct items
v.SetDefault("p12.password", o.Password)

Expand Down
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ require (
github.com/anchore/go-logger v0.0.0-20220728155337-03b66a5207d8
github.com/anchore/go-macholibre v0.0.0-20220308212642-53e6d0aaf6fb
github.com/aws/aws-sdk-go v1.44.114
github.com/blacktop/go-macho v1.1.83
github.com/blacktop/go-macho v1.1.151
github.com/charmbracelet/bubbles v0.11.0
github.com/charmbracelet/bubbletea v0.22.1
github.com/charmbracelet/lipgloss v0.6.0
Expand Down Expand Up @@ -44,6 +44,7 @@ require (
github.com/andybalholm/cascadia v1.3.1 // indirect
github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef // indirect
github.com/atotto/clipboard v0.1.4 // indirect
github.com/blacktop/go-dwarf v1.0.9 // indirect
github.com/charmbracelet/harmonica v0.2.0 // indirect
github.com/containerd/console v1.0.3 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
Expand Down
6 changes: 4 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,10 @@ github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
github.com/blacktop/go-macho v1.1.83 h1:Qx9k4IsOD6rVx7G4SrwJbVcoCL5eUK2gORlaHNazPcc=
github.com/blacktop/go-macho v1.1.83/go.mod h1:7Dj52AvN6Hof0+LNBHC3VQHbdDBnLM5kBrKBYbk6/3g=
github.com/blacktop/go-dwarf v1.0.9 h1:eT/L7gt0gllvvgnRXY0MFKjNB6+jtOY5DTm2ynVX2dY=
github.com/blacktop/go-dwarf v1.0.9/go.mod h1:4W2FKgSFYcZLDwnR7k+apv5i3nrau4NGl9N6VQ9DSTo=
github.com/blacktop/go-macho v1.1.151 h1:78x8/H5OjIlrlBweRNukjLUkpQ2F6zV9sePvz5CCl/o=
github.com/blacktop/go-macho v1.1.151/go.mod h1:f2X4noFBob4G5bWUrzvPBKDVcFWZgDCM7rIn7ygTID0=
github.com/certifi/gocertifi v0.0.0-20180118203423-deb3ae2ef261/go.mod h1:GJKEexRPVJrBSOjoqN5VNOIKJ5Q3RViH6eu3puDRwx4=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/charmbracelet/bubbles v0.11.0 h1:fBLyY0PvJnd56Vlu5L84JJH6f4axhgIJ9P3NET78f0Q=
Expand Down
2 changes: 1 addition & 1 deletion internal/ui/tui/bubbles/testutil/run_model.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
tea "github.com/charmbracelet/bubbletea"
)

func RunModel(t testing.TB, m tea.Model, iterations int, message tea.Msg) string {
func RunModel(_ testing.TB, m tea.Model, iterations int, message tea.Msg) string {
if iterations == 0 {
iterations = 1
}
Expand Down
2 changes: 1 addition & 1 deletion internal/ui/tui/ui.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ type UI struct {
quiet bool
}

func New(debug, quiet bool) *UI {
func New(_, quiet bool) *UI {
s := spinner.New()
s.Spinner = spinner.MiniDot
s.Style = lipgloss.NewStyle().Foreground(lipgloss.Color("205"))
Expand Down
6 changes: 1 addition & 5 deletions quill/event/parser/exit.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,5 @@ import (
)

func Exit(e partybus.Event) error {
if err := checkEventType(e.Type, event.Exit); err != nil {
return err
}

return nil
return checkEventType(e.Type, event.Exit)
}
2 changes: 1 addition & 1 deletion quill/extract/code_directory.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ func getCodeDirectories(m File) (cdObjs []CodeDirectoryDetails) {
},
TeamID: cd.TeamID,
ID: cd.ID,
Platform: cd.Header.Platform,
Platform: uint8(cd.Header.Platform),
Version: DescribedValue{
Value: cd.Header.Version,
Description: cd.Header.Version.String(),
Expand Down
2 changes: 1 addition & 1 deletion quill/extract/entitlements.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ type EntitlementDetails struct {
Blob BlobDetails `json:"blob"`
}

func getEntitlements(m File) []EntitlementDetails {
func getEntitlements(_ File) []EntitlementDetails {
// TODO
return nil
}
2 changes: 1 addition & 1 deletion quill/extract/macho.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ func getMachoDetails(m File) MachoDetails {
Type: m.blacktopFile.Type.String(),
CPU: m.blacktopFile.CPU.String(),
SubCPU: m.blacktopFile.SubCPU.String(m.blacktopFile.CPU),
Flags: m.blacktopFile.Flags.List(),
Flags: m.blacktopFile.Flags.Flags(),
Libs: m.blacktopFile.ImportedLibraries(),
LoadCommandCount: m.blacktopFile.NCommands,
LoadCommandSize: m.blacktopFile.SizeCommands,
Expand Down
5 changes: 1 addition & 4 deletions quill/macho/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,7 @@ func (m *File) Close() error {
if err := m.ReadSeekCloser.Close(); err != nil {
return err
}
if err := m.File.Close(); err != nil {
return err
}
return nil
return m.File.Close()
}

func (m *File) Patch(content []byte, size int, offset uint64) (err error) {
Expand Down
8 changes: 8 additions & 0 deletions quill/notarize.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,14 @@ func Notarize(path string, cfg NotarizeConfig) (notary.SubmissionStatus, error)

defer mon.SetCompleted()

mon.Stage.Current = "validating binary"

if isSigned, err := IsSigned(path); err != nil {
return "", fmt.Errorf("unable to determine if binary is signed: %+v", err)
} else if !isSigned {
return "", fmt.Errorf("binary is not signed thus will not pass notarization")
}

mon.Stage.Current = "initializing client"

token, err := notary.NewSignedToken(cfg.TokenConfig)
Expand Down
53 changes: 53 additions & 0 deletions quill/sign.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (
"os"
"path"

blacktopMacho "github.com/blacktop/go-macho"

macholibre "github.com/anchore/go-macholibre"
"github.com/anchore/quill/internal/bus"
"github.com/anchore/quill/internal/log"
Expand Down Expand Up @@ -248,3 +250,54 @@ func signSingleBinary(cfg SigningConfig) error {

return nil
}

func IsSigned(path string) (bool, error) {
f, err := os.Open(path)
if err != nil {
return false, err
}
defer f.Close()

if macholibre.IsUniversalMachoBinary(f) {
log.WithFields("binary", path).Trace("binary is a universal binary")
mf, err := blacktopMacho.NewFatFile(f)
if mf == nil || err != nil {
return false, fmt.Errorf("failed to parse universal macho binary: %w", err)
}
defer mf.Close()

success := true
for _, arch := range mf.Arches {
sig := arch.CodeSignature()
if sig == nil {
log.WithFields("binary", path, "arch", arch.String()).Trace("no code signature block found")

return false, nil
}
log.WithFields("length", len(sig.CMSSignature), "arch", arch.String()).Trace("CMS signature found")

success = success && len(sig.CMSSignature) > 0
}

return success, nil
}

log.WithFields("binary", path).Trace("binary is for a single architecture")

mf, err := blacktopMacho.NewFile(f)
if mf == nil || err != nil {
return false, fmt.Errorf("failed to parse macho binary: %w", err)
}

defer mf.Close()

sig := mf.CodeSignature()
if sig == nil {
log.WithFields("binary", path).Trace("no code signature block found")
return false, nil
}

log.WithFields("length", len(sig.CMSSignature)).Trace("CMS signature found")

return len(sig.CMSSignature) > 0, nil
}
48 changes: 48 additions & 0 deletions quill/sign_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package quill
import (
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/anchore/quill/internal/test"
Expand Down Expand Up @@ -240,3 +241,50 @@ func TestSign(t *testing.T) {
})
}
}

func TestIsSigned(t *testing.T) {

tests := []struct {
name string
path string
isSigned bool
wantErr require.ErrorAssertionFunc
}{
{
name: "check unsigned syft binary",
path: test.AssetCopy(t, "syft_unsigned_arm64"),
isSigned: false,
},
{
name: "check signed, single arch binary",
path: test.AssetCopy(t, "syft_signed"),
isSigned: true,
},
{
name: "check signed, universal arch binary",
path: test.AssetCopy(t, "ls_universal_signed"),
isSigned: true,
},
{
name: "check non-macho file",
path: test.AssetCopy(t, "hello.p12"),
isSigned: false,
wantErr: require.Error,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {

if tt.wantErr == nil {
tt.wantErr = require.NoError
}

actual, err := IsSigned(tt.path)
tt.wantErr(t, err)
if err != nil {
return
}
assert.Equal(t, tt.isSigned, actual)
})
}
}
2 changes: 1 addition & 1 deletion test/cli/describe_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func Test_DescribeCommand(t *testing.T) {
asset: test.Asset(t, "hello_adhoc_signed"),
assertions: []trait.Assertion{
trait.AssertInStdout("64-bit MachO"), // the file section shows basic info
trait.AssertInStdout("0x10002"), // the Code Directory shows the Adhoc flag
trait.AssertInStdout("adhoc, runtime"), // the Code Directory shows the Adhoc + runtime flags
trait.AssertInStdout("there is no cryptographic signature"), // there is no signed data for ad-hoc signed binaries
trait.AssertSuccessfulReturnCode,
},
Expand Down