@@ -0,0 +1,69 @@ | |||
package main | |||
import ( | |||
"errors" | |||
"flag" | |||
"os" | |||
"strings" | |||
hs "github.com/henrydcase/tlshandshake" | |||
trs "github.com/henrydcase/trs" | |||
) | |||
func getIDByName(m map[uint16]string, name string) (uint16, error) { | |||
for key, value := range m { | |||
if value == name { | |||
return key, nil | |||
} | |||
} | |||
return 0, errors.New("Unknown value") | |||
} | |||
// Usage client args host:port | |||
func main() { | |||
var tls_version, named_groups, named_ciphers string | |||
flag.StringVar(&tls_version, "tls_version", "1.3", "TLS version to use") | |||
flag.StringVar(&named_groups, "groups", "X25519:P-256:P-384:P-521", "NamedGroups IDs to use") | |||
flag.StringVar(&named_ciphers, "ciphers", "TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384", "Named cipher IDs to use") | |||
flag.Parse() | |||
if flag.NArg() != 1 { | |||
flag.Usage() | |||
os.Exit(1) | |||
} | |||
client := hs.NewClient() | |||
client.Addr = flag.Arg(0) | |||
if !strings.Contains(client.Addr, ":") { | |||
client.Addr += ":443" | |||
} | |||
// Set requested DH groups | |||
client.TLS.CurvePreferences = []trs.CurveID{} | |||
for _, ng := range strings.Split(named_groups, ":") { | |||
id, err := getIDByName(hs.NamedGroupsToName, ng) | |||
if err != nil { | |||
panic("Wrong group name provided") | |||
} | |||
client.TLS.CurvePreferences = append(client.TLS.CurvePreferences, trs.CurveID(id)) | |||
} | |||
// Perform TLS handshake with each each requested CipherSuite | |||
tlsID, err := getIDByName(hs.TlsVersionToName, tls_version) | |||
if err != nil { | |||
panic("Unknown TLS version") | |||
} | |||
cn := strings.Split(named_ciphers, ":") | |||
if len(cn) == 0 { | |||
panic("Cipher can't be null") | |||
} | |||
id, err := getIDByName(hs.CipherSuiteIdToName, cn[0]) | |||
if err != nil { | |||
panic("Wrong cipher name provided") | |||
} | |||
client.SetMinMaxTLS(tlsID) | |||
client.TLS.CipherSuites = []uint16{id} | |||
client.Run() | |||
} |
@@ -0,0 +1,71 @@ | |||
package tlshandshake | |||
import ( | |||
"fmt" | |||
trs "github.com/henrydcase/trs" | |||
) | |||
var TlsVersionToName = map[uint16]string{ | |||
trs.VersionTLS10: "1.0", | |||
trs.VersionTLS11: "1.1", | |||
trs.VersionTLS12: "1.2", | |||
trs.VersionTLS13: "1.3", | |||
} | |||
var CipherSuiteIdToName = map[uint16]string{ | |||
trs.TLS_RSA_WITH_AES_128_CBC_SHA: "TLS_RSA_WITH_AES_128_CBC_SHA", | |||
trs.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", | |||
trs.TLS_AES_128_GCM_SHA256: "TLS_AES_128_GCM_SHA256", | |||
trs.TLS_AES_256_GCM_SHA384: "TLS_AES_256_GCM_SHA384", | |||
trs.TLS_CHACHA20_POLY1305_SHA256: "TLS_CHACHA20_POLY1305_SHA256", | |||
} | |||
var NamedGroupsToName = map[uint16]string{ | |||
uint16(trs.HybridSIDHp503Curve25519): "X25519-SIDHp503", | |||
uint16(trs.HybridSIKEp503Curve25519): "X25519-SIKEp503", | |||
uint16(trs.X25519): "X25519", | |||
uint16(trs.CurveP256): "P-256", | |||
uint16(trs.CurveP384): "P-384", | |||
uint16(trs.CurveP521): "P-521", | |||
} | |||
var failed uint | |||
type Client struct { | |||
TLS trs.Config | |||
Addr string | |||
} | |||
func NewClient() *Client { | |||
var c Client | |||
c.TLS.InsecureSkipVerify = true | |||
return &c | |||
} | |||
func (c *Client) Run() { | |||
fmt.Printf("TLS %s with %s\n", TlsVersionToName[c.TLS.MinVersion], CipherSuiteIdToName[c.TLS.CipherSuites[0]]) | |||
con, err := trs.Dial("tcp", c.Addr, &c.TLS) | |||
if err != nil { | |||
fmt.Printf("handshake failed: %v\n\n", err) | |||
failed++ | |||
return | |||
} | |||
defer con.Close() | |||
fmt.Printf("[TLS: %s]\n", TlsVersionToName[con.ConnectionState().Version]) | |||
fmt.Println("OK\n") | |||
} | |||
func (c *Client) Clone() *Client { | |||
var clone Client | |||
clone.TLS = *c.TLS.Clone() | |||
clone.Addr = c.Addr | |||
return &clone | |||
} | |||
func (c *Client) SetMinMaxTLS(ver uint16) { | |||
c.TLS.MinVersion = ver | |||
c.TLS.MaxVersion = ver | |||
} |