hashicorp/packer · error

private key does not implement crypto.Signer

Error message

private key does not implement crypto.Signer

What it means

In loadPEMPrivateKeyAsPublic, the PEM block parsed as a PKCS#8 private key, but the resulting value does not implement crypto.Signer, so a corresponding public verifier cannot be derived (deriving the public key requires calling Signer.Public()). The load is aborted. This mirrors error 104 but on the verifier-extraction path.

Source

Thrown at internal/attestation/sign_key.go:203

	if privateKey, verifier, err := loadPEMPrivateKeyAsPublic(contents); err == nil {
		return privateKey, verifier, nil
	}

	return nil, nil, fmt.Errorf("unsupported PEM verifier data")
}

func loadPEMPrivateKeyAsPublic(contents []byte) (crypto.PublicKey, []byte, error) {
	block, _ := pem.Decode(contents)
	if block == nil {
		return nil, nil, fmt.Errorf("no PEM block found")
	}

	var signer crypto.Signer
	if key, err := x509.ParsePKCS8PrivateKey(block.Bytes); err == nil {
		var ok bool
		signer, ok = key.(crypto.Signer)
		if !ok {
			return nil, nil, fmt.Errorf("private key does not implement crypto.Signer")
		}
	} else if key, err := x509.ParsePKCS1PrivateKey(block.Bytes); err == nil {
		signer = key
	} else if key, err := x509.ParseECPrivateKey(block.Bytes); err == nil {
		signer = key
	} else {
		return nil, nil, fmt.Errorf("unsupported private key data")
	}

	publicKeyPEM, err := marshalPublicKeyPEM(signer.Public())
	if err != nil {
		return nil, nil, err
	}

	publicKey, _, err := loadPEMPublicKey(publicKeyPEM)
	if err != nil {
		return nil, nil, err
	}

View on GitHub (pinned to eb36e3c3e4)

Solutions

  1. Provide the public key or certificate directly instead of deriving it from an exotic private key: 'openssl pkey -pubout -out verifier.pem'.
  2. Regenerate with a standard signing algorithm (RSA, ECDSA, Ed25519) and export as PKCS#8 PEM.
  3. Test-parse the block with x509.ParsePKCS8PrivateKey and type-assert crypto.Signer to see the concrete key type Go produced.
  4. If the key must stay in an HSM, use the HSM's crypto.Signer implementation rather than a PEM file.

Example fix

// before
v, err := attestation.LoadPEMVerifier("kem-private.pem") // private key does not implement crypto.Signer
// after
$ openssl pkey -in signing-key.pem -pubout -out verifier.pem
v, err := attestation.LoadPEMVerifier("verifier.pem")
Defensive patterns

Strategy: validation

Validate before calling

raw, _ := os.ReadFile(path)
block, _ := pem.Decode(raw)
if block == nil {
	return fmt.Errorf("%s: no PEM block", path)
}
key, err := x509.ParsePKCS8PrivateKey(block.Bytes)
if err == nil {
	if _, ok := key.(crypto.Signer); !ok {
		return fmt.Errorf("%s: PKCS#8 key type %T is not a signer; supply the public key/cert instead", path, key)
	}
}
return nil

Type guard

func implementsCryptoSigner(key any) bool {
	s, ok := key.(crypto.Signer)
	return ok && s != nil
}

Try / catch

v, err := attestation.LoadPEMVerifier(path)
if err != nil && strings.Contains(err.Error(), "does not implement crypto.Signer") {
	return fmt.Errorf("%s wraps a non-signing private key; provide a PUBLIC KEY or CERTIFICATE file directly", path)
}

Prevention

When it happens

Trigger: Calling LoadPEMVerifier/LoadPEMVerifierBytes on a PKCS#8 PEM whose parsed key is not a crypto.Signer (non-signing key types wrapped in PKCS#8, unusual algorithm OIDs).

Common situations: Reusing a key-encapsulation or key-agreement PKCS#8 blob as an attestation verifier; HSM-exported blobs with opaque algorithm identifiers; keys generated with tooling that emits non-standard PKCS#8 payloads.

Related errors


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