Skip to content

Commit b450afb

Browse files
committed
Added --client-signing-algorithms flag
Signed-off-by: Riccardo Schirone <[email protected]>
1 parent 9865ca9 commit b450afb

File tree

5 files changed

+140
-9
lines changed

5 files changed

+140
-9
lines changed

cmd/rekor-server/app/root.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,14 @@ import (
2020
"net/http"
2121
"net/http/pprof"
2222
"os"
23+
"sort"
24+
"strings"
2325
"time"
2426

2527
homedir "github.com/mitchellh/go-homedir"
28+
"github.com/sigstore/rekor/pkg/api"
2629
"github.com/sigstore/rekor/pkg/log"
30+
"github.com/sigstore/sigstore/pkg/signature"
2731
"github.com/spf13/cobra"
2832
"github.com/spf13/viper"
2933

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

138+
keyAlgorithmTypes := []string{}
139+
for _, keyAlgorithm := range api.AllowedClientSigningAlgorithms {
140+
keyFlag, err := signature.FormatSignatureAlgorithmFlag(keyAlgorithm)
141+
if err != nil {
142+
panic(err)
143+
}
144+
keyAlgorithmTypes = append(keyAlgorithmTypes, keyFlag)
145+
}
146+
sort.Strings(keyAlgorithmTypes)
147+
keyAlgorithmHelp := fmt.Sprintf("signing algorithm to use for signing/hashing (allowed %s)", strings.Join(keyAlgorithmTypes, ", "))
148+
rootCmd.PersistentFlags().StringSlice("client-signing-algorithms", keyAlgorithmTypes, keyAlgorithmHelp)
149+
134150
if err := viper.BindPFlags(rootCmd.PersistentFlags()); err != nil {
135151
log.Logger.Fatal(err)
136152
}

go.mod

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ require (
2626
github.com/rs/cors v1.10.1
2727
github.com/sassoftware/relic v7.2.1+incompatible
2828
github.com/secure-systems-lab/go-securesystemslib v0.8.0
29-
github.com/sigstore/sigstore v1.8.1
3029
github.com/spf13/cobra v1.8.0
3130
github.com/spf13/pflag v1.0.5
3231
github.com/spf13/viper v1.18.2
@@ -63,7 +62,8 @@ require (
6362
github.com/jmoiron/sqlx v1.3.5
6463
github.com/redis/go-redis/v9 v9.4.0
6564
github.com/sassoftware/relic/v7 v7.6.1
66-
github.com/sigstore/protobuf-specs v0.2.1
65+
github.com/sigstore/protobuf-specs v0.3.0-beta.2
66+
github.com/sigstore/sigstore v1.6.4
6767
github.com/sigstore/sigstore/pkg/signature/kms/aws v1.8.1
6868
github.com/sigstore/sigstore/pkg/signature/kms/azure v1.8.1
6969
github.com/sigstore/sigstore/pkg/signature/kms/gcp v1.8.1
@@ -164,7 +164,7 @@ require (
164164
github.com/godbus/dbus/v5 v5.1.0 // indirect
165165
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
166166
github.com/golang/protobuf v1.5.3 // indirect
167-
github.com/google/go-containerregistry v0.17.0 // indirect
167+
github.com/google/go-containerregistry v0.18.0 // indirect
168168
github.com/google/uuid v1.5.0 // indirect
169169
github.com/google/wire v0.5.0 // indirect
170170
github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect
@@ -204,3 +204,5 @@ require (
204204
gopkg.in/yaml.v2 v2.4.0
205205
gopkg.in/yaml.v3 v3.0.1 // indirect
206206
)
207+
208+
replace github.com/sigstore/sigstore => github.com/trail-of-forks/sigstore v0.0.0-20240129055912-d89eade746d5

go.sum

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -215,8 +215,8 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
215215
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
216216
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
217217
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
218-
github.com/google/go-containerregistry v0.17.0 h1:5p+zYs/R4VGHkhyvgWurWrpJ2hW4Vv9fQI+GzdcwXLk=
219-
github.com/google/go-containerregistry v0.17.0/go.mod h1:u0qB2l7mvtWVR5kNcbFIhFY1hLbf8eeGapA+vbFDCtQ=
218+
github.com/google/go-containerregistry v0.18.0 h1:ShE7erKNPqRh5ue6Z9DUOlk04WsnFWPO6YGr3OxnfoQ=
219+
github.com/google/go-containerregistry v0.18.0/go.mod h1:u0qB2l7mvtWVR5kNcbFIhFY1hLbf8eeGapA+vbFDCtQ=
220220
github.com/google/go-replayers/grpcreplay v1.1.0 h1:S5+I3zYyZ+GQz68OfbURDdt/+cSMqCK1wrvNx7WBzTE=
221221
github.com/google/go-replayers/grpcreplay v1.1.0/go.mod h1:qzAvJ8/wi57zq7gWqaE6AwLM6miiXUQwP1S+I9icmhk=
222222
github.com/google/go-replayers/httpreplay v1.2.0 h1:VM1wEyyjaoU53BwrOnaf9VhAyQQEEioJvFYxYcLRKzk=
@@ -387,10 +387,8 @@ github.com/secure-systems-lab/go-securesystemslib v0.8.0 h1:mr5An6X45Kb2nddcFlbm
387387
github.com/secure-systems-lab/go-securesystemslib v0.8.0/go.mod h1:UH2VZVuJfCYR8WgMlCU1uFsOUU+KeyrTWcSS73NBOzU=
388388
github.com/shibumi/go-pathspec v1.3.0 h1:QUyMZhFo0Md5B8zV8x2tesohbb5kfbpTi9rBnKh5dkI=
389389
github.com/shibumi/go-pathspec v1.3.0/go.mod h1:Xutfslp817l2I1cZvgcfeMQJG5QnU2lh5tVaaMCl3jE=
390-
github.com/sigstore/protobuf-specs v0.2.1 h1:KIoM7E3C4uaK092q8YoSj/XSf9720f8dlsbYwwOmgEA=
391-
github.com/sigstore/protobuf-specs v0.2.1/go.mod h1:xPqQGnH/HllKuZ4VFPz/g+78epWM/NLRGl7Fuy45UdE=
392-
github.com/sigstore/sigstore v1.8.1 h1:mAVposMb14oplk2h/bayPmIVdzbq2IhCgy4g6R0ZSjo=
393-
github.com/sigstore/sigstore v1.8.1/go.mod h1:02SL1158BSj15bZyOFz7m+/nJzLZfFd9A8ab3Kz7w/E=
390+
github.com/sigstore/protobuf-specs v0.3.0-beta.2 h1:neHS0O1z7qz4q21vyXqSaKuKYxA0upzJERT88NrgYlM=
391+
github.com/sigstore/protobuf-specs v0.3.0-beta.2/go.mod h1:ynKzXpqr3dUj2Xk9O/5ZUhjnpi0F53DNi5AdH6pS3jc=
394392
github.com/sigstore/sigstore/pkg/signature/kms/aws v1.8.1 h1:rEDdUefulkIQaMJyzLwtgPDLNXBIltBABiFYfb0YmgQ=
395393
github.com/sigstore/sigstore/pkg/signature/kms/aws v1.8.1/go.mod h1:RCdYCc1IxCYWzh2IdzdA6Yf7JIY0cMRqH08fpQYechw=
396394
github.com/sigstore/sigstore/pkg/signature/kms/azure v1.8.1 h1:DvRWG99QGWZC5mp42SEde2Xke/Q384Idnj2da7yB+Mk=
@@ -432,6 +430,8 @@ github.com/theupdateframework/go-tuf v0.7.0 h1:CqbQFrWo1ae3/I0UCblSbczevCCbS31Qv
432430
github.com/theupdateframework/go-tuf v0.7.0/go.mod h1:uEB7WSY+7ZIugK6R1hiBMBjQftaFzn7ZCDJcp1tCUug=
433431
github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 h1:e/5i7d4oYZ+C1wj2THlRK+oAhjeS/TRQwMfkIuet3w0=
434432
github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399/go.mod h1:LdwHTNJT99C5fTAzDz0ud328OgXz+gierycbcIx2fRs=
433+
github.com/trail-of-forks/sigstore v0.0.0-20240129055912-d89eade746d5 h1:G0g5M0EnhCixAnBMMpilo6IlNDkK67BNStUUOt5/arc=
434+
github.com/trail-of-forks/sigstore v0.0.0-20240129055912-d89eade746d5/go.mod h1:CO6jK1y+gQzIQBTV3/qZG7Nqem6Kxy+YQR4cOi2axLk=
435435
github.com/transparency-dev/merkle v0.0.2 h1:Q9nBoQcZcgPamMkGn7ghV8XiTZ/kRxn1yCG81+twTK4=
436436
github.com/transparency-dev/merkle v0.0.2/go.mod h1:pqSy+OXefQ1EDUVmAJ8MUhHB9TXGuzVAT58PqBoHz1A=
437437
github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8=

pkg/api/api.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import (
3030
"google.golang.org/grpc"
3131
"google.golang.org/grpc/credentials/insecure"
3232

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

77+
var AllowedClientSigningAlgorithms = []v1.KnownSignatureAlgorithm{
78+
v1.KnownSignatureAlgorithm_RSA_SIGN_PKCS1_2048_SHA256,
79+
v1.KnownSignatureAlgorithm_RSA_SIGN_PKCS1_3072_SHA256,
80+
v1.KnownSignatureAlgorithm_RSA_SIGN_PKCS1_4096_SHA256,
81+
v1.KnownSignatureAlgorithm_ECDSA_SHA2_256_NISTP256,
82+
v1.KnownSignatureAlgorithm_ECDSA_SHA2_384_NISTP384,
83+
v1.KnownSignatureAlgorithm_ECDSA_SHA2_512_NISTP521,
84+
v1.KnownSignatureAlgorithm_ED25519,
85+
v1.KnownSignatureAlgorithm_ED25519_PH,
86+
}
87+
var DefaultClientSigningAlgorithms = AllowedClientSigningAlgorithms
88+
7589
func NewAPI(treeID uint) (*API, error) {
7690
logRPCServer := fmt.Sprintf("%s:%d",
7791
viper.GetString("trillian_log_server.address"),
@@ -102,6 +116,32 @@ func NewAPI(treeID uint) (*API, error) {
102116
log.Logger.Infof("Starting Rekor server with active tree %v", tid)
103117
ranges.SetActive(tid)
104118

119+
algorithmsOption := viper.GetStringSlice("client-signing-algorithms")
120+
var algorithms []v1.KnownSignatureAlgorithm
121+
if algorithmsOption == nil {
122+
algorithms = DefaultClientSigningAlgorithms
123+
} else {
124+
for _, a := range algorithmsOption {
125+
algorithm, err := signature.ParseSignatureAlgorithmFlag(a)
126+
if err != nil {
127+
return nil, fmt.Errorf("parsing signature algorithm flag: %w", err)
128+
}
129+
algorithms = append(algorithms, algorithm)
130+
}
131+
}
132+
algorithmsStr := make([]string, len(algorithms))
133+
for i, a := range algorithms {
134+
algorithmsStr[i], err = signature.FormatSignatureAlgorithmFlag(a)
135+
if err != nil {
136+
return nil, fmt.Errorf("formatting signature algorithm flag: %w", err)
137+
}
138+
}
139+
algorithmRegistry, err := signature.NewAlgorithmRegistryConfig(algorithms)
140+
if err != nil {
141+
return nil, fmt.Errorf("getting algorithm registry: %w", err)
142+
}
143+
log.Logger.Infof("Allowed client signing algorithms: %v", algorithmsStr)
144+
105145
rekorSigner, err := signer.New(ctx, viper.GetString("rekor_server.signer"),
106146
viper.GetString("rekor_server.signer-passwd"))
107147
if err != nil {
@@ -142,6 +182,7 @@ func NewAPI(treeID uint) (*API, error) {
142182
signer: rekorSigner,
143183
// Utility functionality not required for operation of the core service
144184
newEntryPublisher: newEntryPublisher,
185+
algorithmRegistry: algorithmRegistry,
145186
}, nil
146187
}
147188

pkg/api/entries.go

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,17 @@ package api
1818
import (
1919
"bytes"
2020
"context"
21+
"crypto"
22+
"crypto/ecdsa"
23+
"crypto/ed25519"
24+
"crypto/rsa"
25+
"crypto/x509"
2126
"encoding/hex"
2227
"errors"
2328
"fmt"
2429
"net/http"
2530
"net/url"
31+
"strings"
2632

2733
"github.com/cyberphone/json-canonicalization/go/src/webpki.org/jsoncanonicalizer"
2834
"github.com/go-openapi/runtime"
@@ -177,12 +183,78 @@ func GetLogEntryByIndexHandler(params entries.GetLogEntryByIndexParams) middlewa
177183
return entries.NewGetLogEntryByIndexOK().WithPayload(logEntry)
178184
}
179185

186+
func checkEntryAlgorithms(entry types.EntryImpl) (bool, error) {
187+
verifiers, err := entry.Verifiers()
188+
if err != nil {
189+
return false, fmt.Errorf("getting verifiers: %w", err)
190+
}
191+
// Get artifact hash from entry
192+
artifactHash, err := entry.ArtifactHash()
193+
if err != nil {
194+
return false, fmt.Errorf("getting artifact hash: %w", err)
195+
}
196+
artifactHashAlgorithm := artifactHash[:strings.Index(artifactHash, ":")]
197+
var artifactHashValue crypto.Hash
198+
switch artifactHashAlgorithm {
199+
case "sha256":
200+
artifactHashValue = crypto.SHA256
201+
case "sha384":
202+
artifactHashValue = crypto.SHA384
203+
case "sha512":
204+
artifactHashValue = crypto.SHA512
205+
default:
206+
return false, fmt.Errorf("unsupported artifact hash algorithm %s", artifactHashAlgorithm)
207+
}
208+
209+
// Check if all the verifiers public keys (together with the ArtifactHash)
210+
// are allowed according to the policy
211+
for _, v := range verifiers {
212+
identities, err := v.Identities()
213+
if err != nil {
214+
return false, fmt.Errorf("getting identities: %w", err)
215+
}
216+
217+
for _, identity := range identities {
218+
var publicKey crypto.PublicKey
219+
switch identityCrypto := identity.Crypto.(type) {
220+
case *x509.Certificate:
221+
publicKey = identityCrypto.PublicKey
222+
case *rsa.PublicKey:
223+
publicKey = identityCrypto
224+
case *ecdsa.PublicKey:
225+
publicKey = identityCrypto
226+
case ed25519.PublicKey:
227+
publicKey = identityCrypto
228+
default:
229+
continue
230+
}
231+
isPermitted, err := api.algorithmRegistry.IsAlgorithmPermitted(publicKey, artifactHashValue)
232+
if err != nil {
233+
return false, fmt.Errorf("checking if algorithm is permitted: %w", err)
234+
}
235+
if !isPermitted {
236+
return false, nil
237+
}
238+
}
239+
}
240+
return true, nil
241+
}
242+
180243
func createLogEntry(params entries.CreateLogEntryParams) (models.LogEntry, middleware.Responder) {
181244
ctx := params.HTTPRequest.Context()
182245
entry, err := types.CreateVersionedEntry(params.ProposedEntry)
183246
if err != nil {
184247
return nil, handleRekorAPIError(params, http.StatusBadRequest, err, fmt.Sprintf(validationError, err))
185248
}
249+
250+
areEntryAlgorithmsAllowed, err := checkEntryAlgorithms(entry)
251+
if err != nil {
252+
return nil, handleRekorAPIError(params, http.StatusBadRequest, err, fmt.Sprintf(validationError, err))
253+
}
254+
if !areEntryAlgorithmsAllowed {
255+
return nil, handleRekorAPIError(params, http.StatusBadRequest, errors.New("entry algorithms are not allowed"), fmt.Sprintf(validationError, "entry algorithms are not allowed"))
256+
}
257+
186258
leaf, err := types.CanonicalizeEntry(ctx, entry)
187259
if err != nil {
188260
if _, ok := (err).(types.ValidationError); ok {

0 commit comments

Comments
 (0)