Files
BatchuKVM/server/utils/cert.go

101 lines
2.5 KiB
Go

package utils
import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"math/big"
"net"
"os"
"time"
log "github.com/sirupsen/logrus"
)
func GenerateCert() error {
var (
host = "localhost"
ipAddress = []net.IP{net.ParseIP("127.0.0.1"), net.ParseIP("::1")}
validFor = time.Hour * 24 * 365 * 10
certFile = "/etc/kvm/server.crt"
keyFile = "/etc/kvm/server.key"
)
privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
log.Errorf("failed to generate RSA private key: %v", err)
return err
}
publicKey := &privateKey.PublicKey
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
if err != nil {
log.Errorf("failed to generate serial number: %v", err)
return err
}
template := x509.Certificate{
SerialNumber: serialNumber,
Subject: pkix.Name{
CommonName: host,
},
NotBefore: time.Now(),
NotAfter: time.Now().Add(validFor),
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
BasicConstraintsValid: true,
IsCA: false,
DNSNames: []string{host},
IPAddresses: ipAddress,
}
derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, publicKey, privateKey)
if err != nil {
log.Errorf("failed to create certificate: %v", err)
return err
}
// generate certificate
certOut, err := os.Create(certFile)
if err != nil {
log.Errorf("failed to create %s: %v", certFile, err)
return err
}
if err := pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}); err != nil {
log.Errorf("failed to encode %s: %v", certFile, err)
return err
}
_ = certOut.Sync()
_ = certOut.Close()
log.Debugf("%s generated", certFile)
// generate private key
keyOut, err := os.OpenFile(keyFile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) // 权限 0600
if err != nil {
log.Errorf("failed to create %s: %v", keyFile, err)
return err
}
privateBytes, err := x509.MarshalPKCS8PrivateKey(privateKey)
if err != nil {
log.Errorf("failed to marshal private key: %v", err)
return err
}
if err := pem.Encode(keyOut, &pem.Block{Type: "PRIVATE KEY", Bytes: privateBytes}); err != nil {
log.Errorf("failed to encode %s: %v", keyFile, err)
return err
}
_ = keyOut.Sync()
_ = keyOut.Close()
log.Debugf("%s generated", keyFile)
return nil
}