Skip to content

Commit d855eea

Browse files
committed
implemented fixes and added new cli flag
Signed-off-by: pxp928 <parth.psu@gmail.com>
1 parent 404d041 commit d855eea

File tree

10 files changed

+149
-45
lines changed

10 files changed

+149
-45
lines changed

cmd/rekor-cli/app/pflag_groups.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,11 @@ func addArtifactPFlags(cmd *cobra.Command) error {
7373
"path or URL to public key file",
7474
false,
7575
},
76+
"multi-public-key": {
77+
multiFileOrURLFlag,
78+
"path or URL to public key files",
79+
false,
80+
},
7681
"artifact": {
7782
fileOrURLFlag,
7883
"path or URL to artifact file",
@@ -157,6 +162,21 @@ func CreatePropsFromPflags() *types.ArtifactProperties {
157162
}
158163
}
159164

165+
multiPublicKeyString := viper.GetString("multi-public-key")
166+
splitPubKeyString := strings.Split(multiPublicKeyString, ",")
167+
if len(splitPubKeyString) > 0 {
168+
collectedKeys := []*url.URL{}
169+
for _, key := range splitPubKeyString {
170+
if isURL(key) {
171+
keyPath, _ := url.Parse(key)
172+
collectedKeys = append(collectedKeys, keyPath)
173+
} else {
174+
collectedKeys = append(collectedKeys, &url.URL{Path: key})
175+
}
176+
}
177+
props.MultiPublicKeyPaths = collectedKeys
178+
}
179+
160180
props.PKIFormat = viper.GetString("pki-format")
161181
b64aad := viper.GetString("aad")
162182
if b64aad != "" {

cmd/rekor-cli/app/pflags.go

Lines changed: 50 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -35,19 +35,20 @@ import (
3535
type FlagType string
3636

3737
const (
38-
uuidFlag FlagType = "uuid"
39-
shaFlag FlagType = "sha"
40-
emailFlag FlagType = "email"
41-
logIndexFlag FlagType = "logIndex"
42-
pkiFormatFlag FlagType = "pkiFormat"
43-
typeFlag FlagType = "type"
44-
fileFlag FlagType = "file"
45-
urlFlag FlagType = "url"
46-
fileOrURLFlag FlagType = "fileOrURL"
47-
oidFlag FlagType = "oid"
48-
formatFlag FlagType = "format"
49-
timeoutFlag FlagType = "timeout"
50-
base64Flag FlagType = "base64"
38+
uuidFlag FlagType = "uuid"
39+
shaFlag FlagType = "sha"
40+
emailFlag FlagType = "email"
41+
logIndexFlag FlagType = "logIndex"
42+
pkiFormatFlag FlagType = "pkiFormat"
43+
typeFlag FlagType = "type"
44+
fileFlag FlagType = "file"
45+
urlFlag FlagType = "url"
46+
fileOrURLFlag FlagType = "fileOrURL"
47+
multiFileOrURLFlag FlagType = "multiFileOrURL"
48+
oidFlag FlagType = "oid"
49+
formatFlag FlagType = "format"
50+
timeoutFlag FlagType = "timeout"
51+
base64Flag FlagType = "base64"
5152
)
5253

5354
type newPFlagValueFunc func() pflag.Value
@@ -95,6 +96,10 @@ func initializePFlagMap() {
9596
// applies logic of fileFlag OR urlFlag validators from above
9697
return valueFactory(fileOrURLFlag, validateFileOrURL, "")
9798
},
99+
multiFileOrURLFlag: func() pflag.Value {
100+
// applies logic of fileFlag OR urlFlag validators from above for multi file and URL
101+
return multiValueFactory(multiFileOrURLFlag, validateFileOrURL, []string{})
102+
},
98103
oidFlag: func() pflag.Value {
99104
// this validates for an OID, which is a sequence of positive integers separated by periods
100105
return valueFactory(oidFlag, validateOID, "")
@@ -137,6 +142,38 @@ func valueFactory(flagType FlagType, v validationFunc, defaultVal string) pflag.
137142
}
138143
}
139144

145+
func multiValueFactory(flagType FlagType, v validationFunc, defaultVal []string) pflag.Value {
146+
return &multiBaseValue{
147+
flagType: flagType,
148+
validationFunc: v,
149+
value: defaultVal,
150+
}
151+
}
152+
153+
// multiBaseValue implements pflag.Value
154+
type multiBaseValue struct {
155+
flagType FlagType
156+
value []string
157+
validationFunc validationFunc
158+
}
159+
160+
func (b *multiBaseValue) String() string {
161+
return strings.Join(b.value, ",")
162+
}
163+
164+
// Type returns the type of this Value
165+
func (b multiBaseValue) Type() string {
166+
return string(b.flagType)
167+
}
168+
169+
func (b *multiBaseValue) Set(value string) error {
170+
if err := b.validationFunc(value); err != nil {
171+
return err
172+
}
173+
b.value = append(b.value, value)
174+
return nil
175+
}
176+
140177
// baseValue implements pflag.Value
141178
type baseValue struct {
142179
flagType FlagType

cmd/rekor-cli/app/pflags_test.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ func TestArtifactPFlags(t *testing.T) {
3737
artifact string
3838
signature string
3939
publicKey string
40+
multiPublicKey []string
4041
uuid string
4142
aad string
4243
uuidRequired bool
@@ -373,6 +374,14 @@ func TestArtifactPFlags(t *testing.T) {
373374
expectParseSuccess: true,
374375
expectValidateSuccess: false,
375376
},
377+
{
378+
caseDesc: "valid intoto - multi keys",
379+
typeStr: "intoto",
380+
artifact: "../../../tests/intoto_multi_dsse.json",
381+
multiPublicKey: []string{"../../../tests/intoto_dsse.pem", "../../../tests/intoto_dsse.pem"},
382+
expectParseSuccess: true,
383+
expectValidateSuccess: true,
384+
},
376385
}
377386

378387
for _, tc := range tests {
@@ -405,6 +414,11 @@ func TestArtifactPFlags(t *testing.T) {
405414
if tc.publicKey != "" {
406415
args = append(args, "--public-key", tc.publicKey)
407416
}
417+
if len(tc.multiPublicKey) > 0 {
418+
for _, key := range tc.multiPublicKey {
419+
args = append(args, "--multi-public-key", key)
420+
}
421+
}
408422
if tc.uuid != "" {
409423
args = append(args, "--uuid", tc.uuid)
410424
}

pkg/generated/models/intoto_v002_schema.go

Lines changed: 16 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/generated/restapi/embedded_spec.go

Lines changed: 6 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/types/intoto/v0.0.2/entry.go

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//
2-
// Copyright 2021 The Sigstore Authors.
2+
// Copyright 2022 The Sigstore Authors.
33
//
44
// Licensed under the Apache License, Version 2.0 (the "License");
55
// you may not use this file except in compliance with the License.
@@ -86,7 +86,7 @@ func (v V002Entry) IndexKeys() ([]string, error) {
8686
return nil, err
8787
}
8888

89-
result = append(result, keyObj.EmailAddresses()...)
89+
result = append(result, keyObj.Subjects()...)
9090
}
9191

9292
payloadKey := strings.ToLower(fmt.Sprintf("%s:%s", *v.IntotoObj.Content.PayloadHash.Algorithm, *v.IntotoObj.Content.PayloadHash.Value))
@@ -98,11 +98,11 @@ func (v V002Entry) IndexKeys() ([]string, error) {
9898
hashkey := strings.ToLower(fmt.Sprintf("%s:%s", *v.IntotoObj.Content.Hash.Algorithm, *v.IntotoObj.Content.Hash.Value))
9999
result = append(result, hashkey)
100100

101-
if v.IntotoObj.Content.Envelope.Payload == "" {
101+
if *v.IntotoObj.Content.Envelope.Payload == "" {
102102
log.Logger.Info("IntotoObj DSSE payload is empty")
103103
return result, nil
104104
}
105-
decodedPayload, err := base64.StdEncoding.DecodeString(string(v.IntotoObj.Content.Envelope.Payload))
105+
decodedPayload, err := base64.StdEncoding.DecodeString(string(*v.IntotoObj.Content.Envelope.Payload))
106106
if err != nil {
107107
return result, fmt.Errorf("could not decode envelope payload: %w", err)
108108
}
@@ -152,7 +152,7 @@ func parseSlsaPredicate(p []byte) (*in_toto.ProvenanceStatement, error) {
152152
func (v *V002Entry) Unmarshal(pe models.ProposedEntry) error {
153153
it, ok := pe.(*models.Intoto)
154154
if !ok {
155-
return errors.New("cannot unmarshal non Intoto v0.0.1 type")
155+
return errors.New("cannot unmarshal non Intoto v0.0.2 type")
156156
}
157157

158158
var err error
@@ -165,12 +165,12 @@ func (v *V002Entry) Unmarshal(pe models.ProposedEntry) error {
165165
return err
166166
}
167167

168-
if string(v.IntotoObj.Content.Envelope.Payload) == "" {
169-
return nil
168+
if string(*v.IntotoObj.Content.Envelope.Payload) == "" {
169+
return errors.New("DSSE envelope does not contain a payload")
170170
}
171171

172172
env := &dsse.Envelope{
173-
Payload: string(v.IntotoObj.Content.Envelope.Payload),
173+
Payload: string(*v.IntotoObj.Content.Envelope.Payload),
174174
PayloadType: *v.IntotoObj.Content.Envelope.PayloadType,
175175
}
176176

@@ -190,13 +190,12 @@ func (v *V002Entry) Unmarshal(pe models.ProposedEntry) error {
190190

191191
v.env = *env
192192

193-
decodedPayload, err := base64.StdEncoding.DecodeString(string(v.IntotoObj.Content.Envelope.Payload))
193+
decodedPayload, err := base64.StdEncoding.DecodeString(string(*v.IntotoObj.Content.Envelope.Payload))
194194
if err != nil {
195195
return fmt.Errorf("could not decode envelope payload: %w", err)
196196
}
197197

198-
paeEncodedPayload := dsse.PAE(*v.IntotoObj.Content.Envelope.PayloadType, decodedPayload)
199-
h := sha256.Sum256(paeEncodedPayload)
198+
h := sha256.Sum256(decodedPayload)
200199
v.IntotoObj.Content.PayloadHash = &models.IntotoV002SchemaContentPayloadHash{
201200
Algorithm: swag.String(models.IntotoV002SchemaContentPayloadHashAlgorithmSha256),
202201
Value: swag.String(hex.EncodeToString(h[:])),
@@ -209,12 +208,17 @@ func (v *V002Entry) Canonicalize(ctx context.Context) ([]byte, error) {
209208

210209
canonicalEntry := models.IntotoV002Schema{
211210
Content: &models.IntotoV002SchemaContent{
212-
Envelope: v.IntotoObj.Content.Envelope,
213-
Hash: v.IntotoObj.Content.Hash,
214-
PayloadHash: v.IntotoObj.Content.PayloadHash,
211+
Envelope: &models.IntotoV002SchemaContentEnvelope{},
212+
Hash: &models.IntotoV002SchemaContentHash{},
213+
PayloadHash: &models.IntotoV002SchemaContentPayloadHash{},
215214
},
216215
}
217216

217+
canonicalEntry.Content.Envelope.PayloadType = v.IntotoObj.Content.Envelope.PayloadType
218+
canonicalEntry.Content.Envelope.Signatures = v.IntotoObj.Content.Envelope.Signatures
219+
canonicalEntry.Content.Hash = v.IntotoObj.Content.Hash
220+
canonicalEntry.Content.PayloadHash = v.IntotoObj.Content.PayloadHash
221+
218222
itObj := models.Intoto{}
219223
itObj.APIVersion = swag.String(APIVERSION)
220224
itObj.Spec = &canonicalEntry
@@ -237,7 +241,11 @@ func (v *V002Entry) AttestationKeyValue() (string, []byte) {
237241
log.Logger.Infof("Skipping attestation storage, size %d is greater than max %d", storageSize, viper.GetInt("max_attestation_size"))
238242
return "", nil
239243
}
240-
attBytes, _ := base64.StdEncoding.DecodeString(v.env.Payload)
244+
attBytes, err := base64.StdEncoding.DecodeString(v.env.Payload)
245+
if err != nil {
246+
log.Logger.Infof("could not decode envelope payload: %w", err)
247+
return "", nil
248+
}
241249
return v.AttestationKey(), attBytes
242250
}
243251

@@ -279,8 +287,12 @@ func (v *verifier) Verify(data, sig []byte) error {
279287

280288
func (v V002Entry) CreateFromArtifactProperties(_ context.Context, props types.ArtifactProperties) (models.ProposedEntry, error) {
281289
returnVal := models.Intoto{}
282-
re := V002Entry{}
283-
290+
re := V002Entry{
291+
IntotoObj: models.IntotoV002Schema{
292+
Content: &models.IntotoV002SchemaContent{
293+
Envelope: &models.IntotoV002SchemaContentEnvelope{},
294+
},
295+
}}
284296
var err error
285297
artifactBytes := props.ArtifactBytes
286298
if artifactBytes == nil {
@@ -334,7 +346,7 @@ func (v V002Entry) CreateFromArtifactProperties(_ context.Context, props types.A
334346
return nil, err
335347
}
336348

337-
re.IntotoObj.Content.Envelope.Payload = env.Payload
349+
re.IntotoObj.Content.Envelope.Payload = swag.String(env.Payload)
338350
re.IntotoObj.Content.Envelope.PayloadType = &env.PayloadType
339351

340352
for _, sig := range env.Signatures {

0 commit comments

Comments
 (0)