github.com/sagernet/sing-box@v1.9.0-rc.20/common/tls/mkcert.go (about) 1 package tls 2 3 import ( 4 "crypto/rand" 5 "crypto/rsa" 6 "crypto/tls" 7 "crypto/x509" 8 "crypto/x509/pkix" 9 "encoding/pem" 10 "math/big" 11 "time" 12 ) 13 14 func GenerateCertificate(timeFunc func() time.Time, serverName string) (*tls.Certificate, error) { 15 privateKeyPem, publicKeyPem, err := GenerateKeyPair(timeFunc, serverName, timeFunc().Add(time.Hour)) 16 if err != nil { 17 return nil, err 18 } 19 certificate, err := tls.X509KeyPair(publicKeyPem, privateKeyPem) 20 if err != nil { 21 return nil, err 22 } 23 return &certificate, err 24 } 25 26 func GenerateKeyPair(timeFunc func() time.Time, serverName string, expire time.Time) (privateKeyPem []byte, publicKeyPem []byte, err error) { 27 if timeFunc == nil { 28 timeFunc = time.Now 29 } 30 key, err := rsa.GenerateKey(rand.Reader, 2048) 31 if err != nil { 32 return 33 } 34 serialNumber, err := rand.Int(rand.Reader, new(big.Int).Lsh(big.NewInt(1), 128)) 35 if err != nil { 36 return 37 } 38 template := &x509.Certificate{ 39 SerialNumber: serialNumber, 40 NotBefore: timeFunc().Add(time.Hour * -1), 41 NotAfter: expire, 42 KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, 43 ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, 44 BasicConstraintsValid: true, 45 Subject: pkix.Name{ 46 CommonName: serverName, 47 }, 48 DNSNames: []string{serverName}, 49 } 50 publicDer, err := x509.CreateCertificate(rand.Reader, template, template, key.Public(), key) 51 if err != nil { 52 return 53 } 54 privateDer, err := x509.MarshalPKCS8PrivateKey(key) 55 if err != nil { 56 return 57 } 58 publicKeyPem = pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: publicDer}) 59 privateKeyPem = pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: privateDer}) 60 return 61 }