mirror of https://github.com/docker/docs.git
127 lines
3.2 KiB
Go
127 lines
3.2 KiB
Go
package data
|
|
|
|
import (
|
|
"crypto/sha256"
|
|
"encoding/hex"
|
|
|
|
"github.com/jfrazelle/go/canonical/json"
|
|
)
|
|
|
|
// SignedTargets is a fully unpacked targets.json, or target delegation
|
|
// json file
|
|
type SignedTargets struct {
|
|
Signatures []Signature
|
|
Signed Targets
|
|
Dirty bool
|
|
}
|
|
|
|
// Targets is the Signed components of a targets.json or delegation json file
|
|
type Targets struct {
|
|
SignedCommon
|
|
Targets Files `json:"targets"`
|
|
Delegations Delegations `json:"delegations,omitempty"`
|
|
}
|
|
|
|
// NewTargets intiializes a new empty SignedTargets object
|
|
func NewTargets() *SignedTargets {
|
|
return &SignedTargets{
|
|
Signatures: make([]Signature, 0),
|
|
Signed: Targets{
|
|
SignedCommon: SignedCommon{
|
|
Type: TUFTypes["targets"],
|
|
Version: 0,
|
|
Expires: DefaultExpires("targets"),
|
|
},
|
|
Targets: make(Files),
|
|
Delegations: *NewDelegations(),
|
|
},
|
|
Dirty: true,
|
|
}
|
|
}
|
|
|
|
// GetMeta attempts to find the targets entry for the path. It
|
|
// will return nil in the case of the target not being found.
|
|
func (t SignedTargets) GetMeta(path string) *FileMeta {
|
|
for p, meta := range t.Signed.Targets {
|
|
if p == path {
|
|
return &meta
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// GetDelegations filters the roles and associated keys that may be
|
|
// the signers for the given target path. If no appropriate roles
|
|
// can be found, it will simply return nil for the return values.
|
|
// The returned slice of Role will have order maintained relative
|
|
// to the role slice on Delegations per TUF spec proposal on using
|
|
// order to determine priority.
|
|
func (t SignedTargets) GetDelegations(path string) []*Role {
|
|
var roles []*Role
|
|
pathHashBytes := sha256.Sum256([]byte(path))
|
|
pathHash := hex.EncodeToString(pathHashBytes[:])
|
|
for _, r := range t.Signed.Delegations.Roles {
|
|
if !r.IsValid() {
|
|
// Role has both Paths and PathHashPrefixes.
|
|
continue
|
|
}
|
|
if r.CheckPaths(path) {
|
|
roles = append(roles, r)
|
|
continue
|
|
}
|
|
if r.CheckPrefixes(pathHash) {
|
|
roles = append(roles, r)
|
|
continue
|
|
}
|
|
//keysDB.AddRole(r)
|
|
}
|
|
return roles
|
|
}
|
|
|
|
// AddTarget adds or updates the meta for the given path
|
|
func (t *SignedTargets) AddTarget(path string, meta FileMeta) {
|
|
t.Signed.Targets[path] = meta
|
|
t.Dirty = true
|
|
}
|
|
|
|
// AddDelegation will add a new delegated role with the given keys,
|
|
// ensuring the keys either already exist, or are added to the map
|
|
// of delegation keys
|
|
func (t *SignedTargets) AddDelegation(role *Role, keys []*PublicKey) error {
|
|
return nil
|
|
}
|
|
|
|
// ToSigned partially serializes a SignedTargets for further signing
|
|
func (t SignedTargets) ToSigned() (*Signed, error) {
|
|
s, err := json.MarshalCanonical(t.Signed)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
signed := json.RawMessage{}
|
|
err = signed.UnmarshalJSON(s)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
sigs := make([]Signature, len(t.Signatures))
|
|
copy(sigs, t.Signatures)
|
|
return &Signed{
|
|
Signatures: sigs,
|
|
Signed: signed,
|
|
}, nil
|
|
}
|
|
|
|
// TargetsFromSigned fully unpacks a Signed object into a SignedTargets
|
|
func TargetsFromSigned(s *Signed) (*SignedTargets, error) {
|
|
t := Targets{}
|
|
err := json.Unmarshal(s.Signed, &t)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
sigs := make([]Signature, len(s.Signatures))
|
|
copy(sigs, s.Signatures)
|
|
return &SignedTargets{
|
|
Signatures: sigs,
|
|
Signed: t,
|
|
}, nil
|
|
}
|