package acme import ( "crypto/rand" "crypto/rsa" "crypto/sha256" "crypto/tls" "crypto/x509" "crypto/x509/pkix" "encoding/hex" "encoding/pem" "fmt" "math/big" "time" ) func generateDefaultCertificate() (*tls.Certificate, error) { rsaPrivKey, err := rsa.GenerateKey(rand.Reader, 2048) if err != nil { return nil, err } rsaPrivPEM := pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(rsaPrivKey)}) randomBytes := make([]byte, 100) _, err = rand.Read(randomBytes) if err != nil { return nil, err } zBytes := sha256.Sum256(randomBytes) z := hex.EncodeToString(zBytes[:sha256.Size]) domain := fmt.Sprintf("%s.%s.traefik.default", z[:32], z[32:]) tempCertPEM, err := generatePemCert(rsaPrivKey, domain) if err != nil { return nil, err } certificate, err := tls.X509KeyPair(tempCertPEM, rsaPrivPEM) if err != nil { return nil, err } return &certificate, nil } func generatePemCert(privKey *rsa.PrivateKey, domain string) ([]byte, error) { derBytes, err := generateDerCert(privKey, time.Time{}, domain) if err != nil { return nil, err } return pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: derBytes}), nil } func generateDerCert(privKey *rsa.PrivateKey, expiration time.Time, domain string) ([]byte, error) { serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) if err != nil { return nil, err } if expiration.IsZero() { expiration = time.Now().Add(365) } template := x509.Certificate{ SerialNumber: serialNumber, Subject: pkix.Name{ CommonName: "TRAEFIK DEFAULT CERT", }, NotBefore: time.Now(), NotAfter: expiration, KeyUsage: x509.KeyUsageKeyEncipherment, BasicConstraintsValid: true, DNSNames: []string{domain}, } return x509.CreateCertificate(rand.Reader, &template, &template, &privKey.PublicKey, privKey) }