package authjwt import ( "crypto/ecdsa" "crypto/x509" "encoding/pem" "fmt" "github.com/golang-jwt/jwt/v5" ) var _ Verifier = (*ecPublicVerifier)(nil) type ecPublicVerifier struct{ public *ecdsa.PublicKey } // NewECPublicKeyVerifier returns a Verifier backed by an ECDSA public key. // Use this in services that verify tokens but never issue them. func NewECPublicKeyVerifier(publicKey *ecdsa.PublicKey) Verifier { return &ecPublicVerifier{public: publicKey} } // NewECPublicKeyVerifierFromPEM parses a PKIX PEM-encoded ECDSA public key. func NewECPublicKeyVerifierFromPEM(pemKey []byte) (Verifier, error) { block, _ := pem.Decode(pemKey) if block == nil { return nil, fmt.Errorf("no PEM block found") } pub, err := x509.ParsePKIXPublicKey(block.Bytes) if err != nil { return nil, fmt.Errorf("parse EC public key: %w", err) } ecPub, ok := pub.(*ecdsa.PublicKey) if !ok { return nil, fmt.Errorf("PEM key is not an EC public key") } return NewECPublicKeyVerifier(ecPub), nil } func (v *ecPublicVerifier) Verify(tokenString string) (*jwt.Token, error) { return jwt.Parse(tokenString, func(t *jwt.Token) (any, error) { if _, ok := t.Method.(*jwt.SigningMethodECDSA); !ok { return nil, fmt.Errorf("unexpected signing method %q", t.Header["alg"]) } return v.public, nil }, jwt.WithJSONNumber()) }