Skip to content

Commit

Permalink
CHORE: move signer locgic out of cmd
Browse files Browse the repository at this point in the history
  • Loading branch information
Cole Kennedy authored and mikhailswift committed Apr 1, 2022
1 parent e194af8 commit 6221b9d
Show file tree
Hide file tree
Showing 5 changed files with 143 additions and 69 deletions.
78 changes: 17 additions & 61 deletions cmd/witness/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@ package cmd

import (
"context"
"crypto/x509"
"fmt"
"os"

"github.com/spf13/cobra"
"github.com/testifysec/witness/cmd/witness/options"
"github.com/testifysec/witness/pkg/cryptoutil"
"github.com/testifysec/witness/pkg/log"
"github.com/testifysec/witness/pkg/spiffe"
"github.com/testifysec/witness/pkg/signer/file"
"github.com/testifysec/witness/pkg/signer/spiffe"
)

var (
Expand Down Expand Up @@ -67,73 +67,29 @@ func preRoot(cmd *cobra.Command, ro *options.RootOptions) {
}
}

func loadSigner(spiffePath, keyPath, certPath string, intermediatePaths []string) (cryptoutil.Signer, error) {
if spiffePath == "" && keyPath == "" {
return nil, fmt.Errorf("one of key or spiffe-socket flags must be provided")
} else if spiffePath != "" && keyPath != "" {
return nil, fmt.Errorf("only one of key or spiffe-socket flags may be provided")
}

if spiffePath != "" {
return spiffe.Signer(context.Background(), spiffePath)
}

keyFile, err := os.Open(keyPath)
if err != nil {
return nil, fmt.Errorf("failed to open key file: %v", err)
}
func loadSigners(ctx context.Context, ko options.KeyOptions) ([]cryptoutil.Signer, []error) {
signers := []cryptoutil.Signer{}
errors := []error{}

defer keyFile.Close()
key, err := cryptoutil.TryParseKeyFromReader(keyFile)
if err != nil {
return nil, fmt.Errorf("failed to load key: %v", err)
}

signerOpts := []cryptoutil.SignerOption{}
if certPath != "" {
leaf, err := loadCert(certPath)
if ko.SpiffePath != "" {
s, err := spiffe.Signer(ctx, ko.SpiffePath)
if err != nil {
return nil, fmt.Errorf("failed to load certificate: %v", err)
errors = append(errors, fmt.Errorf("failed to create signer: %v", err))
} else {
signers = append(signers, s)
}

signerOpts = append(signerOpts, cryptoutil.SignWithCertificate(leaf))
}

if len(intermediatePaths) > 0 {
intermediates := []*x509.Certificate{}
for _, path := range intermediatePaths {
cert, err := loadCert(path)
if err != nil {
return nil, fmt.Errorf("failed to load intermediate: %v", err)
}

intermediates = append(intermediates, cert)
if ko.KeyPath != "" {
s, err := file.Signer(ctx, ko.KeyPath, ko.CertPath, ko.IntermediatePaths)
if err != nil {
errors = append(errors, fmt.Errorf("failed to create signer: %v", err))
} else {
signers = append(signers, s)
}

signerOpts = append(signerOpts, cryptoutil.SignWithIntermediates(intermediates))
}

return cryptoutil.NewSigner(key, signerOpts...)
}

func loadCert(path string) (*x509.Certificate, error) {
certFile, err := os.Open(path)
if err != nil {
return nil, fmt.Errorf("failed to load certificate: %v", err)
}

defer certFile.Close()
possibleCert, err := cryptoutil.TryParseKeyFromReader(certFile)
if err != nil {
return nil, fmt.Errorf("failed to parse certificate")
}

cert, ok := possibleCert.(*x509.Certificate)
if !ok {
return nil, fmt.Errorf("%v is not a x509 certificate", path)
}

return cert, nil
return signers, errors
}

func loadOutfile(outFilePath string) (*os.File, error) {
Expand Down
25 changes: 21 additions & 4 deletions cmd/witness/cmd/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,13 @@
package cmd

import (
"context"
"encoding/json"
"fmt"

"github.com/spf13/cobra"
"github.com/testifysec/witness/cmd/witness/options"
"github.com/testifysec/witness/pkg"
witness "github.com/testifysec/witness/pkg"
"github.com/testifysec/witness/pkg/attestation"
"github.com/testifysec/witness/pkg/log"
"github.com/testifysec/witness/pkg/rekor"
Expand All @@ -44,11 +45,27 @@ func RunCmd() *cobra.Command {
}

func runRun(ro options.RunOptions, args []string) error {
signer, err := loadSigner(ro.KeyOptions.SpiffePath, ro.KeyOptions.KeyPath, ro.KeyOptions.CertPath, ro.KeyOptions.IntermediatePaths)
if err != nil {
return fmt.Errorf("failed to load signer: %w", err)
ctx := context.Background()
signers, errors := loadSigners(ctx, ro.KeyOptions)
if len(errors) > 0 {
for _, err := range errors {
log.Error(err)
}
return fmt.Errorf("failed to load signers")
}

if len(signers) > 1 {
log.Error("only one signer is supported")
return fmt.Errorf("only one signer is supported")
}

if len(signers) == 0 {
log.Error("no signers found")
return fmt.Errorf("no signers found")
}

signer := signers[0]

out, err := loadOutfile(ro.OutFilePath)
if err != nil {
return fmt.Errorf("failed to open out file: %w", err)
Expand Down
26 changes: 22 additions & 4 deletions cmd/witness/cmd/sign.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,14 @@
package cmd

import (
"context"
"fmt"
"os"

"github.com/spf13/cobra"
"github.com/testifysec/witness/cmd/witness/options"
"github.com/testifysec/witness/pkg"
witness "github.com/testifysec/witness/pkg"
"github.com/testifysec/witness/pkg/log"
)

func SignCmd() *cobra.Command {
Expand All @@ -44,11 +46,27 @@ func SignCmd() *cobra.Command {
//todo: this logic should be broken out and moved to pkg/
//we need to abstract where keys are coming from, etc
func runSign(so options.SignOptions) error {
signer, err := loadSigner(so.KeyOptions.SpiffePath, so.KeyOptions.KeyPath, so.KeyOptions.CertPath, so.KeyOptions.IntermediatePaths)
if err != nil {
return err
ctx := context.Background()
signers, errors := loadSigners(ctx, so.KeyOptions)
if len(errors) > 0 {
for _, err := range errors {
log.Error(err)
}
return fmt.Errorf("failed to load signers")
}

if len(signers) > 1 {
log.Error("only one signer is supported")
return fmt.Errorf("only one signer is supported")
}

if len(signers) == 0 {
log.Error("no signers found")
return fmt.Errorf("no signers found")
}

signer := signers[0]

inFile, err := os.Open(so.InFilePath)
if err != nil {
return fmt.Errorf("failed to open file to sign: %v", err)
Expand Down
83 changes: 83 additions & 0 deletions pkg/signer/file/file.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// Copyright 2022 The Witness Contributors
//
// 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 file

import (
"context"
"crypto/x509"
"fmt"
"os"

"github.com/testifysec/witness/pkg/cryptoutil"
)

func Signer(ctx context.Context, keyPath, certPath string, intermediatePaths []string) (cryptoutil.Signer, error) {
keyFile, err := os.Open(keyPath)
if err != nil {
return nil, fmt.Errorf("failed to open key file: %v", err)
}

defer keyFile.Close()
key, err := cryptoutil.TryParseKeyFromReader(keyFile)
if err != nil {
return nil, fmt.Errorf("failed to load key: %v", err)
}

signerOpts := []cryptoutil.SignerOption{}
if certPath != "" {
leaf, err := loadCert(certPath)
if err != nil {
return nil, fmt.Errorf("failed to load certificate: %v", err)
}

signerOpts = append(signerOpts, cryptoutil.SignWithCertificate(leaf))
}

if len(intermediatePaths) > 0 {
intermediates := []*x509.Certificate{}
for _, path := range intermediatePaths {
cert, err := loadCert(path)
if err != nil {
return nil, fmt.Errorf("failed to load intermediate: %v", err)
}

intermediates = append(intermediates, cert)
}

signerOpts = append(signerOpts, cryptoutil.SignWithIntermediates(intermediates))
}

return cryptoutil.NewSigner(key, signerOpts...)
}

func loadCert(path string) (*x509.Certificate, error) {
certFile, err := os.Open(path)
if err != nil {
return nil, fmt.Errorf("failed to load certificate: %v", err)
}

defer certFile.Close()
possibleCert, err := cryptoutil.TryParseKeyFromReader(certFile)
if err != nil {
return nil, fmt.Errorf("failed to parse certificate")
}

cert, ok := possibleCert.(*x509.Certificate)
if !ok {
return nil, fmt.Errorf("%v is not a x509 certificate", path)
}

return cert, nil
}
File renamed without changes.

0 comments on commit 6221b9d

Please sign in to comment.