// Init initializes a local repository. // // The latest root.json is fetched from remote storage, verified using rootKeys // and threshold, and then saved in local storage. It is expected that rootKeys // were securely distributed with the software being updated. func (c *Client) Init(rootKeys []*data.Key, threshold int) error { if len(rootKeys) < threshold { return ErrInsufficientKeys } rootJSON, err := c.downloadMetaUnsafe("root.json") if err != nil { return err } c.db = verify.NewDB() rootKeyIDs := make([]string, len(rootKeys)) for i, key := range rootKeys { id := key.ID() rootKeyIDs[i] = id if err := c.db.AddKey(id, key); err != nil { return err } } role := &data.Role{Threshold: threshold, KeyIDs: rootKeyIDs} if err := c.db.AddRole("root", role); err != nil { return err } if err := c.decodeRoot(rootJSON); err != nil { return err } return c.local.SetMeta("root.json", rootJSON) }
// getLocalMeta decodes and verifies metadata from local storage. // // The verification of local files is purely for consistency, if an attacker // has compromised the local storage, there is no guarantee it can be trusted. func (c *Client) getLocalMeta() error { meta, err := c.local.GetMeta() if err != nil { return err } if rootJSON, ok := meta["root.json"]; ok { // unmarshal root.json without verifying as we need the root // keys first s := &data.Signed{} if err := json.Unmarshal(rootJSON, s); err != nil { return err } root := &data.Root{} if err := json.Unmarshal(s.Signed, root); err != nil { return err } c.db = verify.NewDB() for id, k := range root.Keys { if err := c.db.AddKey(id, k); err != nil { return err } } for name, role := range root.Roles { if err := c.db.AddRole(name, role); err != nil { return err } } if err := c.db.Verify(s, "root", 0); err != nil { return err } c.consistentSnapshot = root.ConsistentSnapshot } else { return ErrNoRootKeys } if snapshotJSON, ok := meta["snapshot.json"]; ok { snapshot := &data.Snapshot{} if err := verify.UnmarshalTrusted(snapshotJSON, snapshot, "snapshot", c.db); err != nil { return err } c.snapshotVer = snapshot.Version } if targetsJSON, ok := meta["targets.json"]; ok { targets := &data.Targets{} if err := verify.UnmarshalTrusted(targetsJSON, targets, "targets", c.db); err != nil { return err } c.targetsVer = targets.Version c.targets = targets.Targets } if timestampJSON, ok := meta["timestamp.json"]; ok { timestamp := &data.Timestamp{} if err := verify.UnmarshalTrusted(timestampJSON, timestamp, "timestamp", c.db); err != nil { return err } c.timestampVer = timestamp.Version } c.localMeta = meta return nil }