Skip to content

Commit

Permalink
implemented fixes and added new cli flag
Browse files Browse the repository at this point in the history
Signed-off-by: pxp928 <parth.psu@gmail.com>
  • Loading branch information
pxp928 committed Aug 17, 2022
1 parent 404d041 commit c4bc858
Show file tree
Hide file tree
Showing 10 changed files with 149 additions and 45 deletions.
20 changes: 20 additions & 0 deletions cmd/rekor-cli/app/pflag_groups.go
Expand Up @@ -73,6 +73,11 @@ func addArtifactPFlags(cmd *cobra.Command) error {
"path or URL to public key file",
false,
},
"multi-public-key": {
multiFileOrURLFlag,
"path or URL to public key files",
false,
},
"artifact": {
fileOrURLFlag,
"path or URL to artifact file",
Expand Down Expand Up @@ -157,6 +162,21 @@ func CreatePropsFromPflags() *types.ArtifactProperties {
}
}

multiPublicKeyString := viper.GetString("multi-public-key")
splitPubKeyString := strings.Split(multiPublicKeyString, ",")
if len(splitPubKeyString) > 0 {
collectedKeys := []*url.URL{}
for _, key := range splitPubKeyString {
if isURL(key) {
keyPath, _ := url.Parse(key)
collectedKeys = append(collectedKeys, keyPath)
} else {
collectedKeys = append(collectedKeys, &url.URL{Path: key})
}
}
props.MultiPublicKeyPaths = collectedKeys
}

