I'm trying to configure TLCP to work like standard TLS, with just one key and one certificate for each side. It happens that I get an error message referring to cipher suites: "server: handshake failed: tlcp: no cipher suite supported by both client and server".
package main
import (
"bufio"
"bytes"
"crypto/rand"
"encoding/pem"
"errors"
"flag"
"fmt"
"log"
"net"
"os"
"gitee.com/Trisia/gotlcp/tlcp"
"github.com/emmansun/gmsm/smx509"
)
var (
cert = flag.String("cert", "Certificate.pem", "Certificate path.")
tcpip = flag.String("tcp", "", "Encrypted TCP Transfer Protocol. [server|client]")
key = flag.String("key", "", "`Private key.")
iport = flag.String("ipport", "", "Local Port/remote's side Public IP:Port.")
)
func handleConnection(c net.Conn) {
log.Printf("Client(TLS) %v connected via secure channel.", c.RemoteAddr())
}
func main() {
flag.Parse()
if (*tcpip == "server" || *tcpip == "client") {
var certPEM []byte
var privPEM []byte
file, err := os.Open(*key)
if err != nil {
log.Fatal(err)
}
info, err := file.Stat()
if err != nil {
log.Fatal(err)
}
buf := make([]byte, info.Size())
file.Read(buf)
var block *pem.Block
block, _ = pem.Decode(buf)
if block == nil {
errors.New("no valid private key found")
}
privPEM = buf
file, err = os.Open(*cert)
if err != nil {
log.Fatal(err)
}
info, err = file.Stat()
if err != nil {
log.Fatal(err)
}
buf = make([]byte, info.Size())
file.Read(buf)
certPEM = buf
if *tcpip == "server" {
var cert tlcp.Certificate
cert, err = tlcp.X509KeyPair(certPEM, privPEM)
cfg := tlcp.Config{Certificates: []tlcp.Certificate{cert, cert}, CipherSuites: []uint16{tlcp.ECC_SM4_GCM_SM3}, ClientAuth: tlcp.RequireAndVerifyClientCert}
cfg.Rand = rand.Reader
port := "8081"
if *iport != "" {
port = *iport
}
ln, err := tlcp.Listen("tcp", ":"+port, &cfg)
if err != nil {
log.Fatal(err)
}
fmt.Fprintln(os.Stderr, "Server(TLCP) up and listening on port "+port)
conn, err := ln.Accept()
if err != nil {
log.Fatal(err)
}
defer ln.Close()
tlcpcon := conn.(*tlcp.Conn)
err = tlcpcon.Handshake()
if err != nil {
log.Fatalf("server: handshake failed: %s", err)
} else {
log.Print("server: conn: Handshake completed")
}
state := tlcpcon.ConnectionState()
for _, v := range state.PeerCertificates {
derBytes, err := smx509.MarshalPKIXPublicKey(v.PublicKey)
if err != nil {
log.Fatal(err)
}
pubPEM := pem.EncodeToMemory(&pem.Block{Type: "PUBLIC KEY", Bytes: derBytes})
fmt.Printf("%s\n", pubPEM)
}
go handleConnection(conn)
fmt.Println("Connection accepted")
for {
message, err := bufio.NewReader(conn).ReadString('\n')
if err != nil {
fmt.Println(err)
os.Exit(3)
}
fmt.Print("Client response: " + string(message))
reader := bufio.NewReader(os.Stdin)
fmt.Print("Text to be sent: ")
text, err := reader.ReadString('\n')
if err != nil {
fmt.Println(err)
os.Exit(3)
}
fmt.Fprintf(conn, text+"\n")
}
}
if *tcpip == "client" {
var cert tlcp.Certificate
cert, err = tlcp.X509KeyPair(certPEM, privPEM)
cfg := tlcp.Config{Certificates: []tlcp.Certificate{cert}, InsecureSkipVerify: true, CipherSuites: []uint16{tlcp.ECC_SM4_GCM_SM3}}
ipport := "127.0.0.1:8081"
if *iport != "" {
ipport = *iport
}
conn, err := tlcp.Dial("tcp", ipport, &cfg)
if err != nil {
log.Fatal(err)
}
certs := conn.ConnectionState().PeerCertificates
for _, cert := range certs {
fmt.Printf("Issuer: \n\t%s\n", cert.Issuer)
fmt.Printf("Subject: \n\t%s\n", cert.Subject)
fmt.Printf("Expiry: %s \n", cert.NotAfter.Format("Monday, 02-Jan-06 15:04:05 MST"))
}
if err != nil {
log.Fatal(err)
}
defer conn.Close()
var b bytes.Buffer
for _, cert := range conn.ConnectionState().PeerCertificates {
err := pem.Encode(&b, &pem.Block{
Type: "CERTIFICATE",
Bytes: cert.Raw,
})
if err != nil {
log.Fatal(err)
}
}
fmt.Println(b.String())
for {
reader := bufio.NewReader(os.Stdin)
fmt.Print("Text to be sent: ")
text, err := reader.ReadString('\n')
if err != nil {
fmt.Println(err)
os.Exit(3)
}
fmt.Fprintf(conn, text+"\n")
message, err := bufio.NewReader(conn).ReadString('\n')
if err != nil {
fmt.Println(err)
os.Exit(3)
}
fmt.Print("Server response: " + message)
}
}
os.Exit(0)
}
}
I don't understand what's wrong, if anyone can help me that would be great.
Thanks in advance.