Files
ihasvpn/internal/wg/keys.go
T
jcoffey 6c006e1d4d WireGuard server with an embedded admin console
Go backend that drives kernel WireGuard over netlink (wireguard-go as the
fallback), nftables NAT with MSS clamping, forwarding and buffer sysctls,
SQLite for peers, users, sessions, traffic history and the audit log.

React console: dashboard with live rates and usage history, peer management
with QR codes and .conf downloads, disconnect, session reset, key rotation,
expiry, client-supplied keys, settings, users with admin and viewer roles,
two-factor authentication with recovery codes, audit log.

Docker image on Alpine with compose files for bridged and host networking,
CI and GHCR publish workflows, performance notes.
2026-09-12 19:56:08 -07:00

61 lines
1.4 KiB
Go

package wg
import (
"crypto/rand"
"encoding/base64"
"errors"
"fmt"
"golang.org/x/crypto/curve25519"
)
// GeneratePrivateKey returns a fresh Curve25519 private key, clamped the way
// WireGuard expects.
func GeneratePrivateKey() (Key, error) {
var k Key
if _, err := rand.Read(k[:]); err != nil {
return Key{}, fmt.Errorf("generate private key: %w", err)
}
k[0] &= 248
k[31] &= 127
k[31] |= 64
return k, nil
}
// GeneratePresharedKey returns 32 random bytes for use as a preshared key.
func GeneratePresharedKey() (Key, error) {
var k Key
if _, err := rand.Read(k[:]); err != nil {
return Key{}, fmt.Errorf("generate preshared key: %w", err)
}
return k, nil
}
// PublicKey derives the public key of a private key.
func (k Key) PublicKey() Key {
var pub Key
priv := k
curve25519.ScalarBaseMult((*[32]byte)(&pub), (*[32]byte)(&priv))
return pub
}
// String renders the key the way wg(8) does: standard base64.
func (k Key) String() string { return base64.StdEncoding.EncodeToString(k[:]) }
// IsZero reports whether the key is all zeros.
func (k Key) IsZero() bool { return k == Key{} }
// ParseKey parses a base64 key as produced by wg genkey / wg pubkey.
func ParseKey(s string) (Key, error) {
b, err := base64.StdEncoding.DecodeString(s)
if err != nil {
return Key{}, errors.New("key is not valid base64")
}
if len(b) != 32 {
return Key{}, errors.New("key must decode to 32 bytes")
}
var k Key
copy(k[:], b)
return k, nil
}