props.PKIFormat = viper.GetString("pki-format")
b64aad := viper.GetString("aad")
if b64aad != "" {
Expand Down
63 changes: 50 additions & 13 deletions cmd/rekor-cli/app/pflags.go
Expand Up @@ -35,19 +35,20 @@ import (
type FlagType string

const (
uuidFlag FlagType = "uuid"
shaFlag FlagType = "sha"
emailFlag FlagType = "email"
logIndexFlag FlagType = "logIndex"
pkiFormatFlag FlagType = "pkiFormat"
typeFlag FlagType = "type"
fileFlag FlagType = "file"
urlFlag FlagType = "url"
fileOrURLFlag FlagType = "fileOrURL"
oidFlag FlagType = "oid"
formatFlag FlagType = "format"
timeoutFlag FlagType = "timeout"
base64Flag FlagType = "base64"
uuidFlag FlagType = "uuid"
shaFlag FlagType = "sha"
emailFlag FlagType = "email"
logIndexFlag FlagType = "logIndex"
pkiFormatFlag FlagType = "pkiFormat"
typeFlag FlagType = "type"
fileFlag FlagType = "file"
urlFlag FlagType = "url"
fileOrURLFlag FlagType = "fileOrURL"
multiFileOrURLFlag FlagType = "multiFileOrURL"
oidFlag FlagType = "oid"
formatFlag FlagType = "format"
timeoutFlag FlagType = "timeout"
base64Flag FlagType = "base64"
)

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

func multiValueFactory(flagType FlagType, v validationFunc, defaultVal []string) pflag.Value {
return &multiBaseValue{
flagType: flagType,
validationFunc: v,
value: defaultVal,
}
}

// multiBaseValue implements pflag.Value
type multiBaseValue struct {
flagType FlagType
value []string
validationFunc validationFunc
}

func (b *multiBaseValue) String() string {
return strings.Join(b.value, ",")
}

// Type returns the type of this Value
func (b multiBaseValue) Type() string {
return string(b.flagType)
}

func (b *multiBaseValue) Set(value string) error {
if err := b.validationFunc(value); err != nil {
return err
}
b.value = append(b.value, value)
return nil
}

// baseValue implements pflag.Value
type baseValue struct {
flagType FlagType
Expand Down
14 changes: 14 additions & 0 deletions cmd/rekor-cli/app/pflags_test.go
Expand Up @@ -37,6 +37,7 @@ func TestArtifactPFlags(t *testing.T) {
artifact string
signature string
publicKey string
multiPublicKey []string
uuid string
aad string
uuidRequired bool
Expand Down Expand Up @@ -373,6 +374,14 @@ func TestArtifactPFlags(t *testing.T) {
expectParseSuccess: true,
expectValidateSuccess: false,
},
{
caseDesc: "valid intoto - multi keys",
typeStr: "intoto",
artifact: "../../../tests/intoto_multi_dsse.json",
multiPublicKey: []string{"../../../tests/intoto_dsse.pem", "../../../tests/intoto_dsse.pem"},
expectParseSuccess: true,
expectValidateSuccess: true,
},
}

for _, tc := range tests {
Expand Down Expand Up @@ -405,6 +414,11 @@ func TestArtifactPFlags(t *testing.T) {
if tc.publicKey != "" {
args = append(args, "--public-key", tc.publicKey)
}
if len(tc.multiPublicKey) > 0 {
for _, key := range tc.multiPublicKey {
args = append(args, "--multi-public-key", key)
}
}
if tc.uuid != "" {
args = append(args, "--uuid", tc.uuid)
}
Expand Down
18 changes: 16 additions & 2 deletions pkg/generated/models/intoto_v002_schema.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 6 additions & 3 deletions pkg/generated/restapi/embedded_spec.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

48 changes: 30 additions & 18 deletions pkg/types/intoto/v0.0.2/entry.go
@@ -1,5 +1,5 @@
//
// Copyright 2021 The Sigstore Authors.
// Copyright 2022 The Sigstore Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -86,7 +86,7 @@ func (v V002Entry) IndexKeys() ([]string, error) {
return nil, err
}

result = append(result, keyObj.EmailAddresses()...)
result = append(result, keyObj.Subjects()...)
}

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

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

var err error
Expand All @@ -165,12 +165,12 @@ func (v *V002Entry) Unmarshal(pe models.ProposedEntry) error {
return err
}

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

env := &dsse.Envelope{
Payload: string(v.IntotoObj.Content.Envelope.Payload),
Payload: string(*v.IntotoObj.Content.Envelope.Payload),
PayloadType: *v.IntotoObj.Content.Envelope.PayloadType,
}

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

v.env = *env

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

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

canonicalEntry := models.IntotoV002Schema{
Content: &models.IntotoV002SchemaContent{
Envelope: v.IntotoObj.Content.Envelope,
Hash: v.IntotoObj.Content.Hash,
PayloadHash: v.IntotoObj.Content.PayloadHash,
Envelope: &models.IntotoV002SchemaContentEnvelope{},
Hash: &models.IntotoV002SchemaContentHash{},
PayloadHash: &models.IntotoV002SchemaContentPayloadHash{},
},
}

canonicalEntry.Content.Envelope.PayloadType = v.IntotoObj.Content.Envelope.PayloadType
canonicalEntry.Content.Envelope.Signatures = v.IntotoObj.Content.Envelope.Signatures
canonicalEntry.Content.Hash = v.IntotoObj.Content.Hash
canonicalEntry.Content.PayloadHash = v.IntotoObj.Content.PayloadHash

itObj := models.Intoto{}
itObj.APIVersion = swag.String(APIVERSION)
itObj.Spec = &canonicalEntry
Expand All @@ -237,7 +241,11 @@ func (v *V002Entry) AttestationKeyValue() (string, []byte) {
log.Logger.Infof("Skipping attestation storage, size %d is greater than max %d", storageSize, viper.GetInt("max_attestation_size"))
return "", nil
}
attBytes, _ := base64.StdEncoding.DecodeString(v.env.Payload)
attBytes, err := base64.StdEncoding.DecodeString(v.env.Payload)
if err != nil {
log.Logger.Infof("could not decode envelope payload: %w", err)
return "", nil
}
return v.AttestationKey(), attBytes
}

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

func (v V002Entry) CreateFromArtifactProperties(_ context.Context, props types.ArtifactProperties) (models.ProposedEntry, error) {
returnVal := models.Intoto{}
re := V002Entry{}

re := V002Entry{
IntotoObj: models.IntotoV002Schema{
Content: &models.IntotoV002SchemaContent{
Envelope: &models.IntotoV002SchemaContentEnvelope{},
},
}}
var err error
artifactBytes := props.ArtifactBytes
if artifactBytes == nil {
Expand Down Expand Up @@ -334,7 +346,7 @@ func (v V002Entry) CreateFromArtifactProperties(_ context.Context, props types.A
return nil, err
}

re.IntotoObj.Content.Envelope.Payload = env.Payload
re.IntotoObj.Content.Envelope.Payload = swag.String(env.Payload)
re.IntotoObj.Content.Envelope.PayloadType = &env.PayloadType

for _, sig := range env.Signatures {
Expand Down

0 comments on commit c4bc858

Please sign in to comment.