Files
tecamino-dbm/cert/cert.go
Adrian Zürcher d515e2d9d7
All checks were successful
Build DBM Service / build (amd64, , linux) (push) Successful in 2m2s
Build DBM Service / build (amd64, .exe, windows) (push) Successful in 1m52s
Build DBM Service / build (arm, 6, , linux) (push) Successful in 1m57s
Build DBM Service / build (arm64, , linux) (push) Successful in 1m52s
change selfsigned cert to work with firefox
2026-02-19 08:41:15 +01:00

178 lines
3.2 KiB
Go

package cert
import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"math/big"
"net"
"os"
"path"
"time"
)
type Cert struct {
Organization string
CertFile string
KeyFile string
}
// Initialize a new ssl certificate handler with organization name
func NewCertHandler(org string) *Cert {
return &Cert{
Organization: org,
}
}
// generates a new self signed ssl certificate foe localhost and development use
func (c *Cert) GenerateSelfSignedCert() error {
// do not generate certs if they exist
_, err := os.Stat(c.CertFile)
_, err2 := os.Stat(c.KeyFile)
if !os.IsNotExist(err) && !os.IsNotExist(err2) {
return nil
}
caCert, caKey, err := createCA()
if err != nil {
return err
}
serverCert, serverKey, err := createServerCert(caCert, caKey)
if err != nil {
return err
}
if err := os.MkdirAll(path.Dir(c.CertFile), 0700); err != nil {
return err
}
if err := os.MkdirAll(path.Dir(c.KeyFile), 0700); err != nil {
return err
}
if err := saveCert(c.CertFile, serverCert.Raw); err != nil {
return err
}
if err := saveKey(c.KeyFile, serverKey); err != nil {
return err
}
return nil
}
func createCA() (*x509.Certificate, *rsa.PrivateKey, error) {
priv, _ := rsa.GenerateKey(rand.Reader, 2048)
serial, _ := rand.Int(rand.Reader, big.NewInt(1<<62))
template := x509.Certificate{
SerialNumber: serial,
Subject: pkix.Name{
CommonName: "Local Dev CA",
},
NotBefore: time.Now(),
NotAfter: time.Now().AddDate(10, 0, 0),
KeyUsage: x509.KeyUsageCertSign | x509.KeyUsageCRLSign,
BasicConstraintsValid: true,
IsCA: true,
}
certDER, _ := x509.CreateCertificate(
rand.Reader,
&template,
&template,
&priv.PublicKey,
priv,
)
cert, _ := x509.ParseCertificate(certDER)
return cert, priv, nil
}
func createServerCert(
ca *x509.Certificate,
caKey *rsa.PrivateKey,
) (*x509.Certificate, *rsa.PrivateKey, error) {
priv, _ := rsa.GenerateKey(rand.Reader, 2048)
serial, _ := rand.Int(rand.Reader, big.NewInt(1<<62))
template := x509.Certificate{
SerialNumber: serial,
Subject: pkix.Name{
CommonName: "localhost",
},
NotBefore: time.Now(),
NotAfter: time.Now().AddDate(1, 0, 0),
KeyUsage: x509.KeyUsageDigitalSignature,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
DNSNames: []string{
"localhost",
"lvh.me",
},
IPAddresses: []net.IP{
net.ParseIP("127.0.0.1"),
net.ParseIP("::1"),
},
}
certDER, _ := x509.CreateCertificate(
rand.Reader,
&template,
ca,
&priv.PublicKey,
caKey,
)
cert, _ := x509.ParseCertificate(certDER)
return cert, priv, nil
}
func saveCert(path string, der []byte) error {
file, err := os.Create(path)
if err != nil {
return err
}
defer file.Close()
if err := pem.Encode(file, &pem.Block{
Type: "CERTIFICATE",
Bytes: der,
}); err != nil {
return err
}
return os.Chmod(path, 0600)
}
func saveKey(path string, key *rsa.PrivateKey) error {
file, err := os.Create(path)
if err != nil {
return err
}
defer file.Close()
if err := pem.Encode(file, &pem.Block{
Type: "RSA PRIVATE KEY",
Bytes: x509.MarshalPKCS1PrivateKey(key),
}); err != nil {
return err
}
return os.Chmod(path, 0600)
}