You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
cosign sign with --signing-config and --key pkcs11:... panics with a nil pointer dereference when attempting to sign. The PKCS#11 session is closed before the signing operation occurs.
Version
cosign v3.0.5 (built with -tags pkcs11key)
Go 1.25.6
Ubuntu 24.04 (GitHub Actions runner)
Steps to Reproduce
Set up a PKCS#11 token with an EC P-256 key (no certificate stored on token)
Create a signing config pointing to a Rekor v2 instance:
NewSignerVerifierKeypair wraps the SignerVerifier (which holds a reference to the PKCS#11 Key). The defer sv.Close() fires on return, which calls Key.Close():
func (k*Key) Close() {
k.ctx.Close()
k.signer=nil// <-- nils the signerk.cert=nilk.ctx=nil
}
The returned keypair still references the same Key struct. When WriteNewBundleWithSigningConfig → bundle.SignData → SignerVerifierKeypair.SignData → Key.SignMessage is called, k.signer is nil, causing the panic.
This does not affect file-based or KMS keys because their Close() is a no-op or doesn't nil out the signer. It specifically affects PKCS#11 and likely PIV keys.
Suggested Fix
Remove the defer sv.Close() from GetKeypairAndToken and instead have the caller (WriteNewBundleWithSigningConfig) manage the lifecycle, similar to how GetBundleComponents returns a closeSV function that the caller defers.
Alternatively, NewSignerVerifierKeypair could snapshot the crypto.Signer and crypto.PublicKey at construction time rather than delegating to the underlying key, but that would require the PKCS#11 module to support detached signing which may not always be true.
Affects
cosign sign --signing-config --key pkcs11:...
cosign attest --signing-config --key pkcs11:...
Likely also cosign sign-blob --signing-config --key pkcs11:...
Likely affects PIV keys (--sk) in the same code path
Description
cosign signwith--signing-configand--key pkcs11:...panics with a nil pointer dereference when attempting to sign. The PKCS#11 session is closed before the signing operation occurs.Version
-tags pkcs11key)Steps to Reproduce
{ "mediaType": "application/vnd.dev.sigstore.signingconfig.v0.2+json", "rekorTlogUrls": [ { "url": "https://rekor.example.com", "majorApiVersion": 2, "validFor": { "start": "2025-01-01T00:00:00Z" } } ], "caUrls": [], "oidcUrls": [], "tsaUrls": [], "rekorTlogConfig": { "selector": "ANY" }, "tsaConfig": { "selector": "ANY" } }cosign sign \ --key "pkcs11:token=mytoken;object=mykey?pin-value=1234&module-path=/usr/lib/libpkcs11.so" \ --cert cert.pem --cert-chain chain.pem \ --signing-config signing-config.json \ --bundle output.bundle --yes \ registry.example.com/image@sha256:abc123Expected Behavior
Image is signed and a bundle is written.
Actual Behavior
Panic with nil pointer dereference:
Root Cause
In
cmd/cosign/cli/signcommon/common.go,GetKeypairAndTokencreates asign.Keypairfrom the PKCS#11-backedSignerVerifier, then deferssv.Close():NewSignerVerifierKeypairwraps theSignerVerifier(which holds a reference to the PKCS#11Key). Thedefer sv.Close()fires on return, which callsKey.Close():The returned
keypairstill references the sameKeystruct. WhenWriteNewBundleWithSigningConfig→bundle.SignData→SignerVerifierKeypair.SignData→Key.SignMessageis called,k.signeris nil, causing the panic.This does not affect file-based or KMS keys because their
Close()is a no-op or doesn't nil out the signer. It specifically affects PKCS#11 and likely PIV keys.Suggested Fix
Remove the
defer sv.Close()fromGetKeypairAndTokenand instead have the caller (WriteNewBundleWithSigningConfig) manage the lifecycle, similar to howGetBundleComponentsreturns acloseSVfunction that the caller defers.Alternatively,
NewSignerVerifierKeypaircould snapshot thecrypto.Signerandcrypto.PublicKeyat construction time rather than delegating to the underlying key, but that would require the PKCS#11 module to support detached signing which may not always be true.Affects
cosign sign --signing-config --key pkcs11:...cosign attest --signing-config --key pkcs11:...cosign sign-blob --signing-config --key pkcs11:...--sk) in the same code path