jose

package
v0.5.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 27, 2026 License: BSD-2-Clause Imports: 20 Imported by: 0

Documentation

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func ExtractClaim

func ExtractClaim(token string, claimName string) (any, error)

ExtractClaim extracts a specific claim from a JWT without validation

Example
package main

import (
	"encoding/base64"
	"encoding/json"
	"fmt"

	"github.com/SUNET/vc/pkg/jose"
)

// makeTestJWT constructs a compact JWT from header and payload maps with a fake signature.
func makeTestJWT(header, payload map[string]any) string {
	h, _ := json.Marshal(header)
	p, _ := json.Marshal(payload)
	return base64.RawURLEncoding.EncodeToString(h) + "." +
		base64.RawURLEncoding.EncodeToString(p) + "." +
		base64.RawURLEncoding.EncodeToString([]byte("fakesig"))
}

func main() {
	token := makeTestJWT(
		map[string]any{"alg": "ES256", "typ": "JWT"},
		map[string]any{"sub": "user-123", "iss": "https://issuer.example.com"},
	)

	sub, err := jose.ExtractClaim(token, "sub")
	if err != nil {
		fmt.Println("error:", err)
		return
	}
	fmt.Println("sub:", sub)

	iss, err := jose.ExtractClaim(token, "iss")
	if err != nil {
		fmt.Println("error:", err)
		return
	}
	fmt.Println("iss:", iss)
}
Output:
sub: user-123
iss: https://issuer.example.com
Example (MissingClaim)
package main

import (
	"encoding/base64"
	"encoding/json"
	"fmt"

	"github.com/SUNET/vc/pkg/jose"
)

// makeTestJWT constructs a compact JWT from header and payload maps with a fake signature.
func makeTestJWT(header, payload map[string]any) string {
	h, _ := json.Marshal(header)
	p, _ := json.Marshal(payload)
	return base64.RawURLEncoding.EncodeToString(h) + "." +
		base64.RawURLEncoding.EncodeToString(p) + "." +
		base64.RawURLEncoding.EncodeToString([]byte("fakesig"))
}

func main() {
	token := makeTestJWT(
		map[string]any{"alg": "ES256"},
		map[string]any{"sub": "user-123"},
	)

	_, err := jose.ExtractClaim(token, "nonexistent")
	fmt.Println("error:", err)
}
Output:
error: claim "nonexistent" not found

func ExtractKIDFromCompactJWT

func ExtractKIDFromCompactJWT(compactToken string) (string, error)

ExtractKIDFromCompactJWT extracts the "kid" field from the header of a compact-serialized JWT/JWE.

Example
package main

import (
	"encoding/base64"
	"encoding/json"
	"fmt"

	"github.com/SUNET/vc/pkg/jose"
)

// makeTestJWT constructs a compact JWT from header and payload maps with a fake signature.
func makeTestJWT(header, payload map[string]any) string {
	h, _ := json.Marshal(header)
	p, _ := json.Marshal(payload)
	return base64.RawURLEncoding.EncodeToString(h) + "." +
		base64.RawURLEncoding.EncodeToString(p) + "." +
		base64.RawURLEncoding.EncodeToString([]byte("fakesig"))
}

func main() {
	token := makeTestJWT(
		map[string]any{"alg": "ES256", "kid": "key-abc-123"},
		map[string]any{"sub": "user"},
	)

	kid, err := jose.ExtractKIDFromCompactJWT(token)
	if err != nil {
		fmt.Println("error:", err)
		return
	}
	fmt.Println("kid:", kid)
}
Output:
kid: key-abc-123
Example (Missing)
package main

import (
	"encoding/base64"
	"encoding/json"
	"fmt"

	"github.com/SUNET/vc/pkg/jose"
)

// makeTestJWT constructs a compact JWT from header and payload maps with a fake signature.
func makeTestJWT(header, payload map[string]any) string {
	h, _ := json.Marshal(header)
	p, _ := json.Marshal(payload)
	return base64.RawURLEncoding.EncodeToString(h) + "." +
		base64.RawURLEncoding.EncodeToString(p) + "." +
		base64.RawURLEncoding.EncodeToString([]byte("fakesig"))
}

func main() {
	token := makeTestJWT(
		map[string]any{"alg": "ES256"},
		map[string]any{"sub": "user"},
	)

	_, err := jose.ExtractKIDFromCompactJWT(token)
	fmt.Println("error:", err)
}
Output:
error: kid not found in JWT header

func GetSigningMethodFromKey

func GetSigningMethodFromKey(privateKey any) (jwt.SigningMethod, string)

GetSigningMethodFromKey determines the JWT signing method and algorithm name from the private key

