github.com/xtls/xray-core@v1.8.12-0.20240518155711-3168d27b0bdb/main/commands/all/tls/ech.go (about)

     1  package tls
     2  
     3  import (
     4  	"encoding/json"
     5  	"encoding/pem"
     6  	"os"
     7  	"strings"
     8  
     9  	"github.com/OmarTariq612/goech"
    10  	"github.com/cloudflare/circl/hpke"
    11  	"github.com/xtls/xray-core/common"
    12  	"github.com/xtls/xray-core/main/commands/base"
    13  )
    14  
    15  var cmdECH = &base.Command{
    16  	UsageLine: `{{.Exec}} tls ech [--serverName (string)] [--json]`,
    17  	Short:     `Generate TLS-ECH certificates`,
    18  	Long: `
    19  Generate TLS-ECH certificates.
    20  
    21  Set serverName to your custom string: {{.Exec}} tls ech --serverName (string)
    22  Generate into json format: {{.Exec}} tls ech --json
    23  `, // Enable PQ signature schemes: {{.Exec}} tls ech --pq-signature-schemes-enabled
    24  }
    25  
    26  func init() {
    27  	cmdECH.Run = executeECH
    28  }
    29  
    30  var input_pqSignatureSchemesEnabled = cmdECH.Flag.Bool("pqSignatureSchemesEnabled", false, "")
    31  var input_serverName = cmdECH.Flag.String("serverName", "cloudflare-ech.com", "")
    32  var input_json = cmdECH.Flag.Bool("json", false, "True == turn on json output")
    33  
    34  func executeECH(cmd *base.Command, args []string) {
    35  	var kem hpke.KEM
    36  
    37  	if *input_pqSignatureSchemesEnabled {
    38  		kem = hpke.KEM_X25519_KYBER768_DRAFT00
    39  	} else {
    40  		kem = hpke.KEM_X25519_HKDF_SHA256
    41  	}
    42  
    43  	echKeySet, err := goech.GenerateECHKeySet(0, *input_serverName, kem)
    44  	common.Must(err)
    45  
    46  	configBuffer, _ := echKeySet.ECHConfig.MarshalBinary()
    47  	keyBuffer, _ := echKeySet.MarshalBinary()
    48  
    49  	configPEM := string(pem.EncodeToMemory(&pem.Block{Type: "ECH CONFIGS", Bytes: configBuffer}))
    50  	keyPEM := string(pem.EncodeToMemory(&pem.Block{Type: "ECH KEYS", Bytes: keyBuffer}))
    51  	if *input_json {
    52  		jECHConfigs := map[string]interface{}{
    53  			"configs": strings.Split(strings.TrimSpace(string(configPEM)), "\n"),
    54  		}
    55  		jECHKey := map[string]interface{}{
    56  			"key": strings.Split(strings.TrimSpace(string(keyPEM)), "\n"),
    57  		}
    58  
    59  		for _, i := range []map[string]interface{}{jECHConfigs, jECHKey} {
    60  			content, err := json.MarshalIndent(i, "", "  ")
    61  			common.Must(err)
    62  			os.Stdout.Write(content)
    63  			os.Stdout.WriteString("\n")
    64  		}
    65  	} else {
    66  		os.Stdout.WriteString(configPEM)
    67  		os.Stdout.WriteString(keyPEM)
    68  	}
    69  }