package main import ( "log" "net" "time" "crypto/tls" "crypto/x509" "io/ioutil" "golang.org/x/net/context" "google.golang.org/grpc" "google.golang.org/grpc/credentials" ) var ( port = ":5000" tlsDir = "./tls-config" tlsServerName = "server.io" ca = tlsDir + "/ca.crt" server_crt = tlsDir + "/server.crt" server_key = tlsDir + "/server.key" client_crt = tlsDir + "/client.crt" client_key = tlsDir + "/client.key" ) type myGrpcServer struct{} func (s *myGrpcServer) SayHello(ctx context.Context, in *HelloRequest) (*HelloReply, error) { return &HelloReply{Message: "Hello " + in.Name}, nil } func main() { go startServer() time.Sleep(time.Second) doClientWork() } func startServer() { certificate, err := tls.LoadX509KeyPair(server_crt, server_key) if err != nil { log.Panicf("could not load server key pair: %s", err) } certPool := x509.NewCertPool() ca, err := ioutil.ReadFile(ca) if err != nil { log.Panicf("could not read ca certificate: %s", err) } // Append the client certificates from the CA if ok := certPool.AppendCertsFromPEM(ca); !ok { log.Panic("failed to append client certs") } // Create the TLS credentials creds := credentials.NewTLS(&tls.Config{ ClientAuth: tls.RequireAndVerifyClientCert, // NOTE: this is optional! Certificates: []tls.Certificate{certificate}, ClientCAs: certPool, }) server := grpc.NewServer(grpc.Creds(creds)) RegisterGreeterServer(server, new(myGrpcServer)) lis, err := net.Listen("tcp", port) if err != nil { log.Panicf("could not list on %s: %s", port, err) } if err := server.Serve(lis); err != nil { log.Panicf("grpc serve error: %s", err) } } func doClientWork() { certificate, err := tls.LoadX509KeyPair(client_crt, client_key) if err != nil { log.Panicf("could not load client key pair: %s", err) } certPool := x509.NewCertPool() ca, err := ioutil.ReadFile(ca) if err != nil { log.Panicf("could not read ca certificate: %s", err) } if ok := certPool.AppendCertsFromPEM(ca); !ok { log.Panic("failed to append ca certs") } creds := credentials.NewTLS(&tls.Config{ InsecureSkipVerify: false, // NOTE: this is required! ServerName: tlsServerName, // NOTE: this is required! Certificates: []tls.Certificate{certificate}, RootCAs: certPool, }) conn, err := grpc.Dial("localhost"+port, grpc.WithTransportCredentials(creds)) if err != nil { log.Fatal(err) } defer conn.Close() c := NewGreeterClient(conn) r, err := c.SayHello(context.Background(), &HelloRequest{Name: "gopher"}) if err != nil { log.Fatalf("could not greet: %v", err) } log.Printf("doClientWork: %s", r.Message) }