Skip to content

Instantly share code, notes, and snippets.

@AudriusButkevicius
Created June 22, 2015 11:07
Show Gist options
  • Save AudriusButkevicius/c53c613c593a247ad695 to your computer and use it in GitHub Desktop.
Save AudriusButkevicius/c53c613c593a247ad695 to your computer and use it in GitHub Desktop.
TLS proxy example with both ends being clients
package main
import(
"fmt"
"net"
"path/filepath"
"crypto/tls"
"time"
"sync"
)
func main(){
dir := "/tmp/certs"
certFile1, keyFile1 := filepath.Join(dir, "cert1.pem"), filepath.Join(dir, "key1.pem")
certFile2, keyFile2 := filepath.Join(dir, "cert2.pem"), filepath.Join(dir, "key2.pem")
cert1, err := tls.LoadX509KeyPair(certFile1, keyFile1)
if err != nil {
panic(err)
}
cert2, err := tls.LoadX509KeyPair(certFile2, keyFile2)
if err != nil {
panic(err)
}
go relay()
time.Sleep(time.Millisecond)
c1, err := net.Dial("tcp", "127.0.0.1:2428")
if err != nil {
panic(err)
}
c2, err := net.Dial("tcp", "127.0.0.1:2428")
if err != nil {
panic(err)
}
c1c := &tls.Config{
Certificates: []tls.Certificate{cert1},
NextProtos: []string{"test"},
ClientAuth: tls.RequestClientCert,
SessionTicketsDisabled: true,
InsecureSkipVerify: true,
MinVersion: tls.VersionTLS12,
CipherSuites: []uint16{
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
},
}
c2c := &tls.Config{
Certificates: []tls.Certificate{cert2},
NextProtos: []string{"test"},
ClientAuth: tls.RequestClientCert,
SessionTicketsDisabled: true,
InsecureSkipVerify: true,
MinVersion: tls.VersionTLS12,
CipherSuites: []uint16{
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
},
}
t1 := tls.Client(c1, c1c)
t2 := tls.Server(c2, c2c)
wg := sync.WaitGroup{}
wg.Add(2)
go func() {
err = t1.Handshake()
if err != nil {
panic(err)
}
wg.Done()
}()
go func() {
err = t2.Handshake()
if err != nil {
panic(err)
}
wg.Done()
}()
wg.Wait()
_, err = t1.Write([]byte("test"))
if err != nil {
panic(err)
}
buf := make([]byte, 1042)
n, err := t2.Read(buf)
if err != nil {
panic(err)
}
fmt.Println("All good", string(buf[:n]))
}
func relay() {
sock, err := net.Listen("tcp", ":2428")
if err != nil {
panic(err)
}
for {
c1, err := sock.Accept()
if err != nil {
panic(err)
}
c2, err := sock.Accept()
if err != nil {
panic(err)
}
go proxy(c1, c2)
go proxy(c2, c1)
}
}
func proxy(c1, c2 net.Conn) {
for {
buf := make([]byte, 1024)
n, err := c1.Read(buf)
if err != nil {
panic(err)
}
_, err = c2.Write(buf[:n])
if err != nil {
panic(err)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment