aboutsummaryrefslogtreecommitdiff
path: root/internal/tlscert/tlscert.go
diff options
context:
space:
mode:
authorhistoria <[not public]>2026-10-05 19:20:17 -0400
committerhistoria <[not public]>2026-10-05 19:20:17 -0400
commit1091d0fae96d152c11aec1bb2dd949f51ed5aa1e (patch)
tree0d867d42726cd3910c9851ec69e15b9a4b031001 /internal/tlscert/tlscert.go
parent9d8c43cd68c960b9a6b8f781684f763e204a4498 (diff)
downloadthehouseoficarus-1091d0fae96d152c11aec1bb2dd949f51ed5aa1e.tar.gz
feat: shared tls cert, validation fixes
Diffstat (limited to 'internal/tlscert/tlscert.go')
-rw-r--r--internal/tlscert/tlscert.go52
1 files changed, 52 insertions, 0 deletions
diff --git a/internal/tlscert/tlscert.go b/internal/tlscert/tlscert.go
new file mode 100644
index 0000000..b865a70
--- /dev/null
+++ b/internal/tlscert/tlscert.go
@@ -0,0 +1,52 @@
+// Package tlscert generates the in-memory self-signed certificate used when a
+// TLS transport is enabled without an explicit cert/key pair.
+package tlscert
+
+import (
+ "crypto/rand"
+ "crypto/rsa"
+ "crypto/tls"
+ "crypto/x509"
+ "crypto/x509/pkix"
+ "fmt"
+ "math/big"
+ "net"
+ "time"
+)
+
+// SelfSigned generates a self-signed certificate for commonName, valid for a
+// year, covering localhost and the loopback addresses. Shared by the game
+// server and the admin server so the two cannot drift.
+func SelfSigned(commonName string) (tls.Certificate, error) {
+ key, err := rsa.GenerateKey(rand.Reader, 2048)
+ if err != nil {
+ return tls.Certificate{}, fmt.Errorf("rsa key generation: %w", err)
+ }
+ serial, err := rand.Int(rand.Reader, new(big.Int).Lsh(big.NewInt(1), 128))
+ if err != nil {
+ return tls.Certificate{}, fmt.Errorf("serial number: %w", err)
+ }
+ now := time.Now()
+ tmpl := &x509.Certificate{
+ SerialNumber: serial,
+ Subject: pkix.Name{
+ CommonName: commonName,
+ },
+ NotBefore: now.Add(-1 * time.Hour),
+ NotAfter: now.Add(365 * 24 * time.Hour),
+ KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
+ ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
+ BasicConstraintsValid: true,
+ IsCA: true,
+ DNSNames: []string{"localhost"},
+ IPAddresses: []net.IP{net.ParseIP("127.0.0.1"), net.ParseIP("::1")},
+ }
+ certDER, err := x509.CreateCertificate(rand.Reader, tmpl, tmpl, &key.PublicKey, key)
+ if err != nil {
+ return tls.Certificate{}, fmt.Errorf("x509 creation: %w", err)
+ }
+ return tls.Certificate{
+ Certificate: [][]byte{certDER},
+ PrivateKey: key,
+ }, nil
+}