{"record":{"id":"a2da079dedbb7ead","repo":"hashicorp/packer","slug":"private-key-does-not-implement-crypto-signer","errorCode":null,"errorMessage":"private key does not implement crypto.Signer","messagePattern":"private key does not implement crypto\\.Signer","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/attestation/sign_key.go","lineNumber":203,"sourceCode":"\tif privateKey, verifier, err := loadPEMPrivateKeyAsPublic(contents); err == nil {\n\t\treturn privateKey, verifier, nil\n\t}\n\n\treturn nil, nil, fmt.Errorf(\"unsupported PEM verifier data\")\n}\n\nfunc loadPEMPrivateKeyAsPublic(contents []byte) (crypto.PublicKey, []byte, error) {\n\tblock, _ := pem.Decode(contents)\n\tif block == nil {\n\t\treturn nil, nil, fmt.Errorf(\"no PEM block found\")\n\t}\n\n\tvar signer crypto.Signer\n\tif key, err := x509.ParsePKCS8PrivateKey(block.Bytes); err == nil {\n\t\tvar ok bool\n\t\tsigner, ok = key.(crypto.Signer)\n\t\tif !ok {\n\t\t\treturn nil, nil, fmt.Errorf(\"private key does not implement crypto.Signer\")\n\t\t}\n\t} else if key, err := x509.ParsePKCS1PrivateKey(block.Bytes); err == nil {\n\t\tsigner = key\n\t} else if key, err := x509.ParseECPrivateKey(block.Bytes); err == nil {\n\t\tsigner = key\n\t} else {\n\t\treturn nil, nil, fmt.Errorf(\"unsupported private key data\")\n\t}\n\n\tpublicKeyPEM, err := marshalPublicKeyPEM(signer.Public())\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\tpublicKey, _, err := loadPEMPublicKey(publicKeyPEM)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}","sourceCodeStart":185,"sourceCodeEnd":221,"githubUrl":"https://github.com/hashicorp/packer/blob/eb36e3c3e48a036f3e8cc94087636ee72e1303c9/internal/attestation/sign_key.go#L185-L221","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Provide the public key or certificate directly instead of deriving it from an exotic private key: 'openssl pkey -pubout -out verifier.pem'.","Regenerate with a standard signing algorithm (RSA, ECDSA, Ed25519) and export as PKCS#8 PEM.","Test-parse the block with x509.ParsePKCS8PrivateKey and type-assert crypto.Signer to see the concrete key type Go produced.","If the key must stay in an HSM, use the HSM's crypto.Signer implementation rather than a PEM file."],"exampleFix":"// before\nv, err := attestation.LoadPEMVerifier(\"kem-private.pem\") // private key does not implement crypto.Signer\n// after\n$ openssl pkey -in signing-key.pem -pubout -out verifier.pem\nv, err := attestation.LoadPEMVerifier(\"verifier.pem\")","handlingStrategy":"validation","validationCode":"raw, _ := os.ReadFile(path)\nblock, _ := pem.Decode(raw)\nif block == nil {\n\treturn fmt.Errorf(\"%s: no PEM block\", path)\n}\nkey, err := x509.ParsePKCS8PrivateKey(block.Bytes)\nif err == nil {\n\tif _, ok := key.(crypto.Signer); !ok {\n\t\treturn fmt.Errorf(\"%s: PKCS#8 key type %T is not a signer; supply the public key/cert instead\", path, key)\n\t}\n}\nreturn nil","typeGuard":"func implementsCryptoSigner(key any) bool {\n\ts, ok := key.(crypto.Signer)\n\treturn ok && s != nil\n}","tryCatchPattern":"v, err := attestation.LoadPEMVerifier(path)\nif err != nil && strings.Contains(err.Error(), \"does not implement crypto.Signer\") {\n\treturn fmt.Errorf(\"%s wraps a non-signing private key; provide a PUBLIC KEY or CERTIFICATE file directly\", path)\n}","preventionTips":["Prefer distributing public keys or certificates to verifiers rather than deriving them from private keys.","Regenerate exotic PKCS#8 blobs with standard RSA/EC/Ed25519 keys when private-key input is required.","Type-assert crypto.Signer on parsed keys in preflight checks to fail early with a clear message.","Keep signing and verification key material in separate, clearly named files to avoid cross-use."],"tags":["go","crypto","pkcs8","attestation"],"backgroundTag":"key-not-crypto-signer","analyzedSha":"eb36e3c3e48a036f3e8cc94087636ee72e1303c9","analyzedAt":"2026-09-05T13:20:43.127Z","contentChangedAt":"2026-09-05T13:20:43.127Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}