// downloadTargets is responsible for downloading any targets file // including delegates roles. func (c *Client) downloadTargets(role string) error { role = data.RoleName(role) // this will really only do something for base targets role if c.local.Snapshot == nil { return ErrMissingMeta{role: role} } snap := c.local.Snapshot.Signed root := c.local.Root.Signed r := c.keysDB.GetRole(role) if r == nil { return fmt.Errorf("Invalid role: %s", role) } keyIDs := r.KeyIDs s, err := c.getTargetsFile(role, keyIDs, snap.Meta, root.ConsistentSnapshot, r.Threshold) if err != nil { logrus.Error("Error getting targets file:", err) return err } t, err := data.TargetsFromSigned(s) if err != nil { return err } err = c.local.SetTargets(role, t) if err != nil { return err } return nil }
// SetTargets parses the Signed object into a SignedTargets object, // reads the delegated roles and keys into the KeyDB, and sets the // SignedTargets object agaist the role in the TufRepo.Targets map. func (tr *TufRepo) SetTargets(role string, s *data.Signed) error { t, err := data.TargetsFromSigned(s) if err != nil { return err } for _, k := range t.Signed.Delegations.Keys { tr.keysDB.AddKey(k) } for _, r := range t.Signed.Delegations.Roles { tr.keysDB.AddRole(r) } tr.Targets[role] = t return nil }
func validateTargets(role string, roles map[string]storage.MetaUpdate, kdb *keys.KeyDB) (*data.SignedTargets, error) { // TODO: when delegations are being validated, validate parent // role exists for any delegation s := &data.Signed{} err := json.Unmarshal(roles[role].Data, s) if err != nil { return nil, fmt.Errorf("could not parse %s", role) } // version specifically gets validated when writing to store to // better handle race conditions there. if err := signed.Verify(s, role, 0, kdb); err != nil { return nil, err } t, err := data.TargetsFromSigned(s) if err != nil { return nil, err } if !data.ValidTUFType(t.Signed.Type, data.CanonicalTargetsRole) { return nil, fmt.Errorf("%s has wrong type", role) } return t, nil }
func (c Client) getTargetsFile(role string, keyIDs []string, snapshotMeta data.Files, consistent bool, threshold int) (*data.Signed, error) { // require role exists in snapshots roleMeta, ok := snapshotMeta[role] if !ok { return nil, ErrMissingMeta{role: role} } expectedSha256, ok := snapshotMeta[role].Hashes["sha256"] if !ok { return nil, ErrMissingMeta{role: role} } // try to get meta file from content addressed cache var download bool old := &data.Signed{} version := 0 raw, err := c.cache.GetMeta(role, roleMeta.Length) if err != nil || raw == nil { logrus.Debugf("Couldn't not find cached %s, must download", role) download = true } else { // file may have been tampered with on disk. Always check the hash! genHash := sha256.Sum256(raw) if !bytes.Equal(genHash[:], expectedSha256) { download = true } err := json.Unmarshal(raw, old) if err == nil { targ, err := data.TargetsFromSigned(old) if err == nil { version = targ.Signed.Version } else { download = true } } else { download = true } } size := snapshotMeta[role].Length var s *data.Signed if download { rolePath, err := c.RoleTargetsPath(role, hex.EncodeToString(expectedSha256), consistent) if err != nil { return nil, err } raw, s, err = c.downloadSigned(rolePath, size, expectedSha256) if err != nil { return nil, err } } else { logrus.Debug("using cached ", role) s = old } err = signed.Verify(s, role, version, c.keysDB) if err != nil { return nil, err } logrus.Debugf("successfully verified %s", role) if download { // if we error when setting meta, we should continue. err = c.cache.SetMeta(role, raw) if err != nil { logrus.Errorf("Failed to write snapshot to local cache: %s", err.Error()) } } return s, nil }