|
|
@@ -0,0 +1,67 @@
|
|
|
+package cert
|
|
|
+
|
|
|
+import (
|
|
|
+ "crypto/rand"
|
|
|
+ "crypto/rsa"
|
|
|
+ "crypto/x509"
|
|
|
+ "crypto/x509/pkix"
|
|
|
+ "encoding/pem"
|
|
|
+ "log"
|
|
|
+ "math/big"
|
|
|
+ "time"
|
|
|
+
|
|
|
+ "v2ray.com/core/common"
|
|
|
+)
|
|
|
+
|
|
|
+//go:generate go run $GOPATH/src/v2ray.com/core/common/errors/errorgen/main.go -pkg cert -path Protocol,TLS,Cert
|
|
|
+
|
|
|
+type Certificate struct {
|
|
|
+ // Cerificate in x509 format
|
|
|
+ Certificate []byte
|
|
|
+ // Private key in x509 format
|
|
|
+ PrivateKey []byte
|
|
|
+}
|
|
|
+
|
|
|
+type Option func(*x509.Certificate)
|
|
|
+
|
|
|
+func Authority(isCA bool) Option {
|
|
|
+ return func(cert *x509.Certificate) {
|
|
|
+ cert.IsCA = isCA
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func Generate() (Certificate, error) {
|
|
|
+ priv, err := rsa.GenerateKey(rand.Reader, 2048)
|
|
|
+ common.Must(err)
|
|
|
+
|
|
|
+ serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
|
|
|
+ serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
|
|
|
+ if err != nil {
|
|
|
+
|
|
|
+ log.Fatalf("failed to generate serial number: %s", err)
|
|
|
+ }
|
|
|
+
|
|
|
+ template := x509.Certificate{
|
|
|
+ SerialNumber: serialNumber,
|
|
|
+ Subject: pkix.Name{
|
|
|
+ Organization: []string{"V2Ray Inc"},
|
|
|
+ },
|
|
|
+ NotBefore: time.Now().Add(time.Hour * -1),
|
|
|
+ NotAfter: time.Now().Add(time.Hour),
|
|
|
+ KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
|
|
|
+ ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
|
|
|
+ BasicConstraintsValid: true,
|
|
|
+ DNSNames: []string{"www.v2ray.com", "v2ray.com"},
|
|
|
+ }
|
|
|
+
|
|
|
+ derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv)
|
|
|
+ common.Must(err)
|
|
|
+
|
|
|
+ certPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: derBytes})
|
|
|
+ keyPEM := pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)})
|
|
|
+
|
|
|
+ return Certificate{
|
|
|
+ Certificate: certPEM,
|
|
|
+ PrivateKey: keyPEM,
|
|
|
+ }, nil
|
|
|
+}
|