Skip to content

Commit

Permalink
Refactor a bit and add tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
Dan Lorenc committed Feb 15, 2021
1 parent e3d4b01 commit fd0c6ad
Show file tree
Hide file tree
Showing 8 changed files with 122 additions and 34 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@
# cosign stuff
cosign.key
cosign.pub
cosign
/cosign
26 changes: 4 additions & 22 deletions cmd/generate_key_pair.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,14 @@ package main

import (
"context"
"crypto/ed25519"
"crypto/rand"
"encoding/pem"
"errors"
"flag"
"fmt"
"io/ioutil"
"os"

"github.com/theupdateframework/go-tuf/encrypted"
"github.com/projectcosign/cosign/pkg/cosign"

"github.com/peterbourgon/ff/v3/ffcli"
"golang.org/x/term"
Expand All @@ -50,36 +48,20 @@ func GenerateKeyPair() *ffcli.Command {
}

func generateKeyPair(ctx context.Context) error {
pub, priv, err := ed25519.GenerateKey(rand.Reader)
keys, err := cosign.GenerateKeyPair(getPass)
if err != nil {
return err
}

// Encrypt the private key and store it.
password, err := getPass(true)
if err != nil {
return err
}

encBytes, err := encrypted.Encrypt(priv, password)
if err != nil {
return err
}

privBytes := pem.EncodeToMemory(&pem.Block{
Bytes: encBytes,
Type: "ENCRYPTED COSIGN PRIVATE KEY",
})
// TODO: make sure the perms are locked down first.
if err := ioutil.WriteFile("cosign.key", privBytes, 0600); err != nil {
if err := ioutil.WriteFile("cosign.key", keys.PrivateBytes, 0600); err != nil {
return err
}
fmt.Fprintln(os.Stderr, "Private key written to cosign.key")

// Now do the public key
pubBytes := pem.EncodeToMemory(&pem.Block{
Type: "COSIGN PUBLIC KEY",
Bytes: pub,
Bytes: keys.PublicBytes,
})
if err := ioutil.WriteFile("cosign.pub", pubBytes, 0600); err != nil {
return err
Expand Down
6 changes: 5 additions & 1 deletion cmd/sign.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,11 @@ func sign(ctx context.Context, keyPath string,
if err != nil {
return err
}
pk, err := cosign.LoadPrivateKey(keyPath, pass)
kb, err := ioutil.ReadFile(keyPath)
if err != nil {
return err
}
pk, err := cosign.LoadPrivateKey(kb, pass)
if err != nil {
return err
}
Expand Down
50 changes: 50 additions & 0 deletions pkg/cosign/keys.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package cosign

import (
"crypto/ed25519"
"crypto/rand"
"encoding/pem"

"github.com/theupdateframework/go-tuf/encrypted"
)

type PassFunc func(bool) ([]byte, error)

type Keys struct {
PrivateBytes []byte
PublicBytes []byte
}

func GenerateKeyPair(pf PassFunc) (*Keys, error) {
pub, priv, err := ed25519.GenerateKey(rand.Reader)
if err != nil {
return nil, err
}

// Encrypt the private key and store it.
password, err := pf(true)
if err != nil {
return nil, err
}

encBytes, err := encrypted.Encrypt(priv, password)
if err != nil {
return nil, err
}

privBytes := pem.EncodeToMemory(&pem.Block{
Bytes: encBytes,
Type: "ENCRYPTED COSIGN PRIVATE KEY",
})

// Now do the public key
pubBytes := pem.EncodeToMemory(&pem.Block{
Type: "COSIGN PUBLIC KEY",
Bytes: pub,
})

return &Keys{
PrivateBytes: privBytes,
PublicBytes: pubBytes,
}, nil
}
1 change: 0 additions & 1 deletion pkg/cosign/payload.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import (
)

func Payload(img v1.Descriptor, a map[string]string) ([]byte, error) {

simpleSigning := SimpleSigning{
Critical: Critical{
Image: Image{
Expand Down
14 changes: 6 additions & 8 deletions pkg/cosign/sign.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ package cosign
import (
"crypto/ed25519"
"encoding/pem"
"errors"
"fmt"
"io/ioutil"

"github.com/theupdateframework/go-tuf/encrypted"
)
Expand All @@ -30,14 +30,12 @@ const (
sigkey = "dev.cosignproject.cosign/signature"
)

func LoadPrivateKey(keyPath string, pass []byte) (ed25519.PrivateKey, error) {
b, err := ioutil.ReadFile(keyPath)
if err != nil {
return nil, err
}

func LoadPrivateKey(key []byte, pass []byte) (ed25519.PrivateKey, error) {
// Decrypt first
p, _ := pem.Decode(b)
p, _ := pem.Decode(key)
if p == nil {
return nil, errors.New("invalid pem block")
}
if p.Type != pemType {
return nil, fmt.Errorf("unsupported pem type: %s", p.Type)
}
Expand Down
56 changes: 56 additions & 0 deletions pkg/cosign/sign_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
Copyright The Cosign 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 cosign

import (
"crypto/rand"
"testing"
)

func pass(s string) PassFunc {
return func(_ bool) ([]byte, error) {
return []byte(s), nil
}
}

func TestLoadPrivateKey(t *testing.T) {
// Generate a valid keypair
keys, err := GenerateKeyPair(pass("hello"))
if err != nil {
t.Fatal(err)
}

// Load the private key with the right password
if _, err := LoadPrivateKey(keys.PrivateBytes, []byte("hello")); err != nil {
t.Errorf("unexpected error decrypting key: %s", err)
}

// Try it with the wrong one
if _, err := LoadPrivateKey(keys.PrivateBytes, []byte("wrong")); err == nil {
t.Error("expected error decrypting key!")
}

// Try to decrypt garbage
buf := [100]byte{}
if _, err := rand.Read(buf[:]); err != nil {
t.Fatal(err)
}
if _, err := LoadPrivateKey(buf[:], []byte("wrong")); err == nil {
t.Error("expected error decrypting key!")
}

}
1 change: 0 additions & 1 deletion pkg/cosign/verify.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ import (
const pubKeyPemType = "COSIGN PUBLIC KEY"

func LoadPublicKey(keyRef string) (ed25519.PublicKey, error) {

// The key could be plaintext or in a file.
// First check if the file exists.
if _, err := os.Stat(keyRef); os.IsNotExist(err) {
Expand Down

0 comments on commit fd0c6ad

Please sign in to comment.