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
- Confirm the signature bytes are DER-encoded ASN.1 (SEQUENCE of two INTEGERs), not raw 64-byte r||s form
- Check the wire/frame handling that carried the signature for truncation or corruption
- 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
- Agree on a single signature encoding (DER) across the protocol
- Validate the leading 0x30 SEQUENCE tag on received signatures
- Guard wire handling against truncation of signature fields
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
- invalid integer
- could not calculate alternate fingerprint to verify: %w
- ErrBadFormat
- ErrNotSelfSigned
- ErrSignatureMismatch
AI-assisted analysis of slackhq/nebula@dd8f660c0a (2026-09-03).
Data as JSON: /api/errors/5a932cc46c1539c9.
Report an issue: GitHub.