github.com/Uhtred009/v2ray-core-1@v4.31.2+incompatible/infra/control/cert.go (about) 1 package control 2 3 import ( 4 "context" 5 "crypto/x509" 6 "encoding/json" 7 "flag" 8 "os" 9 "strings" 10 "time" 11 12 "v2ray.com/core/common" 13 "v2ray.com/core/common/protocol/tls/cert" 14 "v2ray.com/core/common/task" 15 ) 16 17 type stringList []string 18 19 func (l *stringList) String() string { 20 return "String list" 21 } 22 23 func (l *stringList) Set(v string) error { 24 if v == "" { 25 return newError("empty value") 26 } 27 *l = append(*l, v) 28 return nil 29 } 30 31 type jsonCert struct { 32 Certificate []string `json:"certificate"` 33 Key []string `json:"key"` 34 } 35 36 type CertificateCommand struct { 37 } 38 39 func (c *CertificateCommand) Name() string { 40 return "cert" 41 } 42 43 func (c *CertificateCommand) Description() Description { 44 return Description{ 45 Short: "Generate TLS certificates.", 46 Usage: []string{ 47 "v2ctl cert [--ca] [--domain=v2ray.com] [--expire=240h]", 48 "Generate new TLS certificate", 49 "--ca The new certificate is a CA certificate", 50 "--domain Common name for the certificate", 51 "--expire Time until certificate expires. 240h = 10 days.", 52 }, 53 } 54 } 55 56 func (c *CertificateCommand) printJson(certificate *cert.Certificate) { 57 certPEM, keyPEM := certificate.ToPEM() 58 jCert := &jsonCert{ 59 Certificate: strings.Split(strings.TrimSpace(string(certPEM)), "\n"), 60 Key: strings.Split(strings.TrimSpace(string(keyPEM)), "\n"), 61 } 62 content, err := json.MarshalIndent(jCert, "", " ") 63 common.Must(err) 64 os.Stdout.Write(content) 65 os.Stdout.WriteString("\n") 66 } 67 68 func (c *CertificateCommand) writeFile(content []byte, name string) error { 69 f, err := os.Create(name) 70 if err != nil { 71 return err 72 } 73 defer f.Close() 74 75 return common.Error2(f.Write(content)) 76 } 77 78 func (c *CertificateCommand) printFile(certificate *cert.Certificate, name string) error { 79 certPEM, keyPEM := certificate.ToPEM() 80 return task.Run(context.Background(), func() error { 81 return c.writeFile(certPEM, name+"_cert.pem") 82 }, func() error { 83 return c.writeFile(keyPEM, name+"_key.pem") 84 }) 85 } 86 87 func (c *CertificateCommand) Execute(args []string) error { 88 fs := flag.NewFlagSet(c.Name(), flag.ContinueOnError) 89 90 var domainNames stringList 91 fs.Var(&domainNames, "domain", "Domain name for the certificate") 92 93 commonName := fs.String("name", "V2Ray Inc", "The common name of this certificate") 94 organization := fs.String("org", "V2Ray Inc", "Organization of the certificate") 95 96 isCA := fs.Bool("ca", false, "Whether this certificate is a CA") 97 jsonOutput := fs.Bool("json", true, "Print certificate in JSON format") 98 fileOutput := fs.String("file", "", "Save certificate in file.") 99 100 expire := fs.Duration("expire", time.Hour*24*90 /* 90 days */, "Time until the certificate expires. Default value 3 months.") 101 102 if err := fs.Parse(args); err != nil { 103 return err 104 } 105 106 var opts []cert.Option 107 if *isCA { 108 opts = append(opts, cert.Authority(*isCA)) 109 opts = append(opts, cert.KeyUsage(x509.KeyUsageCertSign|x509.KeyUsageKeyEncipherment|x509.KeyUsageDigitalSignature)) 110 } 111 112 opts = append(opts, cert.NotAfter(time.Now().Add(*expire))) 113 opts = append(opts, cert.CommonName(*commonName)) 114 if len(domainNames) > 0 { 115 opts = append(opts, cert.DNSNames(domainNames...)) 116 } 117 opts = append(opts, cert.Organization(*organization)) 118 119 cert, err := cert.Generate(nil, opts...) 120 if err != nil { 121 return newError("failed to generate TLS certificate").Base(err) 122 } 123 124 if *jsonOutput { 125 c.printJson(cert) 126 } 127 128 if len(*fileOutput) > 0 { 129 if err := c.printFile(cert, *fileOutput); err != nil { 130 return err 131 } 132 } 133 134 return nil 135 } 136 137 func init() { 138 common.Must(RegisterCommand(&CertificateCommand{})) 139 }