github.com/xraypb/xray-core@v1.6.6/main/commands/all/tls/cert.go (about) 1 package tls 2 3 import ( 4 "context" 5 "crypto/x509" 6 "encoding/json" 7 "os" 8 "strings" 9 "time" 10 11 "github.com/xraypb/xray-core/common" 12 "github.com/xraypb/xray-core/common/protocol/tls/cert" 13 "github.com/xraypb/xray-core/common/task" 14 "github.com/xraypb/xray-core/main/commands/base" 15 ) 16 17 // cmdCert is the tls cert command 18 var cmdCert = &base.Command{ 19 UsageLine: "{{.Exec}} tls cert [--ca] [--domain=example.com] [--expire=240h]", 20 Short: "Generate TLS certificates", 21 Long: ` 22 Generate TLS certificates. 23 24 Arguments: 25 26 -domain=domain_name 27 The domain name for the certificate. 28 29 -name=common_name 30 The common name for the certificate. 31 32 -org=organization 33 The organization name for the certificate. 34 35 -ca 36 Whether this certificate is a CA 37 38 -json 39 The output of certificate to JSON 40 41 -file 42 The certificate path to save. 43 44 -expire 45 Expire time of the certificate. Default value 3 months. 46 `, 47 } 48 49 func init() { 50 cmdCert.Run = executeCert // break init loop 51 } 52 53 var ( 54 certDomainNames stringList 55 _ = func() bool { 56 cmdCert.Flag.Var(&certDomainNames, "domain", "Domain name for the certificate") 57 return true 58 }() 59 60 certCommonName = cmdCert.Flag.String("name", "Xray Inc", "The common name of this certificate") 61 certOrganization = cmdCert.Flag.String("org", "Xray Inc", "Organization of the certificate") 62 certIsCA = cmdCert.Flag.Bool("ca", false, "Whether this certificate is a CA") 63 certJSONOutput = cmdCert.Flag.Bool("json", true, "Print certificate in JSON format") 64 certFileOutput = cmdCert.Flag.String("file", "", "Save certificate in file.") 65 certExpire = cmdCert.Flag.Duration("expire", time.Hour*24*90 /* 90 days */, "Time until the certificate expires. Default value 3 months.") 66 ) 67 68 func executeCert(cmd *base.Command, args []string) { 69 var opts []cert.Option 70 if *certIsCA { 71 opts = append(opts, cert.Authority(*certIsCA)) 72 opts = append(opts, cert.KeyUsage(x509.KeyUsageCertSign|x509.KeyUsageKeyEncipherment|x509.KeyUsageDigitalSignature)) 73 } 74 75 opts = append(opts, cert.NotAfter(time.Now().Add(*certExpire))) 76 opts = append(opts, cert.CommonName(*certCommonName)) 77 if len(certDomainNames) > 0 { 78 opts = append(opts, cert.DNSNames(certDomainNames...)) 79 } 80 opts = append(opts, cert.Organization(*certOrganization)) 81 82 cert, err := cert.Generate(nil, opts...) 83 if err != nil { 84 base.Fatalf("failed to generate TLS certificate: %s", err) 85 } 86 87 if *certJSONOutput { 88 printJSON(cert) 89 } 90 91 if len(*certFileOutput) > 0 { 92 if err := printFile(cert, *certFileOutput); err != nil { 93 base.Fatalf("failed to save file: %s", err) 94 } 95 } 96 } 97 98 func printJSON(certificate *cert.Certificate) { 99 certPEM, keyPEM := certificate.ToPEM() 100 jCert := &jsonCert{ 101 Certificate: strings.Split(strings.TrimSpace(string(certPEM)), "\n"), 102 Key: strings.Split(strings.TrimSpace(string(keyPEM)), "\n"), 103 } 104 content, err := json.MarshalIndent(jCert, "", " ") 105 common.Must(err) 106 os.Stdout.Write(content) 107 os.Stdout.WriteString("\n") 108 } 109 110 func writeFile(content []byte, name string) error { 111 f, err := os.Create(name) 112 if err != nil { 113 return err 114 } 115 defer f.Close() 116 117 return common.Error2(f.Write(content)) 118 } 119 120 func printFile(certificate *cert.Certificate, name string) error { 121 certPEM, keyPEM := certificate.ToPEM() 122 return task.Run(context.Background(), func() error { 123 return writeFile(certPEM, name+"_cert.pem") 124 }, func() error { 125 return writeFile(keyPEM, name+"_key.pem") 126 }) 127 } 128 129 type stringList []string 130 131 func (l *stringList) String() string { 132 return "String list" 133 } 134 135 func (l *stringList) Set(v string) error { 136 if v == "" { 137 base.Fatalf("empty value") 138 } 139 *l = append(*l, v) 140 return nil 141 } 142 143 type jsonCert struct { 144 Certificate []string `json:"certificate"` 145 Key []string `json:"key"` 146 }