317 lines
19 KiB
Go
317 lines
19 KiB
Go
package saas
|
|
|
|
import (
|
|
"context"
|
|
"crypto/ed25519"
|
|
"crypto/rand"
|
|
"crypto/sha256"
|
|
"encoding/base64"
|
|
"encoding/hex"
|
|
"errors"
|
|
"os"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"data-terminal-cloud/internal/audit"
|
|
"data-terminal-cloud/internal/deviceauth"
|
|
"data-terminal-cloud/internal/identity"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/jackc/pgx/v5/pgxpool"
|
|
)
|
|
|
|
type firmwareIntegrationStore struct {
|
|
verifiedObject string
|
|
verifiedDigest string
|
|
verifiedSize int64
|
|
presigned []string
|
|
removed []string
|
|
}
|
|
|
|
func (s *firmwareIntegrationStore) PresignUpload(_ context.Context, objectRef string, _ time.Duration) (string, error) {
|
|
s.presigned = append(s.presigned, objectRef)
|
|
return "https://objects.invalid/upload/" + objectRef, nil
|
|
}
|
|
|
|
func (s *firmwareIntegrationStore) PresignDownload(_ context.Context, objectRef string, _ time.Duration, filename string) (string, error) {
|
|
return "https://objects.invalid/download/" + objectRef + "?filename=" + filename, nil
|
|
}
|
|
|
|
func (s *firmwareIntegrationStore) VerifyDigest(_ context.Context, objectRef, digest string, size int64) error {
|
|
s.verifiedObject, s.verifiedDigest, s.verifiedSize = objectRef, digest, size
|
|
return nil
|
|
}
|
|
|
|
func (s *firmwareIntegrationStore) Remove(_ context.Context, objectRef string) error {
|
|
s.removed = append(s.removed, objectRef)
|
|
return nil
|
|
}
|
|
|
|
func TestFirmwareReleaseAndRolloutWriteLifecycle(t *testing.T) {
|
|
databaseURL := os.Getenv("TEST_DATABASE_URL")
|
|
if databaseURL == "" {
|
|
t.Skip("TEST_DATABASE_URL is not set")
|
|
}
|
|
ctx := context.Background()
|
|
pool, err := pgxpool.New(ctx, databaseURL)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer pool.Close()
|
|
store := &firmwareIntegrationStore{}
|
|
service := NewService(pool, audit.NewRepository(), nil, nil)
|
|
service.ConfigureFirmwareStore(store, 4*time.Minute)
|
|
owner := identity.Principal{Issuer: testIssuer, Subject: testOwnerSubject}
|
|
outsider := identity.Principal{Issuer: testIssuer, Subject: testOutsideSubject}
|
|
householdID := "10000000-0000-0000-0000-000000000211"
|
|
devicePublicID := "10000000-0000-0000-0000-000000000511"
|
|
keyID := "firmware-integration-" + uuid.NewString()
|
|
version := "integration-" + uuid.NewString()
|
|
var releaseID, retiredReleaseID, replacementReleaseID, rolloutID string
|
|
defer func() {
|
|
_, _ = pool.Exec(ctx, `DELETE FROM audit_event WHERE request_id LIKE 'firmware-integration-%'`)
|
|
if rolloutID != "" {
|
|
_, _ = pool.Exec(ctx, `DELETE FROM firmware_rollout WHERE public_id=$1::uuid`, rolloutID)
|
|
}
|
|
_, _ = pool.Exec(ctx, `DELETE FROM device_command WHERE payload->>'release_id'=$1`, releaseID)
|
|
if releaseID != "" {
|
|
_, _ = pool.Exec(ctx, `DELETE FROM firmware_release WHERE public_id=$1::uuid`, releaseID)
|
|
}
|
|
if retiredReleaseID != "" {
|
|
_, _ = pool.Exec(ctx, `DELETE FROM firmware_release WHERE public_id=$1::uuid`, retiredReleaseID)
|
|
}
|
|
if replacementReleaseID != "" {
|
|
_, _ = pool.Exec(ctx, `DELETE FROM firmware_release WHERE public_id=$1::uuid`, replacementReleaseID)
|
|
}
|
|
_, _ = pool.Exec(ctx, `DELETE FROM firmware_signing_key WHERE key_id=$1`, keyID)
|
|
}()
|
|
|
|
if err := service.RegisterFirmwareSigningKey(ctx, owner, householdID, "firmware-integration-invalid-key", keyID, "invalid"); err == nil {
|
|
t.Fatal("invalid signing key was accepted")
|
|
}
|
|
publicKey, privateKey, err := ed25519.GenerateKey(rand.Reader)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
publicKeyBase64 := base64.StdEncoding.EncodeToString(publicKey)
|
|
if err := service.RegisterFirmwareSigningKey(ctx, outsider, householdID, "firmware-integration-outsider-key", keyID, publicKeyBase64); !errors.Is(err, ErrAccessDenied) {
|
|
t.Fatalf("outsider signing key error=%v", err)
|
|
}
|
|
if err := service.RegisterFirmwareSigningKey(ctx, owner, householdID, "firmware-integration-key", keyID, publicKeyBase64); err != nil {
|
|
t.Fatalf("register signing key: %v", err)
|
|
}
|
|
if err := service.RegisterFirmwareSigningKey(ctx, owner, householdID, "firmware-integration-key-replay", keyID, publicKeyBase64); err != nil {
|
|
t.Fatalf("replay same signing key: %v", err)
|
|
}
|
|
otherPublicKey, _, err := ed25519.GenerateKey(rand.Reader)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := service.RegisterFirmwareSigningKey(ctx, owner, householdID, "firmware-integration-key-overwrite", keyID, base64.StdEncoding.EncodeToString(otherPublicKey)); !errors.Is(err, ErrFirmwareSigningKeyConflict) {
|
|
t.Fatalf("overwrite signing key error=%v", err)
|
|
}
|
|
keys, err := service.ListFirmwareSigningKeys(ctx, owner, householdID)
|
|
expectedFingerprint := sha256.Sum256(publicKey)
|
|
if err != nil || len(keys) != 1 || keys[0].KeyID != keyID || keys[0].Status != "ACTIVE" || keys[0].FingerprintSHA256 != hex.EncodeToString(expectedFingerprint[:]) {
|
|
t.Fatalf("signing keys=%+v err=%v", keys, err)
|
|
}
|
|
|
|
firmwareBytes := []byte("synthetic signed firmware image")
|
|
digestBytes := sha256.Sum256(firmwareBytes)
|
|
digest := hex.EncodeToString(digestBytes[:])
|
|
model, hardware := "simulated-terminal", "sim-rev-a"
|
|
signature := base64.StdEncoding.EncodeToString(ed25519.Sign(privateKey, []byte(firmwareManifest(model, hardware, version, digest, int64(len(firmwareBytes))))))
|
|
release, err := service.PrepareFirmwareRelease(ctx, owner, householdID, "firmware-integration-prepare", PrepareFirmwareInput{
|
|
Model: model, HardwareRevision: hardware, Version: version, ExpectedDigest: digest,
|
|
Signature: signature, SigningKeyID: keyID, MinimumSecurityVersion: "1", ReleaseNotes: "合成固件集成测试",
|
|
ExpectedSize: int64(len(firmwareBytes)),
|
|
})
|
|
if err != nil || release.Status != "UPLOADING" || release.UploadURL == "" || release.UploadUntil == nil {
|
|
t.Fatalf("prepared release=%+v err=%v", release, err)
|
|
}
|
|
releaseID = release.ID
|
|
if _, err := service.RevokeFirmwareSigningKey(ctx, owner, householdID, "firmware-integration-revoke-uploading", keyID); !errors.Is(err, ErrFirmwareSigningKeyInUse) {
|
|
t.Fatalf("revoke uploading signing key error=%v", err)
|
|
}
|
|
keys, err = service.ListFirmwareSigningKeys(ctx, owner, householdID)
|
|
if err != nil || len(keys) != 1 || keys[0].UploadingReleases != 1 {
|
|
t.Fatalf("uploading key references=%+v err=%v", keys, err)
|
|
}
|
|
if !strings.Contains(release.UploadURL, "/firmware/simulated-terminal/sim-rev-a/") {
|
|
t.Fatalf("unexpected upload URL %q", release.UploadURL)
|
|
}
|
|
if _, err := service.RenewFirmwareUpload(ctx, outsider, release.ID, "firmware-integration-outsider-renew"); !errors.Is(err, ErrAccessDenied) {
|
|
t.Fatalf("outsider renew upload error=%v", err)
|
|
}
|
|
renewed, err := service.RenewFirmwareUpload(ctx, owner, release.ID, "firmware-integration-renew")
|
|
if err != nil || renewed.ID != release.ID || renewed.Status != "UPLOADING" || renewed.UploadURL == "" || renewed.UploadUntil == nil || len(store.presigned) != 2 {
|
|
t.Fatalf("renewed release=%+v presigned=%v err=%v", renewed, store.presigned, err)
|
|
}
|
|
releases, err := service.ListFirmwareReleases(ctx, owner, householdID)
|
|
if err != nil || len(releases) != 1 || releases[0].ID != release.ID {
|
|
t.Fatalf("firmware releases=%+v err=%v", releases, err)
|
|
}
|
|
if _, err := service.FinalizeFirmwareRelease(ctx, outsider, release.ID, "firmware-integration-outsider-finalize"); !errors.Is(err, ErrAccessDenied) {
|
|
t.Fatalf("outsider finalize error=%v", err)
|
|
}
|
|
release, err = service.FinalizeFirmwareRelease(ctx, owner, release.ID, "firmware-integration-finalize")
|
|
if err != nil || release.Status != "READY" || release.VerifiedAt == nil {
|
|
t.Fatalf("finalized release=%+v err=%v", release, err)
|
|
}
|
|
if store.verifiedDigest != digest || store.verifiedSize != int64(len(firmwareBytes)) || store.verifiedObject == "" {
|
|
t.Fatalf("object verification=%+v", store)
|
|
}
|
|
replayedRelease, err := service.FinalizeFirmwareRelease(ctx, owner, release.ID, "firmware-integration-finalize-replay")
|
|
if err != nil || replayedRelease.Status != "READY" {
|
|
t.Fatalf("replayed finalize=%+v err=%v", replayedRelease, err)
|
|
}
|
|
if _, err := service.RenewFirmwareUpload(ctx, owner, release.ID, "firmware-integration-renew-ready"); !errors.Is(err, ErrFirmwareStateConflict) {
|
|
t.Fatalf("renew READY release error=%v", err)
|
|
}
|
|
if _, err := service.PauseFirmwareRelease(ctx, outsider, release.ID, "firmware-integration-outsider-release-pause"); !errors.Is(err, ErrAccessDenied) {
|
|
t.Fatalf("outsider pause release error=%v", err)
|
|
}
|
|
release, err = service.PauseFirmwareRelease(ctx, owner, release.ID, "firmware-integration-release-pause")
|
|
if err != nil || release.Status != "PAUSED" {
|
|
t.Fatalf("paused release=%+v err=%v", release, err)
|
|
}
|
|
if replayed, err := service.PauseFirmwareRelease(ctx, owner, release.ID, "firmware-integration-release-pause-replay"); err != nil || replayed.Status != "PAUSED" {
|
|
t.Fatalf("replayed release pause=%+v err=%v", replayed, err)
|
|
}
|
|
if _, err := service.StartFirmwareRollout(ctx, owner, householdID, release.ID, "firmware-integration-paused-release-rollout", "暂停版本禁止下发", 100, []string{devicePublicID}); !errors.Is(err, ErrFirmwareStateConflict) {
|
|
t.Fatalf("rollout with paused release error=%v", err)
|
|
}
|
|
release, err = service.ResumeFirmwareRelease(ctx, owner, release.ID, "firmware-integration-release-resume")
|
|
if err != nil || release.Status != "READY" {
|
|
t.Fatalf("resumed release=%+v err=%v", release, err)
|
|
}
|
|
if replayed, err := service.ResumeFirmwareRelease(ctx, owner, release.ID, "firmware-integration-release-resume-replay"); err != nil || replayed.Status != "READY" {
|
|
t.Fatalf("replayed release resume=%+v err=%v", replayed, err)
|
|
}
|
|
|
|
retireVersion := "retire-" + uuid.NewString()
|
|
retireSignature := base64.StdEncoding.EncodeToString(ed25519.Sign(privateKey, []byte(firmwareManifest(model, hardware, retireVersion, digest, int64(len(firmwareBytes))))))
|
|
retiring, err := service.PrepareFirmwareRelease(ctx, owner, householdID, "firmware-integration-prepare-retire", PrepareFirmwareInput{Model: model, HardwareRevision: hardware, Version: retireVersion, ExpectedDigest: digest, Signature: retireSignature, SigningKeyID: keyID, ExpectedSize: int64(len(firmwareBytes))})
|
|
if err != nil {
|
|
t.Fatalf("prepare retiring release: %v", err)
|
|
}
|
|
retiredReleaseID = retiring.ID
|
|
retired, err := service.RetireFirmwareRelease(ctx, owner, retiring.ID, "firmware-integration-retire")
|
|
if err != nil || retired.Status != "RETIRED" || len(store.removed) != 1 || store.removed[0] == "" {
|
|
t.Fatalf("retired release=%+v removed=%v err=%v", retired, store.removed, err)
|
|
}
|
|
if replayed, err := service.RetireFirmwareRelease(ctx, owner, retiring.ID, "firmware-integration-retire-replay"); err != nil || replayed.Status != "RETIRED" || len(store.removed) != 2 {
|
|
t.Fatalf("replayed retire=%+v removed=%v err=%v", replayed, store.removed, err)
|
|
}
|
|
if _, err := service.FinalizeFirmwareRelease(ctx, owner, retiring.ID, "firmware-integration-finalize-retired"); !errors.Is(err, ErrFirmwareStateConflict) {
|
|
t.Fatalf("finalize retired release error=%v", err)
|
|
}
|
|
replacement, err := service.PrepareFirmwareRelease(ctx, owner, householdID, "firmware-integration-prepare-replacement", PrepareFirmwareInput{Model: model, HardwareRevision: hardware, Version: retireVersion, ExpectedDigest: digest, Signature: retireSignature, SigningKeyID: keyID, ExpectedSize: int64(len(firmwareBytes))})
|
|
if err != nil || replacement.Status != "UPLOADING" || replacement.ID == retiring.ID {
|
|
t.Fatalf("replacement release=%+v err=%v", replacement, err)
|
|
}
|
|
replacementReleaseID = replacement.ID
|
|
if _, err := service.RetireFirmwareRelease(ctx, owner, replacement.ID, "firmware-integration-retire-replacement"); err != nil {
|
|
t.Fatalf("retire replacement release: %v", err)
|
|
}
|
|
|
|
if _, err := service.StartFirmwareRollout(ctx, outsider, householdID, release.ID, "firmware-integration-outsider-rollout", "禁止下发", 100, []string{devicePublicID}); !errors.Is(err, ErrAccessDenied) {
|
|
t.Fatalf("outsider rollout error=%v", err)
|
|
}
|
|
rollout, err := service.StartFirmwareRollout(ctx, owner, householdID, release.ID, "firmware-integration-rollout", "全量合成下发", 100, []string{devicePublicID})
|
|
if err != nil || rollout.Status != "RUNNING" || rollout.Targeted != 1 {
|
|
t.Fatalf("rollout=%+v err=%v", rollout, err)
|
|
}
|
|
rolloutID = rollout.ID
|
|
rollout, err = service.GetFirmwareRollout(ctx, owner, rollout.ID)
|
|
if err != nil || len(rollout.Assignments) != 1 || rollout.Assignments[0].DeviceID != devicePublicID || rollout.Assignments[0].Status != "ASSIGNED" {
|
|
t.Fatalf("rollout detail=%+v err=%v", rollout, err)
|
|
}
|
|
rollouts, err := service.ListFirmwareRollouts(ctx, owner, householdID)
|
|
if err != nil || len(rollouts) != 1 || rollouts[0].ID != rollout.ID {
|
|
t.Fatalf("rollouts=%+v err=%v", rollouts, err)
|
|
}
|
|
impact, err := service.GetFirmwareReleaseImpact(ctx, owner, release.ID)
|
|
if err != nil || impact.ReleaseStatus != "READY" || impact.Rollouts.Total != 1 || impact.Rollouts.Running != 1 || impact.Devices.Total != 1 || impact.Devices.Assigned != 1 || impact.Commands.Queued != 1 || impact.Devices.Observing != 0 {
|
|
t.Fatalf("initial release impact=%+v err=%v", impact, err)
|
|
}
|
|
if _, err := service.GetFirmwareReleaseImpact(ctx, outsider, release.ID); !errors.Is(err, ErrAccessDenied) {
|
|
t.Fatalf("outsider release impact error=%v", err)
|
|
}
|
|
downloadURL, expiresAt, err := service.FirmwareDownloadForDevice(ctx, deviceauth.Identity{
|
|
ID: "10000000-0000-0000-0000-000000000501", TenantID: "10000000-0000-0000-0000-000000000001",
|
|
}, release.ID)
|
|
if err != nil || downloadURL == "" || time.Until(expiresAt) <= 0 {
|
|
t.Fatalf("firmware download url=%q expires=%s err=%v", downloadURL, expiresAt, err)
|
|
}
|
|
observationCommandID := uuid.NewString()
|
|
if _, err := pool.Exec(ctx, `INSERT INTO device_command(id,tenant_id,device_id,command_type,payload,status,requested_by,idempotency_key,request_digest,expires_at,delivered_at,acknowledged_at) VALUES($1::uuid,'10000000-0000-0000-0000-000000000001'::uuid,'10000000-0000-0000-0000-000000000502'::uuid,'firmware_update',jsonb_build_object('release_id',$2::text),'ACKNOWLEDGED','10000000-0000-0000-0000-000000000101'::uuid,$3,repeat('a',64),now()+interval '1 hour',now(),now())`, observationCommandID, release.ID, "firmware-impact-"+uuid.NewString()); err != nil {
|
|
t.Fatalf("insert observation command: %v", err)
|
|
}
|
|
if _, err := pool.Exec(ctx, `INSERT INTO firmware_assignment(rollout_id,tenant_id,device_id,command_id,status,progress_percent,last_result,last_reported_at) SELECT ro.id,ro.tenant_id,'10000000-0000-0000-0000-000000000502'::uuid,$2::uuid,'INSTALLING',72,'{"phase":"installing","progress_percent":72}'::jsonb,now() FROM firmware_rollout ro WHERE ro.public_id=$1::uuid`, rollout.ID, observationCommandID); err != nil {
|
|
t.Fatalf("insert observation assignment: %v", err)
|
|
}
|
|
impact, err = service.GetFirmwareReleaseImpact(ctx, owner, release.ID)
|
|
if err != nil || impact.Devices.Total != 2 || impact.Devices.Installing != 1 || impact.Devices.Observing != 1 || impact.Commands.Queued != 1 || impact.Commands.Acknowledged != 1 || len(impact.ObservationDevices) != 1 || impact.ObservationDevices[0].ObservationReason != "INSTALLATION_IN_PROGRESS" || impact.ObservationDevices[0].ProgressPercent == nil || *impact.ObservationDevices[0].ProgressPercent != 72 {
|
|
t.Fatalf("active release impact=%+v err=%v", impact, err)
|
|
}
|
|
if _, err := service.RetireFirmwareRelease(ctx, owner, release.ID, "firmware-integration-retire-running"); !errors.Is(err, ErrFirmwareReleaseInUse) {
|
|
t.Fatalf("retire release with running rollout error=%v", err)
|
|
}
|
|
if _, err := service.RevokeFirmwareSigningKey(ctx, owner, householdID, "firmware-integration-revoke-running", keyID); !errors.Is(err, ErrFirmwareSigningKeyInUse) {
|
|
t.Fatalf("revoke key with running rollout error=%v", err)
|
|
}
|
|
release, err = service.PauseFirmwareRelease(ctx, owner, release.ID, "firmware-integration-release-pause-running")
|
|
if err != nil || release.Status != "PAUSED" {
|
|
t.Fatalf("paused running release=%+v err=%v", release, err)
|
|
}
|
|
rollout, err = service.GetFirmwareRollout(ctx, owner, rollout.ID)
|
|
if err != nil || rollout.Status != "PAUSED" {
|
|
t.Fatalf("rollout not paused with release=%+v err=%v", rollout, err)
|
|
}
|
|
impact, err = service.GetFirmwareReleaseImpact(ctx, owner, release.ID)
|
|
if err != nil || impact.ReleaseStatus != "PAUSED" || impact.Rollouts.Running != 0 || impact.Rollouts.Paused != 1 || impact.Commands.CancelledBeforeDelivery != 1 || impact.Commands.Acknowledged != 1 || impact.Devices.Observing != 1 || len(impact.ObservationDevices) != 1 {
|
|
t.Fatalf("paused release impact=%+v err=%v", impact, err)
|
|
}
|
|
var cancelledCommands int
|
|
if err := pool.QueryRow(ctx, `SELECT count(*) FROM device_command WHERE payload->>'release_id'=$1 AND status='CANCELLED'`, release.ID).Scan(&cancelledCommands); err != nil || cancelledCommands != 1 {
|
|
t.Fatalf("release pause cancelled commands=%d err=%v", cancelledCommands, err)
|
|
}
|
|
if _, _, err := service.FirmwareDownloadForDevice(ctx, deviceauth.Identity{
|
|
ID: "10000000-0000-0000-0000-000000000501", TenantID: "10000000-0000-0000-0000-000000000001",
|
|
}, release.ID); !errors.Is(err, ErrAccessDenied) {
|
|
t.Fatalf("paused rollout download error=%v", err)
|
|
}
|
|
if _, err := service.RevokeFirmwareSigningKey(ctx, outsider, householdID, "firmware-integration-outsider-revoke", keyID); !errors.Is(err, ErrAccessDenied) {
|
|
t.Fatalf("outsider revoke signing key error=%v", err)
|
|
}
|
|
revokedKey, err := service.RevokeFirmwareSigningKey(ctx, owner, householdID, "firmware-integration-revoke", keyID)
|
|
if err != nil || revokedKey.Status != "REVOKED" || revokedKey.RevokedAt == nil || revokedKey.ReadyReleases != 0 || revokedKey.RunningRollouts != 0 {
|
|
t.Fatalf("revoked signing key=%+v err=%v", revokedKey, err)
|
|
}
|
|
if replayedKey, err := service.RevokeFirmwareSigningKey(ctx, owner, householdID, "firmware-integration-revoke-replay", keyID); err != nil || replayedKey.Status != "REVOKED" {
|
|
t.Fatalf("replayed key revoke=%+v err=%v", replayedKey, err)
|
|
}
|
|
if err := service.RegisterFirmwareSigningKey(ctx, owner, householdID, "firmware-integration-reactivate", keyID, publicKeyBase64); !errors.Is(err, ErrFirmwareSigningKeyConflict) {
|
|
t.Fatalf("reactivate revoked signing key error=%v", err)
|
|
}
|
|
if _, err := service.ResumeFirmwareRelease(ctx, owner, release.ID, "firmware-integration-resume-revoked-key"); !errors.Is(err, ErrFirmwareSigningKeyInactive) {
|
|
t.Fatalf("resume release with revoked signing key error=%v", err)
|
|
}
|
|
removedBeforeVerifiedRetire := len(store.removed)
|
|
release, err = service.RetireFirmwareRelease(ctx, owner, release.ID, "firmware-integration-retire-verified")
|
|
if err != nil || release.Status != "RETIRED" || len(store.removed) != removedBeforeVerifiedRetire {
|
|
t.Fatalf("retired verified release=%+v removed=%v err=%v", release, store.removed, err)
|
|
}
|
|
if replayed, err := service.RetireFirmwareRelease(ctx, owner, release.ID, "firmware-integration-retire-verified-replay"); err != nil || replayed.Status != "RETIRED" || len(store.removed) != removedBeforeVerifiedRetire {
|
|
t.Fatalf("replayed verified retire=%+v removed=%v err=%v", replayed, store.removed, err)
|
|
}
|
|
if _, err := service.StartFirmwareRollout(ctx, owner, householdID, release.ID, "firmware-integration-revoked-key-rollout", "吊销后禁止", 100, []string{devicePublicID}); !errors.Is(err, ErrFirmwareStateConflict) {
|
|
t.Fatalf("rollout with revoked signing key error=%v", err)
|
|
}
|
|
if _, err := service.PrepareFirmwareRelease(ctx, owner, householdID, "firmware-integration-revoked-key-prepare", PrepareFirmwareInput{Model: model, HardwareRevision: hardware, Version: "revoked-" + uuid.NewString(), ExpectedDigest: digest, Signature: signature, SigningKeyID: keyID, ExpectedSize: int64(len(firmwareBytes))}); !errors.Is(err, ErrFirmwareSigningKeyInactive) {
|
|
t.Fatalf("prepare with revoked signing key error=%v", err)
|
|
}
|
|
}
|