hashicorp/packer · error

ECDSA verification failed

Error message

ECDSA verification failed

What it means

pemVerifier.Verify verifies an attestation signature using the loaded public key. For *ecdsa.PublicKey keys it hashes the pre-auth-encoded payload with SHA-256 and calls ecdsa.VerifyASN1; when that returns false the verifier returns the literal error "ECDSA verification failed". This is a signature-validity failure: the signature bytes do not cryptographically match the payload under this ECDSA public key.

Source

Thrown at internal/attestation/sign_key.go:87

		Sig:   signature,
	}, nil
}

func (s *pemSigner) Verifier(context.Context, BackendConfig) (Verifier, error) {
	return s.verifier, nil
}

func (v *pemVerifier) Verify(_ context.Context, payloadType string, payload, signature []byte) error {
	pae := PreAuthEncode(payloadType, payload)

	switch publicKey := v.publicKey.(type) {
	case *rsa.PublicKey:
		digest := sha256.Sum256(pae)
		return rsa.VerifyPKCS1v15(publicKey, crypto.SHA256, digest[:], signature)
	case *ecdsa.PublicKey:
		digest := sha256.Sum256(pae)
		if !ecdsa.VerifyASN1(publicKey, digest[:], signature) {
			return fmt.Errorf("ECDSA verification failed")
		}
		return nil
	case ed25519.PublicKey:
		if !ed25519.Verify(publicKey, pae, signature) {
			return fmt.Errorf("Ed25519 verification failed")
		}
		return nil
	default:
		return fmt.Errorf("unsupported public key type %T", v.publicKey)
	}
}

func (v *pemVerifier) KeyID() string {
	return v.keyID
}

func LoadPEMVerifier(path string) (Verifier, error) {
	contents, err := os.ReadFile(path)

View on GitHub (pinned to eb36e3c3e4)

Solutions

  1. Confirm the verifier's PEM public key matches the private key that produced the signature — compare the KeyID (SHA-256 hex of the PEM public key) from the Signature against the verifier's KeyID().
  2. Ensure the exact same payloadType string and payload bytes are passed to Verify as were passed to Sign; PreAuthEncode makes the signature sensitive to both.
  3. Check the signature encoding: decode it (e.g. base64/hex) exactly as produced and do not truncate or re-encode the ASN.1 DER signature bytes.
  4. If signatures were produced by an external tool, confirm it uses the same scheme: ECDSA over SHA-256 of the PAE, ASN.1-encoded (not P1363 fixed-size r||s) — convert if necessary.

Example fix

// before: verifying with an unrelated public key
verifier, _ := attestation.LoadPEMVerifier("other-key.pub")
err := verifier.Verify(ctx, payloadType, payload, sig.Sig) // ECDSA verification failed

// after: key-match check first (sign_key.go exposes KeyID as sha256 hex of the public PEM)
verifier, _ := attestation.LoadPEMVerifier("signer-key.pub")
if verifier.KeyID() != sig.KeyID {
	return fmt.Errorf("signature key %s does not match verifier %s", sig.KeyID, verifier.KeyID())
}
err := verifier.Verify(ctx, payloadType, payload, sig.Sig)
Defensive patterns

Strategy: validation

Validate before calling

// Verify key correspondence before calling Verify
if verifier.KeyID() != sig.KeyID {
	return fmt.Errorf("signature made with key %s but verifier is %s", sig.KeyID, verifier.KeyID())
}
// Confirm ECDSA verifier type
switch v := verifier.(type) {
case *attestation.PEMVerifier:
	// expected; proceed
}

Type guard

func isECDSAVerifier(v attestation.Verifier, pub crypto.PublicKey) bool {
	_, ok := pub.(*ecdsa.PublicKey)
	return ok
}

Try / catch

if err := verifier.Verify(ctx, payloadType, payload, sig.Sig); err != nil {
	if err.Error() == "ECDSA verification failed" {
		// signature/payload/key mismatch — do not retry blindly;
		// compare sig.KeyID vs verifier.KeyID() and re-check payload bytes
	}
	return fmt.Errorf("attestation verify: %w", err)
}

Prevention

When it happens

Trigger: Calling pemVerifier.Verify(ctx, payloadType, payload, signature) where the verifier's publicKey is *ecdsa.PublicKey and ecdsa.VerifyASN1(publicKey, sha256(PreAuthEncode(payloadType,payload)), signature) returns false — wrong key, tampered payload, truncated/mangled signature, or a signature produced with a different payload encoding.

Common situations: Verifying with the wrong public key (signature was made by a different signer, e.g. rotated keys); the payload bytes differ between signing and verification (whitespace, re-serialization, changed payloadType string); signature was base64/hex mangled in transit; verifying an RSA or Ed25519 signature against an ECDSA verifier.

Related errors


AI-assisted analysis of hashicorp/packer@eb36e3c3e4 (2026-09-05). Data as JSON: /api/errors/455fca6ef15f2b02. Report an issue: GitHub.