func (c *CA) generateCA() error {
	_, certErr := os.Stat(c.caCertPath)
	_, keyErr := os.Stat(c.caKeyPath)
	if certErr == nil && keyErr == nil {
		return nil
	}
	notBefore := time.Now()
	notAfter := notBefore.Add(time.Hour * maxValidCA)
	serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
	serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
	if err != nil {
		return err
	}
	template := &x509.Certificate{
		SerialNumber: serialNumber,
		Subject: pkix.Name{
			Organization: []string{orgName},
		},
		NotBefore: notBefore,
		NotAfter:  notAfter,
		IsCA:                  true,
		KeyUsage:              x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
		ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
		BasicConstraintsValid: true,
		DNSNames:              []string{orgDNS, goPluginHostname},
	}
	key, err := rsa.GenerateKey(rand.Reader, rsaBits)
	if err != nil {
		return err
	}
	derBytes, err := x509.CreateCertificate(rand.Reader, template, template, &key.PublicKey, key)
	if err != nil {
		return err
	}
	certOut, err := os.Create(c.caCertPath)
	if err != nil {
		return err
	}
	err = pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes})
	if err != nil {
		return err
	}
	err = certOut.Close()
	if err != nil {
		return err
	}
	keyOut, err := os.OpenFile(c.caKeyPath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
	if err != nil {
		return err
	}
	privateKey, err := x509.MarshalPKCS8PrivateKey(key)
	if err != nil {
		return err
	}
	err = pem.Encode(keyOut, &pem.Block{Type: "PRIVATE KEY", Bytes: privateKey})
	if err != nil {
		return err
	}
	err = keyOut.Close()
	if err != nil {
		return err
	}
	return nil
}
generateCA generates the CA and puts the certs into the data folder.
If they are already existing, nothing will be done.
package security
import (
	"crypto/rand"
	"crypto/rsa"
	"crypto/tls"
	"crypto/x509"
	"crypto/x509/pkix"
	"encoding/pem"
	"errors"
	"io/ioutil"
	"math/big"
	"os"
	"path/filepath"
	"time"
	"github.com/gaia-pipeline/gaia"
)
const (
	rsaBits      = 2048
	maxValidCA   = 175200  
	maxValidCERT = 48      
	orgName      = "gaia-pipeline"
	orgDNS       = "gaia-pipeline.io"
	certName = "ca.crt"
	keyName  = "ca.key"
	goPluginHostname = "unused"
)
var (
	errCertNotAppended = errors.New("cannot append root CA cert to cert pool")
)
type CA struct {
	caCertPath string
	caKeyPath  string
}
type CAAPI interface {
	CreateSignedCert() (string, string, error)
	CreateSignedCertWithValidOpts(hostname string, hoursBeforeValid, hoursAfterValid time.Duration) (string, string, error)
	GenerateTLSConfig(certPath, keyPath string) (*tls.Config, error)
	CleanupCerts(crt, key string) error
	GetCACertPath() (string, string)
}
func InitCA() (*CA, error) {
	t := &CA{
		caCertPath: filepath.Join(gaia.Cfg.CAPath, certName),
		caKeyPath:  filepath.Join(gaia.Cfg.CAPath, keyName),
	}
	return t, t.generateCA()
}