{"record":{"id":"ac59f5f6de9bcaa2","repo":"slackhq/nebula","slug":"invalid-curve-s-ac59f5","errorCode":null,"errorMessage":"invalid curve: %s","messagePattern":"invalid curve: (.+?)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cert/sign.go","lineNumber":71,"sourceCode":"\t\tsp := func(certBytes []byte) ([]byte, error) {\n\t\t\tsig := ed25519.Sign(pk, certBytes)\n\t\t\treturn sig, nil\n\t\t}\n\t\treturn t.SignWith(signer, curve, sp)\n\tcase Curve_P256:\n\t\tpk, err := ecdsa.ParseRawPrivateKey(elliptic.P256(), key)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tsp := func(certBytes []byte) ([]byte, error) {\n\t\t\t// We need to hash first for ECDSA\n\t\t\t// - https://pkg.go.dev/crypto/ecdsa#SignASN1\n\t\t\thashed := sha256.Sum256(certBytes)\n\t\t\treturn ecdsa.SignASN1(rand.Reader, pk, hashed[:])\n\t\t}\n\t\treturn t.SignWith(signer, curve, sp)\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"invalid curve: %s\", t.Curve)\n\t}\n}\n\n// SignWith does the same thing as sign, but uses the function in `sp` to calculate the signature.\n// You should only use SignWith if you do not have direct access to your private key.\nfunc (t *TBSCertificate) SignWith(signer Certificate, curve Curve, sp SignerLambda) (Certificate, error) {\n\tif curve != t.Curve {\n\t\treturn nil, fmt.Errorf(\"curve in cert and private key supplied don't match\")\n\t}\n\n\tif signer != nil {\n\t\tif t.IsCA {\n\t\t\treturn nil, fmt.Errorf(\"can not sign a CA certificate with another\")\n\t\t}\n\n\t\terr := checkCAConstraints(signer, t.NotBefore, t.NotAfter, t.Groups, t.Networks, t.UnsafeNetworks)\n\t\tif err != nil {\n\t\t\treturn nil, err","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/slackhq/nebula/blob/dd8f660c0ac37903ec4080ca4d3c861ba9342ceb/cert/sign.go#L53-L89","documentation":"TBSCertificate.Sign (and therefore certificate/CA creation) received a Curve value that is neither Curve_CURVE25519 nor Curve_P256, so no signing algorithm can be selected. This happens when a TBSCertificate is built with a zero-value or out-of-range Curve (e.g. constructing the struct manually or decoding a cert with an unknown curve byte).","triggerScenarios":"Call Sign on a TBSCertificate whose t.Curve is 0 (unset) or any value other than Curve_CURVE25519/Curve_P256 — e.g. building TBSCertificate{} by hand without setting Curve, or NewTestCert-style helpers passing an invalid curve.","commonSituations":"Hand-rolled certificate generation code forgetting the Curve field, custom tooling writing an unsupported curve constant into cert details, or a corrupted/deserialized TBS block with an unknown curve byte.","solutions":["Set t.Curve to nebula.Curve_CURVE25519 or nebula.Curve_P256 before calling Sign","If constructing TBSCertificate manually, initialize Curve alongside Name/PublicIp/etc.","If curve comes from decoded input, validate it against the two supported constants before signing"],"exampleFix":"// before\ntbs := &nebula.TBSCertificate{Name: \"host\"}\ncert, err := tbs.Sign(key, sp) // Curve unset => invalid curve: 0\n// after\ntbs := &nebula.TBSCertificate{Name: \"host\", Curve: nebula.Curve_CURVE25519}\ncert, err := tbs.Sign(key, sp)","handlingStrategy":"validation","validationCode":"if tbs.Curve != nebula.Curve_CURVE25519 && tbs.Curve != nebula.Curve_P256 {\n    return fmt.Errorf(\"TBSCertificate.Curve must be set to Curve_CURVE25519 or Curve_P256 before Sign (got %d)\", tbs.Curve)\n}","typeGuard":"func hasSupportedCurve(c nebula.Curve) bool {\n    return c == nebula.Curve_CURVE25519 || c == nebula.Curve_P256\n}","tryCatchPattern":"cert, err := tbs.Sign(key, sp)\nif err != nil {\n    return nil, fmt.Errorf(\"failed to sign certificate: %w (is TBS Curve field set?)\", err)\n}","preventionTips":["Never construct TBSCertificate with struct literal only — always set Curve","Use library constructors (NewCaCert/NewCert) instead of manual assembly","Reject unknown curve bytes when deserializing external cert data"],"tags":["certificate","curve","signing","misconfiguration"],"backgroundTag":"unsupported-curve","analyzedSha":"dd8f660c0ac37903ec4080ca4d3c861ba9342ceb","analyzedAt":"2026-09-03T11:13:55.444Z","contentChangedAt":"2026-09-03T11:13:55.444Z","schemaVersion":2},"datasetVersion":"2026-09-10T17:17:09.494Z"}