package version import ( "encoding/json" "strconv" "testing" "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func encodeSignedLifecycleManifest(t *testing.T, manifest ReleaseInfo) []byte { t.Helper() manifest.Signature = nil require.NoError(t, manifest.Sign("test-release-key", testManifestPrivateKey)) data, err := json.Marshal(manifest) require.NoError(t, err) return data } func TestReleaseTrustStateRejectsReplayRollbackAndEquivocation(t *testing.T) { baseJSON := signedManifestJSON(t, `{"version":"1.3.0"}`) var base ReleaseInfo require.NoError(t, json.Unmarshal([]byte(baseJSON), &base)) previousValidity, previousRevoked, previousBuildTime := ManifestKeyValidity, ManifestRevokedKeyIDs, BuildTime ManifestKeyValidity, ManifestRevokedKeyIDs, BuildTime = "", "", "" t.Cleanup(func() { ManifestKeyValidity, ManifestRevokedKeyIDs, BuildTime = previousValidity, previousRevoked, previousBuildTime }) _, err := decodeReleaseManifest(encodeSignedLifecycleManifest(t, base)) require.NoError(t, err) older := base older.PublishedAt = "2026-08-29T12:00:00Z" _, err = decodeReleaseManifest(encodeSignedLifecycleManifest(t, older)) require.Error(t, err) assert.Contains(t, err.Error(), "older than the highest accepted") rollback := base rollback.PublishedAt = "2026-08-31T12:00:00Z" rollback.Version = "1.2.9" component := rollback.Components[ComponentID] component.Version = rollback.Version rollback.Components[ComponentID] = component _, err = decodeReleaseManifest(encodeSignedLifecycleManifest(t, rollback)) require.Error(t, err) assert.Contains(t, err.Error(), "rolls back highest accepted version") component.Version = base.Version base.Components[ComponentID] = component equivocation := base equivocation.MpvVersion = "0.99.0" _, err = decodeReleaseManifest(encodeSignedLifecycleManifest(t, equivocation)) require.Error(t, err) assert.Contains(t, err.Error(), "equivocation") } func TestReleaseTrustEnforcesBuildFloorKeyEpochAndRevocation(t *testing.T) { baseJSON := signedManifestJSON(t, `{"version":"1.3.0"}`) var base ReleaseInfo require.NoError(t, json.Unmarshal([]byte(baseJSON), &base)) previousValidity, previousRevoked, previousBuildTime := ManifestKeyValidity, ManifestRevokedKeyIDs, BuildTime t.Cleanup(func() { ManifestKeyValidity, ManifestRevokedKeyIDs, BuildTime = previousValidity, previousRevoked, previousBuildTime }) BuildTime = "2026-08-31T00:00:00Z" ManifestKeyValidity = "" ManifestRevokedKeyIDs = "" _, err := decodeReleaseManifest(encodeSignedLifecycleManifest(t, base)) require.Error(t, err) assert.Contains(t, err.Error(), "predates this updater build") BuildTime = "" publishedAt, err := time.Parse(time.RFC3339, base.PublishedAt) require.NoError(t, err) ManifestKeyValidity = "test-release-key=" + strconv.FormatInt(publishedAt.Add(time.Hour).Unix(), 10) + ":" + strconv.FormatInt(publishedAt.Add(2*time.Hour).Unix(), 10) _, err = decodeReleaseManifest(encodeSignedLifecycleManifest(t, base)) require.Error(t, err) assert.Contains(t, err.Error(), "outside key") ManifestKeyValidity = "" ManifestRevokedKeyIDs = "test-release-key" _, err = decodeReleaseManifest(encodeSignedLifecycleManifest(t, base)) require.Error(t, err) assert.Contains(t, err.Error(), "revoked") }