package tls import ( "crypto/rand" "crypto/rsa" "crypto/tls" "crypto/x509" "crypto/x509/pkix" "encoding/pem" "math/big" "net" "time" ) func CreateCertificate() (*tls.Certificate, error) { // 1. Generate an RSA private key privateKey, err := rsa.GenerateKey(rand.Reader, 2048) if err != nil { return nil, err } // 2. Define the certificate template serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) if err != nil { return nil, err } template := x509.Certificate{ SerialNumber: serialNumber, Subject: pkix.Name{ Organization: []string{"home"}, CommonName: "localhost", }, NotBefore: time.Now(), NotAfter: time.Now().Add(365 * 24 * time.Hour), // Valid for 1 year KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, BasicConstraintsValid: true, // Add localhost as a valid IP and DNS name IPAddresses: []net.IP{[]byte{127, 0, 0, 1}}, DNSNames: []string{"localhost"}, } // 3. Create a self-signed certificate // The parent is the template itself, and we use the generated public and private keys. derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &privateKey.PublicKey, privateKey) if err != nil { return nil, err } derBytes = pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: derBytes}) keyBytes := pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(privateKey)}) cert, err := tls.X509KeyPair(derBytes, keyBytes) if err != nil { return nil, err } return &cert, nil }