kubernetes/kops · error
decoding PKCS7 signature: %w
Error message
decoding PKCS7 signature: %w
What it means
parseAndValidatePKCS7Signer wraps the base64 decoding failure of the PKCS7 signature bytes taken from an Azure attested document. The signature field must be a valid base64-encoded DER PKCS#7/CMS blob; when Go's encoding/base64 rejects it (invalid characters, wrong length, empty-adjacent garbage) this error is returned. It means the attested document's signature was not transport-decoded correctly, so parsing was never attempted.
Source
Thrown at upup/pkg/fi/cloudup/azure/attest.go:240
return nil, fmt.Errorf("verifying PKCS7 certificate chain: %w", err)
}
klog.V(4).Infof("PKCS7 certificate chain verified after resolving intermediate certificates for signer issuer %q", signer.Issuer)
return data, nil
}
// parseAndValidatePKCS7Signer decodes and parses a base64-encoded PKCS7 signature, verifies its
// self-signature, and validates that the signer certificate's SAN identifies an Azure metadata
// endpoint. All checks here are CPU-only; no network I/O is performed, so this is safe to call
// before triggering intermediate certificate fetches.
func parseAndValidatePKCS7Signer(signature string) (*pkcs7.PKCS7, *x509.Certificate, error) {
if signature == "" {
return nil, nil, fmt.Errorf("empty PKCS7 signature")
}
sigBytes, err := base64.StdEncoding.DecodeString(signature)
if err != nil {
return nil, nil, fmt.Errorf("decoding PKCS7 signature: %w", err)
}
klog.V(4).Infof("Decoded PKCS7 signature (%d bytes)", len(sigBytes))
p7, err := pkcs7.Parse(sigBytes)
if err != nil {
return nil, nil, fmt.Errorf("parsing PKCS7 signature: %w", err)
}
klog.V(8).Infof("Parsed PKCS7 structure with %d embedded certificate(s)", len(p7.Certificates))
// Verify the PKCS7 signature against the embedded leaf certificate.
if err := p7.Verify(); err != nil {
return nil, nil, fmt.Errorf("verifying PKCS7 signature: %w", err)
}
klog.V(4).Infof("PKCS7 self-signature verified")
signer := p7.GetOnlySigner()
if signer == nil {
return nil, nil, fmt.Errorf("PKCS7 signer certificate not found")View on GitHub (pinned to 4c8573c808)
Solutions
- Log the raw signature string (klog.V(4) already logs decoded length on success; on failure log the first/last chars) and confirm it is standard base64 (RFC 4648, not base64url)
- Trim surrounding whitespace/newlines from the signature before decoding, or normalize with strings.Map removing CR/LF/spaces
- If using a custom attested-document fetcher, ensure it returns the IMDS JSON unmodified and that the 'signature' field is extracted as-is
- Check for middleware/proxies or tests injecting invalid placeholder signatures; use a real base64-encoded PKCS7 blob in fixtures
Example fix
// before sig := rawSignature // may contain newlines from transport p7, err := parseAndValidatePKCS7Signer(sig, ...) // after sig := strings.TrimSpace(rawSignature) sig = strings.ReplaceAll(sig, "\n", "") sig = strings.ReplaceAll(sig, "\r", "") p7, err := parseAndValidatePKCS7Signer(sig, ...)
Defensive patterns
Strategy: validation
Validate before calling
sig := strings.TrimSpace(attestedDoc.Signature)
if sig == "" || strings.ContainsAny(sig, " \n\r\t") {
return fmt.Errorf("signature is not contiguous standard base64")
}
if _, err := base64.StdEncoding.DecodeString(sig); err != nil {
return fmt.Errorf("signature not valid standard base64: %w", err)
} Type guard
func isStandardBase64(s string) bool {
if s == "" {
return false
}
_, err := base64.StdEncoding.DecodeString(s)
return err == nil
} Try / catch
sigBytes, err := base64.StdEncoding.DecodeString(signature)
if err != nil {
klog.V(4).Infof("base64 decode failed for signature (len=%d): %v", len(signature), err)
return nil, nil, fmt.Errorf("decoding PKCS7 signature: %w", err)
} Prevention
- Normalize whitespace/newlines out of the signature field before decoding
- Use base64.StdEncoding, never URLEncoding, when handling IMDS signatures
- In test fixtures, generate signatures with base64.StdEncoding.EncodeToString(realDER)
- Log the decoded length at V(4) to quickly spot truncation
When it happens
Trigger: verifyAttestedDocumentWithRootAndFetcher calls parseAndValidatePKCS7Signer with the 'signature' field extracted from the IMDS attested document JSON; base64.StdEncoding.DecodeString fails because the field is empty of valid base64, contains whitespace/newlines, uses base64url alphabet characters (-, _), or is truncated.
Common situations: Mock/test IMDS servers returning signature fields that are plain text or URL-safe base64 instead of standard base64; a proxy or middleware mangling the JSON response; manually copying an attested document and corrupting the signature string; Azure changing response encoding expectations in a custom fetcher.
Related errors
- parsing PKCS7 signature: %w
- verifying PKCS7 signature: %w
- PKCS7 signer certificate not found
- validating PKCS7 signer SAN: %w
- attested document expired at %s
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/856bc22d693a147d.
Report an issue: GitHub.