Skip to content

Commit

Permalink
Added --client-signing-algorithms flag
Browse files Browse the repository at this point in the history
Signed-off-by: Riccardo Schirone <[email protected]>
  • Loading branch information
ret2libc committed Jan 29, 2024
1 parent 9865ca9 commit 55f01c3
Show file tree
Hide file tree
Showing 5 changed files with 144 additions and 9 deletions.
16 changes: 16 additions & 0 deletions cmd/rekor-server/app/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,14 @@ import (
"net/http"
"net/http/pprof"
"os"
"sort"
"strings"
"time"

homedir "github.com/mitchellh/go-homedir"
"github.com/sigstore/rekor/pkg/api"
"github.com/sigstore/rekor/pkg/log"
"github.com/sigstore/sigstore/pkg/signature"
"github.com/spf13/cobra"
"github.com/spf13/viper"

Expand Down Expand Up @@ -131,6 +135,18 @@ Memory and file-based signers should only be used for testing.`)
rootCmd.PersistentFlags().Int("search_index.mysql.max_open_connections", 0, "maximum open connections")
rootCmd.PersistentFlags().Int("search_index.mysql.max_idle_connections", 0, "maximum idle connections")

keyAlgorithmTypes := []string{}
for _, keyAlgorithm := range api.AllowedClientSigningAlgorithms {
keyFlag, err := signature.FormatSignatureAlgorithmFlag(keyAlgorithm)
if err != nil {
panic(err)
}
keyAlgorithmTypes = append(keyAlgorithmTypes, keyFlag)
}
sort.Strings(keyAlgorithmTypes)
keyAlgorithmHelp := fmt.Sprintf("signing algorithm to use for signing/hashing (allowed %s)", strings.Join(keyAlgorithmTypes, ", "))
rootCmd.PersistentFlags().StringSlice("client-signing-algorithms", keyAlgorithmTypes, keyAlgorithmHelp)

if err := viper.BindPFlags(rootCmd.PersistentFlags()); err != nil {
log.Logger.Fatal(err)
}
Expand Down
8 changes: 5 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ require (
github.com/rs/cors v1.10.1
github.com/sassoftware/relic v7.2.1+incompatible
github.com/secure-systems-lab/go-securesystemslib v0.8.0
github.com/sigstore/sigstore v1.8.1
github.com/spf13/cobra v1.8.0
github.com/spf13/pflag v1.0.5
github.com/spf13/viper v1.18.2
Expand Down Expand Up @@ -63,7 +62,8 @@ require (
github.com/jmoiron/sqlx v1.3.5
github.com/redis/go-redis/v9 v9.4.0
github.com/sassoftware/relic/v7 v7.6.1
github.com/sigstore/protobuf-specs v0.2.1
github.com/sigstore/protobuf-specs v0.3.0-beta.2
github.com/sigstore/sigstore v1.6.4
github.com/sigstore/sigstore/pkg/signature/kms/aws v1.8.1
github.com/sigstore/sigstore/pkg/signature/kms/azure v1.8.1
github.com/sigstore/sigstore/pkg/signature/kms/gcp v1.8.1
Expand Down Expand Up @@ -164,7 +164,7 @@ require (
github.com/godbus/dbus/v5 v5.1.0 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/go-containerregistry v0.17.0 // indirect
github.com/google/go-containerregistry v0.18.0 // indirect
github.com/google/uuid v1.5.0 // indirect
github.com/google/wire v0.5.0 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect
Expand Down Expand Up @@ -204,3 +204,5 @@ require (
gopkg.in/yaml.v2 v2.4.0
gopkg.in/yaml.v3 v3.0.1 // indirect
)

replace github.com/sigstore/sigstore => github.com/trail-of-forks/sigstore v0.0.0-20240129055912-d89eade746d5
12 changes: 6 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -215,8 +215,8 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-containerregistry v0.17.0 h1:5p+zYs/R4VGHkhyvgWurWrpJ2hW4Vv9fQI+GzdcwXLk=
github.com/google/go-containerregistry v0.17.0/go.mod h1:u0qB2l7mvtWVR5kNcbFIhFY1hLbf8eeGapA+vbFDCtQ=
github.com/google/go-containerregistry v0.18.0 h1:ShE7erKNPqRh5ue6Z9DUOlk04WsnFWPO6YGr3OxnfoQ=
github.com/google/go-containerregistry v0.18.0/go.mod h1:u0qB2l7mvtWVR5kNcbFIhFY1hLbf8eeGapA+vbFDCtQ=
github.com/google/go-replayers/grpcreplay v1.1.0 h1:S5+I3zYyZ+GQz68OfbURDdt/+cSMqCK1wrvNx7WBzTE=
github.com/google/go-replayers/grpcreplay v1.1.0/go.mod h1:qzAvJ8/wi57zq7gWqaE6AwLM6miiXUQwP1S+I9icmhk=
github.com/google/go-replayers/httpreplay v1.2.0 h1:VM1wEyyjaoU53BwrOnaf9VhAyQQEEioJvFYxYcLRKzk=
Expand Down Expand Up @@ -387,10 +387,8 @@ github.com/secure-systems-lab/go-securesystemslib v0.8.0 h1:mr5An6X45Kb2nddcFlbm
github.com/secure-systems-lab/go-securesystemslib v0.8.0/go.mod h1:UH2VZVuJfCYR8WgMlCU1uFsOUU+KeyrTWcSS73NBOzU=
github.com/shibumi/go-pathspec v1.3.0 h1:QUyMZhFo0Md5B8zV8x2tesohbb5kfbpTi9rBnKh5dkI=
github.com/shibumi/go-pathspec v1.3.0/go.mod h1:Xutfslp817l2I1cZvgcfeMQJG5QnU2lh5tVaaMCl3jE=
github.com/sigstore/protobuf-specs v0.2.1 h1:KIoM7E3C4uaK092q8YoSj/XSf9720f8dlsbYwwOmgEA=
github.com/sigstore/protobuf-specs v0.2.1/go.mod h1:xPqQGnH/HllKuZ4VFPz/g+78epWM/NLRGl7Fuy45UdE=
github.com/sigstore/sigstore v1.8.1 h1:mAVposMb14oplk2h/bayPmIVdzbq2IhCgy4g6R0ZSjo=
github.com/sigstore/sigstore v1.8.1/go.mod h1:02SL1158BSj15bZyOFz7m+/nJzLZfFd9A8ab3Kz7w/E=
github.com/sigstore/protobuf-specs v0.3.0-beta.2 h1:neHS0O1z7qz4q21vyXqSaKuKYxA0upzJERT88NrgYlM=
github.com/sigstore/protobuf-specs v0.3.0-beta.2/go.mod h1:ynKzXpqr3dUj2Xk9O/5ZUhjnpi0F53DNi5AdH6pS3jc=
github.com/sigstore/sigstore/pkg/signature/kms/aws v1.8.1 h1:rEDdUefulkIQaMJyzLwtgPDLNXBIltBABiFYfb0YmgQ=
github.com/sigstore/sigstore/pkg/signature/kms/aws v1.8.1/go.mod h1:RCdYCc1IxCYWzh2IdzdA6Yf7JIY0cMRqH08fpQYechw=
github.com/sigstore/sigstore/pkg/signature/kms/azure v1.8.1 h1:DvRWG99QGWZC5mp42SEde2Xke/Q384Idnj2da7yB+Mk=
Expand Down Expand Up @@ -432,6 +430,8 @@ github.com/theupdateframework/go-tuf v0.7.0 h1:CqbQFrWo1ae3/I0UCblSbczevCCbS31Qv
github.com/theupdateframework/go-tuf v0.7.0/go.mod h1:uEB7WSY+7ZIugK6R1hiBMBjQftaFzn7ZCDJcp1tCUug=
github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 h1:e/5i7d4oYZ+C1wj2THlRK+oAhjeS/TRQwMfkIuet3w0=
github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399/go.mod h1:LdwHTNJT99C5fTAzDz0ud328OgXz+gierycbcIx2fRs=
github.com/trail-of-forks/sigstore v0.0.0-20240129055912-d89eade746d5 h1:G0g5M0EnhCixAnBMMpilo6IlNDkK67BNStUUOt5/arc=
github.com/trail-of-forks/sigstore v0.0.0-20240129055912-d89eade746d5/go.mod h1:CO6jK1y+gQzIQBTV3/qZG7Nqem6Kxy+YQR4cOi2axLk=
github.com/transparency-dev/merkle v0.0.2 h1:Q9nBoQcZcgPamMkGn7ghV8XiTZ/kRxn1yCG81+twTK4=
github.com/transparency-dev/merkle v0.0.2/go.mod h1:pqSy+OXefQ1EDUVmAJ8MUhHB9TXGuzVAT58PqBoHz1A=
github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8=
Expand Down
41 changes: 41 additions & 0 deletions pkg/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"

v1 "github.com/sigstore/protobuf-specs/gen/pb-go/common/v1"
"github.com/sigstore/rekor/pkg/indexstorage"
"github.com/sigstore/rekor/pkg/log"
"github.com/sigstore/rekor/pkg/pubsub"
Expand Down Expand Up @@ -70,8 +71,21 @@ type API struct {
// Publishes notifications when new entries are added to the log. May be
// nil if no publisher is configured.
newEntryPublisher pubsub.Publisher
algorithmRegistry *signature.AlgorithmRegistryConfig
}

var AllowedClientSigningAlgorithms = []v1.KnownSignatureAlgorithm{
v1.KnownSignatureAlgorithm_RSA_SIGN_PKCS1_2048_SHA256,
v1.KnownSignatureAlgorithm_RSA_SIGN_PKCS1_3072_SHA256,
v1.KnownSignatureAlgorithm_RSA_SIGN_PKCS1_4096_SHA256,
v1.KnownSignatureAlgorithm_ECDSA_SHA2_256_NISTP256,
v1.KnownSignatureAlgorithm_ECDSA_SHA2_384_NISTP384,
v1.KnownSignatureAlgorithm_ECDSA_SHA2_512_NISTP521,
v1.KnownSignatureAlgorithm_ED25519,
v1.KnownSignatureAlgorithm_ED25519_PH,
}
var DefaultClientSigningAlgorithms = AllowedClientSigningAlgorithms

func NewAPI(treeID uint) (*API, error) {
logRPCServer := fmt.Sprintf("%s:%d",
viper.GetString("trillian_log_server.address"),
Expand Down Expand Up @@ -102,6 +116,32 @@ func NewAPI(treeID uint) (*API, error) {
log.Logger.Infof("Starting Rekor server with active tree %v", tid)
ranges.SetActive(tid)

algorithmsOption := viper.GetStringSlice("client-signing-algorithms")
var algorithms []v1.KnownSignatureAlgorithm
if algorithmsOption == nil {
algorithms = DefaultClientSigningAlgorithms
} else {
for _, a := range algorithmsOption {
algorithm, err := signature.ParseSignatureAlgorithmFlag(a)
if err != nil {
return nil, fmt.Errorf("parsing signature algorithm flag: %w", err)
}
algorithms = append(algorithms, algorithm)
}
}
algorithmsStr := make([]string, len(algorithms))
for i, a := range algorithms {
algorithmsStr[i], err = signature.FormatSignatureAlgorithmFlag(a)
if err != nil {
return nil, fmt.Errorf("formatting signature algorithm flag: %w", err)
}
}
algorithmRegistry, err := signature.NewAlgorithmRegistryConfig(algorithms)
if err != nil {
return nil, fmt.Errorf("getting algorithm registry: %w", err)
}
log.Logger.Infof("Allowed client signing algorithms: %v", algorithmsStr)

rekorSigner, err := signer.New(ctx, viper.GetString("rekor_server.signer"),
viper.GetString("rekor_server.signer-passwd"))
if err != nil {
Expand Down Expand Up @@ -142,6 +182,7 @@ func NewAPI(treeID uint) (*API, error) {
signer: rekorSigner,
// Utility functionality not required for operation of the core service
newEntryPublisher: newEntryPublisher,
algorithmRegistry: algorithmRegistry,
}, nil
}

Expand Down
76 changes: 76 additions & 0 deletions pkg/api/entries.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,17 @@ package api
import (
"bytes"
"context"
"crypto"
"crypto/ecdsa"
"crypto/ed25519"
"crypto/rsa"
"crypto/x509"
"encoding/hex"
"errors"
"fmt"
"net/http"
"net/url"
"strings"

"github.com/cyberphone/json-canonicalization/go/src/webpki.org/jsoncanonicalizer"
"github.com/go-openapi/runtime"
Expand Down Expand Up @@ -177,12 +183,82 @@ func GetLogEntryByIndexHandler(params entries.GetLogEntryByIndexParams) middlewa
return entries.NewGetLogEntryByIndexOK().WithPayload(logEntry)
}

func checkEntryAlgorithms(entry types.EntryImpl) (bool, error) {
verifiers, err := entry.Verifiers()
if err != nil {
return false, fmt.Errorf("getting verifiers: %w", err)
}
// Default to SHA256 if no artifact hash is specified
artifactHashValue := crypto.SHA256
// Get artifact hash from entry
artifactHash, err := entry.ArtifactHash()
if err == nil {
var artifactHashAlgorithm string
algoPosition := strings.Index(artifactHash, ":")
if algoPosition != -1 {
artifactHashAlgorithm = artifactHash[:algoPosition]
}
switch artifactHashAlgorithm {
case "sha256":
artifactHashValue = crypto.SHA256
case "sha384":
artifactHashValue = crypto.SHA384
case "sha512":
artifactHashValue = crypto.SHA512
default:
artifactHashValue = crypto.SHA256
}
}

// Check if all the verifiers public keys (together with the ArtifactHash)
// are allowed according to the policy
for _, v := range verifiers {
identities, err := v.Identities()
if err != nil {
return false, fmt.Errorf("getting identities: %w", err)
}

for _, identity := range identities {
var publicKey crypto.PublicKey
switch identityCrypto := identity.Crypto.(type) {
case *x509.Certificate:
publicKey = identityCrypto.PublicKey
case *rsa.PublicKey:
publicKey = identityCrypto
case *ecdsa.PublicKey:
publicKey = identityCrypto
case ed25519.PublicKey:
publicKey = identityCrypto
default:
continue
}
isPermitted, err := api.algorithmRegistry.IsAlgorithmPermitted(publicKey, artifactHashValue)
if err != nil {
return false, fmt.Errorf("checking if algorithm is permitted: %w", err)
}
if !isPermitted {
return false, nil
}
}
}
return true, nil
}

func createLogEntry(params entries.CreateLogEntryParams) (models.LogEntry, middleware.Responder) {
ctx := params.HTTPRequest.Context()
entry, err := types.CreateVersionedEntry(params.ProposedEntry)
if err != nil {
return nil, handleRekorAPIError(params, http.StatusBadRequest, err, fmt.Sprintf(validationError, err))
}

areEntryAlgorithmsAllowed, err := checkEntryAlgorithms(entry)
if err != nil {
return nil, handleRekorAPIError(params, http.StatusBadRequest, err, fmt.Sprintf(validationError, err))
}
if !areEntryAlgorithmsAllowed {
return nil, handleRekorAPIError(params, http.StatusBadRequest, errors.New("entry algorithms are not allowed"), fmt.Sprintf(validationError, "entry algorithms are not allowed"))
}

leaf, err := types.CanonicalizeEntry(ctx, entry)
if err != nil {
if _, ok := (err).(types.ValidationError); ok {
Expand Down

0 comments on commit 55f01c3

Please sign in to comment.