Skip to content

Commit

Permalink
Add fuzzing test for getting password (sigstore#93)
Browse files Browse the repository at this point in the history
* Add fuzzing test to cosign

Signed-off-by: Priya Wadhwa <[email protected]>

* Move fuzzing into test directory, add Makefile for building fuzz target

Signed-off-by: Priya Wadhwa <[email protected]>

* Add build tag for fuzzingg

Signed-off-by: Priya Wadhwa <[email protected]>

* Fix test

Signed-off-by: Priya Wadhwa <[email protected]>

* Fix lint

Signed-off-by: Priya Wadhwa <[email protected]>

* Define Read function immediately

Signed-off-by: Priya Wadhwa <[email protected]>
  • Loading branch information
priyawadhwa authored Mar 16, 2021
1 parent 561f8f2 commit 38e0cae
Show file tree
Hide file tree
Showing 8 changed files with 75 additions and 14 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,6 @@ cosign.pub
/cosign
.vscode

# fuzzing artifacts
*.libfuzzer
*fuzz.a
32 changes: 21 additions & 11 deletions cmd/cosign/cli/generate_key_pair.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ import (
"golang.org/x/term"
)

var (
// Read is for fuzzing
Read = readPasswordFn
)

func GenerateKeyPair() *ffcli.Command {
var (
flagset = flag.NewFlagSet("cosign generate-key-pair", flag.ExitOnError)
Expand All @@ -57,7 +62,7 @@ func GenerateKeyPairCmd(ctx context.Context, kmsVal string) error {
return k.CreateKey(ctx)
}

keys, err := cosign.GenerateKeyPair(getPass)
keys, err := cosign.GenerateKeyPair(GetPass)
if err != nil {
return err
}
Expand All @@ -74,16 +79,8 @@ func GenerateKeyPairCmd(ctx context.Context, kmsVal string) error {
return nil
}

func getPass(confirm bool) ([]byte, error) {
// Handle piped in passwords.
var read = func() ([]byte, error) {
return term.ReadPassword(0)
}
if !term.IsTerminal(0) {
read = func() ([]byte, error) {
return ioutil.ReadAll(os.Stdin)
}
}
func GetPass(confirm bool) ([]byte, error) {
read := Read()
fmt.Fprint(os.Stderr, "Enter password for private key: ")
pw1, err := read()
fmt.Fprintln(os.Stderr)
Expand All @@ -105,3 +102,16 @@ func getPass(confirm bool) ([]byte, error) {
}
return pw1, nil
}

func readPasswordFn() func() ([]byte, error) {
// Handle piped in passwords.
r := func() ([]byte, error) {
return term.ReadPassword(0)
}
if !term.IsTerminal(0) {
r = func() ([]byte, error) {
return ioutil.ReadAll(os.Stdin)
}
}
return r
}
2 changes: 1 addition & 1 deletion cmd/cosign/cli/sign.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ func Sign() *ffcli.Command {
return flag.ErrHelp
}

return SignCmd(ctx, *key, args[0], *upload, *payloadPath, annotations.annotations, *kmsVal, getPass, *force)
return SignCmd(ctx, *key, args[0], *upload, *payloadPath, annotations.annotations, *kmsVal, GetPass, *force)
},
}
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/cosign/cli/sign_blob.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ func SignBlob() *ffcli.Command {
return flag.ErrHelp
}

_, err := SignBlobCmd(ctx, *key, args[0], *b64, getPass)
_, err := SignBlobCmd(ctx, *key, args[0], *b64, GetPass)
return err
},
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/cosign/cli/sign_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func TestSignCmdLocalKeyAndKms(t *testing.T) {
keyPath := "testLocalPath"
kmsVal := "testKmsVal"

err := SignCmd(ctx, keyPath, "", false, "", map[string]string{}, kmsVal, getPass, false)
err := SignCmd(ctx, keyPath, "", false, "", map[string]string{}, kmsVal, GetPass, false)

if (errors.Is(err, &KeyParseError{}) == false) {
t.Fatal("expected KeyParseError")
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ go 1.15
require (
cloud.google.com/go v0.79.0
github.com/coreos/go-oidc v2.2.1+incompatible
github.com/dvyukov/go-fuzz v0.0.0-20210103155950-6a8e9d1f2415 // indirect
github.com/go-openapi/runtime v0.19.26
github.com/go-openapi/strfmt v0.20.0
github.com/go-openapi/swag v0.19.14
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,8 @@ github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDD
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/dvyukov/go-fuzz v0.0.0-20210103155950-6a8e9d1f2415 h1:q1oJaUPdmpDm/VyXosjgPgr6wS7c5iV2p0PwJD73bUI=
github.com/dvyukov/go-fuzz v0.0.0-20210103155950-6a8e9d1f2415/go.mod h1:11Gm+ccJnvAhCNLlf5+cS9KjtbaD5I5zaZpFMsTHWTw=
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
Expand Down
45 changes: 45 additions & 0 deletions test/fuzz.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// +build gofuzz

/*
Copyright The Rekor Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package cli

import (
"bytes"
"fmt"

"github.com/sigstore/cosign/cmd/cosign/cli"
)

func FuzzGetPassword(data []byte) int {
original := cli.Read
cli.Read = func() func() ([]byte, error) {
return func() ([]byte, error) {
return data, nil
}
}
defer func() { cli.Read = original }()
p, err := cli.GetPass(true)
if err != nil {
panic(fmt.Sprintf("error getting password: %v", err))
}
// the password we got back is not what was entered
if bytes.Compare(p, data) != 0 {
panic(fmt.Sprintf("input does not match output: %s %s", string(p), string(data)))
}
return 0
}

0 comments on commit 38e0cae

Please sign in to comment.