90 lines
2.1 KiB
Go
90 lines
2.1 KiB
Go
package main
|
|
|
|
import (
|
|
"crypto/ecdsa"
|
|
"crypto/elliptic"
|
|
"crypto/rand"
|
|
"crypto/x509"
|
|
"encoding/pem"
|
|
"errors"
|
|
"log/slog"
|
|
"net/http"
|
|
"os"
|
|
"time"
|
|
|
|
"github.com/golang-jwt/jwt/v5"
|
|
)
|
|
|
|
var KeyFile = "key"
|
|
|
|
var (
|
|
key *ecdsa.PrivateKey
|
|
)
|
|
|
|
// LoadKey attempts to load a private key from KeyFile.
|
|
// If the file does not exist, it generates a new key (and saves it)
|
|
func LoadKey() {
|
|
// If the key doesn't exist, create it
|
|
if _, err := os.Stat(KeyFile); errors.Is(err, os.ErrNotExist) {
|
|
key, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
|
if err != nil {
|
|
slog.Error("error generating key", "error", err)
|
|
os.Exit(1)
|
|
}
|
|
km, err := x509.MarshalECPrivateKey(key) // Save private key to disk
|
|
if err != nil {
|
|
slog.Error("error marshalling key", "error", err)
|
|
os.Exit(1)
|
|
}
|
|
os.WriteFile(KeyFile, km, 0644)
|
|
slog.Info("generated new key")
|
|
} else {
|
|
km, err := os.ReadFile(KeyFile)
|
|
if err != nil {
|
|
slog.Error("error reading key", "error", err)
|
|
os.Exit(1)
|
|
}
|
|
key, err = x509.ParseECPrivateKey(km)
|
|
if err != nil {
|
|
slog.Error("error parsing key", "error", err)
|
|
os.Exit(1)
|
|
}
|
|
slog.Info("loaded private key")
|
|
}
|
|
slog.Debug("private key", "key", key)
|
|
}
|
|
|
|
// publicKey returns our public key in PKIX, ASN.1 DER form
|
|
func publicKey(w http.ResponseWriter, r *http.Request) {
|
|
key_marshalled, err := x509.MarshalPKIXPublicKey(&key.PublicKey)
|
|
if err != nil {
|
|
slog.Error("error marshalling public key", "error", err)
|
|
http.Error(w, "error marshalling public key", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
// w.Write(key_marshalled)
|
|
block := pem.Block{Bytes: key_marshalled, Type: "ECDSA PUBLIC KEY"}
|
|
// slog.Info("public key", "orig", key_marshalled, "block", block)
|
|
pem.Encode(w, &block)
|
|
}
|
|
|
|
func init() {
|
|
LoadKey()
|
|
}
|
|
|
|
func CreateJWT(usr User) (string, error) {
|
|
t := jwt.NewWithClaims(jwt.SigningMethodES256,
|
|
jwt.MapClaims{
|
|
"iss": "pye",
|
|
"uid": usr.Uuid,
|
|
"sub": usr.Email,
|
|
"iat": time.Now(),
|
|
"exp": time.Now().Add(time.Hour * 24 * 7),
|
|
})
|
|
s, err := t.SignedString(key)
|
|
if err != nil {
|
|
slog.Error("Error creating JWT", "error", err)
|
|
return "", err
|
|
}
|
|
return s, nil
|
|
}
|