{"record":{"id":"63b40f31b8d99cc9","repo":"hashicorp/packer","slug":"summarize-fulcio-certificate-w","errorCode":null,"errorMessage":"summarize Fulcio certificate: %w","messagePattern":"summarize Fulcio certificate: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/attestation/sign_keyless.go","lineNumber":68,"sourceCode":"}\n\nvar verifyKeylessCertificate = func(certificate *x509.Certificate, trustedMaterial sigstoreroot.TrustedMaterial, expectedIdentity, expectedOIDCIssuer, trustedRootPath string) error {\n\tchains, err := sigstoreverify.VerifyLeafCertificate(time.Now().UTC(), certificate, trustedMaterial)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"verify Fulcio certificate chain: %w\", err)\n\t}\n\n\t// When using the public Sigstore root (no custom trusted root configured),\n\t// require a valid SCT so certificates issued outside a public CT log are rejected.\n\tif strings.TrimSpace(trustedRootPath) == \"\" {\n\t\tif err := sigstoreverify.VerifySignedCertificateTimestamp(chains, 1, trustedMaterial); err != nil {\n\t\t\treturn fmt.Errorf(\"verify Fulcio certificate SCT: %w\", err)\n\t\t}\n\t}\n\n\tsummary, err := fulciocertificate.SummarizeCertificate(certificate)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"summarize Fulcio certificate: %w\", err)\n\t}\n\n\tidentity, err := sigstoreverify.NewShortCertificateIdentity(expectedOIDCIssuer, \"\", expectedIdentity, \"\")\n\tif err != nil {\n\t\treturn fmt.Errorf(\"build keyless identity policy: %w\", err)\n\t}\n\tif err := identity.Verify(summary); err != nil {\n\t\treturn fmt.Errorf(\"verify keyless certificate identity: %w\", err)\n\t}\n\n\treturn nil\n}\n\nfunc init() {\n\tRegisterSigner(SigningModeKeyless, newKeylessSigner)\n}\n\ntype keylessSigner struct {","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/hashicorp/packer/blob/eb36e3c3e48a036f3e8cc94087636ee72e1303c9/internal/attestation/sign_keyless.go#L50-L86","documentation":"After chain and SCT checks pass, verifyKeylessCertificate calls fulciocertificate.SummarizeCertificate to extract the OIDC issuer and identity/san extensions from the Fulcio certificate. This error means the certificate is not a well-formed Fulcio certificate: the required extension fields that record the OIDC issuer or subject identity could not be parsed or are absent.","triggerScenarios":"keylessVerifier.Verify invokes SummarizeCertificate(certificate) and it returns an error because the certificate lacks Fulcio's OIDC issuer extension (1.3.6.1.4.1.57264.1.1) or malformed identity extensions, so the issuer/identity summary cannot be built.","commonSituations":"The envelope's certificate was replaced or hand-crafted rather than issued by Fulcio; verifying an artifact signed by a non-Fulcio CA whose cert happens to chain to the trusted root; an old or unusual Fulcio issuance configuration that omits the OIDC-issuer extension; certificate corruption in transit.","solutions":["Verify the attestation was signed with a genuine Fulcio-issued certificate (inspect extensions: 'openssl x509 -in cert.pem -noout -ext 1.3.6.1.4.1.57264.1.1').","Re-sign the artifact with keyless mode so a fresh, correctly-issued Fulcio certificate is produced.","Confirm the certificate in the envelope was not swapped or re-encoded; re-obtain the original attestation bundle.","If your Fulcio instance is custom, ensure it is configured to include the OIDC issuer and SAN identity extensions per the Fulcio profile sigstore-go expects.","Read the wrapped inner error from SummarizeCertificate to see which extension was missing or unparsable."],"exampleFix":"// before: attacker-supplied / non-Fulcio cert in envelope -> no OIDC issuer extension\n// after: re-produce the attestation with signing_mode = \"keyless\" via public Fulcio,\n// so cert carries the Fulcio OIDC-issuer and identity extensions","handlingStrategy":"type-guard","validationCode":"// pre-parse the envelope certificate and require Fulcio OIDC-issuer extension before Verify\nfunc hasFulcioOIDCIssuerExt(certPEM string) error {\n\tblock, _ := pem.Decode([]byte(certPEM))\n\tif block == nil {\n\t\treturn fmt.Errorf(\"no certificate PEM\")\n\t}\n\tcert, err := x509.ParseCertificate(block.Bytes)\n\tif err != nil {\n\t\treturn err\n\t}\n\toidOIDCIssuer := asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 57264, 1, 1}\n\tfor _, ext := range cert.Extensions {\n\t\tif ext.Id.Equal(oidOIDCIssuer) {\n\t\t\treturn nil\n\t\t}\n\t}\n\treturn fmt.Errorf(\"certificate %s lacks Fulcio OIDC-issuer extension; not Fulcio-issued\", cert.Subject)\n}","typeGuard":"func isFulcioIssued(cert *x509.Certificate) bool {\n\t_, err := fulciocertificate.SummarizeCertificate(cert)\n\treturn err == nil\n}","tryCatchPattern":"err := keylessVerifier.Verify(ctx, payloadType, payload, sig)\nif err != nil {\n\tif strings.Contains(err.Error(), \"summarize Fulcio certificate\") {\n\t\treturn fmt.Errorf(\"signing certificate is not a well-formed Fulcio certificate (missing OIDC issuer/identity extensions); obtain the attestation from a trusted signer: %w\", err)\n\t}\n\treturn err\n}","preventionTips":["Only accept keyless attestations from your signing pipeline; a non-Fulcio cert that chains to the root will fail here.","Check certificates for Fulcio identity extensions (1.3.6.1.4.1.57264.1.x) when ingesting envelopes.","Do not re-encode or truncate the Cert field of envelope signatures in transit or storage.","If running a custom Fulcio, verify its issuance profile includes the OIDC-issuer and SAN extensions sigstore-go expects."],"tags":["sigstore","fulcio","x509","keyless"],"backgroundTag":"invalid-fulcio-certificate","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"}