slackhq/nebula · error

invalid ASN.1

Error message

invalid ASN.1

What it means

parseSignature in cert/p256/p256.go raises 'invalid ASN.1' when a P-256 signature blob cannot be parsed as a DER SEQUENCE containing exactly two integers (r, s). This is a low-level Go error, not a sentinel, produced when the cryptobyte ASN.1 read of the signature structure fails.

Source

Thrown at cert/p256/p256.go:97

	newR, newS, err := swap(r, s)
	if err != nil {
		return nil, err
	}

	return encodeSignature(newR, newS)
}

// parseSignature taken exactly from crypto/ecdsa/ecdsa.go
func parseSignature(sig []byte) (r, s []byte, err error) {
	var inner cryptobyte.String
	input := cryptobyte.String(sig)
	if !input.ReadASN1(&inner, asn1.SEQUENCE) ||
		!input.Empty() ||
		!inner.ReadASN1Integer(&r) ||
		!inner.ReadASN1Integer(&s) ||
		!inner.Empty() {
		return nil, nil, errors.New("invalid ASN.1")
	}
	return r, s, nil
}

func encodeSignature(r, s []byte) ([]byte, error) {
	var b cryptobyte.Builder
	b.AddASN1(asn1.SEQUENCE, func(b *cryptobyte.Builder) {
		addASN1IntBytes(b, r)
		addASN1IntBytes(b, s)
	})
	return b.Bytes()
}

// addASN1IntBytes encodes in ASN.1 a positive integer represented as
// a big-endian byte slice with zero or more leading zeroes.
func addASN1IntBytes(b *cryptobyte.Builder, bytes []byte) {
	for len(bytes) > 0 && bytes[0] == 0 {
		bytes = bytes[1:]

View on GitHub (pinned to dd8f660c0a)

Solutions

  1. Confirm the signature bytes are DER-encoded ASN.1 (SEQUENCE of two INTEGERs), not raw 64-byte r||s form
  2. Check the wire/frame handling that carried the signature for truncation or corruption
  3. Convert raw (r||s) signatures to DER (or use a matching encoder) before calling these functions

Example fix

// before
normalized, err := p256.Normalize(raw64ByteSig) // raw r||s, not DER
// after
derSig := encodeRawToDER(raw64ByteSig) // wrap r and s in ASN.1 SEQUENCE
normalized, err := p256.Normalize(derSig)
Defensive patterns

Strategy: validation

Validate before calling

if len(sig) < 8 || sig[0] != 0x30 {
    return fmt.Errorf("signature is not DER-encoded ASN.1")
}

Type guard

func looksLikeDERSignature(b []byte) bool {
    return len(b) >= 8 && b[0] == 0x30
}

Try / catch

r, s, err := p256.parseSignature(sig) // via Normalize/IsNormalized/Swap
if err != nil && err.Error() == "invalid ASN.1" {
    // try raw r||s -> DER conversion before retrying
}

Prevention

When it happens

Trigger: Calling IsNormalized, Normalize, or Swap with a byte slice that is not a well-formed ASN.1 DER ECDSA signature — wrong length, wrong tag, trailing bytes, or missing/oversized integers.

Common situations: Signatures received over the wire corrupted or truncated; raw (r||s) fixed-width signatures supplied where DER is expected (or vice versa); signatures from a library using a different encoding convention.

Related errors


AI-assisted analysis of slackhq/nebula@dd8f660c0a (2026-09-03). Data as JSON: /api/errors/5a932cc46c1539c9. Report an issue: GitHub.