Skip to content

Instantly share code, notes, and snippets.

@spikebike
Created April 4, 2012 10:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save spikebike/2300144 to your computer and use it in GitHub Desktop.
Save spikebike/2300144 to your computer and use it in GitHub Desktop.
Broken TLS + AddService for go-rpcgen
ackage main
import (
"flag"
"log"
"net"
"crypto/rand"
"crypto/tls"
"crypto/x509"
"./addservice"
)
var (
addr = flag.String("addr", ":9999", "RPC Server address (transient)")
message = flag.String("message", "test", "Test echo message")
)
// Echo is the type which will implement the echoservice.EchoService interface
// and can be called remotely. In this case, it does not have any state, but
// it could.
type Add struct{}
// Echo is the function that can be called remotely. Note that this can be
// called concurrently, so if the Echo structure did have internal state,
// it should be designed for concurrent access.
func (Add) Add(in *addservice.AddMessage, out *addservice.SumMessage) error {
log.Printf("server: x=%d", *in.X)
log.Printf("server: y=%d", *in.Y)
out.Z = new(int32)
*out.Z = *in.X + *in.Y
log.Printf("server: zz=%d", *out.Z)
return nil
}
func handleClient(conn net.Conn) {
defer conn.Close()
tlscon, ok := conn.(*tls.Conn)
if ok {
log.Print("server: conn: type assert to TLS succeedded")
err := tlscon.Handshake()
if err != nil {
log.Fatalf("server: handshake failed: %s", err)
} else {
log.Print("server: conn: Handshake completed")
}
state := tlscon.ConnectionState()
log.Println("Server: client public key is:")
for _, v := range state.PeerCertificates {
log.Print(x509.MarshalPKIXPublicKey(v.PublicKey))
}
addservice.ServeAddService(conn,Add{})
}
}
func serverTLSListen(service string) {
cert, err := tls.LoadX509KeyPair("certs/server.pem", "certs/server.key")
if err != nil {
log.Fatalf("server: loadkeys: %s", err)
}
config := tls.Config{Certificates: []tls.Certificate{cert}, ClientAuth: tls.RequireAnyClientCert}
config.Rand = rand.Reader
listener, err := tls.Listen("tcp", service, &config)
if err != nil {
log.Fatalf("server: listen: %s", err)
}
log.Print("server: listening")
for {
conn, err := listener.Accept()
if err != nil {
log.Printf("server: accept: %s", err)
break
}
log.Printf("server: accepted from %s", conn.RemoteAddr())
go handleClient(conn)
}
}
func main() {
flag.Parse()
serverTLSListen("0.0.0.0:8000")
}
package addservice;
message add_message {
required int32 x=1;
required int32 y=2;
}
message sum_message {
required int32 z=1;
}
service add_service {
rpc add (add_message) returns (sum_message);
}
package main
import (
"bufio"
"crypto/tls"
"crypto/x509"
"flag"
"fmt"
"io"
"log"
"os"
// "github.com/kylelemons/go-rpcgen/examples/echo/echoservice"
"../addservice"
)
var server = flag.String("server", "localhost:9999", "RPC server address")
func openTLSClient(ipPort string) (*tls.Conn, error) {
cert, err := tls.LoadX509KeyPair("certs/client.pem", "certs/client.key")
if err != nil {
log.Fatalf("server: loadkeys: %s", err)
}
config := tls.Config{Certificates: []tls.Certificate{cert}, InsecureSkipVerify: true}
conn, err := tls.Dial("tcp", ipPort, &config)
if err != nil {
log.Fatalf("client: dial: %s", err)
}
defer conn.Close()
log.Println("client: connected to: ", conn.RemoteAddr())
state := conn.ConnectionState()
for _, v := range state.PeerCertificates {
fmt.Println("Client: Server public key is:")
fmt.Println(x509.MarshalPKIXPublicKey(v.PublicKey))
}
log.Println("client: handshake: ", state.HandshakeComplete)
log.Println("client: mutual: ", state.NegotiatedProtocolIsMutual)
return conn, err
}
func main() {
var x int32
var y int32
conn, err := openTLSClient("127.0.0.1:8000")
sum := addservice.NewAddServiceClient(conn)
if err != nil {
log.Fatalf("dial: %s", err)
}
lines := bufio.NewReader(os.Stdin)
x = 2
y = 3
for {
os.Stdout.WriteString("sending 2+3")
os.Stdout.WriteString("> ")
line, err := lines.ReadString('\n')
if err != nil {
if err == io.EOF {
return
}
log.Fatalf("read: %s", err)
}
in := &addservice.AddMessage{X: &x, Y: &y}
out := &addservice.SumMessage{}
if err := sum.Add(in, out); err != nil {
log.Fatalf("echo: %s", err)
}
if out.Z == nil {
log.Fatalf("echo: no message returned")
}
os.Stdout.WriteString("< ")
os.Stdout.WriteString(line)
fmt.Println(*out.Z)
}
}
#!/bin/bash
# call this script with an email address (valid or not).
# like:
# ./makecert.sh joe@random.com
mkdir certs
rm certs/*
echo "make server cert"
openssl req -new -nodes -x509 -out certs/server.pem -keyout certs/server.key -days 3650 -subj "/C=DE/ST=NRW/L=Earth/O=Random Company/OU=IT/CN=www.random.com/emailAddress=$1"
echo "make client cert"
openssl req -new -nodes -x509 -out certs/client.pem -keyout certs/client.key -days 3650 -subj "/C=DE/ST=NRW/L=Earth/O=Random Company/OU=IT/CN=www.random.com/emailAddress=$1"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment