diff --git a/main/commands/all/tls/ech.go b/main/commands/all/tls/ech.go index 4ca1411c..a5dc8b2b 100644 --- a/main/commands/all/tls/ech.go +++ b/main/commands/all/tls/ech.go @@ -13,13 +13,14 @@ import ( ) var cmdECH = &base.Command{ - UsageLine: `{{.Exec}} tls ech [--serverName (string)] [--pem]`, + UsageLine: `{{.Exec}} tls ech [--serverName (string)] [--pem] [-i "ECHSeverKeys (base64.StdEncoding)"]`, Short: `Generate TLS-ECH certificates`, Long: ` Generate TLS-ECH certificates. Set serverName to your custom string: {{.Exec}} tls ech --serverName (string) Generate into pem format: {{.Exec}} tls ech --pem +Restore ECHConfigs from ECHSeverKeys: {{.Exec}} tls ech -i "ECHSeverKeys (base64.StdEncoding)" `, // Enable PQ signature schemes: {{.Exec}} tls ech --pq-signature-schemes-enabled } @@ -27,7 +28,9 @@ func init() { cmdECH.Run = executeECH } -var input_pqSignatureSchemesEnabled = cmdECH.Flag.Bool("pqSignatureSchemesEnabled", false, "") +var input_echSeverKeys = cmdECH.Flag.String("i", "", "ECHSeverKeys (base64.StdEncoding)") + +// var input_pqSignatureSchemesEnabled = cmdECH.Flag.Bool("pqSignatureSchemesEnabled", false, "") var input_serverName = cmdECH.Flag.String("serverName", "cloudflare-ech.com", "") var input_pem = cmdECH.Flag.Bool("pem", false, "True == turn on pem output") @@ -37,24 +40,46 @@ func executeECH(cmd *base.Command, args []string) { // if *input_pqSignatureSchemesEnabled { // kem = 0x30 // hpke.KEM_X25519_KYBER768_DRAFT00 // } else { - kem = hpke.DHKEM_X25519_HKDF_SHA256 + kem = hpke.DHKEM_X25519_HKDF_SHA256 // } - echKeySet, priv, err := tls.GenerateECHKeySet(0, *input_serverName, kem) + echConfig, priv, err := tls.GenerateECHKeySet(0, *input_serverName, kem) common.Must(err) - configBytes, _ := tls.MarshalBinary(echKeySet) - var b cryptobyte.Builder - b.AddUint16LengthPrefixed(func(child *cryptobyte.Builder) { - child.AddBytes(configBytes) - }) - configBuffer, _ := b.Bytes() - var b2 cryptobyte.Builder - b2.AddUint16(uint16(len(priv))) - b2.AddBytes(priv) - b2.AddUint16(uint16(len(configBytes))) - b2.AddBytes(configBytes) - keyBuffer, _ := b2.Bytes() + var configBuffer, keyBuffer []byte + if *input_echSeverKeys == "" { + configBytes, _ := tls.MarshalBinary(echConfig) + var b cryptobyte.Builder + b.AddUint16LengthPrefixed(func(child *cryptobyte.Builder) { + child.AddBytes(configBytes) + }) + configBuffer, _ = b.Bytes() + var b2 cryptobyte.Builder + b2.AddUint16(uint16(len(priv))) + b2.AddBytes(priv) + b2.AddUint16(uint16(len(configBytes))) + b2.AddBytes(configBytes) + keyBuffer, _ = b2.Bytes() + } else { + keySetsByte, err := base64.StdEncoding.DecodeString(*input_echSeverKeys) + if err != nil { + os.Stdout.WriteString("Failed to decode ECHSeverKeys: " + err.Error() + "\n") + return + } + keyBuffer = keySetsByte + KeySets, err := tls.ConvertToGoECHKeys(keySetsByte) + if err != nil { + os.Stdout.WriteString("Failed to decode ECHSeverKeys: " + err.Error() + "\n") + return + } + var b cryptobyte.Builder + for _, keySet := range KeySets { + b.AddUint16LengthPrefixed(func(child *cryptobyte.Builder) { + child.AddBytes(keySet.Config) + }) + } + configBuffer, _ = b.Bytes() + } if *input_pem { configPEM := string(pem.EncodeToMemory(&pem.Block{Type: "ECH CONFIGS", Bytes: configBuffer}))