package cert import ( "crypto/rand" "crypto/rsa" "crypto/x509" "crypto/x509/pkix" "encoding/pem" "math/big" "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 } priv, err := rsa.GenerateKey(rand.Reader, 2048) if err != nil { return err } serialNumber, _ := rand.Int(rand.Reader, big.NewInt(1<<62)) template := x509.Certificate{ SerialNumber: serialNumber, Subject: pkix.Name{ CommonName: "localhost", Organization: []string{c.Organization}, }, NotBefore: time.Now(), NotAfter: time.Now().Add(365 * 24 * time.Hour), KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, BasicConstraintsValid: true, DNSNames: []string{"localhost"}, } certDER, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv) if err != nil { return err } if _, err := os.Stat(path.Dir(c.CertFile)); os.IsNotExist(err) { os.MkdirAll(path.Dir(c.CertFile), 0700) } certOut, err := os.Create(c.CertFile) if err != nil { return err } defer certOut.Close() pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: certDER}) // Set permission to 0600 (read/write by owner only) if err := os.Chmod(c.CertFile, 0600); err != nil { return err } if _, err := os.Stat(path.Dir(c.KeyFile)); os.IsNotExist(err) { os.MkdirAll(path.Dir(c.KeyFile), 0700) } keyOut, err := os.Create(c.KeyFile) if err != nil { return err } defer keyOut.Close() pem.Encode(keyOut, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)}) // Set permission to 0600 (read/write by owner only) if err := os.Chmod(c.KeyFile, 0600); err != nil { return err } return nil }