github.com/choria-io/go-choria@v0.28.1-0.20240416190746-b3bf9c7d5a45/integration/testutil/jwt.go (about)

     1  // Copyright (c) 2022, R.I. Pienaar and the Choria Project contributors
     2  //
     3  // SPDX-License-Identifier: Apache-2.0
     4  
     5  package testutil
     6  
     7  import (
     8  	"crypto/ed25519"
     9  	"crypto/rsa"
    10  	"encoding/hex"
    11  	"os"
    12  	"path/filepath"
    13  	"time"
    14  
    15  	iu "github.com/choria-io/go-choria/internal/util"
    16  	"github.com/choria-io/tokens"
    17  	"github.com/golang-jwt/jwt/v4"
    18  )
    19  
    20  func CreateChoriaTokenAndKeys(targetDir string, tokenSignerFile string, public ed25519.PublicKey, create func(pubK ed25519.PublicKey) (jwt.Claims, error)) (tokenFile string, signedToken string, pubFile string, priFile string, err error) {
    21  	if public == nil {
    22  		priFile = filepath.Join(targetDir, "seed")
    23  		pubFile = filepath.Join(targetDir, "public")
    24  
    25  		public, _, err = iu.Ed25519KeyPairToFile(priFile)
    26  		if err != nil {
    27  			return "", "", "", "", err
    28  		}
    29  
    30  		err = os.WriteFile(pubFile, []byte(hex.EncodeToString(public)), 0644)
    31  		if err != nil {
    32  			return "", "", "", "", err
    33  		}
    34  	}
    35  
    36  	claims, err := create(public)
    37  	if err != nil {
    38  		return "", "", "", "", err
    39  	}
    40  
    41  	signed, err := tokens.SignTokenWithKeyFile(claims, tokenSignerFile)
    42  	if err != nil {
    43  		return "", "", "", "", err
    44  	}
    45  
    46  	tokenFile = filepath.Join(targetDir, "jwt")
    47  	err = os.WriteFile(tokenFile, []byte(signed), 0644)
    48  	if err != nil {
    49  		return "", "", "", "", err
    50  	}
    51  
    52  	return tokenFile, signed, pubFile, priFile, nil
    53  }
    54  
    55  func CreateSignedClientJWT(pk any, claims map[string]any) (string, error) {
    56  	c := map[string]any{
    57  		"exp":      time.Now().UTC().Add(time.Hour).Unix(),
    58  		"nbf":      time.Now().UTC().Add(-1 * time.Minute).Unix(),
    59  		"iat":      time.Now().UTC().Unix(),
    60  		"iss":      "Ginkgo",
    61  		"callerid": "up=ginkgo",
    62  		"sub":      "up=ginkgo",
    63  	}
    64  
    65  	for k, v := range claims {
    66  		c[k] = v
    67  	}
    68  
    69  	var alg string
    70  	switch pk.(type) {
    71  	case ed25519.PrivateKey:
    72  		alg = "EdDSA"
    73  	case *rsa.PrivateKey:
    74  		alg = "RS512"
    75  	}
    76  
    77  	token := jwt.NewWithClaims(jwt.GetSigningMethod(alg), jwt.MapClaims(c))
    78  	return token.SignedString(pk)
    79  }
    80  
    81  func CreateSignedServerJWT(pk any, pubK []byte, claims map[string]any) (string, error) {
    82  	c := map[string]any{
    83  		"exp":        time.Now().UTC().Add(time.Hour).Unix(),
    84  		"nbf":        time.Now().UTC().Add(-1 * time.Minute).Unix(),
    85  		"iat":        time.Now().UTC().Unix(),
    86  		"iss":        "Ginkgo",
    87  		"public_key": hex.EncodeToString(pubK),
    88  		"identity":   "ginkgo.example.net",
    89  		"ou":         "choria",
    90  	}
    91  	for k, v := range claims {
    92  		c[k] = v
    93  	}
    94  
    95  	var alg string
    96  	switch pk.(type) {
    97  	case ed25519.PrivateKey:
    98  		alg = "EdDSA"
    99  	case *rsa.PrivateKey:
   100  		alg = "RS512"
   101  	}
   102  
   103  	token := jwt.NewWithClaims(jwt.GetSigningMethod(alg), jwt.MapClaims(c))
   104  
   105  	return token.SignedString(pk)
   106  }