{"record":{"id":"f32d6bd333aa4d50","repo":"kubernetes/kops","slug":"pkcs7-signer-certificate-not-found","errorCode":null,"errorMessage":"PKCS7 signer certificate not found","messagePattern":"PKCS7 signer certificate not found","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/azure/attest.go","lineNumber":258,"sourceCode":"\t\treturn nil, nil, fmt.Errorf(\"decoding PKCS7 signature: %w\", err)\n\t}\n\tklog.V(4).Infof(\"Decoded PKCS7 signature (%d bytes)\", len(sigBytes))\n\n\tp7, err := pkcs7.Parse(sigBytes)\n\tif err != nil {\n\t\treturn nil, nil, fmt.Errorf(\"parsing PKCS7 signature: %w\", err)\n\t}\n\tklog.V(8).Infof(\"Parsed PKCS7 structure with %d embedded certificate(s)\", len(p7.Certificates))\n\n\t// Verify the PKCS7 signature against the embedded leaf certificate.\n\tif err := p7.Verify(); err != nil {\n\t\treturn nil, nil, fmt.Errorf(\"verifying PKCS7 signature: %w\", err)\n\t}\n\tklog.V(4).Infof(\"PKCS7 self-signature verified\")\n\n\tsigner := p7.GetOnlySigner()\n\tif signer == nil {\n\t\treturn nil, nil, fmt.Errorf(\"PKCS7 signer certificate not found\")\n\t}\n\tklog.V(8).Infof(\"PKCS7 signer certificate: subject=%q issuer=%q SANs=%v\", signer.Subject, signer.Issuer, signer.DNSNames)\n\tif err := validateAzureMetadataSignerSAN(signer); err != nil {\n\t\treturn nil, nil, fmt.Errorf(\"validating PKCS7 signer SAN: %w\", err)\n\t}\n\tklog.V(4).Infof(\"PKCS7 signer SAN validated as Azure metadata endpoint\")\n\n\treturn p7, signer, nil\n}\n\n// nonceForBody derives the IMDS attestation nonce from the request body; the shared\n// azuremetadata implementation keeps the authenticator and verifier sides identical.\nfunc nonceForBody(body []byte) string {\n\treturn azuremetadata.NonceForBody(body)\n}\n\n// parseAndValidateAttestedDocumentContent unmarshals the signed attestation payload and validates\n// its nonce and freshness timestamps.","sourceCodeStart":240,"sourceCodeEnd":276,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/azure/attest.go#L240-L276","documentation":"After a successful signature verification, parseAndValidatePKCS7Signer calls p7.GetOnlySigner() to extract the single signer certificate. If the PKCS#7 message has zero or multiple signer certificates, GetOnlySigner returns nil and this error is raised. A valid Azure attested document has exactly one signer.","triggerScenarios":"p7.GetOnlySigner() returns nil because p7.Certificates is empty or contains more than one certificate while the SignerInfos do not resolve to exactly one signer, immediately after p7.Verify() succeeded.","commonSituations":"Hand-crafted or tool-generated (openssl cms) test blobs with countersignatures or multiple signers; PKCS#7 structures produced by an intermediary/proxy that adds extra certificates; malformed fixtures that pass parse but not the single-signer assumption.","solutions":["Regenerate test fixtures with exactly one signer (openssl cms -sign -signer leaf -inkey key -in data -outform DER)","Inspect len(p7.Certificates) and the SignerInfos count; klog.V(8) logs the embedded certificate count to help diagnose","Ensure no proxy or middleware re-signs or augments the IMDS response; fetch directly from 169.254.169.254","If a legitimate multi-cert structure is expected upstream, adjust the validator to pick the leaf matching the expected SAN instead of requiring GetOnlySigner"],"exampleFix":"// before\nsigner := p7.GetOnlySigner()\nif signer == nil {\n    return nil, nil, fmt.Errorf(\"PKCS7 signer certificate not found\")\n}\n// after\nsigner := p7.GetOnlySigner()\nif signer == nil {\n    klog.V(4).Infof(\"PKCS7 has %d certs, %d signer infos\", len(p7.Certificates), len(p7.GetSignerInfos()))\n    return nil, nil, fmt.Errorf(\"PKCS7 signer certificate not found\")\n}","handlingStrategy":"type-guard","validationCode":"if p7 == nil || len(p7.Certificates) == 0 {\n    return fmt.Errorf(\"PKCS7 message contains no certificates\")\n}","typeGuard":"func hasSingleSigner(p7 *pkcs7.PKCS7) bool {\n    return p7 != nil && p7.GetOnlySigner() != nil\n}","tryCatchPattern":"signer := p7.GetOnlySigner()\nif signer == nil {\n    klog.V(4).Infof(\"PKCS7 certs=%d (expected exactly one resolvable signer)\", len(p7.Certificates))\n    return nil, nil, fmt.Errorf(\"PKCS7 signer certificate not found\")\n}","preventionTips":["Generate test PKCS7 blobs with a single signer via `openssl cms -sign` (one -signer flag)","Never let intermediaries re-sign or augment IMDS responses","Check the embedded certificate count (klog V(8)) when debugging fixtures","Assume exactly one signer is an invariant of Azure attested documents and validate fixtures against it"],"tags":["azure","pkcs7","certificate","attestation"],"backgroundTag":"missing-signer-certificate","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}