Skip to content

Commit

Permalink
Allow parsing base64-encoded TUF metadata and root content (#1671)
Browse files Browse the repository at this point in the history
Because these fields are specified as objects, they can either be
data.Signed{} structs when initially created, or base64-encoded strings
after canonicalization and being constructed from the leaf node value.

Signed-off-by: Hayden Blauzvern <[email protected]>
  • Loading branch information
haydentherapper authored Sep 8, 2023
1 parent 2a3bd37 commit 7aa4849
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 5 deletions.
51 changes: 46 additions & 5 deletions pkg/types/tuf/v0.0.1/entry.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"bytes"
"context"
"crypto/sha256"
"encoding/base64"
"encoding/hex"
"encoding/json"
"errors"
Expand Down Expand Up @@ -81,11 +82,11 @@ func NewEntry() types.EntryImpl {

func (v V001Entry) IndexKeys() ([]string, error) {
var result []string
keyBytes, err := json.Marshal(v.TufObj.Root.Content)
keyBytes, err := v.parseRootContent()
if err != nil {
return nil, err
}
sigBytes, err := json.Marshal(v.TufObj.Metadata.Content)
sigBytes, err := v.parseMetadataContent()
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -160,7 +161,7 @@ func (v *V001Entry) fetchExternalEntities(ctx context.Context) (pki.PublicKey, p
var contentBytes []byte
if v.TufObj.Metadata.Content != nil {
var err error
contentBytes, err = json.Marshal(v.TufObj.Metadata.Content)
contentBytes, err = v.parseMetadataContent()
if err != nil {
return closePipesOnError(err)
}
Expand Down Expand Up @@ -189,7 +190,7 @@ func (v *V001Entry) fetchExternalEntities(ctx context.Context) (pki.PublicKey, p
var contentBytes []byte
if v.TufObj.Root.Content != nil {
var err error
contentBytes, err = json.Marshal(v.TufObj.Root.Content)
contentBytes, err = v.parseRootContent()
if err != nil {
return closePipesOnError(err)
}
Expand Down Expand Up @@ -373,7 +374,7 @@ func (v V001Entry) Verifiers() ([]pki.PublicKey, error) {
if v.TufObj.Root == nil {
return nil, errors.New("tuf v0.0.1 entry not initialized")
}
keyBytes, err := json.Marshal(v.TufObj.Root.Content)
keyBytes, err := v.parseRootContent()
if err != nil {
return nil, err
}
Expand All @@ -400,3 +401,43 @@ func (v V001Entry) Insertable() (bool, error) {
}
return true, nil
}

func (v V001Entry) parseRootContent() ([]byte, error) {
var keyBytes []byte
// Root.Content can either be a base64-encoded string or object
switch v := v.TufObj.Root.Content.(type) {
case string:
b, err := base64.StdEncoding.DecodeString(v)
if err != nil {
return nil, fmt.Errorf("base64 decoding TUF root content: %w", err)
}
keyBytes = b
default:
var err error
keyBytes, err = json.Marshal(v)
if err != nil {
return nil, err
}
}
return keyBytes, nil
}

func (v V001Entry) parseMetadataContent() ([]byte, error) {
var sigBytes []byte
// Metadata.Content can either be a base64-encoded string or object
switch v := v.TufObj.Metadata.Content.(type) {
case string:
b, err := base64.StdEncoding.DecodeString(v)
if err != nil {
return nil, fmt.Errorf("base64 decoding TUF metadata content: %w", err)
}
sigBytes = b
default:
var err error
sigBytes, err = json.Marshal(v)
if err != nil {
return nil, err
}
}
return sigBytes, nil
}
17 changes: 17 additions & 0 deletions pkg/types/tuf/v0.0.1/entry_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package tuf
import (
"bytes"
"context"
"encoding/base64"
"encoding/json"
"os"
"reflect"
Expand Down Expand Up @@ -142,6 +143,22 @@ func TestCrossFieldValidation(t *testing.T) {
expectCanonicalizeSuccess: true,
expectVerifierSuccess: true,
},
{
caseDesc: "root with manifest & content base64-encoded",
entry: V001Entry{
TufObj: models.TUFV001Schema{
Root: &models.TUFV001SchemaRoot{
Content: base64.StdEncoding.EncodeToString(keyBytes),
},
Metadata: &models.TUFV001SchemaMetadata{
Content: base64.StdEncoding.EncodeToString(dataBytes),
},
},
},
expectUnmarshalSuccess: true,
expectCanonicalizeSuccess: true,
expectVerifierSuccess: true,
},
{
caseDesc: "root with invalid key content & with manifest with content",
entry: V001Entry{
Expand Down

0 comments on commit 7aa4849

Please sign in to comment.