diff --git a/authority/provisioner/nebula.go b/authority/provisioner/nebula.go index 84887de6..fa9c283f 100644 --- a/authority/provisioner/nebula.go +++ b/authority/provisioner/nebula.go @@ -3,9 +3,12 @@ package provisioner import ( "context" "crypto/ecdh" + "crypto/ecdsa" "crypto/ed25519" + "crypto/elliptic" "crypto/x509" "encoding/base64" + "math/big" "net" "time" @@ -338,13 +341,20 @@ func (p *Nebula) authorizeToken(token string, audiences []string) (*nebula.Nebul return nil, nil, errs.Unauthorized("token is not valid: failed to verify certificate against configured CA") } - var pub interface{} + var pub any switch { case c.Details.Curve == nebula.Curve_P256: // When Nebula is used with ECDSA P-256 keys, both CAs and clients use the same type. - if pub, err = ecdh.P256().NewPublicKey(c.Details.PublicKey); err != nil { + ecdhPub, err := ecdh.P256().NewPublicKey(c.Details.PublicKey) + if err != nil { return nil, nil, errs.UnauthorizedErr(err, errs.WithMessage("failed to parse nebula public key")) } + publicKeyBytes := ecdhPub.Bytes() + pub = &ecdsa.PublicKey{ // convert back to *ecdsa.PublicKey, because our jose package nor go-jose supports *ecdh.PublicKey + Curve: elliptic.P256(), + X: big.NewInt(0).SetBytes(publicKeyBytes[1:33]), + Y: big.NewInt(0).SetBytes(publicKeyBytes[33:]), + } case c.Details.IsCA: pub = ed25519.PublicKey(c.Details.PublicKey) default: @@ -365,6 +375,7 @@ func (p *Nebula) authorizeToken(token string, audiences []string) (*nebula.Nebul }, time.Minute); err != nil { return nil, nil, errs.UnauthorizedErr(err, errs.WithMessage("token is not valid: invalid claims")) } + // Validate token and subject too. if !matchesAudience(claims.Audience, audiences) { return nil, nil, errs.Unauthorized("token is not valid: invalid claims") diff --git a/authority/provisioner/nebula_test.go b/authority/provisioner/nebula_test.go index 631d36db..4288cab7 100644 --- a/authority/provisioner/nebula_test.go +++ b/authority/provisioner/nebula_test.go @@ -3,9 +3,12 @@ package provisioner import ( "context" "crypto" + "crypto/ecdsa" "crypto/ed25519" + "crypto/elliptic" "crypto/rand" "crypto/x509" + "fmt" "net" "net/url" "reflect" @@ -15,11 +18,13 @@ import ( "github.com/google/go-cmp/cmp" "github.com/slackhq/nebula/cert" + "github.com/stretchr/testify/require" + "golang.org/x/crypto/ssh" + "go.step.sm/crypto/jose" "go.step.sm/crypto/randutil" "go.step.sm/crypto/x25519" "go.step.sm/crypto/x509util" - "golang.org/x/crypto/ssh" ) func mustNebulaIPNet(t *testing.T, s string) *net.IPNet { @@ -62,6 +67,34 @@ func mustNebulaCA(t *testing.T) (*cert.NebulaCertificate, ed25519.PrivateKey) { return nc, priv } +func mustNebulaP256CA(t *testing.T) (*cert.NebulaCertificate, *ecdsa.PrivateKey) { + t.Helper() + + key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) + require.NoError(t, err) + priv, err := key.ECDH() + require.NoError(t, err) + + nc := &cert.NebulaCertificate{ + Details: cert.NebulaCertificateDetails{ + Name: "TestCA", + Groups: []string{"test"}, + Ips: []*net.IPNet{ + mustNebulaIPNet(t, "10.1.0.0/16"), + }, + Subnets: []*net.IPNet{}, + NotBefore: time.Now(), + NotAfter: time.Now().Add(10 * time.Minute), + PublicKey: priv.PublicKey().Bytes(), + IsCA: true, + Curve: cert.Curve_P256, + }, + } + err = nc.Sign(cert.Curve_P256, priv.Bytes()) + require.NoError(t, err) + return nc, key +} + func mustNebulaCert(t *testing.T, name string, ipNet *net.IPNet, groups []string, ca *cert.NebulaCertificate, signer ed25519.PrivateKey) (*cert.NebulaCertificate, crypto.Signer) { t.Helper() @@ -104,6 +137,48 @@ func mustNebulaCert(t *testing.T, name string, ipNet *net.IPNet, groups []string return nc, priv } +func mustNebulaP256Cert(t *testing.T, name string, ipNet *net.IPNet, groups []string, ca *cert.NebulaCertificate, signer *ecdsa.PrivateKey) (*cert.NebulaCertificate, crypto.Signer) { + t.Helper() + + key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) + require.NoError(t, err) + priv, err := key.ECDH() + require.NoError(t, err) + + issuer, err := ca.Sha256Sum() + require.NoError(t, err) + + invertedGroups := make(map[string]struct{}, len(groups)) + for _, name := range groups { + invertedGroups[name] = struct{}{} + } + + t1 := time.Now().Truncate(time.Second) + nc := &cert.NebulaCertificate{ + Details: cert.NebulaCertificateDetails{ + Name: name, + Ips: []*net.IPNet{ipNet}, + Subnets: []*net.IPNet{}, + Groups: groups, + NotBefore: t1, + NotAfter: t1.Add(5 * time.Minute), + PublicKey: priv.PublicKey().Bytes(), + IsCA: false, + Issuer: issuer, + InvertedGroups: invertedGroups, + Curve: cert.Curve_P256, + }, + } + + ecdhKey, err := signer.ECDH() + require.NoError(t, err) + + err = nc.Sign(cert.Curve_P256, ecdhKey.Bytes()) + require.NoError(t, err) + + return nc, key +} + func mustNebulaProvisioner(t *testing.T) (*Nebula, *cert.NebulaCertificate, ed25519.PrivateKey) { t.Helper() @@ -131,26 +206,44 @@ func mustNebulaProvisioner(t *testing.T) (*Nebula, *cert.NebulaCertificate, ed25 return p, nc, signer } -func mustNebulaToken(t *testing.T, sub, iss, aud string, iat time.Time, sans []string, nc *cert.NebulaCertificate, key crypto.Signer) string { +func mustNebulaP256Provisioner(t *testing.T) (*Nebula, *cert.NebulaCertificate, *ecdsa.PrivateKey) { + t.Helper() + + nc, signer := mustNebulaP256CA(t) + ncPem, err := nc.MarshalToPEM() + require.NoError(t, err) + bTrue := true + p := &Nebula{ + Type: TypeNebula.String(), + Name: "nebulous", + Roots: ncPem, + Claims: &Claims{ + EnableSSHCA: &bTrue, + }, + } + err = p.Init(Config{ + Claims: globalProvisionerClaims, + Audiences: testAudiences, + }) + require.NoError(t, err) + + return p, nc, signer +} + +func mustNebulaToken(t *testing.T, sub, iss, aud string, iat time.Time, sans []string, nc *cert.NebulaCertificate, key crypto.Signer, algorithm jose.SignatureAlgorithm) string { t.Helper() ncDer, err := nc.Marshal() - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) so := new(jose.SignerOptions) so.WithType("JWT") so.WithHeader(NebulaCertHeader, ncDer) - sig, err := jose.NewSigner(jose.SigningKey{Algorithm: jose.XEdDSA, Key: key}, so) - if err != nil { - t.Fatal(err) - } + sig, err := jose.NewSigner(jose.SigningKey{Algorithm: algorithm, Key: key}, so) + require.NoError(t, err) id, err := randutil.ASCII(64) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) claims := struct { jose.Claims @@ -168,32 +261,25 @@ func mustNebulaToken(t *testing.T, sub, iss, aud string, iat time.Time, sans []s SANS: sans, } tok, err := jose.Signed(sig).Claims(claims).CompactSerialize() - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) + return tok } -func mustNebulaSSHToken(t *testing.T, sub, iss, aud string, iat time.Time, opts *SignSSHOptions, nc *cert.NebulaCertificate, key crypto.Signer) string { +func mustNebulaSSHToken(t *testing.T, sub, iss, aud string, iat time.Time, opts *SignSSHOptions, nc *cert.NebulaCertificate, key crypto.Signer, algorithm jose.SignatureAlgorithm) string { t.Helper() ncDer, err := nc.Marshal() - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) so := new(jose.SignerOptions) so.WithType("JWT") so.WithHeader(NebulaCertHeader, ncDer) - sig, err := jose.NewSigner(jose.SigningKey{Algorithm: jose.XEdDSA, Key: key}, so) - if err != nil { - t.Fatal(err) - } + sig, err := jose.NewSigner(jose.SigningKey{Algorithm: algorithm, Key: key}, so) + require.NoError(t, err) id, err := randutil.ASCII(64) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) claims := struct { jose.Claims @@ -216,9 +302,8 @@ func mustNebulaSSHToken(t *testing.T, sub, iss, aud string, iat time.Time, opts } tok, err := jose.Signed(sig).Claims(claims).CompactSerialize() - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) + return tok } @@ -329,7 +414,7 @@ func TestNebula_GetIDForToken(t *testing.T) { func TestNebula_GetTokenID(t *testing.T) { p, ca, signer := mustNebulaProvisioner(t) c1, priv := mustNebulaCert(t, "test.lan", mustNebulaIPNet(t, "10.1.0.1/16"), []string{"group"}, ca, signer) - t1 := mustNebulaToken(t, "test.lan", p.Name, p.ctl.Audiences.Sign[0], now(), []string{"test.lan", "10.1.0.1"}, c1, priv) + t1 := mustNebulaToken(t, "test.lan", p.Name, p.ctl.Audiences.Sign[0], now(), []string{"test.lan", "10.1.0.1"}, c1, priv, jose.XEdDSA) _, claims, err := parseToken(t1) if err != nil { t.Fatal(err) @@ -443,8 +528,8 @@ func TestNebula_AuthorizeSign(t *testing.T) { ctx := context.TODO() p, ca, signer := mustNebulaProvisioner(t) crt, priv := mustNebulaCert(t, "test.lan", mustNebulaIPNet(t, "10.1.0.1/16"), []string{"test"}, ca, signer) - ok := mustNebulaToken(t, "test.lan", p.Name, p.ctl.Audiences.Sign[0], now(), []string{"test.lan", "10.1.0.1"}, crt, priv) - okNoSANs := mustNebulaToken(t, "test.lan", p.Name, p.ctl.Audiences.Sign[0], now(), nil, crt, priv) + ok := mustNebulaToken(t, "test.lan", p.Name, p.ctl.Audiences.Sign[0], now(), []string{"test.lan", "10.1.0.1"}, crt, priv, jose.XEdDSA) + okNoSANs := mustNebulaToken(t, "test.lan", p.Name, p.ctl.Audiences.Sign[0], now(), nil, crt, priv, jose.XEdDSA) pBadOptions, _, _ := mustNebulaProvisioner(t) pBadOptions.caPool = p.caPool @@ -489,20 +574,20 @@ func TestNebula_AuthorizeSSHSign(t *testing.T) { CertType: "host", KeyID: "test.lan", Principals: []string{"test.lan", "10.1.0.1"}, - }, crt, priv) - okNoOptions := mustNebulaSSHToken(t, "test.lan", p.Name, p.ctl.Audiences.SSHSign[0], now(), nil, crt, priv) + }, crt, priv, jose.XEdDSA) + okNoOptions := mustNebulaSSHToken(t, "test.lan", p.Name, p.ctl.Audiences.SSHSign[0], now(), nil, crt, priv, jose.XEdDSA) okWithValidity := mustNebulaSSHToken(t, "test.lan", p.Name, p.ctl.Audiences.SSHSign[0], now(), &SignSSHOptions{ ValidAfter: NewTimeDuration(now().Add(1 * time.Hour)), ValidBefore: NewTimeDuration(now().Add(10 * time.Hour)), - }, crt, priv) + }, crt, priv, jose.XEdDSA) failUserCert := mustNebulaSSHToken(t, "test.lan", p.Name, p.ctl.Audiences.SSHSign[0], now(), &SignSSHOptions{ CertType: "user", - }, crt, priv) + }, crt, priv, jose.XEdDSA) failPrincipals := mustNebulaSSHToken(t, "test.lan", p.Name, p.ctl.Audiences.SSHSign[0], now(), &SignSSHOptions{ CertType: "host", KeyID: "test.lan", Principals: []string{"test.lan", "10.1.0.1", "foo.bar"}, - }, crt, priv) + }, crt, priv, jose.XEdDSA) // Provisioner with SSH disabled var bFalse bool @@ -594,12 +679,12 @@ func TestNebula_AuthorizeRevoke(t *testing.T) { // Ok provisioner p, ca, signer := mustNebulaProvisioner(t) crt, priv := mustNebulaCert(t, "test.lan", mustNebulaIPNet(t, "10.1.0.1/16"), []string{"test"}, ca, signer) - ok := mustNebulaToken(t, "test.lan", p.Name, p.ctl.Audiences.Revoke[0], now(), nil, crt, priv) + ok := mustNebulaToken(t, "test.lan", p.Name, p.ctl.Audiences.Revoke[0], now(), nil, crt, priv, jose.XEdDSA) // Fail different CA nc, signer := mustNebulaCA(t) crt, priv = mustNebulaCert(t, "test.lan", mustNebulaIPNet(t, "10.1.0.1/16"), []string{"test"}, nc, signer) - failToken := mustNebulaToken(t, "test.lan", p.Name, p.ctl.Audiences.Revoke[0], now(), nil, crt, priv) + failToken := mustNebulaToken(t, "test.lan", p.Name, p.ctl.Audiences.Revoke[0], now(), nil, crt, priv, jose.XEdDSA) type args struct { ctx context.Context @@ -628,12 +713,12 @@ func TestNebula_AuthorizeSSHRevoke(t *testing.T) { // Ok provisioner p, ca, signer := mustNebulaProvisioner(t) crt, priv := mustNebulaCert(t, "test.lan", mustNebulaIPNet(t, "10.1.0.1/16"), []string{"test"}, ca, signer) - ok := mustNebulaSSHToken(t, "test.lan", p.Name, p.ctl.Audiences.SSHRevoke[0], now(), nil, crt, priv) + ok := mustNebulaSSHToken(t, "test.lan", p.Name, p.ctl.Audiences.SSHRevoke[0], now(), nil, crt, priv, jose.XEdDSA) // Fail different CA nc, signer := mustNebulaCA(t) crt, priv = mustNebulaCert(t, "test.lan", mustNebulaIPNet(t, "10.1.0.1/16"), []string{"test"}, nc, signer) - failToken := mustNebulaSSHToken(t, "test.lan", p.Name, p.ctl.Audiences.SSHRevoke[0], now(), nil, crt, priv) + failToken := mustNebulaSSHToken(t, "test.lan", p.Name, p.ctl.Audiences.SSHRevoke[0], now(), nil, crt, priv, jose.XEdDSA) // Provisioner with SSH disabled var bFalse bool @@ -667,7 +752,7 @@ func TestNebula_AuthorizeSSHRevoke(t *testing.T) { func TestNebula_AuthorizeSSHRenew(t *testing.T) { p, ca, signer := mustNebulaProvisioner(t) crt, priv := mustNebulaCert(t, "test.lan", mustNebulaIPNet(t, "10.1.0.1/16"), []string{"test"}, ca, signer) - t1 := mustNebulaSSHToken(t, "test.lan", p.Name, p.ctl.Audiences.SSHRenew[0], now(), nil, crt, priv) + t1 := mustNebulaSSHToken(t, "test.lan", p.Name, p.ctl.Audiences.SSHRenew[0], now(), nil, crt, priv, jose.XEdDSA) type args struct { ctx context.Context @@ -699,7 +784,7 @@ func TestNebula_AuthorizeSSHRenew(t *testing.T) { func TestNebula_AuthorizeSSHRekey(t *testing.T) { p, ca, signer := mustNebulaProvisioner(t) crt, priv := mustNebulaCert(t, "test.lan", mustNebulaIPNet(t, "10.1.0.1/16"), []string{"test"}, ca, signer) - t1 := mustNebulaSSHToken(t, "test.lan", p.Name, p.ctl.Audiences.SSHRekey[0], now(), nil, crt, priv) + t1 := mustNebulaSSHToken(t, "test.lan", p.Name, p.ctl.Audiences.SSHRekey[0], now(), nil, crt, priv, jose.XEdDSA) type args struct { ctx context.Context @@ -736,20 +821,20 @@ func TestNebula_authorizeToken(t *testing.T) { t1 := now() p, ca, signer := mustNebulaProvisioner(t) crt, priv := mustNebulaCert(t, "test.lan", mustNebulaIPNet(t, "10.1.0.1/16"), []string{"test"}, ca, signer) - ok := mustNebulaToken(t, "test.lan", p.Name, p.ctl.Audiences.Sign[0], t1, []string{"10.1.0.1"}, crt, priv) - okNoSANs := mustNebulaToken(t, "test.lan", p.Name, p.ctl.Audiences.Sign[0], t1, nil, crt, priv) + ok := mustNebulaToken(t, "test.lan", p.Name, p.ctl.Audiences.Sign[0], t1, []string{"10.1.0.1"}, crt, priv, jose.XEdDSA) + okNoSANs := mustNebulaToken(t, "test.lan", p.Name, p.ctl.Audiences.Sign[0], t1, nil, crt, priv, jose.XEdDSA) okSSH := mustNebulaSSHToken(t, "test.lan", p.Name, p.ctl.Audiences.SSHSign[0], t1, &SignSSHOptions{ CertType: "host", KeyID: "test.lan", Principals: []string{"test.lan"}, - }, crt, priv) - okSSHNoOptions := mustNebulaSSHToken(t, "test.lan", p.Name, p.ctl.Audiences.SSHSign[0], t1, nil, crt, priv) + }, crt, priv, jose.XEdDSA) + okSSHNoOptions := mustNebulaSSHToken(t, "test.lan", p.Name, p.ctl.Audiences.SSHSign[0], t1, nil, crt, priv, jose.XEdDSA) // Token with errors - failNotBefore := mustNebulaToken(t, "test.lan", p.Name, p.ctl.Audiences.Sign[0], t1.Add(1*time.Hour), []string{"10.1.0.1"}, crt, priv) - failIssuer := mustNebulaToken(t, "test.lan", "foo", p.ctl.Audiences.Sign[0], t1, []string{"10.1.0.1"}, crt, priv) - failAudience := mustNebulaToken(t, "test.lan", p.Name, "foo", t1, []string{"10.1.0.1"}, crt, priv) - failSubject := mustNebulaToken(t, "", p.Name, p.ctl.Audiences.Sign[0], t1, []string{"10.1.0.1"}, crt, priv) + failNotBefore := mustNebulaToken(t, "test.lan", p.Name, p.ctl.Audiences.Sign[0], t1.Add(1*time.Hour), []string{"10.1.0.1"}, crt, priv, jose.XEdDSA) + failIssuer := mustNebulaToken(t, "test.lan", "foo", p.ctl.Audiences.Sign[0], t1, []string{"10.1.0.1"}, crt, priv, jose.XEdDSA) + failAudience := mustNebulaToken(t, "test.lan", p.Name, "foo", t1, []string{"10.1.0.1"}, crt, priv, jose.XEdDSA) + failSubject := mustNebulaToken(t, "", p.Name, p.ctl.Audiences.Sign[0], t1, []string{"10.1.0.1"}, crt, priv, jose.XEdDSA) // Not a nebula token jwk, err := generateJSONWebKey() @@ -846,6 +931,117 @@ func TestNebula_authorizeToken(t *testing.T) { } } +func TestNebula_authorizeToken_P256(t *testing.T) { + t1 := now() + p, ca, signer := mustNebulaP256Provisioner(t) + crt, priv := mustNebulaP256Cert(t, "test.lan", mustNebulaIPNet(t, "10.1.0.1/16"), []string{"test"}, ca, signer) + ok := mustNebulaToken(t, "test.lan", p.Name, p.ctl.Audiences.Sign[0], t1, []string{"10.1.0.1"}, crt, priv, jose.ES256) + okNoSANs := mustNebulaToken(t, "test.lan", p.Name, p.ctl.Audiences.Sign[0], t1, nil, crt, priv, jose.ES256) + okSSH := mustNebulaSSHToken(t, "test.lan", p.Name, p.ctl.Audiences.SSHSign[0], t1, &SignSSHOptions{ + CertType: "host", + KeyID: "test.lan", + Principals: []string{"test.lan"}, + }, crt, priv, jose.ES256) + okSSHNoOptions := mustNebulaSSHToken(t, "test.lan", p.Name, p.ctl.Audiences.SSHSign[0], t1, nil, crt, priv, jose.ES256) + + // Token with errors + failNotBefore := mustNebulaToken(t, "test.lan", p.Name, p.ctl.Audiences.Sign[0], t1.Add(1*time.Hour), []string{"10.1.0.1"}, crt, priv, jose.ES256) + failIssuer := mustNebulaToken(t, "test.lan", "foo", p.ctl.Audiences.Sign[0], t1, []string{"10.1.0.1"}, crt, priv, jose.ES256) + failAudience := mustNebulaToken(t, "test.lan", p.Name, "foo", t1, []string{"10.1.0.1"}, crt, priv, jose.ES256) + failSubject := mustNebulaToken(t, "", p.Name, p.ctl.Audiences.Sign[0], t1, []string{"10.1.0.1"}, crt, priv, jose.ES256) + + // Not a nebula token + jwk, err := generateJSONWebKey() + require.NoError(t, err) + simpleToken, err := generateSimpleToken("iss", "aud", jwk) + require.NoError(t, err) + + // Provisioner with a different CA + p2, _, _ := mustNebulaP256Provisioner(t) + + x509Claims := jose.Claims{ + ID: "[REPLACEME]", + Subject: "test.lan", + Issuer: p.Name, + IssuedAt: jose.NewNumericDate(t1), + NotBefore: jose.NewNumericDate(t1), + Expiry: jose.NewNumericDate(t1.Add(5 * time.Minute)), + Audience: []string{p.ctl.Audiences.Sign[0]}, + } + sshClaims := jose.Claims{ + ID: "[REPLACEME]", + Subject: "test.lan", + Issuer: p.Name, + IssuedAt: jose.NewNumericDate(t1), + NotBefore: jose.NewNumericDate(t1), + Expiry: jose.NewNumericDate(t1.Add(5 * time.Minute)), + Audience: []string{p.ctl.Audiences.SSHSign[0]}, + } + + type args struct { + token string + audiences []string + } + tests := []struct { + name string + p *Nebula + args args + want *cert.NebulaCertificate + want1 *jwtPayload + wantErr bool + }{ + {"ok x509", p, args{ok, p.ctl.Audiences.Sign}, crt, &jwtPayload{ + Claims: x509Claims, + SANs: []string{"10.1.0.1"}, + }, false}, + {"ok x509 no sans", p, args{okNoSANs, p.ctl.Audiences.Sign}, crt, &jwtPayload{ + Claims: x509Claims, + }, false}, + {"ok ssh", p, args{okSSH, p.ctl.Audiences.SSHSign}, crt, &jwtPayload{ + Claims: sshClaims, + Step: &stepPayload{ + SSH: &SignSSHOptions{ + CertType: "host", + KeyID: "test.lan", + Principals: []string{"test.lan"}, + }, + }, + }, false}, + {"ok ssh no principals", p, args{okSSHNoOptions, p.ctl.Audiences.SSHSign}, crt, &jwtPayload{ + Claims: sshClaims, + }, false}, + {"fail parse", p, args{"bad.token", p.ctl.Audiences.Sign}, nil, nil, true}, + {"fail header", p, args{simpleToken, p.ctl.Audiences.Sign}, nil, nil, true}, + {"fail verify", p2, args{ok, p.ctl.Audiences.Sign}, nil, nil, true}, + {"fail claims nbf", p, args{failNotBefore, p.ctl.Audiences.Sign}, nil, nil, true}, + {"fail claims iss", p, args{failIssuer, p.ctl.Audiences.Sign}, nil, nil, true}, + {"fail claims aud", p, args{failAudience, p.ctl.Audiences.Sign}, nil, nil, true}, + {"fail claims sub", p, args{failSubject, p.ctl.Audiences.Sign}, nil, nil, true}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, got1, err := tt.p.authorizeToken(tt.args.token, tt.args.audiences) + if (err != nil) != tt.wantErr { + fmt.Println(err) + t.Errorf("Nebula.authorizeToken() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("Nebula.authorizeToken() got = %#v, want %#v", got, tt.want) + t.Error(cmp.Equal(got, tt.want)) + } + + if got1 != nil && tt.want1 != nil { + tt.want1.ID = got1.ID + } + + if !reflect.DeepEqual(got1, tt.want1) { + t.Errorf("Nebula.authorizeToken() got1 = %v, want %v", got1, tt.want1) + } + }) + } +} + func Test_nebulaSANsValidator_Valid(t *testing.T) { ipNet := mustNebulaIPNet(t, "10.1.2.3/16") type fields struct {