Implements the from-scratch multi-server WireGuard management fork per CLAUDE.md spec: sqlite schema (servers/peers/audit_log/users), Curve25519 key generation, per-interface config rendering + wg-quick/systemd control, nftables hook scaffolding, session+CSRF-protected REST API with QR code and config download endpoints, a minimal vanilla-JS web UI, legacy wg0.conf migration, and both a native installer and a Proxmox LXC provisioning script (with auto-detected latest Debian template). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
48 lines
1.3 KiB
Go
48 lines
1.3 KiB
Go
package wireguard
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"encoding/base64"
|
|
|
|
"golang.org/x/crypto/curve25519"
|
|
)
|
|
|
|
// GenerateKeyPair creates a new WireGuard-compatible Curve25519 key pair,
|
|
// base64-encoded like `wg genkey` / `wg pubkey`.
|
|
func GenerateKeyPair() (privateKey, publicKey string, err error) {
|
|
var priv [32]byte
|
|
if _, err := rand.Read(priv[:]); err != nil {
|
|
return "", "", err
|
|
}
|
|
// Clamp per RFC 7748 / WireGuard convention.
|
|
priv[0] &= 248
|
|
priv[31] &= 127
|
|
priv[31] |= 64
|
|
|
|
var pub [32]byte
|
|
curve25519.ScalarBaseMult(&pub, &priv)
|
|
|
|
return base64.StdEncoding.EncodeToString(priv[:]), base64.StdEncoding.EncodeToString(pub[:]), nil
|
|
}
|
|
|
|
// PublicFromPrivate derives the public key for an existing base64 private key.
|
|
func PublicFromPrivate(privateKeyB64 string) (string, error) {
|
|
privBytes, err := base64.StdEncoding.DecodeString(privateKeyB64)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
var priv, pub [32]byte
|
|
copy(priv[:], privBytes)
|
|
curve25519.ScalarBaseMult(&pub, &priv)
|
|
return base64.StdEncoding.EncodeToString(pub[:]), nil
|
|
}
|
|
|
|
// GeneratePresharedKey creates a random base64 preshared key.
|
|
func GeneratePresharedKey() (string, error) {
|
|
var key [32]byte
|
|
if _, err := rand.Read(key[:]); err != nil {
|
|
return "", err
|
|
}
|
|
return base64.StdEncoding.EncodeToString(key[:]), nil
|
|
}
|