// generateTimestamp generates a new timestamp from the previous one in the store - this assumes all // the other roles have already been set on the repo, and will set the generated timestamp on the repo as well func generateTimestamp(gun string, builder tuf.RepoBuilder, store storage.MetaStore) (*storage.MetaUpdate, error) { var prev *data.SignedTimestamp _, currentJSON, err := store.GetCurrent(gun, data.CanonicalTimestampRole) switch err.(type) { case nil: prev = new(data.SignedTimestamp) if err := json.Unmarshal(currentJSON, prev); err != nil { logrus.Error("Failed to unmarshal existing timestamp for GUN ", gun) return nil, err } case storage.ErrNotFound: break // this is the first timestamp ever for the repo default: return nil, err } meta, ver, err := builder.GenerateTimestamp(prev) switch err.(type) { case nil: return &storage.MetaUpdate{ Role: data.CanonicalTimestampRole, Version: ver, Data: meta, }, nil case signed.ErrInsufficientSignatures, signed.ErrNoKeys: // If we cannot sign the timestamp, then we don't have keys for the timestamp, // and the client screwed up their root return nil, validation.ErrBadRoot{ Msg: fmt.Sprintf("no timestamp keys exist on the server"), } default: return nil, validation.ErrValidation{Msg: err.Error()} } }