func MakeJWT

func MakeJWT(ctx context.Context, header, body jwt.MapClaims, signer pki.Signer) (string, error)

MakeJWT creates a signed JWT using pki.Signer. The pki.Signer interface supports both software keys and HSM.

func ParseJWKToPublicKey

func ParseJWKToPublicKey(jwkData any) (crypto.PublicKey, error)

ParseJWKToPublicKey parses a JWK (as a map or JSON bytes) to extract the public key.

func ParseJWTWithJWKHeader

func ParseJWTWithJWKHeader(token string) (jwt.MapClaims, map[string]any, map[string]any, string, error)

ParseJWTWithJWKHeader parses and validates a JWT where the public key is embedded in the JWT header as a JWK Returns the parsed claims, the token header, the JWK header, the key thumbprint, and any error

func ParseSigningKey

func ParseSigningKey(signingKeyPath string) (crypto.PrivateKey, error)

ParseSigningKey parses a private key from a PEM file (supports EC and RSA in various formats) Handles SEC1, PKCS1, and PKCS8 formats automatically.

func ParseX5CHeader

func ParseX5CHeader(x5cRaw any, ext ...*cryptoutil.Extensions) ([]*x509.Certificate, error)

ParseX5CHeader parses the x5c header into a certificate chain. The x5c header is an array of base64-encoded DER certificates, with the leaf certificate first. Supports both standard and URL-safe base64 encoding. If ext is provided, certificates are parsed using extension-aware parsing (e.g. to support brainpool curves).

Types

type JWKS

type JWKS struct {
	Keys []JWKWithMetadata `json:"keys"`
}

JWKS represents a JSON Web Key Set

Example
package main

import (
	"fmt"

	"github.com/SUNET/vc/pkg/jose"
)

func main() {
	jwks := &jose.JWKS{
		Keys: []jose.JWKWithMetadata{
			{
				Kty: "EC",
				Crv: "P-256",
				Kid: "key-1",
				Alg: "ES256",
				Use: "sig",
				X:   "f83OJ3D2xF1Bg8vub9tLe1gHMzV76e8Tus9uPHvRVEU",
				Y:   "x_FEzRu9m36HLN_tue659LNpXW6pCyStikYjKIWI5a0",
			},
		},
	}

	fmt.Println("keys:", len(jwks.Keys))
	fmt.Println("kty:", jwks.Keys[0].Kty)
	fmt.Println("kid:", jwks.Keys[0].Kid)
	fmt.Println("alg:", jwks.Keys[0].Alg)
	fmt.Println("use:", jwks.Keys[0].Use)
}
Output:
keys: 1
kty: EC
kid: key-1
alg: ES256
use: sig

func CreateJWKSFromSigner

func CreateJWKSFromSigner(signer pki.Signer, keyUsage string) (*JWKS, error)

CreateJWKSFromSigner creates a JWKS from a pki.Signer keyUsage defaults to "sig" if empty string is provided

type JWKWithMetadata

type JWKWithMetadata struct {
	Kty string `json:"kty"`
	Use string `json:"use,omitempty"`
	Kid string `json:"kid,omitempty"`
	Alg string `json:"alg,omitempty"`
	// EC key fields
	Crv string `json:"crv,omitempty"`
	X   string `json:"x,omitempty"`
	Y   string `json:"y,omitempty"`
	// RSA key fields
	N string `json:"n,omitempty"`
	E string `json:"e,omitempty"`
}

JWKWithMetadata includes additional fields like alg, use, kid

func ParseJWK

func ParseJWK(jwkMap map[string]any) (*JWKWithMetadata, error)

ParseJWK converts a JWK map (e.g., from a JWT header) to a JWKWithMetadata struct This is commonly used for DPoP and similar protocols where JWK is embedded in JWT headers

Example
package main

import (
	"fmt"

	"github.com/SUNET/vc/pkg/jose"
)

func main() {
	jwkMap := map[string]any{
		"kty": "EC",
		"crv": "P-256",
		"x":   "f83OJ3D2xF1Bg8vub9tLe1gHMzV76e8Tus9uPHvRVEU",
		"y":   "x_FEzRu9m36HLN_tue659LNpXW6pCyStikYjKIWI5a0",
		"kid": "my-key-id",
		"alg": "ES256",
	}

	jwk, err := jose.ParseJWK(jwkMap)
	if err != nil {
		fmt.Println("error:", err)
		return
	}

	fmt.Println("kty:", jwk.Kty)
	fmt.Println("kid:", jwk.Kid)
	fmt.Println("crv:", jwk.Crv)
}
Output:
kty: EC
kid: my-key-id
crv: P-256

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL