github.com/inazumav/sing-box@v0.0.0-20230926072359-ab51429a14f1/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 GenerateKeyPair(timeFunc func() time.Time, serverName string) (*tls.Certificate, error) {
    15  	if timeFunc == nil {
    16  		timeFunc = time.Now
    17  	}
    18  	key, err := rsa.GenerateKey(rand.Reader, 2048)
    19  	if err != nil {
    20  		return nil, err
    21  	}
    22  	serialNumber, err := rand.Int(rand.Reader, new(big.Int).Lsh(big.NewInt(1), 128))
    23  	if err != nil {
    24  		return nil, err
    25  	}
    26  	template := &x509.Certificate{
    27  		SerialNumber:          serialNumber,
    28  		NotBefore:             timeFunc().Add(time.Hour * -1),
    29  		NotAfter:              timeFunc().Add(time.Hour),
    30  		KeyUsage:              x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
    31  		ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
    32  		BasicConstraintsValid: true,
    33  		Subject: pkix.Name{
    34  			CommonName: serverName,
    35  		},
    36  		DNSNames: []string{serverName},
    37  	}
    38  	publicDer, err := x509.CreateCertificate(rand.Reader, template, template, key.Public(), key)
    39  	if err != nil {
    40  		return nil, err
    41  	}
    42  	privateDer, err := x509.MarshalPKCS8PrivateKey(key)
    43  	if err != nil {
    44  		return nil, err
    45  	}
    46  	publicPem := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: publicDer})
    47  	privPem := pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: privateDer})
    48  	keyPair, err := tls.X509KeyPair(publicPem, privPem)
    49  	if err != nil {
    50  		return nil, err
    51  	}
    52  	return &keyPair, err
    53  }