Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions svid/jwtsvid/svid.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,10 @@ func (svid *SVID) Marshal() string {
}

func parse(token string, audience []string, getClaims tokenValidator) (*SVID, error) {
if len(audience) == 0 {
return nil, wrapJwtsvidErr(errors.New("audience must be non-empty"))
}

// Parse serialized token
tok, err := jwt.ParseSigned(token, allowedSignatureAlgorithms)
if err != nil {
Expand All @@ -122,6 +126,8 @@ func parse(token string, audience []string, getClaims tokenValidator) (*SVID, er
return nil, wrapJwtsvidErr(errors.New("token missing subject claim"))
case claims.Expiry == nil:
return nil, wrapJwtsvidErr(errors.New("token missing exp claim"))
case len(claims.Audience) == 0:
return nil, wrapJwtsvidErr(errors.New("token missing aud claim"))
}

spiffeID, err := spiffeid.FromString(claims.Subject)
Expand Down
125 changes: 108 additions & 17 deletions svid/jwtsvid/svid_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,9 @@ func TestParseAndValidate(t *testing.T) {
svid *jwtsvid.SVID
}{
{
name: "success",
bundle: bundle1,
name: "success",
bundle: bundle1,
audience: []string{"audience"},
generateToken: func(tb testing.TB) string {
claims := jwt.Claims{
Subject: spiffeid.RequireFromPath(trustDomain1, "/host").String(),
Expand All @@ -84,24 +85,76 @@ func TestParseAndValidate(t *testing.T) {
},
},
{
name: "malformed",
name: "nil audience argument",
bundle: bundle1,
generateToken: func(tb testing.TB) string {
claims := jwt.Claims{
Subject: spiffeid.RequireFromPath(trustDomain1, "/host").String(),
Issuer: "issuer",
Expiry: expires,
Audience: []string{"audience"},
IssuedAt: issuedAt,
}

return generateToken(tb, claims, key1, "authority1", "")
},
err: "jwtsvid: audience must be non-empty",
},
{
name: "empty audience argument",
bundle: bundle1,
audience: []string{},
generateToken: func(tb testing.TB) string {
claims := jwt.Claims{
Subject: spiffeid.RequireFromPath(trustDomain1, "/host").String(),
Issuer: "issuer",
Expiry: expires,
Audience: []string{"audience"},
IssuedAt: issuedAt,
}

return generateToken(tb, claims, key1, "authority1", "")
},
err: "jwtsvid: audience must be non-empty",
},
{
name: "token missing aud claim",
bundle: bundle1,
audience: []string{"audience"},
generateToken: func(tb testing.TB) string {
claims := jwt.Claims{
Subject: spiffeid.RequireFromPath(trustDomain1, "/host").String(),
Issuer: "issuer",
Expiry: expires,
IssuedAt: issuedAt,
}

return generateToken(tb, claims, key1, "authority1", "")
},
err: "jwtsvid: token missing aud claim",
},
{
name: "malformed",
bundle: bundle1,
audience: []string{"audience"},
generateToken: func(tb testing.TB) string {
return "invalid token"
},
err: "jwtsvid: unable to parse JWT token",
},
{
name: "unsupported algorithm",
bundle: bundle1,
name: "unsupported algorithm",
bundle: bundle1,
audience: []string{"audience"},
generateToken: func(tb testing.TB) string {
return hs256Token
},
err: "jwtsvid: unable to parse JWT token",
},
{
name: "missing subject",
bundle: bundle1,
name: "missing subject",
bundle: bundle1,
audience: []string{"audience"},
generateToken: func(tb testing.TB) string {
claims := jwt.Claims{
Issuer: "issuer",
Expand All @@ -115,8 +168,9 @@ func TestParseAndValidate(t *testing.T) {
err: "jwtsvid: token missing subject claim",
},
{
name: "missing expiration claim",
bundle: bundle1,
name: "missing expiration claim",
bundle: bundle1,
audience: []string{"audience"},
generateToken: func(tb testing.TB) string {
claims := jwt.Claims{
Subject: spiffeid.RequireFromPath(trustDomain1, "/host").String(),
Expand Down Expand Up @@ -249,8 +303,9 @@ func TestParseAndValidate(t *testing.T) {
err: "jwtsvid: unable to get claims from token: go-jose/go-jose: error in cryptographic primitive",
},
{
name: "invalid typ",
bundle: bundle1,
name: "invalid typ",
bundle: bundle1,
audience: []string{"audience"},
generateToken: func(tb testing.TB) string {
claims := jwt.Claims{
Subject: spiffeid.RequireFromPath(trustDomain1, "/host").String(),
Expand Down Expand Up @@ -309,7 +364,8 @@ func TestParseInsecure(t *testing.T) {
svid *jwtsvid.SVID
}{
{
name: "success",
name: "success",
audience: []string{"audience"},
generateToken: func(tb testing.TB) string {
claims := jwt.Claims{
Subject: spiffeid.RequireFromPath(trustDomain1, "/host").String(),
Expand All @@ -328,21 +384,54 @@ func TestParseInsecure(t *testing.T) {
},
},
{
name: "malformed",
name: "nil audience argument",
generateToken: func(tb testing.TB) string {
claims := jwt.Claims{
Subject: spiffeid.RequireFromPath(trustDomain1, "/host").String(),
Issuer: "issuer",
Expiry: expires,
Audience: []string{"audience"},
IssuedAt: issuedAt,
}

return generateToken(tb, claims, key1, "key1", "")
},
err: "jwtsvid: audience must be non-empty",
},
{
name: "token missing aud claim",
audience: []string{"audience"},
generateToken: func(tb testing.TB) string {
claims := jwt.Claims{
Subject: spiffeid.RequireFromPath(trustDomain1, "/host").String(),
Issuer: "issuer",
Expiry: expires,
IssuedAt: issuedAt,
}

return generateToken(tb, claims, key1, "key1", "")
},
err: "jwtsvid: token missing aud claim",
},
{
name: "malformed",
audience: []string{"audience"},
generateToken: func(tb testing.TB) string {
return "invalid token"
},
err: "jwtsvid: unable to parse JWT token",
},
{
name: "invalid algorithm",
name: "invalid algorithm",
audience: []string{"audience"},
generateToken: func(tb testing.TB) string {
return hs256Token
},
err: "jwtsvid: unable to parse JWT token",
},
{
name: "missing subject claim",
name: "missing subject claim",
audience: []string{"audience"},
generateToken: func(tb testing.TB) string {
claims := jwt.Claims{
Issuer: "issuer",
Expand All @@ -356,7 +445,8 @@ func TestParseInsecure(t *testing.T) {
err: "jwtsvid: token missing subject claim",
},
{
name: "missing expiration claim",
name: "missing expiration claim",
audience: []string{"audience"},
generateToken: func(tb testing.TB) string {
claims := jwt.Claims{
Subject: spiffeid.RequireFromPath(trustDomain1, "/host").String(),
Expand Down Expand Up @@ -418,7 +508,8 @@ func TestParseInsecure(t *testing.T) {
err: `jwtsvid: token has an invalid subject claim: scheme is missing or invalid`,
},
{
name: "success",
name: "invalid typ",

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

small drive-by fix; this test was incorrectly named, as you see generateToken gets "invalid" passed as its fourth argument (typ).

audience: []string{"audience"},
generateToken: func(tb testing.TB) string {
claims := jwt.Claims{
Subject: spiffeid.RequireFromPath(trustDomain1, "/host").String(),
Expand Down