86 lines
1.9 KiB
Go
86 lines
1.9 KiB
Go
|
// Copyright (C) 2023-2024 Umorpha Systems
|
||
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||
|
|
||
|
package apikeys
|
||
|
|
||
|
import (
|
||
|
"crypto/ed25519"
|
||
|
"crypto/x509"
|
||
|
"encoding/pem"
|
||
|
"os"
|
||
|
|
||
|
"github.com/golang-jwt/jwt/v5"
|
||
|
)
|
||
|
|
||
|
var signingMethod = jwt.SigningMethodEdDSA
|
||
|
|
||
|
type PublicKey = ed25519.PublicKey
|
||
|
|
||
|
func GenerateLeaderKeys() (ed25519.PublicKey, ed25519.PrivateKey, error) {
|
||
|
return ed25519.GenerateKey(nil)
|
||
|
}
|
||
|
|
||
|
func LoadLeaderPubKey(filename string) (ed25519.PublicKey, error) {
|
||
|
bs, err := os.ReadFile(filename)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
ret, err := jwt.ParseEdPublicKeyFromPEM(bs)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
return ret.(ed25519.PublicKey), nil
|
||
|
}
|
||
|
|
||
|
func LoadLeaderPrivKey(filename string) (ed25519.PrivateKey, error) {
|
||
|
bs, err := os.ReadFile(filename)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
ret, err := jwt.ParseEdPrivateKeyFromPEM(bs)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
return ret.(ed25519.PrivateKey), nil
|
||
|
}
|
||
|
|
||
|
func WriteLeaderPubKey(filename string, pubKey ed25519.PublicKey) error {
|
||
|
bs, err := x509.MarshalPKIXPublicKey(pubKey)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
bs = pem.EncodeToMemory(&pem.Block{
|
||
|
Type: "PUBLIC KEY",
|
||
|
Bytes: bs,
|
||
|
})
|
||
|
return os.WriteFile(filename, bs, 0400)
|
||
|
}
|
||
|
func WriteLeaderPrivKey(filename string, privKey ed25519.PrivateKey) error {
|
||
|
bs, err := x509.MarshalPKCS8PrivateKey(privKey)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
bs = pem.EncodeToMemory(&pem.Block{
|
||
|
Type: "PRIVATE KEY",
|
||
|
Bytes: bs,
|
||
|
})
|
||
|
return os.WriteFile(filename, bs, 0444)
|
||
|
}
|
||
|
|
||
|
func GenerateAPIKey(leaderPrivKey ed25519.PrivateKey) (string, error) {
|
||
|
return jwt.NewWithClaims(signingMethod, jwt.MapClaims{
|
||
|
"TOOD": "TODO",
|
||
|
}).SignedString(leaderPrivKey)
|
||
|
}
|
||
|
|
||
|
var apikeyParser = jwt.NewParser(
|
||
|
jwt.WithStrictDecoding(),
|
||
|
jwt.WithValidMethods([]string{signingMethod.Alg()}))
|
||
|
|
||
|
func ValidateAPIKey(leaderPubKey ed25519.PublicKey, apikey string) error {
|
||
|
_, err := apikeyParser.Parse(apikey, func(*jwt.Token) (any, error) {
|
||
|
return leaderPubKey, nil
|
||
|
})
|
||
|
return err
|
||
|
}
|