| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117 |
- package client
- import (
- "github.com/DataDog/go-tuf/data"
- "github.com/DataDog/go-tuf/pkg/targets"
- "github.com/DataDog/go-tuf/verify"
- )
- // getTargetFileMeta searches for a verified TargetFileMeta matching a target
- // Requires a local snapshot to be loaded and is locked to the snapshot versions.
- // Searches through delegated targets following TUF spec 1.0.19 section 5.6.
- func (c *Client) getTargetFileMeta(target string) (data.TargetFileMeta, error) {
- snapshot, err := c.loadLocalSnapshot()
- if err != nil {
- return data.TargetFileMeta{}, err
- }
- // delegationsIterator covers 5.6.7
- // - pre-order depth-first search starting with the top targets
- // - filter delegations with paths or path_hash_prefixes matching searched target
- // - 5.6.7.1 cycles protection
- // - 5.6.7.2 terminations
- delegations, err := targets.NewDelegationsIterator(target, c.db)
- if err != nil {
- return data.TargetFileMeta{}, err
- }
- for i := 0; i < c.MaxDelegations; i++ {
- d, ok := delegations.Next()
- if !ok {
- return data.TargetFileMeta{}, ErrUnknownTarget{target, snapshot.Version}
- }
- // covers 5.6.{1,2,3,4,5,6}
- targets, err := c.loadDelegatedTargets(snapshot, d.Delegatee.Name, d.DB)
- if err != nil {
- return data.TargetFileMeta{}, err
- }
- // stop when the searched TargetFileMeta is found
- if m, ok := targets.Targets[target]; ok {
- return m, nil
- }
- if targets.Delegations != nil {
- delegationsDB, err := verify.NewDBFromDelegations(targets.Delegations)
- if err != nil {
- return data.TargetFileMeta{}, err
- }
- err = delegations.Add(targets.Delegations.Roles, d.Delegatee.Name, delegationsDB)
- if err != nil {
- return data.TargetFileMeta{}, err
- }
- }
- }
- return data.TargetFileMeta{}, ErrMaxDelegations{
- Target: target,
- MaxDelegations: c.MaxDelegations,
- SnapshotVersion: snapshot.Version,
- }
- }
- func (c *Client) loadLocalSnapshot() (*data.Snapshot, error) {
- if err := c.getLocalMeta(); err != nil {
- return nil, err
- }
- rawS, ok := c.localMeta["snapshot.json"]
- if !ok {
- return nil, ErrNoLocalSnapshot
- }
- snapshot := &data.Snapshot{}
- if err := c.db.Unmarshal(rawS, snapshot, "snapshot", c.snapshotVer); err != nil {
- return nil, ErrDecodeFailed{"snapshot.json", err}
- }
- return snapshot, nil
- }
- // loadDelegatedTargets downloads, decodes, verifies and stores targets
- func (c *Client) loadDelegatedTargets(snapshot *data.Snapshot, role string, db *verify.DB) (*data.Targets, error) {
- var err error
- fileName := role + ".json"
- fileMeta, ok := snapshot.Meta[fileName]
- if !ok {
- return nil, ErrRoleNotInSnapshot{role, snapshot.Version}
- }
- // 5.6.1 download target if not in the local store
- // 5.6.2 check against snapshot hash
- // 5.6.4 check against snapshot version
- raw, alreadyStored := c.localMetaFromSnapshot(fileName, fileMeta)
- if !alreadyStored {
- raw, err = c.downloadMetaFromSnapshot(fileName, fileMeta)
- if err != nil {
- return nil, err
- }
- }
- targets := &data.Targets{}
- // 5.6.3 verify signature with parent public keys
- // 5.6.5 verify that the targets is not expired
- // role "targets" is a top role verified by root keys loaded in the client db
- err = db.Unmarshal(raw, targets, role, fileMeta.Version)
- if err != nil {
- return nil, ErrDecodeFailed{fileName, err}
- }
- // 5.6.6 persist
- if !alreadyStored {
- if err := c.local.SetMeta(fileName, raw); err != nil {
- return nil, err
- }
- }
- return targets, nil
- }
|