hyperledger/fabric · error

failed marshaling ECDSA signature

Error message

failed marshaling ECDSA signature

What it means

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.

Source

Thrown at common/crypto/sanitize.go:75

	// We assume that the consenter and the CA use the same signature scheme.
	curveOrderUsedByCryptoGen := cert.PublicKey.(*ecdsa.PublicKey).Curve.Params().N
	halfOrder := new(big.Int).Rsh(curveOrderUsedByCryptoGen, 1)
	// Low S, nothing to do here!
	if s.Cmp(halfOrder) != 1 {
		return initialPEM, nil
	}
	// Else it's high-S, so shift it below half the order.
	s.Sub(curveOrderUsedByCryptoGen, s)

	var newCert certificate
	_, err = asn1.Unmarshal(cert.Raw, &newCert)
	if err != nil {
		return nil, errors.Wrapf(err, "failed unmarshaling certificate")
	}

	newSig, err := utils.MarshalECDSASignature(r, s)
	if err != nil {
		return nil, errors.Wrapf(err, "failed marshaling ECDSA signature")
	}
	newCert.SignatureValue = asn1.BitString{Bytes: newSig, BitLength: len(newSig) * 8}

	newCert.Raw = nil
	newRaw, err := asn1.Marshal(newCert)
	if err != nil {
		return nil, errors.Wrapf(err, "failed marshaling new certificate")
	}

	finalPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: newRaw})
	return finalPEM, nil
}

type certificate struct {
	Raw                asn1.RawContent
	TBSCertificate     tbsCertificate
	SignatureAlgorithm pkix.AlgorithmIdentifier
	SignatureValue     asn1.BitString

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Verify the input certificate is a valid, well-formed x509 certificate (run openssl x509 -in cert.pem -text -noout)
  2. Check utils.MarshalECDSASignature for constraints on r/s (e.g., disallowing zero values) and ensure the cert's signature passes them
  3. Regenerate the certificate/key pair; the source cert may be corrupted

Example fix

// before
pemBytes, err := crypto.SanitizeX509Cert(corruptedCertPEM)
// after
if _, err := x509.ParseCertificate(pemBlock.Bytes); err != nil {
    return fmt.Errorf("invalid cert input: %w", err) // validate before sanitizing
}
pemBytes, err := crypto.SanitizeX509Cert(validCertPEM)
Defensive patterns

Strategy: validation

Validate before calling

block, _ := pem.Decode(certPEM)
if block == nil {
    return errors.New("input is not valid PEM")
}
if _, err := x509.ParseCertificate(block.Bytes); err != nil {
    return fmt.Errorf("invalid certificate: %w", err)
}

Try / catch

pem, err := crypto.SanitizeX509Cert(certPEM)
if err != nil {
    if strings.Contains(err.Error(), "failed marshaling ECDSA signature") {
        return fmt.Errorf("certificate signature components are malformed: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling SanitizeX509Cert (directly or via SanitizeIdentity, ConfigureNodeCerts, IsChannelMember) on a certificate whose extracted signature r/s values fail ASN.1 marshaling in utils.MarshalECDSASignature.

Common situations: Parsing a non-standard or corrupted certificate whose signature fields are malformed; negative or zero signature components; corrupted PEM input.

Related errors


AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04). Data as JSON: /api/errors/a5339faf2c112985. Report an issue: GitHub.