Skip to content

Key set AddKey does not seem to add on v3.0.6 #1411

@blkt

Description

@blkt

Hello,

I was writing some code to test a very thin layer built on top of jwt and jwk modules and was adding some tests when I ran into a problem: in my tests I generate a key pair used to sign the tokens and then I use it's public part to test validation. For some reason, the key set does not accept the key I provide.

Here's some code to reproduce the issue.

// Package main for local tests.
package main

import (
	"crypto/ecdsa"
	"crypto/elliptic"
	"crypto/rand"
	"encoding/json"
	"fmt"
	"time"

	"github.com/lestrrat-go/jwx/v3/jwa"
	"github.com/lestrrat-go/jwx/v3/jwk"
	"github.com/lestrrat-go/jwx/v3/jwt"
)

func main() {
	privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
	if err != nil {
		panic("fail")
	}
	fmt.Printf("%T\n", privateKey)
	fmt.Printf("%T\n", privateKey.PublicKey)

	pubJWK, err := jwk.PublicKeyOf(&privateKey.PublicKey)
	if err != nil {
		panic(err)
	}
	err = pubJWK.Set(jwk.KeyIDKey, "test-kid")
	if err != nil {
		panic(err)
	}

	publicKeyJSON, err := json.Marshal(pubJWK)
	if err != nil {
		panic(err)
	}
	fmt.Println(string(publicKeyJSON))

	keySet := jwk.NewSet()
	err = keySet.AddKey(pubJWK)
	if err != nil {
		panic(err)
	}

	tokenString := createTestToken(time.Hour, privateKey)
	fmt.Println(tokenString)

	token, err := jwt.ParseString(tokenString,
		jwt.WithKeySet(keySet),
		jwt.WithValidate(true),
	)
	if err != nil {
		panic(err)
	}

	fmt.Printf("%+v\n", token)
}

func createTestToken(
	duration time.Duration,
	privateKey *ecdsa.PrivateKey,
) string {
	ts := time.Now()
	exp := ts.Add(duration)

	token, err := jwt.NewBuilder().
		Issuer("https://test.example.com").
		Audience([]string{"test-audience"}).
		Expiration(exp).
		IssuedAt(ts).
		NotBefore(ts).
		JwtID("test-jti").
		Subject("test-subject").
		Build()
	if err != nil {
		panic(err)
	}

	// Convert the private key to a JWK and set the kid
	privJWK, err := jwk.Import(privateKey)
	if err != nil {
		panic(err)
	}
	err = privJWK.Set(jwk.KeyIDKey, "test-kid")
	if err != nil {
		panic(err)
	}

	// Sign the token with the private key JWK (with kid)
	signed, err := jwt.Sign(token, jwt.WithKey(jwa.ES256(), privJWK))
	if err != nil {
		panic(err)
	}

	return string(signed)
}

Note that jwt.io seems to accept the printed payloads.
I assume there's no bug in the library, so could anyone clarify what am I doing wrong?

Cheers and thanks!

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions