func validateRoot(gun string, oldRoot, newRoot []byte) (*data.SignedRoot, error) { var parsedOldRoot *data.SignedRoot parsedNewRoot := &data.SignedRoot{} if oldRoot != nil { parsedOldRoot = &data.SignedRoot{} err := json.Unmarshal(oldRoot, parsedOldRoot) if err != nil { // TODO(david): if we can't read the old root should we continue // here to check new root self referential integrity? // This would permit recovery of a repo with a corrupted // root. logrus.Warn("Old root could not be parsed.") } } err := json.Unmarshal(newRoot, parsedNewRoot) if err != nil { return nil, err } if err := checkRoot(parsedOldRoot, parsedNewRoot); err != nil { // TODO(david): how strict do we want to be here about old signatures // for rotations? Should the user have to provide a flag // which gets transmitted to force a root update without // correct old key signatures. return nil, err } if !data.ValidTUFType(parsedNewRoot.Signed.Type, data.CanonicalRootRole) { return nil, fmt.Errorf("root has wrong type") } return parsedNewRoot, nil }
func validateSnapshot(role string, oldSnap *data.SignedSnapshot, snapUpdate storage.MetaUpdate, roles map[string]storage.MetaUpdate, kdb *keys.KeyDB) error { s := &data.Signed{} err := json.Unmarshal(snapUpdate.Data, s) if err != nil { return errors.New("could not parse snapshot") } // 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 err } snap, err := data.SnapshotFromSigned(s) if err != nil { return errors.New("could not parse snapshot") } if !data.ValidTUFType(snap.Signed.Type, data.CanonicalSnapshotRole) { return errors.New("snapshot has wrong type") } err = checkSnapshotEntries(role, oldSnap, snap, roles) if err != nil { return err } return nil }
func verifyMeta(s *data.Signed, role string, minVersion int) error { sm := &data.SignedCommon{} if err := json.Unmarshal(s.Signed, sm); err != nil { return err } if !data.ValidTUFType(sm.Type, role) { return ErrWrongType } if IsExpired(sm.Expires) { logrus.Errorf("Metadata for %s expired", role) return ErrExpired{Role: role, Expired: sm.Expires.Format("Mon Jan 2 15:04:05 MST 2006")} } if sm.Version < minVersion { return ErrLowVersion{sm.Version, minVersion} } return nil }
func validateRoot(gun string, oldRoot, newRoot []byte, store storage.MetaStore) ( *data.SignedRoot, error) { var parsedOldRoot *data.SignedRoot parsedNewRoot := &data.SignedRoot{} if oldRoot != nil { parsedOldRoot = &data.SignedRoot{} err := json.Unmarshal(oldRoot, parsedOldRoot) if err != nil { // TODO(david): if we can't read the old root should we continue // here to check new root self referential integrity? // This would permit recovery of a repo with a corrupted // root. logrus.Warn("Old root could not be parsed.") } } err := json.Unmarshal(newRoot, parsedNewRoot) if err != nil { return nil, err } // Don't update if a timestamp key doesn't exist. algo, keyBytes, err := store.GetKey(gun, data.CanonicalTimestampRole) if err != nil || algo == "" || keyBytes == nil { return nil, fmt.Errorf("no timestamp key for %s", gun) } timestampKey := data.NewPublicKey(algo, keyBytes) if err := checkRoot(parsedOldRoot, parsedNewRoot, timestampKey); err != nil { // TODO(david): how strict do we want to be here about old signatures // for rotations? Should the user have to provide a flag // which gets transmitted to force a root update without // correct old key signatures. return nil, err } if !data.ValidTUFType(parsedNewRoot.Signed.Type, data.CanonicalRootRole) { return nil, fmt.Errorf("root has wrong type") } return parsedNewRoot, 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 validateTargets(role string, roles map[string]storage.MetaUpdate, repo *tuf.Repo) (*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. var targetOrDelgRole data.BaseRole if role == data.CanonicalTargetsRole { targetOrDelgRole, err = repo.GetBaseRole(role) if err != nil { logrus.Debugf("no %s role loaded", role) return nil, err } } else { delgRole, err := repo.GetDelegationRole(role) if err != nil { logrus.Debugf("no %s delegation role loaded", role) return nil, err } targetOrDelgRole = delgRole.BaseRole } if err := signed.Verify(s, targetOrDelgRole, 0); 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 }