{"record":{"id":"a5339faf2c112985","repo":"hyperledger/fabric","slug":"failed-marshaling-ecdsa-signature","errorCode":null,"errorMessage":"failed marshaling ECDSA signature","messagePattern":"failed marshaling ECDSA signature","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"common/crypto/sanitize.go","lineNumber":75,"sourceCode":"\t// We assume that the consenter and the CA use the same signature scheme.\n\tcurveOrderUsedByCryptoGen := cert.PublicKey.(*ecdsa.PublicKey).Curve.Params().N\n\thalfOrder := new(big.Int).Rsh(curveOrderUsedByCryptoGen, 1)\n\t// Low S, nothing to do here!\n\tif s.Cmp(halfOrder) != 1 {\n\t\treturn initialPEM, nil\n\t}\n\t// Else it's high-S, so shift it below half the order.\n\ts.Sub(curveOrderUsedByCryptoGen, s)\n\n\tvar newCert certificate\n\t_, err = asn1.Unmarshal(cert.Raw, &newCert)\n\tif err != nil {\n\t\treturn nil, errors.Wrapf(err, \"failed unmarshaling certificate\")\n\t}\n\n\tnewSig, err := utils.MarshalECDSASignature(r, s)\n\tif err != nil {\n\t\treturn nil, errors.Wrapf(err, \"failed marshaling ECDSA signature\")\n\t}\n\tnewCert.SignatureValue = asn1.BitString{Bytes: newSig, BitLength: len(newSig) * 8}\n\n\tnewCert.Raw = nil\n\tnewRaw, err := asn1.Marshal(newCert)\n\tif err != nil {\n\t\treturn nil, errors.Wrapf(err, \"failed marshaling new certificate\")\n\t}\n\n\tfinalPEM := pem.EncodeToMemory(&pem.Block{Type: \"CERTIFICATE\", Bytes: newRaw})\n\treturn finalPEM, nil\n}\n\ntype certificate struct {\n\tRaw                asn1.RawContent\n\tTBSCertificate     tbsCertificate\n\tSignatureAlgorithm pkix.AlgorithmIdentifier\n\tSignatureValue     asn1.BitString","sourceCodeStart":57,"sourceCodeEnd":93,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/common/crypto/sanitize.go#L57-L93","documentation":"SanitizeX509Cert re-signs/re-encodes an X.509 certificate and rebuilds the ECDSA signature via utils.MarshalECDSASignature. If converting the r/s big integers back to an ASN.1 DER-encoded ECDSA-Sig-Value fails, this wrapped error is returned. It indicates the signature components produced from the original certificate could not be marshaled.","triggerScenarios":"Calling SanitizeX509Cert (directly or via SanitizeIdentity, ConfigureNodeCerts, IsChannelMember) on a certificate whose extracted signature r/s values fail ASN.1 marshaling in utils.MarshalECDSASignature.","commonSituations":"Parsing a non-standard or corrupted certificate whose signature fields are malformed; negative or zero signature components; corrupted PEM input.","solutions":["Verify the input certificate is a valid, well-formed x509 certificate (run openssl x509 -in cert.pem -text -noout)","Check utils.MarshalECDSASignature for constraints on r/s (e.g., disallowing zero values) and ensure the cert's signature passes them","Regenerate the certificate/key pair; the source cert may be corrupted"],"exampleFix":"// before\npemBytes, err := crypto.SanitizeX509Cert(corruptedCertPEM)\n// after\nif _, err := x509.ParseCertificate(pemBlock.Bytes); err != nil {\n    return fmt.Errorf(\"invalid cert input: %w\", err) // validate before sanitizing\n}\npemBytes, err := crypto.SanitizeX509Cert(validCertPEM)","handlingStrategy":"validation","validationCode":"block, _ := pem.Decode(certPEM)\nif block == nil {\n    return errors.New(\"input is not valid PEM\")\n}\nif _, err := x509.ParseCertificate(block.Bytes); err != nil {\n    return fmt.Errorf(\"invalid certificate: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"pem, err := crypto.SanitizeX509Cert(certPEM)\nif err != nil {\n    if strings.Contains(err.Error(), \"failed marshaling ECDSA signature\") {\n        return fmt.Errorf(\"certificate signature components are malformed: %w\", err)\n    }\n    return err\n}","preventionTips":["Only sanitize certificates that parse cleanly with x509.ParseCertificate first","Keep fabric/utils and crypto libraries at matching versions","Reject corrupted or hand-edited PEM files early in the pipeline"],"tags":["crypto","ecdsa","certificate","asn1"],"backgroundTag":"ecdsa-signature-marshal-failed","analyzedSha":"2736b63f8fd5932511d56fe68b7039d15977f7f6","analyzedAt":"2026-09-04T08:52:36.465Z","contentChangedAt":"2026-09-04T08:52:36.465Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}